diff --git a/include/libwebsockets/lws-mqtt.h b/include/libwebsockets/lws-mqtt.h index 462374d4f..71193e662 100644 --- a/include/libwebsockets/lws-mqtt.h +++ b/include/libwebsockets/lws-mqtt.h @@ -70,8 +70,10 @@ typedef struct lws_mqtt_client_connect_param_s { uint16_t keep_alive; /* MQTT keep alive interval in seconds */ - uint8_t clean_start; /* MQTT clean + uint8_t clean_start:1; /* MQTT clean session */ + uint8_t client_id_nofree:1; + /**< do not free the client id */ struct { const char *topic; const char *message; @@ -143,6 +145,8 @@ typedef enum { /* flags from byte 8 of C_TO_S CONNECT */ typedef enum { + LMQCFT_CLIENT_ID_NOFREE = (1 << 8), + /* only the low 8 are standardized and go out in the protocol */ LMQCFT_USERNAME = (1 << 7), LMQCFT_PASSWORD = (1 << 6), LMQCFT_WILL_RETAIN = (1 << 5), diff --git a/lib/roles/mqtt/client/client-mqtt-handshake.c b/lib/roles/mqtt/client/client-mqtt-handshake.c index 009838bef..ffdf262d5 100644 --- a/lib/roles/mqtt/client/client-mqtt-handshake.c +++ b/lib/roles/mqtt/client/client-mqtt-handshake.c @@ -77,7 +77,7 @@ lws_mqtt_client_send_connect(struct lws *wsi) *p++ = 'T'; *p++ = 'T'; *p++ = MQTT_VER_3_1_1; - *p++ = c->conn_flags; + *p++ = (uint8_t)c->conn_flags; lws_ser_wu16be(p, c->keep_alive_secs); p += 2; diff --git a/lib/roles/mqtt/client/client-mqtt.c b/lib/roles/mqtt/client/client-mqtt.c index 5ad4471a6..6529fdc99 100644 --- a/lib/roles/mqtt/client/client-mqtt.c +++ b/lib/roles/mqtt/client/client-mqtt.c @@ -120,7 +120,11 @@ lws_create_client_mqtt_object(const struct lws_client_connect_info *i, if (cp->clean_start || !(cp->client_id && cp->client_id[0])) c->conn_flags = LMQCFT_CLEAN_START; - lws_free((void *)cp->client_id); + if (cp->client_id_nofree) + c->conn_flags |= LMQCFT_CLIENT_ID_NOFREE; + + if (!(c->conn_flags & LMQCFT_CLIENT_ID_NOFREE)) + lws_free((void *)cp->client_id); c->keep_alive_secs = cp->keep_alive; c->aws_iot = cp->aws_iot; @@ -138,8 +142,8 @@ lws_create_client_mqtt_object(const struct lws_client_connect_info *i, if (!c->will.message) goto oom2; } - c->conn_flags = (uint8_t)(unsigned int)(c->conn_flags | ((cp->will_param.qos << 3) & LMQCFT_WILL_QOS_MASK)); - c->conn_flags |= (uint8_t)((!!cp->will_param.retain) * LMQCFT_WILL_RETAIN); + c->conn_flags = (uint16_t)(unsigned int)(c->conn_flags | ((cp->will_param.qos << 3) & LMQCFT_WILL_QOS_MASK)); + c->conn_flags |= (uint16_t)((!!cp->will_param.retain) * LMQCFT_WILL_RETAIN); } if (cp->username && diff --git a/lib/roles/mqtt/private-lib-roles-mqtt.h b/lib/roles/mqtt/private-lib-roles-mqtt.h index 4c225bb2b..a1f5d23c3 100644 --- a/lib/roles/mqtt/private-lib-roles-mqtt.h +++ b/lib/roles/mqtt/private-lib-roles-mqtt.h @@ -346,7 +346,7 @@ typedef struct lws_mqttc { uint8_t retain; } will; uint16_t keep_alive_secs; - uint8_t conn_flags; + uint16_t conn_flags; uint8_t aws_iot; } lws_mqttc_t; diff --git a/lib/secure-streams/protocols/ss-mqtt.c b/lib/secure-streams/protocols/ss-mqtt.c index 9c0ec0ee0..2c3c52222 100644 --- a/lib/secure-streams/protocols/ss-mqtt.c +++ b/lib/secure-streams/protocols/ss-mqtt.c @@ -490,7 +490,7 @@ secstream_connect_munge_mqtt(lws_ss_handle_t *h, char *buf, size_t len, } ct->ccp.keep_alive = h->policy->u.mqtt.keep_alive; - ct->ccp.clean_start = h->policy->u.mqtt.clean_start; + ct->ccp.clean_start = (h->policy->u.mqtt.clean_start & 1u); ct->ccp.will_param.qos = h->policy->u.mqtt.will_qos; ct->ccp.will_param.retain = h->policy->u.mqtt.will_retain; ct->ccp.aws_iot = h->policy->u.mqtt.aws_iot; diff --git a/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c b/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c index 948cbbda8..8eb954240 100644 --- a/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c +++ b/minimal-examples/mqtt-client/minimal-mqtt-client/minimal-mqtt-client.c @@ -41,6 +41,7 @@ static const lws_mqtt_client_connect_param_t client_connect_param = { .client_id = "lwsMqttClient", .keep_alive = 60, .clean_start = 1, + .client_id_nofree = 1, .will_param = { .topic = "good/bye", .message = "sign-off",