def send_raw(self, address, payload, raw_type=1): ret = None with self._global_lock: try: host_id = address & self._hostmask address, port = self.getDeviceAddress(host_id) if address == 0: return None header = chr(0xaa) + chr(0x55) + chr(host_id) + struct.pack( '<I', self._ip) + struct.pack( '<H', self._port) + chr(raw_type) + chr(len(payload)) message = "".join(map(chr, payload)) logger.info("sending %d bytes %s to %s, port %d" % (len(message), map(ord, message), MPTN.ID_TO_STRING(address), port)) sock = socket.socket( socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #sock.sendto(message, (MPTN.ID_TO_STRING(address), MPTN.MPTN_UDP_PORT)) sock.sendto(header + message, (MPTN.ID_TO_STRING(address), port)) sock.close() except Exception as e: ret = traceback.format_exc() logger.error("send_raw exception %s\n%s" % (str(e), ret)) return ret
def _init_socket(self): self.sock = socket.socket( socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind(('', self._port)) logger.info( "transport interface %s initialized on %s IP=%s PORT=%d with Node ID %s/%s" % (self._name, self._dev_addr, MPTN.ID_TO_STRING( self._ip), self._port, MPTN.ID_TO_STRING( self._node_id[0]), str(self._node_id[1])))
def __init__(self, transport_if_addr, transport_if_len, transport_if_send, autonet_mac_addr=[], gateway_application_handlers={}): self._app_handler = gateway_application_handlers self._transport_if_addr = transport_if_addr self._transport_if_addr_len = transport_if_len self._transport_if_send = transport_if_send # _nexthop_db: key = "MPTN ID/NETMASK" STRING, value = next hop's tcp_address tuple ("IP" STRING, PORT INT) self._nexthop_db = DBDict("table_gtw_nexthop.json") self._init_nexthop_lookup() # _addr_db: key = address, value = UUID (such as MAC address) self._addr_db = DBDict("table_gtw_addr_uuid.json") self._settings_db = DBDict("table_gtw_settings.json") self._init_settings_db(autonet_mac_addr) if CONFIG.UNITTEST_MODE: self._id_req_queue = Queue() logger.info("IDService initialized with gateway ID is %s 0x%X" % (MPTN.ID_TO_STRING(self._settings_db["GTWSELF_ID"]), self._settings_db["GTWSELF_ID"]))
def handle_rtrep_message(self, context, dest_id, src_id, msg_type, payload): if payload is None: logger.error("RTREP should have the payload") return if dest_id != self._id: logger.error("RTREP dest_id should be me") return if not self._is_id_master(src_id): logger.error("RTPING src ID %X %s should be Master 0" % (src_id, MPTN.ID_TO_STRING(src_id))) return if payload is None: logger.error("RTREP payload should not be empty") return try: rtrep_nexthop = json.loads(payload) except Exception as e: logger.error( "RTREP payload %s cannot be loaded as json. error=%s\n%s" % (payload, str(e), traceback.format_exc())) return self._nexthop_lookup.clear() try: for network_string, tcp_address in rtrep_nexthop.iteritems(): network = MPTN.ID_NETWORK_FROM_STRING(network_string) if MPTN.IS_ID_IN_NETWORK(self._id, network): continue self._nexthop_lookup[network] = MPTN.NextHop( id=MPTN.ID_FROM_STRING(network_string), tcp_address=tuple(tcp_address)) except Exception as e: logger.error( "RTREP got an incorrect json as payload %s. error=%s\n%s" % (payload, str(e), traceback.format_exc())) self._nexthop_lookup = { MPTN.ID_NETWORK_FROM_STRING(network_string): MPTN.NextHop(id=MPTN.ID_FROM_STRING(network_string), tcp_address=tcp_address) for (network_string, tcp_address) in self._nexthop_db.iteritems() } return self._nexthop_db.clear() for network_string, tcp_address in rtrep_nexthop.iteritems(): self._nexthop_db[network_string] = tuple(tcp_address) self._update_nexthop_hash() # logger.info("new hash is %s" % str(map(ord, payload))) # logger.info("db %s lookup %s" % (str(self._nexthop_db), str(self._nexthop_lookup))) return
def poll(self): ret = None with self._global_lock: if self._mode != MPTN.STOP_MODE and self.last_host_id == 0: ret = 'ready to ' + self._mode[1] else: ret = "%s" % self._mode[1] if self.last_host_id != 0: tmp_node_id = self._prefix | self.last_host_id ret = ret + "\nfound node: %d (ID is %s or %d)" % ( self.last_host_id, MPTN.ID_TO_STRING(tmp_node_id), tmp_node_id) logger.info("polled. " + ret) return ret
def handle_rtping_message(self, context, dest_id, src_id, msg_type, payload): if payload is None: logger.error("RTPING should have the payload") return if dest_id != self._id: logger.error("RTPING dest_id should be me") return if not self._is_id_master(src_id): logger.error("RTPING src ID %X %s should be Master 0" % (src_id, MPTN.ID_TO_STRING(src_id))) return if payload != self._nexthop_hash: logger.debug( "RTPING got different hash %s. mine is %s. need to update routing table" % (str(map(ord, payload)), str(map(ord, self._nexthop_hash)))) message = MPTN.create_packet_to_str(MPTN.MASTER_ID, self._id, MPTN.MPTN_MSGTYPE_RTREQ, None) MPTN.socket_send(None, MPTN.MASTER_ID, message)
def handle_gwdiscover_message(self, context, dest_id, src_id, msg_type, payload): if context.direction != MPTN.ONLY_FROM_TRANSPORT_INTERFACE: logger.error("GWDISCOVER cannot be from TCP Server") return if payload is not None: logger.error("GWDISCOVER should not have the payload") return if dest_id != MPTN.MPTN_MAX_ID: logger.error("GWDISCOVER dest_id should be 0xFFFFFFFF") return if not MPTN.IS_ID_IN_NETWORK(src_id, self._network): logger.error( "GWDISCOVER src ID %X %s does not belong to the network" % (src_id, MPTN.ID_TO_STRING(src_id))) return msg_type = MPTN.MPTN_MSGTYPE_GWOFFER message = MPTN.create_packet_to_str(dest_id, self._id, msg_type, uuid.uuid4().bytes) self._transport_if_send(self._get_address_from_id(src_id), message)
import gtwconfig as CONFIG print "========================\nGateway DB info:" print "1.Nexthop DB" # _nexthop_db: key = "MPTN ID/NETMASK" STRING, value = next hop's tcp_address tuple ("IP" STRING, PORT INT) db = MPTN.DBDict("../../gateway/gtw_nexthop_table.sqlite") if len(db) == 0: print "None" for (network_string, tcp_address) in db.iteritems(): print "TCP address of ID/prefix_len:", network_string, "is", tcp_address print "\n2.Address DB" # _addr_db: key = address, value = True or False db = MPTN.DBDict("../../gateway/gtw_addr_uuid_table.sqlite") if len(db) == 0: print "None" for (address, uuid) in db.iteritems(): print "Registered address and its UUID:", MPTN.ID_TO_STRING( int(address)), map(ord, uuid) print "\n3.Settings DB" db = MPTN.DBDict("../../gateway/gtw_settings_db.sqlite") for (key, value) in db.iteritems(): print "The value of setting", key, "is", value if CONFIG.TRANSPORT_INTERFACE_TYPE == 'udp': from transport_udp import UDPDevice import pickle print "\n4.UDP Pickle File devices.pkl" try: f = open("../../gateway/devices.pkl") devices = pickle.load(f) f.close() except Exception as e:
payload_length = len(message) p = struct.pack('11B', 0xAA, 0x55, int(sys.argv[4]), address & 0xff, (address >> 8) & 0xff, (address >> 16) & 0xff, (address >> 24) & 0xff, port % 256, port / 256, 1, payload_length) p = p + message HOST = socket.gethostbyname(hardcode_ip) sock.sendto(p, (HOST, 5775)) p = sock.recv(1000) dest_id, src_id, msg_type, payload = MPTN.extract_packet_from_str(p) if msg_type == MPTN.MPTN_MSGTYPE_IDACK and src_id == MPTN.MASTER_ID: src_id = dest_id print "Your ID is %d of which dotted format is %s" % ( src_id, MPTN.ID_TO_STRING(src_id)) else: print "Cannot get an ID" elif sys.argv[3] == "sendto": dest_id = MPTN.ID_FROM_STRING(sys.argv[4]) src_id = MPTN.ID_FROM_STRING(sys.argv[5]) payload = sys.argv[6] msg_type = MPTN.MPTN_MSGTYPE_FWDREQ message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) payload_length = len(message) p = struct.pack('11B', 0xAA, 0x55, src_id & 0xff, address & 0xff, (address >> 8) & 0xff, (address >> 16) & 0xff, (address >> 24) & 0xff, port % 256, port / 256, 1, payload_length)
def refreshDeviceData(self, host_id, ip, port, t): if host_id == (self._ip & self._hostmask): return if t != 2: return found = (host_id in self._devices_lookup) if self.enterLearnMode: if not found and self._mode == MPTN.ADD_MODE: newid = 1 while True: found = False for d in self.devices: if d.host_id == newid: newid = newid + 1 if newid & self._hostmask == 0: logger.error("ID is exhausted") return found = True break else: if newid == (self._ip & self._hostmask): newid += 1 if newid & self._hostmask == 0: logger.error("ID is exhausted") return found = True if not found: newd = UDPDevice(newid, ip, port) self.devices.append(newd) self.saveDevice() self.last_host_id = newid self.stop() logger.debug("device added %s %s %s" % (str(newid), str( MPTN.ID_TO_STRING(ip)), str(port))) break elif found and self._mode == MPTN.ADD_MODE: for d in self.devices: if d.host_id == host_id: logger.debug( "device updated for %s from %s:%s to %s:%s" % (str(host_id), str(MPTN.ID_TO_STRING( d.ip)), str(d.port), str( MPTN.ID_TO_STRING(ip)), str(port))) d.ip = ip d.port = port self.saveDevice() self.last_host_id = d.host_id self.stop() break elif found and self._mode == MPTN.DEL_MODE: for i in xrange(len(self.devices)): d = self.devices[i] if d.host_id == host_id: self.send_raw(host_id, [0], raw_type=2) del self.devices[i] self.saveDevice() self.last_host_id = host_id self.stop() logger.debug("device deleted %s %s %s" % (str(host_id), str( MPTN.ID_TO_STRING(ip)), str(port))) self.last_host_id = 0 return self.send_raw(self.last_host_id, [self.last_host_id], raw_type=2) return elif found: # STOP mode for d in self.devices: if d.host_id == host_id: if d.ip == ip and d.port == port: logger.debug("device rechecked for %s %s:%s" % (str(host_id), str(MPTN.ID_TO_STRING( d.ip)), str(d.port))) self.last_host_id = 0 self.send_raw(d.host_id, [d.host_id], raw_type=2) return logger.error( "device %s (%s:%s) not allowed to change/add in STOP mode." % (str(host_id), str(MPTN.ID_TO_STRING(ip)), str(port))) return
def _init_settings_db(self, autonet_mac_addr=RANDOM_BYTES): if self._transport_if_addr_len > MPTN.MPTN_ID_LEN: logger.error( "_init_settings_db length of address (%d) is too long to support" % self._transport_if_addr_len) self._clear_settings_db() exit(-1) if self._transport_if_addr_len == 1 or self._transport_if_addr_len == 2: assert isinstance(self._transport_if_addr, int) and ( self._transport_if_addr < 2**(self._transport_if_addr_len * 8) ), "_init_settings_db ZW or ZB interface address must a integer (%s) with max %d" % ( str(self._transport_if_addr), self._transport_if_addr_len) interface = MPTN.ID_INTERFACE_FROM_TUPLE( MPTN.ID_TO_STRING(self._transport_if_addr), str((MPTN.MPTN_ID_LEN - self._transport_if_addr_len) * 8)) elif self._transport_if_addr_len == 4: assert isinstance( self._transport_if_addr, tuple ) and (len(self._transport_if_addr) == 2) and isinstance( self._transport_if_addr[0], basestring ) and isinstance( self._transport_if_addr[1], basestring ), "_init_settings_db UDP interface address must be a tuple with 2 strings ('IP', 'NETMASK') where NETMASK could be either a single number or or a string representation" interface = MPTN.ID_INTERFACE_FROM_TUPLE( self._transport_if_addr[0], self._transport_if_addr[1]) else: logger.error("_init_settings_db Unsupported interface type: %s" % CONFIG.TRANSPORT_INTERFACE_TYPE) self._clear_settings_db() exit(-1) self._transport_if_addr = int(interface.ip) self._transport_network_size = interface.network.num_addresses self._id_prefix_len = interface.network.prefixlen self._id_hostmask = int(interface.network.hostmask) if ( self._transport_if_addr_len == 2 or self._transport_if_addr_len == 1) else MPTN.MPTN_MAX_ID self._id_netmask = int(interface.network.netmask) if "GTWSELF_UNIQUE_VALUE" not in self._settings_db: if len(autonet_mac_addr) < MPTN.GWIDREQ_PAYLOAD_LEN: autonet_mac_addr = RANDOM_BYTES[0:MPTN.GWIDREQ_PAYLOAD_LEN - len(autonet_mac_addr )] + autonet_mac_addr self._settings_db["GTWSELF_UNIQUE_VALUE"] = autonet_mac_addr logger.debug("GTWSELF_UNIQUE_VALUE is %s" % str(autonet_mac_addr)) # Check whether master is online and gateway's own "MPTN ID/prefix" is valid or not self._init_get_prefix_from_master() if self._id == MPTN.MPTN_MAX_ID: logger.error( "_init_settings_db cannot initialize gateway because of no valid ID" ) self._clear_settings_db() exit(-1) try: self._nexthop_lookup.pop( "%s/%d" % (MPTN.ID_TO_STRING(self._id), self._id_prefix_len)) except Exception as e: pass return
def handle_fwdreq_message(self, context, dest_id, src_id, msg_type, payload): if payload is None: logger.error("FWDREQ should have the payload") return if not self.is_id_valid(src_id): logger.error("invalid FWDREQ src ID %X %s: not found in network" % (src_id, MPTN.ID_TO_STRING(src_id))) return if self._is_id_master(dest_id): logger.debug("FWDREQ is to master") message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) if not self._forward_to_next_hop(context, dest_id, message): logger.error("FWDREQ to master failed") return # no need to return FWDACK back via transport interface if self._is_id_gwself(dest_id): logger.debug("FWDREQ the message is to me") if context.direction == MPTN.ONLY_FROM_TRANSPORT_INTERFACE: payload = map(ord, payload) handler = self._app_handler.get(payload[0]) if handler is not None: handler(context.address, payload[1:]) gevent.sleep(0.001) else: logger.error( "FWDREQ receives invalid gateway application %d" % payload[0]) else: logger.error( "FWDREQ receives invalid message to me from Master or other gateways" ) return if self._is_id_in_gwself_network(dest_id): logger.debug("FWDREQ to transport interface directly") message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) ret = self._transport_if_send(self._get_address_from_id(dest_id), message) msg_type = MPTN.MPTN_MSGTYPE_FWDACK if not ret[0]: msg_type = MPTN.MPTN_MSGTYPE_FWDNAK logger.error("FWDREQ to transport address %X fail" % self._get_address_from_id(dest_id)) if not self._is_id_in_gwself_network(src_id): message = MPTN.create_packet_to_str(src_id, dest_id, msg_type, payload) MPTN.socket_send(context, context.id, message) return logger.debug("FWDREQ may be sent to other gateway's network") message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) if self._forward_to_next_hop(context, dest_id, message): return logger.error( "FWDREQ dest ID %X %s is neither the master, the gateway, nor within MPTN" % (dest_id, MPTN.ID_TO_STRING(dest_id))) return
def handle_idreq_message(self, context, dest_id, src_id, msg_type, payload): if not self._is_id_master(dest_id): logger.error("IDREQ dest ID should be 0 not %X (%s)" % (dest_id, MPTN.ID_TO_STRING(dest_id))) return if src_id != MPTN.MPTN_MAX_ID: logger.error("IDREQ src ID should be 0xFFFFFFFF not %X (%s)" % (dest_id, MPTN.ID_TO_STRING(dest_id))) return if payload is None or len(payload) != MPTN.IDREQ_PAYLOAD_LEN: logger.error("IDREQ length of payload %d should be %d" % (len(payload), MPTN.IDREQ_PAYLOAD_LEN)) return uuid = payload try: temp_addr = int(context.address) except Exception as e: logger.error( "IDREQ cannot turn interface address %s into integer" % str(context.address)) exit(-1) if self._transport_if_addr_len == 1 or self._transport_if_addr_len == 2: temp_id = self._id_prefix | temp_addr elif self._transport_if_addr_len == 4: temp_id = temp_addr dest_id = self._id src_id = temp_id # New addresss from transport interface if not self.is_addr_valid(temp_addr): if CONFIG.UNITTEST_MODE: message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, uuid) self._id_req_queue.put_nowait(message) dest_id = temp_id src_id = MPTN.MASTER_ID msg_type = MPTN.MPTN_MSGTYPE_IDACK message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, uuid) self._transport_if_send(temp_addr, message) return else: message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, uuid) packet = MPTN.socket_send(context, MPTN.MASTER_ID, message, expect_reply=True) if packet is None: logger.error( "IDREQ cannot be confirmed ID=%d (%s) Addr=%d" % (temp_id, MPTN.ID_TO_STRING(temp_id), temp_addr)) return dest_id, src_id, msg_type, payload = packet if dest_id != temp_id or src_id != MPTN.MASTER_ID or ( msg_type not in [ MPTN.MPTN_MSGTYPE_IDACK, MPTN.MPTN_MSGTYPE_IDNAK ]): logger.error( "IDREQ invalid response for dest ID=%X (%s), src ID=%X (%s), msg_type=%X" % (dest_id, MPTN.ID_TO_STRING(dest_id), src_id, MPTN.ID_TO_STRING(src_id), msg_type)) return if msg_type == MPTN.MPTN_MSGTYPE_IDNAK: logger.error("IDREQ for %X (%s) is refused by Master" % (temp_id, MPTN.ID_TO_STRING(temp_id))) return self._alloc_address(temp_addr, uuid) message = MPTN.create_packet_to_str(dest_id, src_id, MPTN.MPTN_MSGTYPE_IDACK, None) self._transport_if_send(temp_addr, message) return # Known address to check uuid elif True: #self._addr_db[temp_addr] == payload: dest_id = temp_id message = MPTN.create_packet_to_str(dest_id, MPTN.MASTER_ID, MPTN.MPTN_MSGTYPE_IDACK, None) self._transport_if_send(temp_addr, message) return else: logger.error( "IDREQ comes with a valid addr=%d, ID=%d or %s, but an unknown uuid %s" % (temp_addr, temp_id, MPTN.ID_TO_STRING(temp_id), str(map(ord, uuid))))
import sys, os tools = os.path.join(os.path.dirname(__file__), "..") wukong = os.path.join(tools, "..") master = os.path.join(wukong, "master") sys.path.append(os.path.abspath(master)) wkpf = os.path.join(master, "wkpf") sys.path.append(os.path.abspath(wkpf)) # print sys.path import mptnUtils as MPTN to_del_node_id = sys.argv[1] print "\n\n***************************************************" print "Going to remove node with %s (%d)" % (MPTN.ID_TO_STRING( MPTN.ID_FROM_STRING(to_del_node_id)), MPTN.ID_FROM_STRING(to_del_node_id)) to_del_node_id = MPTN.ID_FROM_STRING(to_del_node_id) is_id_gateway = False print "***************************************************\n" print "\n\n========================\nMaster DB info:\n========================" print "\n1.Gateway DB" db = MPTN.DBDict( os.path.join(os.path.abspath(master), "master_gateway_info.sqlite")) if len(db) == 0: print "None" else: if to_del_node_id in db: is_id_gateway = True del db[to_del_node_id] # Gateway(id=167772166, tcp_address=('127.0.0.1', 9001), if_address=167772166, if_address_len=4, prefix=167772160, prefix_len=24, # network=IPv4Network('10.0.0.0/24'), network_size=256, netmask=4294967040, hostmask=255, # uuid='\xe5\xa8\xc3\xc6\xa8\xcdB;\x86\xfb\xc5O\\x\xad\xd4')
sys.path.append(os.path.abspath(master)) wkpf = os.path.join(master, "wkpf") sys.path.append(os.path.abspath(wkpf)) # print sys.path import mptnUtils as MPTN print "========================\nMaster DB info:" print "\n1.Gateway DB" db = MPTN.DBDict("../../master/master_gateway_info.sqlite") if len(db) == 0: print "None" # Gateway(id=167772166, tcp_address=('127.0.0.1', 9001), if_address=167772166, if_address_len=4, prefix=167772160, prefix_len=24, # network=IPv4Network('10.0.0.0/24'), network_size=256, netmask=4294967040, hostmask=255, # uuid='\xe5\xa8\xc3\xc6\xa8\xcdB;\x86\xfb\xc5O\\x\xad\xd4') for (gateway_id, gateway) in db.iteritems(): print "Gateway ID:", MPTN.ID_TO_STRING( int(gateway_id) ), "IF_ADDR:", MPTN.ID_TO_STRING( gateway.if_address ), "IF_ADDR_LEN:", gateway.if_address_len, "PREFIX:", MPTN.ID_TO_STRING( gateway.prefix ), "PREFIX_LEN:", gateway.prefix_len, "NETWORK:", str( gateway.network ), "NETWORK_SIZE:", gateway.network_size, "NETMASK:", MPTN.ID_TO_STRING( gateway.netmask), "HOSTMASK:", MPTN.ID_TO_STRING( gateway.hostmask), "UUID:", map( ord, gateway.uuid), "TCP_ADDRESS", str(gateway.tcp_address) print "\n2.Node DB" db = MPTN.DBDict("../../master/master_node_info.sqlite") if len(db) == 0: print "None" for (node_id, node) in db.iteritems():
class WKPF(DatagramProtocol): GET_WUCLASS_LIST = 0x90 GET_WUCLASS_LIST_R = 0x91 GET_WUOBJECT_LIST = 0x92 GET_WUOBJECT_LIST_R = 0x93 READ_PROPERTY = 0x94 READ_PROPERTY_R = 0x95 WRITE_PROPERTY = 0x96 WRITE_PROPERTY_R = 0x97 REQUEST_PROPERTY_INIT = 0x98 REQUEST_PROPERTY_INIT_R = 0x99 GET_LOCATION = 0x9A GET_LOCATION_R = 0x9B SET_LOCATION = 0x9C SET_LOCATION_R = 0x9D GET_FEATURES = 0x9E GET_FEATURES_R = 0x9F SET_FEATURE = 0xA0 SET_FEATURE_R = 0xA1 CHANGE_MAP = 0xA2 CHANGE_MAP_R = 0xA3 CHANGE_LINK = 0xA4 CHANGE_LINK_R = 0xA5 ERROR_R = 0xAF REPROG_OPEN = 0x10 REPROG_OPEN_R = 0x11 REPROG_WRITE = 0x12 REPROG_WRITE_R = 0x13 REPROG_COMMIT = 0x14 REPROG_COMMIT_R = 0x15 REPROG_REBOOT = 0x16 REPROG_REBOOT_R = 0x17 WKREPROG_OK = 0 WKREPROG_REQUEST_RETRANSMIT = 1 WKREPROG_TOOLARGE = 2 WKREPROG_FAILED = 3 LIB_INFUSION = 0 APP_INFUSION = 1 LINK_TABLE = 2 COMPONENT_MAP = 3 INITVALUES_TABLE = 4 DATATYPE_SHORT = 0 DATATYPE_BOOLEAN = 1 DATATYPE_REFRESH = 2 DATATYPE_ARRAY = 3 DATATYPE_STRING = 4 DATATYPE_ThresholdOperator = 10 DATATYPE_LogicalOperator = 11 DATATYPE_MathOperator = 12 DATATYPE_Pin = 13 WK_PROPERTY_ACCESS_READONLY = 1<<7 WK_PROPERTY_ACCESS_WRITEONLY = 1<<6 WK_PROPERTY_ACCESS_READWRITE = (WK_PROPERTY_ACCESS_READONLY+WK_PROPERTY_ACCESS_WRITEONLY) WKCOMM_MESSAGE_PAYLOAD_SIZE=40 OBJECTS_IN_MESSAGE = (WKCOMM_MESSAGE_PAYLOAD_SIZE-3)/4 def __init__(self,dev,host,port,gtwaddr): self.host = host self.port = port self.device = dev self._reactor = reactor self.gtwaddr = gtwaddr self.mptnaddr = 0 self.nodeid=0 self.location = 'Default' self.properties= [] for i in range(0,100): self.properties.append([]) self.tablebin=[] self.components=[] self.links=[] self.seq = 1000 for i in range(0,4096): self.tablebin.append(0) self.load() self.init() def init(self): reactor.listenUDP(self.port, self) reactor.callWhenRunning(self.doInit) def load(self): try: f=open('udpwkpf-%d.json' % self.port) o = cjson.decode(f.read()) # print o self.location = o['location'] self.uuid = o['uuid'] self.nodeid = o['nodeid'] self.components=o['components'] self.links=o['links'] self.mptnaddr = o['mptnaddr'] try: self.properties = o['props'] except: pass f.close() except: self.uuid = map(ord,str(uuid.uuid4().bytes)) self.save() return if o.has_key('uuid') == False: self.uuid = map(ord,str(uuid.uuid4().bytes)) self.save() def save(self): try: o = {'location': self.location,'uuid':self.uuid,'nodeid':self.nodeid,'components':self.components, 'links':self.links,'mptnaddr':self.mptnaddr,'props':self.properties} f = open('udpwkpf-%d.json' % self.port,'w') f.write(cjson.encode(o)) f.close() except: traceback.print_exc() pass def doInit(self): payload_length = 0 p = struct.pack('11B', 0xAA,0x55,self.nodeid,self.host&0xff,(self.host>>8)&0xff,(self.host>>16)&0xff,(self.host>>24)&0xff,self.port%256,self.port/256,2,payload_length) self.transport.write(p,(self.gtwaddr,MPTN.MPTN_UDP_PORT)) self.state = 'WAITID' def requestID(self): dest_id = MPTN.MASTER_ID src_id = 0xffffffff msg_type = MPTN.MPTN_MSGTYPE_IDREQ message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, ''.join(map(chr,self.uuid))) payload_length = len(message) address = self.host port = self.port p = struct.pack('11B', 0xAA,0x55,self.nodeid,address&0xff,(address>>8)&0xff,(address>>16)&0xff,(address>>24)&0xff,port%256,port/256,1,payload_length) p = p+message self.transport.write(p,(self.gtwaddr,MPTN.MPTN_UDP_PORT)) self.state = 'WAITADDR' def datagramReceived(self, data, (host, port)): s = '' for d in data: s = s + '%02x '% ord(d) # print self.state,s if self.state == 'WAITID': if ord(data[0]) == 0xAA and ord(data[1]) == 0x55: self.nodeid = ord(data[2]) self.save() # print 'get node id', self.nodeid self.send(0,'AAAA') self.state = 'INIT' self.requestID() elif self.state == 'WAITRSP': self.state = 'INIT' pass elif self.state == 'WAITADDR': dest_id, src_id, msg_type, payload = MPTN.extract_packet_from_str(data[11:]) if msg_type == MPTN.MPTN_MSGTYPE_IDACK and src_id == MPTN.MASTER_ID: src_id = dest_id print "Your ID is %d of which dotted format is %s" % (src_id, MPTN.ID_TO_STRING(src_id)) self.state = 'INIT' elif self.state == 'INIT': dest_id, src_id, msg_type, payload = MPTN.extract_packet_from_str(data[11:]) #print dest_id,src_id,msg_type, map(ord, payload) #payload info if self.mptnaddr == 0: self.mptnaddr = dest_id self.save() if msg_type == 24: msg_id = ord(data[20]) seq = ord(data[21])+ord(data[22])*256 self.parseWKPF(src_id,msg_id,seq,data[23:])
def _init_get_prefix_from_master(self): if "GTWSELF_ID" not in self._settings_db: self._settings_db["GTWSELF_ID"] = MPTN.MPTN_MAX_ID self._id = self._settings_db["GTWSELF_ID"] MPTN.set_self_id(self._id) if self._id != MPTN.MPTN_MAX_ID: self._network = MPTN.ID_NETWORK_FROM_TUPLE( MPTN.ID_TO_STRING(self._id), str(self._id_prefix_len)) self._id_prefix = self._id & self._id_netmask dest_id = MPTN.MASTER_ID src_id = self._id msg_type = MPTN.MPTN_MSGTYPE_GWIDREQ payload = json.dumps({ "IFADDR": self._transport_if_addr, "IFADDRLEN": self._transport_if_addr_len, "IFNETMASK": self._id_netmask, "PORT": CONFIG.SELF_TCP_SERVER_PORT, "UUID": self._settings_db["GTWSELF_UNIQUE_VALUE"] }) # payload = "IFADDR=%d;IFADDRLEN=%d;IFNETMASK=%d;PORT=%d;VAL=%s" % (self._transport_if_addr, # self._transport_if_addr_len, self._id_netmask, CONFIG.SELF_TCP_SERVER_PORT, # struct.pack("!%dB"%MPTN.GWIDREQ_PAYLOAD_LEN, *self._settings_db["GTWSELF_UNIQUE_VALUE"])) message = MPTN.create_packet_to_str(dest_id, src_id, msg_type, payload) packet = MPTN.socket_send(None, MPTN.MASTER_ID, message, expect_reply=True) if packet is None: logger.error( "GWIDREQ cannot get GWIDACK/NAK from master due to network problem" ) return None # log_msg = MPTN.formatted_print(MPTN.split_packet_to_list(message)) dest_id, src_id, msg_type, payload = packet if msg_type == MPTN.MPTN_MSGTYPE_GWIDNAK: logger.error("GWIDREQ GWIDREQ is refused by master") return None elif msg_type != MPTN.MPTN_MSGTYPE_GWIDACK: logger.error( "GWIDREQ get unexpected msg type (%d) instead of GWIDACK/NAK from master" % msg_type) return None elif dest_id != self._id: if self._id == MPTN.MPTN_MAX_ID: self._settings_db["GTWSELF_ID"] = dest_id self._id = dest_id MPTN.set_self_id(self._id) self._network = MPTN.ID_NETWORK_FROM_TUPLE( MPTN.ID_TO_STRING(self._id), str(self._id_prefix_len)) self._id_prefix = dest_id & self._id_netmask logger.info( "GWIDREQ successfully get new ID %s including prefix" % MPTN.ID_TO_STRING(dest_id)) else: logger.error( "GWIDREQ get an ID %d %s different from old one %d %s" % (dest_id, MPTN.ID_TO_STRING(dest_id), self._id, MPTN.ID_TO_STRING(self._id))) exit(-1) else: logger.info("GWIDREQ successfully check the ID %s with master" % MPTN.ID_TO_STRING(dest_id))