add new qloud-c-sdk component

This commit is contained in:
mculover666
2022-03-25 10:06:56 +08:00
parent 565cd29e94
commit a3ac2e56d8
166 changed files with 35027 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
file(GLOB src_system_mqtt ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c)
set(inc_system_mqtt ${CMAKE_CURRENT_SOURCE_DIR}/inc/)
set(src_services ${src_services} ${src_system_mqtt} PARENT_SCOPE)
set(inc_services ${inc_services} ${inc_system_mqtt} PARENT_SCOPE)
file(GLOB src_data_template_sample ${CMAKE_CURRENT_SOURCE_DIR}/sample/data_template_sample.c)
add_executable(data_template_sample ${src_data_template_sample})
target_link_libraries(data_template_sample ${libsdk})
if( ${CONFIG_IOT_TEST} STREQUAL "ON")
file(GLOB src_unit_test ${CMAKE_CURRENT_SOURCE_DIR}/test/*.cc)
set(src_test ${src_test} ${src_unit_test} PARENT_SCOPE)
endif()

View File

@@ -0,0 +1,194 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template.h
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-08-23
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-08-23 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#ifndef IOT_HUB_DEVICE_C_SDK_SERVICES_EXPLORER_DATA_TEMPLATE_INC_DATA_TEMPLATE_H_
#define IOT_HUB_DEVICE_C_SDK_SERVICES_EXPLORER_DATA_TEMPLATE_INC_DATA_TEMPLATE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "qcloud_iot_common.h"
#include "qcloud_iot_data_template.h"
/**************************************************************************************
* common
**************************************************************************************/
/**
* @brief Type of data template(property/event/action).
*
*/
typedef enum {
DATA_TEMPLATE_TYPE_PROPERTY = 0,
DATA_TEMPLATE_TYPE_EVENT,
DATA_TEMPLATE_TYPE_ACTION,
} DataTemplateType;
/**
* @brief Context of data template, callback and user data.
*
*/
typedef struct {
union {
PropertyMessageCallback property_callback;
EventMessageCallback event_callback;
ActionMessageCallback action_callback;
};
void *usr_data;
} DataTemplateContext;
/**
* @brief Check if topic already subscribed, if not then subscribe.
*
* @param[in,out] client pointer to mqtt client
* @param[in] type @see DataTemplateType
* @param[in] on_message_handler message handle of topic
* @param[in] context @see DataTemplateContext
* @return @see IotReturnCode
*/
int data_template_topic_check_and_sub(void *client, DataTemplateType type, OnMessageHandler on_message_handler,
DataTemplateContext context);
/**
* @brief Unsubscribe data template topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] type @see DataTemplateType
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_topic_unsubscribe(void *client, DataTemplateType type);
/**
* @brief Publish to data template topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] type @see DataTemplateType
* @param[in] qos @see QoS
* @param[in] payload payload of mqtt packet
* @param[in] payload_len payload len
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_publish(void *client, DataTemplateType type, QoS qos, const char *payload, int payload_len);
/**************************************************************************************
* property
**************************************************************************************/
typedef enum {
PROPERTY_UP_METHOD_TYPE_REPORT = 0,
PROPERTY_UP_METHOD_TYPE_REPORT_INFO,
PROPERTY_UP_METHOD_TYPE_GET_STATUS,
PROPERTY_UP_METHOD_TYPE_CLEAR_CONTROL,
PROPERTY_UP_METHOD_TYPE_CONTROL_REPLY,
} PropertyUpMethodType;
typedef union {
const char *json;
int code;
struct {
int code;
UtilsJsonValue client_token;
} control_reply;
} PropertyPublishParams;
/**
* @brief Mqtt message callback for property topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] message message from topic
* @param[in,out] usr_data pointer to @see DataTemplateContext
*/
void data_template_property_message_handler(void *client, const MQTTMessage *message, void *usr_data);
/**
* @brief Publish message to property topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] publish_type @see PropertyUpMethodType
* @param[out] buf publish message buffer
* @param[in] buf_len buffer len
* @param[in] params @see PropertyPublishParams
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_property_publish(void *client, PropertyUpMethodType publish_type, char *buf, int buf_len,
PropertyPublishParams params);
/**************************************************************************************
* event
**************************************************************************************/
/**
* @brief Mqtt message callback for event topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] message message from topic
* @param[in,out] usr_data pointer to @see DataTemplateContext
*/
void data_template_event_message_handler(void *client, const MQTTMessage *message, void *usr_data);
/**
* @brief Publish message to event topic.
*
* @param[in,out] client pointer to mqtt client
* @param[out] buf publish message buffer
* @param[in] buf_len buffer len
* @param[in] data @see IotDataTemplateEventData
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_event_reply_publish(void *client, char *buf, int buf_len, IotDataTemplateEventData data);
/**************************************************************************************
* action
**************************************************************************************/
/**
* @brief Mqtt message callback for action topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] message message from topic
* @param[in,out] usr_data pointer to @see DataTemplateContext
*/
void data_template_action_message_handler(void *client, const MQTTMessage *message, void *usr_data);
/**
* @brief Publish message to event topic.
*
* @param[in,out] client pointer to mqtt client
* @param[out] buf publish message buffer
* @param[in] buf_len buffer len
* @param[in] reply @see IotDataTemplateActionReply
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_action_reply_publish(void *client, char *buf, int buf_len, IotDataTemplateActionReply reply);
#ifdef __cplusplus
}
#endif
#endif // IOT_HUB_DEVICE_C_SDK_SERVICES_EXPLORER_DATA_TEMPLATE_INC_DATA_TEMPLATE_H_

View File

@@ -0,0 +1,314 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template_sample.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-09-27
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-09-27 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "qcloud_iot_common.h"
#include "qcloud_iot_explorer.h"
#include "utils_log.h"
/**
* @brief MQTT event callback, @see MQTTEventHandleFun
*
* @param[in] client pointer to mqtt client
* @param[in] handle_context context
* @param[in] msg msg
*/
static void _mqtt_event_handler(void *client, void *handle_context, MQTTEventMsg *msg)
{
MQTTMessage *mqtt_message = (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_RECEIVED:
Log_i("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
mqtt_message->topic_len, STRING_PTR_PRINT_SANITY_CHECK(mqtt_message->topic_name),
mqtt_message->payload_len, STRING_PTR_PRINT_SANITY_CHECK((char *)mqtt_message->payload));
break;
case MQTT_EVENT_SUBSCRIBE_SUCCESS:
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
break;
case MQTT_EVENT_SUBSCRIBE_TIMEOUT:
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
break;
case MQTT_EVENT_SUBSCRIBE_NACK:
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
break;
case MQTT_EVENT_UNSUBSCRIBE_SUCCESS:
Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
break;
case MQTT_EVENT_UNSUBSCRIBE_TIMEOUT:
Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
break;
case MQTT_EVENT_UNSUBSCRIBE_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;
}
}
/**
* @brief Setup MQTT construct parameters.
*
* @param[in,out] initParams @see MQTTInitParams
* @param[in] device_info @see DeviceInfo
*/
static void _setup_connect_init_params(MQTTInitParams *init_params, DeviceInfo *device_info)
{
init_params->device_info = device_info;
init_params->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
init_params->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
init_params->auto_connect_enable = 1;
init_params->event_handle.h_fp = _mqtt_event_handler;
init_params->event_handle.context = NULL;
}
// ----------------------------------------------------------------------------
// Data template callback
// ----------------------------------------------------------------------------
static void _method_control_callback(UtilsJsonValue client_token, UtilsJsonValue params, void *usr_data)
{
char buf[256];
Log_i("recv msg[%.*s]: params=%.*s", client_token.value_len, client_token.value, params.value_len, params.value);
IOT_DataTemplate_PropertyControlReply(usr_data, buf, sizeof(buf), 0, client_token);
}
static void _method_report_reply_callback(UtilsJsonValue client_token, int code, void *usr_data)
{
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_get_status_reply_callback(UtilsJsonValue client_token, int code, UtilsJsonValue reported,
UtilsJsonValue control, void *usr_data)
{
char buf[256];
Log_i("recv msg[%.*s]: code=%d|reported=%.*s|control=%.*s", client_token.value_len, client_token.value, code,
reported.value_len, STRING_PTR_PRINT_SANITY_CHECK(reported.value), control.value_len,
STRING_PTR_PRINT_SANITY_CHECK(control.value));
IOT_DataTemplate_PropertyClearControl(usr_data, buf, sizeof(buf));
}
static void _method_report_info_reply_callback(UtilsJsonValue client_token, int code, void *usr_data)
{
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_clear_control_reply_callback(UtilsJsonValue client_token, int code, void *usr_data)
{
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_event_reply_callback(UtilsJsonValue client_token, int code, void *usr_data)
{
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_action_callback(UtilsJsonValue client_token, UtilsJsonValue action_id, UtilsJsonValue params,
void *usr_data)
{
char buf[256];
Log_i("recv msg[%.*s]: action_id=%.*s|params=%.*s", client_token.value_len, client_token.value, action_id.value_len,
action_id.value, params.value_len, params.value);
IotDataTemplateActionReply reply = {
.code = 0,
.client_token = client_token,
.response = "{\"err_code\":0}",
};
IOT_DataTemplate_ActionReply(usr_data, buf, sizeof(buf), reply);
}
// ----------------------------------------------------------------------------
// Data template upstream
// ----------------------------------------------------------------------------
static void _cycle_report(void *client)
{
char buf[256];
const char *report_property = "{\"power_switch\":0}";
IotDataTemplateEventData event_data = {
.event_id = "status_report",
.type = IOT_DATA_TEMPLATE_EVENT_TYPE_INFO,
.params = "{\"status\":0,\"message\":\"ok\"}",
};
static Timer sg_cycle_report_timer;
if (HAL_Timer_Expired(&sg_cycle_report_timer)) {
IOT_DataTemplate_PropertyReport(client, buf, sizeof(buf), report_property);
IOT_DataTemplate_EventPost(client, buf, sizeof(buf), event_data);
HAL_Timer_Countdown(&sg_cycle_report_timer, 500);
}
}
// ----------------------------------------------------------------------------
// Main
// ----------------------------------------------------------------------------
static int sg_main_exit = 0;
#ifdef __linux__
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
static void _main_exit(int sig)
{
Log_e("demo exit by signal:%d\n", sig);
sg_main_exit = 1;
}
#endif
int main(int argc, char **argv)
{
#ifdef __linux__
signal(SIGINT, _main_exit);
#endif
int rc;
char buf[1024];
// init log level
LogHandleFunc func = {0};
func.log_malloc = HAL_Malloc;
func.log_free = HAL_Free;
func.log_get_current_time_str = HAL_Timer_Current;
func.log_printf = HAL_Printf;
utils_log_init(func, LOG_LEVEL_DEBUG, 2048);
DeviceInfo device_info;
rc = HAL_GetDevInfo((void *)&device_info);
if (rc) {
Log_e("get device info failed: %d", rc);
return rc;
}
// init connection
MQTTInitParams init_params = DEFAULT_MQTT_INIT_PARAMS;
_setup_connect_init_params(&init_params, &device_info);
// create MQTT client and connect with server
void *client = IOT_MQTT_Construct(&init_params);
if (client) {
Log_i("Cloud Device Construct Success");
} else {
Log_e("MQTT Construct failed!");
return QCLOUD_ERR_FAILURE;
}
// subscribe normal topics and wait result
IotDataTemplateCallback callback = {
.property_callback = {.method_control_callback = _method_control_callback,
.method_clear_control_reply_callback = _method_clear_control_reply_callback,
.method_get_status_reply_callback = _method_get_status_reply_callback,
.method_report_info_reply_callback = _method_report_info_reply_callback,
.method_report_reply_callback = _method_report_reply_callback},
.event_callback = {.method_event_reply_callback = _method_event_reply_callback},
.action_callback = {.method_action_callback = _method_action_callback},
};
rc = IOT_DataTemplate_Init(client, callback, client);
if (rc) {
Log_e("Client Subscribe Topic Failed: %d", rc);
return rc;
}
const char *report_info =
"{\"module_hardinfo\":\"ESP8266\",\"module_softinfo\":\"V1.0\", \"fw_ver\":\"4.0.0\", "
"\"imei\":\"11-22-33-44\",\"lat\":\"22.546015\",\"lon\":\"113.941125\",\"mac\":\"11:22:33:44:55:66\",\"device_"
"label\":{\"append_"
"info\":\"your self defined info\"}}";
IOT_DataTemplate_PropertyReportInfo(client, buf, sizeof(buf), report_info);
IOT_DataTemplate_PropertyGetStatus(client, buf, sizeof(buf));
do {
rc = IOT_MQTT_Yield(client, QCLOUD_IOT_MQTT_YIELD_TIMEOUT);
switch (rc) {
case QCLOUD_RET_SUCCESS:
break;
case QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT:
continue;
case QCLOUD_RET_MQTT_RECONNECTED:
IOT_DataTemplate_PropertyGetStatus(client, buf, sizeof(buf));
break;
default:
Log_e("Exit loop caused of errCode:%d", rc);
goto exit;
}
_cycle_report(client);
} while (!sg_main_exit);
exit:
IOT_DataTemplate_Deinit(client);
rc |= IOT_MQTT_Destroy(&client);
utils_log_deinit();
return rc;
}

View File

@@ -0,0 +1,95 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template_action.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-09-26
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-09-26 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "data_template.h"
/**
* @brief Mqtt message callback for action topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] message message from topic
* @param[in,out] usr_data pointer to @see DataTemplateContext
*/
void data_template_action_message_handler(void *client, const MQTTMessage *message, void *usr_data)
{
DataTemplateContext *data_template_context = (DataTemplateContext *)usr_data;
int rc = 0;
UtilsJsonValue method, client_token, action_id, params;
Log_d("receive action message:%.*s", message->payload_len, message->payload_str);
rc = utils_json_value_get("method", strlen("method"), message->payload_str, message->payload_len, &method);
if (rc) {
return;
}
if (!strncmp(method.value, "action", method.value_len)) {
if (data_template_context->action_callback.method_action_callback) {
rc = utils_json_value_get("clientToken", strlen("clientToken"), message->payload_str, message->payload_len,
&client_token);
if (rc) {
goto error;
}
rc = utils_json_value_get("actionId", strlen("actionId"), message->payload_str, message->payload_len,
&action_id);
if (rc) {
goto error;
}
rc = utils_json_value_get("params", strlen("params"), message->payload_str, message->payload_len, &params);
if (rc) {
goto error;
}
data_template_context->action_callback.method_action_callback(client_token, action_id, params,
data_template_context->usr_data);
}
}
return;
error:
Log_e("invalid format of payload!");
}
/**
* @brief Publish message to event topic.
*
* @param[in,out] client pointer to mqtt client
* @param[out] buf publish message buffer
* @param[in] buf_len buffer len
* @param[in] reply @see IotDataTemplateActionReply
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_action_reply_publish(void *client, char *buf, int buf_len, IotDataTemplateActionReply reply)
{
int len =
HAL_Snprintf(buf, buf_len, "{\"method\":\"action_reply\",\"clientToken\":\"%.*s\",\"code\":%d,\"response\":%s}",
reply.client_token.value_len, reply.client_token.value, reply.code, reply.response);
return data_template_publish(client, DATA_TEMPLATE_TYPE_ACTION, QOS0, buf, len);
}

View File

@@ -0,0 +1,199 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-08-22
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-08-22 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_data_template.h"
#include "data_template.h"
/**
* @brief Check and subscribe data template topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] callback @see IotDataTemplateCallback
* @param[in] usr_data usr data used in callback
* @return 0 for success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_Init(void *client, IotDataTemplateCallback callback, void *usr_data)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
int rc = 0;
DataTemplateContext data_tempale_context;
data_tempale_context.usr_data = usr_data;
data_tempale_context.property_callback = callback.property_callback;
rc |= data_template_topic_check_and_sub(client, DATA_TEMPLATE_TYPE_PROPERTY, data_template_property_message_handler,
data_tempale_context);
// if (callback.event_callback.method_event_reply_callback) {
// data_tempale_context.event_callback = callback.event_callback;
// rc |= data_template_topic_check_and_sub(client, DATA_TEMPLATE_TYPE_EVENT, data_template_event_message_handler,
// data_tempale_context);
// }
// if (callback.action_callback.method_action_callback) {
// data_tempale_context.action_callback = callback.action_callback;
// rc |= data_template_topic_check_and_sub(client, DATA_TEMPLATE_TYPE_ACTION, data_template_action_message_handler,
// data_tempale_context);
// }
return rc;
}
/**
* @brief Unsubscribe data template topic.
*
* @param[in,out] client pointer to mqtt client
*/
void IOT_DataTemplate_Deinit(void *client)
{
POINTER_SANITY_CHECK_RTN(client);
data_template_topic_unsubscribe(client, DATA_TEMPLATE_TYPE_PROPERTY);
data_template_topic_unsubscribe(client, DATA_TEMPLATE_TYPE_EVENT);
data_template_topic_unsubscribe(client, DATA_TEMPLATE_TYPE_ACTION);
}
/**
* @brief Report property.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @param[in] params params constructed with property
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_PropertyReport(void *client, char *buf, int buf_len, const char *params)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
POINTER_SANITY_CHECK(buf, QCLOUD_ERR_INVAL);
PropertyPublishParams publish_params = {.json = params};
return data_template_property_publish(client, PROPERTY_UP_METHOD_TYPE_REPORT, buf, buf_len, publish_params);
}
/**
* @brief Get control message offline.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_PropertyGetStatus(void *client, char *buf, int buf_len)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
POINTER_SANITY_CHECK(buf, QCLOUD_ERR_INVAL);
PropertyPublishParams publish_params = {0};
return data_template_property_publish(client, PROPERTY_UP_METHOD_TYPE_GET_STATUS, buf, buf_len, publish_params);
}
/**
* @brief Report device info.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @param[in] params params constructed with device info
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_PropertyReportInfo(void *client, char *buf, int buf_len, const char *params)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
POINTER_SANITY_CHECK(buf, QCLOUD_ERR_INVAL);
PropertyPublishParams publish_params = {.json = params};
return data_template_property_publish(client, PROPERTY_UP_METHOD_TYPE_REPORT_INFO, buf, buf_len, publish_params);
}
/**
* @brief Clear control message offline.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_PropertyClearControl(void *client, char *buf, int buf_len)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
POINTER_SANITY_CHECK(buf, QCLOUD_ERR_INVAL);
PropertyPublishParams publish_params = {0};
return data_template_property_publish(client, PROPERTY_UP_METHOD_TYPE_CLEAR_CONTROL, buf, buf_len, publish_params);
}
/**
* @brief Reply control message.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @param[in] code 0 for success
* @param[in] client_token client token of control message
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_PropertyControlReply(void *client, char *buf, int buf_len, int code, UtilsJsonValue client_token)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
POINTER_SANITY_CHECK(buf, QCLOUD_ERR_INVAL);
PropertyPublishParams publish_params = {.control_reply.code = code, .control_reply.client_token = client_token};
return data_template_property_publish(client, PROPERTY_UP_METHOD_TYPE_CONTROL_REPLY, buf, buf_len, publish_params);
}
/**
* @brief Post event.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @param[in] data @see IotDataTemplateEventData
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_EventPost(void *client, char *buf, int buf_len, IotDataTemplateEventData data)
{
POINTER_SANITY_CHECK(client, QCLOUD_ERR_INVAL);
POINTER_SANITY_CHECK(buf, QCLOUD_ERR_INVAL);
return data_template_event_reply_publish(client, buf, buf_len, data);
}
/**
* @brief Reply action message.
*
* @param[in,out] client pointer to mqtt client
* @param[in] buf buffer for message
* @param[in] buf_len buffer length
* @param[in] reply @see IotDataTemplateActionReply
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int IOT_DataTemplate_ActionReply(void *client, char *buf, int buf_len, IotDataTemplateActionReply reply)
{
return data_template_action_reply_publish(client, buf, buf_len, reply);
}

View File

@@ -0,0 +1,101 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template_event.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-09-26
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-09-26 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "data_template.h"
/**
* @brief Mqtt message callback for event topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] message message from topic
* @param[in,out] usr_data pointer to @see DataTemplateContext
*/
void data_template_event_message_handler(void *client, const MQTTMessage *message, void *usr_data)
{
DataTemplateContext *data_template_context = (DataTemplateContext *)usr_data;
int rc, code = 0;
UtilsJsonValue method, client_token, value_code;
Log_d("receive event message:%.*s", message->payload_len, message->payload_str);
rc = utils_json_value_get("method", strlen("method"), message->payload_str, message->payload_len, &method);
if (rc) {
return;
}
if (!strncmp(method.value, "event_reply", method.value_len)) {
if (data_template_context->event_callback.method_event_reply_callback) {
rc = utils_json_value_get("clientToken", strlen("clientToken"), message->payload_str, message->payload_len,
&client_token);
if (rc) {
goto error;
}
rc = utils_json_value_get("code", strlen("code"), message->payload_str, message->payload_len, &value_code);
if (rc) {
goto error;
}
rc = utils_json_value_data_get(value_code, UTILS_JSON_VALUE_TYPE_INT32, &code);
if (rc) {
goto error;
}
data_template_context->event_callback.method_event_reply_callback(client_token, code,
data_template_context->usr_data);
}
}
return;
error:
Log_e("invalid format of payload!");
}
/**
* @brief Publish message to event topic.
*
* @param[in,out] client pointer to mqtt client
* @param[out] buf publish message buffer
* @param[in] buf_len buffer len
* @param[in] data @see IotDataTemplateEventData
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_event_reply_publish(void *client, char *buf, int buf_len, IotDataTemplateEventData data)
{
const char *event_type[] = {
"info", // IOT_DATA_TEMPLATE_EVENT_TYPE_INFO
"alert", // IOT_DATA_TEMPLATE_EVENT_TYPE_ALERT
"fault", // IOT_DATA_TEMPLATE_EVENT_TYPE_FAULT
};
static uint32_t token_num = 0;
int len = HAL_Snprintf(
buf, buf_len,
"{\"method\":\"event_post\",\"clientToken\":\"event-%u\",\"eventId\":\"%s\",\"type\":\"%s\",\"params\":%s}",
token_num++, data.event_id, event_type[data.type], data.params);
return data_template_publish(client, DATA_TEMPLATE_TYPE_EVENT, QOS0, buf, len);
}

View File

@@ -0,0 +1,141 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template_mqtt.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-10-18
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-10-18 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_data_template.h"
#include "data_template.h"
/**
* @brief Direction(upstream/downstream) for topic.
*
*/
typedef enum {
DATA_TEMPLATE_DIRECTION_UP = 0,
DATA_TEMPLATE_DIRECTION_DOWN,
} DataTemplateDirection;
/**
* @brief Generate topic string.
*
* @param[out] buf buffer for topic name
* @param[in] buf_len buffer length
* @param[in] direction @see DataTemplateDirection
* @param[in] type @see DataTemplateType
* @param[in] product_id product id of device
* @param[in] device_name device name of device
* @return > 0 for length of topic name, others for fail.
*/
static int _data_template_topic_generate(char *buf, int buf_len, DataTemplateDirection direction, DataTemplateType type,
const char *product_id, const char *device_name)
{
const char *topic_method[] = {"property", "event", "action"};
// $thing/down/property/C283SMY3W3/test1
return HAL_Snprintf(buf, buf_len, "$thing/%s/%s/%s/%s", direction ? "down" : "up", topic_method[type],
STRING_PTR_PRINT_SANITY_CHECK(product_id), STRING_PTR_PRINT_SANITY_CHECK(device_name));
}
/**
* @brief Check if topic already subscribed, if not then subscribe.
*
* @param[in,out] client pointer to mqtt client
* @param[in] type @see DataTemplateType
* @param[in] on_message_handler message handle of topic
* @param[in] context @see DataTemplateContext
* @return @see IotReturnCode
*/
int data_template_topic_check_and_sub(void *client, DataTemplateType type, OnMessageHandler on_message_handler,
DataTemplateContext context)
{
char data_template_topic[MAX_SIZE_OF_CLOUD_TOPIC];
_data_template_topic_generate(data_template_topic, MAX_SIZE_OF_CLOUD_TOPIC, DATA_TEMPLATE_DIRECTION_DOWN, type,
IOT_MQTT_GetDeviceInfo(client)->product_id,
IOT_MQTT_GetDeviceInfo(client)->device_name);
int rc = 0;
DataTemplateContext *data_template_context = HAL_Malloc(sizeof(DataTemplateContext));
if (!data_template_context) {
return QCLOUD_ERR_MALLOC;
}
*data_template_context = context;
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
sub_params.on_message_handler = on_message_handler;
sub_params.qos = QOS1;
sub_params.user_data = data_template_context;
sub_params.user_data_free = HAL_Free;
rc = IOT_MQTT_SubscribeSync(client, data_template_topic, &sub_params);
if (rc) {
Log_e("subscribe topic %s failed!", data_template_topic);
HAL_Free(data_template_context);
}
return rc;
}
/**
* @brief Unsubscribe data template topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] type @see DataTemplateType
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_topic_unsubscribe(void *client, DataTemplateType type)
{
char data_template_topic[MAX_SIZE_OF_CLOUD_TOPIC];
_data_template_topic_generate(data_template_topic, MAX_SIZE_OF_CLOUD_TOPIC, DATA_TEMPLATE_DIRECTION_DOWN, type,
IOT_MQTT_GetDeviceInfo(client)->product_id,
IOT_MQTT_GetDeviceInfo(client)->device_name);
return IOT_MQTT_Unsubscribe(client, data_template_topic);
}
/**
* @brief Publish to data template topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] type @see DataTemplateType
* @param[in] qos @see QoS
* @param[in] payload payload of mqtt packet
* @param[in] payload_len payload len
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_publish(void *client, DataTemplateType type, QoS qos, const char *payload, int payload_len)
{
NUMBERIC_SANITY_CHECK(payload_len, QCLOUD_ERR_BUF_TOO_SHORT);
char data_template_topic[MAX_SIZE_OF_CLOUD_TOPIC];
_data_template_topic_generate(data_template_topic, MAX_SIZE_OF_CLOUD_TOPIC, DATA_TEMPLATE_DIRECTION_UP, type,
IOT_MQTT_GetDeviceInfo(client)->product_id,
IOT_MQTT_GetDeviceInfo(client)->device_name);
PublishParams pub_params = DEFAULT_PUB_PARAMS;
pub_params.qos = qos;
pub_params.payload = (void *)payload;
pub_params.payload_len = payload_len;
return IOT_MQTT_Publish(client, data_template_topic, &pub_params);
}

View File

@@ -0,0 +1,214 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file data_template_property.c
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-08-23
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-08-23 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_data_template.h"
#include "data_template.h"
/**
* @brief Down method type.
*
*/
typedef enum {
PROPERTY_DOWN_METHOD_TYPE_CONTROL = 0,
PROPERTY_DOWN_METHOD_TYPE_REPORT_REPLY,
PROPERTY_DOWN_METHOD_TYPE_GET_STATUS_REPLY,
PROPERTY_DOWN_METHOD_TYPE_REPORT_INFO_REPLY,
PROPERTY_DOWN_METHOD_TYPE_CLEAR_CONTROL_REPLY,
} PropertyDownMethodType;
/**
* @brief Parse payload and callback.
*
* @param[in] type @see PropertyDownMethodType
* @param[in] message message from cloud
* @param[in] callback callback for user
* @param[in,out] usr_data user data used in callback
*/
static void _parse_method_payload_and_callback(PropertyDownMethodType type, const MQTTMessage *message,
const PropertyMessageCallback *callback, void *usr_data)
{
int rc = 0, code;
UtilsJsonValue client_token, value_code, params, reported, control;
// get client token
rc = utils_json_value_get("clientToken", strlen("clientToken"), message->payload_str, message->payload_len,
&client_token);
if (rc) {
goto error;
}
// get code
if (PROPERTY_DOWN_METHOD_TYPE_REPORT_REPLY == type || PROPERTY_DOWN_METHOD_TYPE_GET_STATUS_REPLY == type ||
PROPERTY_DOWN_METHOD_TYPE_REPORT_INFO_REPLY == type || PROPERTY_DOWN_METHOD_TYPE_CLEAR_CONTROL_REPLY == type) {
rc = utils_json_value_get("code", strlen("code"), message->payload_str, message->payload_len, &value_code);
if (rc) {
goto error;
}
rc = utils_json_value_data_get(value_code, UTILS_JSON_VALUE_TYPE_INT32, &code);
if (rc) {
goto error;
}
}
// callback
switch (type) {
case PROPERTY_DOWN_METHOD_TYPE_CONTROL:
if (callback->method_control_callback) {
rc = utils_json_value_get("params", strlen("params"), message->payload_str, message->payload_len,
&params);
if (rc) {
goto error;
}
callback->method_control_callback(client_token, params, usr_data);
}
break;
case PROPERTY_DOWN_METHOD_TYPE_REPORT_REPLY:
if (callback->method_report_reply_callback) {
callback->method_report_reply_callback(client_token, code, usr_data);
}
break;
case PROPERTY_DOWN_METHOD_TYPE_GET_STATUS_REPLY:
if (callback->method_get_status_reply_callback) {
reported.value = NULL;
reported.value_len = 0;
control.value = NULL;
control.value_len = 0;
rc = utils_json_value_get("data.reported", strlen("data.reported"), message->payload_str,
message->payload_len, &reported);
rc &= utils_json_value_get("data.control", strlen("data.control"), message->payload_str,
message->payload_len, &control);
if (rc) {
goto error;
}
callback->method_get_status_reply_callback(client_token, code, reported, control, usr_data);
}
break;
case PROPERTY_DOWN_METHOD_TYPE_REPORT_INFO_REPLY:
if (callback->method_report_info_reply_callback) {
callback->method_report_info_reply_callback(client_token, code, usr_data);
}
break;
case PROPERTY_DOWN_METHOD_TYPE_CLEAR_CONTROL_REPLY:
if (callback->method_clear_control_reply_callback) {
callback->method_clear_control_reply_callback(client_token, code, usr_data);
}
break;
default:
break;
}
return;
error:
Log_e("invalid format of payload!");
return;
}
/**
* @brief Mqtt message callback for property topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] message message from topic
* @param[in,out] usr_data pointer to @see DataTemplateContext
*/
void data_template_property_message_handler(void *client, const MQTTMessage *message, void *usr_data)
{
const char *property_down_method_str[] = {
"control", // PROPERTY_DOWN_METHOD_TYPE_CONTROL
"report_reply", // PROPERTY_DOWN_METHOD_TYPE_REPORT_REPLY
"get_status_reply", // PROPERTY_DOWN_METHOD_TYPE_GET_STATUS_REPLY
"report_info_reply", // PROPERTY_DOWN_METHOD_TYPE_REPORT_INFO_REPLY
"clear_control_reply", // PROPERTY_DOWN_METHOD_TYPE_CLEAR_CONTROL_REPLY
};
int rc, i = 0;
DataTemplateContext *data_template_context = (DataTemplateContext *)usr_data;
UtilsJsonValue method;
Log_d("receive property message:%.*s", message->payload_len, message->payload_str);
rc = utils_json_value_get("method", strlen("method"), message->payload_str, message->payload_len, &method);
if (rc) {
return;
}
for (i = PROPERTY_DOWN_METHOD_TYPE_CONTROL; i <= PROPERTY_DOWN_METHOD_TYPE_CLEAR_CONTROL_REPLY; i++) {
if (!strncmp(method.value, property_down_method_str[i], method.value_len)) {
_parse_method_payload_and_callback(i, message, &data_template_context->property_callback,
data_template_context->usr_data);
}
}
}
/**
* @brief Publish message to property topic.
*
* @param[in,out] client pointer to mqtt client
* @param[in] publish_type @see PropertyUpMethodType
* @param[out] buf publish message buffer
* @param[in] buf_len buffer len
* @param[in] params @see PropertyPublishParams
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
*/
int data_template_property_publish(void *client, PropertyUpMethodType publish_type, char *buf, int buf_len,
PropertyPublishParams params)
{
static uint32_t token_num = 0;
int len = 0;
switch (publish_type) {
case PROPERTY_UP_METHOD_TYPE_REPORT:
len = HAL_Snprintf(buf, buf_len, "{\"method\":\"report\",\"clientToken\":\"property-%u\",\"params\":%s}",
token_num++, params.json);
break;
case PROPERTY_UP_METHOD_TYPE_REPORT_INFO:
len =
HAL_Snprintf(buf, buf_len, "{\"method\":\"report_info\",\"clientToken\":\"property-%u\",\"params\":%s}",
token_num++, params.json);
break;
case PROPERTY_UP_METHOD_TYPE_GET_STATUS:
len =
HAL_Snprintf(buf, buf_len, "{\"method\":\"get_status\",\"clientToken\":\"property-%u\"}", token_num++);
break;
case PROPERTY_UP_METHOD_TYPE_CLEAR_CONTROL:
len = HAL_Snprintf(buf, buf_len, "{\"method\":\"clear_control\",\"clientToken\":\"property-%u\"}",
token_num++);
break;
case PROPERTY_UP_METHOD_TYPE_CONTROL_REPLY:
len = HAL_Snprintf(buf, buf_len, "{\"method\":\"control_reply\",\"clientToken\":\"%.*s\",\"code\":%d}",
params.control_reply.client_token.value_len, params.control_reply.client_token.value,
params.control_reply.code);
break;
default:
return QCLOUD_ERR_FAILURE;
}
return data_template_publish(client, DATA_TEMPLATE_TYPE_PROPERTY, QOS0, buf, len);
}

View File

@@ -0,0 +1,8 @@
Language: Cpp
BasedOnStyle: Google
ColumnLimit: 120
DerivePointerAlignment: true
PointerAlignment: Left
SortIncludes: true
IncludeBlocks: Preserve
IndentPPDirectives: AfterHash

View File

@@ -0,0 +1,156 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 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.
*
* @file test_data_template.cc
* @brief
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-09-29
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-09-29 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include <iostream>
#include <string>
#include "gtest/gtest.h"
#include "mqtt_client_test.h"
#include "qcloud_iot_common.h"
#include "qcloud_iot_explorer.h"
namespace mqtt_client_unittest {
static void _method_control_callback(UtilsJsonValue client_token, UtilsJsonValue params, void *usr_data) {
char buf[256];
Log_i("recv msg[%.*s]: params=%.*s", client_token.value_len, client_token.value, params.value_len, params.value);
IOT_DataTemplate_PropertyControlReply(usr_data, buf, sizeof(buf), 0, client_token);
}
static void _method_report_reply_callback(UtilsJsonValue client_token, int code, void *usr_data) {
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_get_status_reply_callback(UtilsJsonValue client_token, int code, UtilsJsonValue reported,
UtilsJsonValue control, void *usr_data) {
char buf[256];
Log_i("recv msg[%.*s]: code=%d|reported=%.*s|control=%.*s", client_token.value_len, client_token.value, code,
reported.value_len, STRING_PTR_PRINT_SANITY_CHECK(reported.value), control.value_len,
STRING_PTR_PRINT_SANITY_CHECK(control.value));
IOT_DataTemplate_PropertyClearControl(usr_data, buf, sizeof(buf));
}
static void _method_report_info_reply_callback(UtilsJsonValue client_token, int code, void *usr_data) {
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_clear_control_reply_callback(UtilsJsonValue client_token, int code, void *usr_data) {
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_event_reply_callback(UtilsJsonValue client_token, int code, void *usr_data) {
Log_i("recv msg[%.*s]: code=%d", client_token.value_len, client_token.value, code);
}
static void _method_action_callback(UtilsJsonValue client_token, UtilsJsonValue action_id, UtilsJsonValue params,
void *usr_data) {
char buf[256];
Log_i("recv msg[%.*s]: action_id=%.*s|params=%.*s", client_token.value_len, client_token.value, action_id.value_len,
action_id.value, params.value_len, params.value);
IotDataTemplateActionReply reply = {
.client_token = client_token,
.code = 0,
.response = "{\"err_code\":0}",
};
ASSERT_GE(IOT_DataTemplate_ActionReply(usr_data, buf, sizeof(buf), reply), 0);
}
/**
* @brief Test data template property.
*
*/
TEST_F(MqttClientTest, data_template_property) {
char buf[1024];
IotDataTemplateCallback callback = {
.property_callback = {.method_control_callback = _method_control_callback,
.method_report_reply_callback = _method_report_reply_callback,
.method_get_status_reply_callback = _method_get_status_reply_callback,
.method_report_info_reply_callback = _method_report_info_reply_callback,
.method_clear_control_reply_callback = _method_clear_control_reply_callback},
.event_callback = {.method_event_reply_callback = NULL},
.action_callback = {.method_action_callback = NULL},
};
const char *report_info =
"{\"module_hardinfo\":\"ESP8266\",\"module_softinfo\":\"V1.0\", \"fw_ver\":\"4.0.0\", "
"\"imei\":\"11-22-33-44\",\"lat\":\"22.546015\",\"lon\":\"113.941125\",\"mac\":\"11:22:33:44:55:66\",\"device_"
"label\":{\"append_"
"info\":\"your self defined info\"}}";
ASSERT_EQ(IOT_DataTemplate_Init(client, callback, client), 0);
ASSERT_EQ(IOT_DataTemplate_PropertyReportInfo(client, buf, sizeof(buf), report_info), 0);
ASSERT_EQ(IOT_DataTemplate_PropertyGetStatus(client, buf, sizeof(buf)), 0);
IOT_DataTemplate_Deinit(client);
}
/**
* @brief Test data template event.
*
*/
TEST_F(MqttClientTest, data_template_event) {
char buf[1024];
IotDataTemplateCallback callback = {
.property_callback = {0},
.event_callback = {.method_event_reply_callback = _method_event_reply_callback},
.action_callback = {.method_action_callback = _method_action_callback},
};
const char *report_property = "{\"power_switch\":0}";
IotDataTemplateEventData event_data = {
.event_id = "status_report",
.type = IOT_DATA_TEMPLATE_EVENT_TYPE_INFO,
.params = "{\"status\":0,\"message\":\"ok\"}",
};
ASSERT_EQ(IOT_DataTemplate_Init(client, callback, client), 0);
ASSERT_GE(IOT_DataTemplate_EventPost(client, buf, sizeof(buf), event_data), 0);
IOT_DataTemplate_Deinit(client);
}
/**
* @brief Test data template action.
*
*/
TEST_F(MqttClientTest, data_template_action) {
char buf[1024];
IotDataTemplateCallback callback = {
.property_callback = {0},
.event_callback = {.method_event_reply_callback = NULL},
.action_callback = {.method_action_callback = _method_action_callback},
};
ASSERT_EQ(IOT_DataTemplate_Init(client, callback, client), 0);
IOT_DataTemplate_Deinit(client);
}
} // namespace mqtt_client_unittest