630 lines
17 KiB
C
Executable File
630 lines
17 KiB
C
Executable File
/*
|
|
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#if PRJCONF_NET_EN
|
|
|
|
#include "cmd_util.h"
|
|
#include "net/mqtt/MQTTClient-C/MQTTClient.h"
|
|
|
|
#define MQTT_BUF_SIZE (1024)
|
|
|
|
typedef enum {
|
|
MQTT_CMD_CONNECT,
|
|
MQTT_CMD_DISCONNECT,
|
|
MQTT_CMD_SUBSCRIBE,
|
|
MQTT_CMD_UNSUBSCRIBE,
|
|
MQTT_CMD_PUBLISH,
|
|
MQTT_CMD_EXIT
|
|
} MQTT_CMD;
|
|
|
|
struct mqtt_msg {
|
|
MQTT_CMD type;
|
|
void *data;
|
|
int data_len;
|
|
};
|
|
|
|
struct publish_info {
|
|
int qos;
|
|
int retain;
|
|
char topic[128];
|
|
char message[128];
|
|
};
|
|
|
|
struct subscribe_info {
|
|
int qos;
|
|
char topic[128];
|
|
};
|
|
|
|
struct unsubscribe_info {
|
|
char topic[128];
|
|
};
|
|
|
|
struct cmd_mqtt_common {
|
|
int ssl;
|
|
int alive;
|
|
int clean;
|
|
int will_qos;
|
|
int will_retain;
|
|
char *will_topic;
|
|
char *will_message;
|
|
char *username;
|
|
char *password;
|
|
char port[8];
|
|
char host[128];
|
|
char client_id[128];
|
|
char *sub_topic[MAX_MESSAGE_HANDLERS];
|
|
OS_Thread_t thread;
|
|
OS_Queue_t queue;
|
|
};
|
|
|
|
static struct cmd_mqtt_common cmd_mqtt;
|
|
|
|
static void mqtt_msg_cb(MessageData *data)
|
|
{
|
|
CMD_DBG("[topic: %.*s] %.*s\n", data->topicName->lenstring.len,
|
|
data->topicName->lenstring.data, data->message->payloadlen,
|
|
(char *)data->message->payload);
|
|
}
|
|
|
|
static int mqtt_cmd_connect_handler(Client *client, Network *network,
|
|
void *data, int data_len)
|
|
{
|
|
int ret;
|
|
unsigned char *send_buf = NULL;
|
|
unsigned char *recv_buf = NULL;
|
|
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
|
|
|
|
send_buf = cmd_malloc(MQTT_BUF_SIZE);
|
|
if (send_buf == NULL) {
|
|
CMD_ERR("malloc fail.\n");
|
|
return -1;
|
|
}
|
|
recv_buf = cmd_malloc(MQTT_BUF_SIZE);
|
|
if (recv_buf == NULL) {
|
|
CMD_ERR("malloc fail.\n");
|
|
goto err;
|
|
}
|
|
|
|
NewNetwork(network);
|
|
MQTTClient(client, network, 6000, send_buf, MQTT_BUF_SIZE, recv_buf,
|
|
MQTT_BUF_SIZE);
|
|
|
|
if (cmd_mqtt.ssl) {
|
|
/* this test has no ca cert, no client cert, no client pk, no client pwd */
|
|
ret = TLSConnectNetwork(network, cmd_mqtt.host, cmd_mqtt.port, NULL, 0,
|
|
NULL, 0, NULL, 0, NULL, 0);
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from network ssl connect is -0x%04x\n", -ret);
|
|
goto err;
|
|
}
|
|
} else {
|
|
ret = ConnectNetwork(network, cmd_mqtt.host, atoi(cmd_mqtt.port));
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from network connect is %d\n", ret);
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
connectData.clientID.cstring = cmd_mqtt.client_id;
|
|
connectData.keepAliveInterval = cmd_mqtt.alive;
|
|
connectData.cleansession = cmd_mqtt.clean;
|
|
connectData.MQTTVersion = 4; //Version of MQTT 3.1.1
|
|
|
|
if (cmd_mqtt.will_topic && cmd_mqtt.will_message) {
|
|
connectData.willFlag = 1;
|
|
connectData.will.topicName.cstring = cmd_mqtt.will_topic;
|
|
connectData.will.message.cstring = cmd_mqtt.will_message;
|
|
connectData.will.retained = cmd_mqtt.will_retain;
|
|
connectData.will.qos = cmd_mqtt.will_qos;
|
|
}
|
|
if (cmd_mqtt.username) {
|
|
connectData.username.cstring = cmd_mqtt.username;
|
|
}
|
|
if (cmd_mqtt.password) {
|
|
connectData.password.cstring = cmd_mqtt.password;
|
|
}
|
|
ret = MQTTConnect(client, &connectData);
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from MQTT connect is %d\n", ret);
|
|
network->disconnect(network);
|
|
goto err;
|
|
}
|
|
|
|
CMD_DBG("MQTT connect success.\n");
|
|
return 0;
|
|
|
|
err:
|
|
cmd_free(send_buf);
|
|
cmd_free(recv_buf);
|
|
return -1;
|
|
}
|
|
|
|
static int mqtt_cmd_disconnect_handler(Client *client, Network *network,
|
|
void *data, int data_len)
|
|
{
|
|
int i;
|
|
int ret;
|
|
|
|
ret = MQTTDisconnect(client);
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from MQTT disconnect is %d\n", ret);
|
|
network->disconnect(network);
|
|
return -1;
|
|
}
|
|
network->disconnect(network);
|
|
cmd_free(client->buf);
|
|
cmd_free(client->readbuf);
|
|
for (i = 0; i < MAX_MESSAGE_HANDLERS; i++) {
|
|
cmd_free(cmd_mqtt.sub_topic[i]);
|
|
cmd_mqtt.sub_topic[i] = NULL;
|
|
}
|
|
CMD_DBG("MQTT disconnect success.\n");
|
|
return 0;
|
|
}
|
|
|
|
static int mqtt_cmd_subscribe_handler(Client *client, Network *network,
|
|
void *data, int data_len)
|
|
{
|
|
int i;
|
|
int ret;
|
|
int topic_len;
|
|
struct subscribe_info *info = data;
|
|
|
|
topic_len = cmd_strlen(info->topic) + 1;
|
|
for (i = 0; i < MAX_MESSAGE_HANDLERS; i++) {
|
|
if (cmd_mqtt.sub_topic[i] == NULL) {
|
|
cmd_mqtt.sub_topic[i] = malloc(topic_len);
|
|
if (cmd_mqtt.sub_topic[i] == NULL) {
|
|
return -1;
|
|
}
|
|
cmd_memcpy(cmd_mqtt.sub_topic[i], info->topic, topic_len);
|
|
break;
|
|
}
|
|
}
|
|
if (i >= MAX_MESSAGE_HANDLERS) {
|
|
CMD_ERR("Subscribe topic limit %d\n", MAX_MESSAGE_HANDLERS);
|
|
return -1;
|
|
}
|
|
|
|
ret = MQTTSubscribe(client, cmd_mqtt.sub_topic[i], info->qos, mqtt_msg_cb);
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from MQTT subscribe is %d\n", ret);
|
|
cmd_free(cmd_mqtt.sub_topic[i]);
|
|
cmd_mqtt.sub_topic[i] = NULL;
|
|
return -1;
|
|
}
|
|
CMD_DBG("MQTT subscribe success.\n");
|
|
return 0;
|
|
}
|
|
|
|
static int mqtt_cmd_unsubscribe_handler(Client *client, Network *network,
|
|
void *data, int data_len)
|
|
{
|
|
int i;
|
|
int ret;
|
|
struct unsubscribe_info *info = data;
|
|
|
|
ret = MQTTUnsubscribe(client, info->topic);
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from MQTT unsubscribe is %d\n", ret);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < MAX_MESSAGE_HANDLERS; i++) {
|
|
if (cmd_mqtt.sub_topic[i] != NULL &&
|
|
!cmd_strncmp(cmd_mqtt.sub_topic[i], info->topic, cmd_strlen(info->topic))) {
|
|
cmd_free(cmd_mqtt.sub_topic[i]);
|
|
cmd_mqtt.sub_topic[i] = NULL;
|
|
}
|
|
}
|
|
if (i >= MAX_MESSAGE_HANDLERS) {
|
|
CMD_ERR("MQTT unsubscribe fail.No such topic\n");
|
|
return -1;
|
|
}
|
|
CMD_DBG("MQTT unsubscribe success.\n");
|
|
return 0;
|
|
}
|
|
|
|
static int mqtt_cmd_publish_handler(Client *client, Network *network,
|
|
void *data, int data_len)
|
|
{
|
|
int ret;
|
|
MQTTMessage message;
|
|
struct publish_info *info = data;
|
|
|
|
message.qos = info->qos;
|
|
message.retained = info->retain;
|
|
message.payload = info->message;
|
|
message.payloadlen = cmd_strlen(info->message);
|
|
|
|
ret = MQTTPublish(client, info->topic, &message);
|
|
if (ret != 0) {
|
|
CMD_ERR("Return code from MQTT publish is %d\n", ret);
|
|
return -1;
|
|
}
|
|
|
|
CMD_DBG("MQTT publish success.\n");
|
|
return 0;
|
|
}
|
|
|
|
static void mqtt_client_task(void *arg)
|
|
{
|
|
int exit = 0;
|
|
int connected = 0;
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
Client client;
|
|
Network network;
|
|
|
|
while (!exit) {
|
|
status = OS_MsgQueueReceive(&cmd_mqtt.queue, (void **)&msg, 0);
|
|
if (status != OS_OK) {
|
|
if (connected) {
|
|
MQTTYield(&client, 3000);
|
|
}
|
|
OS_MSleep(50);
|
|
continue;
|
|
}
|
|
|
|
CMD_DBG("msg type:%d\n", msg->type);
|
|
switch (msg->type) {
|
|
case MQTT_CMD_CONNECT:
|
|
cmd_memset(&client, 0, sizeof(Client));
|
|
cmd_memset(&network, 0, sizeof(Network));
|
|
mqtt_cmd_connect_handler(&client, &network, msg->data,
|
|
msg->data_len);
|
|
connected = 1;
|
|
break;
|
|
case MQTT_CMD_DISCONNECT:
|
|
mqtt_cmd_disconnect_handler(&client, &network, msg->data,
|
|
msg->data_len);
|
|
connected = 0;
|
|
break;
|
|
case MQTT_CMD_SUBSCRIBE:
|
|
mqtt_cmd_subscribe_handler(&client, &network, msg->data,
|
|
msg->data_len);
|
|
break;
|
|
case MQTT_CMD_UNSUBSCRIBE:
|
|
mqtt_cmd_unsubscribe_handler(&client, &network, msg->data,
|
|
msg->data_len);
|
|
break;
|
|
case MQTT_CMD_PUBLISH:
|
|
mqtt_cmd_publish_handler(&client, &network, msg->data,
|
|
msg->data_len);
|
|
break;
|
|
case MQTT_CMD_EXIT:
|
|
exit = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
cmd_free(msg->data);
|
|
cmd_free(msg);
|
|
}
|
|
OS_ThreadDelete(&cmd_mqtt.thread);
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_init_exec(char *cmd)
|
|
{
|
|
if (OS_MsgQueueCreate(&cmd_mqtt.queue, 4) != OS_OK) {
|
|
CMD_ERR("create queue failed\n");
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
if (OS_ThreadCreate(&cmd_mqtt.thread,
|
|
"mqtt client",
|
|
mqtt_client_task,
|
|
NULL,
|
|
OS_THREAD_PRIO_APP,
|
|
(6 * 1024)) != OS_OK) {
|
|
CMD_ERR("create thread failed\n");
|
|
OS_MsgQueueDelete(&cmd_mqtt.queue);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_config_exec(char *cmd)
|
|
{
|
|
int i;
|
|
int len;
|
|
int argc;
|
|
char *argv[20];
|
|
|
|
argc = cmd_parse_argv(cmd, argv, cmd_nitems(argv));
|
|
for (i = 0; i < argc; i++) {
|
|
if (cmd_strstr(argv[i], "host=")) {
|
|
cmd_strlcpy(cmd_mqtt.host, argv[i] + 5, sizeof(cmd_mqtt.host));
|
|
} else if (cmd_strstr(argv[i], "port=")) {
|
|
cmd_strlcpy(cmd_mqtt.port, argv[i] + 5, sizeof(cmd_mqtt.port));
|
|
} else if (cmd_strstr(argv[i], "client_id=")) {
|
|
cmd_strlcpy(cmd_mqtt.client_id, argv[i] + 10,
|
|
sizeof(cmd_mqtt.client_id));
|
|
} else if (cmd_strstr(argv[i], "username=")) {
|
|
len = cmd_strlen(argv[i]);
|
|
cmd_mqtt.username = cmd_malloc(len);
|
|
cmd_strlcpy(cmd_mqtt.username, argv[i] + 9, len);
|
|
} else if (cmd_strstr(argv[i], "password=")) {
|
|
len = cmd_strlen(argv[i]);
|
|
cmd_mqtt.password = cmd_malloc(len);
|
|
cmd_strlcpy(cmd_mqtt.password, argv[i] + 9, len);
|
|
} else if (cmd_strstr(argv[i], "alive=")) {
|
|
cmd_sscanf(argv[i], "alive=%d", &cmd_mqtt.alive);
|
|
} else if (cmd_strstr(argv[i], "ssl=")) {
|
|
cmd_sscanf(argv[i], "ssl=%d", &cmd_mqtt.ssl);
|
|
} else if (cmd_strstr(argv[i], "clean=")) {
|
|
cmd_sscanf(argv[i], "clean=%d", &cmd_mqtt.clean);
|
|
} else if (cmd_strstr(argv[i], "will_topic=")) {
|
|
len = cmd_strlen(argv[i]);
|
|
cmd_mqtt.will_topic = cmd_malloc(len);
|
|
cmd_strlcpy(cmd_mqtt.will_topic, argv[i] + 11, len);
|
|
} else if (cmd_strstr(argv[i], "will_message=")) {
|
|
len = cmd_strlen(argv[i]);
|
|
cmd_mqtt.will_message = cmd_malloc(len);
|
|
cmd_strlcpy(cmd_mqtt.will_message, argv[i] + 13, len);
|
|
} else if (cmd_strstr(argv[i], "will_qos=")) {
|
|
cmd_sscanf(argv[i], "will_qos=%d", &cmd_mqtt.will_qos);
|
|
} else if (cmd_strstr(argv[i], "will_retain=")) {
|
|
cmd_sscanf(argv[i], "will_retain=%d", &cmd_mqtt.will_retain);
|
|
} else {
|
|
CMD_ERR("invalid param:%s\n", argv[i]);
|
|
}
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_connect_exec(char *cmd)
|
|
{
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
|
|
msg = cmd_malloc(sizeof(struct mqtt_msg));
|
|
if (msg == NULL) {
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(msg, 0, sizeof(struct mqtt_msg));
|
|
msg->type = MQTT_CMD_CONNECT;
|
|
msg->data = NULL;
|
|
msg->data_len = 0;
|
|
|
|
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
|
|
if (status != OS_OK) {
|
|
cmd_free(msg);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_disconnect_exec(char *cmd)
|
|
{
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
|
|
msg = cmd_malloc(sizeof(struct mqtt_msg));
|
|
if (msg == NULL) {
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(msg, 0, sizeof(struct mqtt_msg));
|
|
msg->type = MQTT_CMD_DISCONNECT;
|
|
msg->data = NULL;
|
|
msg->data_len = 0;
|
|
|
|
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
|
|
if (status != OS_OK) {
|
|
cmd_free(msg);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_subscribe_exec(char *cmd)
|
|
{
|
|
int cnt;
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
struct subscribe_info *info;
|
|
|
|
info = cmd_malloc(sizeof(struct subscribe_info));
|
|
if (info == NULL) {
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(info, 0, sizeof(struct subscribe_info));
|
|
cnt = cmd_sscanf(cmd, "qos=%u topic=%128s", &info->qos, info->topic);
|
|
if (cnt != 2) {
|
|
CMD_ERR("invalid param number %d\n", cnt);
|
|
cmd_free(info);
|
|
return CMD_STATUS_INVALID_ARG;
|
|
}
|
|
|
|
msg = cmd_malloc(sizeof(struct mqtt_msg));
|
|
if (msg == NULL) {
|
|
cmd_free(info);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(msg, 0, sizeof(struct mqtt_msg));
|
|
msg->type = MQTT_CMD_SUBSCRIBE;
|
|
msg->data = info;
|
|
msg->data_len = sizeof(struct subscribe_info);
|
|
|
|
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
|
|
if (status != OS_OK) {
|
|
cmd_free(info);
|
|
cmd_free(msg);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_unsubscribe_exec(char *cmd)
|
|
{
|
|
int cnt;
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
struct unsubscribe_info *info;
|
|
|
|
info = cmd_malloc(sizeof(struct unsubscribe_info));
|
|
if (info == NULL) {
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(info, 0, sizeof(struct unsubscribe_info));
|
|
cnt = cmd_sscanf(cmd, "topic=%128s", info->topic);
|
|
if (cnt != 1) {
|
|
CMD_ERR("invalid param number %d\n", cnt);
|
|
cmd_free(info);
|
|
return CMD_STATUS_INVALID_ARG;
|
|
}
|
|
|
|
msg = cmd_malloc(sizeof(struct mqtt_msg));
|
|
if (msg == NULL) {
|
|
cmd_free(info);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(msg, 0, sizeof(struct mqtt_msg));
|
|
msg->type = MQTT_CMD_UNSUBSCRIBE;
|
|
msg->data = info;
|
|
msg->data_len = sizeof(struct unsubscribe_info);
|
|
|
|
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
|
|
if (status != OS_OK) {
|
|
cmd_free(info);
|
|
cmd_free(msg);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_publish_exec(char *cmd)
|
|
{
|
|
int cnt;
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
struct publish_info *info;
|
|
|
|
info = cmd_malloc(sizeof(struct publish_info));
|
|
if (info == NULL) {
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(info, 0, sizeof(struct publish_info));
|
|
cnt = cmd_sscanf(cmd, "qos=%d retain=%d topic=%128s message=%128s",
|
|
&info->qos, &info->retain, info->topic, info->message);
|
|
if (cnt != 4) {
|
|
CMD_ERR("invalid param number %d\n", cnt);
|
|
cmd_free(info);
|
|
return CMD_STATUS_INVALID_ARG;
|
|
}
|
|
|
|
msg = cmd_malloc(sizeof(struct mqtt_msg));
|
|
if (msg == NULL) {
|
|
cmd_free(info);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(msg, 0, sizeof(struct mqtt_msg));
|
|
msg->type = MQTT_CMD_PUBLISH;
|
|
msg->data = info;
|
|
msg->data_len = sizeof(struct publish_info);
|
|
|
|
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
|
|
if (status != OS_OK) {
|
|
cmd_free(info);
|
|
cmd_free(msg);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_mqtt_deinit_exec(char *cmd)
|
|
{
|
|
OS_Status status;
|
|
struct mqtt_msg *msg;
|
|
|
|
msg = cmd_malloc(sizeof(struct mqtt_msg));
|
|
if (msg == NULL) {
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
cmd_memset(msg, 0, sizeof(struct mqtt_msg));
|
|
msg->type = MQTT_CMD_EXIT;
|
|
msg->data = NULL;
|
|
msg->data_len = 0;
|
|
|
|
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
|
|
if (status != OS_OK) {
|
|
cmd_free(msg);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
while (OS_ThreadIsValid(&cmd_mqtt.thread)) {
|
|
OS_MSleep(10);
|
|
}
|
|
OS_MsgQueueDelete(&cmd_mqtt.queue);
|
|
cmd_free(cmd_mqtt.will_topic);
|
|
cmd_free(cmd_mqtt.will_message);
|
|
cmd_free(cmd_mqtt.username);
|
|
cmd_free(cmd_mqtt.password);
|
|
cmd_memset(&cmd_mqtt, 0, sizeof(struct cmd_mqtt_common));
|
|
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
#if CMD_DESCRIBE
|
|
#define mqtt_init_help_info "init"
|
|
#define mqtt_config_help_info "config <field>=<value>..."
|
|
#define mqtt_connect_help_info "connect to server"
|
|
#define mqtt_subscribe_help_info "subscribe qos=<qos> topic=<topic>"
|
|
#define mqtt_unsubscribe_help_info "unsubscribe topic=<topic>"
|
|
#define mqtt_publish_help_info "publish qos=<qos> retain=<retain> topic=<topic> message=<message>"
|
|
#define mqtt_disconnect_help_info "disconnect from server"
|
|
#define mqtt_deinit_help_info "deinit"
|
|
#endif
|
|
|
|
enum cmd_status cmd_mqtt_help_exec(char *cmd);
|
|
|
|
static const struct cmd_data g_mqtt_cmds[] = {
|
|
{ "init", cmd_mqtt_init_exec, CMD_DESC(mqtt_init_help_info) },
|
|
{ "config", cmd_mqtt_config_exec, CMD_DESC(mqtt_config_help_info) },
|
|
{ "connect", cmd_mqtt_connect_exec, CMD_DESC(mqtt_connect_help_info) },
|
|
{ "subscribe", cmd_mqtt_subscribe_exec, CMD_DESC(mqtt_subscribe_help_info) },
|
|
{ "unsubscribe", cmd_mqtt_unsubscribe_exec, CMD_DESC(mqtt_unsubscribe_help_info) },
|
|
{ "publish", cmd_mqtt_publish_exec, CMD_DESC(mqtt_publish_help_info) },
|
|
{ "disconnect", cmd_mqtt_disconnect_exec, CMD_DESC(mqtt_disconnect_help_info) },
|
|
{ "deinit", cmd_mqtt_deinit_exec, CMD_DESC(mqtt_deinit_help_info) },
|
|
{ "help", cmd_mqtt_help_exec, CMD_DESC(CMD_HELP_DESC) },
|
|
};
|
|
|
|
enum cmd_status cmd_mqtt_help_exec(char *cmd)
|
|
{
|
|
return cmd_help_exec(g_mqtt_cmds, cmd_nitems(g_mqtt_cmds), 16);
|
|
}
|
|
|
|
enum cmd_status cmd_mqtt_exec(char *cmd)
|
|
{
|
|
return cmd_exec(cmd, g_mqtt_cmds, cmd_nitems(g_mqtt_cmds));
|
|
}
|
|
|
|
#endif /* PRJCONF_NET_EN */
|