Exemplo n.º 1
0
  def connect2(self, host, port, newsocket,cleanstart, keepalive, protocolName,willFlag, willTopic, willMessage, willQoS, willRetain,properties, willProperties, username, password):
    if newsocket:
      try:
        self.sock.close()
      except:
        pass
      socket.setdefaulttimeout(5)
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.sock.settimeout(5)
      self.sock.connect((host, port))

    connect = MQTTV5.Connects()
    connect.ClientIdentifier = self.clientid
    connect.CleanStart = cleanstart
    connect.KeepAliveTimer = keepalive
    if protocolName:
      connect.ProtocolName = protocolName

    if willFlag:
      connect.WillFlag = True
      connect.WillTopic = willTopic
      connect.WillMessage = willMessage
      connect.WillQoS = willQoS
      connect.WillRETAIN = willRetain
      if willProperties:
        connect.WillProperties = willProperties

    if username:
      connect.usernameFlag = True
      connect.username = username

    if password:
      connect.passwordFlag = True
      connect.password = password

    if properties:
      connect.properties = properties

    sendtosocket(self.sock, connect.pack())

    response = MQTTV5.unpackPacket(MQTTV5.getPacket(self.sock))
    if not response:
      raise MQTTV5.MQTTException("connect failed - socket closed, no connack")
    assert response.fh.PacketType == MQTTV5.PacketTypes.CONNACK

    self.cleanstart = cleanstart
    # print("response =")
    # print(response)
    assert response.reasonCode.getName() == "Success", "connect was %s" % str(response)
    if self.cleanstart or self.__receiver == None:
      self.__receiver = internal.Receivers(self.sock)
    else:
      self.__receiver.socket = self.sock
    if self.callback:
      id = _thread.start_new_thread(self.__receiver, (self.callback,))
    return response
Exemplo n.º 2
0
 def handleRequest(self, sock):
     "this is going to be called from multiple threads, so synchronize"
     self.lock.acquire()
     sendWillMessage = False
     try:
         try:
             raw_packet = MQTTV5.getPacket(sock)
         except:
             raise MQTTV5.MQTTException(
                 "[MQTT-4.8.0-1] 'transient error' reading packet, closing connection"
             )
         if raw_packet == None:
             # will message
             if sock in self.clients.keys():
                 self.disconnect(sock, None, sendWillMessage=True)
             terminate = True
         else:
             try:
                 packet = MQTTV5.unpackPacket(raw_packet,
                                              self.maximumPacketSize)
                 if packet:
                     terminate = self.handlePacket(packet, sock)
                 else:
                     self.disconnect(sock,
                                     reasonCode="Malformed packet",
                                     sendWillMessage=True)
                     terminate = True
             except MQTTV5.MalformedPacket as error:
                 traceback.print_exc()
                 disconnect_properties = MQTTV5.Properties(
                     MQTTV5.PacketTypes.DISCONNECT)
                 disconnect_properties.ReasonString = error.args[0]
                 self.disconnect(sock,
                                 reasonCode="Malformed packet",
                                 sendWillMessage=True)
                 terminate = True
             except MQTTV5.ProtocolError as error:
                 disconnect_properties = MQTTV5.Properties(
                     MQTTV5.PacketTypes.DISCONNECT)
                 disconnect_properties.ReasonString = error.args[0]
                 self.disconnect(sock,
                                 reasonCode=error.args[0],
                                 properties=disconnect_properties,
                                 sendWillMessage=True)
                 terminate = True
     finally:
         self.lock.release()
     return terminate
Exemplo n.º 3
0
 def handleRequest(self, sock):
   "this is going to be called from multiple threads, so synchronize"
   self.lock.acquire()
   sendWillMessage = False
   try:
     try:
       raw_packet = MQTTV5.getPacket(sock)
     except:
       raise MQTTV5.MQTTException("[MQTT-4.8.0-1] 'transient error' reading packet, closing connection")
     if raw_packet == None:
       # will message
       if sock in self.clients.keys():
         self.disconnect(sock, None, sendWillMessage=True)
       terminate = True
     else:
       try:
         packet = MQTTV5.unpackPacket(raw_packet, self.maximumPacketSize)
         if packet:
           terminate = self.handlePacket(packet, sock)
         else:
           self.disconnect(sock, reasonCode="Malformed packet", sendWillMessage=True)
           terminate = True
       except MQTTV5.MalformedPacket as error:
         disconnect_properties = MQTTV5.Properties(MQTTV5.PacketTypes.DISCONNECT)
         disconnect_properties.ReasonString = error.args[0]
         self.disconnect(sock, reasonCode="Malformed packet", sendWillMessage=True)
         terminate = True
       except MQTTV5.ProtocolError as error:
         disconnect_properties = MQTTV5.Properties(MQTTV5.PacketTypes.DISCONNECT)
         disconnect_properties.ReasonString = error.args[0]
         self.disconnect(sock, reasonCode=error.args[0], properties=disconnect_properties,
                         sendWillMessage=True)
         terminate = True
   finally:
     self.lock.release()
   return terminate
