From a0dd3ecd681f2ba4ccedbfa8a95261c38e5a5b84 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 7 Jun 2023 06:47:11 -0400 Subject: [PATCH] byte-encoded properties issue fixed --- mongoose.c | 26 ++++++++++++++++++-------- src/mqtt.c | 28 +++++++++++++++++++--------- test/unit_test.c | 13 +++++++++---- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/mongoose.c b/mongoose.c index 06cec604..81d31616 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3062,9 +3062,17 @@ static size_t get_properties_length(struct mg_mqtt_prop *props, size_t count) { case MQTT_PROP_TYPE_VARIABLE_INT: size += compute_variable_length_size((uint32_t) props[i].iv); break; - case MQTT_PROP_TYPE_INT: size += (uint32_t) sizeof(uint32_t); break; - case MQTT_PROP_TYPE_SHORT: size += (uint32_t) sizeof(uint16_t); break; - default: return size; // cannot parse further down + case MQTT_PROP_TYPE_INT: + size += (uint32_t) sizeof(uint32_t); + break; + case MQTT_PROP_TYPE_SHORT: + size += (uint32_t) sizeof(uint16_t); + break; + case MQTT_PROP_TYPE_BYTE: + size += (uint32_t) sizeof(uint8_t); + break; + default: + return size; // cannot parse further down } } @@ -3168,7 +3176,8 @@ size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop, prop->iv = decode_variable_length((char *) i, &bytes_consumed); new_pos += bytes_consumed; break; - default: new_pos = 0; + default: + new_pos = 0; } return new_pos; @@ -3340,7 +3349,8 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version, m->data.len = (size_t) (end - p); break; } - default: break; + default: + break; } return MQTT_OK; } @@ -3375,7 +3385,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data, if (mm.qos > 0) { uint16_t id = mg_ntohs(mm.id); uint32_t remaining_len = sizeof(id); - if (c->is_mqtt5) remaining_len += 2; // 3.4.2 + if (c->is_mqtt5) remaining_len += 2; // 3.4.2 mg_mqtt_send_header( c, mm.qos == 2 ? MQTT_CMD_PUBREC : MQTT_CMD_PUBACK, 0, @@ -3390,14 +3400,14 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data, mg_call(c, MG_EV_MQTT_MSG, &mm); // let the app handle qos stuff break; } - case MQTT_CMD_PUBREC: { // MQTT5: 3.5.2-1 TODO(): variable header rc + case MQTT_CMD_PUBREC: { // MQTT5: 3.5.2-1 TODO(): variable header rc uint16_t id = mg_ntohs(mm.id); uint32_t remaining_len = sizeof(id); // MQTT5 3.6.2-1 mg_mqtt_send_header(c, MQTT_CMD_PUBREL, 2, remaining_len); mg_send(c, &id, sizeof(id)); // MQTT5 3.6.1-1, flags = 2 break; } - case MQTT_CMD_PUBREL: { // MQTT5: 3.6.2-1 TODO(): variable header rc + case MQTT_CMD_PUBREL: { // MQTT5: 3.6.2-1 TODO(): variable header rc uint16_t id = mg_ntohs(mm.id); uint32_t remaining_len = sizeof(id); // MQTT5 3.7.2-1 mg_mqtt_send_header(c, MQTT_CMD_PUBCOMP, 0, remaining_len); diff --git a/src/mqtt.c b/src/mqtt.c index 00263e8e..fb02cdeb 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -1,8 +1,8 @@ +#include "mqtt.h" #include "arch.h" #include "base64.h" #include "event.h" #include "log.h" -#include "mqtt.h" #include "url.h" #include "util.h" @@ -134,9 +134,17 @@ static size_t get_properties_length(struct mg_mqtt_prop *props, size_t count) { case MQTT_PROP_TYPE_VARIABLE_INT: size += compute_variable_length_size((uint32_t) props[i].iv); break; - case MQTT_PROP_TYPE_INT: size += (uint32_t) sizeof(uint32_t); break; - case MQTT_PROP_TYPE_SHORT: size += (uint32_t) sizeof(uint16_t); break; - default: return size; // cannot parse further down + case MQTT_PROP_TYPE_INT: + size += (uint32_t) sizeof(uint32_t); + break; + case MQTT_PROP_TYPE_SHORT: + size += (uint32_t) sizeof(uint16_t); + break; + case MQTT_PROP_TYPE_BYTE: + size += (uint32_t) sizeof(uint8_t); + break; + default: + return size; // cannot parse further down } } @@ -240,7 +248,8 @@ size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop, prop->iv = decode_variable_length((char *) i, &bytes_consumed); new_pos += bytes_consumed; break; - default: new_pos = 0; + default: + new_pos = 0; } return new_pos; @@ -412,7 +421,8 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version, m->data.len = (size_t) (end - p); break; } - default: break; + default: + break; } return MQTT_OK; } @@ -447,7 +457,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data, if (mm.qos > 0) { uint16_t id = mg_ntohs(mm.id); uint32_t remaining_len = sizeof(id); - if (c->is_mqtt5) remaining_len += 2; // 3.4.2 + if (c->is_mqtt5) remaining_len += 2; // 3.4.2 mg_mqtt_send_header( c, mm.qos == 2 ? MQTT_CMD_PUBREC : MQTT_CMD_PUBACK, 0, @@ -462,14 +472,14 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data, mg_call(c, MG_EV_MQTT_MSG, &mm); // let the app handle qos stuff break; } - case MQTT_CMD_PUBREC: { // MQTT5: 3.5.2-1 TODO(): variable header rc + case MQTT_CMD_PUBREC: { // MQTT5: 3.5.2-1 TODO(): variable header rc uint16_t id = mg_ntohs(mm.id); uint32_t remaining_len = sizeof(id); // MQTT5 3.6.2-1 mg_mqtt_send_header(c, MQTT_CMD_PUBREL, 2, remaining_len); mg_send(c, &id, sizeof(id)); // MQTT5 3.6.1-1, flags = 2 break; } - case MQTT_CMD_PUBREL: { // MQTT5: 3.6.2-1 TODO(): variable header rc + case MQTT_CMD_PUBREL: { // MQTT5: 3.6.2-1 TODO(): variable header rc uint16_t id = mg_ntohs(mm.id); uint32_t remaining_len = sizeof(id); // MQTT5 3.7.2-1 mg_mqtt_send_header(c, MQTT_CMD_PUBCOMP, 0, remaining_len); diff --git a/test/unit_test.c b/test/unit_test.c index 1316476a..ef88d8c6 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -379,10 +379,12 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { size_t pos = 0; struct mg_mqtt_prop prop; - // note: the server will send the properties sorted by their ID ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); ASSERT(prop.iv == 10 && prop.id == MQTT_PROP_MESSAGE_EXPIRY_INTERVAL); + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); + ASSERT(prop.id == MQTT_PROP_PAYLOAD_FORMAT_INDICATOR); + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); ASSERT(prop.id == MQTT_PROP_CONTENT_TYPE); ASSERT(strncmp(prop.val.ptr, "test_content_val_2", prop.val.len) == 0 && @@ -422,6 +424,9 @@ static void construct_props(struct mg_mqtt_prop *props) { props[3].id = MQTT_PROP_CONTENT_TYPE; props[3].val = mg_str("test_content_val_2"); + + props[4].id = MQTT_PROP_PAYLOAD_FORMAT_INDICATOR; + props[4].iv = 1; } static void test_mqtt_base(void); @@ -452,7 +457,7 @@ static void test_mqtt_ver(uint8_t mqtt_version) { struct mg_str topic = mg_str("x/f12"), data = mg_str("hi"); struct mg_connection *c; struct mg_mqtt_opts opts; - struct mg_mqtt_prop properties[4]; + struct mg_mqtt_prop properties[5]; const char *url = "mqtt://broker.hivemq.com:1883"; int i, retries; mg_mgr_init(&mgr); @@ -530,7 +535,7 @@ connect_with_options: opts.topic = topic, opts.message = data, opts.qos = 1, opts.retain = false; if (mqtt_version == 5) { opts.props = properties; - opts.num_props = 4; + opts.num_props = 5; construct_props(properties); } retries = 0; // don't do retries for test speed @@ -548,7 +553,7 @@ connect_with_options: opts.topic = topic, opts.message = data, opts.qos = 2, opts.retain = false; if (mqtt_version == 5) { opts.props = properties; - opts.num_props = 4; + opts.num_props = 5; construct_props(properties); } retries = 0; // don't do retries for test speed