merge new qcloud sdk
1. qcloud has a great revolution, the protocol has been changed to implement data template, so the old TencentCloud_SDK developed by us will not work fine now(mqtt still works, but data template will not works fine for recently created product/devices). 2. I merge the official qlcoud sdk(include both the iot-hub and iot-explorer sdk) into the componet/conectivity to support new protocol of data template 3. iot-hub sdk, supply the fundamental iot protocol(like mqtt coap, etc.) iot-explorer sdk, supply the high level service like data template based on mqtt 4. To know how it works, see qcloud_iot_explorer_sdk_data_template、qcloud_iot_hub_sdk_mqtt example(keil project in board\TencentOS_tiny_EVB_MX_Plus\KEIL\qcloud_iot_explorer_sdk_data_template and board\TencentOS_tiny_EVB_MX_Plus\KEIL\qcloud_iot_hub_sdk_mqtt)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
#ifdef ACTION_ENABLED
|
||||
|
||||
#define TOTAL_ACTION_COUNTS (1)
|
||||
|
||||
static TYPE_DEF_TEMPLATE_INT sg_light_blink_in_time = 0;
|
||||
static TYPE_DEF_TEMPLATE_BOOL sg_light_blink_in_color = 0;
|
||||
static TYPE_DEF_TEMPLATE_INT sg_light_blink_in_total_time = 0;
|
||||
static DeviceProperty g_actionInput_light_blink[] = {
|
||||
|
||||
{.key = "time", .data = &sg_light_blink_in_time, .type = TYPE_TEMPLATE_INT},
|
||||
{.key = "color", .data = &sg_light_blink_in_color, .type = TYPE_TEMPLATE_BOOL},
|
||||
{.key = "total_time", .data = &sg_light_blink_in_total_time, .type = TYPE_TEMPLATE_INT},
|
||||
};
|
||||
static TYPE_DEF_TEMPLATE_BOOL sg_light_blink_out_err_code = 0;
|
||||
static DeviceProperty g_actionOutput_light_blink[] = {
|
||||
|
||||
{.key = "err_code", .data = &sg_light_blink_out_err_code, .type = TYPE_TEMPLATE_BOOL},
|
||||
};
|
||||
|
||||
|
||||
static DeviceAction g_actions[]={
|
||||
|
||||
{
|
||||
.pActionId = "light_blink",
|
||||
.timestamp = 0,
|
||||
.input_num = sizeof(g_actionInput_light_blink)/sizeof(g_actionInput_light_blink[0]),
|
||||
.output_num = sizeof(g_actionOutput_light_blink)/sizeof(g_actionOutput_light_blink[0]),
|
||||
.pInput = g_actionInput_light_blink,
|
||||
.pOutput = g_actionOutput_light_blink,
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
39
examples/qcloud_iot_explorer_sdk_data_template/data_config.c
Normal file
39
examples/qcloud_iot_explorer_sdk_data_template/data_config.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*-----------------data config start -------------------*/
|
||||
|
||||
#define TOTAL_PROPERTY_COUNT 4
|
||||
|
||||
static sDataPoint sg_DataTemplate[TOTAL_PROPERTY_COUNT];
|
||||
|
||||
typedef struct _ProductDataDefine {
|
||||
TYPE_DEF_TEMPLATE_BOOL m_power_switch;
|
||||
TYPE_DEF_TEMPLATE_ENUM m_color;
|
||||
TYPE_DEF_TEMPLATE_INT m_brightness;
|
||||
TYPE_DEF_TEMPLATE_STRING m_name[64+1];
|
||||
} ProductDataDefine;
|
||||
|
||||
static ProductDataDefine sg_ProductData;
|
||||
|
||||
static void _init_data_template(void)
|
||||
{
|
||||
sg_ProductData.m_power_switch = 0;
|
||||
sg_DataTemplate[0].data_property.data = &sg_ProductData.m_power_switch;
|
||||
sg_DataTemplate[0].data_property.key = "power_switch";
|
||||
sg_DataTemplate[0].data_property.type = TYPE_TEMPLATE_BOOL;
|
||||
|
||||
sg_ProductData.m_color = 0;
|
||||
sg_DataTemplate[1].data_property.data = &sg_ProductData.m_color;
|
||||
sg_DataTemplate[1].data_property.key = "color";
|
||||
sg_DataTemplate[1].data_property.type = TYPE_TEMPLATE_ENUM;
|
||||
|
||||
sg_ProductData.m_brightness = 1;
|
||||
sg_DataTemplate[2].data_property.data = &sg_ProductData.m_brightness;
|
||||
sg_DataTemplate[2].data_property.key = "brightness";
|
||||
sg_DataTemplate[2].data_property.type = TYPE_TEMPLATE_INT;
|
||||
|
||||
sg_ProductData.m_name[0] = '\0';
|
||||
sg_DataTemplate[3].data_property.data = sg_ProductData.m_name;
|
||||
sg_DataTemplate[3].data_property.data_buff_len = sizeof(sg_ProductData.m_name)/sizeof(sg_ProductData.m_name[3]);
|
||||
sg_DataTemplate[3].data_property.key = "name";
|
||||
sg_DataTemplate[3].data_property.type = TYPE_TEMPLATE_STRING;
|
||||
|
||||
};
|
@@ -0,0 +1,595 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
// #include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
#include "lite-utils.h"
|
||||
#include "data_config.c"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
static MQTTEventType sg_subscribe_event_result = MQTT_EVENT_UNDEF;
|
||||
static bool sg_control_msg_arrived = false;
|
||||
static char sg_data_report_buffer[2048];
|
||||
size_t sg_data_report_buffersize = sizeof(sg_data_report_buffer) / sizeof(sg_data_report_buffer[0]);
|
||||
|
||||
#ifdef EVENT_POST_ENABLED
|
||||
|
||||
#if defined(EVENT_TIMESTAMP_USED)
|
||||
#undef EVENT_TIMESTAMP_USED
|
||||
#endif
|
||||
|
||||
#include "events_config.c"
|
||||
static void update_events_timestamp(sEvent *pEvents, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < count; i++){
|
||||
if (NULL == (&pEvents[i])) {
|
||||
Log_e("null event pointer");
|
||||
return;
|
||||
}
|
||||
#ifdef EVENT_TIMESTAMP_USED
|
||||
pEvents[i].timestamp = time(NULL); //should be UTC and accurate
|
||||
#else
|
||||
pEvents[i].timestamp = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void event_post_cb(void *pClient, MQTTMessage *msg)
|
||||
{
|
||||
Log_d("Reply:%.*s", msg->payload_len, msg->payload);
|
||||
IOT_Event_clearFlag(pClient, FLAG_EVENT0|FLAG_EVENT1|FLAG_EVENT2);
|
||||
}
|
||||
|
||||
//event check and post
|
||||
static void eventPostCheck(void *client)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
uint32_t eflag;
|
||||
uint8_t event_count;
|
||||
sEvent *pEventList[EVENT_COUNTS];
|
||||
|
||||
IOT_Event_setFlag(client, FLAG_EVENT0|FLAG_EVENT1|FLAG_EVENT2);
|
||||
eflag = IOT_Event_getFlag(client);
|
||||
if((EVENT_COUNTS > 0 )&& (eflag > 0)){
|
||||
event_count = 0;
|
||||
for(i = 0; i < EVENT_COUNTS; i++){
|
||||
if((eflag&(1<<i))&ALL_EVENTS_MASK){
|
||||
pEventList[event_count++] = &(g_events[i]);
|
||||
update_events_timestamp(&g_events[i], 1);
|
||||
IOT_Event_clearFlag(client, 1<<i);
|
||||
}
|
||||
}
|
||||
|
||||
rc = IOT_Post_Event(client, sg_data_report_buffer, sg_data_report_buffersize, \
|
||||
event_count, pEventList, event_post_cb);
|
||||
if(rc < 0){
|
||||
Log_e("events post failed: %d", rc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ACTION_ENABLED
|
||||
#include "action_config.c"
|
||||
|
||||
// action : regist action and set the action handle callback, add your aciton logic here
|
||||
static void OnActionCallback(void *pClient, const char *pClientToken, DeviceAction *pAction)
|
||||
{
|
||||
int i;
|
||||
sReplyPara replyPara;
|
||||
|
||||
//do something base on input, just print as an sample
|
||||
DeviceProperty *pActionInput = pAction->pInput;
|
||||
for (i = 0; i < pAction->input_num; i++) {
|
||||
if (JSTRING == pActionInput[i].type) {
|
||||
Log_d("Input:[%s], data:[%s]", pActionInput[i].key, pActionInput[i].data);
|
||||
HAL_Free(pActionInput[i].data);
|
||||
} else {
|
||||
if(JINT32 == pActionInput[i].type) {
|
||||
Log_d("Input:[%s], data:[%d]", pActionInput[i].key, *((int*)pActionInput[i].data));
|
||||
} else if( JFLOAT == pActionInput[i].type) {
|
||||
Log_d("Input:[%s], data:[%f]", pActionInput[i].key, *((float*)pActionInput[i].data));
|
||||
} else if( JUINT32 == pActionInput[i].type) {
|
||||
Log_d("Input:[%s], data:[%u]", pActionInput[i].key, *((uint32_t*)pActionInput[i].data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// construct output
|
||||
memset((char *)&replyPara, 0, sizeof(sReplyPara));
|
||||
replyPara.code = eDEAL_SUCCESS;
|
||||
replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
strcpy(replyPara.status_msg, "action execute success!"); //add the message about the action resault
|
||||
|
||||
|
||||
DeviceProperty *pActionOutnput = pAction->pOutput;
|
||||
(void)pActionOutnput; //elimate warning
|
||||
//TO DO: add your aciont logic here and set output properties which will be reported by action_reply
|
||||
|
||||
|
||||
IOT_ACTION_REPLY(pClient, pClientToken, sg_data_report_buffer, sg_data_report_buffersize, pAction, &replyPara);
|
||||
}
|
||||
|
||||
static int _register_data_template_action(void *pTemplate_client)
|
||||
{
|
||||
int i,rc;
|
||||
|
||||
for (i = 0; i < TOTAL_ACTION_COUNTS; i++) {
|
||||
rc = IOT_Template_Register_Action(pTemplate_client, &g_actions[i], OnActionCallback);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
rc = IOT_Template_Destroy(pTemplate_client);
|
||||
Log_e("register device data template action failed, err: %d", rc);
|
||||
return rc;
|
||||
} else {
|
||||
Log_i("data template action=%s registered.", g_actions[i].pActionId);
|
||||
}
|
||||
}
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe success, packet-id=%u", packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe nack, packet-id=%u", packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup MQTT construct parameters
|
||||
static int _setup_connect_init_params(TemplateInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
/* TLS with certs*/
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static void OnControlMsgCallback(void *pClient, const char *pJsonValueBuffer, uint32_t valueLength, DeviceProperty *pProperty)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < TOTAL_PROPERTY_COUNT; i++) {
|
||||
/* handle self defined string/json here. Other properties are dealed in _handle_delta()*/
|
||||
if (strcmp(sg_DataTemplate[i].data_property.key, pProperty->key) == 0) {
|
||||
sg_DataTemplate[i].state = eCHANGED;
|
||||
Log_i("Property=%s changed", pProperty->key);
|
||||
sg_control_msg_arrived = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log_e("Property=%s changed no match", pProperty->key);
|
||||
}
|
||||
|
||||
static void OnReportReplyCallback(void *pClient, Method method, ReplyAck replyAck, const char *pJsonDocument, void *pUserdata) {
|
||||
Log_i("recv report reply response, reply ack: %d", replyAck);
|
||||
}
|
||||
|
||||
// register data template properties
|
||||
static int _register_data_template_property(void *pTemplate_client)
|
||||
{
|
||||
int i,rc;
|
||||
|
||||
for (i = 0; i < TOTAL_PROPERTY_COUNT; i++) {
|
||||
rc = IOT_Template_Register_Property(pTemplate_client, &sg_DataTemplate[i].data_property, OnControlMsgCallback);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
rc = IOT_Template_Destroy(pTemplate_client);
|
||||
Log_e("register device data template property failed, err: %d", rc);
|
||||
return rc;
|
||||
} else {
|
||||
Log_i("data template property=%s registered.", sg_DataTemplate[i].data_property.key);
|
||||
}
|
||||
}
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
__weak void OLED_Clear(void)
|
||||
{
|
||||
printf("OLED Clear\n");
|
||||
}
|
||||
|
||||
__weak void OLED_ShowString(int x, int y, uint8_t *str, int bold)
|
||||
{
|
||||
printf("OLED ShowString: %s\n", (char *)str);
|
||||
}
|
||||
|
||||
// handle the light(simulated)
|
||||
static void light_change_color(const char *color)
|
||||
{
|
||||
// <20><>Ϊdemo<6D><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>oled<65><64><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ʾ<EFBFBD><CABE>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>л<EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>ʵ<EFBFBD><CAB5>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ܵƵ<DCB5><C6B5><EFBFBD>ɫ
|
||||
// <20>˴<EFBFBD>demo<6D><6F><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||
OLED_ShowString(0, 0, (uint8_t *)color, 8);
|
||||
}
|
||||
|
||||
static void light_change_brightness(TYPE_DEF_TEMPLATE_INT brightness)
|
||||
{
|
||||
// <20><>Ϊdemo<6D><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>oled<65><64><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ʾ<EFBFBD><CABE>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>л<EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>ʵ<EFBFBD><CAB5>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ܵƵ<DCB5><C6B5><EFBFBD>ɫ
|
||||
// <20>˴<EFBFBD>demo<6D><6F><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||
char brightness_str[12];
|
||||
|
||||
snprintf(brightness_str, sizeof(brightness_str), "%d", brightness);
|
||||
brightness_str[sizeof(brightness_str) - 1] = '\0';
|
||||
OLED_ShowString(0, 2, (uint8_t *)brightness_str, 8);
|
||||
}
|
||||
|
||||
static void light_power_on(void)
|
||||
{
|
||||
// <20><>Ϊdemo<6D><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>oled<65><64><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ʾ<EFBFBD><CABE>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>л<EFBFBD>
|
||||
OLED_Clear();
|
||||
}
|
||||
|
||||
static void light_power_off(void)
|
||||
{
|
||||
// <20><>Ϊdemo<6D><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>oled<65><64><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ʾ<EFBFBD><CABE>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>л<EFBFBD>
|
||||
char *info = "light off";
|
||||
OLED_Clear();
|
||||
OLED_ShowString(0, 0, (uint8_t *)info, 16);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// when control msg received, data_template's properties has been parsed in pData
|
||||
// you should add your logic how to use pData
|
||||
void deal_down_stream_user_logic(void *client, ProductDataDefine * pData)
|
||||
{
|
||||
Log_d("someting about your own product logic wait to be done");
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
char *color_name;
|
||||
|
||||
/* <20>ƹ<EFBFBD><C6B9><EFBFBD>ɫ */
|
||||
switch (sg_ProductData.m_color) {
|
||||
case 0:
|
||||
color_name = " RED ";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
color_name = "GREEN";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
color_name = "BLUE";
|
||||
break;
|
||||
}
|
||||
|
||||
if (sg_ProductData.m_power_switch == 1) {
|
||||
/* <20>ƹ<C6B9><E2BFAA>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD>տ<EFBFBD><D5BF>Ʋ<EFBFBD><C6B2><EFBFBD>չʾ */
|
||||
light_power_on();
|
||||
light_change_color(color_name);
|
||||
light_change_brightness(sg_ProductData.m_brightness);
|
||||
} else {
|
||||
/* <20>ƹ<EFBFBD><C6B9>ر<EFBFBD>չʾ */
|
||||
light_power_off();
|
||||
}
|
||||
}
|
||||
|
||||
void first_time_report_construct(DeviceProperty *pReportDataList[], int *pCount)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < TOTAL_PROPERTY_COUNT; i++) {
|
||||
pReportDataList[j++] = &(sg_DataTemplate[i].data_property);
|
||||
}
|
||||
*pCount = j;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// demo for up-stream
|
||||
// add changed properties to pReportDataList, then the changed properties would be reported
|
||||
// you should add your own logic for how to get the changed properties
|
||||
int deal_up_stream_user_logic(DeviceProperty *pReportDataList[], int *pCount)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < TOTAL_PROPERTY_COUNT; i++) {
|
||||
if(eCHANGED == sg_DataTemplate[i].state) {
|
||||
pReportDataList[j++] = &(sg_DataTemplate[i].data_property);
|
||||
sg_DataTemplate[i].state = eNOCHANGE;
|
||||
}
|
||||
}
|
||||
*pCount = j;
|
||||
|
||||
return (*pCount > 0)?QCLOUD_RET_SUCCESS:QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
/*You should get the real info for your device, here just for example*/
|
||||
static int _get_sys_info(void *handle, char *pJsonDoc, size_t sizeOfBuffer)
|
||||
{
|
||||
/*platform info has at least one of module_hardinfo/module_softinfo/fw_ver property*/
|
||||
DeviceProperty plat_info[] = {
|
||||
{.key = "module_hardinfo", .type = TYPE_TEMPLATE_STRING, .data = "ESP8266"},
|
||||
{.key = "module_softinfo", .type = TYPE_TEMPLATE_STRING, .data = "V1.0"},
|
||||
{.key = "fw_ver", .type = TYPE_TEMPLATE_STRING, .data = QCLOUD_IOT_DEVICE_SDK_VERSION},
|
||||
{.key = "imei", .type = TYPE_TEMPLATE_STRING, .data = "11-22-33-44"},
|
||||
{.key = "lat", .type = TYPE_TEMPLATE_STRING, .data = "22.546015"},
|
||||
{.key = "lon", .type = TYPE_TEMPLATE_STRING, .data = "113.941125"},
|
||||
{NULL, NULL, 0} //end
|
||||
};
|
||||
|
||||
/*self define info*/
|
||||
DeviceProperty self_info[] = {
|
||||
{.key = "append_info", .type = TYPE_TEMPLATE_STRING, .data = "your self define info"},
|
||||
{NULL, NULL, 0} //end
|
||||
};
|
||||
|
||||
return IOT_Template_JSON_ConstructSysInfo(handle, pJsonDoc, sizeOfBuffer, plat_info, self_info);
|
||||
}
|
||||
|
||||
int data_template_light_thread(void) {
|
||||
int rc;
|
||||
sReplyPara replyPara;
|
||||
DeviceProperty *pReportDataList[TOTAL_PROPERTY_COUNT];
|
||||
int ReportCont;
|
||||
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
//init connection
|
||||
TemplateInitParams init_params = DEFAULT_TEMPLATE_INIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *client = IOT_Template_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
int first_time_report = 1;
|
||||
light_power_off();
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
//init data template
|
||||
_init_data_template();
|
||||
|
||||
//register data template propertys here
|
||||
rc = _register_data_template_property(client);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("Register data template propertys Success");
|
||||
} else {
|
||||
Log_e("Register data template propertys Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
//register data template actions here
|
||||
#ifdef ACTION_ENABLED
|
||||
rc = _register_data_template_action(client);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("Register data template actions Success");
|
||||
} else {
|
||||
Log_e("Register data template actions Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
//report device info, then you can manager your product by these info, like position
|
||||
rc = _get_sys_info(client, sg_data_report_buffer, sg_data_report_buffersize);
|
||||
if(QCLOUD_RET_SUCCESS == rc){
|
||||
rc = IOT_Template_Report_SysInfo_Sync(client, sg_data_report_buffer, sg_data_report_buffersize, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("Report system info fail, err: %d", rc);
|
||||
goto exit;
|
||||
}
|
||||
}else{
|
||||
Log_e("Get system info fail, err: %d", rc);
|
||||
}
|
||||
|
||||
//get the property changed during offline
|
||||
rc = IOT_Template_GetStatus_sync(client, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("Get data status fail, err: %d", rc);
|
||||
//goto exit;
|
||||
}else{
|
||||
Log_d("Get data status success");
|
||||
}
|
||||
|
||||
while (IOT_Template_IsConnected(client) || rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT
|
||||
|| rc == QCLOUD_RET_MQTT_RECONNECTED || QCLOUD_RET_SUCCESS == rc) {
|
||||
|
||||
rc = IOT_Template_Yield(client, 200);
|
||||
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
else if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("Exit loop caused of errCode: %d", rc);
|
||||
}
|
||||
|
||||
/* handle control msg from server */
|
||||
if (sg_control_msg_arrived) {
|
||||
|
||||
deal_down_stream_user_logic(client, &sg_ProductData);
|
||||
|
||||
/* control msg should reply, otherwise server treat device didn't receive and retain the msg which would be get by get status*/
|
||||
memset((char *)&replyPara, 0, sizeof(sReplyPara));
|
||||
replyPara.code = eDEAL_SUCCESS;
|
||||
replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
replyPara.status_msg[0] = '\0'; //add extra info to replyPara.status_msg when error occured
|
||||
|
||||
rc = IOT_Template_ControlReply(client, sg_data_report_buffer, sg_data_report_buffersize, &replyPara);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
Log_d("Contol msg reply success");
|
||||
sg_control_msg_arrived = false;
|
||||
} else {
|
||||
Log_e("Contol msg reply failed, err: %d", rc);
|
||||
}
|
||||
} else{
|
||||
Log_d("No control msg received...");
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// some mistake(kind of bug) in this official sample, must do the first time report
|
||||
// the cloud take the light switch state as ON by default
|
||||
if (first_time_report) {
|
||||
/*report msg to server*/
|
||||
/*report the lastest properties's status*/
|
||||
first_time_report_construct(pReportDataList, &ReportCont);
|
||||
rc = IOT_Template_JSON_ConstructReportArray(client, sg_data_report_buffer, sg_data_report_buffersize, ReportCont, pReportDataList);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
rc = IOT_Template_Report(client, sg_data_report_buffer, sg_data_report_buffersize,
|
||||
OnReportReplyCallback, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("data template reporte success");
|
||||
} else {
|
||||
Log_e("data template reporte failed, err: %d", rc);
|
||||
}
|
||||
} else {
|
||||
Log_e("construct reporte data failed, err: %d", rc);
|
||||
}
|
||||
|
||||
first_time_report = 0;
|
||||
} else {
|
||||
///////////////////////////////////
|
||||
|
||||
/*report msg to server*/
|
||||
/*report the lastest properties's status*/
|
||||
if(QCLOUD_RET_SUCCESS == deal_up_stream_user_logic(pReportDataList, &ReportCont)){
|
||||
rc = IOT_Template_JSON_ConstructReportArray(client, sg_data_report_buffer, sg_data_report_buffersize, ReportCont, pReportDataList);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
rc = IOT_Template_Report(client, sg_data_report_buffer, sg_data_report_buffersize,
|
||||
OnReportReplyCallback, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("data template reporte success");
|
||||
} else {
|
||||
Log_e("data template reporte failed, err: %d", rc);
|
||||
}
|
||||
} else {
|
||||
Log_e("construct reporte data failed, err: %d", rc);
|
||||
}
|
||||
|
||||
}else{
|
||||
//Log_d("no data need to be reported or someting goes wrong");
|
||||
}
|
||||
///////////////////////////////////
|
||||
}
|
||||
///////////////////////////////////
|
||||
|
||||
#ifdef EVENT_POST_ENABLED
|
||||
eventPostCheck(client);
|
||||
#endif
|
||||
|
||||
HAL_SleepMs(3000);
|
||||
}
|
||||
exit:
|
||||
rc = IOT_Template_Destroy(client);
|
||||
|
||||
return rc;
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
#ifdef EVENT_POST_ENABLED
|
||||
|
||||
#define EVENT_COUNTS (3)
|
||||
|
||||
static TYPE_DEF_TEMPLATE_BOOL sg_status_report_status = 0;
|
||||
static TYPE_DEF_TEMPLATE_STRING sg_status_report_message[64+1]={0};
|
||||
static DeviceProperty g_propertyEvent_status_report[] = {
|
||||
|
||||
{.key = "status", .data = &sg_status_report_status, .type = TYPE_TEMPLATE_BOOL},
|
||||
{.key = "message", .data = sg_status_report_message, .type = TYPE_TEMPLATE_STRING},
|
||||
};
|
||||
|
||||
static TYPE_DEF_TEMPLATE_FLOAT sg_low_voltage_voltage = 1;
|
||||
static DeviceProperty g_propertyEvent_low_voltage[] = {
|
||||
|
||||
{.key = "voltage", .data = &sg_low_voltage_voltage, .type = TYPE_TEMPLATE_FLOAT},
|
||||
};
|
||||
|
||||
static TYPE_DEF_TEMPLATE_STRING sg_hardware_fault_name[64+1]={0};
|
||||
static TYPE_DEF_TEMPLATE_INT sg_hardware_fault_error_code = 1;
|
||||
static DeviceProperty g_propertyEvent_hardware_fault[] = {
|
||||
|
||||
{.key = "name", .data = sg_hardware_fault_name, .type = TYPE_TEMPLATE_STRING},
|
||||
{.key = "error_code", .data = &sg_hardware_fault_error_code, .type = TYPE_TEMPLATE_INT},
|
||||
};
|
||||
|
||||
|
||||
static sEvent g_events[]={
|
||||
|
||||
{
|
||||
.event_name = "status_report",
|
||||
.type = "info",
|
||||
.timestamp = 0,
|
||||
.eventDataNum = sizeof(g_propertyEvent_status_report)/sizeof(g_propertyEvent_status_report[0]),
|
||||
.pEventData = g_propertyEvent_status_report,
|
||||
},
|
||||
{
|
||||
.event_name = "low_voltage",
|
||||
.type = "alert",
|
||||
.timestamp = 0,
|
||||
.eventDataNum = sizeof(g_propertyEvent_low_voltage)/sizeof(g_propertyEvent_low_voltage[0]),
|
||||
.pEventData = g_propertyEvent_low_voltage,
|
||||
},
|
||||
{
|
||||
.event_name = "hardware_fault",
|
||||
.type = "fault",
|
||||
.timestamp = 0,
|
||||
.eventDataNum = sizeof(g_propertyEvent_hardware_fault)/sizeof(g_propertyEvent_hardware_fault[0]),
|
||||
.pEventData = g_propertyEvent_hardware_fault,
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
@@ -0,0 +1,46 @@
|
||||
#include "tos.h"
|
||||
|
||||
/* 用户根据自己的底层通信链路来配置此宏
|
||||
* 如果是基于以太网lwip的链路,这里应该定义 USE_LWIP
|
||||
* 如果是基于模组的通信链路,这里应该定义相应的模组宏,如使用ESP8266则定义 USE_ESP8266
|
||||
* */
|
||||
#define USE_ESP8266
|
||||
|
||||
#ifdef USE_LWIP
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
#include "esp8266.h"
|
||||
#endif
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
#ifdef USE_LWIP
|
||||
dns_init();
|
||||
MX_LWIP_Init();
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
extern int esp8266_sal_init(hal_uart_port_t uart_port);
|
||||
extern int esp8266_join_ap(const char *ssid, const char *pwd);
|
||||
esp8266_sal_init(HAL_UART_PORT_0);
|
||||
esp8266_join_ap("SheldonDai", "srnr6x9xbhmb0");
|
||||
#endif
|
||||
|
||||
#ifdef USE_NB_BC35
|
||||
extern int bc35_28_95_sal_init(hal_uart_port_t uart_port);
|
||||
bc35_28_95_sal_init(HAL_UART_PORT_0);
|
||||
#endif
|
||||
|
||||
data_template_light_thread();
|
||||
|
||||
while (1) {
|
||||
printf("This is a tencent cloud sdk data template demo!\r\n");
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
191
examples/qcloud_iot_hub_sdk_coap/coap_sample.c
Normal file
191
examples/qcloud_iot_hub_sdk_coap/coap_sample.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
void response_message_callback(void* coap_message, void* userContext)
|
||||
{
|
||||
int ret_code = IOT_COAP_GetMessageCode(coap_message);
|
||||
switch (ret_code) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
Log_i("message received ACK, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT:
|
||||
{
|
||||
char* payload = NULL;
|
||||
int payload_len = 0;
|
||||
int ret = -1;
|
||||
ret = IOT_COAP_GetMessagePayload(coap_message, &payload, &payload_len);
|
||||
if (ret == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("message received response, content: %s", payload);
|
||||
}
|
||||
else {
|
||||
Log_e("message received response, content error.");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT:
|
||||
Log_i("message received ACK but receive response timeout, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void event_handler(void *pcontext, CoAPEventMessage *message)
|
||||
{
|
||||
switch (message->event_type) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
Log_i("message received ACK, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT:
|
||||
Log_i("message received response, content: %s", IOT_COAP_GetMessageId(message->message));
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT:
|
||||
Log_i("message received ACK but receive response timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
default:
|
||||
Log_e("unrecogonized event type: %d", message->event_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(CoAPInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
initParams->max_retry_count = 3;
|
||||
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int coap_basic_thread(void)
|
||||
{
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
CoAPInitParams init_params = DEFAULT_COAPINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *coap_client = IOT_COAP_Construct(&init_params);
|
||||
if (coap_client == NULL) {
|
||||
Log_e("COAP Client construct failed.");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
do {
|
||||
SendMsgParams send_params = DEFAULT_SENDMSG_PARAMS;
|
||||
send_params.pay_load = "{\"name\":\"hello world\"}";
|
||||
send_params.pay_load_len = strlen("{\"name\":\"hello world\"}");
|
||||
send_params.resp_callback = response_message_callback;
|
||||
|
||||
char topicName[128] = "";
|
||||
sprintf(topicName, "%s/%s/data", sg_devInfo.product_id, sg_devInfo.device_name);
|
||||
Log_i("topic name is %s", topicName);
|
||||
|
||||
rc = IOT_COAP_SendMessage(coap_client, topicName, &send_params);
|
||||
if (rc < 0) {
|
||||
Log_e("client publish topic failed :%d.", rc);
|
||||
}
|
||||
else {
|
||||
Log_d("client topic has been sent, msg_id: %d", rc);
|
||||
}
|
||||
|
||||
rc = IOT_COAP_Yield(coap_client, 200);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS){
|
||||
Log_e("exit with error: %d", rc);
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
IOT_COAP_Destroy(&coap_client);
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
48
examples/qcloud_iot_hub_sdk_coap/qcloud_iot_hub_sdk_coap.c
Normal file
48
examples/qcloud_iot_hub_sdk_coap/qcloud_iot_hub_sdk_coap.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "tos.h"
|
||||
|
||||
/* 用户根据自己的底层通信链路来配置此宏
|
||||
* 如果是基于以太网lwip的链路,这里应该定义 USE_LWIP
|
||||
* 如果是基于模组的通信链路,这里应该定义相应的模组宏,如使用ESP8266则定义 USE_ESP8266
|
||||
* */
|
||||
#define USE_ESP8266
|
||||
|
||||
#ifdef USE_LWIP
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
#include "esp8266.h"
|
||||
#endif
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
extern void mqtt_basic_thread(void);
|
||||
|
||||
#ifdef USE_LWIP
|
||||
dns_init();
|
||||
MX_LWIP_Init();
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
extern int esp8266_sal_init(hal_uart_port_t uart_port);
|
||||
extern int esp8266_join_ap(const char *ssid, const char *pwd);
|
||||
esp8266_sal_init(HAL_UART_PORT_0);
|
||||
esp8266_join_ap("SheldonDai", "srnr6x9xbhmb0");
|
||||
#endif
|
||||
|
||||
#ifdef USE_NB_BC35
|
||||
extern int bc35_28_95_sal_init(hal_uart_port_t uart_port);
|
||||
bc35_28_95_sal_init(HAL_UART_PORT_0);
|
||||
#endif
|
||||
|
||||
coap_basic_thread();
|
||||
|
||||
while (1) {
|
||||
printf("This is a mqtt demo!\r\n");
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
322
examples/qcloud_iot_hub_sdk_mqtt/mqtt_sample.c
Normal file
322
examples/qcloud_iot_hub_sdk_mqtt/mqtt_sample.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
static int sg_count = 0;
|
||||
static int sg_sub_packet_id = -1;
|
||||
|
||||
|
||||
// user's log print callback
|
||||
static bool log_handler(const char* message)
|
||||
{
|
||||
// return true if print success
|
||||
return false;
|
||||
}
|
||||
|
||||
// MQTT event callback
|
||||
static void _mqtt_event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
MQTTMessage* mqtt_messge = (MQTTMessage*)msg->msg;
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_RECVEIVED:
|
||||
Log_i("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
|
||||
mqtt_messge->topic_len,
|
||||
mqtt_messge->ptopic,
|
||||
mqtt_messge->payload_len,
|
||||
mqtt_messge->payload);
|
||||
break;
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_SUCCESS:
|
||||
Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
|
||||
Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_NACK:
|
||||
Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Setup MQTT construct parameters
|
||||
static int _setup_connect_init_params(MQTTInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
sprintf(sg_cert_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
#else
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
#endif
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = _mqtt_event_handler;
|
||||
initParams->event_handle.context = NULL;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
#define MAX_SIZE_OF_TOPIC_CONTENT 100
|
||||
// publish MQTT msg
|
||||
static int _publish_test_msg(void *client, char *topic_keyword, QoS qos)
|
||||
{
|
||||
char topicName[128] = {0};
|
||||
sprintf(topicName,"%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, topic_keyword);
|
||||
|
||||
PublishParams pub_params = DEFAULT_PUB_PARAMS;
|
||||
pub_params.qos = qos;
|
||||
|
||||
char topic_content[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0};
|
||||
|
||||
int size = HAL_Snprintf(topic_content, sizeof(topic_content), "{\"action\": \"publish_test\", \"count\": \"%d\"}", sg_count++);
|
||||
if (size < 0 || size > sizeof(topic_content) - 1) {
|
||||
Log_e("payload content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_content));
|
||||
return -3;
|
||||
}
|
||||
|
||||
pub_params.payload = topic_content;
|
||||
pub_params.payload_len = strlen(topic_content);
|
||||
|
||||
return IOT_MQTT_Publish(client, topicName, &pub_params);
|
||||
}
|
||||
|
||||
// callback when MQTT msg arrives
|
||||
static void on_message_callback(void *pClient, MQTTMessage *message, void *userData)
|
||||
{
|
||||
if (message == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log_i("Receive Message With topicName:%.*s, payload:%.*s",
|
||||
(int) message->topic_len, message->ptopic, (int) message->payload_len, (char *) message->payload);
|
||||
}
|
||||
|
||||
// subscrib MQTT topic
|
||||
static int _subscribe_topic(void *client, char *topic_keyword, QoS qos)
|
||||
{
|
||||
static char topic_name[128] = {0};
|
||||
int size = HAL_Snprintf(topic_name, sizeof(topic_name), "%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, topic_keyword);
|
||||
|
||||
if (size < 0 || size > sizeof(topic_name) - 1) {
|
||||
Log_e("topic content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_name));
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
|
||||
sub_params.qos = qos;
|
||||
sub_params.on_message_handler = on_message_callback;
|
||||
return IOT_MQTT_Subscribe(client, topic_name, &sub_params);
|
||||
}
|
||||
|
||||
#ifdef LOG_UPLOAD
|
||||
// init log upload module
|
||||
static int _init_log_upload(void)
|
||||
{
|
||||
LogUploadInitParams log_init_params;
|
||||
memset(&log_init_params, 0, sizeof(LogUploadInitParams));
|
||||
|
||||
log_init_params.product_id = sg_devInfo.product_id;
|
||||
log_init_params.device_name = sg_devInfo.device_name;
|
||||
#ifdef AUTH_MODE_CERT
|
||||
log_init_params.sign_key = sg_cert_file;
|
||||
#else
|
||||
log_init_params.sign_key = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(WIN32)
|
||||
log_init_params.read_func = HAL_Log_Read;
|
||||
log_init_params.save_func = HAL_Log_Save;
|
||||
log_init_params.del_func = HAL_Log_Del;
|
||||
log_init_params.get_size_func = HAL_Log_Get_Size;
|
||||
#endif
|
||||
|
||||
return IOT_Log_Init_Uploader(&log_init_params);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int mqtt_basic_thread(void)
|
||||
{
|
||||
int rc;
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
IOT_Log_Set_MessageHandler(log_handler);
|
||||
|
||||
//init connection
|
||||
MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params error, rc = %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef LOG_UPLOAD
|
||||
// _init_log_upload should be done after _setup_connect_init_params and before IOT_MQTT_Construct
|
||||
rc = _init_log_upload();
|
||||
if (rc != QCLOUD_RET_SUCCESS)
|
||||
Log_e("init log upload error, rc = %d", rc);
|
||||
#endif
|
||||
|
||||
// create MQTT client and connect with server
|
||||
void *client = IOT_MQTT_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
rc = IOT_MQTT_GetErrCode();
|
||||
Log_e("MQTT Construct failed, rc = %d", rc);
|
||||
IOT_Log_Upload(true);
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef SYSTEM_COMM
|
||||
long time = 0;
|
||||
// get system timestamp from server
|
||||
rc = IOT_Get_SysTime(client, &time);
|
||||
if (QCLOUD_RET_SUCCESS == rc){
|
||||
Log_i("system time is %ld", time);
|
||||
} else {
|
||||
Log_e("get system time failed!");
|
||||
}
|
||||
#endif
|
||||
|
||||
//subscribe normal topics here
|
||||
rc = _subscribe_topic(client, "data", QOS0);
|
||||
if (rc < 0) {
|
||||
Log_e("Client Subscribe Topic Failed: %d", rc);
|
||||
IOT_Log_Upload(true);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// wait for subscription result
|
||||
IOT_MQTT_Yield(client, 500);
|
||||
|
||||
do {
|
||||
|
||||
if (sg_sub_packet_id > 0) {
|
||||
rc = _publish_test_msg(client, "data", QOS1);
|
||||
if (rc < 0) {
|
||||
Log_e("client publish topic failed :%d.", rc);
|
||||
}
|
||||
}
|
||||
|
||||
rc = IOT_MQTT_Yield(client, 500);
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
} else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED){
|
||||
Log_e("exit with error: %d", rc);
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
rc = IOT_MQTT_Destroy(&client);
|
||||
|
||||
IOT_Log_Upload(true);
|
||||
|
||||
return rc;
|
||||
}
|
48
examples/qcloud_iot_hub_sdk_mqtt/qcloud_iot_hub_sdk_mqtt.c
Normal file
48
examples/qcloud_iot_hub_sdk_mqtt/qcloud_iot_hub_sdk_mqtt.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "tos.h"
|
||||
|
||||
/* 用户根据自己的底层通信链路来配置此宏
|
||||
* 如果是基于以太网lwip的链路,这里应该定义 USE_LWIP
|
||||
* 如果是基于模组的通信链路,这里应该定义相应的模组宏,如使用ESP8266则定义 USE_ESP8266
|
||||
* */
|
||||
#define USE_ESP8266
|
||||
|
||||
#ifdef USE_LWIP
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
#include "esp8266.h"
|
||||
#endif
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
extern void mqtt_basic_thread(void);
|
||||
|
||||
#ifdef USE_LWIP
|
||||
dns_init();
|
||||
MX_LWIP_Init();
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
extern int esp8266_sal_init(hal_uart_port_t uart_port);
|
||||
extern int esp8266_join_ap(const char *ssid, const char *pwd);
|
||||
esp8266_sal_init(HAL_UART_PORT_0);
|
||||
esp8266_join_ap("SheldonDai", "srnr6x9xbhmb0");
|
||||
#endif
|
||||
|
||||
#ifdef USE_NB_BC35
|
||||
extern int bc35_28_95_sal_init(hal_uart_port_t uart_port);
|
||||
bc35_28_95_sal_init(HAL_UART_PORT_0);
|
||||
#endif
|
||||
|
||||
mqtt_basic_thread();
|
||||
|
||||
while (1) {
|
||||
printf("This is a mqtt demo!\r\n");
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user