eclipse / paho.mqtt-sn.embedded-c

Paho C MQTT-SN gateway and libraries for embedded systems. Paho is an Eclipse IoT project.
https://eclipse.org/paho
Other
313 stars 179 forks source link

MQTT-SNGateway - MQTT Publish Message missing corresponding MQTT-SN Topic ID when sending to MQTT-SN client #246

Closed alfredoant3 closed 2 years ago

alfredoant3 commented 2 years ago

Hello,

I would appreciate some help with an issue I am having with the MQTT-SNGateway. Right now, I have an MQTT-SN client connected to the Paho MQTT-SN gateway in order to engage with an MQTT Broker. The Broker is sending the Gateway A Publish Message to a topic that the MQTT-SN Client is subscribed to. The Publish message is QoS1.

The problem is that the Gateway is packaging the message into MQTT-SN with a bad Topic ID.

For example, instead of sending the MQTT-SN message with a Topic ID of 9, it sends a Topic ID of 3132 (Which is way off). My MQTT-SN Client receives the message and essentially does not do anything with it because it was not the expected Topic ID.

In the perfect scenario, the Gateway should process the MQTT message and repackage into MQTT-SN message with the Topic ID which is corresponding to the Topic name from the original MQTT message.

Has any of you experienced this issue? Is there an additional step that my application has to do to handle this appropriately?

I was looking into the MQTT-SNGateway source code, I found a potential area where could explain this behavior in MQTTGWPublishHandler.cpp in line 97 (develop branch). In this line, I see that we are retrieving a topic object by the Topic name received from the Publish message.

Topic* tp = client->getTopics()->getTopicByName(&topicId);

In my case, the Topic object should exist, so we should fall into the case in line 99. I see here that the topicId type is being set from the retrieved topic object.

if (tp) { topicId.type = tp->getType(); topicId.data.long_.len = pub.topiclen; topicId.data.long_.name = pub.topic; }

But, I do not see the topicId.data.id being set around here. The the next thing that happens is we go directly to line 181 to package the publish message. The message type in this case would be MQTTSN_TOPIC_TYPE_NORMAL and QoS1. Therefore, in MQTTSNSerializePublish.c we fall in line 84 where the topic id is set as part of the message. Here is where the random topic ID is set (in the example above 3132).

if (topic.type == MQTTSN_TOPIC_TYPE_NORMAL && qos == 3) { /* special arrangement for long topic names in QoS -1 publishes. The length of the topic is in the topicid field */ writeInt(&ptr, topic.data.long_.len); /* topic length */ } else if (topic.type == MQTTSN_TOPIC_TYPE_NORMAL || topic.type == MQTTSN_TOPIC_TYPE_PREDEFINED) writeInt(&ptr, topic.data.id); else { writeChar(&ptr, topic.data.short_name[0]); writeChar(&ptr, topic.data.short_name[1]); }

Is it that we must set topicId.data.id somewhere in MQTTGWPublishHandler.cpp?

Thank you very much for the support.

ty4tw commented 2 years ago

Hi alfredoant3 ,

Thank you for your effort.

your are right.

topicId.data.id = tp->getTopicId();  

was deleted by previous commit, 15c527e.

if (tp)
        {
            topicId.type = tp->getType();
            topicId.data.long_.len = pub.topiclen;
            topicId.data.long_.name = pub.topic;
            topicId.data.id = tp->getTopicId();
        }

I will revert it.

alfredoant3 commented 2 years ago

Excellent! Thank you for responding so promptly. I will look forward to the update. I appreciate it.