Exemplo n.º 4
0
 def handleRequest(self, sock):
     "this is going to be called from multiple threads, so synchronize"
     self.lock.acquire()
     raw_packet = None
     try:
         try:
             raw_packet = MQTTV5.getPacket(sock)
         except:
             pass  # handled by raw_packet == None
         if raw_packet == None:
             logger.info(
                 "[MQTT-4.8.0-1] 'transient error' reading packet, closing connection"
             )
             # will message
             if sock in self.clients.keys():
                 self.disconnect(sock, None, sendWillMessage=True)
             terminate = True
         else:
             try:
                 packet = MQTTV5.unpackPacket(
                     raw_packet, self.options["maximumPacketSize"])
                 if self.options["visual"]:
                     clientid = self.clients[
                         sock].id if sock in self.clients.keys() else ""
                     if clientid == "" and hasattr(packet,
                                                   "ClientIdentifier"):
                         clientid = packet.ClientIdentifier
                     try:
                         data = {
                             "direction": "CtoS",
                             "socket": sock.fileno(),
                             "clientid": clientid,
                             "packet": packet.json()
                         }
                         databytes = bytes(json.dumps(data), 'utf-8')
                         self.broker.publish('$internal',
                                             '$SYS/clients-packets',
                                             databytes, 0, 0, None,
                                             time.monotonic())
                     except:
                         traceback.print_exc()
                 if packet:
                     terminate = self.handlePacket(packet, sock)
                 else:
                     self.disconnect(sock,
                                     reasonCode="Malformed packet",
                                     sendWillMessage=True)
                     terminate = True
             except MQTTV5.MalformedPacket as error:
                 traceback.print_exc()
                 disconnect_properties = MQTTV5.Properties(
                     MQTTV5.PacketTypes.DISCONNECT)
                 disconnect_properties.ReasonString = error.args[0]
                 self.disconnect(sock,
                                 reasonCode="Malformed packet",
                                 sendWillMessage=True)
                 terminate = True
             except MQTTV5.ProtocolError as error:
                 disconnect_properties = MQTTV5.Properties(
                     MQTTV5.PacketTypes.DISCONNECT)
                 disconnect_properties.ReasonString = error.args[0]
                 self.disconnect(sock,
                                 reasonCode=error.args[0],
                                 properties=disconnect_properties,
                                 sendWillMessage=True)
                 terminate = True
     finally:
         self.lock.release()
     return terminate
