support dev model ex and ota module

This commit is contained in:
ethan.du 2020-08-11 16:32:36 +08:00
parent 14d95a0f48
commit 4b1572fd61
19 changed files with 1312 additions and 252 deletions

View File

@ -0,0 +1,51 @@
#ifndef _HAL_FLASH_H_
#define _HAL_FLASH_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include "uiot_import.h"
/**
* @brief name
*
* @param handle download_name的指针
* @return download_name的指针
*/
void * HAL_Download_Name_Set(void * handle);
/**
* @brief FLASH等操作
*
* @param name
* @return
*/
void * HAL_Download_Init(_IN_ void * name);
/**
* @brief length的buffer_read的数据写入到FLASH中
*
* @param handle
* @param total_length
* @param buffer_read
* @param length
* @return -1 0
*/
int HAL_Download_Write(_IN_ void * handle,_IN_ uint32_t total_length,_IN_ uint8_t *buffer_read,_IN_ uint32_t length);
/**
* @brief STM32F767 FLASH的information分区的下载标志置位成功
*
* @param
* @return -1 0
*/
int HAL_Download_End(_IN_ void * handle);
#if defined(__cplusplus)
}
#endif
#endif /* _HAL_FLASH_H_ */

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2012-2019 UCloud. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file 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 "HAL_Flash_Platform.h"
#include <fal.h>
#define DOWNLOAD_PARTITION "download"
void * HAL_Download_Name_Set(void * handle)
{
return (void *)DOWNLOAD_PARTITION;
}
void * HAL_Download_Init(_IN_ void * name)
{
char * file_name =(char *)name;
const struct fal_partition * dl_part = RT_NULL;
if ((dl_part = fal_partition_find(file_name)) == RT_NULL)
{
LOG_ERROR("Firmware download failed! Partition (%s) find error!", file_name);
return NULL;
}
LOG_INFO("Start erase flash (%s) partition!", dl_part->name);
if (fal_partition_erase_all(dl_part) < 0)
{
LOG_ERROR("Firmware download failed! Partition (%s) erase error!", dl_part->name);
return NULL;
}
LOG_INFO("Erase flash (%s) partition success!", dl_part->name);
return (void *)dl_part;
}
int HAL_Download_Write(_IN_ void * handle,_IN_ uint32_t total_length,_IN_ uint8_t *buffer_read,_IN_ uint32_t length)
{
const struct fal_partition * dl_part = (struct fal_partition *) handle;
if(dl_part==NULL)
return FAILURE_RET;
if (fal_partition_write(dl_part, total_length, buffer_read, length) < 0){
LOG_ERROR("Firmware download failed! Partition (%s) write data error!", dl_part->name);
return FAILURE_RET;
}
return SUCCESS_RET;
}
int HAL_Download_End(_IN_ void * handle)
{
LOG_INFO("System now will restart...");
rt_thread_delay(rt_tick_from_millisecond(5));
/* Reset the device, Start new firmware */
extern void rt_hw_cpu_reset(void);
rt_hw_cpu_reset();
return SUCCESS_RET;
}

View File

