Files
kunlun/app/bsrm/iot_bsrm_pm_upgrade.c
2024-09-28 14:24:04 +08:00

902 lines
28 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os_shim header files */
#include "os_types_api.h"
#include "os_timer_api.h"
#include "os_utils_api.h"
#include "iot_errno_api.h"
#include "proto_645.h"
#include "proto_69845.h"
#include "iot_bsrm_common.h"
#include "iot_bsrm_pm_upgrade_img.h"
#if IOT_BSRM_PM_UPGRADE_ENABLE
/* pm upgrade cmd retry max count */
#define IOT_BSRM_PM_UPGRADE_RETRY_MAX_CNT (3)
/* resend pm miss image data max count */
#define IOT_BSRM_PM_UPGRADE_RESEND_MAX_CNT (2)
/* define pm upgrade status */
/* meter upgrade idle */
#define IOT_BSRM_PM_UPGRADE_STATE_IDLE (0)
/* check meter version */
#define IOT_BSRM_PM_UPGRADE_STATE_CHECK_VER (1)
/* translate upgrade file info */
#define IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_INFO (2)
/* translate upgrade data */
#define IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_DATA (3)
/* query upgrade file status info */
#define IOT_BSRM_PM_UPGRADE_STATE_QUERY_INFO (4)
/* exe upgrade */
#define IOT_BSRM_PM_UPGRADE_STATE_EXE (5)
/* default timeout time for upgrade cmd response, uint is 1ms. */
#define IOT_BSRM_PM_UPGRADE_DEFAULT_RSP_TIMEOUT (2000)
/* the timeout time for broadcast data timeout, uint is 1ms. */
#define IOT_BSRM_PM_UPGRADE_BROADCAST_TIMEOUT (1000)
/* bsrm pm upgrade info */
typedef struct _iot_bsrm_pm_upgrade_info {
/* upgrade pm status see - IOT_BSRM_PM_UPGRADE_STATE_XXX */
uint8_t state;
/* retry upgrade cmd count */
uint8_t retry_cnt : 4,
/* resend miss transfile data count */
resend_cnt : 4;
/* transfile block index */
uint16_t block_index;
/* total block count */
uint16_t block_cnt;
/* img bitmap */
uint8_t *bitmap;
/* img bitmap size */
uint16_t bitmap_size;
} iot_bsrm_pm_upgrade_info_t;
static iot_bsrm_pm_upgrade_info_t *g_pm_upgrade_info = NULL;
static uint32_t iot_bsrm_pm_upgrade_get_block_to_resend(uint16_t src_index,
uint16_t *dec_index)
{
if (src_index >= g_pm_upgrade_info->block_cnt) {
return ERR_FAIL;
}
/* check if pm received all block in the window */
for (; src_index < g_pm_upgrade_info->block_cnt; ++src_index) {
/* bit7~bit0 is index0~index7 */
if (0 == (g_pm_upgrade_info->bitmap[src_index >> 3] &
(0x80 >> (src_index & 0x7)))) {
break;
}
}
if (src_index == g_pm_upgrade_info->block_cnt) {
return ERR_FAIL;
}
iot_bsrm_printf("%s rsc data: %08x, index: %d \n",
__FUNCTION__, g_pm_upgrade_info->bitmap[src_index >> 3],
src_index);
*dec_index = src_index;
return ERR_OK;
}
static iot_pkt_t *iot_bsrm_pm_upgrade_build_69845_check_pkt()
{
server_addr_info_t server = {0};
proto_69845_app_get_req_info_t req = {0};
req.type = PROTO_69845_APP_GET_NORMAL;
req.piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
req.piid.sn = 0;
req.oad.oi = PROTO_69845_APP_OI_ELE_ID;
req.oad.attribute_id = 3;
req.oad.attribute_char = 0;
req.oad.element_index = 0;
server.len = IOT_MAC_ADDR_LEN;
server.type = PROTO_69845_SA_TYPE_WILDCARD;
iot_mac_addr_cpy(server.addr, proto_645_any_addr);
return proto_69845_build_get_req_msg(&req, &server);
}
static iot_pkt_t *iot_bsrm_pm_upgrade_build_69845_fileinfo_pkt()
{
iot_pkt_t *pkt = NULL;
proto_69845_app_action_req_single_t *req_info;
uint8_t file_info_data[128] = { 0 }, *app_data;
uint16_t i;
uint32_t local_ver = iot_bsrm_pm_get_local_img_version();
uint32_t size = iot_bsrm_pm_get_local_img_size();
uint32_t crc = iot_bsrm_pm_get_local_img_crc();
server_addr_info_t server_info = {0};
char ver_string[16];
server_info.len = PROTO_69845_SA_LEN;
server_info.type = PROTO_69845_SA_TYPE_WILDCARD;
iot_mac_addr_cpy(server_info.addr, proto_645_any_addr);
req_info = (proto_69845_app_action_req_single_t *)file_info_data;
req_info->omd.method_id = PROTO_OMD_TRANSFILE_INFO_START_METHOD_ID;
req_info->omd.oi = PROTO_69845_APP_OI_FILETRANS_BLOCK;
req_info->omd.operation_mode = 0;
req_info->data.data_type = PROTO_69845_APP_DATA_STRUCTURE;
app_data = (file_info_data + sizeof(*req_info));
i = 0;
app_data[i++] = 6;
/* file info, type is struct */
app_data[i++] = PROTO_69845_APP_DATA_STRUCTURE;
app_data[i++] = 6;
/* src file path, type is visible string */
app_data[i++] = PROTO_69845_APP_DATA_VISIBLE_STRING;
app_data[i++] = 1;
/* src file is null */
app_data[i++] = 0x30;
/* destination file path, type is visible string */
app_data[i++] = PROTO_69845_APP_DATA_VISIBLE_STRING;
app_data[i++] = 1;
/* destination file is null */
app_data[i++] = 0x30;
/* file size type is double long unsigned */
app_data[i++] = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_uint32_to_bytes(size, app_data + i, 1);
i += PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
/* file attribute, type is bit-string size 3, bit0 - 1 read, 0 not read;
bit1 - 1 write, 0 not write; bit2 - 1 exe, 0 not exe.
*/
app_data[i++] = PROTO_69845_APP_DATA_BIT_STRING;
app_data[i++] = 3;
app_data[i++] = 0;
/* file version, type is visible string */
app_data[i++] = PROTO_69845_APP_DATA_VISIBLE_STRING;
/* local image version */
app_data[i] = iot_sprintf(ver_string, "%d", local_ver);
os_mem_cpy(app_data + i + 1, ver_string, app_data[i]);
i += app_data[i] + 1;
/* file type, type is enum, 0 - local file, 1 - other file */
app_data[i++] = PROTO_69845_APP_DATA_ENUM;
app_data[i++] = 0;
/* translate block size, type is long unsigned */
app_data[i++] = PROTO_69845_APP_DATA_LONG_UNSIGNED;
iot_uint16_to_bytes(IOT_BSRM_PM_UPGRADE_BLOCK_SIZE, app_data + i, 1);
i += PROTO_69845_METER_DATA_LONG_LEN;
/* check type, type is struct */
app_data[i++] = PROTO_69845_APP_DATA_STRUCTURE;
app_data[i++] = 2;
/* check mode, type is enum, 0 - crc, 1 -mdt, 2 - sha1, 255 - other */
app_data[i++] = PROTO_69845_APP_DATA_ENUM;
app_data[i++] = 0;
/* check value, type is octet-string */
app_data[i++] = PROTO_69845_APP_DATA_OCTET_STRING;
app_data[i++] = sizeof(crc);
iot_uint16_to_bytes(crc, app_data + i, 1);
i += sizeof(crc);
/* compatible soft version, type is array visible string */
app_data[i++] = PROTO_69845_APP_DATA_ARRAY;
app_data[i++] = 1;
app_data[i++] = PROTO_69845_APP_DATA_VISIBLE_STRING;
/* compatible soft version default 0 */
app_data[i] = iot_sprintf(ver_string, "0", local_ver);
os_mem_cpy(app_data + i + 1, ver_string, app_data[i]);
i += app_data[i] + 1;
/* compatible hardware version, type is array visible string */
app_data[i++] = PROTO_69845_APP_DATA_ARRAY;
app_data[i++] = 1;
app_data[i++] = PROTO_69845_APP_DATA_VISIBLE_STRING;
/* compatible hardware version default 0 */
app_data[i] = iot_sprintf(ver_string, "0", local_ver);
os_mem_cpy(app_data + i + 1, ver_string, app_data[i]);
i += app_data[i] + 1;
/* loader id type is octet string */
app_data[i++] = PROTO_69845_APP_DATA_OCTET_STRING;
app_data[i++] = 1;
app_data[i++] = 0;
pkt = proto_69845_build_action_req_single_msg(req_info, i,
&server_info);
iot_bsrm_printf("%s size: %lu \n", __FUNCTION__, size);
return pkt;
}
static iot_pkt_t *iot_bsrm_pm_upgrade_build_69845_query_pkt()
{
server_addr_info_t server = {0};
proto_69845_app_get_req_info_t req = {0};
req.type = PROTO_69845_APP_GET_NORMAL;
req.piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
req.piid.sn = 0;
req.oad.oi = PROTO_69845_APP_OI_FILETRANS_BLOCK;
req.oad.attribute_id = 4;
req.oad.attribute_char = 0;
req.oad.element_index = 0;
server.len = IOT_MAC_ADDR_LEN;
server.type = PROTO_69845_SA_TYPE_WILDCARD;
iot_mac_addr_cpy(server.addr, proto_645_any_addr);
return proto_69845_build_get_req_msg(&req, &server);
}
static iot_pkt_t *iot_bsrm_pm_upgrade_build_69845_exe_pkt()
{
iot_pkt_t *pkt = NULL;
proto_69845_app_action_req_single_t *req_info;
uint8_t file_info_data[64] = { 0 };
proto_69845_app_data_time_s_t *times;
server_addr_info_t server_info = {0};
server_info.len = PROTO_69845_SA_LEN;
server_info.type = PROTO_69845_SA_TYPE_WILDCARD;
iot_mac_addr_cpy(server_info.addr, proto_645_any_addr);
req_info = (proto_69845_app_action_req_single_t *)file_info_data;
req_info->omd.method_id = 13;
req_info->omd.oi = PROTO_69845_APP_OI_FILETRANS_BLOCK;
req_info->omd.operation_mode = 0;
req_info->data.data_type = PROTO_69845_APP_DATA_TIME_S;
times = (proto_69845_app_data_time_s_t*)(file_info_data +
sizeof(*req_info));
times->year = 0xffff;
times->month = 0xff;
times->day = 0xff;
times->hour = 0xff;
times->minute = 0xff;
times->second = 0xff;
pkt = proto_69845_build_action_req_single_msg(req_info, sizeof(*times),
&server_info);
return pkt;
}
static iot_pkt_t *iot_bsrm_pm_upgrade_build_69845_transfile_data_pkt()
{
proto_69845_app_action_req_single_t *req_info;
proto_69845_app_len_descript_t *len_desc;
uint16_t len;
uint8_t *data, *app_data;
uint8_t reason = 0;
uint16_t i = 0;
server_addr_info_t server_info = { 0 };
iot_pkt_t *pkt = NULL, *tmp_pkt = NULL;
const uint8_t *img_data = NULL;
/* proto_69845_app_action_req_single_t + 1 byte struct
* element unmber + 1 byte element1 long-unsigned type + 2 byte
* long_unsigned size + 1 byte element2 octet-string + 1 byte octet-string
* len descript + 2 byte octet string length +
* IOT_BSRM_PM_UPGRADE_BLOCK_SIZE byte block data
*/
len = sizeof(*req_info) + sizeof(*len_desc) + 7 +
IOT_BSRM_PM_UPGRADE_BLOCK_SIZE;
tmp_pkt = iot_pkt_alloc(len, IOT_BSRM_MID);
if (!tmp_pkt) {
reason = 1;
goto out;
}
data = iot_pkt_data(tmp_pkt);
req_info = (proto_69845_app_action_req_single_t *)data;
req_info->omd.method_id = PROTO_OMD_TRANSFILE_DATA_METHOD_ID;
req_info->omd.oi = PROTO_69845_APP_OI_FILETRANS_BLOCK;
req_info->omd.operation_mode = 0;
req_info->data.data_type = PROTO_69845_APP_DATA_STRUCTURE;
app_data = data + sizeof(*req_info);
/* element cnt in structure, it's always 2 */
*(app_data + i) = 2;
i++;
/* element1, block number, type is long-unsigned */
*(app_data + i) = PROTO_69845_APP_DATA_LONG_UNSIGNED;
i++;
/* long-unsigned size, 2 bytes */
iot_uint16_to_bytes(g_pm_upgrade_info->block_index, app_data + i, 1);
i += PROTO_69845_METER_DATA_LONG_LEN;
/* element2, block data, type is octet-string */
*(app_data + i) = PROTO_69845_APP_DATA_OCTET_STRING;
i++;
/* get data length, ready to fillwith length sigment */
len = (uint16_t)iot_bsrm_pm_get_local_img_data(&img_data,
IOT_BSRM_PM_UPGRADE_BLOCK_SIZE, g_pm_upgrade_info->block_index);
if (len >= 0x80) {
/* octet-string length descript,
* proto_69845_app_len_descript_t, length byte is 2B
*/
len_desc = (proto_69845_app_len_descript_t *)(app_data + i);
len_desc->mub_flag = 1;
len_desc->byte_num = 0x02;
i += sizeof(*len_desc);
/* block data length */
iot_uint16_to_bytes(len, app_data + i, 1);
i += 2;
} else {
*(app_data + i) = len;
i++;
}
/* block data */
IOT_ASSERT(len);
os_mem_cpy(app_data + i, img_data, len);
iot_data_reverse(app_data + i, len);
i += len;
server_info.len = 1;
server_info.addr[0] = PROTO_69845_SA_BROADCAST_ADD;
server_info.type = PROTO_69845_SA_TYPE_BROADCAST;
pkt = proto_69845_build_action_req_single_msg(req_info, i,
&server_info);
out:
if (tmp_pkt) {
iot_pkt_free(tmp_pkt);
}
iot_bsrm_printf("%s state: %d, reason: %d, index: %d, len: %d\n",
__FUNCTION__, g_pm_upgrade_info->state, reason,
g_pm_upgrade_info->block_index, len);
return pkt;
}
static uint8_t iot_bsrm_handle_pm_upgrade_check_ver(
proto_69845_frame_head_info_t *hdr_698, apdu_info_t *apdu_desc)
{
uint8_t done = 0;
uint8_t reason = 0;
uint32_t oad_value;
proto_69845_apdu_t *apdu;
proto_69845_apdu_get_rsp_t *get_rsp;
proto_69845_app_result_normal_t *normal_resp;
proto_69845_ver_info_uint_t *ver_app_data;
uint32_t local_ver;
uint8_t pm_ver[16] = { 0 };
if (hdr_698->ctrl.dir_prm != PROTO_69845_D_P_SERVER_RESPONSE) {
reason = 1;
goto out;
}
apdu = (proto_69845_apdu_t *)apdu_desc->ptr;
if (apdu_desc->len < (sizeof(*apdu) + sizeof(*get_rsp) +
sizeof(*normal_resp) + sizeof(*ver_app_data))) {
reason = 2;
goto out;
}
if (apdu->type != PROTO_69845_S_APP_GET_RESP) {
reason = 3;
goto out;
}
get_rsp = (proto_69845_apdu_get_rsp_t *)apdu->data;
if (get_rsp->type != PROTO_69845_APP_GET_NORMAL) {
reason = 4;
goto out;
}
normal_resp = (proto_69845_app_result_normal_t *)get_rsp->data;
oad_value = iot_bytes_to_uint32((uint8_t *)&normal_resp->oad.oi, 1);
if (PROTO_69845_APP_OAD_VERSION != oad_value) {
reason = 5;
goto out;
}
if (normal_resp->get_result.result_type !=
PROTO_69845_APP_GET_RESULT_DATA) {
reason = 6;
goto fail;
}
ver_app_data = (proto_69845_ver_info_uint_t *)
(normal_resp->get_result.result);
if (ver_app_data->data0_type != PROTO_69845_APP_DATA_STRUCTURE) {
reason = 7;
goto fail;
}
if (ver_app_data->cnt < PROTO_69845_GET_VERSION_CNT) {
reason = 8;
goto fail;
}
local_ver = iot_bsrm_pm_get_local_img_version();
os_mem_cpy(pm_ver, ver_app_data->soft_ver, sizeof(ver_app_data->soft_ver));
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_INFO;
iot_bsrm_printf("%s local ver:0x%04x - %lu, pm ver: %s\n", __FUNCTION__,
local_ver, local_ver, pm_ver);
done = 1;
goto out;
fail:
done = 1;
iot_bsrm_set_pm_upgrade_guard_code(0);
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_IDLE;
out:
iot_bsrm_printf("%s state: %d, reason: %d, done: %d\n", __FUNCTION__,
g_pm_upgrade_info->state, reason, done);
return done;
}
static uint8_t iot_bsrm_handle_pm_upgrade_fileinfo_rsp(
proto_69845_frame_head_info_t *hdr_698, apdu_info_t *apdu_desc)
{
uint8_t done = 0;
uint8_t reason = 0;
proto_69845_apdu_t *apdu;
proto_69845_app_action_resp_t *act_resp;
proto_69845_app_action_resp_normal_t *act_resp_single;
uint32_t oad_value;
if (hdr_698->ctrl.dir_prm != PROTO_69845_D_P_SERVER_RESPONSE) {
reason = 1;
goto out;
}
apdu = (proto_69845_apdu_t *)apdu_desc->ptr;
if (apdu_desc->len < (sizeof(*apdu) + sizeof(*act_resp) +
sizeof(*act_resp_single))) {
reason = 2;
goto out;
}
if (apdu->type != PROTO_69845_S_APP_ACTION_RESP) {
reason = 3;
goto out;
}
act_resp = (proto_69845_app_action_resp_t*)apdu->data;
if (act_resp->data_type != PROTO_69845_APP_ACTION_NORMAL) {
reason = 4;
goto out;
}
act_resp_single = (proto_69845_app_action_resp_normal_t*)act_resp->data;
oad_value = iot_bytes_to_uint32((uint8_t*)&act_resp_single->result.omd.oi,
1);
if (PROTO_69845_APP_OAD_TRANSFILE_START != oad_value) {
reason = 5;
goto out;
}
if (act_resp_single->result.dar != PROTO_69845_APP_DAR_SUCCESS) {
reason = 6;
iot_bsrm_printf("%s result dar: %d , exit upgrade \n", __FUNCTION__,
g_pm_upgrade_info->state, act_resp_single->result.dar);
iot_bsrm_set_pm_upgrade_guard_code(0);
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_IDLE;
} else {
g_pm_upgrade_info->block_index = 0;
g_pm_upgrade_info->resend_cnt = 0;
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_DATA;
}
done = 1;
out:
iot_bsrm_printf("%s state: %d, reason: %d, done: %d\n", __FUNCTION__,
g_pm_upgrade_info->state, reason, done);
return done;
}
static uint8_t iot_bsrm_handle_pm_upgrade_check_exe(
proto_69845_frame_head_info_t *hdr_698, apdu_info_t *apdu_desc)
{
uint8_t done = 0;
uint8_t reason = 0;
proto_69845_apdu_t *apdu;
proto_69845_app_action_resp_t *act_resp;
proto_69845_app_action_resp_normal_t *act_resp_single;
uint32_t oad_value;
if (hdr_698->ctrl.dir_prm != PROTO_69845_D_P_SERVER_RESPONSE) {
reason = 1;
goto out;
}
apdu = (proto_69845_apdu_t *)apdu_desc->ptr;
if (apdu_desc->len < (sizeof(*apdu) + sizeof(*act_resp) +
sizeof(*act_resp_single))) {
reason = 2;
goto out;
}
if (apdu->type != PROTO_69845_S_APP_ACTION_RESP) {
reason = 3;
goto out;
}
act_resp = (proto_69845_app_action_resp_t*)apdu->data;
if (act_resp->data_type != PROTO_69845_APP_ACTION_NORMAL) {
reason = 4;
goto out;
}
act_resp_single = (proto_69845_app_action_resp_normal_t*)act_resp->data;
oad_value = iot_bytes_to_uint32((uint8_t *)&act_resp_single->result.omd.oi,
1);
if (PROTO_69845_APP_OAD_TRANSFILE_EXE != oad_value) {
reason = 5;
goto out;
}
if (act_resp_single->result.dar != PROTO_69845_APP_DAR_SUCCESS) {
reason = 6;
goto out;
}
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_IDLE;
iot_bsrm_set_pm_upgrade_guard_code(0);
iot_bsrm_printf("%s upgrade done\n", __FUNCTION__);
done = 1;
out:
iot_bsrm_printf("%s state: %d, reason: %d, done: %d\n", __FUNCTION__,
g_pm_upgrade_info->state, reason, done);
return done;
}
static uint8_t iot_bsrm_handle_pm_upgrade_transfile_status_rsp(
proto_69845_frame_head_info_t *hdr_698, apdu_info_t *apdu_desc)
{
uint8_t done = 0;
uint8_t reason = 0;
uint32_t oad_value;
proto_69845_apdu_t *apdu;
proto_69845_app_result_normal_t *normal_resp;
proto_69845_apdu_get_rsp_t *get_rsp;
proto_69845_app_len_descript_t *desc_len;
uint8_t *app_data;
uint16_t app_len;
uint16_t i = 0;
uint16_t miss_index = 0;
uint32_t bitmap_len;
uint8_t *bitmap_ptr;
if (hdr_698->ctrl.dir_prm != PROTO_69845_D_P_SERVER_RESPONSE) {
reason = 1;
goto out;
}
apdu = (proto_69845_apdu_t *)apdu_desc->ptr;
if (apdu_desc->len < (sizeof(*apdu) + sizeof(*get_rsp) +
sizeof(*normal_resp) + sizeof(*desc_len))) {
reason = 2;
goto out;
}
app_len = apdu_desc->len - (sizeof(*apdu) + sizeof(*get_rsp) +
sizeof(*normal_resp) + sizeof(*desc_len));
if (apdu->type != PROTO_69845_S_APP_GET_RESP) {
reason = 3;
goto out;
}
get_rsp = (proto_69845_apdu_get_rsp_t *)apdu->data;
if (get_rsp->type != PROTO_69845_APP_GET_NORMAL) {
reason = 4;
goto out;
}
normal_resp = (proto_69845_app_result_normal_t *)get_rsp->data;
if (normal_resp->get_result.result_type !=
PROTO_69845_APP_GET_RESULT_DATA) {
reason = 5;
goto out;
}
oad_value = iot_bytes_to_uint32((uint8_t *)&normal_resp->oad.oi, 1);
if (PROTO_69845_APP_OAD_TRANSFILE_STATUS != oad_value) {
reason = 6;
goto out;
}
app_data = normal_resp->get_result.result;
if (*app_data != PROTO_69845_APP_DATA_BIT_STRING) {
reason = 7;
goto out;
}
i++;
desc_len = (proto_69845_app_len_descript_t *)(app_data + i);
if (desc_len->mub_flag == 0) {
bitmap_len = *(app_data + i);
bitmap_ptr = app_data + i + 1;
} else if (desc_len->byte_num == 1) {
if (app_len < 1) {
reason = 8;
goto out;
}
i++;
bitmap_len = *(app_data + i);
bitmap_ptr = app_data + i + 1;
app_len--;
} else if (desc_len->byte_num == 2) {
if (app_len < 2) {
reason = 9;
goto out;
}
i++;
bitmap_len = iot_bytes_to_uint16(app_data + i, 1);
bitmap_ptr = app_data + i + 2;
app_len -= 2;
} else {
reason = 10;
goto out;
}
if (bitmap_len < g_pm_upgrade_info->bitmap_size) {
reason = 11;
goto out;
}
if (app_len < g_pm_upgrade_info->bitmap_size) {
reason = 12;
goto out;
}
os_mem_cpy(g_pm_upgrade_info->bitmap, bitmap_ptr,
g_pm_upgrade_info->bitmap_size);
if ((g_pm_upgrade_info->resend_cnt++ > IOT_BSRM_PM_UPGRADE_RESEND_MAX_CNT)
|| (iot_bsrm_pm_upgrade_get_block_to_resend(
g_pm_upgrade_info->block_index, &miss_index) != ERR_OK)) {
g_pm_upgrade_info->block_index = 0;
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_EXE;
} else {
g_pm_upgrade_info->block_index = miss_index;
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_DATA;
}
done = 1;
out:
iot_bsrm_printf("%s state: %d, reason: %d, done: %d\n",
__FUNCTION__, g_pm_upgrade_info->state, reason, done);
return done;
}
uint8_t iot_bsrm_handle_pm_upgrade_resp(iot_pkt_t *pkt)
{
uint8_t *data;
uint32_t len = 0;
uint8_t reason = 0;
uint8_t done = 0;
apdu_info_t apdu_desc;
proto_69845_frame_head_info_t *hdr_698 = NULL;
uint16_t miss_index;
IOT_ASSERT(g_pm_upgrade_info);
if ((g_pm_upgrade_info->state == IOT_BSRM_PM_UPGRADE_STATE_IDLE) ||
(g_pm_upgrade_info->state ==
IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_DATA)) {
goto check_resp;
}
if (NULL == pkt) {
reason = 1;
if (g_pm_upgrade_info->retry_cnt++ >
IOT_BSRM_PM_UPGRADE_RETRY_MAX_CNT) {
iot_bsrm_set_pm_upgrade_guard_code(0);
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_IDLE;
reason = 2;
}
goto out;
}
data = iot_pkt_data(pkt);
len = iot_pkt_data_len(pkt);
if (ERR_OK != proto_69845_parse(&data, &len, &hdr_698, &apdu_desc)) {
reason = 3;
goto out;
}
check_resp:
switch (g_pm_upgrade_info->state) {
case IOT_BSRM_PM_UPGRADE_STATE_CHECK_VER:
{
done = iot_bsrm_handle_pm_upgrade_check_ver(hdr_698, &apdu_desc);
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_INFO:
{
done = iot_bsrm_handle_pm_upgrade_fileinfo_rsp(hdr_698, &apdu_desc);
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_DATA:
{
if (iot_bsrm_pm_upgrade_get_block_to_resend(
g_pm_upgrade_info->block_index + 1, &miss_index) == ERR_OK) {
g_pm_upgrade_info->block_index = miss_index;
} else {
/* transfile done, query bitmap next */
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_QUERY_INFO;
}
done = 1;
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_QUERY_INFO:
{
done = iot_bsrm_handle_pm_upgrade_transfile_status_rsp(hdr_698,
&apdu_desc);
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_EXE:
{
done = iot_bsrm_handle_pm_upgrade_check_exe(hdr_698, &apdu_desc);
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_IDLE:
{
done = 1;
break;
}
default:
break;
}
out:
if (done) {
g_pm_upgrade_info->retry_cnt = 0;
}
iot_bsrm_printf("%s state: %d, reason: %d done: %d\n", __FUNCTION__,
g_pm_upgrade_info->state, reason, done);
if (pkt) {
iot_pkt_free(pkt);
}
return done;
}
uint32_t iot_bsrm_handle_pm_upgrade_req(uint32_t *timeout)
{
iot_pkt_t *pkt = NULL;
uint32_t ret = ERR_FAIL;
if (!g_pm_upgrade_info) {
return ret;
}
*timeout = IOT_BSRM_PM_UPGRADE_DEFAULT_RSP_TIMEOUT;
switch (g_pm_upgrade_info->state) {
case IOT_BSRM_PM_UPGRADE_STATE_CHECK_VER:
{
pkt = iot_bsrm_pm_upgrade_build_69845_check_pkt();
if (NULL == pkt) {
ret = ERR_NOMEM;
}
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_INFO:
{
pkt = iot_bsrm_pm_upgrade_build_69845_fileinfo_pkt();
if (NULL == pkt) {
ret = ERR_NOMEM;
}
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_QUERY_INFO:
{
g_pm_upgrade_info->block_index = 0;
pkt = iot_bsrm_pm_upgrade_build_69845_query_pkt();
if (NULL == pkt) {
ret = ERR_NOMEM;
}
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_EXE:
{
pkt = iot_bsrm_pm_upgrade_build_69845_exe_pkt();
if (NULL == pkt) {
ret = ERR_NOMEM;
}
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_TRANSFILE_DATA:
{
*timeout = IOT_BSRM_PM_UPGRADE_BROADCAST_TIMEOUT;
pkt = iot_bsrm_pm_upgrade_build_69845_transfile_data_pkt();
if (NULL == pkt) {
ret = ERR_NOMEM;
}
break;
}
case IOT_BSRM_PM_UPGRADE_STATE_IDLE:
{
break;
}
default:
break;
}
if (pkt) {
ret = ERR_OK;
iot_bsrm_uart_send(pkt);
}
return ret;
}
uint32_t iot_bsrm_pm_upgrade_init()
{
uint32_t ret = ERR_OK;
uint32_t size = iot_bsrm_pm_get_local_img_size();
uint32_t block_cnt;
if (iot_bsrm_get_pm_upgrade_guard_code() !=
IOT_BSRM_PM_UPGRADE_GUARD_CODE) {
iot_bsrm_printf("%s invalid upgrade flag\n", __FUNCTION__);
return ret;
}
if (!size) {
goto out;
}
if (g_pm_upgrade_info) {
goto out;
}
g_pm_upgrade_info = os_mem_malloc(IOT_BSRM_MID, sizeof(*g_pm_upgrade_info));
if (g_pm_upgrade_info == NULL) {
ret = ERR_NOMEM;
goto out;
}
block_cnt = (size + IOT_BSRM_PM_UPGRADE_BLOCK_SIZE - 1) /
IOT_BSRM_PM_UPGRADE_BLOCK_SIZE;
g_pm_upgrade_info->bitmap_size = (uint16_t)((block_cnt + 8 - 1) / 8);
g_pm_upgrade_info->block_cnt = block_cnt;
g_pm_upgrade_info->bitmap = os_mem_malloc(IOT_BSRM_MID,
g_pm_upgrade_info->bitmap_size);
if (g_pm_upgrade_info->bitmap == NULL) {
ret = ERR_NOMEM;
goto bitmap_fail;
}
os_mem_set(g_pm_upgrade_info->bitmap, 0, g_pm_upgrade_info->bitmap_size);
g_pm_upgrade_info->state = IOT_BSRM_PM_UPGRADE_STATE_CHECK_VER;
g_pm_upgrade_info->retry_cnt = 0;
g_pm_upgrade_info->block_index = 0;
g_pm_upgrade_info->resend_cnt = 0;
goto out;
bitmap_fail:
os_mem_free(g_pm_upgrade_info);
g_pm_upgrade_info = NULL;
out:
if (ERR_OK == ret) {
iot_bsrm_printf("%s success, size: %lu, block cnt: %d\n", __FUNCTION__,
size, g_pm_upgrade_info->block_cnt);
} else {
iot_bsrm_printf("%s fail\n", __FUNCTION__);
}
return ret;
}
void iot_bsrm_pm_upgrade_deinit()
{
if (!g_pm_upgrade_info) {
return;
}
if (g_pm_upgrade_info->bitmap) {
os_mem_free(g_pm_upgrade_info->bitmap);
g_pm_upgrade_info->bitmap = NULL;
}
os_mem_free(g_pm_upgrade_info);
g_pm_upgrade_info = NULL;
}
#else
uint8_t iot_bsrm_handle_pm_upgrade_resp(iot_pkt_t *pkt)
{
uint8_t done = 1;
if (pkt) {
iot_pkt_free(pkt);
}
return done;
}
uint32_t iot_bsrm_handle_pm_upgrade_req(uint32_t *timeout)
{
(void)timeout;
return ERR_FAIL;
}
uint32_t iot_bsrm_pm_upgrade_init()
{
if (iot_bsrm_get_pm_upgrade_guard_code() ==
IOT_BSRM_PM_UPGRADE_GUARD_CODE) {
iot_bsrm_set_pm_upgrade_guard_code(0);
iot_bsrm_printf("%s support pm upgrade, clean pm upgrade flag\n",
__FUNCTION__);
}
return ERR_OK;
}
void iot_bsrm_pm_upgrade_deinit()
{
}
#endif /* IOT_BSRM_PM_UPGRADE_ENABLE */