902 lines
28 KiB
C
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 */
|
|
|