sdk-hwV1.3/lichee/xr806/appos/project/example/mqtt/main.c

305 lines
8.5 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.
*/
#include <stdio.h>
#include "kernel/os/os.h"
#include "common/framework/platform_init.h"
#include "net/wlan/wlan.h"
#include "common/framework/net_ctrl.h"
#include "net/mqtt/MQTTClient-C/MQTTClient.h"
#define MQTT_DEMO_THREAD_STACK_SIZE (8 * 1024) /* ssl need more stack */
static OS_Thread_t mqtt_demo_thread;
static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer;
static Client mqtt_demo_client;
static Network mqtt_demo_network;
#define MQTT_DEMO_CLIENT_ID "12345|securemode=2,signmethod=hmacsha1,timestamp=789|"
#define MQTT_DEMO_HOST_NAME "iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define MQTT_DEMO_PORT "1883"
#define MQTT_DEMO_USERNAME "xr806_senor_set0&vo84Hm3xbUj"
#define MQTT_DEMO_PASSWORD "4f9ebb2143f01e4489133c1ea55051fbbfc4c44e"
#define MQTT_DEMO_TOPIC "/vo84Hm3xbUj/xr806_senor_set0/data"
#define MQTT_DEMO_BUF_SIZE (2*1024)
#define MQTT_DEMO_MSG_TEXT "mqtt demo test"
static int mqtt_demo_init(void)
{
char *send_buf;
char *recv_buf;
/* init client id */
mqtt_demo_connectData.clientID.cstring = MQTT_DEMO_CLIENT_ID;
/* init keep alive interval */
mqtt_demo_connectData.keepAliveInterval = 30; // 30s
/* enable session reuse */
mqtt_demo_connectData.cleansession = 0;
/* set mqtt version */
mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1
/* send/recv buffer must free when mqtt deinit */
send_buf = malloc(MQTT_DEMO_BUF_SIZE);
if (send_buf == NULL) {
printf("no memory\n");
return -1;
}
recv_buf = malloc(MQTT_DEMO_BUF_SIZE);
if (recv_buf == NULL) {
free(send_buf);
printf("no memory\n");
return -1;
}
/* init network */
NewNetwork(&mqtt_demo_network);
/* init mqtt client object */
MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000,
(unsigned char *)send_buf, MQTT_DEMO_BUF_SIZE,
(unsigned char *)recv_buf, MQTT_DEMO_BUF_SIZE);
/**
* set will function, when this client disconnect,
* server will sent the message to every client in MQTT_DEMO_TOPIC
*/
mqtt_demo_connectData.willFlag = 1;
mqtt_demo_connectData.will.topicName.cstring = MQTT_DEMO_TOPIC;
mqtt_demo_connectData.will.message.cstring = "I am disconnected";
mqtt_demo_connectData.will.retained = 0;
mqtt_demo_connectData.will.qos = 0;
/* set username and password */
mqtt_demo_connectData.username.cstring = MQTT_DEMO_USERNAME;
mqtt_demo_connectData.password.cstring = MQTT_DEMO_PASSWORD;
return 0;
}
static int mqtt_demo_connect(char *host_name, char *host_port)
{
int ret = -1;
/* need connect the server in tcp level first, if use ssl, use TLSConnectNetwork() */
ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port));
if (ret != 0) {
printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port);
goto exit;
}
/* if tcp level connected, then connect mqtt level */
ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData);
if (ret != 0) {
printf("mqtt connect faild, ret:%d\n", ret);
/* disconnect the tcp level */
mqtt_demo_network.disconnect(&mqtt_demo_network);
goto exit;
}
printf("mqtt connected\n");
exit:
return ret;
}
static void mqtt_demo_msg_cb(MessageData *data)
{
printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len,
data->topicName->lenstring.data, data->message->payloadlen,
(char *)data->message->payload);
}
static int mqtt_demo_subscribe(char *topic)
{
int ret = -1;
if (mqtt_demo_client.isconnected) {
/* set the message callback */
ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb);
if (ret != 0)
printf("mqtt subscribe faild ret:%d\n", ret);
}
return ret;
}
static int mqtt_demo_unsubscribe(char *topic)
{
int ret = -1;
if (mqtt_demo_client.isconnected) {
ret = MQTTUnsubscribe(&mqtt_demo_client, topic);
if (ret != 0)
printf("mqtt unsubscribe faild, ret:%d\n", ret);
}
return ret;
}
static int mqtt_demo_publish(char *topic, char *msg)
{
int ret = -1;
MQTTMessage message;
memset(&message, 0, sizeof(message));
message.qos = 0;
message.retained = 0; /* disable retain the message in server */
message.payload = msg;
message.payloadlen = strlen(msg);
ret = MQTTPublish(&mqtt_demo_client, topic, &message);
if (ret != 0)
printf("mqtt publish faild, ret:%d\n", ret);
return ret;
}
static int mqtt_demo_disconnect(void)
{
int ret = -1;
if (mqtt_demo_client.isconnected) {
/* need disconnect mqtt level first */
ret = MQTTDisconnect(&mqtt_demo_client);
if (ret != 0)
printf("mqtt disconnect fail, ret:%d\n", ret);
/* then disconnect tcp level */
mqtt_demo_network.disconnect(&mqtt_demo_network);
}
return ret;
}
static void mqtt_demo_deinit(void)
{
if (mqtt_demo_client.buf) {
free(mqtt_demo_client.buf);
mqtt_demo_client.buf = NULL;
}
if (mqtt_demo_client.readbuf) {
free(mqtt_demo_client.readbuf);
mqtt_demo_client.readbuf = NULL;
}
}
static void mqtt_demo_fun(void *arg)
{
int ret;
int reconnect_times = 0;
/* mqtt init */
mqtt_demo_init();
/* mqtt connect */
ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
if (ret != 0)
goto exit;
/* subscribe topic */
ret = mqtt_demo_subscribe(MQTT_DEMO_TOPIC);
if (ret != 0)
goto exit;
while (1) {
/* publish message to topic */
mqtt_demo_publish(MQTT_DEMO_TOPIC, MQTT_DEMO_MSG_TEXT);
ret = MQTTYield(&mqtt_demo_client, 300);
if (ret != 0) {
printf("mqtt yield err, ret:%d\n", ret);
reconnect:
printf("mqtt reconnect\n");
mqtt_demo_disconnect();
ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
if (ret != 0) {
reconnect_times++;
if (reconnect_times > 5)
goto exit;
OS_MSleep(5000); //5s
goto reconnect;
}
}
OS_MSleep(1000); //1s
}
exit:
mqtt_demo_unsubscribe(MQTT_DEMO_TOPIC);
mqtt_demo_disconnect();
mqtt_demo_deinit();
OS_ThreadDelete(&mqtt_demo_thread);
}
static void net_cb(uint32_t event, uint32_t data, void *arg)
{
uint16_t type = EVENT_SUBTYPE(event);
switch (type) {
case NET_CTRL_MSG_NETWORK_UP:
if (!OS_ThreadIsValid(&mqtt_demo_thread)) {
OS_ThreadCreate(&mqtt_demo_thread,
"mqtt_demo_thread",
mqtt_demo_fun,
(void *)NULL,
OS_THREAD_PRIO_APP,
MQTT_DEMO_THREAD_STACK_SIZE);
}
break;
case NET_CTRL_MSG_NETWORK_DOWN:
break;
default:
break;
}
}
int main(void)
{
observer_base *net_ob;
platform_init();
printf("mqtt demo start\n\n");
printf("use these commands to connect ap:\n\n");
printf("1. config ssid and password : net sta config ssid password\n");
printf("2. enable sta to connect ap : net sta enable\n\n");
/* create an observer to monitor the net work state */
net_ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK,
NET_CTRL_MSG_ALL,
net_cb,
NULL);
if (net_ob == NULL)
return -1;
if (sys_ctrl_attach(net_ob) != 0)
return -1;
return 0;
}