def process_msg(self, ppmsg: object, addr: object) -> None: dst_id = ppmsg.get("dst_id") if dst_id == self.node_id or dst_id == BroadCastId: sequence = ppmsg.get("sequence") src_id = ppmsg.get("src_id") # 回响应包 if ppmsg.get("need_ack") and not dst_id == BroadCastId: self.services[PP_APPID["Ack"]].send_ack( { "src_id": src_id, "sequence": sequence }, addr) if (src_id, sequence) in self.rx_queue: logging.debug("{0} duplication message! {1}".format( self.node_id, self.rx_queue)) return else: self.rx_queue.append((src_id, sequence)) self.rx_queue.pop(0) self.byte_in += ppmsg.length() self.packet_in += 1 app_id = ppmsg.get("app_id") if app_id in self.services: self.services[app_id].process(ppmsg, addr) return ''' call upper layer process''' if self.message_callback: self.message_callback(ppmsg, addr) else: logging.warning("{0} no process seting for {1}".format( self.node_id, get_app_name(ppmsg.get("app_id"))))
def start(self): ''' must need overload,to load service_process ''' logging.info("{} {} is start.".format(self.station.node_id, get_app_name(self.app_id))) return self
def load(self, bindata): try: command, _ = struct.unpack("BB", bindata[0:2]) data_parameters = {} start_pos = 2 while start_pos < len(bindata): tlv = TLV().load(bindata[start_pos:]) if not tlv: return None data_parameters[tlv.tag] = tlv.value start_pos += tlv.bin_length() self.data2dict(data_parameters) if command in self.tags_string: self.dict_data["command"] = self.tags_string[command] parameters = self.dict_data["parameters"].copy() self.dict_data["parameters"] = {} # comment to comptable for para in parameters: if para in self.tags_string: self.dict_data["parameters"][ self.tags_string[para]] = parameters[para] except Exception as exp: print(self.dict_data) logging.warning( "error when decode {0} app_message {1}\n {2}".format( get_app_name(self.app_id), bindata, exp)) return None return self
def quit(self): logging.info("{0} Layer2 is quitting...".format(self.node_id)) self.quitting = True for service in self.services: self.services[service].quit() logging.info("{0} {1} is quit.".format(self.node_id, get_app_name(service))) time.sleep(1) self.underlayer.quit()
def process_bindata(self, data, addr): try: ppmsg = PPMessage(bindata=data) logging.debug( "%d receive %s (seq=%d)(ttl=%d) from %s to %s addr %s!" % (self.node_id, get_app_name(ppmsg.get("app_id")), ppmsg.get("sequence"), ppmsg.get("ttl"), ppmsg.get("src_id"), ppmsg.get("dst_id"), addr)) self.process_msg(ppmsg, addr) except Exception as exp: logging.warning("can't decode %s from (%s,%d) Error %s " % (data, addr[0], addr[1], exp)) return
def send_ppmsg_peer(self, ppmsg, peer, need_ack=False): """ peer 是一个对象 return sequence 0 if failure if need_ack must have ack,will retry 3 times if no_ack, then call ack_callback(sequence,False) """ addr = (peer.ip, peer.port) self.send(ppmsg, addr, need_ack) sequence = ppmsg.get("sequence") # if need_ack: # peer.tx_queue.update({sequence: (ppmsg, 1)}) peer.set_flow_status(send_count=ppmsg.length()) logging.debug( "{0}: send {1}(seq={2})(ttl={3}) to {4}:({5},{6}).".format( self.node_id, get_app_name(ppmsg.get("app_id")), sequence, ppmsg.get("ttl"), peer.node_id, (peer.ip, peer.port), NAT_STRING[peer.nat_type])) return sequence