def push_into_que(self): dev_eui = hexlify(self.device.dev_eui).decode() db0.set(ConstDB.mac_cmd + dev_eui + ':' + hexlify(self.cid).decode(), self.cid + self.generate_payload()) que_key = ConstDB.mac_cmd_que + dev_eui db0.lrem(que_key, count=0, value=self.cid) db0.rpush(que_key, self.cid) if self.device.dev_class == ClassType.c: db0.publish(Channel.que_down_alarm_c, self.device.dev_eui) Logger.info(action=Action.publish, resource=Resource.device, id=dev_eui, msg='add_mac_cmd que_down_alarm_c:' + self.device.dev_eui)
def publish(self): message = { 'dev_eui': hexlify(self.dev_eui).decode(), 'addr': hexlify(self.addr).decode(), 'nwkskey': hexlify(self.nwkskey).decode(), 'appskey': hexlify(self.appskey).decode(), 'ts': self.active_at.replace(tzinfo=timezone.utc).timestamp(), } db0.publish( Channel1.join_success_alarm + hexlify(self.app_eui).decode(), json.dumps(message))
def push(self, fport, payload, cipher=True, seqno=None, confirmed=False, rx_window=0): assert isinstance(payload, bytes) and len( payload) < MAX_FRMPAYLOAD_LENGTH, 'Payload over Max Length' assert isinstance(fport, int) and 0 < fport < 255, 'FPort Error' assert isinstance(cipher, bool), 'Cipher Type Error' assert rx_window == 0 or rx_window == 1 or rx_window == 2, 'RX WINDOW ERROR' if self.que_limit <= self.len(): raise QueOccupied('The queue of this Dev:%s is occupied' % hexlify(self.dev_eui).decode()) fport = pack('B', fport) if cipher is False: appskey = db0.hget(self.key, FieldDevice.appskey) if len(appskey) != 16: raise AppSKeyAbsence(self.key) cipher = 0 else: fcnt_down = int(db0.hget(self.key, FieldDevice.fcnt_down)) que_len = self.len() seqno_expect = fcnt_down + que_len + 1 if seqno != seqno_expect: raise SeqNoError(seqno, seqno_expect) cipher = 1 settings = (cipher << 7) + (rx_window << 5) + (confirmed.real << 4) settings = bytes([settings]) dev_class = ClassType( db0.hget(self.key, FieldDevice.dev_class).decode()) if dev_class == ClassType.c and rx_window == 1: db0.rpush(ConstDB.que_down + self.key + ':1', settings + fport + payload) else: db0.rpush(ConstDB.que_down + self.key, settings + fport + payload) if dev_class == ClassType.c and (rx_window == 2 or rx_window == 0): db0.publish(Channel.que_down_alarm_c, self.key) Logger.info(action=Action.publish, resource=Resource.device, id=self.dev_eui, msg='Publish ' + Channel.que_down_alarm_c + ' ' + self.key) elif dev_class == ClassType.b: db0.publish(Channel.que_down_alarm_b, self.key) Logger.info(action=Action.publish, resource=Resource.device, id=self.dev_eui, msg='Publish ' + Channel.que_down_alarm_b + ' ' + self.key)
def push(self, fport, payload, cipher=False, seqno=None): """ :param fport: int from 0 to 255 :param payload: bytes :param cipher: True or False :param seqno: if cipher is True, seqno mush present and must math fcnt else will raise SeqNoError :return: """ assert isinstance( payload, bytes) and len(payload) < MAX_FRMPAYLOAD_LENGTH, 'Payload Error' assert isinstance(fport, int) and 0 < fport < 255, 'FPort Error' assert isinstance(cipher, bool), 'Cipher Type Error' if self.que_limit <= self.len(): raise QueOccupied('The queue of this Group:%s is occupied' % hexlify(self.id).decode()) fport = pack('B', fport) if cipher is False: appskey = db0.hget(self.key, FieldGroup.appskey) if len(appskey) != 16: raise AppSKeyAbsence(self.key) cipher = b'\x00' else: fcnt = int(db0.hget(self.key, FieldGroup.fcnt)) que_len = self.len() seqno_expect = fcnt + que_len + 1 if seqno != seqno_expect: raise SeqNoError(seqno, seqno_expect) cipher = b'\x01' db0.rpush(ConstDB.que_down + self.key, cipher + fport + payload) db0.publish(Channel.que_down_alarm_multi, self.key) Logger.info(action=Action.publish, resource=Resource.group, id=self.id, msg='Publish ' + Channel.que_down_alarm_multi + ' ' + self.key)
def process_join_request(data): global appCache error_msg = None try: app_eui = unhexlify(data['app_eui']) app_eui_str = data['app_eui'] dev_eui = unhexlify(data['dev_eui']) device = db_session.query(Device).get(dev_eui) if device is None: error_msg = 'DEV:%s is not registered' % hexlify(dev_eui).decode() logger.error(ConstLog.join_req + error_msg) return elif device.app_eui != app_eui: error_msg = 'DEV:%s is already registered in other application' logger.error( ConstLog.join_req + 'DEV:%s belong to APP:%s, not APP:%s' % (hexlify(dev_eui).decode(), hexlify(device.app_eui).decode(), hexlify(app_eui).decode())) return addr = AddrManger.dis_dev_addr() try: join_dev = JoiningDev(app_eui, dev_eui, addr) join_dev.save() except Exception as error: error_msg = error logger.error(ConstLog.join_req + str(error_msg)) return data['dev_addr'] = hexlify(join_dev.addr).decode() logger.info('OTAA DATA TO JOINSERVER: %s' % data) r = requests.post(url, data=json.dumps(data), headers=headers) try: data = r.json() logger.info(ConstLog.join_resp + 'GET MSG FROM JOIN SERVER %s' % data) if r.ok: accept_msg = data.get('accept_msg') if accept_msg is not None: if app_eui_str in appCache.keys(): device.active(addr=join_dev.addr, dev_class='C', nwkskey=b64decode(data['nwkskey']), appskey=b64decode(data['appskey'])) else: device.active(addr=join_dev.addr, nwkskey=b64decode(data['nwkskey']), appskey=b64decode(data['appskey'])) device.active_at = datetime.utcnow() device.active_mode = ActiveMode.otaa db_session.commit() db1.publish( Channel1.join_accept_alarm + hexlify(join_dev.dev_eui).decode(), accept_msg) device.publish() logger.info('[OTAA] device %s join success' % hexlify(device.dev_eui).decode()) logger.info(ConstLog.publish + Channel1.join_accept_alarm + hexlify(join_dev.dev_eui).decode() + ': %s' % accept_msg) else: error_msg = data.get('error') if error_msg is not None: logger.error(ConstLog.join_resp + str(error_msg)) return except Exception as error: error_msg = error logger.error(ConstLog.join_resp + str(error_msg)) except Exception as error: error_msg = error logger.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + str(error_msg)) finally: db_session.close() if error_msg: db0.publish(Channel1.join_error_alarm + hexlify(app_eui).decode(), message=json.dumps({ 'dev_eui': hexlify(dev_eui).decode(), 'error': str(error_msg), 'ts': time.time() }))