/** * @file * A simple program to that publishes the current time whenever ENTER is pressed. */ #include #include #include #include #include "templates/bio_sockets.h" /** * @brief The function that would be called whenever a PUBLISH is received. * * @note This function is not used in this example. */ void publish_callback(void** unused, struct mqtt_response_publish *published); /** * @brief The client's refresher. This function triggers back-end routines to * handle ingress/egress traffic to the broker. * * @note All this function needs to do is call \ref __mqtt_recv and * \ref __mqtt_send every so often. I've picked 100 ms meaning that * client ingress/egress traffic will be handled every 100 ms. */ void client_refresher(void* client); /** * @brief Safelty closes the \p sockfd and cancels the \p client_daemon before \c exit. */ void exit_example(int status, BIO* sockfd); /** * A simple program to that publishes the current time whenever ENTER is pressed. */ 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); } /* 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); } /* start a thread to refresh the client (handle egress and ingree client traffic) */ if(_beginthread(client_refresher, 0, &client) == -1) { fprintf(stderr, "Failed to start client daemon.\n"); exit_example(EXIT_FAILURE, sockfd); } /* 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, "\nerror: %s\n", mqtt_error_str(client.error)); exit_example(EXIT_FAILURE, sockfd); } } /* disconnect */ printf("\n%s disconnecting from %s\n", argv[0], addr); Sleep(1000); /* exit */ exit_example(EXIT_SUCCESS, sockfd); } void exit_example(int status, BIO* sockfd) { if (sockfd != NULL) BIO_free_all(sockfd); 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); Sleep(100); } }