Exemplo n.º 1
0
	def __call__(self, sockid):
		logger.debug("*** running")
		self.running = True
		packet = None
		try:
			while True:
				packet = MQTTV3.unpackPacket(MQTTV3.getPacket(state.sockets[sockid]))
				if packet == None:
					break
				if test:
					logger.debug("received result %s", (sockid, packet))
					test.addResult((sockid, packet))
					if packet.fh.MessageType == MQTTV3.CONNACK:
						self.packets.append(packet)
				else:
					mbt.observe((sockid, packet))
					if packet.fh.MessageType == MQTTV3.PUBREC:
						mbt.execution.pools["pubrecs"].append(mbt.Choices((sockid, packet)))
					elif packet.fh.MessageType == MQTTV3.PUBLISH and packet.fh.QoS in [1, 2]:
						mbt.execution.pools["publishes"].append(mbt.Choices((sockid, packet)))
					elif packet.fh.MessageType == MQTTV3.PUBREL:
						mbt.execution.pools["pubrels"].append(mbt.Choices((sockid, packet)))
					elif packet.fh.MessageType == MQTTV3.CONNACK:
						self.packets.append(packet)
		except:
			if sys.exc_info()[0] != socket.error:
				logger.debug("unexpected exception %s", sys.exc_info())
			#mbt.log(traceback.format_exc())
		self.running = False
		logger.debug("*** stopping "+str(packet))
Exemplo n.º 2
0
	def __call__(self, sockid):
		logger.debug("*** running")
		self.running = True
		packet = None
		try:
			while True:
				packet = MQTTV3.unpackPacket(MQTTV3.getPacket(state.sockets[sockid]))
				if packet == None:
					break
				if test:
					logger.debug("received result %s", (sockid, packet))
					test.addResult((sockid, packet))
					if packet.fh.MessageType == MQTTV3.CONNACK:
						self.packets.append(packet)
				else:
					mbt.observe((sockid, packet))
					if packet.fh.MessageType == MQTTV3.PUBREC:
						mbt.execution.pools["pubrecs"].append(mbt.Choices((sockid, packet)))
					elif packet.fh.MessageType == MQTTV3.PUBLISH and packet.fh.QoS in [1, 2]:
						mbt.execution.pools["publishes"].append(mbt.Choices((sockid, packet)))
					elif packet.fh.MessageType == MQTTV3.PUBREL:
						mbt.execution.pools["pubrels"].append(mbt.Choices((sockid, packet)))
					elif packet.fh.MessageType == MQTTV3.CONNACK:
						self.packets.append(packet)
		except:
			if sys.exc_info()[0] != socket.error:
				logger.debug("unexpected exception %s", sys.exc_info())
			#mbt.log(traceback.format_exc())
		self.running = False
		logger.debug("*** stopping "+str(packet))
Exemplo n.º 3
0
 def publish(self, sock, packet):
     packet.receivedTime = time.monotonic()
     if packet.topicName.find("+") != -1 or packet.topicName.find(
             "#") != -1:
         raise MQTTV3.MQTTException(
             "[MQTT-3.3.2-2][MQTT-4.7.1-1] wildcards not allowed in topic name"
         )
     if packet.fh.QoS == 0:
         self.broker.publish(self.clients[sock].id, packet.topicName,
                             packet.data, packet.fh.QoS, packet.fh.RETAIN,
                             packet.receivedTime)
     elif packet.fh.QoS == 1:
         if packet.fh.DUP:
             logger.info(
                 "[MQTT-3.3.1-3] Incoming publish DUP 1 ==> outgoing publish with DUP 0"
             )
             logger.info(
                 "[MQTT-4.3.2-2] server must store message in accordance with QoS 1"
             )
         self.broker.publish(self.clients[sock].id, packet.topicName,
                             packet.data, packet.fh.QoS, packet.fh.RETAIN,
                             packet.receivedTime)
         resp = MQTTV3.Pubacks()
         logger.info("[MQTT-2.3.1-6] puback messge id same as publish")
         resp.messageIdentifier = packet.messageIdentifier
         respond(sock, resp)
     elif packet.fh.QoS == 2:
         myclient = self.clients[sock]
         if self.publish_on_pubrel:
             if packet.messageIdentifier in myclient.inbound.keys():
                 if packet.fh.DUP == 0:
                     logger.error(
                         "[MQTT-3.3.1-2] duplicate QoS 2 message id %d found with DUP 0",
                         packet.messageIdentifier)
                 else:
                     logger.info(
                         "[MQTT-3.3.1-2] DUP flag is 1 on redelivery")
             else:
                 myclient.inbound[packet.messageIdentifier] = packet
         else:
             if packet.messageIdentifier in myclient.inbound:
                 if packet.fh.DUP == 0:
                     logger.error(
                         "[MQTT-3.3.1-2] duplicate QoS 2 message id %d found with DUP 0",
                         packet.messageIdentifier)
                 else:
                     logger.info(
                         "[MQTT-3.3.1-2] DUP flag is 1 on redelivery")
             else:
                 myclient.inbound.append(packet.messageIdentifier)
                 logger.info(
                     "[MQTT-4.3.3-2] server must store message in accordance with QoS 2"
                 )
                 self.broker.publish(myclient, packet.topicName,
                                     packet.data, packet.fh.QoS,
                                     packet.fh.RETAIN, packet.receivedTime)
         resp = MQTTV3.Pubrecs()
         logger.info("[MQTT-2.3.1-6] pubrec messge id same as publish")
         resp.messageIdentifier = packet.messageIdentifier
         respond(sock, resp)
