示例#1
0
文件: addp.py 项目: posborne/cp4pc
    def addp_conf_req(self, frame, address, local_ip, local_mac):
        addp_ver = 0x0100  # ADDPv1, may be overwritten in command
        mac_addr = frame.payload[:6]
        # check if mac_addr matches ours or is equal to broadcast MAC
        if mac_addr != "\xff\xff\xff\xff\xff\xff" and mac_addr != local_mac:
            logger.debug("Message has wrong address.")
            return None
        index = 6
        logger.info("Received 'Configuration' request from: %s" % str(address))
        # pull out any OP commands in frame
        while len(frame.payload) > index + 2:
            op_code, length = struct.unpack(">BB", frame.payload[index,
                                                                 index + 2])
            index += 2
            if op_code == ADDP_OP_VERSION:
                addp_ver, = struct.unpack(">H", frame.payload[index:index + 2])
                index += 2
            else:
                # unsupported OP code
                index += length

        # Create response
        response = ADDP_Frame(ADDP_CMD_CONF_REPLY)

        # add MAC address
        response.payload += struct.pack(">BB", ADDP_OP_MAC, 6)
        response.payload += self.mac
        # add IP address, submask, and gateway IP
        response.payload += struct.pack(">BBI", ADDP_OP_IPADDR, 4, local_ip)
        #NOTE: add more parameters to response (Python netifaces module would work well for this).
        #response.payload += struct.pack(">BBI", ADDP_OP_SUBMASK, 4, 0x00000000)
        #response.payload += struct.pack(">BBI", ADDP_OP_GATEWAY, 4, 0x00000000)
        # add DNS servers
        #response.payload += struct.pack(">BBI", ADDP_OP_DNS, 4, 0x00000000)
        #response.payload += struct.pack(">BBI", ADDP_OP_DNS, 4, 0x00000000)
        # add DHCP settings (DHCP server or 0)
        #response.payload += struct.pack(">BBI", ADDP_OP_DHCP, 4, 0x00000000)
        # add device name
        device_name = settings.get('device_name', '')
        response.payload += struct.pack(">BB", ADDP_OP_NAME, len(device_name))
        response.payload += device_name
        # add hardware name
        device_type = settings.get('device_type')
        response.payload += struct.pack(">BB", ADDP_OP_HWNAME,
                                        len(device_type))
        response.payload += device_type

        if addp_ver == 0x0100:
            # add version
            # get the time of when the program was started
            (year, mon, mday, hour, min, sec, wday, yday,
             isdst) = time.gmtime(time.time() - time.clock())
            version = "Version %s %d/%02d/%d" % (settings.get(
                'version', '0.0.0'), mon, mday, year)
            response.payload += struct.pack(">BB", ADDP_OP_FEPREV,
                                            len(version))
            response.payload += version

        return response
