summaryrefslogtreecommitdiff
path: root/dcs8000lh-configure.py
blob: 6dda24558e5d9c8dcd1a4ef4eb735a3340c58096 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/python3

import sys
import hashlib
import base64
from bluepy.btle import Peripheral

class BleCam(object):
    def __init__(self, address, pincode):
        self.pincode = pincode
        self.periph = Peripheral(address)
        self.ipcamservice()
        self.name = self.periph.getCharacteristics(uuid=0x2a00)[0].read().decode() # wellknown name characteristic
        self.dumpchars()
        self.unlock()

    def ipcamservice(self):
        try:
            print("getting IPCam service")
            self.service = self.periph.getServiceByUUID(0xd001)
        except BTLEEException:
            print("no IPCam service found for %s" % periph.address)

    def dumpchars(self):
        handles = self.service.getCharacteristics()
        print("%s supports these characteristics:" % self.name)
        for h in handles:
            print("%s - Handle=%#06x (%s)" % (h.uuid, h.getHandle(), h.propertiesToString()))

    def unlock(self):
        auth = self.service.getCharacteristics(0xa001)[0]
        for t in auth.read().decode().split(";", 10):
            if t.startswith("C="):
                self.challenge=t.split("=",2)[1]
        hashit = self.name + self.pincode + self.challenge
        self.key = base64.b64encode(hashlib.md5(hashit.encode()).digest())[:16]
        try:
            auth.write("M=0;K=".encode() + self.key, True)
        except:
            print("write failed")

    def get_ipconfig(self):
        return self.service.getCharacteristics(0xa104)[0].read()

    
    def wifi_scan(self):

        def _wifi_network(netstr):
            keymap = {
                "I": "essid",
                "M": "authalg",  # ??
                "C": "channel",
                "S": "key_mgmt", # ?? /auth_alg/proto?
                "E": "proto",    # ??
                "P": "rssi",     # ??
            }
            result = {}
            for x in netstr[2:].split(",", 10):
                (k, v) = x.split("=", 2)
                result[keymap[k]] = v
            return result

        scan = self.service.getCharacteristics(0xa100)[0]
        p = -1
        n = 0
        result = ""
        while p < n:
            t = scan.read().decode().split(";", 3)
            result = result + t[2]
            if not t[0].startswith("N=") or not t[1].startswith("P="):
                return
            n = int(t[0].split("=",2)[1])
            p = int(t[1].split("=",2)[1])
            print("read page %d of %d" % (p, n))
        return map(_wifi_network, result.split("&", 50))
                    
    def run_command(self, command):
        run = "P=" + self.pincode + ";N=" + self.pincode + "&&(" + command + ")&"
        try:
            self.service.getCharacteristics(0xa201)[0].write(run.encode(), True)
        except:
            print("failed")
        
if __name__ == '__main__':
    if len(sys.argv) < 3:
        print("Usage: {} <addr> <pincode>".format(sys.argv[0]))
        sys.exit(1)

    cam = BleCam(sys.argv[1], sys.argv[2])
    print("ip config is: %s" % cam.get_ipconfig())
    for network in cam.wifi_scan():
        print(network)
    if len(sys.argv) > 3:
        cam.run_command(sys.argv[3])

print("Done.")