Exemplo n.º 4
0
 def handleRequest(self, sock):
     "this is going to be called from multiple threads, so synchronize"
     self.lock.acquire()
     terminate = False
     try:
         try:
             raw_packet = MQTTV3.getPacket(sock)
         except:
             raise MQTTV3.MQTTException(
                 "[MQTT-4.8.0-1] 'transient error' reading packet, closing connection"
             )
         if raw_packet == None:
             # will message
             self.disconnect(sock, None, terminate=True)
             terminate = True
         else:
             packet = MQTTV3.unpackPacket(raw_packet)
             if packet:
                 terminate = self.handlePacket(packet, sock)
             else:
                 raise MQTTV3.MQTTException(
                     "[MQTT-2.0.0-1] handleRequest: badly formed MQTT packet"
                 )
     finally:
         self.lock.release()
     return terminate
Exemplo n.º 5
0
def isValidTopicName(aName):
  logger.info("[MQTT-4.7.3-1] all topic names and filters must be at least 1 char")
  if len(aName) < 1:
    raise MQTTV3.MQTTException("MQTT-4.7.3-1] all topic names and filters must be at least 1 char")
    return False
  logger.info("[MQTT-4.7.3-3] all topic names and filters must be <= 65535 bytes long")
  if len(aName) > 65535:
    raise MQTTV3.MQTTException("[MQTT-4.7.3-3] all topic names and filters must be <= 65535 bytes long")
    return False
  rc = True

  # '#' wildcard can be only at the end of a topic (used to be beginning as well)
  logger.info("[MQTT-4.7.1-2] # must be last, and next to /")
  if aName[0:-1].find('#') != -1:
    raise MQTTV3.MQTTException("[MQTT-4.7.1-2] # must be last, and next to /")
    rc = False

  logger.info("[MQTT-4.7.1-3] + can be used at any complete level")
  # '#' or '+' only next to a slash separator or end of name
  wilds = '#+'
  for c in wilds:
    pos = 0
    pos = aName.find(c, pos)
    while pos != -1:
      if pos > 0: # check previous char is '/'
        if aName[pos-1] != '/':
          raise MQTTV3.MQTTException("[MQTT-4.7.1-3] + can be used at any complete level")
          rc = False
      if pos < len(aName)-1: # check that subsequent char is '/'
        if aName[pos+1] != '/':
          raise MQTTV3.MQTTException("[MQTT-4.7.1-3] + can be used at any complete level")
          rc = False
      pos = aName.find(c, pos+1)
  return rc
Exemplo n.º 6
0
def puback(publish: "publishes"):
    sockid, publish = publish
    sock = state.sockets[sockid]
    if publish.fh.QoS == 1:
        puback = MQTTV3.Pubacks()
        puback.messageIdentifier = publish.messageIdentifier
        sock.send(puback.pack())
    elif publish.fh.QoS == 2:
        pubrec = MQTTV3.Pubrecs()
        pubrec.messageIdentifier = publish.messageIdentifier
        sock.send(pubrec.pack())
Exemplo n.º 7
0
    def connect2(self, host, port, cleansession, keepalive, newsocket,
                 protocolName, willFlag, willTopic, willMessage, willQoS,
                 willRetain, username, password):
        if newsocket:
            try:
                self.sock.close()
            except:
                pass
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.settimeout(.5)
            self.sock.connect((host, port))

        connect = MQTTV3.Connects()  #mqtt login
        connect.ClientIdentifier = self.clientid
        connect.CleanSession = cleansession
        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 username:
            connect.usernameFlag = True
            connect.username = username

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

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

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

        self.cleansession = cleansession
        assert response.returnCode == 0, "connect was %s" % str(response)

        if self.cleansession 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.º 8