示例#2
0
文件: addp.py 项目: EdCornejo/cp4pc
    def addp_conf_req(self, frame, address, local_ip, local_mac):
        addp_ver = 0x0100 # ADDPv1, may be overwritten in command
        mac_addr = frame.payload[:6]
        # check if mac_addr matches ours or is equal to broadcast MAC
        if mac_addr != "\xff\xff\xff\xff\xff\xff" and mac_addr != local_mac:
            logger.debug("Message has wrong address.")
            return None
        index = 6
        logger.info("Received 'Configuration' request from: %s" % str(address))
        # pull out any OP commands in frame
        while len(frame.payload) > index + 2:
            op_code, length = struct.unpack(">BB", frame.payload[index, index + 2])
            index += 2
            if op_code == ADDP_OP_VERSION:
                addp_ver, = struct.unpack(">H", frame.payload[index: index + 2])
                index += 2
            else:
                # unsupported OP code
                index += length

        # Create response
        response = ADDP_Frame(ADDP_CMD_CONF_REPLY)

        # add MAC address
        response.payload += struct.pack(">BB", ADDP_OP_MAC, 6)
        response.payload += self.mac
        # add IP address, submask, and gateway IP
        response.payload += struct.pack(">BBI", ADDP_OP_IPADDR, 4, local_ip)
        #NOTE: add more parameters to response (Python netifaces module would work well for this).
        #response.payload += struct.pack(">BBI", ADDP_OP_SUBMASK, 4, 0x00000000)
        #response.payload += struct.pack(">BBI", ADDP_OP_GATEWAY, 4, 0x00000000)
        # add DNS servers
        #response.payload += struct.pack(">BBI", ADDP_OP_DNS, 4, 0x00000000)
        #response.payload += struct.pack(">BBI", ADDP_OP_DNS, 4, 0x00000000)
        # add DHCP settings (DHCP server or 0)
        #response.payload += struct.pack(">BBI", ADDP_OP_DHCP, 4, 0x00000000)
        # add device name
        device_name = settings.get('device_name', '')
        response.payload += struct.pack(">BB", ADDP_OP_NAME, len(device_name))
        response.payload += device_name
        # add hardware name
        device_type = settings.get('device_type')
        response.payload += struct.pack(">BB", ADDP_OP_HWNAME, len(device_type))
        response.payload += device_type

        if addp_ver == 0x0100:
            # add version
            # get the time of when the program was started
            (year, mon, mday, hour, min, sec, wday, yday, isdst) = time.gmtime(time.time() - time.clock())
            version = "Version %s %d/%02d/%d" % (settings.get('version', '0.0.0'), mon, mday, year)
            response.payload += struct.pack(">BB", ADDP_OP_FEPREV, len(version))
            response.payload += version

        return response
示例#3
0
 def run(self):
     while(1):
         #NOTE: we take no action if the local port is changed dynamically
         local_port = settings.get('local_port')
         if not local_port:
             time.sleep(1)
             continue
         logger.info("Starting web server at http://localhost:%d" % local_port)
         make_server('', local_port, self, handler_class=RCIWSGIRequestHandler).serve_forever()
示例#4
0
 def run(self):
     while (1):
         #NOTE: we take no action if the local port is changed dynamically
         local_port = settings.get('local_port')
         if not local_port:
             time.sleep(1)
             continue
         logger.info("Starting web server at http://localhost:%d" %
                     local_port)
         make_server('',
                     local_port,
                     self,
                     handler_class=RCIWSGIRequestHandler).serve_forever()
示例#5
0
文件: settings.py 项目: nkhoa123/XIG
 def __call__(self, request):
     if request.method == 'GET':
         key = request.GET.get('key')
         if key:
             notify = request.GET.get('notify')
             if notify is not None:
                 if notify and notify not in self.callbacks:
                     # add a notify callback
                     callback = lambda new_value, old_value, key=key: self.callback(
                         key, new_value, old_value)
                     settings.add_callback(key, callback)
                     self.callbacks[key] = callback
                 elif not notify and notify in self.callbacks:
                     # remove callback
                     settings.remove_callback(key, self.callbacks[key])
                     del self.callbacks[key]
             # return the value of a setting
             value = str(settings.get(key, ''))
             return webob.Response(json.dumps(value), content_type='json')
         else:
             # return all of the keys
             return webob.Response(json.dumps(settings),
                                   content_type='json')
     if request.method == 'POST':
         # set a value
         key = request.POST.get('key')
         if key:
             value = request.POST.get('value')
             # remove the setting if no value is given
             if value is None or value == 'undefined':
                 settings.pop(key, None)
             # figure out if the value is an int
             try:
                 value = int(value)
             except:
                 try:
                     value = float(value)
                 except:
                     pass
             # set the value
             settings[key] = value
             return  #success
     else:
         return webob.exc.HTTPMethodNotAllowed()
