|
|
@@ -0,0 +1,252 @@
|
|
|
+/**
|
|
|
+ * Copyright (C) 2013 Guangzhou Tronlong Electronic Technology Co., Ltd. - www.tronlong.com
|
|
|
+ *
|
|
|
+ * @file mqtt_client.c
|
|
|
+ *
|
|
|
+ * @brief Example application main file.
|
|
|
+ * This application publish or subscribe message use the MQTT protocol
|
|
|
+ *
|
|
|
+ * @author Tronlong <support@tronlong.com>
|
|
|
+ *
|
|
|
+ * @version V1.0
|
|
|
+ *
|
|
|
+ * @date 2022-2-15
|
|
|
+ **/
|
|
|
+
|
|
|
+#include "mqtt_client.h"
|
|
|
+
|
|
|
+static const int keepalive = 600;
|
|
|
+static int is_connect = false;
|
|
|
+
|
|
|
+/* Exit flag */
|
|
|
+volatile bool g_quit = false;
|
|
|
+
|
|
|
+struct mosquitto *mosq = NULL;
|
|
|
+
|
|
|
+static void usage(char **argv)
|
|
|
+{
|
|
|
+ fprintf(stdout,
|
|
|
+ "Usage: %s [options]\n\n"
|
|
|
+ "Options:\n"
|
|
|
+ " -h | --host The hostname or ip address of the broker to connect to.\n"
|
|
|
+ " -p | --port The network port to connect to. Usually 1883.\n"
|
|
|
+ " -t | --topic MQTT topic to publish to.\n"
|
|
|
+ " -m | --message Message payload to send.\n"
|
|
|
+ " -M | --mode MQTT mode [publish|subscribe]\n"
|
|
|
+ " -q | --quality quality of service level to use for all messages. Defaults to 0. value: [0, 1, 2]\n"
|
|
|
+ " -v | --version Display version information\n"
|
|
|
+ " --help Show help content\n\n"
|
|
|
+ "Example:\n"
|
|
|
+ " # ./%s -h 192.168.0.115 -p 1883 -t test -m 'www.tronlong.com'\n"
|
|
|
+ "", basename(argv[0]),
|
|
|
+ basename(argv[0]));
|
|
|
+}
|
|
|
+
|
|
|
+static bool parse_parameter(struct _Params *params, int argc, char **argv)
|
|
|
+{
|
|
|
+ int opt;
|
|
|
+
|
|
|
+ /* Set default value */
|
|
|
+ params->port = 0;
|
|
|
+ params->quality = 0;
|
|
|
+ params->mode = MQTT_INVALID;
|
|
|
+ memset(params->topic, 0, sizeof(params->topic));
|
|
|
+ memset(params->message, 0, sizeof(params->message));
|
|
|
+
|
|
|
+ while ((opt = getopt_long(argc, argv, g_shortopts, g_longopts, NULL)) != -1) {
|
|
|
+ switch (opt) {
|
|
|
+ case 'h':
|
|
|
+ strcpy(params->host, optarg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'p':
|
|
|
+ params->port = atoi(optarg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 't':
|
|
|
+ strcpy(params->topic, optarg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'm':
|
|
|
+ strcpy(params->message, optarg);
|
|
|
+ break;
|
|
|
+ /* mode */
|
|
|
+ case 'M':
|
|
|
+ if (strcmp(optarg, "publish") == 0) {
|
|
|
+ params->mode = MQTT_PUBLISH;
|
|
|
+ } else if (strcmp(optarg, "subscribe") == 0) {
|
|
|
+ params->mode = MQTT_SUBSCRIBE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'q':
|
|
|
+ params->quality = atoi(optarg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'v':
|
|
|
+ printf("version : %s\n", VERSION);
|
|
|
+ exit(0);
|
|
|
+ /* help */
|
|
|
+ case 0:
|
|
|
+ usage(argv);
|
|
|
+ exit(0);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ fprintf(stderr, "Unknown option %c\n", optopt);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (strlen(params->host) == 0 || params->port == 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (params->mode == MQTT_PUBLISH) {
|
|
|
+ if (strlen(params->topic) == 0 || strlen(params->message) == 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else if(params->mode == MQTT_SUBSCRIBE) {
|
|
|
+ if (strlen(params->topic) == 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void mqtt_connect_callback(struct mosquitto *mosq, void *obj, int rc)
|
|
|
+{
|
|
|
+ struct _Params *userdata = (struct _Params *)obj;
|
|
|
+
|
|
|
+ if (rc == 0) {
|
|
|
+ is_connect = true;
|
|
|
+ printf("Connect mqtt broker success (%s:%d).\n", userdata->host, userdata->port);
|
|
|
+
|
|
|
+ /* Subscribe topic */
|
|
|
+ if (userdata->mode == MQTT_SUBSCRIBE) {
|
|
|
+ mosquitto_subscribe(mosq, NULL, userdata->topic, userdata->quality);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void mqtt_disconnect_callback(struct mosquitto *mosq, void *obj, int result)
|
|
|
+{
|
|
|
+ struct _Params *userdata = (struct _Params *)obj;
|
|
|
+
|
|
|
+ if (userdata->mode == MQTT_SUBSCRIBE) {
|
|
|
+ printf("disconnect mqtt broker server\n");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void mqtt_publish_callback(struct mosquitto *mosq, void *obj, int mid)
|
|
|
+{
|
|
|
+ g_quit = true;
|
|
|
+ printf("send message success.\n");
|
|
|
+ //mosquitto_disconnect(mosq);
|
|
|
+}
|
|
|
+
|
|
|
+void mqtt_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
|
|
|
+{
|
|
|
+ printf("recv message: %s\n", (char *)message->payload);
|
|
|
+}
|
|
|
+
|
|
|
+void sig_handle(int arg)
|
|
|
+{
|
|
|
+ g_quit = true;
|
|
|
+ mosquitto_disconnect(mosq);
|
|
|
+}
|
|
|
+
|
|
|
+bool MQTT_Init( char* nclientname,char* nhost, int nport)
|
|
|
+{
|
|
|
+ int ret = -1;
|
|
|
+ int status = 0;
|
|
|
+ /* Ctrl+c handler */
|
|
|
+ signal(SIGINT, sig_handle);
|
|
|
+
|
|
|
+ /* Must be called before any other mosquitto functions. */
|
|
|
+ ret = mosquitto_lib_init();
|
|
|
+ if (ret != MOSQ_ERR_SUCCESS) {
|
|
|
+ printf("mosquitto lib init failed!\n");
|
|
|
+ exit(-1);
|
|
|
+ }
|
|
|
+
|
|
|
+ mosq = mosquitto_new(nclientname, true, nhost);
|
|
|
+ if (mosq == NULL) {
|
|
|
+ printf("Create new mosquitto client instance failed!\n");
|
|
|
+ exit(-1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set the connect callback. */
|
|
|
+ mosquitto_connect_callback_set(mosq, mqtt_connect_callback);
|
|
|
+ /* Set the disconnect callback. */
|
|
|
+ mosquitto_disconnect_callback_set(mosq, mqtt_disconnect_callback);
|
|
|
+ /* Set the publish callback. This is called when a message initiated with mosquitto_publish has been sent to the broker successfully. */
|
|
|
+ mosquitto_publish_callback_set(mosq, mqtt_publish_callback);
|
|
|
+ /* Set the message callback. This is called when a message is received from the broker. */
|
|
|
+ mosquitto_message_callback_set(mosq, mqtt_message_callback);
|
|
|
+
|
|
|
+ /* Connect to an MQTT broker. */
|
|
|
+ ret = mosquitto_connect(mosq, nhost, nport, keepalive);
|
|
|
+ if (ret != MOSQ_ERR_SUCCESS) {
|
|
|
+ printf("mosquitto connect failed!\n");
|
|
|
+ status = -1;
|
|
|
+ mosquitto_destroy(mosq);
|
|
|
+ mosquitto_lib_cleanup();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void MQTT_Release()
|
|
|
+{
|
|
|
+ if (mosq!=NULL)
|
|
|
+ {
|
|
|
+ mosquitto_disconnect(mosq);
|
|
|
+ mosquitto_destroy(mosq);
|
|
|
+ mosquitto_lib_cleanup();
|
|
|
+ printf("mosquitto Released!\n");
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ printf("mosquitto is Null!\n");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool MQTT_Publish( struct _Params nParam)
|
|
|
+{
|
|
|
+ int ret = -1;
|
|
|
+ bool PubFlag=false;
|
|
|
+
|
|
|
+ if (nParam.mode == MQTT_PUBLISH) {
|
|
|
+
|
|
|
+ ret = mosquitto_publish(mosq, NULL, nParam.topic, strlen(nParam.message), nParam.message, 0, false);
|
|
|
+ if (ret) {
|
|
|
+ printf("Error: Publish returned %d, disconnecting.\n", ret);
|
|
|
+ }
|
|
|
+ else PubFlag=true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return PubFlag;
|
|
|
+}
|
|
|
+bool MQTT_Subscribe( struct _Params nParam)
|
|
|
+{
|
|
|
+ int ret = -1;
|
|
|
+ bool SubFlag=false;
|
|
|
+
|
|
|
+ if (nParam.mode == MQTT_SUBSCRIBE) {
|
|
|
+ /* subscribe */
|
|
|
+ //mosquitto_loop_forever(mosq, -1, 1);
|
|
|
+ ret = mosquitto_subscribe(mosq, NULL, nParam.topic, 0);
|
|
|
+ if (ret) {
|
|
|
+ printf("Error: Subscribe returned %d, disconnecting.\n", ret);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ mosquitto_loop_forever(mosq, -1, 1);
|
|
|
+ SubFlag=true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return SubFlag;
|
|
|
+}
|