0
 def handle(self):
     global brokers, clients, options, break_connections, control_broker
     if not hasattr(self, "ids"):
         self.ids = {}
     if not hasattr(self, "versions"):
         self.versions = {}
     inbuf = True
     i = o = e = None
     try:
         clients = self.request
         brokers = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         brokers.connect((brokerhost, brokerport))
         while inbuf != None:
             (i, o, e) = select.select([clients, brokers], [], [])
             for s in i:
                 if s == clients:
                     inbuf = MQTTV3.getPacket(clients)  # get one packet
                     if inbuf == None:
                         break
                     try:
                         packet = MQTTV3.unpackPacket(inbuf)
                         if packet.fh.MessageType == MQTTV3.CONNECT:
                             self.ids[id(clients)] = packet.ClientIdentifier
                             self.versions[id(clients)] = 3
                         logger.debug("C to S " + self.ids[id(clients)] +
                                      " " + repr(packet))
                         #logger.debug([hex(b) for b in inbuf])
                         #logger.debug(inbuf)
                     except:
                         traceback.print_exc()
                     brokers.send(inbuf)  # pass it on
                 elif s == brokers:
                     inbuf = MQTTV3.getPacket(brokers)  # get one packet
                     if inbuf == None:
                         break
                     try:
                         logger.debug("S to C " + self.ids[id(clients)] +
                                      " " +
                                      repr(MQTTV3.unpackPacket(inbuf)))
                     except:
                         traceback.print_exc()
                     clients.send(inbuf)
         if id(clients) in self.ids.keys():
             logger.info("client " + self.ids[id(clients)] +
                         " connection closing")
     except:
         #logger.debug(repr((i, o, e)) + " " + repr(inbuf))
         traceback.print_exc()
     if id(clients) in self.ids.keys():
         del self.ids[id(clients)]
     elif id(clients) in self.versions.keys():
         del self.versions[id(clients)]
Exemplo n.º 9
0
    def __init__(self, socket):
        logging.debug("initializing receiver")
        self.socket = socket
        self.stopping = False
        self.paused = False

        self.inMsgs = {}
        self.outMsgs = {}

        self.puback = MQTTV3.Pubacks()
        self.pubrec = MQTTV3.Pubrecs()
        self.pubrel = MQTTV3.Pubrels()
        self.pubcomp = MQTTV3.Pubcomps()
        self.running = False
Exemplo n.º 10
0
  def connect(self, host="localhost", port=1883, cleansession=True, keepalive=0, newsocket=True, protocolName=None,
              willFlag=False, willTopic=None, willMessage=None, willQoS=2, willRetain=False, username=None, password=None):
    if newsocket:
      try:
        self.sock.close()
      except:
        pass
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.sock.settimeout(.5)
      self.sock.connect((host, port))

    connect = MQTTV3.Connects()
    connect.ClientIdentifier = self.clientid
    connect.CleanSession = cleansession
    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 username:
      connect.usernameFlag = True
      connect.username = username

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

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

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

    self.cleansession = cleansession
    assert response.returnCode == 0, "connect was %s" % str(response)
    if self.cleansession 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.º 11
0
 def handle(self):
   global brokers, clients, options, break_connections, control_broker
   if not hasattr(self, "ids"):
     self.ids = {}
   if not hasattr(self, "versions"):
     self.versions = {}
   inbuf = True
   i = o = e = None
   try:
     clients = self.request
     brokers = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     brokers.connect((brokerhost, brokerport))
     while inbuf != None:
       (i, o, e) = select.select([clients, brokers], [], [])
       for s in i:
         if s == clients:
           inbuf = MQTTV3.getPacket(clients) # get one packet
           if inbuf == None:
             break
           try:
             packet = MQTTV3.unpackPacket(inbuf)
             if packet.fh.MessageType == MQTTV3.CONNECT:
               self.ids[id(clients)] = packet.ClientIdentifier
               self.versions[id(clients)] = 3
             logger.debug("C to S "+self.ids[id(clients)]+" "+repr(packet))
             #logger.debug([hex(b) for b in inbuf])
             #logger.debug(inbuf)
           except:
             traceback.print_exc()
           brokers.send(inbuf)       # pass it on
         elif s == brokers:
           inbuf = MQTTV3.getPacket(brokers) # get one packet
           if inbuf == None:
             break
           try:
             logger.debug("S to C "+self.ids[id(clients)]+" "+repr(MQTTV3.unpackPacket(inbuf)))
           except:
             traceback.print_exc()
           clients.send(inbuf)
     if id(clients) in self.ids.keys():
       logger.info("client "+self.ids[id(clients)]+" connection closing")
   except:
     #logger.debug(repr((i, o, e)) + " " + repr(inbuf))
     traceback.print_exc()
   if id(clients) in self.ids.keys():
     del self.ids[id(clients)]
   elif id(clients) in self.versions.keys():
     del self.versions[id(clients)]
Exemplo n.º 12
0
 def subscribe(self, sock, packet):
     topics = []
     qoss = []
     respqoss = []
     for p in packet.data:
         if p[0] == "test/nosubscribe":
             respqoss.append(0x80)
         else:
             if p[0] == "test/QoS 1 only":
                 respqoss.append(min(1), p[1])
             elif p[0] == "test/QoS 0 only":
                 respqoss.append(min(0), p[1])
             else:
                 respqoss.append(p[1])
             topics.append(p[0])
             qoss.append(respqoss[-1])
     if len(topics) > 0:
         self.broker.subscribe(self.clients[sock].id, topics, qoss)
     resp = MQTTV3.Subacks()
     logger.info(
         "[MQTT-2.3.1-7][MQTT-3.8.4-2] Suback has same message id as subscribe"
     )
     logger.info("[MQTT-3.8.4-1] Must respond with suback")
     resp.messageIdentifier = packet.messageIdentifier
     logger.info(
         "[MQTT-3.8.4-5] return code must be returned for each topic in subscribe"
     )
     logger.info(
         "[MQTT-3.9.3-1] the order of return codes must match order of topics in subscribe"
     )
     resp.data = respqoss
     respond(sock, resp)
