def get_config(self): retval = True id = 0 name = "" #============================================================================== # Request SL config #============================================================================== bt = BLEClient(self.auth_id, self.key, self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) # send challenge request log.debug('request challenge') message = cmd.challenge_request(self.auth_id, self.key) bt.send_encrypted(message) # receive sl challenge auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) if ((0x0004 == cmd_id) and (True == retval)): log.debug('SL challenge received') nonce_k = cmd.challenge_decode(message) # send request SL states log.debug('request SL states') message = cmd.config_request_encode(nonce_k) bt.send_encrypted(message) # receive SL states auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no challenge received') retval = False if ((0x0015 == cmd_id) and (True == retval)): # SL state received log.debug('SL config received') id, name = cmd.config_decode(message) else: # no SL state received log.debug('Nuki error: no Nuki config received') retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() return retval, id, name
def update_time(self, sec_pin): retval = True bt = BLEClient(self.auth_id, self.key, self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) # send challenge request message = cmd.challenge_request(self.auth_id, self.key) bt.send_encrypted(message) # receive sl challenge auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) # send update time if ((0x0004 == cmd_id) and (True == retval)): nonce_k = cmd.challenge_decode(message) time = utils.get_time() message = cmd.update_time(time, nonce_k, sec_pin) bt.send_encrypted(message) # receive status accepted auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) if ((0x000E == cmd_id) and (True == retval)): status = cmd.status_decode(message) log.debug('Status: ' + str(hex(status))) if (0x01 == status): log.debug('Todo: update_time') #hmk TODO: else: retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() return retval
def get_states(self): retval = True nuki_state = 0 lock_state = 0 trigger = 0 sl_time = 0 sl_time_z = 0 bat = 0 #============================================================================== # Request SL status #============================================================================== bt = BLEClient(self.auth_id, self.key, self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) # send request SL states log.debug('request SL states') message = cmd.nuki_states_request() bt.send_encrypted(message) # receive SL states auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) if ((0x000C == cmd_id) and (True == retval)): # SL state received log.debug('SL state received') nuki_state, lock_state, trigger, sl_time, sl_time_z, bat = cmd.nuki_states_decode( message) else: # no SL state received log.debug('Nuki error: no Nuki state received') retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() return retval, nuki_state, lock_state, trigger, sl_time, sl_time_z, bat
def get_battery_report(self): retval = True critical_battery_state = 0 battery_voltage = 0 bt = BLEClient(self.auth_id, self.key, self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) # send battery report request log.debug('request battery report') message = cmd.battery_report_request() bt.send_encrypted(message) # receive battery report auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) if ((0x0011 == cmd_id) and (True == retval)): # battery report received log.debug('SL battery report received') bat_drain, bat_voltage, bat_state = cmd.battery_report_decode( message) log.debug('Battery drain: ' + str(hex(bat_drain))) log.debug('Battery voltage: ' + str(hex(bat_voltage))) log.debug('Battery state: ' + str(hex(bat_state))) else: # no battery report received log.debug('Nuki error: no SL battery report received') retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() return retval, critical_battery_state, battery_voltage
def lock_action(self, lock_action, auto_Unlock=False, force_unlock=False): retval = True bat = 0 bt = BLEClient(self.auth_id, self.key, self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) flags = 0x00 if (auto_Unlock == True): flags |= 0x01 if (force_unlock == True): flags |= 0x02 #============================================================================== # Lock action #============================================================================== # send challenge request log.debug('request challenge') message = cmd.challenge_request(self.auth_id, self.key) bt.send_encrypted(message) # receive sl challenge auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) if ((0x0004 == cmd_id) and (True == retval)): log.debug('SL challenge received') nonce_k = cmd.challenge_decode(message) # send lock action log.debug('send lock action') message = cmd.lock_action(self.auth_id, lock_action, self.bridge_id, flags, nonce_k) bt.send_encrypted(message) # receive status accepted auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no challenge received') retval = False if ((0x000E == cmd_id) and (True == retval)): # status received status = cmd.status_decode(message) if (0x01 == status): # lock action accepted log.debug('lock action accepted') retries = 20 while (retries): log.debug('wait for lock action complete') auth_id, message, decrypted = bt.get_encrypted() cmd_id = cmd.get_cmd_id(message) if (0x000C == cmd_id): # Nuki state received log.debug('Nuki state received') n_stat, l_stat, trigger, sl_time, sl_time_z, bat = cmd.nuki_states_decode( message) elif (0x000E == cmd_id): # status received retries = 0 elif (0x0012 == cmd_id): # error received retries = 0 else: retries = retries - 1 if (0x000E == cmd_id): status = cmd.status_decode(message) if (0x00 == status): # lock status complete log.debug('lock status complete') retval = True else: # lock status not complete log.debug('Nuki error: lock status not complete') retval = False else: # no lock status received log.debug('Nuki error: no lock status received') retval = False else: # lock action not accepted log.debug('Nuki error: lock action not accepted') retval = False else: log.debug('Nuki error: no status received') retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() return retval, bat
def authorize(self): retval = True auth_id = 0 uuid = '' key = '' nonce_abf = None bt = BLEClient(port=self.port, bgapi=self.bgapi) bt.connect(self.mac_addr) #============================================================================== # Authentication process #============================================================================== # request sl public key log.debug('request SL public key') message = cmd.public_key_request() bt.send_unencrypted(message) # receive sl public key message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) if ((0x0003 == cmd_id) and (True == retval)): log.debug('SL public key received') sl_public_k = cmd.public_key_decode(message) # generate keys log.debug('generating key') cl_public_k, cl_private_k = self._generate_keypair() self.key = self._generate_kdf1(cl_private_k, sl_public_k) # send own public key log.debug('send own public key') message = cmd.public_key(cl_public_k) bt.send_unencrypted(message) # receive sl challenge 1 message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no public key received') retval = False if ((0x0004 == cmd_id) and (True == retval)): log.debug('SL nonce_k received') nonce_k = cmd.challenge_decode(message) #send authenticator log.debug('send authenticator') message = cmd.authenticator(cl_public_k, sl_public_k, nonce_k, self.key) bt.send_unencrypted(message) # receive sl challenge 2 message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no nonce nonce_k received') retval = False if ((0x0004 == cmd_id) and (True == retval)): log.debug('SL nonce_k received') nonce_k = cmd.challenge_decode(message) # send authorization data log.debug('send authorization data') nonce_abf = nacl.utils.random(32) message = cmd.authorization_data(self.id_type, self.bridge_id, self.name, nonce_abf, nonce_k, self.key) bt.send_unencrypted(message) # receive authorization id message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no nonce_k received') retval = False if ((0x0007 == cmd_id) and (True == retval)): # cl verifies authorization id log.debug('SL authorization id received') verify = self._auth_message(message, nonce_abf, self.key) if (0 != verify): error_code = 0x11 command = cmd.get_cmd_id(message) message = cmd.error_bridge(error_code, command) cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: no authorization id received') retval = False if ((0x0007 == cmd_id) and (True == retval)): log.debug('SL authorization id verified') self.auth_id, uuid, nonce_k = cmd.authorization_id_decode(message) self.uuid = uuid log.debug('Authentication ID: ' + hex(self.auth_id)) log.debug('UUID: ' + hexlify(self.uuid)) # send authorization id confirmation log.debug('send authorization id confirmation') message = cmd.authorization_id_confirmation( self.auth_id, nonce_k, self.key) bt.send_unencrypted(message) # receive status ok message = bt.get_unencrypted() cmd_id = cmd.get_cmd_id(message) else: log.debug('Nuki error: authorization id verification') retval = False if ((0x000E == cmd_id) and (True == retval)): # Nuki states received log.debug('SL status received') status = cmd.status_decode(message) log.debug('status: ' + str(hex(status))) else: log.debug('Nuki error: no status received') retval = False if (False == retval): # error handler log.debug('Nuki error handler') self._err_handler(cmd_id, message) bt.stop() retval, id, name = self.get_config() return retval, self.auth_id, uuid, self.key, id, name