def _process_incoming_tlvs(self, sock, host, port, device, enc, data): tlvs = tlvlib.parse_tlvs(data) if device is not None: last_seeen = device.last_seen device.last_seen = time.time(); device.log.debug("RECV %s",tlvlib.get_tlv_short_info(tlvs)) else: last_seen = time.time() self.log.debug("[%s] RECV %s",host,tlvlib.get_tlv_short_info(tlvs)) ping_device = False dev_watchdog = None dev_type = 0 # print " Received TLVs:" # tlvlib.print_tlvs(tlvs) for tlv in tlvs: if tlv.error != 0: if device is not None: device.log.error("Received error (" + str(tlv.error) + "):") else: self.log.error("[%s] Received error:", host) tlvlib.print_tlv(tlv) elif tlv.instance == 0 and tlv.op == tlvlib.TLV_GET_RESPONSE: if tlv.variable == tlvlib.VARIABLE_OBJECT_TYPE: dev_type = tlv.int_value elif tlv.variable == tlvlib.VARIABLE_UNIT_BOOT_TIMER: pass elif tlv.variable == tlvlib.VARIABLE_TIME_SINCE_LAST_GOOD_UC_RX: if device is not None and last_seen - time.time() > 55: ping_device = True elif tlv.variable == tlvlib.VARIABLE_UNIT_CONTROLLER_WATCHDOG: dev_watchdog = tlv.int_value if not device: if dev_watchdog is not None or self.grab_all == 0: if dev_type == tlvlib.INSTANCE_BORDER_ROUTER: # Do not try to grab the border router pass elif not self.is_device_acceptable(host, dev_type): self.log.debug("[%s] IGNORING device of type 0x%016x that could be taken over", host, dev_type) else: # Unknown device - do a grab attempt if dev_watchdog is not None: self.log.debug("[%s] FOUND new device of type 0x%016x that can be taken over - WDT = %d", host, dev_type, dev_watchdog) if self.grab_device(host): device = self._add_device(sock, host, port) device.next_update = time.time() + self.watchdog_time - self.guard_time self.discover_device(device) elif device.is_discovered(): # time.sleep(0.005) device._process_tlvs(tlvs) if not device.is_sleepy_device() and ping_device and device.get_pending_packet_count() == 0: t = tlvlib.create_get_tlv64(0, tlvlib.VARIABLE_UNIT_BOOT_TIMER) device.send_tlv(t) device._flush() else: self.discover_device(device)
def _fetch_periodic(self, device): t = [] t.append(tlvlib.create_get_tlv64(0, tlvlib.VARIABLE_UNIT_BOOT_TIMER)) if False and device.nstats_instance is not None: t.append(nstatslib.create_nstats_tlv(device.nstats_instance)) if device.button_instance is not None: t.append(tlvlib.create_set_vector_tlv(0, tlvlib.VARIABLE_EVENT_ARRAY, 0, 0, 1, struct.pack("!L", 1))) t.append(tlvlib.create_set_vector_tlv(device.button_instance, tlvlib.VARIABLE_EVENT_ARRAY, 0, 0, 2, struct.pack("!LL", 1, 2))) if device.motion_instance is not None: if device.button_instance is None: t.append(tlvlib.create_set_vector_tlv(0, tlvlib.VARIABLE_EVENT_ARRAY, 0, 0, 1, struct.pack("!L", 1))) t.append(tlvlib.create_set_vector_tlv(device.motion_instance, tlvlib.VARIABLE_EVENT_ARRAY, 0, 0, 2, struct.pack("!LL", 1, 2))) try: device.log.debug("requesting periodic data: %s",tlvlib.get_tlv_short_info(t)) return device.send_tlv(t) except socket.timeout: device.log.error("failed to fetch from device (time out)") return False
def _flush(self): if self._outgoing is not None and len(self._outgoing) > 0: self.log.debug("FLUSH %s",tlvlib.get_tlv_short_info(self._outgoing)) tlvs = self._outgoing self._outgoing = [] self._send_immediately(tlvs)