Exemplo n.º 13
0
 def disconnect(self):
   if self.__receiver:
     self.__receiver.stopping = True
     count = 0
     while (len(self.__receiver.inMsgs) > 0 or len(self.__receiver.outMsgs) > 0) and self.__receiver.paused == False:
       logger.debug("disconnecting %s %s", self.__receiver.inMsgs, self.__receiver.outMsgs)
       time.sleep(.2)
       count += 1
       if count == 20:
         break
     if self.__receiver and self.__receiver.paused == False:
       assert self.__receiver.inMsgs == {}, self.__receiver.inMsgs
       assert self.__receiver.outMsgs == {}, self.__receiver.outMsgs
   disconnect = MQTTV3.Disconnects()
   sendtosocket(self.sock, disconnect.pack())
   time.sleep(0.1)
   if self.cleansession:
     self.__receiver = None
   else:
     self.__receiver.socket = None
   self.sock.close()
   if self.__receiver:
     while self.__receiver.running:
       time.sleep(0.1)
     self.__receiver.stopping = False
Exemplo n.º 14
0
 def publishArrived(self, topic, msg, qos, retained=False):
   pub = MQTTV3.Publishes()
   logger.info("[MQTT-3.2.3-3] topic name must match the subscription's topic filter")
   pub.topicName = topic
   pub.data = msg
   pub.fh.QoS = qos
   pub.fh.RETAIN = retained
   if retained:
     logger.info("[MQTT-2.1.2-7] Last retained message on matching topics sent on subscribe")
   if pub.fh.RETAIN:
     logger.info("[MQTT-2.1.2-9] Set retained flag on retained messages")
   if qos == 2:
     pub.qos2state = "PUBREC"
   if qos in [1, 2]:
     pub.messageIdentifier = self.msgid
     logger.debug("client id: %d msgid: %d", self.id, self.msgid)
     if self.msgid == 65535:
       self.msgid = 1
     else:
       self.msgid += 1
     self.outbound.append(pub)
     self.outmsgs[pub.messageIdentifier] = pub
   logger.info("[MQTT-4.6.0-6] publish packets must be sent in order of receipt from any given client")
   if self.connected:
     respond(self.socket, pub)
   else:
     if qos == 0 and not self.broker.dropQoS0:
       self.outbound.append(pub)
     if qos in [1, 2]:
       logger.info("[MQTT-3.1.2-5] storing of QoS 1 and 2 messages for disconnected client %s", self.id)
Exemplo n.º 15
0
 def unsubscribe(self, topics):
     unsubscribe = MQTTV3.Unsubscribes()
     unsubscribe.messageIdentifier = self.__nextMsgid()
     unsubscribe.data = topics
     a = unsubscribe.pack()
     sendtosocket(self.sock, unsubscribe.pack())
     return unsubscribe.messageIdentifier
Exemplo n.º 16
0
def connect(
    sockid: "socket",
    clientid: "clientids",
    cleansession: "boolean",  #willmsg : "willmsgs",
    #	    username : "******", password : "******"
) -> "connackrc":
    sock = state.sockets[sockid]
    connect = MQTTV3.Connects()
    connect.ClientIdentifier = clientid
    connect.CleanSession = cleansession
    connect.KeepAliveTimer = 60
    #if username:
    #	connect.usernameFlag = True
    #	connect.username = username
    #if password:
    #	connect.passwordFlag = True
    #	connect.password = password
    #if willmsg:
    #	connect.willFlag = True
    #   connect.WillQoS = 0
    #	connect.WillRETAIN = 0
    #   connect.WillTopic = None        # UTF-8
    #	connect.WillMessage = None      # binary
    sock.send(connect.pack())
    time.sleep(0.5)
    checksocket(sockid)
    response = state.clientlist[sockid].packets.pop(
        0)  #MQTTV3.unpackPacket(MQTTV3.getPacket(sock))
    logger.debug("+++connect response", response)
    if response == None or response.returnCode not in [0, 2]:
        raise Exception("Return code " + str(response.returnCode) +
                        " in connack")

    return response.returnCode
