### Build All MQTT-C Tests and Examples Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/README.md Use this command to build all unit tests and examples for the MQTT-C library. Ensure cmocka is installed and you are on a UNIX-like system. ```bash $ make all ``` -------------------------------- ### Build MQTT C Subscriber Examples Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt Builds subscriber example executables for MQTT C. Links against the Threads library and the MQTT C library. These targets are always installed if examples are enabled. ```cmake 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() ``` -------------------------------- ### Install MQTT-C Library and Headers Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt This section defines the installation rules for the MQTT-C library and its header files. The library target 'mqttc' is installed to the specified library directory, and the 'include/' directory is installed to the specified include directory. ```cmake # Install includes and library install(TARGETS mqttc DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ``` -------------------------------- ### Example HTTP Requests Source: https://github.com/duet3d/reprapfirmware/wiki/HTTP-requests Examples demonstrating how to connect to the printer and then list files or query the object model using curl. ```bash curl http://
/rr_connect?password= curl http://
/rr_files?dir=/macros/ ``` ```bash curl http://
/rr_connect?password= curl http://
/rr_model?key=boards[0] ``` -------------------------------- ### Configuration Response Example Source: https://github.com/duet3d/reprapfirmware/wiki/JSON-responses This JSON object contains machine configuration parameters such as axis limits, accelerations, currents, and firmware details. It reflects the current setup of the printer. ```json { "axisMins": [0.0, 0.0, 0.0], "axisMaxes": [220.0, 200.0, 180.0], "accelerations": [1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0], "currents": [800.0, 1000.0, 800.0, 1000.0, 800.0, 800.0, 8000, 800.0], "firmwareElectronics": "Duet 3 MB6HC", "firmwareName": "RepRapFirmware", "boardName": "MB6HC", "firmwareVersion": "3.0beta12+1", "dwsVersion": "1.24", "firmwareDate": "2019-11-05b1", "idleCurrentFactor": 35.0, "idleTimeout": 30.0, "minFeedrates": [10.0, 10.0, 0.5, 0.33, 0.33, 0.33, 0.33, 0.33], "maxFeedrates": [250.0, 250.0, 3.0, 60.0, 60.0, 60.0, 60.0, 60.0] } ``` -------------------------------- ### Build MQTT C Simple Publisher Example Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt Builds a simple publisher example for MQTT C when no specific TLS support is enabled. Links against the Threads library and the MQTT C library. ```cmake 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() ``` -------------------------------- ### Build MQTT C Examples with OpenSSL (Windows) Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt Builds example executables for MQTT C using OpenSSL on Windows. Links against the Threads library and the MQTT C library. ```cmake 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) ``` -------------------------------- ### Build MQTT C Examples with BearSSL Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt Builds an example executable for MQTT C using BearSSL. Links against the MQTT C library and the BearSSL library. ```cmake 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() ``` -------------------------------- ### Build MQTT C Examples with Mbed TLS Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt Builds an example executable for MQTT C using Mbed TLS. Links against the Threads library, MQTT C library, and Mbed TLS libraries. ```cmake 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() ``` -------------------------------- ### Install Make Utility on MSYS2 Source: https://github.com/duet3d/reprapfirmware/wiki/Building-RepRapFirmware Installs the 'make' utility using the pacman package manager within the MSYS2 environment. Ensure MSYS2 is installed and its 'usr/bin' directory is in your PATH. ```bash pacman -S make ``` -------------------------------- ### PPP Notify Phase Callback Example Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/LwipEthernet/Lwip/doc/ppp.txt A callback function that is invoked on each PPP internal state change. This example demonstrates setting an LED based on the current phase of the PPP session, such as initializing, running, or dead. ```c static void ppp_notify_phase_cb(ppp_pcb *pcb, u8_t phase, void *ctx) { switch (phase) { /* Session is down (either permanently or briefly) */ case PPP_PHASE_DEAD: led_set(PPP_LED, LED_OFF); break; /* We are between two sessions */ case PPP_PHASE_HOLDOFF: led_set(PPP_LED, LED_SLOW_BLINK); break; /* Session just started */ case PPP_PHASE_INITIALIZE: led_set(PPP_LED, LED_FAST_BLINK); break; /* Session is running */ case PPP_PHASE_RUNNING: led_set(PPP_LED, LED_ON); break; default: break; } } ``` -------------------------------- ### Example TXT Record Callback Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/LwipEthernet/Lwip/doc/mdns.txt An example callback function for providing TXT records for a registered service. It demonstrates adding a single TXT item. Note the constraints on individual item length (63 bytes) and total length (255 bytes). ```c static void srv_txt(struct mdns_service *service, void *txt_userdata) { res = mdns_resp_add_service_txtitem(service, "path=/", 6); LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return); } ``` -------------------------------- ### MQTT Client Initialization and Connection Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/LwipEthernet/Lwip/doc/mqtt_client.txt Demonstrates how to reserve memory for the MQTT client and establish a connection to the server. Supports both static and dynamic memory allocation. ```c mqtt_client_t static_client; example_do_connect(&static_client); ``` ```c mqtt_client_t *client = mqtt_client_new(); if(client != NULL) { example_do_connect(&client); } ``` ```c void example_do_connect(mqtt_client_t *client) { struct mqtt_connect_client_info_t ci; err_t err; /* Setup an empty client info structure */ memset(&ci, 0, sizeof(ci)); /* Minimal amount of information required is client identifier, so set it here */ ci.client_id = "lwip_test"; /* Initiate client and connect to server, if this fails immediately an error code is returned otherwise mqtt_connection_cb will be called with connection result after attempting to establish a connection with the server. For now MQTT version 3.1.1 is always used */ err = mqtt_client_connect(client, ip_addr, MQTT_PORT, mqtt_connection_cb, 0, &ci); /* For now just print the result code if something goes wrong */ if(err != ERR_OK) { printf("mqtt_connect return %d\n", err); } } ``` -------------------------------- ### MQTT Client Initialization and Connection Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/LwipEthernet/Lwip/doc/mqtt_client.txt Demonstrates how to initialize the MQTT client, either statically or dynamically, and establish a connection to the MQTT server. ```APIDOC ## MQTT Client Initialization and Connection ### Description This section covers the initial steps for using the MQTT client, including memory allocation and establishing a connection to the MQTT server. ### Static Allocation ```c mqtt_client_t static_client; example_do_connect(&static_client); ``` ### Dynamic Allocation ```c mqtt_client_t *client = mqtt_client_new(); if(client != NULL) { example_do_connect(&client); } ``` ### Establishing Connection ```c void example_do_connect(mqtt_client_t *client) { struct mqtt_connect_client_info_t ci; err_t err; memset(&ci, 0, sizeof(ci)); ci.client_id = "lwip_test"; err = mqtt_client_connect(client, ip_addr, MQTT_PORT, mqtt_connection_cb, 0, &ci); if(err != ERR_OK) { printf("mqtt_connect return %d\n", err); } } ``` ### Checking Connection Status Connection status can be checked using `mqtt_client_is_connected(client)`. ``` -------------------------------- ### Configure Installation Paths for UNIX Systems Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt This snippet handles multi-lib Linux systems correctly and allows custom installation locations by including the GNUInstallDirs module and marking standard installation directories as advanced. This ensures flexibility in where the library and headers are installed. ```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() ``` -------------------------------- ### Install Eclipse for C++ Source: https://github.com/duet3d/reprapfirmware/wiki/Building-RepRapFirmware Installs the Eclipse IDE for C++ developers using Homebrew. ```bash brew install --cask eclipse-cpp ``` -------------------------------- ### Install GCC ARM Embedded Toolchain Source: https://github.com/duet3d/reprapfirmware/wiki/Building-RepRapFirmware Installs the GCC ARM Embedded toolchain using Homebrew. ```bash brew install --cask gcc-arm-embedded ``` -------------------------------- ### Build and Run Unit Tests Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/index.html Build all unit tests and examples using the provided Makefile. Run tests specifying broker address and port if needed. ```bash $ make all $ ./bin/tests [address [port]] ``` -------------------------------- ### GET /rr_upload Source: https://github.com/duet3d/reprapfirmware/wiki/HTTP-requests Get the last file upload result. Returns a JSON object indicating success or failure. ```APIDOC ## GET /rr_upload ### Description Get the last file upload result. ### Method GET ### Endpoint /rr_upload ### Response #### Success Response (200) - **object** - An object containing the upload result code. - **err** (integer) - `0` if the last upload successfully finished or `1` if an error occurred. ``` -------------------------------- ### Advanced Status Response Example Source: https://github.com/duet3d/reprapfirmware/wiki/JSON-responses This is an example of the Type 2 advanced status response, providing detailed machine parameters. ```json { "params": { "fanNames": [""], }, "temps": { "names": ["" } }, ... "coldExtrudeTemp": 160.0, "coldRetractTemp": 90.0, "compensation": "None", "controllableFans": 0, "tempLimit": 290.0, "endstops": 0, "firmwareName": "RepRapFirmware for Duet 3 v0.6", "firmwareVersion": "3.0beta12+1", "geometry": "cartesian", "axes": 3, "totalAxes": 3, "axisNames": "XYZ", "volumes": 1, "mountedVolumes": 0, "mode": "FFF", "name": "duet3", "probe": { "threshold": 500, "height": 0.70, "type": 0 }, "tools": [], "mcutemp": { "min": 24.0, "cur": 37.4, "max": 37.6 }, "vin": { "min": 0.2, "cur": 0.3, "max": 0.3 }, "v12": { "min": 0.2, "cur": 0.2, "max": 0.2 } } ``` -------------------------------- ### Exit Example Function Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/bio_publisher_8c-example.html Handles the cleanup and exit process for the example, freeing resources such as the BIO socket and canceling the client daemon thread. ```c 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); } ``` -------------------------------- ### Initialize OpenSSL and Load Libraries Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/openssl_publisher_8c-example.html This snippet shows the necessary steps to initialize the OpenSSL library, load error strings, and add all algorithms for use in secure communication. ```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 (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\"\n", 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; } ``` -------------------------------- ### Initialize and Connect MQTT Client Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/bio_publisher_8c-example.html Initializes the MQTT client with socket details and connects to the broker. Ensure the send and receive buffers are adequately sized for expected message loads. ```c #include #include #include #include #include "templates/bio_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; /* Load OpenSSL */ SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); /* 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) */ BIO* sockfd = open_nb_socket(addr, port); 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); } ``` -------------------------------- ### Initialize MQTT Client Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/README.md Instantiate and initialize an mqtt_client struct before use. ```c struct mqtt_client client; /* instantiate the client */ mqtt_init(&client, ...); /* initialize the client */ ``` -------------------------------- ### Configure MQTT-C Library Include Directories and Link Libraries Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/CMakeLists.txt Sets public include directories for the 'mqttc' library and links necessary system libraries, such as 'ws2_32' on MSVC. ```cmake target_include_directories(mqttc PUBLIC include) target_link_libraries(mqttc PUBLIC $<$:ws2_32> ) ``` -------------------------------- ### mqtt_mq_init Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/group__details.html Initialize a message queue. ```APIDOC ## mqtt_mq_init ### Description Initialize a message queue. ### Signature ```c void mqtt_mq_init(struct mqtt_message_queue *mq, void *buf, size_t bufsz) ``` ### Parameters * **mq** (*struct mqtt_message_queue **) - Pointer to the message queue structure. * **buf** (*void **) - Pointer to the buffer to be used for the message queue. * **bufsz** (*size_t*) - The size of the buffer. ``` -------------------------------- ### mqtt_init() Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/group__api.html Initializes an MQTT client. This function must be called before any other API function calls. It sets up buffers and a callback for handling incoming publish messages. ```APIDOC ## mqtt_init() ### Description Initializes an MQTT client. This function must be called before any other API function calls. ### Method (Implicitly POST or similar, as it initializes state) ### Endpoint N/A (Function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response `MQTT_OK` upon success, an `MQTTErrors` otherwise. #### Response Example `MQTT_OK` ``` -------------------------------- ### Simple MQTT Publisher in C Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/simple_publisher_8c-example.html This C program connects to an MQTT broker and publishes the current time to a specified topic whenever the ENTER key is pressed. It allows customization of the broker address, port, and topic via command-line arguments. ```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; } ``` -------------------------------- ### Query Object Model with GET /rr_model Source: https://github.com/duet3d/reprapfirmware/wiki/HTTP-requests Retrieve object model information using the GET /rr_model endpoint. This is useful for querying specific data points within the RepRapFirmware's object model, similar to G-code M409. Supported in RRF 3 and later. ```json { "key": , "flags": , "result": } ``` -------------------------------- ### GET /rr_filelist Source: https://github.com/duet3d/reprapfirmware/wiki/HTTP-requests Retrieves a list of files and directories from a specified directory. Supports pagination. ```APIDOC ## GET /rr_filelist ### Description Retrieve a (partial) file list. ### Method GET ### Endpoint /rr_filelist ### Parameters #### Query Parameters - **dir** (string) - Required - Directory to query - **first** (integer) - Optional - First item index to return. Defaults to `0` - **max** (integer) - Optional - Maximum number of items to return. Defaults to `-1` ### Response #### Success Response (200) - **dir** (string) - The queried directory - **first** (integer) - The starting index of the returned items - **files** (array) - An array of file objects - **type** (string) - Type of the file item (`d` for directories, `f` for files) - **name** (string) - Name of the file or directory - **size** (integer) - Size of the file (0 for directories) - **date** (string) - Datetime of the last file modification (may be missing) - **next** (integer) - Index for the next block of items, `0` if no further items - **err** (integer) - `0` on success #### Error Response - **err** (integer) - `1`: Drive is not mounted, `2`: Directory does not exist ``` -------------------------------- ### Build MQTT-C Library Source: https://github.com/duet3d/reprapfirmware/blob/3.6-dev/src/Networking/MQTT/MQTT_C/docs/index.html Build the core MQTT-C source files and include the header file in your project. ```c #include /* Declares all the MQTT-C functions and datastructures. */ ``` -------------------------------- ### GET /rr_delete Source: https://github.com/duet3d/reprapfirmware/wiki/HTTP-requests Deletes a file or directory from the RepRapFirmware. Supports recursive deletion of directories. ```APIDOC ## GET /rr_delete ### Description Delete a file or directory. ### Method GET ### Endpoint /rr_delete ### Parameters #### Query Parameters - **name** (string) - Required - Filename to delete - **recursive** (string) - Optional - Set this to `yes` to delete the directory recursively if applicable. Defaults to `no`. ### Response #### Success Response (200) - **err** (integer) - `0` on success #### Error Response - **err** (integer) - `1` on error ```