Giter VIP home page Giter VIP logo

Comments (5)

jedidiahuang avatar jedidiahuang commented on May 29, 2024 1

Hi Liam,

you missed to fix application_message_size in mqtt.c after line 1167

1163 if (response->qos_level > 0) {
1116 response->packet_id = (uint16_t) MQTT_PAL_NTOHS(*(uint16_t*) buf);
1165 buf += 2;
1166 }
1167
1168 /* get payload */
1169 response->application_message = buf;
1170 if ( response->qos_level > 0)
1171 response->application_message_size = fixed_header->remaining_length - response->topic_name_size - 4;
1172 else response->application_message_size = fixed_header->remaining_length - response->topic_name_size - 2;

Now mqtt.c is working very well for subscribing topics, Thanks a lot.

Best Regards,
Jedidiahuang

from mqtt-c.

jedidiahuang avatar jedidiahuang commented on May 29, 2024 1

Hi Liam

For mqtt_publish() , there is still have 1 bug code in mqtt.c line 1093
1092 /* calculate remaining length */
1093 remaining_length = __mqtt_packed_cstrlen(topic_name) + 2; /* variable header size */

This bug will cause an error: MQTT_ERROR_SOCKET_ERROR if publishing QoS 0 topic.

I corrected line 1093 as below, and it works well now
1093 remaining_length = __mqtt_packed_cstrlen(topic_name);
1094 if ((publish_flags & 0x06) != 0) remaining_length +=2;

Best Regards,
Jedidiahuang

from mqtt-c.

LiamBindle avatar LiamBindle commented on May 29, 2024

Hi Jedidiahuang,

Thanks for the issue submission, this is a bug and I've managed to locate it. First I'll highlight how I reproduced your error, then I'll explain the bug.

Reproducing the bug

You are correct, it looks like something is wrong with the first two bytes of the application message. I was able to reproduce what you see using a local Mosquitto broker. This is what I see.


Broker:

$ mosquitto -v -p 1884                             
1525878911: mosquitto version 1.4.8 (build date Thu, 01 Mar 2018 09:34:49 -0500) starting
1525878911: Using default config.
1525878911: Opening ipv4 listen socket on port 1884.
1525878911: Opening ipv6 listen socket on port 1884.
1525878935: New connection from 127.0.0.1 on port 1884.
1525878935: New client connected from 127.0.0.1 as publishing_client (c0, k400).
1525878935: Sending CONNACK to publishing_client (0, 0)
1525878948: New connection from 127.0.0.1 on port 1884.
1525878948: New client connected from 127.0.0.1 as subscribing_client (c0, k400).
1525878948: Sending CONNACK to subscribing_client (0, 0)
1525878948: Received SUBSCRIBE from subscribing_client
1525878948: 	datetime (QoS 0)
1525878948: subscribing_client 0 datetime
1525878948: Sending SUBACK to subscribing_client
1525878959: New connection from 127.0.0.1 on port 1884.
1525878959: New client connected from 127.0.0.1 as mosqsub/5264-workstatio (c1, k60).
1525878959: Sending CONNACK to mosqsub/5264-workstatio (0, 0)
1525878959: Received SUBSCRIBE from mosqsub/5264-workstatio
1525878959: 	datetime (QoS 0)
1525878959: mosqsub/5264-workstatio 0 datetime
1525878959: Sending SUBACK to mosqsub/5264-workstatio
1525878967: Received PUBLISH from publishing_client (d0, q0, r0, m0, 'datetime', ... (34 bytes))
1525878967: Sending PUBLISH to subscribing_client (d0, q0, r0, m0, 'datetime', ... (34 bytes))
1525878967: Sending PUBLISH to mosqsub/5264-workstatio (d0, q0, r0, m0, 'datetime', ... (34 bytes))
1525878969: Received PUBLISH from publishing_client (d0, q0, r0, m0, 'datetime', ... (34 bytes))
1525878969: Sending PUBLISH to subscribing_client (d0, q0, r0, m0, 'datetime', ... (34 bytes))
1525878969: Sending PUBLISH to mosqsub/5264-workstatio (d0, q0, r0, m0, 'datetime', ... (34 bytes))
^C1525878978: mosquitto version 1.4.8 terminating

Publisher (simple_publisher.c):

$ ./bin/simple_publisher 0.0.0.0 1884  
./bin/simple_publisher is ready to begin publishing the time.
Press ENTER to publish the current time.
Press CTRL-D (or any other key) to exit.


./bin/simple_publisher published : "The time is 2018-05-09 09:16:07"
./bin/simple_publisher published : "The time is 2018-05-09 09:16:09"
./bin/simple_publisher disconnecting from 0.0.0.0

Mosquitto Subscriber:

$ mosquitto_sub -h localhost -p 1884 -v -t datetime
datetime �QThe time is 2018-05-09 09:16:07
datetime �(The time is 2018-05-09 09:16:09

I found that I could reproduce these bad characters with simple_subscriber.c by changing this line

printf("Received publish('%s'): %s\n", topic_name, (const char*) published->application_message);

to

printf("Received publish('%s'): %s\n", topic_name, (const char*) published->application_message - 2); 

The resulting output was this:

$ ./bin/simple_subscriber 0.0.0.0 1884 
./bin/simple_subscriber listening for 'datetime' messages.
Press CTRL-D to exit.

Received publish('datetime'): �QThe time is 2018-05-09 09:16:07
Received publish('datetime'): �(The time is 2018-05-09 09:16:09

Diagnosing the bug

One thing to notice is that the first character is always "�Q" and the second character is "�(". The last two characters of the variable header (two bytes preceding the payload) are the packet ID. MQTT-C uses an LFSR to generate packet ID's which would explain why the same sequence of bad characters shows up.

It turns our packet ID's are only supposed to be included in the variable header for PUBLISH's with QOS > 0 (see mqtt-v3.1.1.pdf line 799-801). In mqtt_pack_publish_request packet ID's are being included in the variable header for all QoS levels (see snippet below). This means that this bug should only be present for PUBLISH's with QoS 0.

MQTT-C/src/mqtt.c

Lines 1124 to 1131 in 5e18fed

/* pack variable header */
buf += __mqtt_pack_str(buf, topic_name);
*(uint16_t*) buf = (uint16_t) MQTT_PAL_HTONS(packet_id);
buf += 2;
/* pack payload */
memcpy(buf, application_message, application_message_size);
buf += application_message_size;

How to fix

This is actually an easy fix. We only want to include the variable header iff (publish_flags & 0x06) != 0 (i.e. QoS is not 0). This means that changing lines 1126-1127 to:

1126        if ((publish_flags & 0x06) != 0) {
1127            *(uint16_t*) buf = (uint16_t) MQTT_PAL_HTONS(packet_id);
1128            buf += 2;
1129        }

Additionally, the PUBLISH response unpacker (mqtt_unpack_publish_response lines 1163-1164) needs to be updated to only unpack PID's if QoS > 0.

1163        if (response->qos_level > 0) {
1116            response->packet_id = (uint16_t) MQTT_PAL_NTOHS(*(uint16_t*) buf);
1165            buf += 2;
1166        }

Thanks for bringing this up! I will fix this tonight or tomorrow.

Best regards,

Liam

from mqtt-c.

jedidiahuang avatar jedidiahuang commented on May 29, 2024

from mqtt-c.

LiamBindle avatar LiamBindle commented on May 29, 2024

Hi Jedidiahuang,

Oh right, thanks, I forgot both of those will need to be updated.

Do you want to make a pull request with the updates? If not, I can implement those changes this weekend.

Liam

from mqtt-c.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.