Exemplo n.º 5
0
    def receive(self, callback=None):
        packet = None
        try:
            packet = MQTTV5.unpackPacket(MQTTV5.getPacket(self.socket))
        except:
            if not self.stopping and sys.exc_info()[0] != socket.timeout:
                logger.info("receive: unexpected exception %s",
                            str(sys.exc_info()))
                #traceback.print_exc()
                raise
        if packet == None:
            time.sleep(0.1)
            return
        logger.debug("in :%s", str(packet))

        if packet.fh.PacketType == MQTTV5.PacketTypes.SUBACK:
            if hasattr(callback, "subscribed"):
                callback.subscribed(packet.packetIdentifier,
                                    packet.reasonCodes)

        elif packet.fh.PacketType == MQTTV5.PacketTypes.DISCONNECT:
            if hasattr(callback, "disconnected"):
                callback.disconnected(packet.reasonCode, packet.properties)

        elif packet.fh.PacketType == MQTTV5.PacketTypes.UNSUBACK:
            if hasattr(callback, "unsubscribed"):
                callback.unsubscribed(packet.packetIdentifier)

        elif packet.fh.PacketType == MQTTV5.PacketTypes.PUBACK:
            "check if we are expecting a puback"
            if packet.packetIdentifier in self.outMsgs.keys() and \
              self.outMsgs[packet.packetIdentifier].fh.QoS == 1:
                del self.outMsgs[packet.packetIdentifier]
                if hasattr(callback, "published"):
                    callback.published(packet.packetIdentifier)
            else:
                raise Exception("No QoS 1 with that message id sent")

        elif packet.fh.PacketType == MQTTV5.PacketTypes.PUBREC:
            if packet.packetIdentifier in self.outMsgs.keys():
                #self.outMsgs[packet.packetIdentifier].pubrec_received = True
                self.pubrel.packetIdentifier = packet.packetIdentifier
                logger.debug("out: %s", str(self.pubrel))
                self.socket.send(self.pubrel.pack())
            else:
                raise Exception("PUBREC received for unknown msg id "+ \
                            str(packet.packetIdentifier))

        elif packet.fh.PacketType == MQTTV5.PacketTypes.PUBREL:
            "release QOS 2 publication to client, & send PUBCOMP"
            msgid = packet.packetIdentifier
            if packet.packetIdentifier not in self.inMsgs.keys():
                pass  # what should we do here?
            else:
                pub = self.inMsgs[packet.packetIdentifier]
                if callback == None or \
                   callback.publishArrived(pub.topicName, pub.data, 2,
                                   pub.fh.RETAIN, pub.packetIdentifier, pub.properties):
                    del self.inMsgs[packet.packetIdentifier]
                    self.pubcomp.packetIdentifier = packet.packetIdentifier
                    logger.debug("out: %s", str(self.pubcomp))
                    self.socket.send(self.pubcomp.pack())
                if callback == None:
                    return (pub.topicName, pub.data, 2, pub.fh.RETAIN,
                            pub.packetIdentifier)

        elif packet.fh.PacketType == MQTTV5.PacketTypes.PUBCOMP:
            "finished with this message id"
            if packet.packetIdentifier in self.outMsgs.keys():
                del self.outMsgs[packet.packetIdentifier]
                if hasattr(callback, "published"):
                    callback.published(packet.packetIdentifier)
            else:
                raise Exception("PUBCOMP received for unknown msg id "+ \
                            str(packet.packetIdentifier))

        elif packet.fh.PacketType == MQTTV5.PacketTypes.PUBLISH:
            if self.paused:
                return
            if packet.fh.QoS == 0:
                if callback == None:
                    return (packet.topicName, packet.data, 0, packet.fh.RETAIN,
                            packet.packetIdentifier)
                else:
                    callback.publishArrived(packet.topicName, packet.data, 0,
                                            packet.fh.RETAIN,
                                            packet.packetIdentifier,
                                            packet.properties)
            elif packet.fh.QoS == 1:
                if callback == None:
                    return (packet.topicName, packet.data, 1, packet.fh.RETAIN,
                            packet.packetIdentifier)
                else:
                    if callback.publishArrived(packet.topicName, packet.data,
                                               1, packet.fh.RETAIN,
                                               packet.packetIdentifier,
                                               packet.properties):
                        self.puback.packetIdentifier = packet.packetIdentifier
                        logger.debug("out: %s", str(self.puback))
                        self.socket.send(self.puback.pack())
            elif packet.fh.QoS == 2:
                self.inMsgs[packet.packetIdentifier] = packet
                self.pubrec.packetIdentifier = packet.packetIdentifier
                logger.debug("out: %s", str(self.pubrec))
                self.socket.send(self.pubrec.pack())

        else:
            raise Exception("Unexpected packet" + str(packet))
Exemplo n.º 6
0
    def test_flow_control1(self):
      testcallback = Callbacks()
      # no callback means no background thread, to control receiving
      testclient = mqtt_client.Client("myclientid".encode("utf-8"))

      # set receive maximum - the number of concurrent QoS 1 and 2 messages
      clientReceiveMaximum = 2 # set to low number so we can test
      connect_properties = MQTTV5.Properties(MQTTV5.PacketTypes.CONNECT)
      connect_properties.ReceiveMaximum = clientReceiveMaximum
      connect_properties.SessionExpiryInterval = 0
      connack = testclient.connect(host=host, port=port, cleanstart=True,
                   properties=connect_properties)

      serverReceiveMaximum = 2**16-1 # the default
      if hasattr(connack.properties, "ReceiveMaximum"):
        serverReceiveMaximum = connack.properties.ReceiveMaximum

      receiver = testclient.getReceiver()

      testclient.subscribe([topics[0]], [MQTTV5.SubscribeOptions(2)])
      receiver.receive(testcallback)
      self.waitfor(testcallback.subscribeds, 1, 3)

      pubs = 0
      for i in range(1, clientReceiveMaximum + 2):
        testclient.publish(topics[0], "message %d" % i, 1)
        pubs += 1

      # get two publishes
      acks = 0
      while True:
        response1 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
        if response1.fh.PacketType == MQTTV5.PacketTypes.PUBLISH:
          break
        self.assertEqual(response1.fh.PacketType, MQTTV5.PacketTypes.PUBACK)
        acks += 1
        del receiver.outMsgs[response1.packetIdentifier]
      self.assertEqual(response1.fh.PacketType, MQTTV5.PacketTypes.PUBLISH)
      self.assertEqual(response1.fh.QoS, 1, response1.fh.QoS)

      while True:
        response2 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
        if response2.fh.PacketType == MQTTV5.PacketTypes.PUBLISH:
          break
        self.assertEqual(response2.fh.PacketType, MQTTV5.PacketTypes.PUBACK)
        acks += 1
        del receiver.outMsgs[response2.packetIdentifier]
      self.assertEqual(response2.fh.PacketType, MQTTV5.PacketTypes.PUBLISH)
      self.assertEqual(response2.fh.QoS, 1, response1.fh.QoS)

      while acks < pubs:
        ack = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
        self.assertEqual(ack.fh.PacketType, MQTTV5.PacketTypes.PUBACK)
        acks += 1
        del receiver.outMsgs[ack.packetIdentifier]

      with self.assertRaises(socket.timeout):
        # this should time out because we haven't acknowledged the first one
        response3 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))

      # ack the first one
      puback = MQTTV5.Pubacks()
      puback.packetIdentifier = response1.packetIdentifier
      testclient.sock.send(puback.pack())

      # now get the next packet
      response3 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
      self.assertEqual(response3.fh.PacketType, MQTTV5.PacketTypes.PUBLISH)
      self.assertEqual(response3.fh.QoS, 1, response1.fh.QoS)

      # ack the second one
      puback.packetIdentifier = response2.packetIdentifier
      testclient.sock.send(puback.pack())

      # ack the third one
      puback.packetIdentifier = response3.packetIdentifier
      testclient.sock.send(puback.pack())

      testclient.disconnect()
