### Build MQTT-C Tests and Examples (Makefile) Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html This shell command compiles the MQTT-C unit tests and examples. It requires the `cmocka` unit testing framework to be installed and uses the provided `makefile` for convenience on UNIX-like systems. ```Shell make all ``` -------------------------------- ### Build MQTT-C Tests and Examples Source: https://github.com/liambindle/mqtt-c/blob/master/README.md Command to build the unit tests and examples for MQTT-C on UNIX-like machines using the provided Makefile. This process requires the cmocka unit testing framework to be installed. ```Bash make all ``` -------------------------------- ### Install MQTT-C Library and Headers using CMake Source: https://github.com/liambindle/mqtt-c/blob/master/CMakeLists.txt This CMake snippet defines installation rules for the 'mqttc' target library and its public header files. It ensures the library is placed in the standard library directory (CMAKE_INSTALL_LIBDIR) and headers in the standard include directory (CMAKE_INSTALL_INCLUDEDIR), making them available for other projects to link against and include. ```CMake install(TARGETS mqttc DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ``` -------------------------------- ### Build MQTT-C Examples with TLS and Threading Support Source: https://github.com/liambindle/mqtt-c/blob/master/CMakeLists.txt This section compiles various example executables for MQTT-C, conditionally based on the enabled TLS support (OpenSSL, MbedTLS, BearSSL, or none). It links them against the 'mqttc' library and the 'Threads' library, and optionally installs them. Platform-specific source files are used for OpenSSL examples on Windows. ```CMake # Build examples if(MQTT_C_EXAMPLES) find_package(Threads REQUIRED) if(MQTT_C_OpenSSL_SUPPORT) if(MSVC) add_executable(bio_publisher examples/bio_publisher_win.c) add_executable(openssl_publisher examples/openssl_publisher_win.c) else() add_executable(bio_publisher examples/bio_publisher.c) add_executable(openssl_publisher examples/openssl_publisher.c) endif() if(MQTT_C_INSTALL_EXAMPLES) install(TARGETS bio_publisher openssl_publisher) endif() target_link_libraries(bio_publisher Threads::Threads mqttc) target_link_libraries(openssl_publisher Threads::Threads mqttc) elseif(MQTT_C_MbedTLS_SUPPORT) add_executable(mbedtls_publisher examples/mbedtls_publisher.c) target_link_libraries(mbedtls_publisher Threads::Threads mqttc ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY}) if(MQTT_C_INSTALL_EXAMPLES) install(TARGETS mbedtls_publisher) endif() elseif(MQTT_C_BearSSL_SUPPORT) add_executable(bearssl_publisher examples/bearssl_publisher.c) target_link_libraries(bearssl_publisher mqttc bearssl) if(MQTT_C_INSTALL_EXAMPLES) install(TARGETS bearssl_publisher) endif() else() add_executable(simple_publisher examples/simple_publisher.c) target_link_libraries(simple_publisher Threads::Threads mqttc) if(MQTT_C_INSTALL_EXAMPLES) install(TARGETS simple_publisher) endif() endif() # Always install subscriber targets add_executable(simple_subscriber examples/simple_subscriber.c) target_link_libraries(simple_subscriber Threads::Threads mqttc) add_executable(reconnect_subscriber examples/reconnect_subscriber.c) target_link_libraries(reconnect_subscriber Threads::Threads mqttc) if(MQTT_C_INSTALL_EXAMPLES) install(TARGETS simple_subscriber reconnect_subscriber) endif() endif() ``` -------------------------------- ### Configure Installation Directories for MQTT-C Source: https://github.com/liambindle/mqtt-c/blob/master/CMakeLists.txt This section handles the configuration of installation directories for MQTT-C. On Unix-like systems, it uses CMake's GNUInstallDirs module to set standard paths for binaries, libraries, and includes. For other systems, it defaults to 'lib' and 'include' for library and include paths respectively. ```CMake # Handle multi-lib linux systems correctly and allow custom installation locations. if(UNIX) include(GNUInstallDirs) mark_as_advanced(CLEAR CMAKE_INSTALL_BINDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR) else() set(CMAKE_INSTALL_LIBDIR "lib") set(CMAKE_INSTALL_INCLUDEDIR "include") endif() ``` -------------------------------- ### C MQTT Subscriber Example Source: https://github.com/liambindle/mqtt-c/blob/master/docs/simple_subscriber_8c-example.html This C program demonstrates how to subscribe to an MQTT topic using the MQTT-C library. It connects to a specified broker (default: test.mosquitto.org:1883), subscribes to a topic (default: datetime), and prints all received messages. It includes error handling, a background thread for client refreshing, and proper resource cleanup. The program can be run with optional command-line arguments for address, port, and topic. ```C #include #include #include #include #include "templates/posix_sockets.h" void publish_callback(void** unused, struct mqtt_response_publish *published); void* client_refresher(void* client); void exit_example(int status, int sockfd, pthread_t *client_daemon); int main(int argc, const char *argv[]) { const char* addr; const char* port; const char* topic; /* get address (argv[1] if present) */ if (argc > 1) { addr = argv[1]; } else { addr = "test.mosquitto.org"; } /* get port number (argv[2] if present) */ if (argc > 2) { port = argv[2]; } else { port = "1883"; } /* get the topic name to publish */ if (argc > 3) { topic = argv[3]; } else { topic = "datetime"; } /* open the non-blocking TCP socket (connecting to the broker) */ int sockfd = open_nb_socket(addr, port); if (sockfd == -1) { perror("Failed to open socket: "); exit_example(EXIT_FAILURE, sockfd, NULL); } /* setup a client */ struct mqtt_client client; uint8_t sendbuf[2048]; /* sendbuf should be large enough to hold multiple whole mqtt messages */ uint8_t recvbuf[1024]; /* recvbuf should be large enough any whole mqtt message expected to be received */ mqtt_init(&client, sockfd, sendbuf, sizeof(sendbuf), recvbuf, sizeof(recvbuf), publish_callback); mqtt_connect(&client, "subscribing_client", NULL, NULL, 0, NULL, NULL, 0, 400); /* check that we don't have any errors */ if (client.error != MQTT_OK) { fprintf(stderr, "error: %s\n", mqtt_error_str(client.error)); exit_example(EXIT_FAILURE, sockfd, NULL); } /* start a thread to refresh the client (handle egress and ingree client traffic) */ pthread_t client_daemon; if(pthread_create(&client_daemon, NULL, client_refresher, &client)) { fprintf(stderr, "Failed to start client daemon.\n"); exit_example(EXIT_FAILURE, sockfd, NULL); } /* subscribe */ mqtt_subscribe(&client, topic, 0); /* start publishing the time */ printf("%s listening for '%s' messages.\n", argv[0], topic); printf("Press CTRL-D to exit.\n\n"); /* block */ while(fgetc(stdin) != EOF); /* disconnect */ printf("\n%s disconnecting from %s\n", argv[0], addr); sleep(1); /* exit */ exit_example(EXIT_SUCCESS, sockfd, &client_daemon); } void exit_example(int status, int sockfd, pthread_t *client_daemon) { if (sockfd != -1) close(sockfd); if (client_daemon != NULL) pthread_cancel(*client_daemon); exit(status); } void publish_callback(void** unused, struct mqtt_response_publish *published) { /* note that published->topic_name is NOT null-terminated (here we'll change it to a c-string) */ char* topic_name = (char*) malloc(published->topic_name_size + 1); memcpy(topic_name, published->topic_name, published->topic_name_size); topic_name[published->topic_name_size] = '\0'; printf("Received publish('%s'): %s\n", topic_name, (const char*) published->application_message); free(topic_name); } void* client_refresher(void* client) { while(1) { mqtt_sync((struct mqtt_client*) client); usleep(100000U); } return NULL; } ``` -------------------------------- ### C Example: Secure MQTT Publisher with OpenSSL Source: https://github.com/liambindle/mqtt-c/blob/master/docs/openssl_publisher_8c-example.html This C program demonstrates how to publish messages to an MQTT broker over an encrypted connection using OpenSSL. It handles command-line arguments for CA certificate path, broker address, port, and topic. The program initializes OpenSSL, establishes a secure connection, sets up an MQTT client, and continuously publishes the current time. It includes error handling and a background thread for client refreshing. Usage: ./bin/openssl_publisher ca_file [address [port [topic]]] ```C #include #include #include #include #include "templates/openssl_sockets.h" void publish_callback(void** unused, struct mqtt_response_publish *published); void* client_refresher(void* client); void exit_example(int status, BIO* sockfd, pthread_t *client_daemon); int main(int argc, const char *argv[]) { const char* addr; const char* port; const char* topic; const char* ca_file; /* Load OpenSSL */ SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); SSL_CTX* ssl_ctx; BIO* sockfd; if (argc > 1) { ca_file = argv[1]; } else { printf("error: path to the CA certificate to use\n"); exit(1); } /* get address (argv[2] if present) */ if (argc > 2) { addr = argv[2]; } else { addr = "test.mosquitto.org"; } /* get port number (argv[3] if present) */ if (argc > 3) { port = argv[3]; } else { port = "8883"; } /* get the topic name to publish */ if (argc > 4) { topic = argv[4]; } else { topic = "datetime"; } /* open the non-blocking TCP socket (connecting to the broker) */ open_nb_socket(&sockfd, &ssl_ctx, addr, port, ca_file, NULL); if (sockfd == NULL) { exit_example(EXIT_FAILURE, sockfd, NULL); } /* setup a client */ struct mqtt_client client; uint8_t sendbuf[2048]; /* sendbuf should be large enough to hold multiple whole mqtt messages */ uint8_t recvbuf[1024]; /* recvbuf should be large enough any whole mqtt message expected to be received */ mqtt_init(&client, sockfd, sendbuf, sizeof(sendbuf), recvbuf, sizeof(recvbuf), publish_callback); mqtt_connect(&client, "publishing_client", NULL, NULL, 0, NULL, NULL, 0, 400); /* check that we don't have any errors */ if (client.error != MQTT_OK) { fprintf(stderr, "error: %s\n", mqtt_error_str(client.error)); exit_example(EXIT_FAILURE, sockfd, NULL); } /* start a thread to refresh the client (handle egress and ingree client traffic) */ pthread_t client_daemon; if(pthread_create(&client_daemon, NULL, client_refresher, &client)) { fprintf(stderr, "Failed to start client daemon.\n"); exit_example(EXIT_FAILURE, sockfd, NULL); } /* start publishing the time */ printf("%s is ready to begin publishing the time.\n", argv[0]); printf("Press ENTER to publish the current time.\n"); printf("Press CTRL-D (or any other key) to exit.\n\n"); while(fgetc(stdin) == '\n') { /* get the current time */ time_t timer; time(&timer); struct tm* tm_info = localtime(&timer); char timebuf[26]; strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tm_info); /* print a message */ char application_message[256]; snprintf(application_message, sizeof(application_message), "The time is %s", timebuf); printf("%s published : \"%s\"", argv[0], application_message); /* publish the time */ mqtt_publish(&client, topic, application_message, strlen(application_message) + 1, MQTT_PUBLISH_QOS_2); /* check for errors */ if (client.error != MQTT_OK) { fprintf(stderr, "error: %s\n", mqtt_error_str(client.error)); exit_example(EXIT_FAILURE, sockfd, &client_daemon); } } /* disconnect */ printf("\n%s disconnecting from %s\n", argv[0], addr); sleep(1); /* exit */ exit_example(EXIT_SUCCESS, sockfd, &client_daemon); } void exit_example(int status, BIO* sockfd, pthread_t *client_daemon) { if (sockfd != NULL) BIO_free_all(sockfd); if (client_daemon != NULL) pthread_cancel(*client_daemon); exit(status); } void publish_callback(void** unused, struct mqtt_response_publish *published) { /* not used in this example */ } void* client_refresher(void* client) { while(1) { mqtt_sync((struct mqtt_client*) client); usleep(100000U); } return NULL; } ``` -------------------------------- ### C MQTT Time Publisher Example Source: https://github.com/liambindle/mqtt-c/blob/master/docs/simple_publisher_8c-example.html This C program implements a simple MQTT client that publishes the current system time. It connects to a configurable MQTT broker (default: test.mosquitto.org:1883) and publishes to a specified topic (default: datetime) whenever the user presses ENTER. The program manages client connection, error handling, and uses a separate thread for refreshing MQTT client traffic. ```C #include #include #include #include #include "templates/posix_sockets.h" void publish_callback(void** unused, struct mqtt_response_publish *published); void* client_refresher(void* client); void exit_example(int status, int sockfd, pthread_t *client_daemon); int main(int argc, const char *argv[]) { const char* addr; const char* port; const char* topic; /* get address (argv[1] if present) */ if (argc > 1) { addr = argv[1]; } else { addr = "test.mosquitto.org"; } /* get port number (argv[2] if present) */ if (argc > 2) { port = argv[2]; } else { port = "1883"; } /* get the topic name to publish */ if (argc > 3) { topic = argv[3]; } else { topic = "datetime"; } /* open the non-blocking TCP socket (connecting to the broker) */ int sockfd = open_nb_socket(addr, port); if (sockfd == -1) { perror("Failed to open socket: "); exit_example(EXIT_FAILURE, sockfd, NULL); } /* setup a client */ struct mqtt_client client; uint8_t sendbuf[2048]; /* sendbuf should be large enough to hold multiple whole mqtt messages */ uint8_t recvbuf[1024]; /* recvbuf should be large enough any whole mqtt message expected to be received */ mqtt_init(&client, sockfd, sendbuf, sizeof(sendbuf), recvbuf, sizeof(recvbuf), publish_callback); mqtt_connect(&client, "publishing_client", NULL, NULL, 0, NULL, NULL, 0, 400); /* check that we don't have any errors */ if (client.error != MQTT_OK) { fprintf(stderr, "error: %s\n", mqtt_error_str(client.error)); exit_example(EXIT_FAILURE, sockfd, NULL); } /* start a thread to refresh the client (handle egress and ingree client traffic) */ pthread_t client_daemon; if(pthread_create(&client_daemon, NULL, client_refresher, &client)) { fprintf(stderr, "Failed to start client daemon.\n"); exit_example(EXIT_FAILURE, sockfd, NULL); } /* start publishing the time */ printf("%s is ready to begin publishing the time.\n", argv[0]); printf("Press ENTER to publish the current time.\n"); printf("Press CTRL-D (or any other key) to exit.\n\n"); while(fgetc(stdin) == '\n') { /* get the current time */ time_t timer; time(&timer); struct tm* tm_info = localtime(&timer); char timebuf[26]; strftime(timebuf, 26, "%Y-%m-%d %H:%M:%S", tm_info); /* print a message */ char application_message[256]; snprintf(application_message, sizeof(application_message), "The time is %s", timebuf); printf("%s published : \"%s\"", argv[0], application_message); /* publish the time */ mqtt_publish(&client, topic, application_message, strlen(application_message) + 1, MQTT_PUBLISH_QOS_0); /* check for errors */ if (client.error != MQTT_OK) { fprintf(stderr, "error: %s\n", mqtt_error_str(client.error)); exit_example(EXIT_FAILURE, sockfd, &client_daemon); } } /* disconnect */ printf("\n%s disconnecting from %s\n", argv[0], addr); sleep(1); /* exit */ exit_example(EXIT_SUCCESS, sockfd, &client_daemon); } void exit_example(int status, int sockfd, pthread_t *client_daemon) { if (sockfd != -1) close(sockfd); if (client_daemon != NULL) pthread_cancel(*client_daemon); exit(status); } void publish_callback(void** unused, struct mqtt_response_publish *published) { /* not used in this example */ } void* client_refresher(void* client) { while(1) { mqtt_sync((struct mqtt_client*) client); usleep(100000U); } return NULL; } ``` -------------------------------- ### Subscribe to MQTT Topic in C Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html This example illustrates how to subscribe to a specific MQTT topic, "toaster/temperature", with a Quality of Service (QoS) level of 0. Subscribing allows the client to receive messages published on that topic. ```C /* subscribe to "toaster/temperature" with a max QoS level of 0 */ mqtt_subscribe(&client, "toaster/temperature", 0); ``` -------------------------------- ### Build MQTT-C Tests with CMocka Framework Source: https://github.com/liambindle/mqtt-c/blob/master/CMakeLists.txt This snippet configures the build process for MQTT-C tests. It attempts to find the CMocka unit testing framework, links it with the 'mqttc' library, and includes its headers. A fatal error is raised if CMocka is not found, guiding the user to set CMAKE_PREFIX_PATH. ```CMake # Build tests if(MQTT_C_TESTS) find_path(CMOCKA_INCLUDE_DIR cmocka.h) find_library(CMOCKA_LIBRARY cmocka) if((NOT CMOCKA_INCLUDE_DIR) OR (NOT CMOCKA_LIBRARY)) message(FATAL_ERROR "Failed to find cmocka! Add cmocka's install prefix to CMAKE_PREFIX_PATH to resolve this error.") endif() add_executable(tests tests.c) target_link_libraries(tests ${CMOCKA_LIBRARY} mqttc) target_include_directories(tests PRIVATE ${CMOCKA_INCLUDE_DIR}) endif() ``` -------------------------------- ### Configure MQTT-C Project and Basic Build Options Source: https://github.com/liambindle/mqtt-c/blob/master/CMakeLists.txt This snippet sets the minimum required CMake version, defines the project name and version, and declares various build options for MQTT-C, such as enabling support for different TLS libraries, building examples, and building tests. ```CMake cmake_minimum_required(VERSION 3.5) project(MQTT-C VERSION 1.1.2 LANGUAGES C) # MQTT-C build options option(MQTT_C_OpenSSL_SUPPORT "Build MQTT-C with OpenSSL support?" OFF) option(MQTT_C_MbedTLS_SUPPORT "Build MQTT-C with mbed TLS support?" OFF) option(MQTT_C_BearSSL_SUPPORT "Build MQTT-C with Bear SSL support?" OFF) option(MQTT_C_EXAMPLES "Build MQTT-C examples?" ON) option(MQTT_C_INSTALL_EXAMPLES "Install MQTT-C examples?" OFF) option(MQTT_C_TESTS "Build MQTT-C tests?" OFF) list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_POSITION_INDEPENDENT_CODE ON) ``` -------------------------------- ### C Example: MQTT Subscriber with Automatic Reconnection Source: https://github.com/liambindle/mqtt-c/blob/master/docs/reconnect_subscriber_8c-example.html This C code demonstrates an MQTT subscriber that automatically reconnects to the broker upon connection loss or errors. It initializes an MQTT client with a custom `reconnect_client` callback, which handles socket closure, re-opening, client reinitialization, and re-subscription. The main function sets up the client, starts a refresh daemon in a separate thread, and allows manual injection of errors to test the reconnection logic. It subscribes to a user-defined topic (defaulting to 'datetime') and prints messages received. ```C #include #include #include #include #include "templates/posix_sockets.h" struct reconnect_state_t { const char* hostname; const char* port; const char* topic; uint8_t* sendbuf; size_t sendbufsz; uint8_t* recvbuf; size_t recvbufsz; }; void reconnect_client(struct mqtt_client* client, void **reconnect_state_vptr); void publish_callback(void** unused, struct mqtt_response_publish *published); void* client_refresher(void* client); void exit_example(int status, int sockfd, pthread_t *client_daemon); int main(int argc, const char *argv[]) { const char* addr; const char* port; const char* topic; /* get address (argv[1] if present) */ if (argc > 1) { addr = argv[1]; } else { addr = "test.mosquitto.org"; } /* get port number (argv[2] if present) */ if (argc > 2) { port = argv[2]; } else { port = "1883"; } /* get the topic name to publish */ if (argc > 3) { topic = argv[3]; } else { topic = "datetime"; } /* build the reconnect_state structure which will be passed to reconnect */ struct reconnect_state_t reconnect_state; reconnect_state.hostname = addr; reconnect_state.port = port; reconnect_state.topic = topic; uint8_t sendbuf[2048]; uint8_t recvbuf[1024]; reconnect_state.sendbuf = sendbuf; reconnect_state.sendbufsz = sizeof(sendbuf); reconnect_state.recvbuf = recvbuf; reconnect_state.recvbufsz = sizeof(recvbuf); /* setup a client */ struct mqtt_client client; mqtt_init_reconnect(&client, reconnect_client, &reconnect_state, publish_callback ); /* start a thread to refresh the client (handle egress and ingree client traffic) */ pthread_t client_daemon; if(pthread_create(&client_daemon, NULL, client_refresher, &client)) { fprintf(stderr, "Failed to start client daemon.\n"); exit_example(EXIT_FAILURE, -1, NULL); } /* start publishing the time */ printf("%s listening for '%s' messages.\n", argv[0], topic); printf("Press ENTER to inject an error.\n"); printf("Press CTRL-D to exit.\n\n"); /* block */ while(fgetc(stdin) != EOF) { printf("Injecting error: \"MQTT_ERROR_SOCKET_ERROR\"\n"); client.error = MQTT_ERROR_SOCKET_ERROR; } /* disconnect */ printf("\n%s disconnecting from %s\n", argv[0], addr); sleep(1); /* exit */ exit_example(EXIT_SUCCESS, client.socketfd, &client_daemon); } void reconnect_client(struct mqtt_client* client, void **reconnect_state_vptr) { struct reconnect_state_t *reconnect_state = *((struct reconnect_state_t**) reconnect_state_vptr); /* Close the clients socket if this isn't the initial reconnect call */ if (client->error != MQTT_ERROR_INITIAL_RECONNECT) { close(client->socketfd); } /* Perform error handling here. */ if (client->error != MQTT_ERROR_INITIAL_RECONNECT) { printf("reconnect_client: called while client was in error state \"%s\"\n", mqtt_error_str(client->error) ); } /* Open a new socket. */ int sockfd = open_nb_socket(reconnect_state->hostname, reconnect_state->port); if (sockfd == -1) { perror("Failed to open socket: "); exit_example(EXIT_FAILURE, sockfd, NULL); } /* Reinitialize the client. */ mqtt_reinit(client, sockfd, reconnect_state->sendbuf, reconnect_state->sendbufsz, reconnect_state->recvbuf, reconnect_state->recvbufsz ); /* Send connection request to the broker. */ mqtt_connect(client, "subscribing_client", NULL, NULL, 0, NULL, NULL, 0, 400); /* Subscribe to the topic. */ mqtt_subscribe(client, reconnect_state->topic, 0); } void exit_example(int status, int sockfd, pthread_t *client_daemon) { if (sockfd != -1) close(sockfd); if (client_daemon != NULL) pthread_cancel(*client_daemon); exit(status); } void publish_callback(void** unused, struct mqtt_response_publish *published) { } ``` -------------------------------- ### C++ Class Structure for Doxygen Graph Example Source: https://github.com/liambindle/mqtt-c/blob/master/docs/graph_legend.html This C++ code defines a set of classes demonstrating various inheritance and composition relationships, specifically crafted to illustrate how Doxygen visualizes these structures in its generated graphs. It includes examples of public, protected, and private inheritance, template class usage, and class containment. ```C++ /*! Invisible class because of truncation */ class Invisible { }; /*! Truncated class, inheritance relation is hidden */ class Truncated : public Invisible { }; /* Class not documented with doxygen comments */ class Undocumented { }; /*! Class that is inherited using public inheritance */ class PublicBase : public Truncated { }; /*! A template class */ template class Templ { }; /*! Class that is inherited using protected inheritance */ class ProtectedBase { }; /*! Class that is inherited using private inheritance */ class PrivateBase { }; /*! Class that is used by the Inherited class */ class Used { }; /*! Super class that inherits a number of other classes */ class Inherited : public PublicBase, protected ProtectedBase, private PrivateBase, public Undocumented, public Templ { private: Used *m_usedClass; }; ``` -------------------------------- ### Initialize MQTT-C Client in C Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html This snippet demonstrates the initial steps to set up an MQTT-C client. It involves declaring a `struct mqtt_client` and then calling `mqtt_init` to prepare the client for operations. This is a prerequisite for any further MQTT communication. ```C struct mqtt_client client; /* instantiate the client */ mqtt_init(&client, ...); /* initialize the client */ ``` -------------------------------- ### MQTT-C Core API and File References Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html This section provides a quick reference to key structures, functions, and source/header files within the MQTT-C library. It covers client instantiation, connection, subscription, publishing, and the core implementation files. ```APIDOC struct mqtt_client: An MQTT client structure. mqtt_init(client, ...): Initializes an MQTT client. mqtt_connect(client, ...): Sends a connection request to the broker. mqtt_subscribe(client, topic, qos): Subscribes to an MQTT topic. mqtt_publish(client, topic, payload, size, qos): Publishes a message to an MQTT topic. mqtt.c: Implements the functionality of MQTT-C. mqtt_pal.c: Implements mqtt_pal_sendall and mqtt_pal_recvall and platform-specific helpers. mqtt.h: Declares all the MQTT-C functions and datastructures. mqtt_pal.h: Includes/supports the types/calls required by the MQTT-C client. ``` -------------------------------- ### Initialize MQTT Client Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h.html Initializes an MQTT client instance. This function is a prerequisite and must be called before any other API functions are used to ensure the client is properly set up with its socket and buffers. ```APIDOC enum MQTTErrors mqtt_init( struct mqtt_client *client, mqtt_pal_socket_handle sockfd, uint8_t *sendbuf, size_t sendbufsz, uint8_t *recvbuf, size_t recvbufsz, void(*publish_response_callback)(void **state, struct mqtt_response_publish *publish) ) ``` -------------------------------- ### Get Message from MQTT Queue by Index Macro Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Macro to retrieve a queued message from the MQTT message queue by its index, relative to the end of the memory buffer. ```C #define mqtt_mq_get(mq_ptr, index) (((struct mqtt_queued_message*) ((mq_ptr)->mem_end)) - 1 - index) ``` -------------------------------- ### Initialize MQTT Client in C Source: https://github.com/liambindle/mqtt-c/blob/master/README.md Demonstrates how to instantiate a `struct mqtt_client` and initialize it by calling the `mqtt_init` function. This is the first step before connecting to an MQTT broker. ```C struct mqtt_client client; /* instantiate the client */ mqtt_init(&client, ...); /* initialize the client */ ``` -------------------------------- ### Get String Representation of MQTT Error Code Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Retrieves a human-readable string representation for a given MQTT error code. This function is useful for debugging and logging. ```C const char* mqtt_error_str(enum MQTTErrors error); ``` -------------------------------- ### Get MQTT Error String from Error Code Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h.html Retrieves a human-readable error message corresponding to a given MQTT error code. Useful for debugging and error reporting. ```APIDOC const char * mqtt_error_str(enum MQTTErrors error): Returns an error message for error code, 'error'. Parameters: error: enum MQTTErrors - The MQTT error code. Returns: const char *: A string describing the error. ``` -------------------------------- ### API: Get MQTT Error String Source: https://github.com/liambindle/mqtt-c/blob/master/docs/group__api.html Retrieves a human-readable error message corresponding to a given MQTT error code. This is useful for debugging and displaying informative messages to the user. ```APIDOC mqtt_error_str(error: enum MQTTErrors) -> const char* Description: Returns an error message for error code, error. Parameters: error: [in] enum MQTTErrors - the error code. Returns: The associated error message. ``` -------------------------------- ### Initialize MQTT Client (mqtt_init) Source: https://github.com/liambindle/mqtt-c/blob/master/docs/group__api.html Initializes an MQTT client instance, setting up its internal state, socket handle, and send/receive buffers. This function is a prerequisite and must be called before any other MQTT-C API functions are used for a given client. ```APIDOC enum MQTTErrors mqtt_init( struct mqtt_client *client, mqtt_pal_socket_handle sockfd, uint8_t *sendbuf, size_t sendbufsz, uint8_t *recvbuf, size_t recvbufsz, void(*publish_response_callback)(void **state, struct mqtt_response_publish *publish) ) client: Pointer to the mqtt_client structure to initialize. sockfd: The platform-specific socket handle for network communication. sendbuf: Pointer to the buffer used for sending data. sendbufsz: Size of the send buffer in bytes. recvbuf: Pointer to the buffer used for receiving data. recvbufsz: Size of the receive buffer in bytes. publish_response_callback: A callback function invoked when a PUBLISH message is received from the broker. Returns: An MQTTErrors enumeration value indicating the success or failure of the initialization. ``` -------------------------------- ### mqtt_queued_message Struct Members Source: https://github.com/liambindle/mqtt-c/blob/master/docs/functions.html Outlines members of the mqtt_queued_message struct, used for managing properties of messages stored in a queue, including size, start position, state, and send time. ```APIDOC struct mqtt_queued_message { size; start; state; time_sent; } ``` -------------------------------- ### Connect to MQTT Broker in C Source: https://github.com/liambindle/mqtt-c/blob/master/README.md Shows how to establish a connection from the initialized MQTT client to an MQTT broker using the `mqtt_connect` function. After this, the client is ready for messaging operations. ```C mqtt_connect(&client, ...); /* send a connection request to the broker. */ ``` -------------------------------- ### C Macro: Get MQTT Message Queue Length Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h.html This macro returns the number of messages currently in the mq_ptr message queue. It provides a way to determine the queue's occupancy. ```C #define mqtt_mq_length(mq_ptr) (((struct mqtt_queued_message*) ((mq_ptr)->mem_end)) - (mq_ptr)->queue_tail) ``` -------------------------------- ### C Macro: Get MQTT Queued Message by Index Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h.html This macro returns the mqtt_queued_message at a specified index within a message queue. It provides direct access to messages stored in the queue. ```C #define mqtt_mq_get(mq_ptr, index) (((struct mqtt_queued_message*) ((mq_ptr)->mem_end)) - 1 - index) ``` -------------------------------- ### API: Initialize MQTT Client Source: https://github.com/liambindle/mqtt-c/blob/master/docs/group__api.html Initializes an MQTT client instance, setting up buffers and a callback for incoming publish messages. This function must be called before any other API functions and prepares the client for connection. It handles potential buffer overflow errors during runtime. ```APIDOC mqtt_init( client: struct mqtt_client *, sockfd: mqtt_pal_socket_handle, sendbuf: uint8_t *, sendbufsz: size_t, recvbuf: uint8_t *, recvbufsz: size_t, publish_response_callback: void(*)(void **state, struct mqtt_response_publish *publish) ) -> enum MQTTErrors Description: Initializes an MQTT client. This function must be called before any other API function calls. Precondition: None. Parameters: client: [out] struct mqtt_client * - The MQTT client. sockfd: [in] mqtt_pal_socket_handle - The socket file descriptor (or equivalent socket handle, e.g. BIO pointer for OpenSSL sockets) connected to the MQTT broker. sendbuf: [in] uint8_t * - A buffer that will be used for sending messages to the broker. sendbufsz: [in] size_t - The size of sendbuf in bytes. recvbuf: [in] uint8_t * - A buffer that will be used for receiving messages from the broker. recvbufsz: [in] size_t - The size of recvbuf in bytes. publish_response_callback: [in] void(*)(void **state, struct mqtt_response_publish *publish) - The callback to call whenever application messages are received from the broker. Postcondition: mqtt_connect must be called. Note: sockfd is a non-blocking TCP connection. If sendbuf fills up completely during runtime a MQTT_ERROR_SEND_BUFFER_IS_FULL error will be set. Similarly if recvbuf is ever to small to receive a message from the broker an MQTT_ERROR_RECV_BUFFER_TOO_SMALL error will be set. A pointer to mqtt_client::publish_response_callback_state is always passed as the state argument to publish_response_callback. Note that the second argument is the mqtt_response_publish that was received from the broker. Attention: Only initialize an MQTT client once (i.e. don't call mqtt_init or mqtt_init_reconnect more than once per client). Returns: MQTT_OK upon success, an MQTTErrors otherwise. ``` -------------------------------- ### Get MQTT Error String (mqtt_error_str) Source: https://github.com/liambindle/mqtt-c/blob/master/docs/group__api.html Retrieves a human-readable string message for a given MQTT error code. This function is useful for debugging and logging purposes, allowing applications to present more descriptive error information to users. ```APIDOC const char * mqtt_error_str(enum MQTTErrors error) error: The MQTTErrors enumeration value representing the error code. Returns: A constant character pointer to the error message string. ``` -------------------------------- ### MQTT-C API Module Documentation Source: https://github.com/liambindle/mqtt-c/blob/master/docs/modules.html Provides comprehensive documentation for using the MQTT-C client, covering all essential functionalities and interfaces. ```APIDOC Module Name: API Purpose: Documentation of everything you need to know to use the MQTT-C client ``` -------------------------------- ### MQTT Internal Ping Broker Function (No Lock) Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Pings the MQTT broker without acquiring a mutex lock. This is an internal function used when mutex locking is handled externally or not required, for example, within a locked context. ```APIDOC Function: __mqtt_ping Signature: enum MQTTErrors __mqtt_ping(struct mqtt_client *client) Parameters: client: struct mqtt_client * - Pointer to the MQTT client instance. Returns: enum MQTTErrors - An error code indicating success or failure. ``` -------------------------------- ### Establish Session with MQTT Broker Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h.html Initiates and establishes a session with the MQTT broker using the provided client ID, optional will message, user credentials, connection flags, and keep-alive interval. ```APIDOC enum MQTTErrors mqtt_connect( struct mqtt_client *client, const char *client_id, const char *will_topic, const void *will_message, size_t will_message_size, const char *user_name, const char *password, uint8_t connect_flags, uint16_t keep_alive ) ``` -------------------------------- ### Run MQTT-C Unit Tests (Shell) Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html This command executes the compiled MQTT-C unit tests. Users can optionally specify the address and port of an MQTT broker; otherwise, the Mosquitto MQTT Test Server and port 1883 are used by default. ```Shell ./bin/tests [address [port]] ``` -------------------------------- ### APIDOC: MQTT Client Connection and Publish Functions Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html These functions provide the primary API for establishing an MQTT connection and publishing messages. `mqtt_connect` initiates a connection to the broker with specified client details and connection flags, while `mqtt_publish` sends an application message to a given topic. ```APIDOC enum MQTTErrors mqtt_connect( struct mqtt_client *client, const char* client_id, const char* will_topic, const void* will_message, size_t will_message_size, const char* user_name, const char* password, uint8_t connect_flags, uint16_t keep_alive ); client: Pointer to the MQTT client instance. client_id: The client identifier string. will_topic: The topic for the Last Will and Testament message (optional). will_message: The content of the Last Will and Testament message (optional). will_message_size: Size of the Last Will and Testament message. user_name: Username for authentication (optional). password: Password for authentication (optional). connect_flags: Bitmask of MQTT connect flags (e.g., clean session, will flags). keep_alive: Keep-alive interval in seconds. Returns: MQTTErrors enum indicating success or failure. enum MQTTErrors mqtt_publish( struct mqtt_client *client, const char* topic_name, void* application_message, size_t application_message_size, uint8_t publish_flags ); client: Pointer to the MQTT client instance. topic_name: The topic to publish to. application_message: The payload of the message. application_message_size: Size of the message payload. publish_flags: Bitmask of MQTT publish flags (e.g., QoS, retain). Returns: MQTTErrors enum indicating success or failure. ``` -------------------------------- ### Run MQTT-C Unit Tests Source: https://github.com/liambindle/mqtt-c/blob/master/README.md Command to execute the built unit tests for MQTT-C. Optional arguments for the MQTT broker address and port can be provided; if omitted, it defaults to the Mosquitto MQTT Test Server on port 1883. ```Bash ./bin/tests [address [port]] ``` -------------------------------- ### Pack MQTT Connection Request Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Packs an MQTT CONNECT packet into a buffer, including client ID, will topic/message, user credentials, and connection flags. ```C ssize_t mqtt_pack_connection_request(uint8_t* buf, size_t bufsz, const char* client_id, const char* will_topic, const void* will_message, size_t will_message_size, const char* user_name, const char* password, uint8_t connect_flags, uint16_t keep_alive); ``` -------------------------------- ### Connect MQTT-C Client to Broker in C Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html After initialization, the client must connect to an MQTT broker. This snippet shows how to use `mqtt_connect` to send a connection request, establishing the link for message exchange. ```C mqtt_connect(&client, ...); /* send a connection request to the broker. */ ``` -------------------------------- ### Initialize MQTT Message Queue Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Initializes an MQTT message queue with a provided buffer and its size. ```C void mqtt_mq_init(struct mqtt_message_queue *mq, void *buf, size_t bufsz); ``` -------------------------------- ### APIDOC: MQTT Client Initialization and Synchronization Functions Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html These functions provide the primary API for initializing and managing the MQTT client's lifecycle. `mqtt_init` sets up a new client, `mqtt_init_reconnect` configures automatic reconnection, `mqtt_reinit` allows re-initialization with new socket/buffers, and `mqtt_sync` processes pending MQTT messages. ```APIDOC enum MQTTErrors mqtt_sync(struct mqtt_client *client); client: Pointer to the MQTT client instance. Returns: MQTTErrors enum indicating success or failure. enum MQTTErrors mqtt_init( struct mqtt_client *client, mqtt_pal_socket_handle sockfd, uint8_t *sendbuf, size_t sendbufsz, uint8_t *recvbuf, size_t recvbufsz, void (*publish_response_callback)(void** state, struct mqtt_response_publish *publish) ); client: Pointer to the MQTT client instance to initialize. sockfd: The socket file descriptor to use for communication. sendbuf: Pointer to the send buffer. sendbufsz: Size of the send buffer. recvbuf: Pointer to the receive buffer. recvbufsz: Size of the receive buffer. publish_response_callback: Callback function for handling incoming PUBLISH messages. Returns: MQTTErrors enum indicating success or failure. void mqtt_init_reconnect( struct mqtt_client *client, void (*reconnect_callback)(struct mqtt_client *client, void** state), void *reconnect_state, void (*publish_response_callback)(void** state, struct mqtt_response_publish *publish) ); client: Pointer to the MQTT client instance. reconnect_callback: Callback function to be invoked when a reconnection attempt is needed. reconnect_state: User-defined state passed to the reconnect callback. publish_response_callback: Callback function for handling incoming PUBLISH messages. void mqtt_reinit( struct mqtt_client* client, mqtt_pal_socket_handle socketfd, uint8_t *sendbuf, size_t sendbufsz, uint8_t *recvbuf, size_t recvbufsz ); client: Pointer to the MQTT client instance to reinitialize. socketfd: The new socket file descriptor. sendbuf: Pointer to the new send buffer. sendbufsz: Size of the new send buffer. recvbuf: Pointer to the new receive buffer. recvbufsz: Size of the new receive buffer. ``` -------------------------------- ### Publish Message to MQTT Topic in C Source: https://github.com/liambindle/mqtt-c/blob/master/README.md Demonstrates how to publish data, like a coffee temperature, to an MQTT topic with a specified Quality of Service (QoS) level using the `mqtt_publish` function. ```C /* publish coffee temperature with a QoS level of 1 */ int temperature = 67; mqtt_publish(&client, "coffee/temperature", &temperature, sizeof(int), MQTT_PUBLISH_QOS_1); ``` -------------------------------- ### API Reference: mqtt_mq_init - Initialize Message Queue Source: https://github.com/liambindle/mqtt-c/blob/master/docs/group__details.html Documents the `mqtt_mq_init` function, responsible for initializing a message queue with a specified buffer and size. ```APIDOC mqtt_mq_init: Description: Initialize a message queue. Signature: void mqtt_mq_init ( struct mqtt_message_queue * mq, void * buf, size_t bufsz ) Parameters: mq: The message queue to initialize. buf: The buffer for this message queue. bufsz: The number of bytes in the buffer. ``` -------------------------------- ### MQTT-C Utilities Module Source: https://github.com/liambindle/mqtt-c/blob/master/docs/modules.html Documents various utility functions and components that support the implementation of the MQTT-C client, useful for developers seeking to understand the underlying helper mechanisms. ```APIDOC Module Name: Utilities Purpose: Developer documentation for the utilities used to implement the MQTT-C client ``` -------------------------------- ### Initialize MQTT Client with Reconnect in C Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Initializes an MQTT client instance and configures it for automatic reconnections. This function serves as an alternative to mqtt_init, providing callbacks for reconnection events and handling publish responses. It requires a client structure, a reconnection callback, its state, and a publish response callback. ```C void mqtt_init_reconnect(struct mqtt_client *client, void(*reconnect_callback)(struct mqtt_client *client, void **state), void *reconnect_state, void(*publish_response_callback)(void **state, struct mqtt_response_publish *publish)) ``` -------------------------------- ### Establish MQTT Session (C API) Source: https://github.com/liambindle/mqtt-c/blob/master/docs/mqtt_8h_source.html Establishes a session with the MQTT broker by sending a CONNECT packet. This function handles client identification, will messages, authentication, and keep-alive settings. ```APIDOC enum MQTTErrors mqtt_connect(struct mqtt_client *client, const char *client_id, const char *will_topic, const void *will_message, size_t will_message_size, const char *user_name, const char *password, uint8_t connect_flags, uint16_t keep_alive) client: Pointer to the MQTT client instance. client_id: The client identifier. will_topic: Topic for the Last Will and Testament message. will_message: The Last Will and Testament message payload. will_message_size: Size of the will message payload. user_name: Username for authentication. password: Password for authentication. connect_flags: Flags for the connect operation (e.g., clean session, will flags). keep_alive: Keep-alive interval in seconds. Returns: MQTTErrors enum indicating success or failure. ``` -------------------------------- ### Publish MQTT Message in C Source: https://github.com/liambindle/mqtt-c/blob/master/docs/index.html This snippet demonstrates publishing an integer value, representing coffee temperature, to the "coffee/temperature" topic. It uses `mqtt_publish` with a QoS level of 1, ensuring message delivery. ```C /* publish coffee temperature with a QoS level of 1 */ int temperature = 67; mqtt_publish(&client, "coffee/temperature", &temperature, sizeof(int), MQTT_PUBLISH_QOS_1); ```