add new qloud-c-sdk component
This commit is contained in:
@@ -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, ¶ms);
|
||||
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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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,
|
||||
¶ms);
|
||||
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);
|
||||
}
|
Reference in New Issue
Block a user