示例#6
0
文件: settings.py 项目: Rahuldee/XIG
 def __call__(self, request):
     if request.method == 'GET':
         key = request.GET.get('key')
         if key:
             notify = request.GET.get('notify')
             if notify is not None:
                 if notify and notify not in self.callbacks:
                     # add a notify callback
                     callback = lambda new_value, old_value, key=key: self.callback(key, new_value, old_value)
                     settings.add_callback(key, callback)
                     self.callbacks[key] = callback
                 elif not notify and notify in self.callbacks:
                     # remove callback
                     settings.remove_callback(key, self.callbacks[key])
                     del self.callbacks[key]
             # return the value of a setting
             value = str(settings.get(key, ''))
             return webob.Response(json.dumps(value), content_type='json')
         else:
             # return all of the keys
             return webob.Response(json.dumps(settings), content_type='json')
     if request.method == 'POST':
         # set a value
         key = request.POST.get('key')
         if key:
             value = request.POST.get('value')
             # remove the setting if no value is given
             if value is None or value == 'undefined':
                 settings.pop(key, None)
             # figure out if the value is an int
             try:
                 value = int(value)
             except:
                 try:
                     value = float(value)
                 except:
                     pass
             # set the value
             settings[key] = value
             return #success
     else:
         return webob.exc.HTTPMethodNotAllowed()
示例#7
0
文件: edp.py 项目: digidotcom/cp4pc
    def handle_msg(self, msg):
        """self.msg_type is current message type, msg contains the message."""        
        # reset server KA timer
        self.tx_ka = time.time() + self.tx_intvl

        if self.msg_type != EDP_KEEPALIVE:
            logger.debug("received message type=0x%04X len=%u" % (self.msg_type, len(msg))) #TODO: decode type

        if self.msg_type == EDP_PAYLOAD:
            if self.phase == self.PHASE_WAIT_VERS_OK:
                
                if len(msg) != 1 or ord(msg[0]):
                    logger.error("bad version - code %d (msg len %d) waiting for inner vers OK" % (ord(msg[0]), len(msg)))
                    self._handle_error("Bad version")
                else:
                    # Success, proceed to security
                    self.phase = self.PHASE_SECURING
                    
                    # We're using simple identification here...
                    self.send_msg(EDP_PAYLOAD, "\x80\x00")
                    payload = "\x81" # Device ID
                    payload += self._device_id_str(settings['device_id'])
                    self.send_msg(EDP_PAYLOAD, payload)

                    # Connection URI
                    if self.red_uri is not None:
                        conn_uri = self.red_uri
                    else:
                        conn_uri = self.uri
                    payload = struct.pack("!BH", 0x86, len(conn_uri))
                    payload += conn_uri
                    self.send_msg(EDP_PAYLOAD, payload)
                    

                    # Simple form does not require waiting for any response,
                    # so proceed to discovery...
                    self.phase = self.PHASE_DISCOVERY
                    payload = "\x00" # Security layer payload
                    
                    if settings.get('vendor_id'):
                        # Send Vendor ID (needs to be done before type)
                        payload = "\x06"
                        payload += struct.pack("!I", settings['vendor_id'])
                        self.send_msg(EDP_PAYLOAD, payload)
                    
                    payload += "\x04" # Device type discovery message
                    payload += struct.pack("!H", len(settings['device_type']))
                    payload += settings['device_type']
                    self.send_msg(EDP_PAYLOAD, payload)

                    # Initialization: send a few odd messages
                    if self.red_uri is not None:
                        payload = "\x04\x01\x0DRedirected OK" # Redirected OK
                        payload += struct.pack("!H", len(self.uri))
                        payload += self.uri
                        self.send_fac(EDP_FACILITY_CONN_CONTROL, payload)
                    else:
                        payload = "\x04\x00\x00\x00\x00" # Not redirected
                        self.send_fac(EDP_FACILITY_CONN_CONTROL, payload)

                    # Connection report
                    payload = "\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
                    # append IP
                    IP_list = [int(num) for num in socket.gethostbyname(socket.gethostname()).split(".")]
                    payload += struct.pack("!BBBBB", IP_list[0], IP_list[1], IP_list[2], IP_list[3], 0x01)
                    payload += struct.pack("!Q", settings['mac'])[-6:]
                    self.send_fac(EDP_FACILITY_CONN_CONTROL, payload)
                    
                    # Announce RCI compression.
                    #self.send_fac(EDP_FACILITY_RCI, "\xB0\x01\x01\xFF") #ZLIB, reply
                    self.send_fac(EDP_FACILITY_RCI, "\xB0\x00\x00") # None, no reply

                    # Done init
                    self.send_msg(EDP_PAYLOAD, "\x00\x05")
                    self.phase = self.PHASE_FACILITY
            
            
            elif self.phase == self.PHASE_SECURING:
                self.phase = self.PHASE_FACILITY    
            elif self.phase == self.PHASE_DISCOVERY:
                self.phase = self.PHASE_FACILITY    
            elif self.phase == self.PHASE_FACILITY: 
                if len(msg) < 5:
                    logger.error("bad message length %u" % len(msg))
                    self._handle_error()
                
                fac = struct.unpack("!H", msg[2:4])[0]
                if fac == EDP_FACILITY_CLIENT_LOOPBACK:
                    self.send_msg(EDP_PAYLOAD, msg)
                elif fac == EDP_FACILITY_CONN_CONTROL:
                    opcode = ord(msg[4])
                    if opcode == 0x00: # disconnect (server has nothing to send)
                        logger.warning("got disconnect request - ignoring for now")
                        # We should theoretically close, but server seems to
                        # send this even though we have successfully started
                        # and should not close.  Just ignore it for now, until
                        # situation is clarified.
                        #self.close(1)
                        #time.sleep(RECONNECT_TIME) # give a few seconds before trying to reconnect...
                    elif opcode == 0x03: # redirect
                        # Ignore the URL count.  Just use the 1st URL, since
                        # we have a nameserver.
                        urllen = struct.unpack("!H", msg[6:8])[0]                
                        if len(msg) < 13 or ord(msg[5]) < 1 or urllen+8 > len(msg):
                            logger.error("Redirect error - no URL provided, or bad URL length")
                            self._handle_error("Redirect Error")
                        else:
                            self.red_uri = msg[8:8+urllen]
                            self.close(2) #close and redirect
                elif fac == EDP_FACILITY_RCI:
                    self.handle_rci(msg[4:])
                else:
                    handler = self.fac.get(fac)
                    if handler is None:
                        logger.warning("got unhandled facility code 0x%04X" % fac)
                    else:
                        handler(msg[4:])
                
        elif self.msg_type == EDP_VERSION_OK:
            if self.phase == self.PHASE_INIT:
                #Send inner versioning info
                self.send_msg(EDP_PAYLOAD, "\x00\x00\x01\x20")
                self.phase = self.PHASE_WAIT_VERS_OK
        elif self.msg_type == EDP_VERSION_BAD:
            logger.error("server error - bad version")
            self._handle_error()            
        elif self.msg_type == EDP_SERVER_OVERLOAD:
            logger.warning("server error - overloaded")
            self._handle_error()
        else:
            # Ignore anything unknown.  (This also handles keepalives)
            if self.msg_type != EDP_KEEPALIVE:
                logger.warning("unexpected message type 0x%04X" % self.msg_type)

        return 0
