### 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":