diff --git a/include/libwebsockets/lws-mqtt.h b/include/libwebsockets/lws-mqtt.h index cbf8b3637..32e1d278e 100644 --- a/include/libwebsockets/lws-mqtt.h +++ b/include/libwebsockets/lws-mqtt.h @@ -33,6 +33,11 @@ struct lws_mqtt_str_st; typedef struct lws_mqtt_str_st lws_mqtt_str_t; #define MQTT_VER_3_1_1 4 +#if MQTT_VER_3_1_1 == 4 + #define MQTT_VER_STRING "3.1.1" +#else + #define MQTT_VER_STRING "unknown" +#endif #define LWS_MQTT_FINAL_PART 1 diff --git a/lib/roles/mqtt/client/client-mqtt.c b/lib/roles/mqtt/client/client-mqtt.c index ada9cffb9..8dd300a1f 100644 --- a/lib/roles/mqtt/client/client-mqtt.c +++ b/lib/roles/mqtt/client/client-mqtt.c @@ -338,8 +338,28 @@ lws_mqtt_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd, else n = lws_read_mqtt(wsi, ebuf.token, (unsigned int)ebuf.len); if (n < 0) { - lwsl_err("%s: Parsing packet failed\n", __func__); - goto fail; + lws_mqttc_t *c = &wsi->mqtt->client; + char msgBuffer[128]; + switch (c->par.reason) { + case LMQCP_REASON_UNSUPPORTED_PROTOCOL: + snprintf(msgBuffer, sizeof(msgBuffer), "reason: %s %s\n", "server does not support MQTT protocol", MQTT_VER_STRING); + break; + case LMQCP_REASON_CLIENT_ID_INVALID: + snprintf(msgBuffer, sizeof(msgBuffer), "reason: %s %.*s\n", "server does not accept client ID", c->id->len, c->id->buf); + break; + case LMQCP_REASON_BAD_CREDENTIALS: + snprintf(msgBuffer, sizeof(msgBuffer), "reason: %s\n", "invalid credentials"); + break; + case LMQCP_REASON_NOT_AUTHORIZED: + snprintf(msgBuffer, sizeof(msgBuffer), "reason: %s\n", "not authorized"); + break; + default: + snprintf(msgBuffer, sizeof(msgBuffer), "reason: %s\n", "unknown MQTT connection failure"); + break; + } + lws_inform_client_conn_fail(wsi, (void *)msgBuffer, strlen(msgBuffer)); + lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, __func__); + return -1; } m = ebuf.len - n; diff --git a/lib/roles/mqtt/mqtt.c b/lib/roles/mqtt/mqtt.c index 9e9dd5a80..64829050c 100644 --- a/lib/roles/mqtt/mqtt.c +++ b/lib/roles/mqtt/mqtt.c @@ -1029,17 +1029,27 @@ _lws_mqtt_rx_parser(struct lws *wsi, lws_mqtt_parser_t *par, switch (par->conn_rc) { case 0: goto cmd_completion; + /* 3.1.1 errors [MQTT-3.2.3] */ case 1: + par->reason = LMQCP_REASON_UNSUPPORTED_PROTOCOL; + goto send_reason_and_close; case 2: + par->reason = LMQCP_REASON_CLIENT_ID_INVALID; + goto send_reason_and_close; case 3: + par->reason = LMQCP_REASON_SERVER_UNAVAILABLE; + goto send_reason_and_close; case 4: + par->reason = LMQCP_REASON_BAD_CREDENTIALS; + goto send_reason_and_close; case 5: - par->reason = LMQCP_REASON_UNSUPPORTED_PROTOCOL + - par->conn_rc - 1; + par->reason = LMQCP_REASON_NOT_AUTHORIZED; goto send_reason_and_close; + /* 5.0 and all other errors [MQTT-3.2.2.2] */ default: + par->reason = (lws_mqtt_reason_t)par->conn_rc; lwsl_notice("%s: bad connack retcode\n", __func__); - goto send_protocol_error_and_close; + goto send_reason_and_close; } break;