Exemplo n.º 17
0
 def resend(self):
   logger.debug("resending unfinished publications %s", str(self.outbound))
   if len(self.outbound) > 0:
     logger.info("[MQTT-4.4.0-1] resending inflight QoS 1 and 2 messages")
   for pub in self.outbound:
     logger.debug("resending", pub)
     logger.info("[MQTT-4.4.0-2] dup flag must be set on in re-publish")
     if pub.fh.QoS == 0:
       respond(self.socket, pub)
     elif pub.fh.QoS == 1:
       pub.fh.DUP = 1
       logger.info("[MQTT-2.1.2-3] Dup when resending QoS 1 publish id %d", pub.messageIdentifier)
       logger.info("[MQTT-2.3.1-4] Message id same as original publish on resend")
       logger.info("[MQTT-4.3.2-1] Resending QoS 1 with DUP flag")
       respond(self.socket, pub)
     elif pub.fh.QoS == 2:
       if pub.qos2state == "PUBREC":
         logger.info("[MQTT-2.1.2-3] Dup when resending QoS 2 publish id %d", pub.messageIdentifier)
         pub.fh.DUP = 1
         logger.info("[MQTT-2.3.1-4] Message id same as original publish on resend")
         logger.info("[MQTT-4.3.3-1] Resending QoS 2 with DUP flag")
         respond(self.socket, pub)
       else:
         resp = MQTTV3.Pubrels()
         logger.info("[MQTT-2.3.1-4] Message id same as original publish on resend")
         resp.messageIdentifier = pub.messageIdentifier
         respond(self.socket, resp)
Exemplo n.º 18
0
 def pubrec(self, sock, packet):
   "confirmed reception of qos 2"
   myclient = self.clients[sock]
   if myclient.pubrec(packet.messageIdentifier):
     logger.info("[MQTT-3.5.4-1] must reply with pubrel in response to pubrec")
     resp = MQTTV3.Pubrels()
     resp.messageIdentifier = packet.messageIdentifier
     respond(sock, resp)
Exemplo n.º 19
0
def unsubscribe(sockid: "socket", packetid: "packetids", topics: "topicLists"):
    sock = state.sockets[sockid]
    unsubscribe = MQTTV3.Unsubscribes()
    unsubscribe.messageIdentifier = packetid
    unsubscribe.data = topics
    sock.send(unsubscribe.pack())
    checksocket(sockid)
    return unsubscribe.messageIdentifier
Exemplo n.º 20
0
 def subscribe(self, topics, qoss):
   subscribe = MQTTV3.Subscribes()
   subscribe.messageIdentifier = self.__nextMsgid()
   count = 0
   for t in topics:
     subscribe.data.append((t, qoss[count]))
     count += 1
   sendtosocket(self.sock, subscribe.pack())
   return subscribe.messageIdentifier
Exemplo n.º 21
0
 def unsubscribe(self, sock, packet):
   self.broker.unsubscribe(self.clients[sock].id, packet.data)
   resp = MQTTV3.Unsubacks()
   logger.info("[MQTT-2.3.1-7] Unsuback has same message id as unsubscribe")
   logger.info("[MQTT-3.10.4-4] Unsuback must be sent - same message id as unsubscribe")
   me = self.clients[sock]
   if len(me.outbound) > 0:
     logger.info("[MQTT-3.10.4-3] sending unsuback has no effect on outward inflight messages")
   resp.messageIdentifier = packet.messageIdentifier
   respond(sock, resp)
Exemplo n.º 22
0
def publish(sockid : "socket", packetid : "packetids", topic : "topics", payload : "payloads", qos : "QoSs", retained : "boolean"):
	sock = state.sockets[sockid]
	publish = MQTTV3.Publishes()
	publish.fh.QoS = qos
	publish.fh.RETAIN = retained
	publish.messageIdentifier = packetid
	publish.topicName = topic
	publish.data = payload
	sock.send(publish.pack())
	checksocket(sockid)
	return publish.messageIdentifier
Exemplo n.º 23
0
def subscribe(sockid : "socket", packetid : "packetids", topics : "topicLists", qoss : "qosLists"):
	sock = state.sockets[sockid]
	subscribe = MQTTV3.Subscribes()
	subscribe.messageIdentifier = packetid
	count = 0
	for t in topics:
		subscribe.data.append((t, qoss[count]))
		count += 1
	sock.send(subscribe.pack())
	checksocket(sockid)
	return subscribe.messageIdentifier
Exemplo n.º 24
0
 def pubrel(self, sock, packet):
   myclient = self.clients[sock]
   pub = myclient.pubrel(packet.messageIdentifier)
   if pub:
     if self.publish_on_pubrel:
       self.broker.publish(myclient.id, pub.topicName, pub.data, pub.fh.QoS, pub.fh.RETAIN)
       del myclient.inbound[packet.messageIdentifier]
     else:
       myclient.inbound.remove(packet.messageIdentifier)
   resp = MQTTV3.Pubcomps()
   logger.info("[MQTT-2.3.1-6] pubcomp messge id same as publish")
   resp.messageIdentifier = packet.messageIdentifier
   respond(sock, resp)
