def handlePacket(self, packet, sock, callback): terminate = False logger.info("in: " + str(packet)) if sock not in self.clients.keys() and not isinstance( packet, MQTTSN.Connects): print(self.clients.keys(), sock) self.disconnect(sock, packet) raise MQTTSN.MQTTSNException( "[MQTT-3.1.0-1] Connect was not first packet on socket") else: getattr(self, MQTTSN.Messages.Names[packet.messageType].lower())( sock, packet, callback) if sock in self.clients.keys(): self.clients[sock].lastPacket = time.time() if packet.messageType == MQTTSN.MessageTypes.DISCONNECT: terminate = True return terminate
def handleRequest(self, raw_packet, client_address, callback): "this is going to be called from multiple threads, so synchronize" self.lock.acquire() terminate = False try: if raw_packet == None: # will message self.disconnect(sock, None, terminate=True) terminate = True else: packet = MQTTSN.unpackPacket(raw_packet) if packet: terminate = self.handlePacket(packet, client_address, callback) else: raise MQTTSN.MQTTSNException( "[MQTT-2.0.0-1] handleRequest: badly formed MQTT packet" ) finally: self.lock.release() return terminate
def connect(self, sock, packet, callback): if packet.ProtocolId != 1: logger.error("[MQTT-3.1.2-2] Wrong protocol version %d", packet.ProtocolVersion) resp = MQTTSN.Connacks() resp.ReturnCode = 1 respond(sock, callback, resp) logger.info( "[MQTT-3.2.2-5] must close connection after non-zero connack") self.disconnect(sock, None) logger.info( "[MQTT-3.1.4-5] When rejecting connect, no more data must be processed" ) return if sock in self.clients.keys(): # is socket is already connected? self.disconnect(sock, None) logger.info( "[MQTT-3.1.4-5] When rejecting connect, no more data must be processed" ) raise MQTTSN.MQTTSNException( "[MQTT-3.1.0-2] Second connect packet") if len(packet.ClientId) == 0: if self.zero_length_clientids == False or packet.CleanSession == False: if self.zero_length_clientids: logger.info( "[MQTT-3.1.3-8] Reject 0-length clientid with cleansession false" ) logger.info( "[MQTT-3.1.3-9] if clientid is rejected, must send connack 2 and close connection" ) resp = MQTTSN.Connacks() resp.returnCode = 2 respond(sock, callback, resp) logger.info( "[MQTT-3.2.2-5] must close connection after non-zero connack" ) self.disconnect(sock, None) logger.info( "[MQTT-3.1.4-5] When rejecting connect, no more data must be processed" ) return else: logger.info( "[MQTT-3.1.3-7] 0-length clientid must have cleansession true" ) packet.ClientId = uuid.uuid4( ) # give the client a unique clientid logger.info( "[MQTT-3.1.3-6] 0-length clientid must be assigned a unique id %s", packet.ClientId) logger.info( "[MQTT-3.1.3-5] Clientids of 1 to 23 chars and ascii alphanumeric must be allowed" ) if packet.ClientId in [ client.id for client in self.clients.values() ]: # is this client already connected on a different socket? for s in self.clients.keys(): if self.clients[s].id == packet.ClientId: logger.info("[MQTT-3.1.4-2] Disconnecting old client %s", packet.ClientId) self.disconnect(s, None) break me = None if not packet.Flags.CleanSession: me = self.broker.getClient( packet.ClientId) # find existing state, if there is any if me: logger.info( "[MQTT-3.1.3-2] clientid used to retrieve client state") resp = MQTTSN.Connacks() if me == None: me = MQTTSNClients(packet.ClientId, packet.Flags.CleanSession, packet.Duration, sock, self) else: me.socket = sock # set existing client state to new socket me.cleansession = packet.Flags.CleanSession me.keepalive = packet.Duration logger.info( "[MQTT-4.1.0-1] server must store data for at least as long as the network connection lasts" ) self.clients[sock] = me #me.will = (packet.WillTopic, packet.WillQoS, packet.WillMessage, packet.WillRETAIN) if packet.WillFlag else None self.broker.connect(me) logger.info( "[MQTT-3.2.0-1] the first response to a client must be a connack") resp.ReturnCode = 0 respond(sock, callback, resp) me.resend()