diff --git a/MQTTClient-C/src/CMakeLists.txt b/MQTTClient-C/src/CMakeLists.txt index 632ca4d7..331196a1 100644 --- a/MQTTClient-C/src/CMakeLists.txt +++ b/MQTTClient-C/src/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2017 IBM Corp. +# Copyright (c) 2017, 2023 IBM Corp. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 @@ -26,10 +26,12 @@ target_link_libraries(paho-embed-mqtt3cc paho-embed-mqtt3c) target_compile_definitions(paho-embed-mqtt3cc PRIVATE MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h MQTTCLIENT_QOS2=1) -file(GLOB SOURCES "*.c" "V5/*.c" "linux/*.c") -add_library(paho-embed-mqtt5cc SHARED ${SOURCES}) -install(TARGETS paho-embed-mqtt5cc DESTINATION /usr/lib) -target_include_directories(paho-embed-mqtt5cc PRIVATE "linux") -target_link_libraries(paho-embed-mqtt5cc paho-embed-mqtt5c) -target_compile_definitions(paho-embed-mqtt5cc PRIVATE - MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h MQTTCLIENT_QOS2=1 MQTTV5) +# TODO: Temporarily disable MQTT v5 +# +# file(GLOB SOURCES "*.c" "V5/*.c" "linux/*.c") +# add_library(paho-embed-mqtt5cc SHARED ${SOURCES}) +# install(TARGETS paho-embed-mqtt5cc DESTINATION /usr/lib) +# target_include_directories(paho-embed-mqtt5cc PRIVATE "linux") +# target_link_libraries(paho-embed-mqtt5cc paho-embed-mqtt5c) +# target_compile_definitions(paho-embed-mqtt5cc PRIVATE +# MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h MQTTCLIENT_QOS2=1 MQTTV5) diff --git a/MQTTClient-C/src/MQTTClient.h b/MQTTClient-C/src/MQTTClient.h index fe9c3c10..47328878 100755 --- a/MQTTClient-C/src/MQTTClient.h +++ b/MQTTClient-C/src/MQTTClient.h @@ -35,7 +35,7 @@ #endif #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif /* MQTTV5 */ diff --git a/MQTTClient-C/src/V5/MQTTV5Client.h b/MQTTClient-C/src/V5/MQTTV5Client.h index f87305ff..a32259d5 100755 --- a/MQTTClient-C/src/V5/MQTTV5Client.h +++ b/MQTTClient-C/src/V5/MQTTV5Client.h @@ -21,7 +21,7 @@ #include #include "../MQTTClient.h" -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" /** diff --git a/MQTTClient/src/MQTTClient.h b/MQTTClient/src/MQTTClient.h index a8258f0e..791ae02c 100644 --- a/MQTTClient/src/MQTTClient.h +++ b/MQTTClient/src/MQTTClient.h @@ -421,10 +421,16 @@ int MQTT::Client::sendPacket(int32_t length, Timer& timer) rc = FAILURE; #if defined(MQTT_DEBUG) + char printbuf[150]; DEBUG("Rc %d from sending packet %s\r\n", rc, +#if defined(MQTTV5) + MQTTV5Format_toServerString(printbuf, sizeof(printbuf), sendbuf, length)); +#else MQTTFormat_toServerString(printbuf, sizeof(printbuf), sendbuf, length)); -#endif +#endif // MQTTV5 + +#endif // MQTT_DEBUG return rc; } @@ -503,7 +509,12 @@ int MQTT::Client::readPacket(Timer& tim { char printbuf[50]; DEBUG("Rc %d receiving packet %s\r\n", rc, - MQTTFormat_toClientString(printbuf, sizeof(printbuf), readbuf, len)); +#if defined(MQTTV5) + MQTTV5Format_toClientString(printbuf, sizeof(printbuf), readbuf, len)); +#else + MQTTFormat_toClientString(printbuf, sizeof(printbuf), readbuf, len)); +#endif // MQTTV5 + } #endif return rc; diff --git a/MQTTPacket/samples/v5log.c b/MQTTPacket/samples/v5log.c index 260c62c5..a0fa723a 100644 --- a/MQTTPacket/samples/v5log.c +++ b/MQTTPacket/samples/v5log.c @@ -12,7 +12,8 @@ * *******************************************************************************/ -#include "V5/MQTTV5Packet.h" +#include +#include "MQTTV5Packet.h" static const char* v5property_identifier_to_string(int identifier) { diff --git a/MQTTPacket/samples/v5log.h b/MQTTPacket/samples/v5log.h index 300a041c..c8c8fa11 100644 --- a/MQTTPacket/samples/v5log.h +++ b/MQTTPacket/samples/v5log.h @@ -12,7 +12,7 @@ * *******************************************************************************/ -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" void v5property_print(MQTTProperty property); const char* v5reasoncode_to_string(int reasoncode); diff --git a/MQTTPacket/samples/v5ping.c b/MQTTPacket/samples/v5ping.c index 21be61c9..60de103a 100644 --- a/MQTTPacket/samples/v5ping.c +++ b/MQTTPacket/samples/v5ping.c @@ -16,7 +16,7 @@ #include #include -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #include "transport.h" #include "v5log.h" @@ -92,15 +92,14 @@ int main(int argc, char *argv[]) data.clientID.cstring = "paho-emb-ping"; data.keepAliveInterval = KEEPALIVE_INTERVAL; - data.cleansession = 1; + data.cleanstart = 1; data.username.cstring = "rw"; data.password.cstring = "readwrite"; data.MQTTVersion = 5; MQTTProperties conn_properties = MQTTProperties_initializer; - MQTTProperties will_properties = MQTTProperties_initializer; - len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties, &will_properties); + len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties); rc = transport_sendPacketBuffer(mysock, buf, len); printf("Sent MQTTv5 connect\n"); diff --git a/MQTTPacket/samples/v5ping_nb.c b/MQTTPacket/samples/v5ping_nb.c index cc5b6837..2889fce5 100644 --- a/MQTTPacket/samples/v5ping_nb.c +++ b/MQTTPacket/samples/v5ping_nb.c @@ -16,7 +16,7 @@ #include #include -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #include "transport.h" #include "v5log.h" @@ -99,15 +99,14 @@ int main(int argc, char *argv[]) mytransport.state = 0; data.clientID.cstring = "paho-emb-ping_nb"; data.keepAliveInterval = KEEPALIVE_INTERVAL; - data.cleansession = 1; + data.cleanstart = 1; data.username.cstring = "rw"; data.password.cstring = "readwrite"; data.MQTTVersion = 5; MQTTProperties conn_properties = MQTTProperties_initializer; - MQTTProperties will_properties = MQTTProperties_initializer; - len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties, &will_properties); + len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties); rc = transport_sendPacketBuffer(mysock, buf, len); printf("Sent MQTT connect\n"); diff --git a/MQTTPacket/samples/v5pub0sub1.c b/MQTTPacket/samples/v5pub0sub1.c index 95555d1c..3df9b4ea 100644 --- a/MQTTPacket/samples/v5pub0sub1.c +++ b/MQTTPacket/samples/v5pub0sub1.c @@ -16,7 +16,7 @@ #include #include -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #include "transport.h" #include "v5log.h" @@ -80,15 +80,14 @@ int main(int argc, char *argv[]) data.clientID.cstring = "paho-emb-v5pub0sub1"; data.keepAliveInterval = 20; - data.cleansession = 1; + data.cleanstart = 1; data.username.cstring = "rw"; data.password.cstring = "readwrite"; data.MQTTVersion = 5; MQTTProperties conn_properties = MQTTProperties_initializer; - MQTTProperties will_properties = MQTTProperties_initializer; - len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties, &will_properties); + len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties); rc = transport_sendPacketBuffer(mysock, buf, len); /* wait for connack */ @@ -259,7 +258,7 @@ int main(int argc, char *argv[]) } printf("disconnecting\n"); - len = MQTTSerialize_disconnect(buf, buflen); + len = MQTTV5Serialize_disconnect(buf, buflen, MQTTREASONCODE_NORMAL_DISCONNECTION, NULL); rc = transport_sendPacketBuffer(mysock, buf, len); exit: diff --git a/MQTTPacket/samples/v5pub0sub1_nb.c b/MQTTPacket/samples/v5pub0sub1_nb.c index 92213790..6528fd4c 100644 --- a/MQTTPacket/samples/v5pub0sub1_nb.c +++ b/MQTTPacket/samples/v5pub0sub1_nb.c @@ -90,9 +90,8 @@ int main(int argc, char *argv[]) data.MQTTVersion = 5; MQTTProperties conn_properties = MQTTProperties_initializer; - MQTTProperties will_properties = MQTTProperties_initializer; - len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties, &will_properties); + len = MQTTV5Serialize_connect(buf, buflen, &data, &conn_properties); rc = transport_sendPacketBuffer(mysock, buf, len); /* wait for connack */ @@ -272,7 +271,7 @@ int main(int argc, char *argv[]) } printf("disconnecting\n"); - len = MQTTSerialize_disconnect(buf, buflen); + len = MQTTV5Serialize_disconnect(buf, buflen, MQTTREASONCODE_NORMAL_DISCONNECTION, NULL); rc = transport_sendPacketBuffer(mysock, buf, len); exit: diff --git a/MQTTPacket/samples/v5qos0pub.c b/MQTTPacket/samples/v5qos0pub.c index a66ff8c0..fd0d703f 100644 --- a/MQTTPacket/samples/v5qos0pub.c +++ b/MQTTPacket/samples/v5qos0pub.c @@ -16,7 +16,7 @@ #include #include -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #include "transport.h" #include "v5log.h" @@ -48,15 +48,13 @@ int main(int argc, char *argv[]) conn_data.clientID.cstring = "paho-emb-v5qos0pub"; conn_data.keepAliveInterval = 20; - conn_data.cleansession = 1; + conn_data.cleanstart = 1; conn_data.username.cstring = "rw"; conn_data.password.cstring = "readwrite"; conn_data.MQTTVersion = 5; MQTTProperties conn_properties = MQTTProperties_initializer; - MQTTProperties will_properties = MQTTProperties_initializer; - - len = MQTTV5Serialize_connect((unsigned char *)buf, buflen, &conn_data, &conn_properties, &will_properties); + len = MQTTV5Serialize_connect((unsigned char *)buf, buflen, &conn_data, &conn_properties); MQTTProperty pub_properties_array[1]; MQTTProperties pub_properties = MQTTProperties_initializer; diff --git a/MQTTPacket/src/CMakeLists.txt b/MQTTPacket/src/CMakeLists.txt index e4054481..41c87fa2 100644 --- a/MQTTPacket/src/CMakeLists.txt +++ b/MQTTPacket/src/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2017 IBM Corp. +# Copyright (c) 2017, 2023 IBM Corp. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 @@ -15,33 +15,33 @@ #*******************************************************************************/ # MQTTPacket Library -file(GLOB SOURCES "*.c") +file(GLOB SOURCES "*.c" "V3/*.c") add_library(paho-embed-mqtt3c SHARED ${SOURCES}) install(TARGETS paho-embed-mqtt3c DESTINATION /usr/lib) target_compile_definitions(paho-embed-mqtt3c PRIVATE MQTT_SERVER MQTT_CLIENT) -add_library(MQTTPacketClient SHARED MQTTFormat MQTTPacket +add_library(MQTTPacketClient SHARED V3/MQTTFormat MQTTPacket MQTTSerializePublish MQTTDeserializePublish MQTTConnectClient MQTTSubscribeClient MQTTUnsubscribeClient) target_compile_definitions(MQTTPacketClient PRIVATE MQTT_CLIENT) -add_library(MQTTPacketServer SHARED MQTTFormat MQTTPacket +add_library(MQTTPacketServer SHARED V3/MQTTFormat MQTTPacket MQTTSerializePublish MQTTDeserializePublish MQTTConnectServer MQTTSubscribeServer MQTTUnsubscribeServer) target_compile_definitions(MQTTPacketServer PRIVATE MQTT_SERVER) -file(GLOB SOURCES5 "*.c" "V5/*.c" ../samples/transport.c) +file(GLOB SOURCES5 "*.c" "V5/*.c") add_library(paho-embed-mqtt5c SHARED ${SOURCES5}) install(TARGETS paho-embed-mqtt5c DESTINATION /usr/lib) target_compile_definitions(paho-embed-mqtt5c PRIVATE MQTT_SERVER MQTT_CLIENT MQTTV5) -add_library(MQTTPacketClient5 SHARED MQTTFormat MQTTPacket +add_library(MQTTPacketClient5 SHARED V5/MQTTV5Format MQTTPacket MQTTSerializePublish MQTTDeserializePublish V5/MQTTProperties V5/MQTTV5Packet MQTTConnectClient MQTTSubscribeClient MQTTUnsubscribeClient) target_compile_definitions(MQTTPacketClient5 PRIVATE MQTT_CLIENT MQTTV5) -add_library(MQTTPacketServer5 SHARED MQTTFormat MQTTPacket +add_library(MQTTPacketServer5 SHARED V5/MQTTV5Format MQTTPacket MQTTSerializePublish MQTTDeserializePublish V5/MQTTProperties V5/MQTTV5Packet MQTTConnectServer MQTTSubscribeServer MQTTUnsubscribeServer) target_compile_definitions(MQTTPacketServer5 PRIVATE MQTT_SERVER MQTTV5) diff --git a/MQTTPacket/src/MQTTConnectClient.c b/MQTTPacket/src/MQTTConnectClient.c index d46eaf8d..c7a2b0d9 100644 --- a/MQTTPacket/src/MQTTConnectClient.c +++ b/MQTTPacket/src/MQTTConnectClient.c @@ -15,7 +15,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif @@ -29,8 +29,7 @@ * @return the length of buffer needed to contain the serialized version of the packet */ #if defined(MQTTV5) -int MQTTSerialize_connectLength(MQTTPacket_connectData* options, MQTTProperties* connectProperties, - MQTTProperties* willProperties) +int MQTTSerialize_connectLength(MQTTPacket_connectData* options, MQTTProperties* connectProperties) #else int MQTTSerialize_connectLength(MQTTPacket_connectData* options) #endif @@ -56,8 +55,8 @@ int MQTTSerialize_connectLength(MQTTPacket_connectData* options) { if (connectProperties) len += MQTTProperties_len(connectProperties); - if (options->willFlag && willProperties) - len += MQTTProperties_len(willProperties); + if (options->willFlag && options->will.properties) + len += MQTTProperties_len(options->will.properties); } #endif @@ -65,7 +64,6 @@ int MQTTSerialize_connectLength(MQTTPacket_connectData* options) return len; } - /** * Serializes the connect options into the buffer. * @param buf the buffer into which the packet will be serialized @@ -74,13 +72,8 @@ int MQTTSerialize_connectLength(MQTTPacket_connectData* options) * @return serialized length, or error if 0 */ #if defined(MQTTV5) -int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connectData* options) -{ - return MQTTV5Serialize_connect(buf, buflen, options, NULL, NULL); -} - int MQTTV5Serialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connectData* options, - MQTTProperties* connectProperties, MQTTProperties* willProperties) + MQTTProperties* connectProperties) #else int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connectData* options) #endif @@ -93,8 +86,7 @@ int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connect FUNC_ENTRY; #if defined(MQTTV5) - if (MQTTPacket_len(len = MQTTSerialize_connectLength(options, - connectProperties, willProperties)) > buflen) + if (MQTTPacket_len(len = MQTTSerialize_connectLength(options, connectProperties)) > buflen) #else if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen) #endif @@ -147,8 +139,8 @@ int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connect { #if defined(MQTTV5) /* write will properties */ - if (options->MQTTVersion == 5 && willProperties) - MQTTProperties_write(&ptr, willProperties); + if (options->MQTTVersion == 5 && options->will.properties) + MQTTProperties_write(&ptr, options->will.properties); #endif writeMQTTString(&ptr, options->will.topicName); writeMQTTString(&ptr, options->will.message); @@ -174,11 +166,6 @@ int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connect * @return error code. 1 is success, 0 is failure */ #if defined(MQTTV5) -int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int32_t buflen) -{ - return MQTTV5Deserialize_connack(NULL, sessionPresent, connack_rc, buf, buflen); -} - int MQTTV5Deserialize_connack(MQTTProperties* connackProperties, unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int32_t buflen) #else @@ -229,11 +216,6 @@ int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connac int MQTTV5Serialize_zero(unsigned char* buf, int32_t buflen, unsigned char packettype, unsigned char reasonCode, MQTTProperties* properties); -int MQTTSerialize_zero(unsigned char* buf, int32_t buflen, unsigned char packettype) -{ - return MQTTV5Serialize_zero(buf, buflen, packettype, -1, NULL); -} - int MQTTV5Serialize_zero(unsigned char* buf, int32_t buflen, unsigned char packettype, unsigned char reasonCode, MQTTProperties* properties) #else @@ -286,11 +268,6 @@ int MQTTSerialize_zero(unsigned char* buf, int32_t buflen, unsigned char packett * @return serialized length, or error if 0 */ #if defined(MQTTV5) -int MQTTSerialize_disconnect(unsigned char* buf, int32_t buflen) -{ - return MQTTV5Serialize_disconnect(buf, buflen, -1, NULL); -} - int MQTTV5Serialize_disconnect(unsigned char* buf, int32_t buflen, unsigned char reasonCode, MQTTProperties* properties) #else @@ -322,5 +299,9 @@ int MQTTV5Serialize_auth(unsigned char* buf, int32_t buflen, */ int MQTTSerialize_pingreq(unsigned char* buf, int32_t buflen) { +#if defined(MQTTV5) + return MQTTV5Serialize_zero(buf, buflen, PINGREQ, -1, NULL); +#else return MQTTSerialize_zero(buf, buflen, PINGREQ); +#endif } diff --git a/MQTTPacket/src/MQTTConnect.h b/MQTTPacket/src/MQTTConnectCommon.h similarity index 73% rename from MQTTPacket/src/MQTTConnect.h rename to MQTTPacket/src/MQTTConnectCommon.h index 27d92512..6c8d3e24 100644 --- a/MQTTPacket/src/MQTTConnect.h +++ b/MQTTPacket/src/MQTTConnectCommon.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2023 IBM Corp. and others + * Copyright (c) 2023 Microsoft Corporation. All rights reserved. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -10,18 +10,15 @@ * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * - * Contributors: - * Ian Craggs - initial API and implementation and/or initial documentation - * Ian Craggs - add connack return code definitions - * Xiang Rong - 442039 Add makefile to Embedded C client - * Ian Craggs - fix for issue #64, bit order in connack response *******************************************************************************/ -#ifndef MQTTCONNECT_H_ -#define MQTTCONNECT_H_ +#ifndef MQTTCONNECT_COMMON_H_ +#define MQTTCONNECT_COMMON_H_ #include - +#if defined(MQTTV5) +#include "V5/MQTTProperties.h" +#else enum MQTTConnackReturnCodes { MQTTCONNACK_CONNECTION_ACCEPTED = 0, @@ -31,6 +28,8 @@ enum MQTTConnackReturnCodes MQTTCONNACK_BAD_USERNAME_OR_PASSWORD = 4, MQTTCONNACK_NOT_AUTHORIZED = 5, }; +#endif + #if !defined(DLLImport) #define DLLImport @@ -78,8 +77,6 @@ typedef struct { /** The eyecatcher for this structure. must be MQTW. */ char struct_id[4]; - /** The version number of this structure. Must be 0 */ - int struct_version; /** The LWT topic to which the LWT message will be published. */ MQTTString topicName; /** The LWT payload. */ @@ -93,19 +90,25 @@ typedef struct * MQTTAsync_message.qos and @ref qos). */ char qos; +#if defined(MQTTV5) + /** + * LWT properties. + */ + MQTTProperties* properties; +#endif } MQTTPacket_willOptions; - -#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 } - +#if defined(MQTTV5) +#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0, NULL } +#else +#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 } +#endif typedef struct { /** The eyecatcher for this structure. must be MQTC. */ char struct_id[4]; - /** The version number of this structure. Must be 0 */ - int struct_version; - /** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1 + /** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1, 5 = 5.0 */ unsigned char MQTTVersion; MQTTString clientID; @@ -139,17 +142,14 @@ typedef union #endif } MQTTConnackFlags; /**< connack flags byte */ -#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \ +#if defined(MQTTV5) +#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 5, {NULL, {0, NULL}}, 60, 1, 0, \ MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} } +#else +#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 4, {NULL, {0, NULL}}, 60, 1, 0, \ + MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} } +#endif -DLLExport int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connectData* options); -DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int32_t len); - -DLLExport int MQTTSerialize_connack(unsigned char* buf, int32_t buflen, unsigned char connack_rc, unsigned char sessionPresent); -DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int32_t buflen); - -DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int32_t buflen); -DLLExport int MQTTDeserialize_disconnect(unsigned char* buf, int32_t buflen); DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int32_t buflen); -#endif /* MQTTCONNECT_H_ */ +#endif /* MQTTCONNECT_COMMON_H_ */ diff --git a/MQTTPacket/src/MQTTConnectServer.c b/MQTTPacket/src/MQTTConnectServer.c index 842e94fa..46abba4c 100644 --- a/MQTTPacket/src/MQTTConnectServer.c +++ b/MQTTPacket/src/MQTTConnectServer.c @@ -17,7 +17,7 @@ #include "StackTrace.h" #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif @@ -55,7 +55,7 @@ int MQTTPacket_checkVersion(MQTTString* protocol, int version) #if defined(MQTTV5) int32_t MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int32_t len) { - return MQTTV5Deserialize_connect(NULL, NULL, data, buf, len); + return MQTTV5Deserialize_connect(NULL, data, buf, len); } /** @@ -67,8 +67,8 @@ int32_t MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf * @param len the length in bytes of the data in the supplied buffer * @return error code. 1 is success, 0 is failure */ -int32_t MQTTV5Deserialize_connect(MQTTProperties* willProperties, MQTTProperties* connectProperties, - MQTTPacket_connectData* data, unsigned char* buf, int32_t len) +int32_t MQTTV5Deserialize_connect(MQTTProperties* connectProperties, MQTTPacket_connectData* data, + unsigned char* buf, int32_t len) #else /** * Deserializes the supplied (wire) buffer into connect data structure @@ -128,7 +128,7 @@ int32_t MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf #if defined(MQTTV5) if (data->MQTTVersion == 5) { - if (!MQTTProperties_read(willProperties, &curdata, enddata)) + if (!MQTTProperties_read(data->will.properties, &curdata, enddata)) goto exit; } #endif diff --git a/MQTTPacket/src/MQTTDeserializePublish.c b/MQTTPacket/src/MQTTDeserializePublish.c index bc695470..1e19e229 100644 --- a/MQTTPacket/src/MQTTDeserializePublish.c +++ b/MQTTPacket/src/MQTTDeserializePublish.c @@ -16,7 +16,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif diff --git a/MQTTPacket/src/MQTTPacket.c b/MQTTPacket/src/MQTTPacket.c index 68770de3..e9715e89 100644 --- a/MQTTPacket/src/MQTTPacket.c +++ b/MQTTPacket/src/MQTTPacket.c @@ -16,7 +16,12 @@ *******************************************************************************/ #include "StackTrace.h" + +#if defined(MQTTV5) +#include "MQTTV5Packet.h" +#else #include "MQTTPacket.h" +#endif #include diff --git a/MQTTPacket/src/MQTTPacket.h b/MQTTPacket/src/MQTTPacket.h index 13860697..5b2d7239 100644 --- a/MQTTPacket/src/MQTTPacket.h +++ b/MQTTPacket/src/MQTTPacket.h @@ -24,112 +24,12 @@ extern "C" { #endif -#if defined(WIN32_DLL) || defined(WIN64_DLL) - #define DLLImport __declspec(dllimport) - #define DLLExport __declspec(dllexport) -#elif defined(LINUX_SO) - #define DLLImport extern - #define DLLExport __attribute__ ((visibility ("default"))) -#else - #define DLLImport - #define DLLExport -#endif - -enum errors -{ - MQTTPACKET_BUFFER_TOO_SHORT = -2, - MQTTPACKET_READ_ERROR = -1, - MQTTPACKET_READ_COMPLETE -}; - -enum msgTypes -{ - CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, - PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, - PINGREQ, PINGRESP, DISCONNECT -#if defined(MQTTV5) - , AUTH -#endif /* MQTTV5 */ -}; - -/** - * Bitfields for the MQTT header byte. - */ -typedef union -{ - unsigned char byte; /**< the whole byte */ -#if defined(REVERSED) - struct - { - unsigned int type : 4; /**< message type nibble */ - unsigned int dup : 1; /**< DUP flag bit */ - unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ - unsigned int retain : 1; /**< retained flag bit */ - } bits; -#else - struct - { - unsigned int retain : 1; /**< retained flag bit */ - unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ - unsigned int dup : 1; /**< DUP flag bit */ - unsigned int type : 4; /**< message type nibble */ - } bits; -#endif -} MQTTHeader; - -typedef struct -{ - int32_t len; - char* data; -} MQTTLenString; - -typedef struct -{ - char* cstring; - MQTTLenString lenstring; -} MQTTString; - -#define MQTTString_initializer {NULL, {0, NULL}} - -int MQTTstrlen(MQTTString mqttstring); - -#include "MQTTConnect.h" -#include "MQTTPublish.h" -#include "MQTTSubscribe.h" -#include "MQTTUnsubscribe.h" -#include "MQTTFormat.h" - -DLLExport int32_t MQTTSerialize_ack(unsigned char* buf, int32_t buflen, unsigned char type, unsigned char dup, unsigned short packetid); -DLLExport int32_t MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int32_t buflen); - -int32_t MQTTPacket_VBIlen(int32_t rem_len); -int32_t MQTTPacket_len(int32_t rem_len); -DLLExport int MQTTPacket_equals(MQTTString* a, char* b); - -DLLExport int32_t MQTTPacket_encode(unsigned char* buf, int32_t length); -int32_t MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int32_t* value); -int32_t MQTTPacket_decodeBuf(unsigned char* buf, int32_t* value); - -int readInt(unsigned char** pptr); -char readChar(unsigned char** pptr); -void writeChar(unsigned char** pptr, char c); -void writeInt(unsigned char** pptr, int anInt); -int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata); -void writeCString(unsigned char** pptr, const char* string); -void writeMQTTString(unsigned char** pptr, MQTTString mqttstring); - -DLLExport int MQTTPacket_read(unsigned char* buf, int32_t buflen, int (*getfn)(unsigned char*, int)); - -typedef struct { - int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */ - void *sck; /* pointer to whatever the system may use to identify the transport */ - int multiplier; - int rem_len; - int32_t len; - char state; -}MQTTTransport; - -int MQTTPacket_readnb(unsigned char* buf, int32_t buflen, MQTTTransport *trp); +#include "MQTTPacketCommon.h" +#include "V3/MQTTConnect.h" +#include "V3/MQTTPublish.h" +#include "V3/MQTTSubscribe.h" +#include "V3/MQTTUnsubscribe.h" +#include "V3/MQTTFormat.h" #ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ } diff --git a/MQTTPacket/src/MQTTPacketCommon.h b/MQTTPacket/src/MQTTPacketCommon.h new file mode 100644 index 00000000..1eb7ee8e --- /dev/null +++ b/MQTTPacket/src/MQTTPacketCommon.h @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2023 Microsoft Corporation. All rights reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ + +#ifndef MQTTPACKETCOMMON_H_ +#define MQTTPACKETCOMMON_H_ + +#include + +#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */ +extern "C" { +#endif + +#if defined(WIN32_DLL) || defined(WIN64_DLL) + #define DLLImport __declspec(dllimport) + #define DLLExport __declspec(dllexport) +#elif defined(LINUX_SO) + #define DLLImport extern + #define DLLExport __attribute__ ((visibility ("default"))) +#else + #define DLLImport + #define DLLExport +#endif + +enum errors +{ + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT +#if defined(MQTTV5) + , AUTH +#endif +}; + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + unsigned char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + unsigned int dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + unsigned int retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + unsigned int retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + unsigned int dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} MQTTHeader; + +typedef struct +{ + int32_t len; + char* data; +} MQTTLenString; + +typedef struct +{ + char* cstring; + MQTTLenString lenstring; +} MQTTString; + +#define MQTTString_initializer {NULL, {0, NULL}} + +int MQTTstrlen(MQTTString mqttstring); + +DLLExport int32_t MQTTSerialize_ack(unsigned char* buf, int32_t buflen, unsigned char type, unsigned char dup, unsigned short packetid); +DLLExport int32_t MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int32_t buflen); + +int32_t MQTTPacket_VBIlen(int32_t rem_len); +int32_t MQTTPacket_len(int32_t rem_len); +DLLExport int MQTTPacket_equals(MQTTString* a, char* b); + +DLLExport int32_t MQTTPacket_encode(unsigned char* buf, int32_t length); +int32_t MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int32_t* value); +int32_t MQTTPacket_decodeBuf(unsigned char* buf, int32_t* value); + +int readInt(unsigned char** pptr); +char readChar(unsigned char** pptr); +void writeChar(unsigned char** pptr, char c); +void writeInt(unsigned char** pptr, int anInt); +int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata); +void writeCString(unsigned char** pptr, const char* string); +void writeMQTTString(unsigned char** pptr, MQTTString mqttstring); + +DLLExport int MQTTPacket_read(unsigned char* buf, int32_t buflen, int (*getfn)(unsigned char*, int)); + +typedef struct { + int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */ + void *sck; /* pointer to whatever the system may use to identify the transport */ + int multiplier; + int rem_len; + int32_t len; + char state; +}MQTTTransport; + +int MQTTPacket_readnb(unsigned char* buf, int32_t buflen, MQTTTransport *trp); + +#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ +} +#endif + + +#endif /* MQTTPACKETCOMMON_H_ */ diff --git a/MQTTPacket/src/MQTTSerializePublish.c b/MQTTPacket/src/MQTTSerializePublish.c index f0acb351..80f48e80 100644 --- a/MQTTPacket/src/MQTTSerializePublish.c +++ b/MQTTPacket/src/MQTTSerializePublish.c @@ -17,7 +17,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif diff --git a/MQTTPacket/src/MQTTSubscribeClient.c b/MQTTPacket/src/MQTTSubscribeClient.c index a62360bc..371ce69a 100644 --- a/MQTTPacket/src/MQTTSubscribeClient.c +++ b/MQTTPacket/src/MQTTSubscribeClient.c @@ -16,7 +16,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif diff --git a/MQTTPacket/src/MQTTSubscribeServer.c b/MQTTPacket/src/MQTTSubscribeServer.c index 23f8e1e4..789aa5aa 100644 --- a/MQTTPacket/src/MQTTSubscribeServer.c +++ b/MQTTPacket/src/MQTTSubscribeServer.c @@ -16,7 +16,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif diff --git a/MQTTPacket/src/MQTTUnsubscribeClient.c b/MQTTPacket/src/MQTTUnsubscribeClient.c index 2def67fb..c3e4145f 100644 --- a/MQTTPacket/src/MQTTUnsubscribeClient.c +++ b/MQTTPacket/src/MQTTUnsubscribeClient.c @@ -16,7 +16,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif diff --git a/MQTTPacket/src/MQTTUnsubscribeServer.c b/MQTTPacket/src/MQTTUnsubscribeServer.c index 529aae65..ec3c7364 100644 --- a/MQTTPacket/src/MQTTUnsubscribeServer.c +++ b/MQTTPacket/src/MQTTUnsubscribeServer.c @@ -16,7 +16,7 @@ *******************************************************************************/ #if defined(MQTTV5) -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #else #include "MQTTPacket.h" #endif diff --git a/MQTTPacket/src/V5/MQTTV5Packet.h b/MQTTPacket/src/MQTTV5Packet.h similarity index 82% rename from MQTTPacket/src/V5/MQTTV5Packet.h rename to MQTTPacket/src/MQTTV5Packet.h index 14a96b6b..7fb5b504 100644 --- a/MQTTPacket/src/V5/MQTTV5Packet.h +++ b/MQTTPacket/src/MQTTV5Packet.h @@ -17,23 +17,21 @@ #ifndef MQTTV5PACKET_H_ #define MQTTV5PACKET_H_ -#include "MQTTPacket.h" +#ifndef MQTTV5 +#define MQTTV5 +#endif #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */ extern "C" { #endif -#include "MQTTReasonCodes.h" - -#include "MQTTProperties.h" - -#include "MQTTV5Connect.h" - -#include "MQTTV5Publish.h" - -#include "MQTTV5Subscribe.h" - -#include "MQTTV5Unsubscribe.h" +#include "MQTTPacketCommon.h" +#include "V5/MQTTReasonCodes.h" +#include "V5/MQTTProperties.h" +#include "V5/MQTTV5Connect.h" +#include "V5/MQTTV5Publish.h" +#include "V5/MQTTV5Subscribe.h" +#include "V5/MQTTV5Unsubscribe.h" void writeInt4(unsigned char** pptr, int anInt); int readInt4(unsigned char** pptr); diff --git a/MQTTPacket/src/V3/MQTTConnect.h b/MQTTPacket/src/V3/MQTTConnect.h new file mode 100644 index 00000000..cf84845c --- /dev/null +++ b/MQTTPacket/src/V3/MQTTConnect.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2014, 2023 IBM Corp. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - add connack return code definitions + * Xiang Rong - 442039 Add makefile to Embedded C client + * Ian Craggs - fix for issue #64, bit order in connack response + *******************************************************************************/ + +#ifndef MQTTCONNECT_H_ +#define MQTTCONNECT_H_ + +#include +#include "MQTTConnectCommon.h" + +#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 4, {NULL, {0, NULL}}, 60, 1, 0, \ + MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} } + +DLLExport int MQTTSerialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connectData* options); +DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int32_t len); + +DLLExport int MQTTSerialize_connack(unsigned char* buf, int32_t buflen, unsigned char connack_rc, unsigned char sessionPresent); +DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int32_t buflen); + +DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int32_t buflen); +DLLExport int MQTTDeserialize_disconnect(unsigned char* buf, int32_t buflen); + +#endif /* MQTTCONNECT_H_ */ diff --git a/MQTTPacket/src/MQTTFormat.c b/MQTTPacket/src/V3/MQTTFormat.c similarity index 98% rename from MQTTPacket/src/MQTTFormat.c rename to MQTTPacket/src/V3/MQTTFormat.c index f4f2d779..ae07c8af 100644 --- a/MQTTPacket/src/MQTTFormat.c +++ b/MQTTPacket/src/V3/MQTTFormat.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 IBM Corp. + * Copyright (c) 2014, 2023 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -33,7 +33,6 @@ const char* MQTTPacket_getName(unsigned short packetid) return MQTTPacket_names[packetid]; } - int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data) { int strindex = 0; @@ -41,11 +40,7 @@ int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData strindex = snprintf(strbuf, strbuflen, "CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d", (int)data->MQTTVersion, (int) data->clientID.lenstring.len, data->clientID.lenstring.data, -#if defined(MQTTV5) - (int)data->cleanstart, -#else (int)data->cleansession, -#endif data->keepAliveInterval); if (data->willFlag) @@ -63,14 +58,14 @@ int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData return strindex; } - int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent) { - int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc); + int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, + connack_rc); + return strindex; } - int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen) { @@ -91,7 +86,6 @@ int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, return strindex; } - int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, MQTTString topicFilters[], unsigned char requestedQoSs[]) { diff --git a/MQTTPacket/src/MQTTFormat.h b/MQTTPacket/src/V3/MQTTFormat.h similarity index 100% rename from MQTTPacket/src/MQTTFormat.h rename to MQTTPacket/src/V3/MQTTFormat.h diff --git a/MQTTPacket/src/MQTTPublish.h b/MQTTPacket/src/V3/MQTTPublish.h similarity index 100% rename from MQTTPacket/src/MQTTPublish.h rename to MQTTPacket/src/V3/MQTTPublish.h diff --git a/MQTTPacket/src/MQTTSubscribe.h b/MQTTPacket/src/V3/MQTTSubscribe.h similarity index 97% rename from MQTTPacket/src/MQTTSubscribe.h rename to MQTTPacket/src/V3/MQTTSubscribe.h index 18f53cf5..ae0e4a07 100644 --- a/MQTTPacket/src/MQTTSubscribe.h +++ b/MQTTPacket/src/V3/MQTTSubscribe.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 IBM Corp. + * Copyright (c) 2014, 2023 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 diff --git a/MQTTPacket/src/MQTTUnsubscribe.h b/MQTTPacket/src/V3/MQTTUnsubscribe.h similarity index 100% rename from MQTTPacket/src/MQTTUnsubscribe.h rename to MQTTPacket/src/V3/MQTTUnsubscribe.h diff --git a/MQTTPacket/src/V5/MQTTProperties.h b/MQTTPacket/src/V5/MQTTProperties.h index 39bf5061..6a1fd84d 100644 --- a/MQTTPacket/src/V5/MQTTProperties.h +++ b/MQTTPacket/src/V5/MQTTProperties.h @@ -14,6 +14,8 @@ * Ian Craggs - initial API and implementation and/or initial documentation *******************************************************************************/ +#ifndef MQTTPROPERTIES_H_ +#define MQTTPROPERTIES_H_ enum MQTTPropertyNames { MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, @@ -102,3 +104,5 @@ DLLExport int MQTTProperties_read(MQTTProperties* properties, unsigned char** pp * @return the `PropertyTypes` type of the property */ DLLExport int MQTTProperty_getType(int identifier); + +#endif // MQTTPROPERTIES_H_ diff --git a/MQTTPacket/src/V5/MQTTReasonCodes.h b/MQTTPacket/src/V5/MQTTReasonCodes.h index c303b6e7..9ded243c 100644 --- a/MQTTPacket/src/V5/MQTTReasonCodes.h +++ b/MQTTPacket/src/V5/MQTTReasonCodes.h @@ -13,6 +13,8 @@ * Contributors: * Ian Craggs - initial API and implementation and/or initial documentation *******************************************************************************/ +#ifndef MQTTREASONCODES_H_ +#define MQTTREASONCODES_H_ /** * @brief MQTTv5 Reason Codes @@ -65,3 +67,5 @@ enum MQTTReasonCodes { MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161, MQTTREASONCODE_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED = 162 }; + +#endif // MQTTREASONCODES_H_ diff --git a/MQTTPacket/src/V5/MQTTV5Connect.h b/MQTTPacket/src/V5/MQTTV5Connect.h index bc6512e1..fdf5b01b 100644 --- a/MQTTPacket/src/V5/MQTTV5Connect.h +++ b/MQTTPacket/src/V5/MQTTV5Connect.h @@ -17,13 +17,13 @@ #ifndef MQTT5CONNECT_H_ #define MQTT5CONNECT_H_ -#include "MQTTConnect.h" +#include "MQTTConnectCommon.h" DLLExport int32_t MQTTV5Serialize_connect(unsigned char* buf, int32_t buflen, MQTTPacket_connectData* options, - MQTTProperties* connectProperties, MQTTProperties* willProperties); + MQTTProperties* connectProperties); -DLLExport int32_t MQTTV5Deserialize_connect(MQTTProperties* willProperties, - MQTTProperties* connectProperties, MQTTPacket_connectData* data, unsigned char* buf, int32_t len); +DLLExport int32_t MQTTV5Deserialize_connect(MQTTProperties* connectProperties, MQTTPacket_connectData* data, + unsigned char* buf, int32_t len); DLLExport int32_t MQTTV5Serialize_connack(unsigned char* buf, int32_t buflen, unsigned char connack_rc, unsigned char sessionPresent, MQTTProperties* connackProperties); diff --git a/MQTTPacket/src/V5/MQTTV5Format.c b/MQTTPacket/src/V5/MQTTV5Format.c new file mode 100644 index 00000000..447fe62f --- /dev/null +++ b/MQTTPacket/src/V5/MQTTV5Format.c @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright (c) 2023 Microsoft Corporation. All rights reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ + +// TODO: Add MQTTv5 properties implementation (some of the code exists in v5log.h), application must provide memory. +#include "StackTrace.h" +#include "MQTTV5Packet.h" + +#include + +// The index of each packet name as described by the MQTTv5.0 spec, section 2.1.2. +// E.g. MQTTV5Packet_names[15] == "AUTH" +const char* MQTTV5Packet_names[] = +{ + "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", + "PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", + "PINGREQ", "PINGRESP", "DISCONNECT", "AUTH" +}; + + +const char* MQTTV5Packet_getName(unsigned short packetid) +{ + return MQTTV5Packet_names[packetid]; +} + + +int MQTTV5StringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data) +{ + int strindex = 0; + + strindex = snprintf(strbuf, strbuflen, + "CONNECT MQTT version %d, client id %.*s, clean start %d, keep alive %d", + (int)data->MQTTVersion, (int) data->clientID.lenstring.len, data->clientID.lenstring.data, + (int)data->cleanstart, data->keepAliveInterval); + if (data->willFlag) + strindex += snprintf(&strbuf[strindex], strbuflen - strindex, + ", will QoS %d, will retain %d, will topic %.*s, will message %.*s", + data->will.qos, data->will.retained, + (int) data->will.topicName.lenstring.len, data->will.topicName.lenstring.data, + (int) data->will.message.lenstring.len, data->will.message.lenstring.data); + if (data->username.lenstring.data && data->username.lenstring.len > 0) + strindex += snprintf(&strbuf[strindex], strbuflen - strindex, + ", user name %.*s", (int) data->username.lenstring.len, data->username.lenstring.data); + if (data->password.lenstring.data && data->password.lenstring.len > 0) + strindex += snprintf(&strbuf[strindex], strbuflen - strindex, + ", password %.*s", (int) data->password.lenstring.len, data->password.lenstring.data); + return strindex; +} + + +int MQTTV5StringFormat_connack(char* strbuf, int strbuflen, enum MQTTReasonCodes reason_code, unsigned char sessionPresent) +{ + int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, reason_code); + return strindex; +} + + +int MQTTV5StringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, + unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen) +{ + int strindex = snprintf(strbuf, strbuflen, + "PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s", + dup, qos, retained, packetid, + (topicName.lenstring.len < 20) ? (int) topicName.lenstring.len : 20, topicName.lenstring.data, + (int) payloadlen, (payloadlen < 20) ? (int) payloadlen : 20, payload); + return strindex; +} + + +int MQTTV5StringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned char reason, unsigned short packetid) +{ + int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d reason %d", MQTTV5Packet_names[packettype], packetid, reason); + if (dup) + strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup); + return strindex; +} + + +int MQTTV5StringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, + MQTTString topicFilters[], unsigned char requestedQoSs[]) +{ + return snprintf(strbuf, strbuflen, + "SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d", + dup, packetid, count, + (int) topicFilters[0].lenstring.len, topicFilters[0].lenstring.data, + requestedQoSs[0]); +} + + +int MQTTV5StringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, unsigned char* grantedQoSs) +{ + return snprintf(strbuf, strbuflen, + "SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]); +} + + +int MQTTV5StringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[]) +{ + return snprintf(strbuf, strbuflen, + "UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s", + dup, packetid, count, + (int) topicFilters[0].lenstring.len, topicFilters[0].lenstring.data); +} + + +#if defined(MQTT_CLIENT) +char* MQTTV5Format_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int32_t buflen) +{ + int index = 0; + int rem_length = 0; + MQTTHeader header = {0}; + int strindex = 0; + + header.byte = buf[index++]; + index += MQTTPacket_decodeBuf(&buf[index], &rem_length); + + switch (header.bits.type) + { + + case CONNACK: + { + unsigned char sessionPresent, connack_rc; +#if defined(MQTT5) + +#else + if (MQTTV5Deserialize_connack(NULL, &sessionPresent, &connack_rc, buf, buflen) == 1) + strindex = MQTTV5StringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent); +#endif + } + break; + case PUBLISH: + { + unsigned char dup, retained, *payload, qos; + unsigned short packetid; + int32_t payloadlen; + MQTTString topicName = MQTTString_initializer; + if (MQTTV5Deserialize_publish(&dup, &qos, &retained, &packetid, &topicName, + NULL, &payload, &payloadlen, buf, buflen) == 1) + strindex = MQTTV5StringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, + topicName, payload, payloadlen); + } + break; + case PUBACK: + case PUBREC: + case PUBREL: + case PUBCOMP: + { + unsigned char packettype, dup, reason; + unsigned short packetid; + if (MQTTV5Deserialize_ack(&packettype, &dup, &packetid, &reason, NULL, buf, buflen) == 1) + strindex = MQTTV5StringFormat_ack(strbuf, strbuflen, packettype, dup, reason, packetid); + } + break; + case SUBACK: + { + unsigned short packetid; + int maxcount = 1, count = 0; + unsigned char grantedQoSs[1]; + unsigned char reasonCodes[1]; + if (MQTTV5Deserialize_suback(&packetid, NULL, maxcount, &count, reasonCodes, buf, buflen) == 1) + strindex = MQTTV5StringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs); + } + break; + case UNSUBACK: + { + unsigned short packetid; + int maxcount = 1, count = 0; + unsigned char reasonCodes[1]; + + if (MQTTV5Deserialize_unsuback(&packetid, NULL, maxcount, &count, reasonCodes, buf, buflen) == 1) + strindex = MQTTV5StringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, reasonCodes[0], packetid); + } + break; + case PINGREQ: + case PINGRESP: + case DISCONNECT: + strindex = snprintf(strbuf, strbuflen, "%s", MQTTV5Packet_names[header.bits.type]); + break; + } + return strbuf; +} +#endif + +#if defined(MQTT_SERVER) +char* MQTTV5Format_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int32_t buflen) +{ + int index = 0; + int rem_length = 0; + MQTTHeader header = {0}; + int strindex = 0; + + header.byte = buf[index++]; + index += MQTTPacket_decodeBuf(&buf[index], &rem_length); + + switch (header.bits.type) + { + case CONNECT: + { + MQTTPacket_connectData data; + int rc; + if ((rc = MQTTV5Deserialize_connect(NULL, &data, buf, buflen)) == 1) + strindex = MQTTV5StringFormat_connect(strbuf, strbuflen, &data); + } + break; + case PUBLISH: + { + unsigned char dup, retained, *payload, qos; + unsigned short packetid; + int32_t payloadlen; + MQTTString topicName = MQTTString_initializer; + if (MQTTV5Deserialize_publish(&dup, &qos, &retained, &packetid, &topicName, NULL, + &payload, &payloadlen, buf, buflen) == 1) + strindex = MQTTV5StringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, + topicName, payload, payloadlen); + } + break; + case PUBACK: + case PUBREC: + case PUBREL: + case PUBCOMP: + { + unsigned char packettype, dup, reason; + unsigned short packetid; + if (MQTTV5Deserialize_ack(&packettype, &dup, &packetid, &reason, NULL, buf, buflen) == 1) + strindex = MQTTV5StringFormat_ack(strbuf, strbuflen, packettype, dup, reason, packetid); + } + break; + case SUBSCRIBE: + { + unsigned char dup; + unsigned short packetid; + int maxcount = 1, count = 0; + MQTTString topicFilters[1]; + unsigned char requestedQoSs[1]; + MQTTSubscribe_options sub_options[1]; + + if (MQTTV5Deserialize_subscribe(&dup, &packetid, NULL, maxcount, &count, + topicFilters, requestedQoSs, sub_options, buf, buflen) == 1) + strindex = MQTTV5StringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);; + } + break; + case UNSUBSCRIBE: + { + unsigned char dup; + unsigned short packetid; + int maxcount = 1, count = 0; + MQTTString topicFilters[1]; + if (MQTTV5Deserialize_unsubscribe(&dup, &packetid, NULL, maxcount, &count, topicFilters, buf, buflen) == 1) + strindex = MQTTV5StringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters); + } + break; + case PINGREQ: + case PINGRESP: + case DISCONNECT: + strindex = snprintf(strbuf, strbuflen, "%s", MQTTV5Packet_names[header.bits.type]); + break; + } + strbuf[strbuflen] = '\0'; + return strbuf; +} +#endif diff --git a/MQTTPacket/src/V5/MQTTV5Format.h b/MQTTPacket/src/V5/MQTTV5Format.h new file mode 100644 index 00000000..51797730 --- /dev/null +++ b/MQTTPacket/src/V5/MQTTV5Format.h @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2023 Microsoft Corporation. All rights reserved. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + *******************************************************************************/ + +#if !defined(MQTTV5FORMAT_H) +#define MQTTV5FORMAT_H + +#include "StackTrace.h" +#include "MQTTV5Packet.h" + +const char* MQTTV5Packet_getName(unsigned short packetid); +int MQTTV5StringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data); +int MQTTV5StringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent); +int MQTTV5StringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, + unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen); +int MQTTV5StringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid); +int MQTTV5StringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, + MQTTString topicFilters[], unsigned char requestedQoSs[]); +int MQTTV5StringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, unsigned char* grantedQoSs); +int MQTTV5StringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[]); +char* MQTTV5Format_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int32_t buflen); +char* MQTTV5Format_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int32_t buflen); + +#endif diff --git a/MQTTPacket/src/V5/MQTTV5Publish.h b/MQTTPacket/src/V5/MQTTV5Publish.h index 91a6c02a..84d1c697 100644 --- a/MQTTPacket/src/V5/MQTTV5Publish.h +++ b/MQTTPacket/src/V5/MQTTV5Publish.h @@ -24,8 +24,6 @@ #define DLLExport #endif -#include "MQTTPublish.h" - DLLExport int32_t MQTTV5Serialize_publish(unsigned char* buf, int32_t buflen, unsigned char dup, unsigned char qos, unsigned char retained, unsigned short packetid, MQTTString topicName, MQTTProperties* props, unsigned char* payload, int32_t payloadlen); diff --git a/MQTTPacket/test/CMakeLists.txt b/MQTTPacket/test/CMakeLists.txt index 6e51141b..a18ecc7c 100644 --- a/MQTTPacket/test/CMakeLists.txt +++ b/MQTTPacket/test/CMakeLists.txt @@ -12,6 +12,7 @@ ELSE () SET(CERTDIR $ENV{TRAVIS_BUILD_DIR}/test/ssl) ENDIF () +# transport.h/c are reused from ../samples: include_directories(../src ../src/V5 ../samples) ADD_EXECUTABLE( @@ -38,30 +39,6 @@ SET_TESTS_PROPERTIES( PROPERTIES TIMEOUT 540 ) -ADD_EXECUTABLE( - test15 - test1.c -) - -# Disabling deprecation warnings: -# warning: ‘ftime’ is deprecated [-Wdeprecated-declarations] -target_compile_options(test15 PRIVATE -Wno-deprecated-declarations) - -TARGET_LINK_LIBRARIES( - test15 - paho-embed-mqtt5c -) - -ADD_TEST( - NAME test15 - COMMAND "test15" "--connection" ${MQTT_TEST_BROKER} -) - -SET_TESTS_PROPERTIES( - test15 - PROPERTIES TIMEOUT 540 -) - ADD_EXECUTABLE( test2 test2.c @@ -90,6 +67,7 @@ SET_TESTS_PROPERTIES( ADD_EXECUTABLE( test3 test3.c + ../samples/transport.c ) # Disabling deprecation warnings: diff --git a/MQTTPacket/test/test1.c b/MQTTPacket/test/test1.c index a04c4a55..73e404ad 100644 --- a/MQTTPacket/test/test1.c +++ b/MQTTPacket/test/test1.c @@ -273,9 +273,6 @@ int checkConnectPackets(MQTTPacket_connectData* before, MQTTPacket_connectData* assert("struct_ids should be the same", memcmp(before->struct_id, after->struct_id, 4) == 0, "struct_ids were different %.4s\n", after->struct_id); - assert("struct_versions should be the same", - before->struct_version == after->struct_version, "struct_versions were different\n", rc); - assert("MQTT versions should be the same", before->MQTTVersion == after->MQTTVersion, "MQTT versions were different\n", rc); @@ -296,9 +293,6 @@ int checkConnectPackets(MQTTPacket_connectData* before, MQTTPacket_connectData* assert("will struct_ids should be the same", memcmp(before->will.struct_id, after->will.struct_id, 4) == 0, "will struct_ids were different %.4s\n", after->struct_id); - assert("will struct_versions should be the same", - before->will.struct_version == after->will.struct_version, "will struct_versions were different\n", rc); - assert("topic names should be the same", checkMQTTStrings(before->will.topicName, after->will.topicName), "topic names were different\n", rc); diff --git a/MQTTPacket/test/test2.c b/MQTTPacket/test/test2.c index 1c890ac3..b051b8db 100644 --- a/MQTTPacket/test/test2.c +++ b/MQTTPacket/test/test2.c @@ -18,7 +18,7 @@ Tests for MQTTV5 serialization and deserialization ***/ -#include "V5/MQTTV5Packet.h" +#include "MQTTV5Packet.h" #include #include #include @@ -276,9 +276,6 @@ int checkConnectPackets(MQTTPacket_connectData* before, MQTTPacket_connectData* assert("struct_ids should be the same", memcmp(before->struct_id, after->struct_id, 4) == 0, "struct_ids were different %.4s\n", after->struct_id); - assert("struct_versions should be the same", - before->struct_version == after->struct_version, "struct_versions were different\n", rc); - assert("MQTT versions should be the same", before->MQTTVersion == after->MQTTVersion, "MQTT versions were different\n", rc); @@ -288,8 +285,8 @@ int checkConnectPackets(MQTTPacket_connectData* before, MQTTPacket_connectData* assert("keepAliveIntervals should be the same", before->keepAliveInterval == after->keepAliveInterval, "keepAliveIntervals were different %d\n", after->keepAliveInterval); - assert("cleansessions should be the same", - before->cleansession == after->cleansession, "cleansessions were different\n", rc); + assert("cleanstarts should be the same", + before->cleanstart == after->cleanstart, "cleanstarts were different\n", rc); assert("willFlags should be the same", before->willFlag == after->willFlag, "willFlags were different\n", rc); @@ -299,9 +296,6 @@ int checkConnectPackets(MQTTPacket_connectData* before, MQTTPacket_connectData* assert("will struct_ids should be the same", memcmp(before->will.struct_id, after->will.struct_id, 4) == 0, "will struct_ids were different %.4s\n", after->struct_id); - assert("will struct_versions should be the same", - before->will.struct_version == after->will.struct_version, "will struct_versions were different\n", rc); - assert("topic names should be the same", checkMQTTStrings(before->will.topicName, after->will.topicName), "topic names were different\n", rc); @@ -391,7 +385,7 @@ int test1(struct Options options) data.clientID.cstring = "my clientid"; data.keepAliveInterval = 20; - data.cleansession = 1; + data.cleanstart = 1; data.username.cstring = "testuser"; data.password.cstring = "testpassword"; @@ -400,11 +394,13 @@ int test1(struct Options options) data.will.qos = 1; data.will.retained = 0; data.will.topicName.cstring = "will topic"; + data.will.properties = &willProperties; - rc = MQTTV5Serialize_connect(buf, buflen, &data, &connectProperties, &willProperties); + rc = MQTTV5Serialize_connect(buf, buflen, &data, &connectProperties); assert("good rc from serialize connect", rc > 0, "rc was %d\n", rc); - rc = MQTTV5Deserialize_connect(&outWillProperties, &outConnectProperties, &data_after, buf, buflen); + data_after.will.properties = &outWillProperties; + rc = MQTTV5Deserialize_connect(&outConnectProperties, &data_after, buf, buflen); assert("good rc from deserialize connect", rc == 1, "rc was %d\n", rc); /* data after should be the same as data before */ diff --git a/MQTTPacket/test/test3.c b/MQTTPacket/test/test3.c index ba7577e6..b921c3a0 100644 --- a/MQTTPacket/test/test3.c +++ b/MQTTPacket/test/test3.c @@ -266,7 +266,7 @@ int test1(struct Options options) data.clientID.cstring = "mqtt5_test3_test1"; data.keepAliveInterval = 20; - data.cleansession = 1; + data.cleanstart = 1; data.username.cstring = "testuser"; data.password.cstring = "testpassword"; data.MQTTVersion = 5; @@ -287,7 +287,7 @@ int test1(struct Options options) rc = MQTTProperties_add(&properties, &one); assert("add properties rc should be 0", rc == 0, "rc was different %d\n", rc); - len = MQTTV5Serialize_connect((unsigned char *)buf, buflen, &data, &properties, NULL); + len = MQTTV5Serialize_connect((unsigned char *)buf, buflen, &data, &properties); rc = transport_sendPacketBuffer(mysock, buf, len); assert("rc and len should be the same", rc == len, "rc was different %d\n", rc);