Exemplo n.º 25
0
 def handleRequest(self, sock):
   "this is going to be called from multiple threads, so synchronize"
   self.lock.acquire()
   terminate = False
   try:
     try:
       raw_packet = MQTTV3.getPacket(sock)
     except:
       raise MQTTV3.MQTTException("[MQTT-4.8.0-1] 'transient error' reading packet, closing connection")
     if raw_packet == None:
       # will message
       self.disconnect(sock, None, terminate=True)
       terminate = True
     else:
       packet = MQTTV3.unpackPacket(raw_packet)
       if packet:
         terminate = self.handlePacket(packet, sock)
       else:
         raise MQTTV3.MQTTException("[MQTT-2.0.0-1] handleRequest: badly formed MQTT packet")
   finally:
     self.lock.release()
   return terminate
Exemplo n.º 26
0
 def handlePacket(self, packet, sock):
   terminate = False
   logger.info("in: "+repr(packet))
   if sock not in self.clients.keys() and packet.fh.MessageType != MQTTV3.CONNECT:
     self.disconnect(sock, packet)
     raise MQTTV3.MQTTException("[MQTT-3.1.0-1] Connect was not first packet on socket")
   else:
     getattr(self, MQTTV3.packetNames[packet.fh.MessageType].lower())(sock, packet)
     if sock in self.clients.keys():
       self.clients[sock].lastPacket = time.time()
   if packet.fh.MessageType == MQTTV3.DISCONNECT:
     terminate = True
   return terminate
Exemplo n.º 27
0
 def publish(self, topic, payload, qos=0, retained=False):
   publish = MQTTV3.Publishes()
   publish.fh.QoS = qos
   publish.fh.RETAIN = retained
   if qos == 0:
     publish.messageIdentifier = 0
   else:
     publish.messageIdentifier = self.__nextMsgid()
     if publish.fh.QoS == 2:
       publish.pubrec_received = False
     self.__receiver.outMsgs[publish.messageIdentifier] = publish
   publish.topicName = topic
   publish.data = payload
   sendtosocket(self.sock, publish.pack())
   return publish.messageIdentifier
Exemplo n.º 28
0
 def handlePacket(self, packet, sock):
     terminate = False
     packet_string = str(packet)
     if len(packet_string) > 256:
         packet_string = packet_string[:255] + '...' + (
             ' payload length:' +
             str(len(packet.data)) if hasattr(packet, "data") else "")
     logger.debug("in: (%d) %s", sock.fileno(), packet_string)
     if sock not in self.clients.keys(
     ) and packet.fh.MessageType != MQTTV3.CONNECT:
         self.disconnect(sock, packet)
         raise MQTTV3.MQTTException(
             "[MQTT-3.1.0-1] Connect was not first packet on socket")
     else:
         getattr(self,
                 MQTTV3.packetNames[packet.fh.MessageType].lower())(sock,
                                                                    packet)
         if sock in self.clients.keys():
             self.clients[sock].lastPacket = time.time()
     if packet.fh.MessageType == MQTTV3.DISCONNECT:
         terminate = True
     return terminate
Exemplo n.º 29
0
 def connect(self, sock, packet):
     if packet.ProtocolName != "MQTT":
         self.disconnect(sock, None)
         raise MQTTV3.MQTTException(
             "[MQTT-3.1.2-1] Wrong protocol name %s" % packet.ProtocolName)
     if packet.ProtocolVersion != 4:
         logger.error("[MQTT-3.1.2-2] Wrong protocol version %d",
                      packet.ProtocolVersion)
         resp = MQTTV3.Connacks()
         resp.returnCode = 1
         respond(sock, 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 MQTTV3.MQTTException("[MQTT-3.1.0-2] Second connect packet")
     if len(packet.ClientIdentifier) == 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 = MQTTV3.Connacks()
             resp.returnCode = 2
             respond(sock, 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.ClientIdentifier = 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.ClientIdentifier)
     logger.info(
         "[MQTT-3.1.3-5] Clientids of 1 to 23 chars and ascii alphanumeric must be allowed"
     )
     if packet.ClientIdentifier 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.ClientIdentifier:
                 logger.info("[MQTT-3.1.4-2] Disconnecting old client %s",
                             packet.ClientIdentifier)
                 self.disconnect(s, None)
                 break
     me = None
     if not packet.CleanSession:
         me = self.broker.getClient(
             packet.ClientIdentifier
         )  # find existing state, if there is any
         if me:
             logger.info(
                 "[MQTT-3.1.3-2] clientid used to retrieve client state")
     resp = MQTTV3.Connacks()
     resp.flags = 0x01 if me else 0x00
     if me == None:
         me = MQTTClients(packet.ClientIdentifier, packet.CleanSession,
                          packet.KeepAliveTimer, sock, self)
     else:
         me.socket = sock  # set existing client state to new socket
         me.cleansession = packet.CleanSession
         me.keepalive = packet.KeepAliveTimer
     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, resp)
     me.resend()