示例#8
0
文件: edp.py 项目: ayoungpe/cp4pc
    def handle_msg(self, msg):
        """self.msg_type is current message type, msg contains the message."""
        # reset server KA timer
        self.tx_ka = time.time() + self.tx_intvl

        if self.msg_type != EDP_KEEPALIVE:
            logger.debug("received message type=0x%04X len=%u" %
                         (self.msg_type, len(msg)))  #TODO: decode type

        if self.msg_type == EDP_PAYLOAD:
            if self.phase == self.PHASE_WAIT_VERS_OK:

                if len(msg) != 1 or ord(msg[0]):
                    logger.error(
                        "bad version - code %d (msg len %d) waiting for inner vers OK"
                        % (ord(msg[0]), len(msg)))
                    self._handle_error("Bad version")
                else:
                    # Success, proceed to security
                    self.phase = self.PHASE_SECURING

                    # We're using simple identification here...
                    self.send_msg(EDP_PAYLOAD, "\x80\x00")
                    payload = "\x81"  # Device ID
                    payload += self._device_id_str(settings['device_id'])
                    self.send_msg(EDP_PAYLOAD, payload)

                    # Connection URI
                    if self.red_uri is not None:
                        conn_uri = self.red_uri
                    else:
                        conn_uri = self.uri
                    payload = struct.pack("!BH", 0x86, len(conn_uri))
                    payload += conn_uri
                    self.send_msg(EDP_PAYLOAD, payload)

                    # Simple form does not require waiting for any response,
                    # so proceed to discovery...
                    self.phase = self.PHASE_DISCOVERY
                    payload = "\x00"  # Security layer payload

                    if settings.get('vendor_id'):
                        # Send Vendor ID (needs to be done before type)
                        payload = "\x06"
                        payload += struct.pack("!I", settings['vendor_id'])
                        self.send_msg(EDP_PAYLOAD, payload)

                    payload += "\x04"  # Device type discovery message
                    payload += struct.pack("!H", len(settings['device_type']))
                    payload += settings['device_type']
                    self.send_msg(EDP_PAYLOAD, payload)

                    # Initialization: send a few odd messages
                    if self.red_uri is not None:
                        payload = "\x04\x01\x0DRedirected OK"  # Redirected OK
                        payload += struct.pack("!H", len(self.uri))
                        payload += self.uri
                        self.send_fac(EDP_FACILITY_CONN_CONTROL, payload)
                    else:
                        payload = "\x04\x00\x00\x00\x00"  # Not redirected
                        self.send_fac(EDP_FACILITY_CONN_CONTROL, payload)

                    # Connection report
                    payload = "\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
                    # append IP
                    try:
                        IP_list = [
                            int(num) for num in socket.gethostbyname(
                                socket.gethostname()).split(".")
                        ]
                    except socket.gaierror:
                        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                        s.connect(("my.idigi.com", self.PORT))
                        IP_list = s.getsockname()[0].split(".")
                        del (s)
                    payload += struct.pack("!BBBBB", IP_list[0], IP_list[1],
                                           IP_list[2], IP_list[3], 0x01)
                    payload += struct.pack("!Q", settings['mac'])[-6:]
                    self.send_fac(EDP_FACILITY_CONN_CONTROL, payload)

                    if settings.get('firmware_version'):
                        try:
                            payload = struct.pack("!B", 0x00)
                            payload += struct.pack(
                                "!BI", 0, settings['firmware_version'])
                            self.send_fac(EDP_FACILITY_FIRMWARE, payload)
                        except (TypeError, ValueError, struct.error), e:
                            logger.error(
                                "bad firmware version: %s\terror: %s" %
                                (settings['firmware_version'], str(e)))

                    # Announce RCI compression.
                    #self.send_fac(EDP_FACILITY_RCI, "\xB0\x01\x01\xFF") #ZLIB, reply
                    self.send_fac(EDP_FACILITY_RCI,
                                  "\xB0\x00\x00")  # None, no reply

                    # Done init
                    self.send_msg(EDP_PAYLOAD, "\x00\x05")
                    self.phase = self.PHASE_FACILITY

            elif self.phase == self.PHASE_SECURING:
                self.phase = self.PHASE_FACILITY
            elif self.phase == self.PHASE_DISCOVERY:
                self.phase = self.PHASE_FACILITY
            elif self.phase == self.PHASE_FACILITY:
                if len(msg) < 5:
                    logger.error("bad message length %u" % len(msg))
                    self._handle_error()

                fac = struct.unpack("!H", msg[2:4])[0]
                if fac == EDP_FACILITY_CLIENT_LOOPBACK:
                    self.send_msg(EDP_PAYLOAD, msg)
                elif fac == EDP_FACILITY_CONN_CONTROL:
                    opcode = ord(msg[4])
                    if opcode == 0x00:  # disconnect (server has nothing to send)
                        logger.warning(
                            "got disconnect request - ignoring for now")
                        # We should theoretically close, but server seems to
                        # send this even though we have successfully started
                        # and should not close.  Just ignore it for now, until
                        # situation is clarified.
                        #self.close(1)
                        #time.sleep(RECONNECT_TIME) # give a few seconds before trying to reconnect...
                    elif opcode == 0x03:  # redirect
                        # Ignore the URL count.  Just use the 1st URL, since
                        # we have a nameserver.
                        urllen = struct.unpack("!H", msg[6:8])[0]
                        if len(msg) < 13 or ord(
                                msg[5]) < 1 or urllen + 8 > len(msg):
                            logger.error(
                                "Redirect error - no URL provided, or bad URL length"
                            )
                            self._handle_error("Redirect Error")
                        else:
                            self.red_uri = msg[8:8 + urllen]
                            self.close(2)  #close and redirect
                elif fac == EDP_FACILITY_RCI:
                    self.handle_rci(msg[4:])
                else:
                    handler = self.fac.get(fac)
                    if handler is None:
                        logger.warning("got unhandled facility code 0x%04X" %
                                       fac)
                    else:
                        handler(msg[4:])