Exemplo n.º 7
0
    def test_flow_control1(self):
      testcallback = Callbacks()
      # no callback means no background thread, to control receiving
      testclient = mqtt_client.Client("myclientid".encode("utf-8"))

      # set receive maximum - the number of concurrent QoS 1 and 2 messages
      clientReceiveMaximum = 2 # set to low number so we can test
      connect_properties = MQTTV5.Properties(MQTTV5.PacketTypes.CONNECT)
      connect_properties.ReceiveMaximum = clientReceiveMaximum
      connect_properties.SessionExpiryInterval = 0
      connack = testclient.connect(host=host, port=port, cleanstart=True,
                   properties=connect_properties)

      serverReceiveMaximum = 2**16-1 # the default
      if hasattr(connack.properties, "ReceiveMaximum"):
        serverReceiveMaximum = connack.properties.ReceiveMaximum

      receiver = testclient.getReceiver()

      testclient.subscribe([topics[0]], [MQTTV5.SubscribeOptions(2)])
      receiver.receive(testcallback)
      self.waitfor(testcallback.subscribeds, 1, 3)

      pubs = 0
      for i in range(1, clientReceiveMaximum + 2):
        testclient.publish(topics[0], "message %d" % i, 1)
        pubs += 1

      # get two publishes
      acks = 0
      while True:
        response1 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
        if response1.fh.PacketType == MQTTV5.PacketTypes.PUBLISH:
          break
        self.assertEqual(response1.fh.PacketType, MQTTV5.PacketTypes.PUBACK)
        acks += 1
        del receiver.outMsgs[response1.packetIdentifier]
      self.assertEqual(response1.fh.PacketType, MQTTV5.PacketTypes.PUBLISH)
      self.assertEqual(response1.fh.QoS, 1, response1.fh.QoS)

      while True:
        response2 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
        if response2.fh.PacketType == MQTTV5.PacketTypes.PUBLISH:
          break
        self.assertEqual(response2.fh.PacketType, MQTTV5.PacketTypes.PUBACK)
        acks += 1
        del receiver.outMsgs[response2.packetIdentifier]
      self.assertEqual(response2.fh.PacketType, MQTTV5.PacketTypes.PUBLISH)
      self.assertEqual(response2.fh.QoS, 1, response1.fh.QoS)

      while acks < pubs:
        ack = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
        self.assertEqual(ack.fh.PacketType, MQTTV5.PacketTypes.PUBACK)
        acks += 1
        del receiver.outMsgs[ack.packetIdentifier]

      with self.assertRaises(socket.timeout):
        # this should time out because we haven't acknowledged the first one
        response3 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))

      # ack the first one
      puback = MQTTV5.Pubacks()
      puback.packetIdentifier = response1.packetIdentifier
      testclient.sock.send(puback.pack())

      # now get the next packet
      response3 = MQTTV5.unpackPacket(MQTTV5.getPacket(testclient.sock))
      self.assertEqual(response3.fh.PacketType, MQTTV5.PacketTypes.PUBLISH)
      self.assertEqual(response3.fh.QoS, 1, response1.fh.QoS)

      # ack the second one
      puback.packetIdentifier = response2.packetIdentifier
      testclient.sock.send(puback.pack())

      # ack the third one
      puback.packetIdentifier = response3.packetIdentifier
      testclient.sock.send(puback.pack())

      testclient.disconnect()