Exemplo n.º 30
0
 def handle(self):
     if not hasattr(self, "ids"):
         self.ids = {}
     if not hasattr(self, "versions"):
         self.versions = {}
     inbuf = True
     i = o = e = None
     try:
         clients = self.request
         brokers = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         brokers.connect((brokerhost, brokerport))
         while inbuf != None:
             (i, o, e) = select.select([clients, brokers], [], [])
             for s in i:
                 if s == clients:
                     inbuf = MQTTV3.getPacket(clients)  # get one packet
                     if inbuf == None:
                         break
                     try:
                         packet = MQTTV3.unpackPacket(inbuf)
                         if (
                             packet.fh.MessageType == MQTTV3.PUBLISH
                             and packet.topicName == "MQTTSAS topic"
                             and packet.data == "TERMINATE"
                         ):
                             print("Terminating client", self.ids[id(clients)])
                             brokers.close()
                             clients.close()
                             break
                         else:
                             if packet.fh.MessageType == MQTTV3.CONNECT:
                                 self.ids[id(clients)] = packet.ClientIdentifier
                                 self.versions[id(clients)] = 3
                         wx.CallAfter(myWindow.log, timestamp(), "C to S", self.ids[id(clients)], repr(packet))
                     except:
                         traceback.print_exc()
                         # next line should not be needed once things work properly
                         print("C to S", timestamp(), repr(inbuf))
                         sys.exit()
                     # print "C to S", timestamp(), repr(inbuf)
                     brokers.send(inbuf)  # pass it on
                 elif s == brokers:
                     inbuf = MQTTV3.getPacket(brokers)  # get one packet
                     if inbuf == None:
                         break
                     try:
                         wx.CallAfter(
                             myWindow.log,
                             timestamp(),
                             "S to C",
                             self.ids[id(clients)],
                             repr(MQTTV3.unpackPacket(inbuf)),
                         )
                     except:
                         traceback.print_exc()
                         # next line should not be needed once things work properly
                         print("S to C", timestamp(), repr(inbuf))
                         sys.exit()
                     # print "S to C", timestamp(), repr(inbuf)
                     clients.send(inbuf)
         wx.CallAfter(myWindow.status, timestamp() + " client " + self.ids[id(clients)] + " connection closing")
     except:
         print(repr((i, o, e)), repr(inbuf))
         traceback.print_exc()
     if self.ids.has_key(id(clients)):
         del self.ids[id(clients)]
     elif self.versions.has_key(id(clients)):
         del self.versions[id(clients)]
Exemplo n.º 31
0
def pubrel(pubrec: "pubrecs"):  # pubrecs are observable events
    sockid, pubrec = pubrec
    sock = state.sockets[sockid]
    pubrel = MQTTV3.Pubrels()
    pubrel.messageIdentifier = pubrec.messageIdentifier
    sock.send(pubrel.pack())
Exemplo n.º 32
0
def pingreq():
    pingreq = MQTTV3.Pingreqs()
    state.sockets[0].send(pingreq.pack())
Exemplo n.º 33
0
    def receive(self, callback=None):
        packet = None
        try:
            packet = MQTTV3.unpackPacket(MQTTV3.getPacket(self.socket))
        except:
            if not self.stopping and sys.exc_info()[0] != socket.timeout:
                logging.error("receive: unexpected exception %s",
                              str(sys.exc_info()))
                #traceback.print_exc()
                raise
        if packet == None:
            time.sleep(0.1)
            return
        logging.debug("in :%s", str(packet))

        if packet.fh.MessageType == MQTTV3.SUBACK:
            if hasattr(callback, "subscribed"):
                callback.subscribed(packet.messageIdentifier, packet.data)

        elif packet.fh.MessageType == MQTTV3.UNSUBACK:
            if hasattr(callback, "unsubscribed"):
                callback.unsubscribed(packet.messageIdentifier)

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

        elif packet.fh.MessageType == MQTTV3.PUBREC:
            if packet.messageIdentifier in self.outMsgs.keys():
                self.outMsgs[packet.messageIdentifier].pubrec_received == True
                self.pubrel.messageIdentifier = packet.messageIdentifier
                logging.debug("out: %s", str(self.pubrel))
                self.socket.send(self.pubrel.pack())
            else:
                raise Exception("PUBREC received for unknown msg id "+ \
                            str(packet.messageIdentifier))

        elif packet.fh.MessageType == MQTTV3.PUBREL:
            "release QOS 2 publication to client, & send PUBCOMP"
            msgid = packet.messageIdentifier
            if packet.messageIdentifier not in self.inMsgs.keys():
                pass  # what should we do here?
            else:
                pub = self.inMsgs[packet.messageIdentifier]
                if callback == None or \
                   callback.publishArrived(pub.topicName, pub.data, 2,
                                   pub.fh.RETAIN, pub.messageIdentifier):
                    del self.inMsgs[packet.messageIdentifier]
                    self.pubcomp.messageIdentifier = packet.messageIdentifier
                    logging.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.messageIdentifier)

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

        elif packet.fh.MessageType == MQTTV3.PUBLISH:
            if self.paused:
                return
            if packet.fh.QoS == 0:
                if callback == None:
                    return (packet.topicName, packet.data, 0, packet.fh.RETAIN,
                            packet.messageIdentifier)
                else:
                    callback.publishArrived(packet.topicName, packet.data, 0,
                                            packet.fh.RETAIN,
                                            packet.messageIdentifier)
            elif packet.fh.QoS == 1:
                if callback == None:
                    return (packet.topicName, packet.data, 1, packet.fh.RETAIN,
                            packet.messageIdentifier)
                else:
                    if callback.publishArrived(packet.topicName, packet.data,
                                               1, packet.fh.RETAIN,
                                               packet.messageIdentifier):
                        self.puback.messageIdentifier = packet.messageIdentifier
                        logging.debug("out: %s", str(self.puback))
                        self.socket.send(self.puback.pack())
            elif packet.fh.QoS == 2:
                self.inMsgs[packet.messageIdentifier] = packet
                self.pubrec.messageIdentifier = packet.messageIdentifier
                logging.debug("out: %s", str(self.pubrec))
                self.socket.send(self.pubrec.pack())

        else:
            raise Exception("Unexpected packet" + str(packet))