示例#9
0
def create_accessor(name, default=''):
    return lambda: str(settings.get(name, default)
                       )  #make sure return value is string
示例#10
0
http_server = HTTPHandler()
http_server.start()

# Create RCI tree that responds to RCI requests
rci_tree = DeviceRoot()
#-- RCI Descriptor --#
rci_tree.attach(RciDescriptor(rci_tree))
#-- RCI STATE --#
rci_tree.attach(RciState().attach(
    BranchNode('device_info', 'Device Information').attach(
        SimpleLeafNode(
            'mac',
            dtype=DTYPE.MAC_ADDR,
            desc="MAC Address",
            accessor=lambda: ":".join("%02X" % (
                (settings.get('mac', 0) >>
                 (i * 8)) & 0xFF) for i in xrange(6)))).attach(
                     SimpleLeafNode(
                         'product',
                         dtype=DTYPE.STRING,
                         desc="product",
                         accessor=create_accessor('device_type'))).attach(
                             SimpleLeafNode(
                                 'company',
                                 dtype=DTYPE.STRING,
                                 desc="company",
                                 accessor=create_accessor('company'))).attach(
                                     SimpleLeafNode(
                                         'os_name',
                                         dtype=DTYPE.STRING,
                                         desc="Name of host operating system",
示例#11
0
def create_accessor(name, default=''):
    return lambda: str(settings.get(name, default)) #make sure return value is string
示例#12
0
#NOTE: code will only run on first import - Python only imports files once
# start HTTP server thread for processing RCI requests
http_server = HTTPHandler()
http_server.start()

# Create RCI tree that responds to RCI requests
rci_tree = DeviceRoot()
#-- RCI Descriptor --#
rci_tree.attach(RciDescriptor(rci_tree))
#-- RCI STATE --#
rci_tree.attach(RciState()
    .attach(BranchNode('device_info', 'Device Information')
        .attach(SimpleLeafNode('mac', dtype=DTYPE.MAC_ADDR,
                                desc="MAC Address",
                                accessor=lambda: ":".join("%02X" % ((settings.get('mac', 0) >> (i*8)) & 0xFF) for i in xrange(6))))
        .attach(SimpleLeafNode('product', dtype=DTYPE.STRING,
                                desc="product",
                                accessor=create_accessor('device_type')))
        .attach(SimpleLeafNode('company', dtype=DTYPE.STRING,
                               desc="company",
                               accessor=create_accessor('company')))
        .attach(SimpleLeafNode('os_name', dtype=DTYPE.STRING,
                               desc="Name of host operating system",
                               accessor=lambda: sys.platform))
    )
    .attach(BranchNode('boot_stats', 'Primary interface')
        .attach(SimpleLeafNode('ip', dtype=DTYPE.IPV4, desc='IP Address', accessor=create_accessor('ip_address', '0.0.0.0')))
    )
    .attach(BranchNode('zigbee_state', 'Gateway XBee')
        .attach(SimpleLeafNode('gateway_addr', dtype=DTYPE.XBEE_EXT_ADDR, desc='XBee extended address', accessor=lambda: ':'.join("%02x" % ord(x) for x in xbee.ddo_get_param(None, 'SH')+xbee.ddo_get_param(None, 'SL'))))