@ -15,6 +15,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
@ -80,10 +81,9 @@ int property_post_cb(const char *request_id, const int ret_code){
return SUCCESS_RET;
}
int command_cb(const char *request_id, const char *identifier, const char *input, char **output){
int command_cb(const char *request_id, const char *identifier, const char *input, char *output){
LOG_INFO("command_cb; request_id: %s; identifier: %s; input: %s", request_id, identifier, input);
*output = (char *)HAL_Malloc(100);
HAL_Snprintf(*output, 1000, "{\"result\":%d}", 1);
HAL_Snprintf(output, 1000, "{\"result\":%d}", 1);
return SUCCESS_RET;
}
@ -140,8 +140,8 @@ static void mqtt_devmodel_thread(void)
IOT_DM_Yield(h_dm, 200);
for (i = 0; i < 10; i++) {
IOT_DM_Property_Report(h_dm, PROPERTY_POST, i * 2, "{\"volume\": {\"Value\":50}}");
IOT_DM_TriggerEvent(h_dm, i * 2 + 1, "low_power_alert", "{\"power\": 5}");
IOT_DM_Property_Report(h_dm, PROPERTY_POST, i * 2, "\"volume\": {\"Value\":50}");
IOT_DM_TriggerEvent(h_dm, i * 2 + 1, "low_power_alert", "\"power\": 5");
IOT_DM_Yield(h_dm, 200);
HAL_SleepMs(2000);

View File

@ -110,12 +110,12 @@ static void ota_test_thread(void)
}
/* Must report version first */
if (IOT_OTA_ReportVersion(h_ota, "1.0.0") < 0) {
if (IOT_OTA_ReportVersion(h_ota, "default", "1.0.0") < 0) {
LOG_ERROR("report OTA version failed");
return;
}
if (IOT_OTA_RequestFirmware(h_ota, "1.0.0") < 0) {
if (IOT_OTA_RequestFirmware(h_ota, "default", "1.0.0") < 0) {
LOG_ERROR("Request firmware failed");
return;
}

View File

@ -6,5 +6,5 @@
<runtime>
<enforceFIPSPolicy enabled="false" />
</runtime>
<configs SELEFILE="C:\Users\usser\Desktop\rtthread.bin" SAVEFILE="C:\Users\usser\Desktop\rtthread.rbl" COMPRESS="2" CRYPT="0" KEY="" IV="" NAME="app" VERSION="2.0.0" />
<configs SELEFILE="C:\Users\usser\Desktop\rtthread.bin" SAVEFILE="C:\Users\usser\Desktop\rtthread.rbl" COMPRESS="0" CRYPT="0" KEY="" IV="" NAME="app" VERSION="2.0.0" />
</configuration>

View File

@ -22,9 +22,9 @@ extern "C" {
#define DM_TOPIC_BUF_LEN (128)
#define DM_MSG_REPLY_BUF_LEN (128)
#define DM_MSG_REPORT_BUF_LEN (256)
#define DM_EVENT_POST_BUF_LEN (256)
#define DM_CMD_REPLY_BUF_LEN (256)
#define DM_MSG_REPORT_BUF_LEN (2048)
#define DM_EVENT_POST_BUF_LEN (2048)
#define DM_CMD_REPLY_BUF_LEN (2048)
//pub
#define PROPERTY_RESTORE_TOPIC_TEMPLATE "/$system/%s/%s/tmodel/property/restore"

View File

@ -67,10 +67,16 @@ void *dsc_init(const char *product_sn, const char *device_sn, void *channel, voi
int dsc_deinit(void *handle);
int dm_gen_properties_payload(DM_Property_t *property, int property_num, DM_Type type, bool value_key, char *properties_payload);
int dm_mqtt_property_report_publish(DM_MQTT_Struct_t *handle, DM_Type type, int request_id, const char *payload);
int dm_mqtt_property_report_publish_Ex(DM_MQTT_Struct_t *handle, DM_Type type, int request_id, DM_Property_t *property, int property_num);
int dm_mqtt_event_publish(DM_MQTT_Struct_t *handle, int request_id, const char *identifier, const char *payload);
int dm_mqtt_event_publish_Ex(DM_MQTT_Struct_t *handle, int request_id, DM_Event_t *event);
#ifdef __cplusplus
}
#endif

View File

@ -63,6 +63,32 @@ int IOT_DM_Property_Report(void *handle, DM_Type type, int request_id, const cha
return dm_mqtt_property_report_publish(h_dm->ch_signal, type, request_id, payload);
}
int IOT_DM_Property_ReportEx(void *handle, DM_Type type, int request_id, int property_num, ...)
{
POINTER_VALID_CHECK(handle, FAILURE_RET);
int loop = 0;
int ret = 0;
DM_Struct_t *h_dm = (DM_Struct_t*) handle;
va_list pArgs;
va_start(pArgs, property_num);
DM_Property_t *property = (DM_Property_t *)HAL_Malloc(property_num * sizeof(DM_Property_t));
for(loop = 0; loop < property_num; loop++)
{
DM_Property_t *property_node;
property_node = va_arg(pArgs, DM_Property_t *);
property[loop] = *property_node;
}
va_end(pArgs);
ret = dm_mqtt_property_report_publish_Ex(h_dm->ch_signal, type, request_id, property, property_num);
HAL_Free(property);
return ret;
}
int IOT_DM_TriggerEvent(void *handle, int request_id, const char *identifier, const char *payload)
{
POINTER_VALID_CHECK(handle, FAILURE_RET);
@ -72,6 +98,40 @@ int IOT_DM_TriggerEvent(void *handle, int request_id, const char *identifier, co
return dm_mqtt_event_publish(h_dm->ch_signal, request_id, identifier, payload);
}
int IOT_DM_TriggerEventEx(void *handle, int request_id, DM_Event_t *event)
{
POINTER_VALID_CHECK(handle, FAILURE_RET);
DM_Struct_t *h_dm = (DM_Struct_t*) handle;
return dm_mqtt_event_publish_Ex(h_dm->ch_signal, request_id, event);
}
int IOT_DM_GenCommandOutput(char *output, int property_num, ...)
{
POINTER_VALID_CHECK(output, FAILURE_RET);
int ret = 0;
int loop = 0;
va_list pArgs;
va_start(pArgs, property_num);
DM_Property_t *property = (DM_Property_t *)HAL_Malloc(property_num * sizeof(DM_Property_t));
for(loop = 0; loop < property_num; loop++)
{
DM_Property_t *property_node;
property_node = va_arg(pArgs, DM_Property_t *);
property[loop] = *property_node;
}
va_end(pArgs);
ret = dm_gen_properties_payload(property, property_num, PROPERTY_POST, false, output);
HAL_Free(property);
return ret;
}
int IOT_DM_Yield(void *handle, uint32_t timeout_ms)
{
POINTER_VALID_CHECK(handle, FAILURE_RET);

View File

@ -39,7 +39,7 @@ static int _dm_mqtt_gen_topic_name(char *buf, size_t buf_len, const char *topic_
ret = HAL_Snprintf(buf, buf_len, topic_template, product_sn, device_sn);
if (ret < 0 || ret >= buf_len) {
LOG_ERROR("HAL_Snprintf failed");
LOG_ERROR("HAL_Snprintf failed\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
@ -55,18 +55,18 @@ static int _dm_mqtt_gen_property_payload(char *buf, size_t buf_len, DM_Type type
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\"}", request_id);
break;
case PROPERTY_POST:
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Property\": %s}", request_id, payload);
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Property\": {%s}}", request_id, payload);
break;
case PROPERTY_DESIRED_GET:
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Require\": %s}", request_id, payload);
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Require\": [%s]}", request_id, payload);
break;
case PROPERTY_DESIRED_DELETE:
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Delete\": %s}", request_id, payload);
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Delete\": {%s}}", request_id, payload);
break;
default: FUNC_EXIT_RC(FAILURE_RET);
}
if (ret < 0 || ret >= buf_len) {
LOG_ERROR("generate property payload failed");
LOG_ERROR("generate property payload failed\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
@ -77,11 +77,11 @@ static int _dm_mqtt_gen_event_payload(char *buf, size_t buf_len, int request_id,
FUNC_ENTRY;
int ret;
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Identifier\": \"%s\", \"Output\": %s}", request_id,
ret = HAL_Snprintf(buf, buf_len, "{\"RequestID\": \"%d\", \"Identifier\": \"%s\", \"Output\": {%s}}", request_id,
identifier, payload);
if (ret < 0 || ret >= buf_len) {
LOG_ERROR("generate event payload failed");
LOG_ERROR("generate event payload failed\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
@ -105,7 +105,7 @@ static int _dm_mqtt_publish(DM_MQTT_Struct_t *handle, char *topic_name, int qos,
ret = IOT_MQTT_Publish(handle->mqtt, topic_name, &pub_params);
if (ret < 0) {
LOG_ERROR("publish to topic: %s failed", topic_name);
LOG_ERROR("publish to topic: %s failed\r\n", topic_name);
FUNC_EXIT_RC(FAILURE_RET);
}
@ -121,22 +121,22 @@ static void _dm_mqtt_common_reply_cb(MQTTMessage *message, CommonReplyCB cb) {
char *msg = NULL;
if (NULL == (msg = HAL_Malloc(message->payload_len + 1))) {
LOG_ERROR("allocate for message failed");
LOG_ERROR("allocate for message failed\r\n");
FUNC_EXIT;
}
HAL_Snprintf(msg, message->payload_len + 1, "%s", message->payload);
if (NULL == (ret_code_char = LITE_json_value_of((char *) "RetCode", msg))) {
LOG_ERROR("allocate for ret_code_char failed");
LOG_ERROR("allocate for ret_code_char failed\r\n");
goto do_exit;
}
if (SUCCESS_RET != LITE_get_int8(&ret_code, ret_code_char)) {
LOG_ERROR("get ret_code failed");
LOG_ERROR("get ret_code failed\r\n");
goto do_exit;
}
if (NULL == (request_id = LITE_json_value_of((char *) "RequestID", msg))) {
LOG_ERROR("allocate for request_id failed");
LOG_ERROR("allocate for request_id failed\r\n");
goto do_exit;
}
@ -169,26 +169,26 @@ void dm_mqtt_property_restore_cb(void *pClient, MQTTMessage *message, void *pCon
char *msg = NULL;
if (NULL == (msg = HAL_Malloc(message->payload_len + 1))) {
LOG_ERROR("allocate for message failed");
LOG_ERROR("allocate for message failed\r\n");
FUNC_EXIT;
}
HAL_Snprintf(msg, message->payload_len + 1, "%s", message->payload);
if (NULL == (ret_code_char = LITE_json_value_of((char *) "RetCode", msg))) {
LOG_ERROR("allocate for ret_code_char failed");
LOG_ERROR("allocate for ret_code_char failed\r\n");
goto do_exit;
}
if (SUCCESS_RET != LITE_get_int8(&ret_code, ret_code_char)) {
LOG_ERROR("get for ret_code failed");
LOG_ERROR("get for ret_code failed\r\n");
goto do_exit;
}
if (NULL == (request_id = LITE_json_value_of((char *) "RequestID", msg))) {
LOG_ERROR("allocate for request_id failed");
LOG_ERROR("allocate for request_id failed\r\n");
goto do_exit;
}
if (NULL == (property = LITE_json_value_of((char *) "Property", msg))) {
LOG_ERROR("allocate for property failed");
LOG_ERROR("allocate for property failed\r\n");
goto do_exit;
}
@ -241,18 +241,18 @@ void dm_mqtt_property_set_cb(void *pClient, MQTTMessage *message, void *pContext
char *msg = NULL;
if (NULL == (msg = HAL_Malloc(message->payload_len + 1))) {
LOG_ERROR("allocate for message failed");
LOG_ERROR("allocate for message failed\r\n");
FUNC_EXIT;
}
HAL_Snprintf(msg, message->payload_len + 1, "%s", message->payload);
if (NULL == (request_id = LITE_json_value_of((char *) "RequestID", msg))) {
LOG_ERROR("allocate for request_id failed");
LOG_ERROR("allocate for request_id failed\r\n");
goto do_exit;
}
if (NULL == (property = LITE_json_value_of((char *) "Property", msg))) {
LOG_ERROR("allocate for property failed");
LOG_ERROR("allocate for property failed\r\n");
goto do_exit;
}
@ -260,26 +260,26 @@ void dm_mqtt_property_set_cb(void *pClient, MQTTMessage *message, void *pContext
cb_ret = cb(request_id, property);
if (NULL == (msg_reply = HAL_Malloc(DM_MSG_REPLY_BUF_LEN))) {
LOG_ERROR("allocate for msg_reply failed");
LOG_ERROR("allocate for msg_reply failed\r\n");
goto do_exit;
}
if (NULL == (topic = HAL_Malloc(DM_TOPIC_BUF_LEN))) {
LOG_ERROR("allocate for topic failed");
LOG_ERROR("allocate for topic failed\r\n");
goto do_exit;
}
if (SUCCESS_RET != _dm_mqtt_gen_topic_name(topic, DM_TOPIC_BUF_LEN, handle->upstream_topic_templates[PROPERTY_SET],
handle->product_sn, handle->device_sn)) {
LOG_ERROR("generate topic name failed");
LOG_ERROR("generate topic name failed\r\n");
goto do_exit;
}
ret = HAL_Snprintf(msg_reply, DM_MSG_REPLY_BUF_LEN, "{\"RequestID\": \"%s\", \"RetCode\": %d}", request_id, cb_ret);
if (ret < 0 || ret >= DM_MSG_REPLY_BUF_LEN) {
LOG_ERROR("HAL_Snprintf msg_reply failed");
LOG_ERROR("HAL_Snprintf msg_reply failed\r\n");
goto do_exit;
}
ret = _dm_mqtt_publish(handle, topic, 1, msg_reply);
if (ret < 0) {
LOG_ERROR("mqtt publish msg failed");
LOG_ERROR("mqtt publish msg failed\r\n");
goto do_exit;
}
@ -312,26 +312,26 @@ void dm_mqtt_property_desired_get_cb(void *pClient, MQTTMessage *message, void *
char *msg = NULL;
if (NULL == (msg = HAL_Malloc(message->payload_len + 1))) {
LOG_ERROR("allocate for message failed");
LOG_ERROR("allocate for message failed\r\n");
goto do_exit;
}
HAL_Snprintf(msg, message->payload_len + 1, "%s", message->payload);
if (NULL == (ret_code_char = LITE_json_value_of((char *) "RetCode", msg))) {
LOG_ERROR("allocate for ret_code_char failed");
LOG_ERROR("allocate for ret_code_char failed\r\n");
goto do_exit;
}
if (SUCCESS_RET != LITE_get_int8(&ret_code, ret_code_char)) {
LOG_ERROR("get ret_code failed");
LOG_ERROR("get ret_code failed\r\n");
goto do_exit;
}
if (NULL == (request_id = LITE_json_value_of((char *) "RequestID", msg))) {
LOG_ERROR("allocate for request_id failed");
LOG_ERROR("allocate for request_id failed\r\n");
goto do_exit;
}
if (NULL == (desired = LITE_json_value_of((char *) "Desired", msg))) {
LOG_ERROR("allocate for desired failed");
LOG_ERROR("allocate for desired failed\r\n");
goto do_exit;
}
@ -401,58 +401,65 @@ void dm_mqtt_command_cb(void *pClient, MQTTMessage *message, void *pContext) {
char *msg = NULL;
if (NULL == (msg = HAL_Malloc(message->payload_len + 1))) {
LOG_ERROR("allocate for message failed");
LOG_ERROR("allocate for message failed\r\n");
FUNC_EXIT;
}
HAL_Snprintf(msg, message->payload_len + 1, "%s", message->payload);
if (NULL == (request_id = LITE_json_value_of((char *) "RequestID", msg))) {
LOG_ERROR("allocate for request_id failed");
LOG_ERROR("allocate for request_id failed\r\n");
goto do_exit;
}
if (NULL == (identifier = LITE_json_value_of((char *) "Identifier", msg))) {
LOG_ERROR("allocate for identifier failed");
LOG_ERROR("allocate for identifier failed\r\n");
goto do_exit;
}
if (NULL == (input = LITE_json_value_of((char *) "Input", msg))) {
LOG_ERROR("allocate for input failed");
LOG_ERROR("allocate for input failed\r\n");
goto do_exit;
}
output = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == output) {
LOG_ERROR("allocate for output failed\r\n");
goto do_exit;
}
cb = (CommandCB) handle->callbacks[COMMAND];
cb_ret = cb(request_id, identifier, input, &output);
cb_ret = cb(request_id, identifier, input, output);
if (NULL == output) {
LOG_ERROR("output error");
LOG_ERROR("output error\r\n");
goto do_exit;
}
if (NULL == (cmd_reply = HAL_Malloc(DM_CMD_REPLY_BUF_LEN))) {
LOG_ERROR("allocate for cmd_reply failed");
LOG_ERROR("allocate for cmd_reply failed\r\n");
goto do_exit;
}
if (NULL == (topic = HAL_Malloc(DM_TOPIC_BUF_LEN))) {
LOG_ERROR("allocate for topic failed");
LOG_ERROR("allocate for topic failed\r\n");
goto do_exit;
}
int ret = HAL_Snprintf(topic, DM_TOPIC_BUF_LEN, handle->upstream_topic_templates[COMMAND], handle->product_sn,
handle->device_sn, request_id);
if (ret < 0 || ret > DM_TOPIC_BUF_LEN) {
LOG_ERROR("topic error");
LOG_ERROR("topic error\r\n");
goto do_exit;
}
ret = HAL_Snprintf(cmd_reply, DM_CMD_REPLY_BUF_LEN,
"{\"RequestID\": \"%s\", \"RetCode\": %d, \"Identifier\": \"%s\", \"Output\": %s}",
"{\"RequestID\": \"%s\", \"RetCode\": %d, \"Identifier\": \"%s\", \"Output\": {%s}}",
request_id, cb_ret, identifier, output);
if (ret < 0 || ret > DM_CMD_REPLY_BUF_LEN) {
LOG_ERROR("generate cmd_reply msg failed");
LOG_ERROR("generate cmd_reply msg failed\r\n");
goto do_exit;
}
ret = _dm_mqtt_publish(handle, topic, 1, cmd_reply);
if (ret < 0) {
LOG_ERROR("mqtt publish msg failed");
LOG_ERROR("mqtt publish msg failed\r\n");
goto do_exit;
}
@ -473,7 +480,7 @@ int _dsc_mqtt_register_callback(DM_MQTT_Struct_t *handle, DM_Type dm_type, void
int ret;
if (NULL == handle || callback == NULL) {
LOG_ERROR("params error!");
LOG_ERROR("params error!\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
handle->callbacks[dm_type] = callback;
@ -484,7 +491,7 @@ int _dsc_mqtt_register_callback(DM_MQTT_Struct_t *handle, DM_Type dm_type, void
ret = _dm_mqtt_gen_topic_name(topic, DM_TOPIC_BUF_LEN, handle->downstream_topic_templates[dm_type],
handle->product_sn, handle->device_sn);
if (ret < 0) {
LOG_ERROR("generate topic name failed");
LOG_ERROR("generate topic name failed\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
@ -495,7 +502,7 @@ int _dsc_mqtt_register_callback(DM_MQTT_Struct_t *handle, DM_Type dm_type, void
ret = IOT_MQTT_Subscribe(handle->mqtt, topic, &sub_params);
if (ret < 0) {
LOG_ERROR("mqtt subscribe failed!");
LOG_ERROR("mqtt subscribe failed!\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
@ -503,19 +510,19 @@ int _dsc_mqtt_register_callback(DM_MQTT_Struct_t *handle, DM_Type dm_type, void
}
DEFINE_DM_CALLBACK(PROPERTY_RESTORE, PropertyRestoreCB)
DEFINE_DM_CALLBACK(PROPERTY_RESTORE, PropertyRestoreCB);
DEFINE_DM_CALLBACK(PROPERTY_POST, CommonReplyCB)
DEFINE_DM_CALLBACK(PROPERTY_POST, CommonReplyCB);
DEFINE_DM_CALLBACK(PROPERTY_SET, PropertySetCB)
DEFINE_DM_CALLBACK(PROPERTY_SET, PropertySetCB);
DEFINE_DM_CALLBACK(PROPERTY_DESIRED_GET, PropertyDesiredGetCB)
DEFINE_DM_CALLBACK(PROPERTY_DESIRED_GET, PropertyDesiredGetCB);
DEFINE_DM_CALLBACK(PROPERTY_DESIRED_DELETE, CommonReplyCB)
DEFINE_DM_CALLBACK(PROPERTY_DESIRED_DELETE, CommonReplyCB);
DEFINE_DM_CALLBACK(EVENT_POST, CommonReplyCB)
DEFINE_DM_CALLBACK(EVENT_POST, CommonReplyCB);
DEFINE_DM_CALLBACK(COMMAND, CommandCB)
DEFINE_DM_CALLBACK(COMMAND, CommandCB);
void *dsc_init(const char *product_sn, const char *device_sn, void *channel, void *context) {
FUNC_ENTRY;
@ -523,7 +530,7 @@ void *dsc_init(const char *product_sn, const char *device_sn, void *channel, voi
DM_MQTT_Struct_t *h_dsc = NULL;
if (NULL == (h_dsc = HAL_Malloc(sizeof(DM_MQTT_Struct_t)))) {
LOG_ERROR("allocate for h_dsc failed");
LOG_ERROR("allocate for h_dsc failed\r\n");
FUNC_EXIT_RC(NULL);
}
@ -547,6 +554,433 @@ int dsc_deinit(void *handle) {
FUNC_EXIT_RC(SUCCESS_RET);
}
static int dm_gen_node_payload(DM_Node_t *dm_node, bool value_key, char *node_payload)
{
int ret = 0;
switch(dm_node->base_type)
{
case TYPE_INT:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": %d}":"\"%s\": %d", dm_node->key, dm_node->value.int32_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "%d", dm_node->value.int32_value);
break;
case TYPE_BOOL:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": %d}":"\"%s\": %d", dm_node->key, dm_node->value.bool_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "%d", dm_node->value.bool_value);
break;
case TYPE_ENUM:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": %d}":"\"%s\": %d", dm_node->key, dm_node->value.enum_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "%d", dm_node->value.enum_value);
break;
case TYPE_FLOAT:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": %f}":"\"%s\": %f", dm_node->key, dm_node->value.float32_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "%f", dm_node->value.float32_value);
break;
case TYPE_DOUBLE:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": %lf}":"\"%s\": %lf", dm_node->key, dm_node->value.float64_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "%lf", dm_node->value.float64_value);
break;
case TYPE_STRING:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": \"%s\"}":"\"%s\": \"%s\"", dm_node->key, dm_node->value.string_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\"", dm_node->value.string_value);
break;
case TYPE_DATE:
if(NULL != dm_node->key)
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": %ld}":"\"%s\": %ld", dm_node->key, dm_node->value.date_value);
else
ret = HAL_Snprintf(node_payload, DM_MSG_REPORT_BUF_LEN, "%ld", dm_node->value.date_value);
break;
default:
LOG_ERROR("illegal node type\r\n");
return FAILURE_RET;
}
if (ret < 0 || ret >= DM_MSG_REPORT_BUF_LEN) {
LOG_ERROR("generate node payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
static int dm_gen_struct_payload(DM_Type_Struct_t *dm_struct, bool value_key, char *struct_payload)
{
int remain_size = 0;
int write_size = 0;
int loop = 0;
int ret = 0;
DM_Node_t *p_node = dm_struct->value;
char *node_payload = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == node_payload) {
LOG_ERROR("allocate for node_payload failed\r\n");
return FAILURE_RET;
}
//结构体中只有一个成员
if(1 == dm_struct->num)
{
ret = dm_gen_node_payload(p_node, false, node_payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_node_payload failed\r\n");
HAL_Free(node_payload);
return ret;
}
if(NULL != dm_struct->key)
{
write_size = HAL_Snprintf(struct_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": {%s}}":"\"%s\": {%s}", dm_struct->key, node_payload);
}
else
{
write_size = HAL_Snprintf(struct_payload, DM_MSG_REPORT_BUF_LEN, "{%s}", node_payload);
}
}
else
{
for(loop = 0; loop < dm_struct->num; loop++)
{
ret = dm_gen_node_payload(&p_node[loop], false, node_payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_node_payload failed\r\n");
HAL_Free(node_payload);
return ret;
}
if(0 == loop)
{
if(NULL != dm_struct->key)
{
write_size = HAL_Snprintf(struct_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": {%s":"\"%s\": {%s", dm_struct->key, node_payload);
remain_size = DM_MSG_REPORT_BUF_LEN - write_size;
}
else
{
write_size = HAL_Snprintf(struct_payload, DM_MSG_REPORT_BUF_LEN, "{%s", node_payload);
remain_size = DM_MSG_REPORT_BUF_LEN - write_size;
}
}
else if(loop == dm_struct->num - 1)
{
if(NULL != dm_struct->key)
{
write_size = HAL_Snprintf(struct_payload + strlen(struct_payload), remain_size, value_key?", %s}}":", %s}", node_payload);
remain_size = remain_size - write_size;
}
else
{
write_size = HAL_Snprintf(struct_payload + strlen(struct_payload), remain_size, ", %s}", node_payload);
remain_size = remain_size - write_size;
}
}
else
{
write_size = HAL_Snprintf(struct_payload + strlen(struct_payload), remain_size, ", %s", node_payload);
remain_size = remain_size - write_size;
}
}
}
HAL_Free(node_payload);
if (write_size < 0 || remain_size < 0) {
LOG_ERROR("generate struct payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
static int dm_gen_array_base_payload(DM_Array_Base_t *dm_array_base, bool value_key, char *array_base_payload)
{
int remain_size = 0;
int write_size = 0;
int loop = 0;
int ret = 0;
DM_Node_t *p_node = dm_array_base->value;
char *node_payload = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == node_payload) {
LOG_ERROR("allocate for node_payload failed\r\n");
return FAILURE_RET;
}
//数组只有一个成员
if(1 == dm_array_base->num)
{
ret = dm_gen_node_payload(p_node, false, node_payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_node_payload failed\r\n");
HAL_Free(node_payload);
return ret;
}
write_size = HAL_Snprintf(array_base_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": [%s]}":"\"%s\": [%s]", dm_array_base->key, node_payload);
}
else
{
for(loop = 0; loop < dm_array_base->num; loop++)
{
ret = dm_gen_node_payload(&p_node[loop], false, node_payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_node_payload failed\r\n");
HAL_Free(node_payload);
return ret;
}
if(0 == loop)
{
write_size = HAL_Snprintf(array_base_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": [%s":"\"%s\": [%s", dm_array_base->key, node_payload);
remain_size = DM_MSG_REPORT_BUF_LEN - write_size;
}
else if(loop == dm_array_base->num - 1)
{
write_size = HAL_Snprintf(array_base_payload + strlen(array_base_payload), remain_size, value_key?", %s]}":", %s]", node_payload);
remain_size = remain_size - write_size;
}
else
{
write_size = HAL_Snprintf(array_base_payload + strlen(array_base_payload), remain_size, ", %s", node_payload);
remain_size = remain_size - write_size;
}
}
}
HAL_Free(node_payload);
if (write_size < 0 || remain_size < 0) {
LOG_ERROR("generate struct payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
static int dm_gen_array_struct_payload(DM_Array_Struct_t *dm_array_struct, bool value_key, char *array_struct_payload)
{
int remain_size = 0;
int write_size = 0;
int loop = 0;
int ret = 0;
DM_Type_Struct_t *p_struct = dm_array_struct->value;
char *struct_payload = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == struct_payload) {
LOG_ERROR("allocate for struct_payload failed\r\n");
return FAILURE_RET;
}
//数组只有一个结构体成员
if(1 == dm_array_struct->num)
{
ret = dm_gen_struct_payload(p_struct, false, struct_payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_struct_payload failed\r\n");
HAL_Free(struct_payload);
return ret;
}
write_size = HAL_Snprintf(array_struct_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": [%s]}":"\"%s\": [%s]", dm_array_struct->key, struct_payload);
}
else
{
for(loop = 0; loop < dm_array_struct->num; loop++)
{
ret = dm_gen_struct_payload(&p_struct[loop], false, struct_payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_struct_payload failed\r\n");
HAL_Free(struct_payload);
return ret;
}
if(0 == loop)
{
write_size = HAL_Snprintf(array_struct_payload, DM_MSG_REPORT_BUF_LEN, value_key?"\"%s\": {\"Value\": [%s":"\"%s\": [%s", dm_array_struct->key, struct_payload);
remain_size = DM_MSG_REPORT_BUF_LEN - write_size;
}
else if(loop == dm_array_struct->num - 1)
{
write_size = HAL_Snprintf(array_struct_payload + strlen(array_struct_payload), remain_size, value_key?", %s]}":", %s]", struct_payload);
remain_size = remain_size - write_size;
}
else
{
write_size = HAL_Snprintf(array_struct_payload + strlen(array_struct_payload), remain_size, ", %s", struct_payload);
remain_size = remain_size - write_size;
}
}
}
HAL_Free(struct_payload);
if (write_size < 0 || remain_size < 0) {
LOG_ERROR("generate array struct payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
static int dm_gen_property_post_payload(DM_Property_t *property, bool value_key, char *property_payload)
{
int ret = 0;
switch(property->parse_type)
{
case TYPE_NODE:
ret = dm_gen_node_payload(property->value.dm_node, value_key, property_payload);
break;
case TYPE_STRUCT:
ret = dm_gen_struct_payload(property->value.dm_struct, value_key, property_payload);
break;
case TYPE_ARRAY_BASE:
ret = dm_gen_array_base_payload(property->value.dm_array_base, value_key, property_payload);
break;
case TYPE_ARRAY_STRUCT:
ret = dm_gen_array_struct_payload(property->value.dm_array_struct, value_key, property_payload);
break;
default:
LOG_ERROR("illegal property type\r\n");
return FAILURE_RET;
}
return ret;
}
static int dm_gen_property_desired_payload(DM_Property_t *property, char *desired_payload)
{
int write_size = 0;
switch(property->parse_type)
{
case TYPE_NODE:
write_size = HAL_Snprintf(desired_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\"", property->value.dm_node->key);
break;
case TYPE_STRUCT:
write_size = HAL_Snprintf(desired_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\"", property->value.dm_struct->key);
break;
case TYPE_ARRAY_BASE:
write_size = HAL_Snprintf(desired_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\"", property->value.dm_array_base->key);
break;
case TYPE_ARRAY_STRUCT:
write_size = HAL_Snprintf(desired_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\"", property->value.dm_array_struct->key);
break;
default:
LOG_ERROR("illegal property type\r\n");
return FAILURE_RET;
}
if (write_size < 0) {
LOG_ERROR("generate property desired payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
static int dm_gen_property_delete_payload(DM_Property_t *property, char *delete_payload)
{
int write_size = 0;
switch(property->parse_type)
{
case TYPE_NODE:
write_size = HAL_Snprintf(delete_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\": {\"version\": %d}", property->value.dm_node->key, property->desired_ver);
break;
case TYPE_STRUCT:
write_size = HAL_Snprintf(delete_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\": {\"version\": %d}", property->value.dm_struct->key, property->desired_ver);
break;
case TYPE_ARRAY_BASE:
write_size = HAL_Snprintf(delete_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\": {\"version\": %d}", property->value.dm_array_base->key, property->desired_ver);
break;
case TYPE_ARRAY_STRUCT:
write_size = HAL_Snprintf(delete_payload, DM_MSG_REPORT_BUF_LEN, "\"%s\": {\"version\": %d}", property->value.dm_array_struct->key, property->desired_ver);
break;
default:
LOG_ERROR("illegal property type\r\n");
return FAILURE_RET;
}
if (write_size < 0) {
LOG_ERROR("generate property delete payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
int dm_gen_properties_payload(DM_Property_t *property, int property_num, DM_Type type, bool value_key, char *properties_payload)
{
int remain_size = 0;
int write_size = 0;
int loop = 0;
int ret = 0;
if (NULL == property || NULL == properties_payload) {
LOG_ERROR("params error!\r\n");
FUNC_EXIT_RC(FAILURE_RET);
}
char *payload = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == payload) {
LOG_ERROR("allocate for payload failed\r\n");
return FAILURE_RET;
}
for(loop = 0; loop < property_num; loop++)
{
switch(type)
{
case PROPERTY_POST:
ret = dm_gen_property_post_payload(&(property[loop]), value_key, payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_property_post_payload failed\r\n");
HAL_Free(payload);
return ret;
}
break;
case PROPERTY_DESIRED_GET:
ret = dm_gen_property_desired_payload(&(property[loop]), payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_property_post_payload failed\r\n");
HAL_Free(payload);
return ret;
}
break;
case PROPERTY_DESIRED_DELETE:
ret = dm_gen_property_delete_payload(&(property[loop]), payload);
if (SUCCESS_RET != ret) {
LOG_ERROR("dm_gen_property_post_payload failed\r\n");
HAL_Free(payload);
return ret;
}
break;
default:
LOG_ERROR("illegal dm type\r\n");
break;
}
if(0 == loop)
{
write_size = HAL_Snprintf(properties_payload, DM_MSG_REPORT_BUF_LEN, "%s", payload);
remain_size = DM_MSG_REPORT_BUF_LEN - write_size;
}
else
{
write_size = HAL_Snprintf(properties_payload + strlen(properties_payload), remain_size, ", %s", payload);
remain_size = remain_size - write_size;
}
}
HAL_Free(payload);
if (write_size < 0 || remain_size < 0) {
LOG_ERROR("dm_gen_properties_payload failed\r\n");
return FAILURE_RET;
}
return SUCCESS_RET;
}
int dm_mqtt_property_report_publish(DM_MQTT_Struct_t *handle, DM_Type type, int request_id, const char *payload) {
FUNC_ENTRY;
@ -555,29 +989,30 @@ int dm_mqtt_property_report_publish(DM_MQTT_Struct_t *handle, DM_Type type, int
char *topic = NULL;
if (NULL == (msg_report = HAL_Malloc(DM_MSG_REPORT_BUF_LEN))) {
LOG_ERROR("allocate for msg_report failed");
goto do_exit;
LOG_ERROR("allocate for msg_report failed\r\n");
return FAILURE_RET;
}
if (NULL == (topic = HAL_Malloc(DM_TOPIC_BUF_LEN))) {
LOG_ERROR("allocate for topic failed");
goto do_exit;
LOG_ERROR("allocate for topic failed\r\n");
HAL_Free(msg_report);
return FAILURE_RET;
}
if (SUCCESS_RET != _dm_mqtt_gen_topic_name(topic, DM_TOPIC_BUF_LEN, handle->upstream_topic_templates[type],
handle->product_sn, handle->device_sn)) {
LOG_ERROR("generate topic failed");
LOG_ERROR("generate topic failed\r\n");
goto do_exit;
}
ret = _dm_mqtt_gen_property_payload(msg_report, DM_MSG_REPORT_BUF_LEN, type, request_id, payload);
if (ret < 0) {
LOG_ERROR("generate msg_report failed");
LOG_ERROR("generate msg_report failed\r\n");
ret = FAILURE_RET;
goto do_exit;
}
ret = _dm_mqtt_publish(handle, topic, 1, msg_report);
if (ret < 0) {
LOG_ERROR("mqtt publish msg failed");
LOG_ERROR("mqtt publish msg failed\r\n");
}
do_exit:
@ -587,6 +1022,37 @@ do_exit:
FUNC_EXIT_RC(ret);
}
int dm_mqtt_property_report_publish_Ex(DM_MQTT_Struct_t *handle, DM_Type type, int request_id, DM_Property_t *property, int property_num) {
FUNC_ENTRY;
int ret = 0;
char *payload = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == payload) {
LOG_ERROR("allocate for payload failed\r\n");
return FAILURE_RET;
}
ret = dm_gen_properties_payload(property, property_num, type, true, payload);
if(FAILURE_RET == ret)
{
LOG_ERROR("dm_gen_properties_payload failed\r\n");
HAL_Free(payload);
return FAILURE_RET;
}
ret = dm_mqtt_property_report_publish(handle, type, request_id, payload);
if(FAILURE_RET == ret)
{
LOG_ERROR("dm_mqtt_property_report_publish failed\r\n");
HAL_Free(payload);
return FAILURE_RET;
}
HAL_Free(payload);
return ret;
}
int dm_mqtt_event_publish(DM_MQTT_Struct_t *handle, int request_id, const char *identifier, const char *payload) {
FUNC_ENTRY;
@ -595,28 +1061,28 @@ int dm_mqtt_event_publish(DM_MQTT_Struct_t *handle, int request_id, const char *
char *topic = NULL;
if (NULL == (msg_report = HAL_Malloc(DM_EVENT_POST_BUF_LEN))) {
LOG_ERROR("allocate for msg_report failed");
LOG_ERROR("allocate for msg_report failed\r\n");
goto do_exit;
}
if (NULL == (topic = HAL_Malloc(DM_TOPIC_BUF_LEN))) {
LOG_ERROR("allocate for topic failed");
LOG_ERROR("allocate for topic failed\r\n");
goto do_exit;
}
if (SUCCESS_RET != _dm_mqtt_gen_topic_name(topic, DM_TOPIC_BUF_LEN, handle->upstream_topic_templates[EVENT_POST],
handle->product_sn, handle->device_sn)) {
LOG_ERROR("generate topic failed");
LOG_ERROR("generate topic failed\r\n");
goto do_exit;
}
ret = _dm_mqtt_gen_event_payload(msg_report, DM_EVENT_POST_BUF_LEN, request_id, identifier, payload);
if (ret < 0) {
LOG_ERROR("generate msg_report failed");
LOG_ERROR("generate msg_report failed\r\n");
goto do_exit;
}
ret = _dm_mqtt_publish(handle, topic, 1, msg_report);
if (ret < 0) {
LOG_ERROR("mqtt publish msg failed");
LOG_ERROR("mqtt publish msg failed\r\n");
}
do_exit:
@ -625,3 +1091,36 @@ do_exit:
FUNC_EXIT_RC(ret);
}
int dm_mqtt_event_publish_Ex(DM_MQTT_Struct_t *handle, int request_id, DM_Event_t *event) {
FUNC_ENTRY;
int ret = 0;
DM_Property_t *p_property = event->dm_property;
char *properties_payload = HAL_Malloc(DM_MSG_REPORT_BUF_LEN);
if (NULL == properties_payload) {
LOG_ERROR("allocate for properties_payload failed\r\n");
return FAILURE_RET;
}
ret = dm_gen_properties_payload(p_property, event->property_num, PROPERTY_POST, false, properties_payload);
if (FAILURE_RET == ret) {
LOG_ERROR("dm_gen_properties_payload failed\r\n");
HAL_Free(properties_payload);
return FAILURE_RET;
}
ret = dm_mqtt_event_publish(handle, request_id, event->event_identy, properties_payload);
if(FAILURE_RET == ret)
{
LOG_ERROR("dm_mqtt_property_report_publish failed\r\n");
HAL_Free(properties_payload);
return FAILURE_RET;
}
HAL_Free(properties_payload);
return ret;
}

View File

@ -22,16 +22,18 @@ extern "C" {
#define TYPE_FIELD "Method"
#define MD5_FIELD "Payload.MD5"
#define MODULE_FIELD "Payload.Module"
#define VERSION_FIELD "Payload.Version"
#define URL_FIELD "Payload.URL"
#define SIZE_FIELD "Payload.Size"
#define UPDATE_FIRMWARE_METHOD "update_firmware"
#define CANCEL_UPDATE_METHOD "cancel_update"
#define REPORT_PROGRESS_MSG_TEMPLATE "{\"Method\": \"report_progress\", \"Payload\": {\"State\":\"%s\", \"Percent\":%d}}"
#define REPORT_SUCCESS_MSG_TEMPLATE "{\"Method\": \"report_success\", \"Payload\":{\"Version\":\"%s\"}}"
#define REPORT_FAIL_MSG_TEMPLATE "{\"Method\": \"report_fail\", \"Payload\": {\"ErrCode\": %d}}"
#define REPORT_VERSION_MSG_TEMPLATE "{\"Method\": \"report_version\", \"Payload\":{\"Version\":\"%s\"}}"
#define REQUEST_FIRMWARE_MSG_TEMPLATE "{\"Method\": \"request_firmware\", \"Payload\":{\"Version\":\"%s\"}}"
#define REPORT_PROGRESS_MSG_TEMPLATE "{\"Method\": \"report_progress\", \"Payload\": {\"State\":\"%s\", \"Percent\":%d, \"Module\":\"%s\", \"Version\":\"%s\" }}"
#define REPORT_SUCCESS_MSG_TEMPLATE "{\"Method\": \"report_success\", \"Payload\":{\"Module\":\"%s\", \"Version\":\"%s\"}}"
#define REPORT_FAIL_MSG_TEMPLATE "{\"Method\": \"report_fail\", \"Payload\": {\"ErrCode\": %d, \"Module\":\"%s\", \"Version\":\"%s\"}}"
#define REPORT_VERSION_MSG_TEMPLATE "{\"Method\": \"report_version\", \"Payload\":{\"Module\":\"%s\", \"Version\":\"%s\"}}"
#define REQUEST_FIRMWARE_MSG_TEMPLATE "{\"Method\": \"request_firmware\", \"Payload\":{\"Module\":\"%s\", \"Version\":\"%s\"}}"
#define OTA_VERSION_STR_LEN_MIN (1)
#define OTA_VERSION_STR_LEN_MAX (32)

View File

@ -21,43 +21,42 @@ extern "C" {
#endif
#include <stdint.h>
#include "ota_config.h"
#include "uiot_export_ota.h"
typedef enum {
OTA_REPORT_UNDEFINED_ERROR = -6,
OTA_REPORT_FIRMWARE_BURN_FAILED = -5,
OTA_REPORT_MD5_MISMATCH = -4,
OTA_REPORT_DOWNLOAD_TIMEOUT = -3,
OTA_REPORT_SIGNATURE_EXPIRED = -2,
OTA_REPORT_FIRMWARE_NOT_EXIST = -1,
OTA_REPORT_NONE = 0,
OTA_REPORT_DOWNLOADING = 1,
OTA_REPORT_BURNING = 2,
OTA_REPORT_SUCCESS = 3,
OTA_REQUEST_FIRMWARE = 4,
OTA_REPORT_VERSION = 5,
} IOT_OTA_UpstreamMsgType;
/* OTA状态 */
typedef enum {
OTA_STATE_UNINITED = 0, /* 未初始化 */
OTA_STATE_INITED, /* 初始化完成 */
OTA_STATE_FETCHING, /* 正在下载固件 */
OTA_STATE_FETCHED, /* 固件下载完成 */
OTA_STATE_DISCONNECTED /* 连接已经断开 */
} IOT_OTA_State;
#include "utils_httpc.h"
#include "utils_list.h"
// OTA Signal Channel
typedef void (*OnOTAMessageCallback)(void *pContext, const char *msg, uint32_t msgLen);
typedef struct{
char *payload; // MQTT 消息负载
size_t payload_len; // MQTT 消息负载长度
}OTA_UPLOAD_Msg;
typedef struct {
const char *url;
http_client_t http; /* http client */
http_client_data_t http_data; /* http client data */
} OTA_Http_Client;
void *osc_init(const char *product_sn, const char *device_sn, void *channel, OnOTAMessageCallback callback,
void *context);
/* OSC, OTA signal channel */
typedef struct {
void *mqtt;
const char *product_sn;
const char *device_sn;
char topic_upgrade[OTA_TOPIC_BUF_LEN];
OnOTAMessageCallback msg_callback;
List *msg_list; /* recv update msg */
void *msg_mutex; /* mutex for msg list */
void *context;
} OTA_MQTT_Struct_t;
int osc_deinit(void *handle);
int osc_report_progress(void *handle, const char *msg);
@ -84,10 +83,12 @@ void ota_lib_md5_deinit(void *md5);
int ota_lib_get_msg_type(char *json, char **type);
int ota_lib_get_params(char *json, char **url, char **version, char **md5,
int ota_lib_get_msg_module_ver(char *json, char **module, char **ver);
int ota_lib_get_params(char *json, char **url, char **module, char **download_name, char **version, char **md5,
uint32_t *fileSize);
int ota_lib_gen_upstream_msg(char *buf, size_t bufLen, const char *version, int progress,
int ota_lib_gen_upstream_msg(char *buf, size_t bufLen, const char *module, const char *version, int progress,
IOT_OTA_UpstreamMsgType reportType);
#ifdef __cplusplus

View File

@ -61,33 +61,65 @@ static void print_progress(uint32_t percent)
progress_sign[sizeof(progress_sign) - 1] = '\0';
HAL_Printf("Download: [%s] %d%%\r\n", progress_sign, percent);
LOG_INFO("Download: [%s] %d%%\r\n", progress_sign, percent);
}
typedef struct {
uint32_t id; /* message id */
IOT_OTA_State state; /* OTA state */
uint32_t size_last_fetched; /* size of last downloaded */
uint32_t size_fetched; /* size of already downloaded */
uint32_t size_file; /* size of file */
static void _ota_push_upload_msg(void *handle, const char *msg, uint32_t msg_len)
{
OTA_Struct_t *h_ota = (OTA_Struct_t *) handle;
OTA_MQTT_Struct_t *h_osc = h_ota->ch_signal;
char *url; /* point to URL */
char *version; /* point to version */
char *md5sum; /* MD5 string */
OTA_UPLOAD_Msg *push_msg = (OTA_UPLOAD_Msg *)HAL_Malloc(sizeof(OTA_UPLOAD_Msg));
if (NULL == (push_msg->payload = HAL_Malloc(msg_len + 1))) {
LOG_ERROR("HAL_Malloc failed!");
return;
}
HAL_Snprintf(push_msg->payload, msg_len + 1, "%s", msg);
push_msg->payload_len = msg_len;
ListNode *node = list_node_new((void *)push_msg);
if (NULL == node)
{
LOG_ERROR("run list_node_new is error!\n");
HAL_Free(push_msg->payload);
HAL_Free(push_msg);
return;
}
HAL_MutexLock(h_osc->msg_mutex);
list_rpush(h_osc->msg_list, node);
HAL_MutexUnlock(h_osc->msg_mutex);
return;
}
void *md5; /* MD5 handle */
void *ch_signal; /* channel handle of signal exchanged with OTA server */
void *ch_fetch; /* channel handle of download */
static void _ota_pop_upload_msg(void *handle)
{
OTA_Struct_t *h_ota = (OTA_Struct_t *) handle;
OTA_MQTT_Struct_t *h_osc = h_ota->ch_signal;
int err; /* last error code */
if(h_osc->msg_list->len > 0)
{
HAL_MutexLock(h_osc->msg_mutex);
ListNode *node = list_lpop(h_osc->msg_list);
HAL_MutexUnlock(h_osc->msg_mutex);
OTA_UPLOAD_Msg *pop_msg = node->val;
h_osc->msg_callback(h_ota, pop_msg->payload, pop_msg->payload_len);
HAL_Free(pop_msg->payload);
HAL_Free(pop_msg);
HAL_Free(node);
return;
}
return;
}
Timer report_timer;
} OTA_Struct_t;
static void _ota_callback(void *pContext, const char *msg, uint32_t msg_len) {
static void _ota_callback(void *pContext, const char *msg, uint32_t msg_len)
{
char *msg_method = NULL;
char *msg_str = NULL;
char *msg_module = NULL;
char *msg_ver = NULL;
OTA_Struct_t *h_ota = (OTA_Struct_t *) pContext;
if (h_ota == NULL || msg == NULL) {
@ -95,11 +127,6 @@ static void _ota_callback(void *pContext, const char *msg, uint32_t msg_len) {
return;
}
if (h_ota->state == OTA_STATE_FETCHING) {
LOG_INFO("In OTA_STATE_FETCHING state");
return;
}
if (NULL == (msg_str = HAL_Malloc(msg_len + 1))) {
LOG_ERROR("HAL_Malloc failed!");
return;
@ -112,32 +139,66 @@ static void _ota_callback(void *pContext, const char *msg, uint32_t msg_len) {
goto do_exit;
}
if (strcmp(msg_method, UPDATE_FIRMWARE_METHOD) != 0) {
LOG_ERROR("Message type error! type: %s", msg_method);
if((NULL == h_ota->ch_fetch) && (0 == strcmp(msg_method, CANCEL_UPDATE_METHOD)))
{
LOG_ERROR("download is canceled!");
goto do_exit;
}
if (SUCCESS_RET != ota_lib_get_params(msg_str, &h_ota->url, &h_ota->version,
&h_ota->md5sum, &h_ota->size_file)) {
LOG_ERROR("Get firmware parameter failed");
goto do_exit;
if (0 == strcmp(msg_method, UPDATE_FIRMWARE_METHOD))
{
/* downloading, push update msg to list */
if (h_ota->state == OTA_STATE_FETCHING) {
LOG_INFO("In OTA_STATE_FETCHING state");
_ota_push_upload_msg(h_ota, msg_str, msg_len);
goto do_exit;
}
if (SUCCESS_RET != ota_lib_get_params(msg_str, &h_ota->url, &h_ota->module, &h_ota->download_name, &h_ota->version, &h_ota->md5sum, &h_ota->size_file)) {
LOG_ERROR("Get firmware parameter failed");
goto do_exit;
}
if (NULL == (h_ota->ch_fetch = ofc_init(h_ota->url))) {
LOG_ERROR("Initialize fetch module failed");
goto do_exit;
}
if (SUCCESS_RET != ofc_connect(h_ota->ch_fetch)) {
LOG_ERROR("Connect fetch module failed");
h_ota->state = OTA_STATE_DISCONNECTED;
goto do_exit;
}
h_ota->state = OTA_STATE_FETCHING;
if(SUCCESS_RET != IOT_OTA_fw_download(h_ota)) {
LOG_ERROR("download file failed");
h_ota->state = OTA_STATE_DISCONNECTED;
}
/* download over, pop first pushed msg to download */
_ota_pop_upload_msg(h_ota);
}
else if(0 == strcmp(msg_method, CANCEL_UPDATE_METHOD))
{
if (SUCCESS_RET != ota_lib_get_msg_module_ver(msg_str, &msg_module, &msg_ver)) {
LOG_ERROR("Get message module failed!");
HAL_Free(msg_module);
HAL_Free(msg_ver);
goto do_exit;
}
if (NULL == (h_ota->ch_fetch = ofc_init(h_ota->url))) {
LOG_ERROR("Initialize fetch module failed");
goto do_exit;
if((0 == strcmp(msg_module, h_ota->module)) && (0 == strcmp(msg_ver, h_ota->version)))
{
OTA_Http_Client *h_ofc = (OTA_Http_Client *)h_ota->ch_fetch;
http_client_close(&h_ofc->http);
h_ota->state = OTA_STATE_DISCONNECTED;
}
HAL_Free(msg_module);
HAL_Free(msg_ver);
}
if (SUCCESS_RET != ofc_connect(h_ota->ch_fetch)) {
LOG_ERROR("Connect fetch module failed");
h_ota->state = OTA_STATE_DISCONNECTED;
goto do_exit;
}
h_ota->state = OTA_STATE_FETCHING;
IOT_OTA_fw_download(h_ota);
do_exit:
HAL_Free(msg_str);
HAL_Free(msg_method);
@ -171,7 +232,7 @@ int IOT_OTA_ReportProgress(void *handle, int progress, IOT_OTA_ProgressState sta
return ERR_OTA_NO_MEMORY;
}
ret = ota_lib_gen_upstream_msg(msg_report, OTA_UPSTREAM_MSG_BUF_LEN, h_ota->version, progress, (IOT_OTA_UpstreamMsgType)state);
ret = ota_lib_gen_upstream_msg(msg_report, OTA_UPSTREAM_MSG_BUF_LEN, h_ota->module, h_ota->version, progress, (IOT_OTA_UpstreamMsgType)state);
if (SUCCESS_RET != ret) {
LOG_ERROR("generate reported message failed");
h_ota->err = ret;
@ -193,7 +254,7 @@ do_exit:
}
static int send_upstream_msg_with_version(void *handle, const char *version, IOT_OTA_UpstreamMsgType reportType)
static int send_upstream_msg_with_version(void *handle, const char *module, const char *version, IOT_OTA_UpstreamMsgType reportType)
{
POINTER_VALID_CHECK(handle, ERR_OTA_INVALID_PARAM);
POINTER_VALID_CHECK(version, ERR_OTA_INVALID_PARAM);
@ -221,7 +282,7 @@ static int send_upstream_msg_with_version(void *handle, const char *version, IOT
return ERR_OTA_NO_MEMORY;
}
ret = ota_lib_gen_upstream_msg(msg_upstream, OTA_UPSTREAM_MSG_BUF_LEN, version, 0, reportType);
ret = ota_lib_gen_upstream_msg(msg_upstream, OTA_UPSTREAM_MSG_BUF_LEN, module, version, 0, reportType);
if (SUCCESS_RET != ret) {
LOG_ERROR("generate upstream message failed");
h_ota->err = ret;
@ -242,7 +303,6 @@ do_exit:
return ret;
}
void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signal)
{
POINTER_VALID_CHECK(product_sn, NULL);
@ -263,7 +323,7 @@ void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signa
LOG_ERROR("initialize signal channel failed");
goto do_exit;
}
h_ota->md5 = ota_lib_md5_init();
if (NULL == h_ota->md5) {
LOG_ERROR("initialize md5 failed");
@ -301,7 +361,7 @@ int IOT_OTA_Destroy(void *handle)
return FAILURE_RET;
}
osc_deinit(h_ota->ch_signal);
osc_deinit(h_ota->ch_signal);
ofc_deinit(h_ota->ch_fetch);
ota_lib_md5_deinit(h_ota->md5);
@ -309,6 +369,10 @@ int IOT_OTA_Destroy(void *handle)
HAL_Free(h_ota->url);
}
if (NULL != h_ota->module) {
HAL_Free(h_ota->module);
}
if (NULL != h_ota->version) {
HAL_Free(h_ota->version);
}
@ -317,6 +381,10 @@ int IOT_OTA_Destroy(void *handle)
HAL_Free(h_ota->md5sum);
}
if (NULL != h_ota->download_name) {
HAL_Free(h_ota->download_name);
}
HAL_Free(h_ota);
return SUCCESS_RET;
}
@ -324,35 +392,60 @@ int IOT_OTA_Destroy(void *handle)
void IOT_OTA_Clear(void *handle)
{
OTA_Struct_t *h_ota = (OTA_Struct_t *)handle;
memset(h_ota->url, 0, strlen(h_ota->url));
memset(h_ota->version, 0, strlen(h_ota->version));
memset(h_ota->md5sum, 0, strlen(h_ota->md5sum));
ofc_deinit(h_ota->ch_fetch);
if (NULL != h_ota->url) {
memset(h_ota->url, 0, strlen(h_ota->url));
}
if (NULL != h_ota->module) {
memset(h_ota->module, 0, strlen(h_ota->module));
}
if(NULL != h_ota->download_name){
memset(h_ota->download_name, 0, strlen(h_ota->download_name));
}
if (NULL != h_ota->version) {
memset(h_ota->version, 0, strlen(h_ota->version));
}
if (NULL != h_ota->md5sum) {
memset(h_ota->md5sum, 0, strlen(h_ota->md5sum));
}
h_ota->size_last_fetched = 0;
h_ota->size_fetched = 0;
h_ota->size_file = 0;
ota_lib_md5_deinit(h_ota->md5);
ota_lib_md5_deinit(h_ota->md5);
h_ota->md5 = ota_lib_md5_init();
h_ota->state = OTA_STATE_INITED;
return;
}
int IOT_OTA_ReportVersion(void *handle, const char *version)
int IOT_OTA_ReportVersion(void *handle, const char *module, const char *version)
{
return send_upstream_msg_with_version(handle, version, OTA_REPORT_VERSION);
return send_upstream_msg_with_version(handle, module, version, OTA_REPORT_VERSION);
}
int IOT_OTA_RequestFirmware(void *handle, const char *version)
int IOT_OTA_RequestFirmware(void *handle, const char *module, const char *version)
{
return send_upstream_msg_with_version(handle, version, OTA_REQUEST_FIRMWARE);
return send_upstream_msg_with_version(handle, module, version, OTA_REQUEST_FIRMWARE);
}
int IOT_OTA_ReportSuccess(void *handle, const char *version)
{
return send_upstream_msg_with_version(handle, version, OTA_REPORT_SUCCESS);
{
OTA_Struct_t *h_ota = (OTA_Struct_t *)handle;
if(h_ota->fetch_callback_func != NULL)
{
h_ota->fetch_callback_func(handle, OTA_REPORT_SUCCESS);
}
return send_upstream_msg_with_version(handle, h_ota->module, version, OTA_REPORT_SUCCESS);
}
int IOT_OTA_ReportFail(void *handle, IOT_OTA_ReportErrCode err_code)
{
POINTER_VALID_CHECK(handle, ERR_OTA_INVALID_PARAM);
@ -373,7 +466,7 @@ int IOT_OTA_ReportFail(void *handle, IOT_OTA_ReportErrCode err_code)
return ERR_OTA_NO_MEMORY;
}
ret = ota_lib_gen_upstream_msg(msg_upstream, OTA_UPSTREAM_MSG_BUF_LEN, "", 0, (IOT_OTA_UpstreamMsgType)err_code);
ret = ota_lib_gen_upstream_msg(msg_upstream, OTA_UPSTREAM_MSG_BUF_LEN, h_ota->module, "", 0, (IOT_OTA_UpstreamMsgType)err_code);
if (SUCCESS_RET != ret) {
LOG_ERROR("generate upstream message failed");
h_ota->err = ret;
@ -387,6 +480,9 @@ int IOT_OTA_ReportFail(void *handle, IOT_OTA_ReportErrCode err_code)
goto do_exit;
}
if(h_ota->fetch_callback_func != NULL)
h_ota->fetch_callback_func(handle, (IOT_OTA_UpstreamMsgType)err_code);
do_exit:
if (NULL != msg_upstream) {
HAL_Free(msg_upstream);
@ -432,6 +528,14 @@ int IOT_OTA_IsFetchFinish(void *handle)
return (OTA_STATE_FETCHED == h_ota->state);
}
int IOT_OTA_Yield(void *handle, uint32_t timeout_ms)
{
POINTER_VALID_CHECK(handle, FAILURE_RET);
OTA_Struct_t *h_ota = (OTA_Struct_t*) handle;
return IOT_MQTT_Yield(((OTA_MQTT_Struct_t *)h_ota->ch_signal)->mqtt, timeout_ms);
}
int IOT_OTA_FetchYield(void *handle, char *buf, size_t buf_len, size_t range_len, uint32_t timeout_s)
{
@ -453,7 +557,7 @@ int IOT_OTA_FetchYield(void *handle, char *buf, size_t buf_len, size_t range_len
/* fetch fail,try again utill 5 time */
ret = ofc_fetch(h_ota->ch_fetch, h_ota->size_fetched ,buf, buf_len, range_len, timeout_s);
/* range download send request too often maybe cutdown by server, need reconnect and continue to download. */
if(ret == ERR_HTTP_CONN_ERROR) {
if((ret == ERR_HTTP_CONN_ERROR) && (h_ota->state != OTA_STATE_DISCONNECTED)) {
ofc_deinit(h_ota->ch_fetch);
h_ota->ch_fetch = ofc_init(h_ota->url);
ofc_connect(h_ota->ch_fetch);
@ -610,37 +714,26 @@ int IOT_OTA_fw_download(void *handle)
{
int ret = 0;
int file_size = 0, length, firmware_valid, total_length = 0;
uint8_t *buffer_read = RT_NULL;
const struct fal_partition * dl_part = RT_NULL;
char *buffer_read = NULL;
OTA_Struct_t * h_ota = (OTA_Struct_t *) handle;
void * download_handle = NULL;
// 用于存放云端下发的固件版本
char msg_version[33];
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_FILE_SIZE, &file_size, 4);
/* Get download partition information and erase download partition data */
if ((dl_part = fal_partition_find("download")) == RT_NULL)
download_handle = HAL_Download_Init(h_ota->download_name);
if(download_handle == NULL)
{
LOG_ERROR("Firmware download failed! Partition (%s) find error!", "download");
ret = -RT_ERROR;
ret = FAILURE_RET;
goto __exit;
}
LOG_INFO("Start erase flash (%s) partition!", dl_part->name);
if (fal_partition_erase(dl_part, 0, file_size) < 0)
{
LOG_ERROR("Firmware download failed! Partition (%s) erase error!", dl_part->name);
ret = -RT_ERROR;
goto __exit;
}
LOG_INFO("Erase flash (%s) partition success!", dl_part->name);
buffer_read = (uint8_t *)HAL_Malloc(HTTP_OTA_BUFF_LEN);
if (buffer_read == RT_NULL)
buffer_read = (char *)HAL_Malloc(HTTP_OTA_BUFF_LEN);
if (buffer_read == NULL)
{
LOG_ERROR("No memory for http ota!");
ret = -RT_ERROR;
ret = FAILURE_RET;
goto __exit;
}
memset(buffer_read, 0x00, HTTP_OTA_BUFF_LEN);
@ -652,25 +745,26 @@ int IOT_OTA_fw_download(void *handle)
if (length > 0)
{
/* Write the data to the corresponding partition address */
if (fal_partition_write(dl_part, total_length, buffer_read, length) < 0)
{
LOG_ERROR("Firmware download failed! Partition (%s) write data error!", dl_part->name);
ret = -RT_ERROR;
if(HAL_Download_Write(download_handle, total_length, buffer_read, length) == FAILURE_RET){
ret = FAILURE_RET;
goto __exit;
}
total_length += length;
//wait cancel cmd
IOT_OTA_Yield(handle, 100);
}
else
{
LOG_ERROR("Exit: server return err (%d)!", length);
ret = -RT_ERROR;
ret = ERR_OTA_FETCH_FAILED;
goto __exit;
}
} while (!IOT_OTA_IsFetchFinish(h_ota));
if (total_length == file_size)
{
ret = RT_EOK;
ret = SUCCESS_RET;
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_CHECK_FIRMWARE, &firmware_valid, 4);
if (0 == firmware_valid) {
LOG_ERROR("The firmware is invalid");
@ -681,23 +775,18 @@ int IOT_OTA_fw_download(void *handle)
IOT_OTA_Ioctl(h_ota, OTA_IOCTL_VERSION, msg_version, 33);
IOT_OTA_ReportSuccess(h_ota, msg_version);
}
if(HAL_Download_End(download_handle))
ret = FAILURE_RET;
LOG_INFO("Download firmware to flash success.");
LOG_INFO("System now will restart...");
rt_thread_delay(rt_tick_from_millisecond(5));
/* Reset the device, Start new firmware */
extern void rt_hw_cpu_reset(void);
rt_hw_cpu_reset();
}
__exit:
if (buffer_read != RT_NULL)
HAL_Free(buffer_read);
if (buffer_read != NULL)
HAL_Free(buffer_read);
IOT_OTA_Clear(h_ota);
return ret;
}

View File

@ -21,15 +21,6 @@
#include "ca.h"
#include "utils_httpc.h"
typedef struct {
const char *url;
http_client_t http; /* http client */
http_client_data_t http_data; /* http client data */
} OTA_Http_Client;
void *ofc_init(const char *url)
{
FUNC_ENTRY;

View File

@ -64,16 +64,42 @@ int ota_lib_get_msg_type(char *json, char **type) {
FUNC_EXIT_RC(SUCCESS_RET);
}
int ota_lib_get_msg_module_ver(char *json, char **module, char **ver) {
FUNC_ENTRY;
int ota_lib_get_params(char *json, char **url, char **version, char **md5,
if (NULL == (*module = LITE_json_value_of(MODULE_FIELD, json))) {
LOG_ERROR("get value of module key failed");
FUNC_EXIT_RC(ERR_OTA_GENERAL_FAILURE);
}
if (NULL == (*ver = LITE_json_value_of(VERSION_FIELD, json))) {
LOG_ERROR("get value of ver key failed");
FUNC_EXIT_RC(ERR_OTA_GENERAL_FAILURE);
}
FUNC_EXIT_RC(SUCCESS_RET);
}
int ota_lib_get_params(char *json, char **url, char **module, char **download_name, char **version, char **md5,
uint32_t *fileSize) {
FUNC_ENTRY;
char *module_str;
char *file_size_str;
char *version_str;
char *url_str;
char *md5_str;
/* get module */
if (NULL == (module_str = LITE_json_value_of(MODULE_FIELD, json))) {
LOG_ERROR("get value of module key failed");
FUNC_EXIT_RC(ERR_OTA_GENERAL_FAILURE);
}
if (NULL != *module) {
HAL_Free(*module);
}
*module = module_str;
/* get version */
if (NULL == (version_str = LITE_json_value_of(VERSION_FIELD, json))) {
LOG_ERROR("get value of version key failed");
@ -94,6 +120,8 @@ int ota_lib_get_params(char *json, char **url, char **version, char **md5,
}
*url = url_str;
*download_name = HAL_Download_Name_Set((void*)url_str);
/* get md5 */
if (NULL == (md5_str = LITE_json_value_of(MD5_FIELD, json))) {
LOG_ERROR("get value of md5 failed");
@ -119,7 +147,7 @@ int ota_lib_get_params(char *json, char **url, char **version, char **md5,
FUNC_EXIT_RC(SUCCESS_RET);
}
int ota_lib_gen_upstream_msg(char *buf, size_t bufLen, const char *version, int progress,
int ota_lib_gen_upstream_msg(char *buf, size_t bufLen, const char *module, const char *version, int progress,
IOT_OTA_UpstreamMsgType reportType) {
FUNC_ENTRY;
@ -136,23 +164,23 @@ int ota_lib_gen_upstream_msg(char *buf, size_t bufLen, const char *version, int
break;
case OTA_REPORT_DOWNLOADING:
ret = HAL_Snprintf(buf, bufLen, REPORT_PROGRESS_MSG_TEMPLATE, "downloading", progress);
ret = HAL_Snprintf(buf, bufLen, REPORT_PROGRESS_MSG_TEMPLATE, "downloading", progress, module, version);
break;
case OTA_REPORT_BURNING:
ret = HAL_Snprintf(buf, bufLen, REPORT_PROGRESS_MSG_TEMPLATE, "burning", progress);
ret = HAL_Snprintf(buf, bufLen, REPORT_PROGRESS_MSG_TEMPLATE, "burning", progress, module, version);
break;
case OTA_REPORT_SUCCESS:
ret = HAL_Snprintf(buf, bufLen, REPORT_SUCCESS_MSG_TEMPLATE, version);
ret = HAL_Snprintf(buf, bufLen, REPORT_SUCCESS_MSG_TEMPLATE, module, version);
break;
case OTA_REQUEST_FIRMWARE:
ret = HAL_Snprintf(buf, bufLen, REQUEST_FIRMWARE_MSG_TEMPLATE, version);
ret = HAL_Snprintf(buf, bufLen, REQUEST_FIRMWARE_MSG_TEMPLATE, module, version);
break;
case OTA_REPORT_VERSION:
ret = HAL_Snprintf(buf, bufLen, REPORT_VERSION_MSG_TEMPLATE, version);
ret = HAL_Snprintf(buf, bufLen, REPORT_VERSION_MSG_TEMPLATE, module, version);
break;
default: FUNC_EXIT_RC(ERR_OTA_GENERAL_FAILURE);

View File

@ -23,16 +23,6 @@
#include "ota_config.h"
#include "ota_internal.h"
/* OSC, OTA signal channel */
typedef struct {
void *mqtt;
const char *product_sn;
const char *device_sn;
char topic_upgrade[OTA_TOPIC_BUF_LEN];
OnOTAMessageCallback msg_callback;
void *context;
} OTA_MQTT_Struct_t;
static int _ota_mqtt_gen_topic_name(char *buf, size_t buf_len, const char *ota_topic_type, const char *product_sn,
const char *device_sn)
{
@ -119,6 +109,10 @@ void *osc_init(const char *product_sn, const char *device_sn, void *channel, OnO
h_osc->device_sn = device_sn;
h_osc->msg_callback = callback;
h_osc->context = context;
h_osc->msg_list = list_new();
h_osc->msg_mutex = HAL_MutexCreate();
if (h_osc->msg_mutex == NULL)
goto do_exit;
/* subscribe the OTA topic: "/$system/$(product_sn)/$(device_sn)/ota/downstream" */
ret = _ota_mqtt_gen_topic_name(h_osc->topic_upgrade, OTA_TOPIC_BUF_LEN, OTA_DOWNSTREAM_TOPIC_TYPE, product_sn,
@ -153,6 +147,11 @@ int osc_deinit(void *handle)
{
FUNC_ENTRY;
OTA_MQTT_Struct_t *h_osc = handle;
list_destroy(h_osc->msg_list);
HAL_MutexDestroy(h_osc->msg_mutex);
if (NULL != handle) {
HAL_Free(handle);
}

View File

@ -134,7 +134,7 @@ typedef enum {
{\
HAL_Printf("DEBUG: %s L#%d ", __func__, __LINE__); \
HAL_Printf(__VA_ARGS__); \
HAL_Printf("\n"); \
HAL_Printf("\r\n"); \
}
#else
#define LOG_DEBUG(...)
@ -149,7 +149,7 @@ typedef enum {
#define LOG_INFO(...) \
{\
HAL_Printf(__VA_ARGS__); \
HAL_Printf("\n"); \
HAL_Printf("\r\n"); \
}
#else
#define LOG_INFO(...)
@ -165,7 +165,7 @@ typedef enum {
{ \
HAL_Printf("WARN: %s L#%d ", __func__, __LINE__); \
HAL_Printf(__VA_ARGS__); \
HAL_Printf("\n"); \
HAL_Printf("\r\n"); \
}
#else
#define LOG_WARN(...)
@ -181,7 +181,7 @@ typedef enum {
{ \
HAL_Printf("ERROR: %s L#%d ", __func__, __LINE__); \
HAL_Printf(__VA_ARGS__); \
HAL_Printf("\n"); \
HAL_Printf("\r\n"); \
}
#else
#define LOG_ERROR(...)
@ -190,16 +190,16 @@ typedef enum {
#ifdef ENABLE_IOT_TRACE
#define FUNC_ENTRY \
{\
HAL_Printf("FUNC_ENTRY: %s L#%d \n", __func__, __LINE__); \
HAL_Printf("FUNC_ENTRY: %s L#%d \r\n", __func__, __LINE__); \
}
#define FUNC_EXIT \
{\
HAL_Printf("FUNC_EXIT: %s L#%d \n", __func__, __LINE__); \
HAL_Printf("FUNC_EXIT: %s L#%d \r\n", __func__, __LINE__); \
return; \
}
#define FUNC_EXIT_RC(x) \
{\
HAL_Printf("FUNC_EXIT: %s L#%d Return Code : %d \n", __func__, __LINE__, x); \
HAL_Printf("FUNC_EXIT: %s L#%d Return Code : %d \r\n", __func__, __LINE__, x); \
return x; \
}
#else

View File

@ -34,11 +34,87 @@ typedef enum _dm_type {
DM_TYPE_MAX
}DM_Type;
typedef enum{
TYPE_INT,
TYPE_FLOAT,
TYPE_DOUBLE,
TYPE_BOOL,
TYPE_ENUM,
TYPE_STRING,
TYPE_DATE,
} DM_Base_Type;
typedef enum{
TYPE_NODE,
TYPE_STRUCT,
TYPE_ARRAY_BASE,
TYPE_ARRAY_STRUCT,
} DM_Parse_Type;
typedef union{
int int32_value;
float float32_value;
double float64_value;
bool bool_value;
int enum_value;
char *string_value;
long date_value;
}DM_Base_Value_U;
typedef struct{
DM_Base_Type base_type;
char *key;
DM_Base_Value_U value;
} DM_Node_t;
typedef struct{
char *key;
DM_Node_t *value;
int num;
} DM_Type_Struct_t;
typedef struct{
char *key;
DM_Node_t *value;
int num;
} DM_Array_Base_t;
typedef struct{
char *key;
DM_Type_Struct_t *value;
int num;
} DM_Array_Struct_t;
typedef union{
DM_Node_t *dm_node;
DM_Type_Struct_t *dm_struct;
DM_Array_Base_t *dm_array_base;
DM_Array_Struct_t *dm_array_struct;
}DM_Property_Value_U;
typedef struct{
DM_Parse_Type parse_type;
DM_Property_Value_U value;
int desired_ver;
} DM_Property_t;
typedef struct{
char *event_identy;
DM_Property_t *dm_property;
int property_num;
} DM_Event_t;
typedef struct{
DM_Property_t *input;
int input_num;
DM_Property_t *output;
int output_num;
} DM_Command_t;
typedef int (* PropertyRestoreCB)(const char *request_id, const int ret_code, const char *property);
typedef int (* PropertySetCB)(const char *request_id, const char *property);
typedef int (* PropertyDesiredGetCB)(const char *request_id, const int ret_code, const char *desired);
typedef int (* CommandCB)(const char *request_id, const char *identifier, const char *input, char **output);
typedef int (* CommandCB)(const char *request_id, const char *identifier, const char *input, char *output);
typedef int (* CommonReplyCB)(const char *request_id, const int ret_code);
#define DECLARE_DM_CALLBACK(type, cb) int uiot_register_for_##type(void*, cb);
@ -105,6 +181,24 @@ int IOT_DM_Destroy(void *handle);
*/
int IOT_DM_Property_Report(void *handle, DM_Type type, int request_id, const char *payload);
/**
* @brief ,
*
* @param handle: IOT_DM_Init返回的句柄
* @param type:
PROPERTY_RESTORE,
PROPERTY_POST,
PROPERTY_DESIRED_GET,
PROPERTY_DESIRED_DELETE
* @param request_id: request_id
* @param property_num:
* @param ...:
*
* @retval 0 :
* @retval < 0 :
*/
int IOT_DM_Property_ReportEx(void *handle, DM_Type type, int request_id, int property_num, ...);
/**
* @brief
@ -119,6 +213,29 @@ int IOT_DM_Property_Report(void *handle, DM_Type type, int request_id, const cha
*/
int IOT_DM_TriggerEvent(void *handle, int request_id, const char *identifier, const char *payload);
/**
* @brief
*
* @param handle: IOT_DM_Init返回的句柄
* @param request_id: request_id
* @param event:
*
* @retval 0 :
* @retval < 0 :
*/
int IOT_DM_TriggerEventEx(void *handle, int request_id, DM_Event_t *event);
/**
* @brief
*
* @param output:
* @param property_num:
* @param ...:
*
* @retval 0 :
* @retval < 0 :
*/
int IOT_DM_GenCommandOutput(char *output, int property_num, ...);
/**
* @brief 线MQTT客户端让出一定CPU执行时间

View File

@ -50,6 +50,58 @@ typedef enum {
} IOT_OTA_ReportErrCode;
typedef enum {
OTA_REPORT_UNDEFINED_ERROR = -6,
OTA_REPORT_FIRMWARE_BURN_FAILED = -5,
OTA_REPORT_MD5_MISMATCH = -4,
OTA_REPORT_DOWNLOAD_TIMEOUT = -3,
OTA_REPORT_SIGNATURE_EXPIRED = -2,
OTA_REPORT_FIRMWARE_NOT_EXIST = -1,
OTA_REPORT_NONE = 0,
OTA_REPORT_DOWNLOADING = 1,
OTA_REPORT_BURNING = 2,
OTA_REPORT_SUCCESS = 3,
OTA_REQUEST_FIRMWARE = 4,
OTA_REPORT_VERSION = 5,
} IOT_OTA_UpstreamMsgType;
typedef int (*IOT_OTA_FetchCallback)(void *handle, IOT_OTA_UpstreamMsgType state);
/* OTA状态 */
typedef enum {
OTA_STATE_UNINITED = 0, /* 未初始化 */
OTA_STATE_INITED, /* 初始化完成 */
OTA_STATE_FETCHING, /* 正在下载固件 */
OTA_STATE_FETCHED, /* 固件下载完成 */
OTA_STATE_DISCONNECTED /* 连接已经断开 */
} IOT_OTA_State;
typedef struct {
uint32_t id; /* message id */
IOT_OTA_State state; /* OTA state */
uint32_t size_last_fetched; /* size of last downloaded */
uint32_t size_fetched; /* size of already downloaded */
uint32_t size_file; /* size of file */
char *url; /* point to URL */
char *download_name; /* download partition name */
char *module; /* download module name */
char *version; /* point to version */
char *md5sum; /* MD5 string */
void *md5; /* MD5 handle */
void *ch_signal; /* channel handle of signal exchanged with OTA server */
void *ch_fetch; /* channel handle of download */
int err; /* last error code */
Timer report_timer;
IOT_OTA_FetchCallback fetch_callback_func;
} OTA_Struct_t;
/**
* @brief OTA模块和返回句柄
@ -81,12 +133,13 @@ int IOT_OTA_Destroy(void *handle);
* NOTE: OTA前请保证先上报一次本地固件的版本信息便
*
* @param handle: OTA模块
* @param module:
* @param version:
*
* @retval > 0 : publish的packet id
* @retval < 0 :
*/
int IOT_OTA_ReportVersion(void *handle, const char *version);
int IOT_OTA_ReportVersion(void *handle, const char *module, const char *version);
/**
@ -101,7 +154,6 @@ int IOT_OTA_ReportVersion(void *handle, const char *version);
*/
int IOT_OTA_ReportProgress(void *handle, int progress, IOT_OTA_ProgressState state);
/**
* @brief OTA服务器上报升级成功
*
@ -113,7 +165,6 @@ int IOT_OTA_ReportProgress(void *handle, int progress, IOT_OTA_ProgressState sta
*/
int IOT_OTA_ReportSuccess(void *handle, const char *version);
/**
* @brief OTA服务器上报失败信息
*
@ -189,12 +240,13 @@ int IOT_OTA_GetLastError(void *handle);
* @brief 线MQTT协议接入物联网平台的设备再次上线后
*
* @param handle: OTA模块
* @param module:
* @param version:
*
* @retval > 0 : publish的packet id
* @retval < 0 :
*/
int IOT_OTA_RequestFirmware(void *handle, const char *version);
int IOT_OTA_RequestFirmware(void *handle, const char *module, const char *version);
/**
* @brief

View File

@ -29,7 +29,10 @@ extern "C" {
#include "uiot_defs.h"
#include "HAL_Timer_Platform.h"
#include "HAL_Flash_Platform.h"
#include "utils_net.h"
#include "lite-utils.h"
#include "json_parser.h"
/**
* @brief
@ -316,17 +319,108 @@ int32_t HAL_TCP_Write(_IN_ uintptr_t fd, _IN_ unsigned char *buf, _IN_ size_t le
*/
int32_t HAL_TCP_Read(_IN_ uintptr_t fd, _OU_ unsigned char *buf, _IN_ size_t len, _IN_ uint32_t timeout_ms);
/**
* @brief name
*
* @param handle download_name的指针
* @return download_name的指针
*/
void * HAL_Download_Name_Set(void * handle);
/**
* @brief
*
* @param name
* @return
*/
void * HAL_Download_Init(_IN_ void * name);
/**
* @brief length的buffer_read的数据写入到FLASH中
*
* @param handle
* @param total_length
* @param buffer_read
* @param length
* @return
*/
int HAL_Download_Write(_IN_ void * handle,_IN_ uint32_t total_length,_IN_ uint8_t *buffer_read,_IN_ uint32_t length);
/**
* @brief STM32F767 FLASH的information分区的下载标志置位成功
*
* @param handle
* @return -1 0
*/
int HAL_Download_End(_IN_ void * handle);
#ifdef SUPPORT_AT_CMD
/**
* @brief
*
* @param
* @return
*/
void HAL_AT_Init();
/**
* @brief AT命令执行结果
*
* @param pNetwork
* @param buf
* @param len
* @return <0: TCP读取错误; =0: TCP读超时, ; >0: TCP成功读取的字节数
*/
int HAL_AT_Read(_IN_ utils_network_pt pNetwork, _OU_ unsigned char *buffer, _IN_ size_t len);
/**
* @brief AT命令
*
* @param buf
* @param len
* @return <0: TCP写入错误; =0: TCP写超时, ; >0: TCP成功写入的字节数
*/
int HAL_AT_Write(_IN_ unsigned char *buffer, _IN_ size_t len);
int HAL_AT_TCP_Disconnect(void);
/**
* @brief TCP连接,
*
* @param pNetwork
* @return SUCCESSFAILURE
*/
int HAL_AT_TCP_Disconnect(utils_network_pt pNetwork);
int HAL_AT_TCP_Connect(_IN_ void * pNetwork, _IN_ const char *host, _IN_ uint16_t port);
/**
* @brief TCP连接HOST地址, TCP连接,
*
* @param pNetwork
* @param host TCP服务器网络地址
* @param port TCP服务器端口
* @return , TCP连接句柄NULL
*/
int HAL_AT_TCP_Connect(_IN_ utils_network_pt pNetwork, _IN_ const char *host, _IN_ uint16_t port);
/**
* @brief TCP连接写入数据
*
* @param pNetwork
* @param buf
* @param len
* @return <0: TCP写入错误; =0: TCP写超时, ; >0: TCP成功写入的字节数
*/
int HAL_AT_Write_Tcp(_IN_ utils_network_pt pNetwork, _IN_ unsigned char *buffer, _IN_ size_t len);
/**
* @brief TCP连接读取数据
*
* @param pNetwork
* @param buf
* @param len
* @return <0: TCP读取错误; =0: TCP读超时, ; >0: TCP成功读取的字节数
*/
int HAL_AT_Read_Tcp(_IN_ utils_network_pt pNetwork, _IN_ unsigned char *buffer, _IN_ size_t len);
#endif
#if defined(__cplusplus)
}