Exemplo n.º 34
0
  def receive(self, callback=None):
    packet = None
    try:
      packet = MQTTV3.unpackPacket(MQTTV3.getPacket(self.socket))
    except:
      if not self.stopping and sys.exc_info()[0] != socket.timeout:
        logging.error("receive: unexpected exception %s", str(sys.exc_info()))
        #traceback.print_exc()
        raise
    if packet == None:
      time.sleep(0.1)
      return
    logging.debug("in :%s", str(packet))

    if packet.fh.MessageType == MQTTV3.SUBACK:
      if hasattr(callback, "subscribed"):
        callback.subscribed(packet.messageIdentifier, packet.data)

    elif packet.fh.MessageType == MQTTV3.UNSUBACK:
      if hasattr(callback, "unsubscribed"):
        callback.unsubscribed(packet.messageIdentifier)

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

    elif packet.fh.MessageType == MQTTV3.PUBREC:
      if packet.messageIdentifier in self.outMsgs.keys():
        self.outMsgs[packet.messageIdentifier].pubrec_received == True
        self.pubrel.messageIdentifier = packet.messageIdentifier
        logging.debug("out: %s", str(self.pubrel))
        self.socket.send(self.pubrel.pack())
      else:
        raise Exception("PUBREC received for unknown msg id "+ \
                    str(packet.messageIdentifier))

    elif packet.fh.MessageType == MQTTV3.PUBREL:
      "release QOS 2 publication to client, & send PUBCOMP"
      msgid = packet.messageIdentifier
      if packet.messageIdentifier not in self.inMsgs.keys():
        pass # what should we do here?
      else:
        pub = self.inMsgs[packet.messageIdentifier]
        if callback == None or \
           callback.publishArrived(pub.topicName, pub.data, 2,
                           pub.fh.RETAIN, pub.messageIdentifier):
          del self.inMsgs[packet.messageIdentifier]
          self.pubcomp.messageIdentifier = packet.messageIdentifier
          logging.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.messageIdentifier)

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

    elif packet.fh.MessageType == MQTTV3.PUBLISH:
      if self.paused:
        return
      if packet.fh.QoS == 0:
        if callback == None:
          return (packet.topicName, packet.data, 0,
                           packet.fh.RETAIN, packet.messageIdentifier)
        else:
          callback.publishArrived(packet.topicName, packet.data, 0,
                        packet.fh.RETAIN, packet.messageIdentifier)
      elif packet.fh.QoS == 1:
        if callback == None:
          return (packet.topicName, packet.data, 1,
                           packet.fh.RETAIN, packet.messageIdentifier)
        else:
          if callback.publishArrived(packet.topicName, packet.data, 1,
                           packet.fh.RETAIN, packet.messageIdentifier):
            self.puback.messageIdentifier = packet.messageIdentifier
            logging.debug("out: %s", str(self.puback))
            self.socket.send(self.puback.pack())
      elif packet.fh.QoS == 2:
        self.inMsgs[packet.messageIdentifier] = packet
        self.pubrec.messageIdentifier = packet.messageIdentifier
        logging.debug("out: %s", str(self.pubrec))
        self.socket.send(self.pubrec.pack())

    else:
      raise Exception("Unexpected packet"+str(packet))
Exemplo n.º 35
0
 def pingreq(self, sock, packet):
     resp = MQTTV3.Pingresps()
     logger.info("[MQTT-3.12.4-1] sending pingresp in response to pingreq")
     respond(sock, resp)
Exemplo n.º 36
0
def pubcomp(pubrel: "pubrels"):
    sockid, pubrel = pubrel
    sock = state.sockets[sockid]
    pubcomp = MQTTV3.Pubcomps()
    pubcomp.messageIdentifier = pubrel.messageIdentifier
    sock.send(pubcomp.pack())