From 8cc1f7ec980a63a4716da6a2c61a42da3b1edf49 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Fri, 2 Oct 2020 18:28:16 +0200 Subject: [PATCH 1/2] msvc: Copy bio_publisher and openssl_publisher (unmodified) --- CMakeLists.txt | 11 +- examples/bio_publisher_win.c | 156 +++++++++++++++++++++++++++++ examples/openssl_publisher_win.c | 167 +++++++++++++++++++++++++++++++ 3 files changed, 331 insertions(+), 3 deletions(-) create mode 100644 examples/bio_publisher_win.c create mode 100644 examples/openssl_publisher_win.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 43798d9..601d484 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,10 +65,15 @@ if(MQTT_C_EXAMPLES) find_package(Threads REQUIRED) if(MQTT_C_OpenSSL_SUPPORT) - add_executable(bio_publisher examples/bio_publisher.c) - target_link_libraries(bio_publisher Threads::Threads mqttc) + 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() - add_executable(openssl_publisher examples/openssl_publisher.c) + 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) diff --git a/examples/bio_publisher_win.c b/examples/bio_publisher_win.c new file mode 100644 index 0000000..8c92b54 --- /dev/null +++ b/examples/bio_publisher_win.c @@ -0,0 +1,156 @@ + +/** + * @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, pthread_t *client_daemon); + +/** + * 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, 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; +} \ No newline at end of file diff --git a/examples/openssl_publisher_win.c b/examples/openssl_publisher_win.c new file mode 100644 index 0000000..a09fbbe --- /dev/null +++ b/examples/openssl_publisher_win.c @@ -0,0 +1,167 @@ + +/** + * @file + */ +#include +#include +#include + +#include +#include "templates/openssl_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, pthread_t *client_daemon); + +/** + * 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; + 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; +} \ No newline at end of file From bd6a61e17c5bb5aa2f959aa1433dfeef1a8a179a Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Fri, 2 Oct 2020 21:24:38 +0200 Subject: [PATCH 2/2] msvc/examples: Update bio_publisher/ openssl_publisher for windows --- examples/bio_publisher_win.c | 33 +++++++++++++++----------------- examples/openssl_publisher_win.c | 29 +++++++++++++--------------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/examples/bio_publisher_win.c b/examples/bio_publisher_win.c index 8c92b54..cf13bc9 100644 --- a/examples/bio_publisher_win.c +++ b/examples/bio_publisher_win.c @@ -3,7 +3,7 @@ * @file * A simple program to that publishes the current time whenever ENTER is pressed. */ -#include +#include #include #include @@ -26,12 +26,12 @@ void publish_callback(void** unused, struct mqtt_response_publish *published); * \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); +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, pthread_t *client_daemon); +void exit_example(int status, BIO* sockfd); /** * A simple program to that publishes the current time whenever ENTER is pressed. @@ -72,7 +72,7 @@ int main(int argc, const char *argv[]) BIO* sockfd = open_nb_socket(addr, port); if (sockfd == NULL) { - exit_example(EXIT_FAILURE, sockfd, NULL); + exit_example(EXIT_FAILURE, sockfd); } /* setup a client */ @@ -85,14 +85,13 @@ int main(int argc, const char *argv[]) /* 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); + exit_example(EXIT_FAILURE, sockfd); } /* 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)) { + if(_beginthread(client_refresher, 0, &client) == -1) { fprintf(stderr, "Failed to start client daemon.\n"); - exit_example(EXIT_FAILURE, sockfd, NULL); + exit_example(EXIT_FAILURE, sockfd); } @@ -118,23 +117,22 @@ int main(int argc, const char *argv[]) /* 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); + 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(1); + Sleep(1000); /* exit */ - exit_example(EXIT_SUCCESS, sockfd, &client_daemon); + exit_example(EXIT_SUCCESS, sockfd); } -void exit_example(int status, BIO* sockfd, pthread_t *client_daemon) +void exit_example(int status, BIO* sockfd) { if (sockfd != NULL) BIO_free_all(sockfd); - if (client_daemon != NULL) pthread_cancel(*client_daemon); exit(status); } @@ -145,12 +143,11 @@ void publish_callback(void** unused, struct mqtt_response_publish *published) /* not used in this example */ } -void* client_refresher(void* client) +void client_refresher(void* client) { - while(1) + while(1) { mqtt_sync((struct mqtt_client*) client); - usleep(100000U); + Sleep(100); } - return NULL; } \ No newline at end of file diff --git a/examples/openssl_publisher_win.c b/examples/openssl_publisher_win.c index a09fbbe..28b3a1f 100644 --- a/examples/openssl_publisher_win.c +++ b/examples/openssl_publisher_win.c @@ -2,7 +2,7 @@ /** * @file */ -#include +#include #include #include @@ -25,12 +25,12 @@ void publish_callback(void** unused, struct mqtt_response_publish *published); * \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); +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, pthread_t *client_daemon); +void exit_example(int status, BIO* sockfd); /** * A simple program to that publishes the current time whenever ENTER is pressed. @@ -83,7 +83,7 @@ int main(int argc, const char *argv[]) open_nb_socket(&sockfd, &ssl_ctx, addr, port, ca_file, NULL); if (sockfd == NULL) { - exit_example(EXIT_FAILURE, sockfd, NULL); + exit_example(EXIT_FAILURE, sockfd); } /* setup a client */ @@ -96,14 +96,13 @@ int main(int argc, const char *argv[]) /* 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); + exit_example(EXIT_FAILURE, sockfd); } /* 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)) { + if(_beginthread(client_refresher, 0, &client) == -1) { fprintf(stderr, "Failed to start client daemon.\n"); - exit_example(EXIT_FAILURE, sockfd, NULL); + exit_example(EXIT_FAILURE, sockfd); } @@ -130,22 +129,21 @@ int main(int argc, const char *argv[]) /* 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); + exit_example(EXIT_FAILURE, sockfd); } } /* disconnect */ printf("\n%s disconnecting from %s\n", argv[0], addr); - sleep(1); + Sleep(1000); /* exit */ - exit_example(EXIT_SUCCESS, sockfd, &client_daemon); + exit_example(EXIT_SUCCESS, sockfd); } -void exit_example(int status, BIO* sockfd, pthread_t *client_daemon) +void exit_example(int status, BIO* sockfd) { if (sockfd != NULL) BIO_free_all(sockfd); - if (client_daemon != NULL) pthread_cancel(*client_daemon); exit(status); } @@ -156,12 +154,11 @@ void publish_callback(void** unused, struct mqtt_response_publish *published) /* not used in this example */ } -void* client_refresher(void* client) +void client_refresher(void* client) { while(1) { mqtt_sync((struct mqtt_client*) client); - usleep(100000U); + Sleep(100); } - return NULL; } \ No newline at end of file