def publish(self, sock, packet): packet.receivedTime = time.monotonic() if packet.topicName.find("+") != -1 or packet.topicName.find("#") != -1: raise MQTTV5.AcksProtocolError("Topic name invalid %s" % packet.topicName) # Test Topic to disconnect the client if packet.topicName.startswith("cmd/"): self.handleBehaviourPublish(sock, packet.topicName, packet.data) else: if len(self.clients[sock].inbound) >= self.receiveMaximum: self.disconnect(sock, reasonCode="Receive maximum exceeded", sendWillMessage=True) elif packet.fh.QoS == 0: self.broker.publish(self.clients[sock].id, packet.topicName, packet.data, packet.fh.QoS, packet.properties, packet.receivedTime, packet.fh.RETAIN) 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.properties, packet.receivedTime, packet.fh.RETAIN) resp = MQTTV5.Pubacks() logger.info("[MQTT-2.3.1-6] puback messge id same as publish") resp.packetIdentifier = packet.packetIdentifier respond(sock, resp) elif packet.fh.QoS == 2: myclient = self.clients[sock] if self.publish_on_pubrel: if packet.packetIdentifier 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.packetIdentifier) else: logger.info("[MQTT-3.3.1-2] DUP flag is 1 on redelivery") else: myclient.inbound[packet.packetIdentifier] = packet else: if packet.packetIdentifier 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.packetIdentifier) else: logger.info("[MQTT-3.3.1-2] DUP flag is 1 on redelivery") else: myclient.inbound.append(packet.packetIdentifier) 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.properties, packet.receivedTime, packet.fh.RETAIN) resp = MQTTV5.Pubrecs() logger.info("[MQTT-2.3.1-6] pubrec messge id same as publish") resp.packetIdentifier = packet.packetIdentifier respond(sock, resp)
def publish(self, sock, packet): packet.receivedTime = time.monotonic() if packet.topicName.find("+") != -1 or packet.topicName.find( "#") != -1: raise MQTTV5.AcksProtocolError("Topic name invalid %s" % packet.topicName) # Test Topic to disconnect the client if packet.topicName.startswith("cmd/"): self.handleBehaviourPublish(sock, packet.topicName, packet.data) else: if len(self.clients[sock].inbound ) >= self.options["receiveMaximum"]: self.disconnect(sock, reasonCode="Receive maximum exceeded", sendWillMessage=True) return if hasattr(packet.properties, "UserProperty") and len( packet.properties.UserProperty) > 1: logger.info( "[MQTT-3.1.3-10] Must maintain order of user properties") if packet.fh.QoS == 0: self.broker.publish(self.clients[sock].id, packet.topicName, packet.data, packet.fh.QoS, packet.fh.RETAIN, packet.properties, 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" ) subscribers = self.broker.publish(self.clients[sock].id, packet.topicName, packet.data, packet.fh.QoS, packet.fh.RETAIN, packet.properties, packet.receivedTime) resp = MQTTV5.Pubacks() logger.info( "[MQTT5-2.2.1-5-puback] puback message id same as publish") resp.packetIdentifier = packet.packetIdentifier if subscribers == None: resp.reasonCode.set("No matching subscribers") if packet.topicName == "test_qos_1_2_errors": # specific error behaviour for testing resp.reasonCode.set("Not authorized") if hasattr(packet.properties, "UserProperty"): resp.properties.UserProperty = packet.properties.UserProperty respond(sock, resp) elif packet.fh.QoS == 2: myclient = self.clients[sock] subscribers = None if self.options["publish_on_pubrel"]: if packet.packetIdentifier 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.packetIdentifier) else: logger.info( "[MQTT-3.3.1-2] DUP flag is 1 on redelivery") else: myclient.inbound[packet.packetIdentifier] = packet if len(packet.topicName) == 0 and hasattr( packet.properties, "TopicAlias"): packet.topicName = self.broker.getAliasTopic( self.clients[sock].id, packet.properties.TopicAlias) subscribers = self.broker.se.getSubscriptions( packet.topicName) else: if packet.packetIdentifier 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.packetIdentifier) else: logger.info( "[MQTT-3.3.1-2] DUP flag is 1 on redelivery") else: myclient.inbound.append(packet.packetIdentifier) logger.info( "[MQTT-4.3.3-2] server must store message in accordance with QoS 2" ) if len(packet.topicName) == 0 and hasattr( packet.properties, "TopicAlias"): packet.topicName = self.broker.getAliasTopic( self.clients[sock].id, packet.properties.TopicAlias) subscribers = self.broker.publish( self.clients[sock].id, packet.topicName, packet.data, packet.fh.QoS, packet.fh.RETAIN, packet.properties, packet.receivedTime) if packet.topicName == "test_qos_1_2_errors_pubcomp": myclient.pubcomp_error = packet.packetIdentifier resp = MQTTV5.Pubrecs() logger.info( "[MQTT5-2.2.1-5-pubrec] pubrec message id same as publish") resp.packetIdentifier = packet.packetIdentifier if subscribers == None: resp.reasonCode.set("No matching subscribers") if hasattr(packet, "topicName" ) and packet.topicName == "test_qos_1_2_errors": resp.reasonCode.set("Not authorized") if self.options["publish_on_pubrel"]: del myclient.inbound[packet.packetIdentifier] else: myclient.inbound.remove(packet.packetIdentifier) if hasattr(packet.properties, "UserProperty"): resp.properties.UserProperty = packet.properties.UserProperty respond(sock, resp)