support aliyun sdk on TencentOS tiny
sample: examples\aliyun_iotkit_csdk_mqtt project: board\TencentOS_tiny_EVB_MX_Plus\KEIL\aliyun_iotkit_csdk_mqtt
This commit is contained in:
291
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/examples/ota_example_mqtt.c
vendored
Normal file
291
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/examples/ota_example_mqtt.c
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "infra_compat.h"
|
||||
#include "mqtt_api.h"
|
||||
#include "ota_api.h"
|
||||
|
||||
void *HAL_Malloc(uint32_t size);
|
||||
void HAL_Free(void *ptr);
|
||||
|
||||
void HAL_Printf(const char *fmt, ...);
|
||||
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN]);
|
||||
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN]);
|
||||
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
|
||||
void HAL_SleepMs(uint32_t ms);
|
||||
|
||||
char g_product_key[IOTX_PRODUCT_KEY_LEN + 1];
|
||||
char g_product_secret[IOTX_PRODUCT_SECRET_LEN + 1];
|
||||
char g_device_name[IOTX_DEVICE_NAME_LEN + 1];
|
||||
char g_device_secret[IOTX_DEVICE_SECRET_LEN + 1];
|
||||
|
||||
#define OTA_MQTT_MSGLEN (2048)
|
||||
|
||||
#define EXAMPLE_TRACE(fmt, ...) \
|
||||
do { \
|
||||
HAL_Printf("%s|%03d :: ", __func__, __LINE__); \
|
||||
HAL_Printf(fmt, ##__VA_ARGS__); \
|
||||
HAL_Printf("%s", "\r\n"); \
|
||||
} while(0)
|
||||
|
||||
static int user_argc;
|
||||
static char **user_argv;
|
||||
|
||||
void event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
|
||||
{
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
|
||||
|
||||
switch (msg->event_type) {
|
||||
case IOTX_MQTT_EVENT_UNDEF:
|
||||
EXAMPLE_TRACE("undefined event occur.");
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_DISCONNECT:
|
||||
EXAMPLE_TRACE("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_RECONNECT:
|
||||
EXAMPLE_TRACE("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
EXAMPLE_TRACE("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
EXAMPLE_TRACE("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
|
||||
EXAMPLE_TRACE("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS:
|
||||
EXAMPLE_TRACE("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
|
||||
EXAMPLE_TRACE("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK:
|
||||
EXAMPLE_TRACE("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
EXAMPLE_TRACE("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
EXAMPLE_TRACE("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_PUBLISH_NACK:
|
||||
EXAMPLE_TRACE("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
|
||||
EXAMPLE_TRACE("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
|
||||
topic_info->topic_len,
|
||||
topic_info->ptopic,
|
||||
topic_info->payload_len,
|
||||
topic_info->payload);
|
||||
break;
|
||||
|
||||
default:
|
||||
EXAMPLE_TRACE("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _ota_mqtt_client(void)
|
||||
{
|
||||
#define OTA_BUF_LEN (5000)
|
||||
|
||||
int rc = 0, ota_over = 0;
|
||||
void *pclient = NULL, *h_ota = NULL;
|
||||
iotx_conn_info_pt pconn_info;
|
||||
iotx_mqtt_param_t mqtt_params;
|
||||
char *msg_buf = NULL, *msg_readbuf = NULL;
|
||||
FILE *fp;
|
||||
char buf_ota[OTA_BUF_LEN];
|
||||
|
||||
if (NULL == (fp = fopen("ota.bin", "wb+"))) {
|
||||
EXAMPLE_TRACE("open file failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
|
||||
if (NULL == (msg_buf = (char *)HAL_Malloc(OTA_MQTT_MSGLEN))) {
|
||||
EXAMPLE_TRACE("not enough memory");
|
||||
rc = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
if (NULL == (msg_readbuf = (char *)HAL_Malloc(OTA_MQTT_MSGLEN))) {
|
||||
EXAMPLE_TRACE("not enough memory");
|
||||
rc = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
/**< get device info*/
|
||||
HAL_GetProductKey(g_product_key);
|
||||
HAL_GetDeviceName(g_device_name);
|
||||
HAL_GetDeviceSecret(g_device_secret);
|
||||
/**< end*/
|
||||
|
||||
/* Device AUTH */
|
||||
if (0 != IOT_SetupConnInfo(g_product_key, g_device_name, g_device_secret, (void **)&pconn_info)) {
|
||||
EXAMPLE_TRACE("AUTH request failed!");
|
||||
rc = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
/* Initialize MQTT parameter */
|
||||
memset(&mqtt_params, 0x0, sizeof(mqtt_params));
|
||||
|
||||
mqtt_params.port = pconn_info->port;
|
||||
mqtt_params.host = pconn_info->host_name;
|
||||
mqtt_params.client_id = pconn_info->client_id;
|
||||
mqtt_params.username = pconn_info->username;
|
||||
mqtt_params.password = pconn_info->password;
|
||||
mqtt_params.pub_key = pconn_info->pub_key;
|
||||
|
||||
mqtt_params.request_timeout_ms = 2000;
|
||||
mqtt_params.clean_session = 0;
|
||||
mqtt_params.keepalive_interval_ms = 60000;
|
||||
mqtt_params.read_buf_size = OTA_MQTT_MSGLEN;
|
||||
mqtt_params.write_buf_size = OTA_MQTT_MSGLEN;
|
||||
|
||||
mqtt_params.handle_event.h_fp = event_handle;
|
||||
mqtt_params.handle_event.pcontext = NULL;
|
||||
|
||||
|
||||
/* Construct a MQTT client with specify parameter */
|
||||
pclient = IOT_MQTT_Construct(&mqtt_params);
|
||||
if (NULL == pclient) {
|
||||
EXAMPLE_TRACE("MQTT construct failed");
|
||||
rc = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
h_ota = IOT_OTA_Init(g_product_key, g_device_name, pclient);
|
||||
if (NULL == h_ota) {
|
||||
rc = -1;
|
||||
EXAMPLE_TRACE("initialize OTA failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
/* if (0 != IOT_OTA_ReportVersion(h_ota, "iotx_ver_1.1.0")) { */
|
||||
/* rc = -1; */
|
||||
/* EXAMPLE_TRACE("report OTA version failed"); */
|
||||
/* goto do_exit; */
|
||||
/* } */
|
||||
|
||||
HAL_SleepMs(1000);
|
||||
|
||||
do {
|
||||
uint32_t firmware_valid;
|
||||
|
||||
EXAMPLE_TRACE("wait ota upgrade command....");
|
||||
|
||||
/* handle the MQTT packet received from TCP or SSL connection */
|
||||
IOT_MQTT_Yield(pclient, 200);
|
||||
|
||||
if (IOT_OTA_IsFetching(h_ota)) {
|
||||
uint32_t last_percent = 0, percent = 0;
|
||||
char md5sum[33];
|
||||
char version[128] = {0};
|
||||
uint32_t len, size_downloaded, size_file;
|
||||
do {
|
||||
|
||||
len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
|
||||
if (len > 0) {
|
||||
if (1 != fwrite(buf_ota, len, 1, fp)) {
|
||||
EXAMPLE_TRACE("write data to file failed");
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
IOT_OTA_ReportProgress(h_ota, IOT_OTAP_FETCH_FAILED, NULL);
|
||||
EXAMPLE_TRACE("ota fetch fail");
|
||||
}
|
||||
|
||||
/* get OTA information */
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &size_downloaded, 4);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &size_file, 4);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);
|
||||
|
||||
last_percent = percent;
|
||||
percent = (size_downloaded * 100) / size_file;
|
||||
if (percent - last_percent > 0) {
|
||||
IOT_OTA_ReportProgress(h_ota, percent, NULL);
|
||||
IOT_OTA_ReportProgress(h_ota, percent, "hello");
|
||||
}
|
||||
IOT_MQTT_Yield(pclient, 100);
|
||||
} while (!IOT_OTA_IsFetchFinish(h_ota));
|
||||
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
|
||||
if (0 == firmware_valid) {
|
||||
EXAMPLE_TRACE("The firmware is invalid");
|
||||
} else {
|
||||
EXAMPLE_TRACE("The firmware is valid");
|
||||
}
|
||||
|
||||
ota_over = 1;
|
||||
}
|
||||
HAL_SleepMs(2000);
|
||||
} while (!ota_over);
|
||||
|
||||
HAL_SleepMs(200);
|
||||
|
||||
|
||||
|
||||
do_exit:
|
||||
|
||||
if (NULL != h_ota) {
|
||||
IOT_OTA_Deinit(h_ota);
|
||||
}
|
||||
|
||||
if (NULL != pclient) {
|
||||
IOT_MQTT_Destroy(&pclient);
|
||||
}
|
||||
|
||||
if (NULL != msg_buf) {
|
||||
HAL_Free(msg_buf);
|
||||
}
|
||||
|
||||
if (NULL != msg_readbuf) {
|
||||
HAL_Free(msg_readbuf);
|
||||
}
|
||||
|
||||
if (NULL != fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
EXAMPLE_TRACE("hello main func");
|
||||
IOT_SetLogLevel(IOT_LOG_DEBUG);
|
||||
|
||||
user_argc = argc;
|
||||
user_argv = argv;
|
||||
|
||||
_ota_mqtt_client();
|
||||
|
||||
IOT_DumpMemoryStats(IOT_LOG_DEBUG);
|
||||
|
||||
EXAMPLE_TRACE("out of sample!");
|
||||
return 0;
|
||||
}
|
||||
|
13
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iot.mk
vendored
Normal file
13
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iot.mk
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
LIBA_TARGET := libiot_ota.a
|
||||
|
||||
HDR_REFS := src/infra
|
||||
|
||||
DEPENDS += wrappers
|
||||
LDFLAGS += -liot_sdk -liot_hal -liot_tls
|
||||
|
||||
LIB_SRCS_PATTERN := *.c
|
||||
|
||||
LIB_SRCS_EXCLUDE += examples/ota_example_mqtt.c
|
||||
SRCS_ota-example-mqtt := examples/ota_example_mqtt.c
|
||||
|
||||
$(call Append_Conditional, TARGET, ota-example-mqtt, OTA_ENABLED, BUILD_AOS NO_EXECUTABLES)
|
984
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota.c
vendored
Normal file
984
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota.c
vendored
Normal file
@@ -0,0 +1,984 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "iotx_ota_internal.h"
|
||||
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
#include "ota_mqtt.c"
|
||||
#elif (OTA_SIGNAL_CHANNEL) == 2
|
||||
#include "ota_coap.c"
|
||||
#else
|
||||
#error "NOT support yet!"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *product_key; /* point to product key */
|
||||
const char *device_name; /* point to device name */
|
||||
|
||||
uint32_t id; /* message id */
|
||||
IOT_OTA_State_t state; /* OTA state */
|
||||
IOT_OTA_Type_t type; /* OTA Type */
|
||||
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 *purl; /* point to URL */
|
||||
char *version; /* point to string */
|
||||
char md5sum[33]; /* MD5 string */
|
||||
|
||||
void *md5; /* MD5 handle */
|
||||
void *sha256; /* Sha256 handle */
|
||||
void *ch_signal; /* channel handle of signal exchanged with OTA server */
|
||||
void *ch_fetch; /* channel handle of download */
|
||||
|
||||
/* cota */
|
||||
char *configId;
|
||||
uint32_t configSize;
|
||||
char *sign;
|
||||
char *signMethod;
|
||||
char *cota_url;
|
||||
char *getType;
|
||||
|
||||
int err; /* last error code */
|
||||
|
||||
ota_fetch_cb_fpt fetch_cb; /* fetch_callback */
|
||||
void *user_data; /* fetch_callback's user_data */
|
||||
|
||||
cota_fetch_cb_fpt fetch_cota_cb;
|
||||
void *cota_user_data;
|
||||
|
||||
} OTA_Struct_t, *OTA_Struct_pt;
|
||||
|
||||
|
||||
/* check whether the progress state is valid or not */
|
||||
/* return: true, valid progress state; false, invalid progress state. */
|
||||
static int ota_check_progress(IOT_OTA_Progress_t progress)
|
||||
{
|
||||
return ((progress >= IOT_OTAP_BURN_FAILED)
|
||||
&& (progress <= IOT_OTAP_FETCH_PERCENTAGE_MAX));
|
||||
}
|
||||
|
||||
|
||||
int iotx_ota_set_fetch_callback(void *pt, ota_fetch_cb_fpt fetch_cb, void *user_data)
|
||||
{
|
||||
OTA_Struct_pt ota_pt = (OTA_Struct_pt)pt;
|
||||
|
||||
if (NULL == ota_pt || NULL == fetch_cb) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ota_pt->fetch_cb = fetch_cb;
|
||||
ota_pt->user_data = user_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int iotx_ota_set_cota_fetch_callback(void *pt, cota_fetch_cb_fpt fetch_cb, void *user_data)
|
||||
{
|
||||
OTA_Struct_pt ota_pt = (OTA_Struct_pt)pt;
|
||||
|
||||
if (NULL == ota_pt || NULL == fetch_cb) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ota_pt->fetch_cota_cb = fetch_cb;
|
||||
ota_pt->cota_user_data = user_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ota_callback(void *pcontext, const char *msg, uint32_t msg_len, iotx_ota_topic_types_t type)
|
||||
{
|
||||
const char *pvalue;
|
||||
uint32_t val_len;
|
||||
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) pcontext;
|
||||
|
||||
if (h_ota->state == IOT_OTAS_FETCHING) {
|
||||
OTA_LOG_INFO("In downloading state");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case IOTX_OTA_TOPIC_TYPE_DEVICE_REQUEST:
|
||||
case IOTX_OTA_TOPIC_TYPE_DEVICE_UPGRATE: {
|
||||
pvalue = otalib_JsonValueOf(msg, msg_len, "message", &val_len);
|
||||
if (NULL == pvalue) {
|
||||
OTA_LOG_ERROR("invalid json doc of OTA ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check whether is positive message */
|
||||
if (!((strlen("success") == val_len) && (0 == strncmp(pvalue, "success", val_len)))) {
|
||||
OTA_LOG_ERROR("fail state of json doc of OTA");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get value of 'data' key */
|
||||
pvalue = otalib_JsonValueOf(msg, msg_len, "data", &val_len);
|
||||
if (NULL == pvalue) {
|
||||
OTA_LOG_ERROR("Not 'data' key in json doc of OTA");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != otalib_GetParams(pvalue, val_len, &h_ota->purl, &h_ota->version, h_ota->md5sum, &h_ota->size_file)) {
|
||||
OTA_LOG_ERROR("Get config parameter failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (h_ota->ch_fetch = ofc_Init(h_ota->purl))) {
|
||||
OTA_LOG_ERROR("Initialize fetch module failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
h_ota->type = IOT_OTAT_FOTA;
|
||||
h_ota->state = IOT_OTAS_FETCHING;
|
||||
|
||||
if (h_ota->fetch_cb) {
|
||||
h_ota->fetch_cb(h_ota->user_data, 0, h_ota->size_file, h_ota->purl, h_ota->version);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IOTX_OTA_TOPIC_TYPE_CONFIG_GET: {
|
||||
pvalue = otalib_JsonValueOf(msg, msg_len, "code", &val_len);
|
||||
if (NULL == pvalue) {
|
||||
OTA_LOG_ERROR("invalid json doc of OTA ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check whether is positive message */
|
||||
if (!((strlen("200") == val_len) && (0 == strncmp(pvalue, "200", val_len)))) {
|
||||
OTA_LOG_ERROR("fail state of json doc of OTA");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get value of 'data' key */
|
||||
pvalue = otalib_JsonValueOf(msg, msg_len, "data", &val_len);
|
||||
if (NULL == pvalue) {
|
||||
OTA_LOG_ERROR("Not 'data' key in json doc of OTA");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != otalib_GetConfigParams(pvalue, val_len, &h_ota->configId, &h_ota->configSize,
|
||||
&h_ota->sign, &h_ota->signMethod, &h_ota->cota_url, &h_ota->getType)) {
|
||||
OTA_LOG_ERROR("Get firmware parameter failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
h_ota->size_file = h_ota->configSize;
|
||||
h_ota->size_fetched = 0;
|
||||
if (NULL != h_ota->md5) {
|
||||
otalib_MD5Deinit(h_ota->md5);
|
||||
}
|
||||
h_ota->md5 = otalib_MD5Init();
|
||||
|
||||
if (NULL != h_ota->sha256) {
|
||||
otalib_Sha256Deinit(h_ota->sha256);
|
||||
}
|
||||
h_ota->sha256 = otalib_Sha256Init();
|
||||
|
||||
if (NULL == (h_ota->ch_fetch = ofc_Init(h_ota->cota_url))) {
|
||||
OTA_LOG_ERROR("Initialize fetch module failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
h_ota->type = IOT_OTAT_COTA;
|
||||
h_ota->state = IOT_OTAS_FETCHING;
|
||||
|
||||
if (h_ota->fetch_cota_cb) {
|
||||
h_ota->fetch_cota_cb(h_ota->user_data, 0, h_ota->configId, h_ota->configSize, h_ota->sign, h_ota->signMethod,
|
||||
h_ota->cota_url, h_ota->getType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IOTX_OTA_TOPIC_TYPE_CONFIG_PUSH: {
|
||||
/* get value of 'params' key */
|
||||
pvalue = otalib_JsonValueOf(msg, msg_len, "params", &val_len);
|
||||
if (NULL == pvalue) {
|
||||
OTA_LOG_ERROR("Not 'data' key in json doc of OTA");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != otalib_GetConfigParams(pvalue, val_len, &h_ota->configId, &h_ota->configSize,
|
||||
&h_ota->sign, &h_ota->signMethod, &h_ota->cota_url, &h_ota->getType)) {
|
||||
OTA_LOG_ERROR("Get firmware parameter failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
h_ota->size_file = h_ota->configSize;
|
||||
h_ota->size_fetched = 0;
|
||||
if (NULL != h_ota->md5) {
|
||||
otalib_MD5Deinit(h_ota->md5);
|
||||
}
|
||||
h_ota->md5 = otalib_MD5Init();
|
||||
|
||||
if (NULL != h_ota->sha256) {
|
||||
otalib_Sha256Deinit(h_ota->sha256);
|
||||
}
|
||||
h_ota->sha256 = otalib_Sha256Init();
|
||||
|
||||
if (NULL == (h_ota->ch_fetch = ofc_Init(h_ota->cota_url))) {
|
||||
OTA_LOG_ERROR("Initialize fetch module failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
h_ota->type = IOT_OTAT_COTA;
|
||||
h_ota->state = IOT_OTAS_FETCHING;
|
||||
|
||||
if (h_ota->fetch_cota_cb) {
|
||||
h_ota->fetch_cota_cb(h_ota->user_data, 0, h_ota->configId, h_ota->configSize, h_ota->sign, h_ota->signMethod,
|
||||
h_ota->cota_url, h_ota->getType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int g_ota_is_initialized = 0;
|
||||
|
||||
/* Initialize OTA module */
|
||||
void *IOT_OTA_Init(const char *product_key, const char *device_name, void *ch_signal)
|
||||
{
|
||||
OTA_Struct_pt h_ota = NULL;
|
||||
|
||||
if (1 == g_ota_is_initialized) {
|
||||
OTA_LOG_ERROR("iot ota has been initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((NULL == product_key) || (NULL == device_name)) {
|
||||
OTA_LOG_ERROR("one or more parameters is invalid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (NULL == (h_ota = OTA_MALLOC(sizeof(OTA_Struct_t)))) {
|
||||
OTA_LOG_ERROR("allocate failed");
|
||||
return NULL;
|
||||
}
|
||||
memset(h_ota, 0, sizeof(OTA_Struct_t));
|
||||
h_ota->type = IOT_OTAT_NONE;
|
||||
h_ota->state = IOT_OTAS_UNINITED;
|
||||
|
||||
h_ota->ch_signal = osc_Init(product_key, device_name, ch_signal, ota_callback, h_ota);
|
||||
if (NULL == h_ota->ch_signal) {
|
||||
OTA_LOG_ERROR("initialize signal channel failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
h_ota->md5 = otalib_MD5Init();
|
||||
if (NULL == h_ota->md5) {
|
||||
OTA_LOG_ERROR("initialize md5 failed");
|
||||
goto do_exit;
|
||||
}
|
||||
h_ota->sha256 = otalib_Sha256Init();
|
||||
if (NULL == h_ota->sha256) {
|
||||
OTA_LOG_ERROR("initialize sha256 failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
h_ota->product_key = product_key;
|
||||
h_ota->device_name = device_name;
|
||||
h_ota->state = IOT_OTAS_INITED;
|
||||
g_ota_is_initialized = 1;
|
||||
return h_ota;
|
||||
|
||||
do_exit:
|
||||
|
||||
if (NULL != h_ota->ch_signal) {
|
||||
osc_Deinit(h_ota->ch_signal);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->md5) {
|
||||
otalib_MD5Deinit(h_ota->md5);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->sha256) {
|
||||
otalib_Sha256Deinit(h_ota->sha256);
|
||||
}
|
||||
|
||||
if (NULL != h_ota) {
|
||||
OTA_FREE(h_ota);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
#undef AOM_INFO_MSG_LEN
|
||||
}
|
||||
|
||||
|
||||
/* deinitialize OTA module */
|
||||
int IOT_OTA_Deinit(void *handle)
|
||||
{
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if (NULL == h_ota) {
|
||||
OTA_LOG_ERROR("handle is NULL");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_ota_is_initialized = 0;
|
||||
|
||||
if (NULL != h_ota->ch_signal) {
|
||||
osc_Deinit(h_ota->ch_signal);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->ch_fetch) {
|
||||
ofc_Deinit(h_ota->ch_fetch);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->md5) {
|
||||
otalib_MD5Deinit(h_ota->md5);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->sha256) {
|
||||
otalib_Sha256Deinit(h_ota->sha256);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->purl) {
|
||||
OTA_FREE(h_ota->purl);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->version) {
|
||||
OTA_FREE(h_ota->version);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->configId) {
|
||||
OTA_FREE(h_ota->configId);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->sign) {
|
||||
OTA_FREE(h_ota->sign);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->signMethod) {
|
||||
OTA_FREE(h_ota->signMethod);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->cota_url) {
|
||||
OTA_FREE(h_ota->cota_url);
|
||||
}
|
||||
|
||||
if (NULL != h_ota->getType) {
|
||||
OTA_FREE(h_ota->getType);
|
||||
}
|
||||
|
||||
OTA_FREE(h_ota);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define OTA_VERSION_STR_LEN_MIN (1)
|
||||
#define OTA_VERSION_STR_LEN_MAX (32)
|
||||
|
||||
int IOT_OTA_ReportVersion(void *handle, const char *version)
|
||||
{
|
||||
#define MSG_INFORM_LEN (128)
|
||||
|
||||
int ret, len;
|
||||
char *msg_informed;
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if ((NULL == h_ota) || (NULL == version)) {
|
||||
OTA_LOG_ERROR("one or more invalid parameter");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
len = strlen(version);
|
||||
if ((len < OTA_VERSION_STR_LEN_MIN) || (len > OTA_VERSION_STR_LEN_MAX)) {
|
||||
OTA_LOG_ERROR("version string is invalid: must be [1, 32] chars");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (msg_informed = OTA_MALLOC(MSG_INFORM_LEN))) {
|
||||
OTA_LOG_ERROR("allocate for msg_informed failed");
|
||||
h_ota->err = IOT_OTAE_NOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = otalib_GenInfoMsg(msg_informed, MSG_INFORM_LEN, h_ota->id, version);
|
||||
if (ret != 0) {
|
||||
OTA_LOG_ERROR("generate inform message failed");
|
||||
h_ota->err = ret;
|
||||
ret = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = osc_ReportVersion(h_ota->ch_signal, msg_informed);
|
||||
if (0 != ret) {
|
||||
OTA_LOG_ERROR("Report version failed");
|
||||
h_ota->err = ret;
|
||||
ret = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
do_exit:
|
||||
if (NULL != msg_informed) {
|
||||
OTA_FREE(msg_informed);
|
||||
}
|
||||
return ret;
|
||||
|
||||
#undef MSG_INFORM_LEN
|
||||
}
|
||||
|
||||
int iotx_req_image(void *handle, const char *version)
|
||||
{
|
||||
#define MSG_REQUEST_LEN (128)
|
||||
|
||||
int ret, len;
|
||||
char *msg_informed;
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if ((NULL == h_ota) || (NULL == version)) {
|
||||
OTA_LOG_ERROR("one or more invalid parameter");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
len = strlen(version);
|
||||
if ((len < OTA_VERSION_STR_LEN_MIN) || (len > OTA_VERSION_STR_LEN_MAX)) {
|
||||
OTA_LOG_ERROR("version string is invalid: must be [1, 32] chars");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_FETCHING == h_ota->state) {
|
||||
OTA_LOG_ERROR("ota is busying");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (msg_informed = OTA_MALLOC(MSG_REQUEST_LEN))) {
|
||||
OTA_LOG_ERROR("allocate for msg_informed failed");
|
||||
h_ota->err = IOT_OTAE_NOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = otalib_GenInfoMsg(msg_informed, MSG_REQUEST_LEN, h_ota->id, version);
|
||||
if (ret != 0) {
|
||||
OTA_LOG_ERROR("generate request image message failed");
|
||||
h_ota->err = ret;
|
||||
ret = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = osc_RequestImage(h_ota->ch_signal, msg_informed);
|
||||
if (0 != ret) {
|
||||
OTA_LOG_ERROR("Request image failed");
|
||||
h_ota->err = ret;
|
||||
ret = -1;
|
||||
goto do_exit;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
do_exit:
|
||||
if (NULL != msg_informed) {
|
||||
OTA_FREE(msg_informed);
|
||||
}
|
||||
return ret;
|
||||
|
||||
#undef MSG_REQUEST_LEN
|
||||
}
|
||||
|
||||
|
||||
int IOT_OTA_ReportProgress(void *handle, IOT_OTA_Progress_t progress, const char *msg)
|
||||
{
|
||||
#define MSG_REPORT_LEN (256)
|
||||
|
||||
int ret = -1;
|
||||
char *msg_reported;
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if (NULL == handle) {
|
||||
OTA_LOG_ERROR("handle is NULL");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
if (!ota_check_progress(progress)) {
|
||||
OTA_LOG_ERROR("progress is a invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (msg_reported = OTA_MALLOC(MSG_REPORT_LEN))) {
|
||||
OTA_LOG_ERROR("allocate for msg_reported failed");
|
||||
h_ota->err = IOT_OTAE_NOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = otalib_GenReportMsg(msg_reported, MSG_REPORT_LEN, h_ota->id, progress, msg);
|
||||
if (0 != ret) {
|
||||
OTA_LOG_ERROR("generate reported message failed");
|
||||
h_ota->err = ret;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = osc_ReportProgress(h_ota->ch_signal, msg_reported);
|
||||
if (0 != ret) {
|
||||
OTA_LOG_ERROR("Report progress failed");
|
||||
h_ota->err = ret;
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
do_exit:
|
||||
if (NULL != msg_reported) {
|
||||
OTA_FREE(msg_reported);
|
||||
}
|
||||
return ret;
|
||||
|
||||
#undef MSG_REPORT_LEN
|
||||
}
|
||||
|
||||
int iotx_ota_get_config(void *handle, const char *configScope, const char *getType, const char *attributeKeys)
|
||||
{
|
||||
#define MSG_REPORT_LEN (256)
|
||||
|
||||
int ret = -1;
|
||||
char *msg_get;
|
||||
char topic[OTA_MQTT_TOPIC_LEN] = {0};
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
iotx_mqtt_topic_info_t topic_info;
|
||||
|
||||
memset(&topic_info, 0, sizeof(iotx_mqtt_topic_info_t));
|
||||
|
||||
if (NULL == handle) {
|
||||
OTA_LOG_ERROR("handle is NULL");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_FETCHING == h_ota->state) {
|
||||
OTA_LOG_ERROR("ota is busying");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (msg_get = OTA_MALLOC(MSG_REPORT_LEN))) {
|
||||
OTA_LOG_ERROR("allocate for msg_reported failed");
|
||||
h_ota->err = IOT_OTAE_NOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 > HAL_Snprintf(topic,
|
||||
OTA_MQTT_TOPIC_LEN,
|
||||
"/sys/%s/%s/thing/config/get",
|
||||
h_ota->product_key,
|
||||
h_ota->device_name)) {
|
||||
goto do_exit;
|
||||
};
|
||||
|
||||
if (0 > HAL_Snprintf(msg_get,
|
||||
MSG_REPORT_LEN,
|
||||
"{\"id\" : %d,\"version\":\"1.0\",\"params\":{\"configScope\":\"%s\",\"getType\":\"%s\",\"attributeKeys\":\"%s\"},\"method\":\"thing.config.get\"}",
|
||||
h_ota->id,
|
||||
configScope,
|
||||
getType,
|
||||
attributeKeys)) {
|
||||
goto do_exit;
|
||||
};
|
||||
OTA_LOG_INFO(msg_get);
|
||||
topic_info.qos = IOTX_MQTT_QOS0;
|
||||
topic_info.payload = (void *)msg_get;
|
||||
topic_info.payload_len = strlen(msg_get);
|
||||
|
||||
ret = osc_RequestConfig(h_ota->ch_signal, topic, &topic_info);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("publish failed");
|
||||
return IOT_OTAE_OSC_FAILED;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
do_exit:
|
||||
if (NULL != msg_get) {
|
||||
OTA_FREE(msg_get);
|
||||
}
|
||||
return ret;
|
||||
|
||||
#undef MSG_REPORT_LEN
|
||||
}
|
||||
|
||||
|
||||
/* check whether is downloading */
|
||||
int IOT_OTA_IsFetching(void *handle)
|
||||
{
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt)handle;
|
||||
|
||||
if (NULL == handle) {
|
||||
OTA_LOG_ERROR("handle is NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (IOT_OTAS_FETCHING == h_ota->state);
|
||||
}
|
||||
|
||||
|
||||
/* check whether fetch over */
|
||||
int IOT_OTA_IsFetchFinish(void *handle)
|
||||
{
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if (NULL == handle) {
|
||||
OTA_LOG_ERROR("handle is NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_UNINITED == h_ota->state) {
|
||||
OTA_LOG_ERROR("handle is uninitialized");
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (IOT_OTAS_FETCHED == h_ota->state);
|
||||
}
|
||||
|
||||
|
||||
int IOT_OTA_FetchYield(void *handle, char *buf, uint32_t buf_len, uint32_t timeout_s)
|
||||
{
|
||||
int ret;
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if ((NULL == handle) || (NULL == buf) || (0 == buf_len)) {
|
||||
OTA_LOG_ERROR("invalid parameter");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (IOT_OTAS_FETCHING != h_ota->state) {
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return IOT_OTAE_INVALID_STATE;
|
||||
}
|
||||
|
||||
ret = ofc_Fetch(h_ota->ch_fetch, buf, buf_len, timeout_s);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("Fetch firmware failed");
|
||||
h_ota->state = IOT_OTAS_FETCHED;
|
||||
h_ota->type = IOT_OTAT_NONE;
|
||||
h_ota->err = IOT_OTAE_FETCH_FAILED;
|
||||
|
||||
if (h_ota->fetch_cb && h_ota->purl) {
|
||||
h_ota->fetch_cb(h_ota->user_data, 1, h_ota->size_file, h_ota->purl, h_ota->version);
|
||||
/* remove */
|
||||
h_ota->purl = NULL;
|
||||
} else if (h_ota->fetch_cota_cb && h_ota->cota_url) {
|
||||
h_ota->fetch_cota_cb(h_ota->user_data, 1, h_ota->configId, h_ota->configSize, h_ota->sign, h_ota->signMethod,
|
||||
h_ota->cota_url, h_ota->getType);
|
||||
/* remove */
|
||||
h_ota->cota_url = NULL;
|
||||
}
|
||||
h_ota->size_fetched = 0;
|
||||
return -1;
|
||||
} else if (0 == h_ota->size_fetched) {
|
||||
/* force report status in the first */
|
||||
IOT_OTA_ReportProgress(h_ota, IOT_OTAP_FETCH_PERCENTAGE_MIN, "Enter in downloading state");
|
||||
}
|
||||
|
||||
otalib_MD5Update(h_ota->md5, buf, ret);
|
||||
otalib_Sha256Update(h_ota->sha256, buf, ret);
|
||||
h_ota->size_last_fetched = ret;
|
||||
h_ota->size_fetched += ret;
|
||||
|
||||
if (h_ota->size_fetched >= h_ota->size_file) {
|
||||
h_ota->type = IOT_OTAT_NONE;
|
||||
h_ota->state = IOT_OTAS_FETCHED;
|
||||
if (h_ota->fetch_cb && h_ota->purl) {
|
||||
h_ota->fetch_cb(h_ota->user_data, 1, h_ota->size_file, h_ota->purl, h_ota->version);
|
||||
/* remove */
|
||||
h_ota->purl = NULL;
|
||||
} else if (h_ota->fetch_cota_cb && h_ota->cota_url) {
|
||||
h_ota->fetch_cota_cb(h_ota->user_data, 1, h_ota->configId, h_ota->configSize, h_ota->sign, h_ota->signMethod,
|
||||
h_ota->cota_url, h_ota->getType);
|
||||
/* remove */
|
||||
h_ota->cota_url = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int IOT_OTA_Ioctl(void *handle, IOT_OTA_CmdType_t type, void *buf, int buf_len)
|
||||
{
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if ((NULL == handle) || (NULL == buf) || (0 == buf_len)) {
|
||||
OTA_LOG_ERROR("invalid parameter");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (h_ota->state < IOT_OTAS_FETCHING) {
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
return IOT_OTAE_INVALID_STATE;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case IOT_OTAG_COTA_CONFIG_ID: {
|
||||
char **value = (char **)buf;
|
||||
if (value == NULL || *value != NULL || h_ota->configId == NULL) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*value = OTA_API_MALLOC(strlen(h_ota->configId) + 1);
|
||||
if (*value == NULL) {
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
memset(*value, 0, strlen(h_ota->configId) + 1);
|
||||
memcpy(*value, h_ota->configId, strlen(h_ota->configId));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_COTA_CONFIG_SIZE: {
|
||||
if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = h_ota->configSize;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_COTA_SIGN: {
|
||||
char **value = (char **)buf;
|
||||
if (value == NULL || *value != NULL || h_ota->sign == NULL) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*value = OTA_API_MALLOC(strlen(h_ota->sign) + 1);
|
||||
if (*value == NULL) {
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
memset(*value, 0, strlen(h_ota->sign) + 1);
|
||||
memcpy(*value, h_ota->sign, strlen(h_ota->sign));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_COTA_SIGN_METHOD: {
|
||||
char **value = (char **)buf;
|
||||
if (value == NULL || *value != NULL || h_ota->signMethod == NULL) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*value = OTA_API_MALLOC(strlen(h_ota->signMethod) + 1);
|
||||
if (*value == NULL) {
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
memset(*value, 0, strlen(h_ota->signMethod) + 1);
|
||||
memcpy(*value, h_ota->signMethod, strlen(h_ota->signMethod));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_COTA_URL: {
|
||||
char **value = (char **)buf;
|
||||
if (value == NULL || *value != NULL || h_ota->cota_url == NULL) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*value = OTA_API_MALLOC(strlen(h_ota->cota_url) + 1);
|
||||
if (*value == NULL) {
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
memset(*value, 0, strlen(h_ota->cota_url) + 1);
|
||||
memcpy(*value, h_ota->cota_url, strlen(h_ota->cota_url));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_COTA_GETTYPE: {
|
||||
char **value = (char **)buf;
|
||||
if (value == NULL || *value != NULL || h_ota->getType == NULL) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*value = OTA_API_MALLOC(strlen(h_ota->getType) + 1);
|
||||
if (*value == NULL) {
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
memset(*value, 0, strlen(h_ota->getType) + 1);
|
||||
memcpy(*value, h_ota->getType, strlen(h_ota->getType));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_OTA_TYPE: {
|
||||
if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = h_ota->type;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IOT_OTAG_FETCHED_SIZE:
|
||||
if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = h_ota->size_fetched;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case IOT_OTAG_FILE_SIZE:
|
||||
if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = h_ota->size_file;
|
||||
return 0;
|
||||
};
|
||||
|
||||
case IOT_OTAG_VERSION: {
|
||||
strncpy(buf, h_ota->version, buf_len);
|
||||
((char *)buf)[buf_len - 1] = '\0';
|
||||
}
|
||||
break;
|
||||
|
||||
case IOT_OTAG_MD5SUM:
|
||||
strncpy(buf, h_ota->md5sum, buf_len);
|
||||
((char *)buf)[buf_len - 1] = '\0';
|
||||
break;
|
||||
|
||||
case IOT_OTAG_CHECK_FIRMWARE:
|
||||
if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else if (h_ota->state != IOT_OTAS_FETCHED) {
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
OTA_LOG_ERROR("Firmware can be checked in IOT_OTAS_FETCHED state only");
|
||||
return -1;
|
||||
} else {
|
||||
char md5_str[33];
|
||||
otalib_MD5Finalize(h_ota->md5, md5_str);
|
||||
OTA_LOG_DEBUG("origin=%s, now=%s", h_ota->md5sum, md5_str);
|
||||
if (0 == strcmp(h_ota->md5sum, md5_str)) {
|
||||
*((uint32_t *)buf) = 1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = 0;
|
||||
IOT_OTA_ReportProgress(h_ota, IOT_OTAP_CHECK_FALIED, NULL);
|
||||
OTA_LOG_ERROR("image checksum compare failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case IOT_OTAG_CHECK_CONFIG:
|
||||
if ((4 != buf_len) || (0 != ((unsigned long)buf & 0x3))) {
|
||||
OTA_LOG_ERROR("Invalid parameter");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
} else if (h_ota->state != IOT_OTAS_FETCHED) {
|
||||
h_ota->err = IOT_OTAE_INVALID_STATE;
|
||||
OTA_LOG_ERROR("Config can be checked in IOT_OTAS_FETCHED state only");
|
||||
return -1;
|
||||
} else {
|
||||
if (0 == strncmp(h_ota->signMethod, "Md5", strlen(h_ota->signMethod))) {
|
||||
char md5_str[33];
|
||||
otalib_MD5Finalize(h_ota->md5, md5_str);
|
||||
OTA_LOG_DEBUG("origin=%s, now=%s", h_ota->sign, md5_str);
|
||||
if (0 == strcmp(h_ota->sign, md5_str)) {
|
||||
*((uint32_t *)buf) = 1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = 0;
|
||||
}
|
||||
}
|
||||
if (0 == strncmp(h_ota->signMethod, "Sha256", strlen(h_ota->signMethod))) {
|
||||
char sha256_str[65];
|
||||
otalib_Sha256Finalize(h_ota->sha256, sha256_str);
|
||||
OTA_LOG_DEBUG("origin=%s, now=%s", h_ota->sign, sha256_str);
|
||||
if (0 == strcmp(h_ota->sign, sha256_str)) {
|
||||
*((uint32_t *)buf) = 1;
|
||||
} else {
|
||||
*((uint32_t *)buf) = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case IOT_OTAG_RESET_FETCHED_SIZE: {
|
||||
h_ota->size_fetched = 0;
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
OTA_LOG_ERROR("invalid cmd type");
|
||||
h_ota->err = IOT_OTAE_INVALID_PARAM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Get last error code */
|
||||
int IOT_OTA_GetLastError(void *handle)
|
||||
{
|
||||
OTA_Struct_pt h_ota = (OTA_Struct_pt) handle;
|
||||
|
||||
if (NULL == handle) {
|
||||
OTA_LOG_ERROR("handle is NULL");
|
||||
return IOT_OTAE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return h_ota->err;
|
||||
}
|
||||
|
||||
|
||||
|
15
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota.h
vendored
Normal file
15
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota.h
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __IOTX_OTA_H__
|
||||
#define __IOTX_OTA_H__
|
||||
|
||||
int iotx_ota_get_config(void *handle, const char *configScope, const char *getType,
|
||||
const char *attributeKeys);
|
||||
|
||||
int iotx_req_image(void *handle, const char *version);
|
||||
|
||||
#endif /* #ifndef __IOTX_OTA_H__ */
|
||||
|
||||
|
14
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota_config.h
vendored
Normal file
14
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota_config.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __IOTX_OTA_CONFIG_H__
|
||||
#define __IOTX_OTA_CONFIG_H__
|
||||
|
||||
#ifndef OTA_SIGNAL_CHANNEL
|
||||
#define OTA_SIGNAL_CHANNEL (1)
|
||||
#endif
|
||||
|
||||
#endif /* __IOTX_OTA_CONFIG_H__ */
|
||||
|
||||
|
102
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota_internal.h
vendored
Normal file
102
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/iotx_ota_internal.h
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _IOTX_OTA_INTERNAL_H_
|
||||
#define _IOTX_OTA_INTERNAL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "infra_httpc.h"
|
||||
#include "infra_string.h"
|
||||
#include "infra_md5.h"
|
||||
#include "infra_sha256.h"
|
||||
#include "infra_json_parser.h"
|
||||
#include "ota_api.h"
|
||||
#include "iotx_ota_config.h"
|
||||
#include "ota_wrapper.h"
|
||||
|
||||
#ifdef INFRA_MEM_STATS
|
||||
#include "infra_mem_stats.h"
|
||||
#define OTA_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "ota")
|
||||
#define OTA_FREE(ptr) LITE_free(ptr)
|
||||
#define OTA_API_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "ota.api")
|
||||
#define OTA_API_FREE(ptr) LITE_free(ptr)
|
||||
#else
|
||||
#define OTA_MALLOC(size) HAL_Malloc(size)
|
||||
#define OTA_FREE(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
|
||||
#define OTA_API_MALLOC(size) HAL_Malloc(size)
|
||||
#define OTA_API_FREE(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
|
||||
#endif
|
||||
|
||||
#define OTA_SNPRINTF HAL_Snprintf
|
||||
|
||||
#ifdef INFRA_LOG
|
||||
#include "infra_log.h"
|
||||
#define OTA_LOG_CRIT(...) log_crit("ota", __VA_ARGS__)
|
||||
#define OTA_LOG_ERROR(...) log_err("ota", __VA_ARGS__)
|
||||
#define OTA_LOG_WRN(...) log_warning("ota", __VA_ARGS__)
|
||||
#define OTA_LOG_INFO(...) log_info("ota", __VA_ARGS__)
|
||||
#define OTA_LOG_DEBUG(...) log_debug("ota", __VA_ARGS__)
|
||||
#else
|
||||
#define OTA_LOG_CRIT(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define OTA_LOG_ERROR(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define OTA_LOG_WRN(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define OTA_LOG_INFO(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#define OTA_LOG_DEBUG(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
IOTX_OTA_TOPIC_TYPE_DEVICE_REQUEST = 1,
|
||||
IOTX_OTA_TOPIC_TYPE_DEVICE_UPGRATE = 2,
|
||||
IOTX_OTA_TOPIC_TYPE_CONFIG_GET = 3,
|
||||
IOTX_OTA_TOPIC_TYPE_CONFIG_PUSH = 4,
|
||||
IOTX_OTA_TOPIC_TYPE_MAX
|
||||
} iotx_ota_topic_types_t;
|
||||
|
||||
typedef int (*ota_cb_fpt)(void *pcontext, const char *msg, uint32_t msg_len, iotx_ota_topic_types_t type);
|
||||
/* is_fetch = 0; start fetch */
|
||||
/* is_fetch = 1; stop fetch */
|
||||
typedef void(*ota_fetch_cb_fpt)(void *user_data, int is_fetch, uint32_t size_file, char *purl, char *version);
|
||||
/* is_fetch = 0; start fetch */
|
||||
/* is_fetch = 1; stop fetch */
|
||||
typedef void(*cota_fetch_cb_fpt)(void *user_data, int is_fetch, char *configId, uint32_t configSize, char *sign, \
|
||||
char *signMethod, char *url, char *getType);
|
||||
|
||||
int iotx_ota_set_fetch_callback(void *pt, ota_fetch_cb_fpt fetch_cb, void *user_data);
|
||||
int iotx_ota_set_cota_fetch_callback(void *pt, cota_fetch_cb_fpt fetch_cb, void *user_data);
|
||||
|
||||
const char *otalib_JsonValueOf(const char *json, uint32_t json_len, const char *key, uint32_t *val_len);
|
||||
void *otalib_MD5Init(void);
|
||||
void otalib_MD5Update(void *md5, const char *buf, size_t buf_len);
|
||||
void otalib_MD5Finalize(void *md5, char *output_str);
|
||||
void otalib_MD5Deinit(void *md5);
|
||||
void *otalib_Sha256Init(void);
|
||||
void otalib_Sha256Update(void *sha256, const char *buf, size_t buf_len);
|
||||
void otalib_Sha256Finalize(void *sha256, char *output_str);
|
||||
void otalib_Sha256Deinit(void *sha256);
|
||||
int otalib_GetFirmwareFixlenPara(const char *json_doc,
|
||||
size_t json_doc_len,
|
||||
const char *key,
|
||||
char *dest,
|
||||
size_t dest_len);
|
||||
int otalib_GetFirmwareVarlenPara(const char *json_doc,
|
||||
size_t json_doc_len,
|
||||
const char *key,
|
||||
char **dest);
|
||||
int otalib_GetParams(const char *json_doc, uint32_t json_len, char **url, char **version, char *md5,
|
||||
uint32_t *file_size);
|
||||
int otalib_GetConfigParams(const char *json_doc, uint32_t json_len, char **configId, uint32_t *configSize, char **sign,
|
||||
char **signMethod, char **url, char **getType);
|
||||
int otalib_GenInfoMsg(char *buf, size_t buf_len, uint32_t id, const char *version);
|
||||
int otalib_GenReportMsg(char *buf, size_t buf_len, uint32_t id, int progress, const char *msg_detail);
|
||||
|
||||
void *ofc_Init(char *url);
|
||||
int32_t ofc_Fetch(void *handle, char *buf, uint32_t buf_len, uint32_t timeout_s);
|
||||
int ofc_Deinit(void *handle);
|
||||
|
||||
#endif /* _IOTX_OTA_INTERNAL_H_ */
|
||||
|
||||
|
242
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_api.h
vendored
Normal file
242
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_api.h
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __OTA_EXPORT_H__
|
||||
#define __OTA_EXPORT_H__
|
||||
|
||||
#include "infra_types.h"
|
||||
#include "infra_defs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OTA_CH_SIGNAL_MQTT (0)
|
||||
#define OTA_CH_SIGNAL_COAP (1)
|
||||
#define OTA_CH_FETCH_HTTP (1)
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
IOT_OTAE_GENERAL = -1,
|
||||
IOT_OTAE_INVALID_PARAM = -2,
|
||||
IOT_OTAE_INVALID_STATE = -3,
|
||||
IOT_OTAE_STR_TOO_LONG = -4,
|
||||
IOT_OTAE_FETCH_FAILED = -5,
|
||||
IOT_OTAE_NOMEM = -6,
|
||||
IOT_OTAE_OSC_FAILED = -7,
|
||||
IOT_OTAE_NONE = 0,
|
||||
|
||||
} IOT_OTA_Err_t;
|
||||
|
||||
|
||||
/* State of OTA */
|
||||
typedef enum {
|
||||
IOT_OTAS_UNINITED = 0, /* Uninitialized State */
|
||||
IOT_OTAS_INITED, /* Initialized State */
|
||||
IOT_OTAS_FETCHING, /* Fetching firmware */
|
||||
IOT_OTAS_FETCHED /* Fetching firmware finish */
|
||||
} IOT_OTA_State_t;
|
||||
|
||||
typedef enum {
|
||||
IOT_OTAT_NONE,
|
||||
IOT_OTAT_COTA,
|
||||
IOT_OTAT_FOTA
|
||||
} IOT_OTA_Type_t;
|
||||
|
||||
/* Progress of OTA */
|
||||
typedef enum {
|
||||
|
||||
/* Burn firmware file failed */
|
||||
IOT_OTAP_BURN_FAILED = -4,
|
||||
|
||||
/* Check firmware file failed */
|
||||
IOT_OTAP_CHECK_FALIED = -3,
|
||||
|
||||
/* Fetch firmware file failed */
|
||||
IOT_OTAP_FETCH_FAILED = -2,
|
||||
|
||||
/* Initialized failed */
|
||||
IOT_OTAP_GENERAL_FAILED = -1,
|
||||
|
||||
|
||||
/* [0, 100], percentage of fetch progress */
|
||||
|
||||
/* The minimum percentage of fetch progress */
|
||||
IOT_OTAP_FETCH_PERCENTAGE_MIN = 0,
|
||||
|
||||
/* The maximum percentage of fetch progress */
|
||||
IOT_OTAP_FETCH_PERCENTAGE_MAX = 100
|
||||
|
||||
} IOT_OTA_Progress_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
IOT_OTAG_COTA_CONFIG_ID,
|
||||
IOT_OTAG_COTA_CONFIG_SIZE,
|
||||
IOT_OTAG_COTA_SIGN,
|
||||
IOT_OTAG_COTA_SIGN_METHOD,
|
||||
IOT_OTAG_COTA_URL,
|
||||
IOT_OTAG_COTA_GETTYPE,
|
||||
IOT_OTAG_OTA_TYPE,
|
||||
IOT_OTAG_FETCHED_SIZE, /* option for get already fetched size */
|
||||
IOT_OTAG_FILE_SIZE, /* size of file */
|
||||
IOT_OTAG_MD5SUM, /* md5 in string format */
|
||||
IOT_OTAG_VERSION, /* version in string format */
|
||||
IOT_OTAG_CHECK_FIRMWARE, /* Check firmware is valid or not */
|
||||
IOT_OTAG_CHECK_CONFIG, /* Check config file is valid or not */
|
||||
IOT_OTAG_RESET_FETCHED_SIZE /* reset the size_fetched parameter to be 0 */
|
||||
} IOT_OTA_CmdType_t;
|
||||
|
||||
/** @defgroup group_api api
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup group_api_ota ota
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize OTA module, and return handle.
|
||||
* The MQTT client must be construct before calling this interface.
|
||||
*
|
||||
* @param [in] product_key: specify the product key.
|
||||
* @param [in] device_name: specify the device name.
|
||||
* @param [in] ch_signal: specify the signal channel.
|
||||
*
|
||||
* @retval 0 : Successful.
|
||||
* @retval -1 : Failed.
|
||||
* @see None.
|
||||
*/
|
||||
void *IOT_OTA_Init(const char *product_key, const char *device_name, void *ch_signal);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deinitialize OTA module specified by the 'handle', and release the related resource.
|
||||
* You must call this interface to release resource if reboot is not invoked after downloading.
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
*
|
||||
* @retval 0 : Successful.
|
||||
* @retval < 0 : Failed, the value is error code.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_Deinit(void *handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Report firmware version information to OTA server (optional).
|
||||
* NOTE: please
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
* @param [in] version: specify the firmware version in string format.
|
||||
*
|
||||
* @retval 0 : Successful.
|
||||
* @retval < 0 : Failed, the value is error code.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_ReportVersion(void *handle, const char *version);
|
||||
|
||||
/**
|
||||
* @brief Report detail progress to OTA server (optional).
|
||||
* NOTE: please
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
* @param [in] progress: specify the progress defined by 'IOT_OTA_Progress_t'.
|
||||
* @param [in] msg: detail progress information in string.
|
||||
*
|
||||
* @retval 0 : Successful.
|
||||
* @retval < 0 : Failed, the value is error code.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_ReportProgress(void *handle, IOT_OTA_Progress_t progress, const char *msg);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check whether is on fetching state
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
*
|
||||
* @retval 1 : Yes.
|
||||
* @retval 0 : No.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_IsFetching(void *handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check whether is on end-of-fetch state.
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
*
|
||||
* @retval 1 : Yes.
|
||||
* @retval 0 : False.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_IsFetchFinish(void *handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief fetch firmware from remote server with specific timeout value.
|
||||
* NOTE: If you want to download more faster, the bigger 'buf' should be given.
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
* @param [out] buf: specify the space for storing firmware data.
|
||||
* @param [in] buf_len: specify the length of 'buf' in bytes.
|
||||
* @param [in] timeout_s: specify the timeout value in second.
|
||||
*
|
||||
* @retval < 0 : Error occur..
|
||||
* @retval 0 : No any data be downloaded in 'timeout_s' timeout period.
|
||||
* @retval (0, len] : The length of data be downloaded in 'timeout_s' timeout period in bytes.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_FetchYield(void *handle, char *buf, uint32_t buf_len, uint32_t timeout_s);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get OTA information specified by 'type'.
|
||||
* By this interface, you can get information like state, size of file, md5 of file, etc.
|
||||
*
|
||||
* @param [in] handle: handle of the specific OTA
|
||||
* @param [in] type: specify what information you want, see detail 'IOT_OTA_CmdType_t'
|
||||
* @param [out] buf: specify buffer for data exchange
|
||||
* @param [in] buf_len: specify the length of 'buf' in byte.
|
||||
* @return
|
||||
@verbatim
|
||||
NOTE:
|
||||
1) When type is IOT_OTAG_FETCHED_SIZE, 'buf' should be pointer of uint32_t, and 'buf_len' should be 4.
|
||||
2) When type is IOT_OTAG_FILE_SIZE, 'buf' should be pointer of uint32_t, and 'buf_len' should be 4.
|
||||
3) When type is IOT_OTAG_MD5SUM, 'buf' should be a buffer, and 'buf_len' should be 33.
|
||||
4) When type is IOT_OTAG_VERSION, 'buf' should be a buffer, and 'buf_len' should be OTA_VERSION_LEN_MAX.
|
||||
5) When type is IOT_OTAG_CHECK_FIRMWARE, 'buf' should be pointer of uint32_t, and 'buf_len' should be 4.
|
||||
0, firmware is invalid; 1, firmware is valid.
|
||||
@endverbatim
|
||||
*
|
||||
* @retval 0 : Successful.
|
||||
* @retval < 0 : Failed, the value is error code.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_Ioctl(void *handle, IOT_OTA_CmdType_t type, void *buf, int buf_len);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get last error code.
|
||||
*
|
||||
* @param [in] handle: specify the OTA module.
|
||||
*
|
||||
* @return The error code.
|
||||
* @see None.
|
||||
*/
|
||||
int IOT_OTA_GetLastError(void *handle);
|
||||
|
||||
/** @} */ /* end of api_ota */
|
||||
/** @} */ /* end of api */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OTA_EXPORT_H__ */
|
||||
|
||||
|
160
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_coap.c
vendored
Normal file
160
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_coap.c
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __OTA_COAP_C_H__
|
||||
#define __OTA_COAP_C_H__
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
|
||||
#include "iotx_ota_internal.h"
|
||||
|
||||
/* OSC, OTA signal channel */
|
||||
|
||||
/* Specify the maximum characters of version */
|
||||
#define OSC_COAP_URI_MAX_LEN (135) /* IoTx CoAP uri maximal length */
|
||||
|
||||
|
||||
typedef struct {
|
||||
void *coap;
|
||||
const char *product_key;
|
||||
const char *device_name;
|
||||
ota_cb_fpt cb;
|
||||
void *context;
|
||||
} otacoap_Struct_t, *otacoap_Struct_pt;
|
||||
|
||||
|
||||
static otacoap_Struct_pt h_osc_coap = NULL;
|
||||
|
||||
static void otacoap_response_handler(void *arg, void *p_response)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned char *p_payload = NULL;
|
||||
iotx_coap_resp_code_t resp_code;
|
||||
IOT_CoAP_GetMessageCode(p_response, &resp_code);
|
||||
IOT_CoAP_GetMessagePayload(p_response, &p_payload, &len);
|
||||
OTA_LOG_DEBUG("CoAP response code = %d", resp_code);
|
||||
OTA_LOG_DEBUG("[CoAP msg_len=%d, msg=%s\r\n", len, p_payload);
|
||||
|
||||
if ((NULL != h_osc_coap) && (NULL != p_payload)) {
|
||||
h_osc_coap->cb(h_osc_coap->context, (const char *)p_payload, (uint32_t)len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Generate topic name according to @ota_topic_type, @product_key, @device_name */
|
||||
/* and then copy to @buf. */
|
||||
/* 0, successful; -1, failed */
|
||||
static int otacoap_GenTopicName(char *buf, size_t buf_len, const char *ota_topic_type, const char *product_key,
|
||||
const char *device_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = OTA_SNPRINTF(buf,
|
||||
buf_len,
|
||||
"/topic/ota/device/%s/%s/%s",
|
||||
ota_topic_type,
|
||||
product_key,
|
||||
device_name);
|
||||
|
||||
if (ret >= buf_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("snprintf failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* report progress of OTA */
|
||||
static int otacoap_Publish(otacoap_Struct_pt handle, const char *topic_type, const char *msg)
|
||||
{
|
||||
int ret;
|
||||
char uri[IOTX_URI_MAX_LEN + 1] = {0};
|
||||
iotx_message_t message;
|
||||
message.p_payload = (unsigned char *)msg;
|
||||
message.payload_len = (unsigned short)strlen(msg);
|
||||
message.resp_callback = otacoap_response_handler;
|
||||
message.msg_type = IOTX_MESSAGE_CON;
|
||||
message.content_type = IOTX_CONTENT_TYPE_JSON;
|
||||
|
||||
/* topic name: /topic/ota/device/${topic_type}/${productKey}/${deviceName} */
|
||||
ret = otacoap_GenTopicName(uri, OSC_COAP_URI_MAX_LEN, topic_type, handle->product_key, handle->device_name);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("generate topic name failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IOTX_SUCCESS != (ret = IOT_CoAP_SendMessage(handle->coap, (char *)uri, &message))) {
|
||||
OTA_LOG_ERROR("send CoAP msg failed%d", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *osc_Init(const char *product_key, const char *device_name, void *ch_signal, ota_cb_fpt cb, void *context)
|
||||
{
|
||||
otacoap_Struct_pt h_osc = NULL;
|
||||
|
||||
if (NULL == (h_osc = OTA_MALLOC(sizeof(otacoap_Struct_t)))) {
|
||||
OTA_LOG_ERROR("allocate for h_osc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(h_osc, 0, sizeof(otacoap_Struct_t));
|
||||
|
||||
h_osc->coap = ch_signal;
|
||||
h_osc->product_key = product_key;
|
||||
h_osc->device_name = device_name;
|
||||
h_osc->cb = cb;
|
||||
h_osc->context = context;
|
||||
|
||||
h_osc_coap = h_osc;
|
||||
|
||||
return h_osc;
|
||||
}
|
||||
|
||||
|
||||
int osc_Deinit(void *handle)
|
||||
{
|
||||
if (NULL != handle) {
|
||||
OTA_FREE(handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* report progress of OTA */
|
||||
int osc_ReportProgress(void *handle, const char *msg)
|
||||
{
|
||||
return otacoap_Publish(handle, "progress", msg);
|
||||
}
|
||||
|
||||
|
||||
/* report version of OTA firmware */
|
||||
int osc_ReportVersion(void *handle, const char *msg)
|
||||
{
|
||||
static int state = 0;
|
||||
int ret;
|
||||
|
||||
if (0 == state) { /* report version in initial state */
|
||||
ret = otacoap_Publish(handle, "inform", msg);
|
||||
if (0 != ret) {
|
||||
return ret;
|
||||
}
|
||||
state = 1;
|
||||
}
|
||||
|
||||
/* request new firmware after initial state */
|
||||
return otacoap_Publish(handle, "request", msg);
|
||||
}
|
||||
|
||||
#endif /* #if (OTA_SIGNAL_CHANNEL) == 2 */
|
||||
#endif
|
||||
|
||||
|
||||
|
88
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_fetch.c
vendored
Normal file
88
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_fetch.c
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "iotx_ota_internal.h"
|
||||
|
||||
/* ofc, OTA fetch channel */
|
||||
|
||||
typedef struct {
|
||||
|
||||
const char *url;
|
||||
httpclient_t http; /* http client */
|
||||
httpclient_data_t http_data; /* http client data */
|
||||
|
||||
} otahttp_Struct_t, *otahttp_Struct_pt;
|
||||
|
||||
extern int httpclient_common(httpclient_t *client,
|
||||
const char *url,
|
||||
int port,
|
||||
const char *ca_crt,
|
||||
HTTPCLIENT_REQUEST_TYPE method,
|
||||
uint32_t timeout_ms,
|
||||
httpclient_data_t *client_data);
|
||||
|
||||
void *ofc_Init(char *url)
|
||||
{
|
||||
otahttp_Struct_pt h_odc;
|
||||
|
||||
if (NULL == (h_odc = OTA_MALLOC(sizeof(otahttp_Struct_t)))) {
|
||||
OTA_LOG_ERROR("allocate for h_odc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(h_odc, 0, sizeof(otahttp_Struct_t));
|
||||
|
||||
/* set http request-header parameter */
|
||||
h_odc->http.header = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" \
|
||||
"Accept-Encoding: gzip, deflate\r\n";
|
||||
#if defined(SUPPORT_ITLS)
|
||||
char *s_ptr = strstr(url, "://");
|
||||
if (strlen("https") == (s_ptr - url) && (0 == strncmp(url, "https", strlen("https")))) {
|
||||
strncpy(url + 1, url, strlen("http"));
|
||||
url++;
|
||||
}
|
||||
#endif
|
||||
h_odc->url = url;
|
||||
|
||||
return h_odc;
|
||||
}
|
||||
|
||||
|
||||
extern const char *iotx_ca_crt;
|
||||
|
||||
int32_t ofc_Fetch(void *handle, char *buf, uint32_t buf_len, uint32_t timeout_s)
|
||||
{
|
||||
int diff;
|
||||
otahttp_Struct_pt h_odc = (otahttp_Struct_pt)handle;
|
||||
|
||||
h_odc->http_data.response_buf = buf;
|
||||
h_odc->http_data.response_buf_len = buf_len;
|
||||
diff = h_odc->http_data.response_content_len - h_odc->http_data.retrieve_len;
|
||||
|
||||
#if !defined(SUPPORT_TLS)
|
||||
if (0 != httpclient_common(&h_odc->http, h_odc->url, 80, 0, HTTPCLIENT_GET, timeout_s * 1000,
|
||||
&h_odc->http_data)) {
|
||||
#else
|
||||
if (0 != httpclient_common(&h_odc->http, h_odc->url, 443, iotx_ca_crt, HTTPCLIENT_GET, timeout_s * 1000,
|
||||
&h_odc->http_data)) {
|
||||
#endif
|
||||
OTA_LOG_ERROR("fetch firmware failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return h_odc->http_data.response_content_len - h_odc->http_data.retrieve_len - diff;
|
||||
}
|
||||
|
||||
|
||||
int ofc_Deinit(void *handle)
|
||||
{
|
||||
if (NULL != handle) {
|
||||
OTA_FREE(handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
285
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_lib.c
vendored
Normal file
285
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_lib.c
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "iotx_ota_internal.h"
|
||||
|
||||
const char *otalib_JsonValueOf(const char *json, uint32_t json_len, const char *key, uint32_t *val_len)
|
||||
{
|
||||
int length;
|
||||
const char *val;
|
||||
val = json_get_value_by_name((char *)json, json_len, (char *)key, &length, NULL);
|
||||
if (NULL != val) {
|
||||
*val_len = (uint32_t) length;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void *otalib_MD5Init(void)
|
||||
{
|
||||
iot_md5_context *ctx = OTA_MALLOC(sizeof(iot_md5_context));
|
||||
if (NULL == ctx) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utils_md5_init(ctx);
|
||||
utils_md5_starts(ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void otalib_MD5Update(void *md5, const char *buf, size_t buf_len)
|
||||
{
|
||||
utils_md5_update(md5, (unsigned char *)buf, buf_len);
|
||||
}
|
||||
|
||||
void otalib_MD5Finalize(void *md5, char *output_str)
|
||||
{
|
||||
int i;
|
||||
unsigned char buf_out[16];
|
||||
utils_md5_finish(md5, buf_out);
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
output_str[i * 2] = infra_hex2char(buf_out[i] >> 4);
|
||||
output_str[i * 2 + 1] = infra_hex2char(buf_out[i]);
|
||||
}
|
||||
output_str[32] = '\0';
|
||||
}
|
||||
|
||||
void otalib_MD5Deinit(void *md5)
|
||||
{
|
||||
if (NULL != md5) {
|
||||
OTA_FREE(md5);
|
||||
}
|
||||
}
|
||||
|
||||
void *otalib_Sha256Init(void)
|
||||
{
|
||||
iot_sha256_context *ctx = OTA_MALLOC(sizeof(iot_sha256_context));
|
||||
if (NULL == ctx) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utils_sha256_init(ctx);
|
||||
utils_sha256_starts(ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void otalib_Sha256Update(void *sha256, const char *buf, size_t buf_len)
|
||||
{
|
||||
utils_sha256_update(sha256, (unsigned char *)buf, buf_len);
|
||||
}
|
||||
|
||||
void otalib_Sha256Finalize(void *sha256, char *output_str)
|
||||
{
|
||||
int i;
|
||||
unsigned char buf_out[32];
|
||||
utils_sha256_finish(sha256, buf_out);
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
output_str[i * 2] = infra_hex2char(buf_out[i] >> 4);
|
||||
output_str[i * 2 + 1] = infra_hex2char(buf_out[i]);
|
||||
}
|
||||
output_str[64] = '\0';
|
||||
}
|
||||
|
||||
void otalib_Sha256Deinit(void *sha256)
|
||||
{
|
||||
utils_sha256_free(sha256);
|
||||
if (NULL != sha256) {
|
||||
OTA_FREE(sha256);
|
||||
}
|
||||
}
|
||||
/* Get the specific @key value, and copy to @dest */
|
||||
/* 0, successful; -1, failed */
|
||||
int otalib_GetFirmwareFixlenPara(const char *json_doc,
|
||||
size_t json_doc_len,
|
||||
const char *key,
|
||||
char *dest,
|
||||
size_t dest_len)
|
||||
{
|
||||
const char *pvalue;
|
||||
uint32_t val_len;
|
||||
|
||||
if (NULL == (pvalue = otalib_JsonValueOf(json_doc, json_doc_len, key, &val_len))) {
|
||||
OTA_LOG_ERROR("Not '%s' key in json doc of OTA", key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (val_len > dest_len) {
|
||||
OTA_LOG_ERROR("value length of the key is too long");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dest, pvalue, val_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Get variant length parameter of firmware, and copy to @dest */
|
||||
/* 0, successful; -1, failed */
|
||||
int otalib_GetFirmwareVarlenPara(const char *json_doc,
|
||||
size_t json_doc_len,
|
||||
const char *key,
|
||||
char **dest)
|
||||
{
|
||||
const char *pvalue;
|
||||
uint32_t val_len;
|
||||
|
||||
if (NULL == (pvalue = otalib_JsonValueOf(json_doc, json_doc_len, key, &val_len))) {
|
||||
OTA_LOG_ERROR("Not %s key in json doc of OTA", key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == (*dest = OTA_MALLOC(val_len + 1))) {
|
||||
OTA_LOG_ERROR("allocate for dest failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(*dest, pvalue, val_len);
|
||||
(*dest)[val_len] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int otalib_GetParams(const char *json_doc, uint32_t json_len, char **url, char **version, char *md5,
|
||||
uint32_t *file_size)
|
||||
{
|
||||
#define OTA_FILESIZE_STR_LEN (16)
|
||||
char file_size_str[OTA_FILESIZE_STR_LEN + 1] = {0};
|
||||
|
||||
/* get version */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "version", version)) {
|
||||
OTA_LOG_ERROR("get value of version key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get URL */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "url", url)) {
|
||||
OTA_LOG_ERROR("get value of url key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get md5 */
|
||||
if (0 != otalib_GetFirmwareFixlenPara(json_doc, json_len, "md5", md5, 32)) {
|
||||
OTA_LOG_ERROR("get value of md5 key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get file size */
|
||||
if (0 != otalib_GetFirmwareFixlenPara(json_doc, json_len, "size", file_size_str, OTA_FILESIZE_STR_LEN)) {
|
||||
OTA_LOG_ERROR("get value of size key failed");
|
||||
return -1;
|
||||
}
|
||||
file_size_str[OTA_FILESIZE_STR_LEN] = '\0';
|
||||
*file_size = atoi(file_size_str);
|
||||
|
||||
return 0;
|
||||
|
||||
#undef OTA_FILESIZE_STR_LEN
|
||||
}
|
||||
|
||||
int otalib_GetConfigParams(const char *json_doc, uint32_t json_len, char **configId, uint32_t *configSize, char **sign,
|
||||
char **signMethod, char **url, char **getType)
|
||||
{
|
||||
#define OTA_FILESIZE_STR_LEN (16)
|
||||
char file_size_str[OTA_FILESIZE_STR_LEN + 1];
|
||||
|
||||
/* get configId */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "configId", configId)) {
|
||||
OTA_LOG_ERROR("get value of configId key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get configSize */
|
||||
if (0 != otalib_GetFirmwareFixlenPara(json_doc, json_len, "configSize", file_size_str, OTA_FILESIZE_STR_LEN)) {
|
||||
OTA_LOG_ERROR("get value of size key failed");
|
||||
return -1;
|
||||
}
|
||||
file_size_str[OTA_FILESIZE_STR_LEN] = '\0';
|
||||
*configSize = atoi(file_size_str);
|
||||
|
||||
/* get sign */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "sign", sign)) {
|
||||
OTA_LOG_ERROR("get value of sign key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get signMethod */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "signMethod", signMethod)) {
|
||||
OTA_LOG_ERROR("get value of signMethod key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get url */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "url", url)) {
|
||||
OTA_LOG_ERROR("get value of url key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get getType */
|
||||
if (0 != otalib_GetFirmwareVarlenPara(json_doc, json_len, "getType", getType)) {
|
||||
OTA_LOG_ERROR("get value of getType key failed");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
#undef OTA_FILESIZE_STR_LEN
|
||||
}
|
||||
|
||||
/* Generate firmware information according to @id, @version */
|
||||
/* and then copy to @buf. */
|
||||
/* 0, successful; -1, failed */
|
||||
int otalib_GenInfoMsg(char *buf, size_t buf_len, uint32_t id, const char *version)
|
||||
{
|
||||
int ret;
|
||||
ret = HAL_Snprintf(buf,
|
||||
buf_len,
|
||||
"{\"id\":%d,\"params\":{\"version\":\"%s\"}}",
|
||||
id,
|
||||
version);
|
||||
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("HAL_Snprintf failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate report information according to @id, @msg */
|
||||
/* and then copy to @buf. */
|
||||
/* 0, successful; -1, failed */
|
||||
int otalib_GenReportMsg(char *buf, size_t buf_len, uint32_t id, int progress, const char *msg_detail)
|
||||
{
|
||||
int ret;
|
||||
if (NULL == msg_detail) {
|
||||
ret = HAL_Snprintf(buf,
|
||||
buf_len,
|
||||
"{\"id\":%d,\"params\":{\"step\":\"%d\",\"desc\":\"\"}}",
|
||||
id,
|
||||
progress);
|
||||
} else {
|
||||
ret = HAL_Snprintf(buf,
|
||||
buf_len,
|
||||
"{\"id\":%d,\"params\":{\"step\":\"%d\",\"desc\":\"%s\"}}",
|
||||
id,
|
||||
progress,
|
||||
msg_detail);
|
||||
}
|
||||
|
||||
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("HAL_Snprintf failed");
|
||||
return -1;
|
||||
} else if (ret >= buf_len) {
|
||||
OTA_LOG_ERROR("msg is too long");
|
||||
return IOT_OTAE_STR_TOO_LONG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
301
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_mqtt.c
vendored
Normal file
301
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_mqtt.c
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __OTA_MQTT_C_H__
|
||||
#define __OTA_MQTT_C_H__
|
||||
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
|
||||
#include "mqtt_api.h"
|
||||
#include "ota_api.h"
|
||||
#include "iotx_ota_internal.h"
|
||||
|
||||
/* OSC, OTA signal channel */
|
||||
|
||||
/* Specify the maximum characters of version */
|
||||
#define OTA_MQTT_TOPIC_LEN (128)
|
||||
|
||||
typedef struct {
|
||||
void *mqtt;
|
||||
const char *product_key;
|
||||
const char *device_name;
|
||||
char topic_upgrade[OTA_MQTT_TOPIC_LEN];
|
||||
char topic_request[OTA_MQTT_TOPIC_LEN];
|
||||
char topic_config_get[OTA_MQTT_TOPIC_LEN];
|
||||
char topic_config_push[OTA_MQTT_TOPIC_LEN];
|
||||
ota_cb_fpt cb;
|
||||
void *context;
|
||||
} otamqtt_Struct_t, *otamqtt_Struct_pt;
|
||||
|
||||
|
||||
/* Generate topic name according to @ota_topic_type, @product_key, @device_name */
|
||||
/* and then copy to @buf. */
|
||||
/* 0, successful; -1, failed */
|
||||
static int otamqtt_GenTopicName(char *buf, size_t buf_len, const char *ota_topic_type, const char *product_key,
|
||||
const char *device_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_Snprintf(buf,
|
||||
buf_len,
|
||||
"/ota/device/%s/%s/%s",
|
||||
ota_topic_type,
|
||||
product_key,
|
||||
device_name);
|
||||
|
||||
if (ret >= buf_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("HAL_Snprintf failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* report progress of OTA */
|
||||
static int otamqtt_Publish(otamqtt_Struct_pt handle, const char *topic_type, int qos, const char *msg)
|
||||
{
|
||||
int ret;
|
||||
char topic_name[OTA_MQTT_TOPIC_LEN];
|
||||
iotx_mqtt_topic_info_t topic_info;
|
||||
|
||||
memset(&topic_info, 0, sizeof(iotx_mqtt_topic_info_t));
|
||||
|
||||
if (0 == qos) {
|
||||
topic_info.qos = IOTX_MQTT_QOS0;
|
||||
} else {
|
||||
topic_info.qos = IOTX_MQTT_QOS1;
|
||||
}
|
||||
topic_info.payload = (void *)msg;
|
||||
topic_info.payload_len = strlen(msg);
|
||||
|
||||
/* inform OTA to topic: "/ota/device/progress/$(product_key)/$(device_name)" */
|
||||
ret = otamqtt_GenTopicName(topic_name, OTA_MQTT_TOPIC_LEN, topic_type, handle->product_key, handle->device_name);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("generate topic name of info failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = IOT_MQTT_Publish(handle->mqtt, topic_name, &topic_info);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("publish failed");
|
||||
return IOT_OTAE_OSC_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int otamqtt_publish_full_topic(otamqtt_Struct_pt handle, const char *topic_name,
|
||||
iotx_mqtt_topic_info_pt topic_msg)
|
||||
{
|
||||
if (IOT_MQTT_Publish(handle->mqtt, topic_name, topic_msg) < 0) {
|
||||
OTA_LOG_ERROR("publish failed");
|
||||
return IOT_OTAE_OSC_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* decode JSON string to get firmware information, like firmware version, URL, file size, MD5. */
|
||||
/* return NONE */
|
||||
static void otamqtt_UpgrageCb(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
|
||||
{
|
||||
otamqtt_Struct_pt handle = (otamqtt_Struct_pt) pcontext;
|
||||
iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
|
||||
|
||||
OTA_LOG_DEBUG("topic=%.*s", topic_info->topic_len, topic_info->ptopic);
|
||||
OTA_LOG_DEBUG("len=%u, topic_msg=%.*s", topic_info->payload_len, topic_info->payload_len, (char *)topic_info->payload);
|
||||
|
||||
if (IOTX_MQTT_EVENT_PUBLISH_RECEIVED != msg->event_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL != strstr(topic_info->ptopic, "/ota/device/request")) {
|
||||
OTA_LOG_DEBUG("receive device request");
|
||||
/*if(NULL != HAL_strnstr(topic_info->payload, topic_info->payload_len,
|
||||
"url", strlen("url")))*/
|
||||
if (NULL != strstr(topic_info->payload, "url")) {
|
||||
OTA_LOG_INFO("get request reply for new version image");
|
||||
if (NULL != handle->cb) {
|
||||
handle->cb(handle->context, topic_info->payload, topic_info->payload_len, IOTX_OTA_TOPIC_TYPE_DEVICE_REQUEST);
|
||||
}
|
||||
}
|
||||
} else if (NULL != strstr(topic_info->ptopic, "/ota/device/upgrade")) {
|
||||
OTA_LOG_DEBUG("receive device upgrade");
|
||||
if (NULL != handle->cb) {
|
||||
handle->cb(handle->context, topic_info->payload, topic_info->payload_len, IOTX_OTA_TOPIC_TYPE_DEVICE_UPGRATE);
|
||||
}
|
||||
} else if (NULL != strstr(topic_info->ptopic, "/thing/config/get_reply")) {
|
||||
OTA_LOG_DEBUG("receive config get_reply");
|
||||
if (NULL != handle->cb) {
|
||||
handle->cb(handle->context, topic_info->payload, topic_info->payload_len, IOTX_OTA_TOPIC_TYPE_CONFIG_GET);
|
||||
}
|
||||
} else if (NULL != strstr(topic_info->ptopic, "/thing/config/push")) {
|
||||
OTA_LOG_DEBUG("receive config push");
|
||||
if (NULL != handle->cb) {
|
||||
if (0 != handle->cb(handle->context, topic_info->payload, topic_info->payload_len, IOTX_OTA_TOPIC_TYPE_CONFIG_PUSH)) {
|
||||
/* fail, send fail response code:400 */
|
||||
const char *pvalue;
|
||||
uint32_t val_len;
|
||||
char topic[OTA_MQTT_TOPIC_LEN] = {0};
|
||||
char message[OTA_MQTT_TOPIC_LEN] = {0};
|
||||
iotx_mqtt_topic_info_t message_info;
|
||||
|
||||
memset(&message_info, 0, sizeof(iotx_mqtt_topic_info_t));
|
||||
|
||||
pvalue = otalib_JsonValueOf(topic_info->payload, topic_info->payload_len, "id", &val_len);
|
||||
|
||||
HAL_Snprintf(topic,
|
||||
OTA_MQTT_TOPIC_LEN,
|
||||
"/sys/%s/%s/thing/config/push_reply",
|
||||
handle->product_key,
|
||||
handle->device_name);
|
||||
HAL_Snprintf(message,
|
||||
OTA_MQTT_TOPIC_LEN,
|
||||
"\"id\":%.*s,\"code\":\"%d\",\"data\":{}",
|
||||
val_len,
|
||||
pvalue,
|
||||
400);
|
||||
message_info.qos = IOTX_MQTT_QOS0;
|
||||
message_info.payload = (void *)message;
|
||||
message_info.payload_len = strlen(message);
|
||||
|
||||
if (IOT_MQTT_Publish(handle->mqtt, topic, &message_info) < 0) {
|
||||
OTA_LOG_ERROR("publish failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *osc_Init(const char *product_key, const char *device_name, void *ch_signal, ota_cb_fpt cb, void *context)
|
||||
{
|
||||
int ret;
|
||||
otamqtt_Struct_pt h_osc = NULL;
|
||||
|
||||
if (NULL == (h_osc = OTA_MALLOC(sizeof(otamqtt_Struct_t)))) {
|
||||
OTA_LOG_ERROR("allocate for h_osc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(h_osc, 0, sizeof(otamqtt_Struct_t));
|
||||
|
||||
/* subscribe the OTA topic: "/ota/device/request/$(product_key)/$(device_name)" */
|
||||
ret = otamqtt_GenTopicName(h_osc->topic_request, OTA_MQTT_TOPIC_LEN, "request", product_key, device_name);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("generate topic name of request failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = IOT_MQTT_Subscribe(ch_signal, h_osc->topic_request, IOTX_MQTT_QOS1, otamqtt_UpgrageCb, h_osc);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("mqtt subscribe failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
/* subscribe the OTA topic: "/ota/device/upgrade/$(product_key)/$(device_name)" */
|
||||
ret = otamqtt_GenTopicName(h_osc->topic_upgrade, OTA_MQTT_TOPIC_LEN, "upgrade", product_key, device_name);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("generate topic name of upgrade failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = IOT_MQTT_Subscribe(ch_signal, h_osc->topic_upgrade, IOTX_MQTT_QOS1, otamqtt_UpgrageCb, h_osc);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("mqtt subscribe failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
/* subscribe the OTA topic: "/sys/{productKey}/{deviceName}/thing/config/get_reply" */
|
||||
ret = HAL_Snprintf(h_osc->topic_config_get,
|
||||
OTA_MQTT_TOPIC_LEN,
|
||||
"/sys/%s/%s/thing/config/get_reply",
|
||||
product_key,
|
||||
device_name);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("generate topic name of config get failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = IOT_MQTT_Subscribe(ch_signal, h_osc->topic_config_get, IOTX_MQTT_QOS0, otamqtt_UpgrageCb, h_osc);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("mqtt subscribe failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
/* subscribe the OTA topic: "/sys/{productKey}/{deviceName}/thing/config/push" */
|
||||
ret = HAL_Snprintf(h_osc->topic_config_push,
|
||||
OTA_MQTT_TOPIC_LEN,
|
||||
"/sys/%s/%s/thing/config/push",
|
||||
product_key,
|
||||
device_name);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("generate topic name of config get failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
ret = IOT_MQTT_Subscribe(ch_signal, h_osc->topic_config_push, IOTX_MQTT_QOS0, otamqtt_UpgrageCb, h_osc);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_ERROR("mqtt subscribe failed");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
h_osc->mqtt = ch_signal;
|
||||
h_osc->product_key = product_key;
|
||||
h_osc->device_name = device_name;
|
||||
h_osc->cb = cb;
|
||||
h_osc->context = context;
|
||||
|
||||
return h_osc;
|
||||
|
||||
do_exit:
|
||||
if (NULL != h_osc) {
|
||||
OTA_FREE(h_osc);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int osc_Deinit(void *handle)
|
||||
{
|
||||
if (NULL != handle) {
|
||||
OTA_FREE(handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* report progress of OTA */
|
||||
int osc_ReportProgress(void *handle, const char *msg)
|
||||
{
|
||||
return otamqtt_Publish(handle, "progress", 0, msg);
|
||||
}
|
||||
|
||||
|
||||
/* report version of OTA firmware */
|
||||
int osc_ReportVersion(void *handle, const char *msg)
|
||||
{
|
||||
return otamqtt_Publish(handle, "inform", 1, msg);
|
||||
}
|
||||
|
||||
/* request the OTA firmware pushed by user*/
|
||||
int osc_RequestImage(void *handle, const char *msg)
|
||||
{
|
||||
return otamqtt_Publish(handle, "request", 1, msg);
|
||||
}
|
||||
|
||||
/* request the config */
|
||||
int osc_RequestConfig(void *handle, const char *topic_name, iotx_mqtt_topic_info_pt topic_msg)
|
||||
{
|
||||
return otamqtt_publish_full_topic(handle, topic_name, topic_msg);
|
||||
}
|
||||
|
||||
#endif /* #if (OTA_SIGNAL_CHANNEL) == 1 */
|
||||
#endif /* #ifndef __OTA_MQTT_C_H__ */
|
||||
|
||||
|
16
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_wrapper.h
vendored
Normal file
16
components/connectivity/iotkit-embedded-3.0.1/3rdparty/src/ota/ota_wrapper.h
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _OTA_WRAPPER_H_
|
||||
#define _OTA_WRAPPER_H_
|
||||
|
||||
#include "infra_types.h"
|
||||
|
||||
void *HAL_Malloc(uint32_t size);
|
||||
void HAL_Free(void *ptr);
|
||||
void HAL_Printf(const char *fmt, ...);
|
||||
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
|
||||
|
||||
int HAL_SetProductKey(char *product_key);
|
||||
int HAL_SetDeviceName(char *device_name);
|
||||
int HAL_SetDeviceSecret(char *device_secret);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user