#!/usr/bin/env python from bluepy.btle import Peripheral, DefaultDelegate, UUID, ADDR_TYPE_RANDOM, ADDR_TYPE_PUBLIC, Scanner import hexdump import binascii import urllib2 import json import fnmatch from Crypto.Cipher import AES class NotifyDelegate(DefaultDelegate): def __init__(self): DefaultDelegate.__init__(self) def handleNotification(self, cHandle, data): print "Token obtained" # Try to unlock it mica.unlock(data) class ScanDelegate(DefaultDelegate): def __init__(self): DefaultDelegate.__init__(self) def handleDiscovery(self, dev, isNewDev, isNewData): if isNewDev: if fnmatch.fnmatch(dev.addr, 'f0:?5:*'): print "Found Nokelock, %s, unlocking it" % (dev.getValueText(9)) unlockMicaLock(dev.addr) class MicaLock(): def __init__(self): self.addr="" self.key="" self.apitoken="" def setAddr(self,addr): self.addr=addr self.p = Peripheral(self.addr, addrType=ADDR_TYPE_PUBLIC) self.p.setDelegate(NotifyDelegate()) def getAddr(self): return self.addr def setKey(self,key): self.key=key self.aes=AES.new(key, AES.MODE_ECB) def getKey(self): return self.key def getApiToken(self): return self.apitoken def setApiToken(self, token): self.apitoken=token def getToken(self): message=binascii.unhexlify('060101017031321c66567559003a0a4d') # Start listening for notification self.p.writeCharacteristic(7,b'\x01\x00') # Send message self.p.writeCharacteristic(3,self.aes.encrypt(message)) self.p.waitForNotifications(1.0) def unlock(self,token): unlockit=binascii.unhexlify('050106303030303030') + self.aes.decrypt(token)[3:7] + binascii.unhexlify('000000') print "Unlocking" self.p.writeCharacteristic(3,self.aes.encrypt(unlockit)) self.p.disconnect() def unlockMicaLock(addr): mica.setAddr(addr) print "Obtaining Encryption key" body='{"mac":"%s"}' % (addr) request=urllib2.Request("http://app.nokelock.com:8080/newNokelock/lock/queryDevice",data=str(body),headers={'Content-Type': 'application/json','token': mica.getApiToken()}) response=urllib2.urlopen(request) apiresp=json.loads(response.read()) deckey=apiresp['result']['lockKey'] hexkey='' for i in deckey.split(","): a=hex(int(i))[2:].zfill(2) hexkey=hexkey+a key=binascii.unhexlify(hexkey) mica.setKey(key) # Bluetooth stuff now print "Obtaining BLE token" mica.getToken() mica=MicaLock() username="username" password="password" # log in print "Getting API token" body='{"type":19,"account":"%s","code":"%s"}' % (username,password) request=urllib2.Request("http://app.nokelock.com:8080/newNokelock/user/loginByPassword",data=str(body),headers={'Content-Type': 'application/json'}) response=urllib2.urlopen(request) apiresp=json.loads(response.read()) apitoken=apiresp['result']['token'] mica.setApiToken(apitoken) scanner=Scanner(0).withDelegate(ScanDelegate()) devices=scanner.scan()