Linux_SDK_V2.0.2

Signed-off-by: devops_admin <devops_admin@alibabacloud.com>
This commit is contained in:
devops_admin
2024-08-26 01:45:12 +00:00
committed by Han Gao
parent fc9575fa63
commit 8942b2dce6
106 changed files with 19083 additions and 529 deletions

View File

@@ -135,6 +135,14 @@ config FASTBOOT_CMD_OEM_FORMAT
relies on the env variable partitions to contain the list of
partitions as required by the gpt command.
config FASTBOOT_CMD_OEM_NV_OPERATION
bool "Enable the 'oem nv get/set' command"
help
Add support for the "oem get/set" command from a client.
config FASTBOOT_ECIES_AUTH
bool "Enabled ecies fastboot auth"
endif # FASTBOOT
endmenu

View File

@@ -3,5 +3,7 @@
obj-y += fb_common.o
obj-y += fb_getvar.o
obj-y += fb_command.o
obj-$(CONFIG_FASTBOOT_ECIES_AUTH) += fb_ecies.o
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o
obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
obj-$(CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION) += fb_nv_operation.o

View File

@@ -45,6 +45,19 @@ static void oem_format(char *, char *);
static void oem_command(char *, char *);
int image_have_head(unsigned long img_src_addr);
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
void oem_nv_get_proccess(char *cmd_parameter, char *response);
void oem_nv_set_proccess(char *cmd_parameter, char *response);
void oem_nv_factory_recovery_process(char *cmd_parameter, char *response);
static void oem_nv_get(char *cmd_parameter, char *response);
static void oem_nv_set(char *cmd_parameter, char *response);
static void oem_fcty(char *cmd_parameter, char *response);
#endif
#ifdef CONFIG_FASTBOOT_ECIES_AUTH
int ecies_process_data(uint8_t * data, int data_size,char *response);
#endif
static const struct {
const char *command;
void (*dispatch)(char *cmd_parameter, char *response);
@@ -97,6 +110,20 @@ static const struct {
.command = "oem command",
.dispatch = oem_command,
},
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
[FASTBOOT_COMMAND_OEM_NV_GET] = {
.command = "oem nv get",
.dispatch = oem_nv_get,
},
[FASTBOOT_COMMAND_OEM_NV_SET] = {
.command = "oem nv set",
.dispatch = oem_nv_set,
},
[FASTBOOT_COMMAND_OEM_FCTY] = {
.command = "oem fcty",
.dispatch = oem_fcty,
},
#endif
};
/**
@@ -294,7 +321,90 @@ int check_image_board_id(uint8_t *image_data)
return 0;
}
int hibernate_image_cleaned_flag = 0;
void clean_hibernate_image_header(char *response)
{
struct blk_desc *dev_desc;
disk_partition_t info;
if(0x03 == hibernate_image_cleaned_flag) //already erased all
{
return;
}
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
fastboot_fail("invalid mmc device", response);
return;
}
char * buf = memalign(CONFIG_SYS_CACHELINE_SIZE,4096);
if(!buf) {
printf(" mem alloc for hibernate partition header failed!\n");
return;
}
/* if fastresume partition exists, earse the old image header */
if(part_get_info_by_name(dev_desc, "fastresume", &info)) {
printf(" find fastresume partition , erase the header:\n");
memset(buf,0xff,4096);
if(blk_dwrite(dev_desc, info.start, 4096/info.blksz, buf) != 4096/info.blksz)
{
printf(" fastresume header write failed!\n");
hibernate_image_cleaned_flag = 0;
}
else
{
hibernate_image_cleaned_flag |= 0x1;
}
}
/* if swap partition exists, earse the old image header */
if(part_get_info_by_name(dev_desc, "swap", &info)) {
printf(" find swap partition , erase the header:\n");
memset(buf,0xff,4096);
if(blk_dwrite(dev_desc, info.start, 4096/info.blksz, buf) != 4096/info.blksz)
{
printf(" swap header write failed!\n");
hibernate_image_cleaned_flag = 0;
}
else
{
hibernate_image_cleaned_flag |= 0x2;
}
}
free(buf);
}
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
void fasboot_uboot_write_process(void *buf, char *response)
{
char cmdbuf[32];
u32 block_cnt;
struct blk_desc *dev_desc;
int ret = 0;
disk_partition_t info;
ret = check_image_board_id(buf);
if (ret != 0) {
fastboot_fail("U-BOOT image does not match the type of BOARD", response);
return;
}
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
fastboot_fail("invalid mmc device", response);
return;
}
run_command("mmc partconf 0 1 0 1", 0);
block_cnt = image_size / BLOCK_SIZE;
if (image_size % BLOCK_SIZE) {
block_cnt = block_cnt +1;
}
sprintf(cmdbuf, "mmc write 0x%p 0 %x", buf, block_cnt);
run_command(cmdbuf, 0);
run_command("mmc partconf 0 1 0 0", 0);
}
/**
* flash() - write the downloaded image to the indicated partition.
*
@@ -308,36 +418,10 @@ static void flash(char *cmd_parameter, char *response)
{
#ifdef THEAD_LIGHT_FASTBOOT
char cmdbuf[32];
u32 block_cnt;
struct blk_desc *dev_desc;
disk_partition_t info;
int ret = 0;
if (strcmp(cmd_parameter, "uboot") == 0) {
ret = check_image_board_id(fastboot_buf_addr);
if (ret != 0) {
fastboot_fail("U-BOOT image does not match the type of BOARD", response);
return;
}
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
fastboot_fail("invalid mmc device", response);
return;
}
run_command("mmc partconf 0 1 0 1", 0);
block_cnt = image_size / BLOCK_SIZE;
if (image_size % BLOCK_SIZE) {
block_cnt = block_cnt +1;
}
sprintf(cmdbuf, "mmc write 0x%p 0 %x", fastboot_buf_addr, block_cnt);
run_command(cmdbuf, 0);
run_command("mmc partconf 0 1 0 0", 0);
fasboot_uboot_write_process(fastboot_buf_addr, response);
} else if ((strcmp(cmd_parameter, "fw") == 0)) {
memcpy((void *)LIGHT_FW_ADDR, fastboot_buf_addr, image_size);
} else if ((strcmp(cmd_parameter, "uImage") == 0)) {
@@ -352,13 +436,15 @@ static void flash(char *cmd_parameter, char *response)
memcpy((void *)LIGHT_TF_FW_ADDR, fastboot_buf_addr, image_size);
} else if ((strcmp(cmd_parameter, TEE_PART_NAME) == 0)) {
memcpy((void *)LIGHT_TEE_FW_ADDR, fastboot_buf_addr, image_size);
} else if ((strcmp(cmd_parameter, "boot") == 0)) {
}
#ifdef CONFIG_RV_BOOK
else if ((strcmp(cmd_parameter, "boot") == 0)) {
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
fastboot_fail("invalid mmc device", response);
return;
}
/* if fastresume partition exists, earse the old image header */
fastboot_fail("invalid mmc device", response);
return;
}
/* if fastresume partition exists, earse the old image header */
if(part_get_info_by_name(dev_desc, "fastresume", &info)) {
printf(" find fastresume partition , erase the header:\n");
char * buf = memalign(CONFIG_SYS_CACHELINE_SIZE,4096);
@@ -371,6 +457,22 @@ static void flash(char *cmd_parameter, char *response)
free(buf);
}
}
#endif
#ifdef CONFIG_FASTBOOT_ECIES_AUTH
else if ((strcmp(cmd_parameter, "ecies") == 0)) {
ecies_process_data(fastboot_buf_addr, image_size,response);
return;
}
#endif
//If version is updated, hibernate image may not compatible with current,erase it.
if ((strcmp(cmd_parameter, "boot") == 0)
|| (strcmp(cmd_parameter, "uboot") == 0)
|| (strcmp(cmd_parameter, "root") == 0)) {
clean_hibernate_image_header(response);
}
if(strcmp(cmd_parameter, "uboot") == 0 || (strcmp(cmd_parameter, "fw") == 0) ||
(strcmp(cmd_parameter, "uImage") == 0) || (strcmp(cmd_parameter, "dtb") == 0) ||
(strcmp(cmd_parameter, "rootfs") == 0) || (strcmp(cmd_parameter, "aon") == 0)) {
@@ -380,54 +482,7 @@ static void flash(char *cmd_parameter, char *response)
#endif
#if CONFIG_IS_ENABLED(LIGHT_SEC_UPGRADE)
if(strcmp(cmd_parameter, TF_IMG_UPD_NAME) == 0) {
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
/* tee/tf/uboot image must be written into stash partition */
sprintf(cmdbuf, "%s", STASH_PART_NAME);
fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response);
#endif
/* Send ACK to host */
fastboot_okay(NULL, response);
/* set secure upgrade flag to indicate it is TF image upgrade*/
sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", TF_SEC_UPGRADE_FLAG);
run_command(cmdbuf, 0);
run_command("saveenv", 0);
run_command("reset", 0);
return;
} else if (strcmp(cmd_parameter, TEE_IMG_UPD_NAME) == 0) {
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
/* tee/tf/uboot image must be written into stash partition */
sprintf(cmdbuf, "%s", STASH_PART_NAME);
fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response);
#endif
/* Send ACK to host */
fastboot_okay(NULL, response);
/* set secure upgrade flag to indicate it is TEE image upgrade*/
sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", TEE_SEC_UPGRADE_FLAG);
run_command(cmdbuf, 0);
run_command("saveenv", 0);
run_command("reset", 0);
return;
} else if (strcmp(cmd_parameter, SBMETA_IMG_UPD_NAME) == 0) {
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
/* tee/tf/uboot image must be written into stash partition */
sprintf(cmdbuf, "%s", STASH_PART_NAME);
fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response);
#endif
/* Send ACK to host */
fastboot_okay(NULL, response);
/* set secure upgrade flag to indicate it is TEE image upgrade*/
sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", SBMETA_SEC_UPGRADE_FLAG);
run_command(cmdbuf, 0);
run_command("saveenv", 0);
run_command("reset", 0);
return;
} else if (strcmp(cmd_parameter, UBOOT_IMG_UPD_NAME) == 0) {
if (strcmp(cmd_parameter, UBOOT_IMG_UPD_NAME) == 0) {
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
env_set_hex("ubootupdsize", image_size);
@@ -530,3 +585,38 @@ static void oem_command(char *cmd_parameter, char *response)
else
fastboot_okay(NULL, response);
}
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
/**
* oem_nv_get() - Execute the OEM NV GET command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
static void oem_nv_get(char *cmd_parameter, char *response)
{
oem_nv_get_proccess(cmd_parameter,response);
}
/**
* oem_nv_set() - Execute the OEM NV Set command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
static void oem_nv_set(char *cmd_parameter, char *response)
{
oem_nv_set_proccess(cmd_parameter,response);
}
/**
* oem_fcty() - Execute the OEM fcty command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
static void oem_fcty(char *cmd_parameter, char *response)
{
oem_nv_factory_recovery_process(cmd_parameter,response);
}
#endif

198
drivers/fastboot/fb_ecies.c Normal file
View File

@@ -0,0 +1,198 @@
#include <sec_ecies_session.h>
#include <common.h>
#include <command.h>
#include <env.h>
#include <fastboot.h>
#include <fastboot-internal.h>
#include <fb_mmc.h>
#include <fb_nand.h>
#include <part.h>
#include <stdlib.h>
#include <csi_sec_img_verify.h>
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
extern void fasboot_uboot_write_process(void *buf, char *response);
#define MAX_ECIES_IMAGE_SIZE (9*1024*1024)
#define ECIES_MALLOC_START (MAX_ECIES_IMAGE_SIZE * 2)
typedef struct {
uint32_t magic;
uint32_t file_size;
char partition_name[64];
} __attribute__((__packed__)) send_file_info_t;
static uint32_t ecies_file_pos = 0;
static int slave_init = 0;
static int current_pos = 0;
void *csi_ecies_malloc(uint32_t size)
{
void * ptr = NULL;
if (current_pos + size >= CONFIG_FASTBOOT_BUF_SIZE) {
current_pos = 0;
}
ptr = (void *)(long)(CONFIG_FASTBOOT_BUF_ADDR + ECIES_MALLOC_START + current_pos);
current_pos += size;
return ptr;
};
void csi_ecies_free(void *buffer)
{
return;
};
static int ecies_data_write(uint8_t *buf,uint8_t *data,int data_len)
{
char response[FASTBOOT_RESPONSE_LEN];
if (data_len == 0 || buf == NULL || data == NULL) {
return -1;
}
memcpy(buf + ecies_file_pos,data,data_len);
ecies_file_pos += data_len;
if (ecies_file_pos == sizeof(send_file_info_t) + ((send_file_info_t *)buf)->file_size) {
if (strcmp(((send_file_info_t *)buf)->partition_name, TEE_PART_NAME) == 0) {
memcpy((void *)LIGHT_TEE_FW_ADDR, buf + sizeof(send_file_info_t), ((send_file_info_t *)buf)->file_size);
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
fastboot_mmc_flash_write(((send_file_info_t *)buf)->partition_name, buf + sizeof(send_file_info_t), ((send_file_info_t *)buf)->file_size,
response);
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
fastboot_nand_flash_write(((send_file_info_t *)buf)->partition_name, buf + sizeof(send_file_info_t), ((send_file_info_t *)buf)->file_size,
response);
#endif
} else if (strcmp(((send_file_info_t *)buf)->partition_name, UBOOT_PART_NAME) == 0) {
fasboot_uboot_write_process(buf + sizeof(send_file_info_t),response);
} else {
printf("unknown partition name\n");
return -2;
}
ecies_file_pos = 0;
} else if(ecies_file_pos > sizeof(send_file_info_t) + ((send_file_info_t *)buf)->file_size) {
return -3;
}
return 0;
}
static void hex_to_str(char *dest, const uint8_t *src, int len)
{
char ddl = 0;
char ddh = 0;
int i = 0;
for (i = 0; i < len; i++) {
ddh = 48 + src[i] / 16;
ddl = 48 + src[i] % 16;
if (ddh > 57) {
ddh = ddh + 7;
}
if (ddl > 57) {
ddl = ddl + 7;
}
dest[i * 2] = ddh;
dest[i * 2 + 1] = ddl;
}
dest[len * 2] = '\0';
}
int ecies_process_data(uint8_t * data, int data_size,char *response)
{
static ecies_session_t ss_slave;
char apduResponse[ECIES_INIT_RESPONSE_LEN] = {0};
uint8_t *plaintext = csi_ecies_malloc(MAX_ECIES_IMAGE_SIZE);
uint32_t plaintextLen = 0;
uint32_t apduResponseLen = 0;
int ret = 0;
uint8_t cla = 0;
uint8_t errcode = 0;
if (plaintext == NULL) {
ret = -1;
goto end;
}
if (!slave_init) {
csi_sec_library_init();
ret = hal_ecies_slave_init(&ss_slave);
if (ret != 0) {
strcpy(response,"hal_ecies_slave_init ERROR");
ret = -2;
goto end;
}
}
ret = hal_ecies_slave_session_comm(&ss_slave, data, data_size, (uint8_t *)apduResponse, &apduResponseLen, plaintext, &plaintextLen);
if (ret != 0) {
ret = hal_ecies_status_get((uint8_t *)apduResponse, apduResponseLen, &cla, &errcode);
if (ret != 0) {
strcpy(response,"hal_ecies_errcode_get ERROR");
ret = -3;
goto end;
}
if (cla == ECIES_CLA_INITIALIZE_UPDATE_RESPONSE && errcode == ECIES_RESPONSE_SESSION_OPENED_ERROR) {
slave_init = 0;
ecies_file_pos = 0;
hal_ecies_slave_uninit(&ss_slave);
ret = hal_ecies_slave_init(&ss_slave);
if (ret != 0) {
strcpy(response,"hal_ecies_slave_init ERROR");
ret = -4;
goto end;
}
ret = hal_ecies_slave_session_comm(&ss_slave, data, data_size, (uint8_t*)apduResponse, &apduResponseLen, plaintext, &plaintextLen);
if (ret != 0) {
strcpy(response,"hal_ecies_slave_session_comm ERROR");
ret = -5;
goto end;
}
} else if(errcode != ECIES_RESPONSE_OK) {
if (errcode == ECIES_CLA_SDATA_SEND_RESPONSE) {
strcpy(response,"ECIES_CLA_SDATA_SEND_RESPONSE ERROR");
ret = -6;
goto end;
} else if (errcode == ECIES_CLA_SESSION_CLOSE) {
strcpy(response,"ECIES_CLA_SESSION_CLOSE ERROR");
ret = -7;
goto end;
} else if (errcode == ECIES_CLA_INITIALIZE_UPDATE) {
strcpy(response,"ECIES_CLA_INITIALIZE_UPDATE ERROR");
ret = -8;
goto end;
}
}
}
if (slave_init && plaintextLen) {
ret = ecies_data_write((uint8_t*)(long)(CONFIG_FASTBOOT_BUF_ADDR + MAX_ECIES_IMAGE_SIZE),plaintext,plaintextLen);
if (ret != 0) {
strcpy(response,"ecies_data_write ERROR");
ret = -8;
goto end;
}
}
slave_init = 1;
strcpy(response,"SUCCESS:");
hex_to_str(response + strlen(response),(uint8_t*)apduResponse,apduResponseLen);
ret = 0;
end:
if (plaintext) {
csi_ecies_free(plaintext);
plaintext = NULL;
}
return ret;
}
#endif

View File

@@ -0,0 +1,342 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <common.h>
#include <fb_mmc.h>
#include <command.h>
#include <asm/io.h>
#include <asm/types.h>
#include <configs/light-c910.h>
#include <thead/clock_config.h>
#include <linux/bitops.h>
#include <asm/arch-thead/light-iopmp.h>
#include "../lib/sec_library/include/soc.h"
#define MAX_NV_NUMBER_SIZE 32
#define MAX_NV_DATA_SIZE 128
#define NV_BLOCK_SIZE 512
extern int32_t wj_efuse_get_lc(long unsigned int, int *lc);
typedef enum {
FB_SYS_ACTION_FACTORY_RECOVER,
FB_SYS_ACTION_READ_EFUSE,
} fb_sys_action_t;
static int nv_get(uint8_t *data,int offset,int data_len)
{
struct blk_desc *dev_desc;
struct disk_partition part_info;
ulong block_start;
uint8_t data_nv[NV_BLOCK_SIZE] = {0};
int ret;
int n;
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (dev_desc == NULL) {
return -1;
}
ret = part_get_info_by_name(dev_desc, NV_PARTITION_NAME, &part_info);
if (ret < 0) {
return -2;
}
if(NV_BLOCK_SIZE != dev_desc->blksz) {
return -4;
}
block_start = part_info.start + offset / dev_desc->blksz;
n = blk_dread(dev_desc, block_start, 1, data_nv);
if (n != 1) {
return -5;
}
memcpy(data,data_nv + offset % NV_BLOCK_SIZE,data_len);
return 0;
}
static int nv_set(uint8_t *data,int offset,int data_len)
{
struct blk_desc *dev_desc;
struct disk_partition part_info;
ulong block_start;
uint8_t data_nv[NV_BLOCK_SIZE] = {0};
int ret;
int n;
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (dev_desc == NULL) {
return -1;
}
ret = part_get_info_by_name(dev_desc, NV_PARTITION_NAME, &part_info);
if (ret < 0) {
return -2;
}
if (NV_BLOCK_SIZE != dev_desc->blksz) {
return -3;
}
block_start = part_info.start + offset / dev_desc->blksz;
n = blk_dread(dev_desc, block_start, 1, data_nv);
if (n != 1) {
return -4;
}
memcpy(data_nv + offset % NV_BLOCK_SIZE,data,data_len);
n = blk_dwrite(dev_desc, block_start, 1, data_nv);
if (n != 1) {
return -5;
}
return 0;
}
static int factory_recovery(char *response)
{
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
fastboot_mmc_erase("metadata", response);
if (strcmp(response, "OKAY") != 0) {
return -1;
}
fastboot_mmc_erase("misc", response);
if (strcmp(response, "OKAY") != 0) {
return -2;
}
#endif
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
fastboot_nand_erase("metadata", response);
if (strcmp(response, "OKAY") != 0) {
return -3;
}
fastboot_nand_erase("misc", response);
if (strcmp(response, "OKAY") != 0) {
return -4;
}
#endif
strcpy(response,"OKAY");
return 0;
}
static int read_efuse_status(char *response)
{
int ret;
int lc = 0;
ret = wj_efuse_get_lc(WJ_EFUSE_BASE, &lc);
if (ret) {
return -1;
}
if(lc == 0) {
strcpy(response,"LC_INIT");
} else {
strcpy(response,"LC_BLOWNED");
}
return 0;
}
static int sys_action(int flag,char *response)
{
if (flag == FB_SYS_ACTION_FACTORY_RECOVER) {
return factory_recovery(response);
} else if (flag == FB_SYS_ACTION_READ_EFUSE) {
return read_efuse_status(response);
} else {
return -1;
}
return 0;
}
static int toupper(int c)
{
if (c >= 'a' && c <= 'z') {
return c - 32;
}
return c;
}
static void str_to_hex(uint8_t *dest, const char *src, int len)
{
char h1, h2;
unsigned char s1, s2;
for (int i = 0; i < len; i++) {
h1 = src[2 * i];
h2 = src[2 * i + 1];
s1 = toupper(h1) - 48;
s2 = toupper(h2) - 48;
if (s1 > 9) {
s1 = s1 - 7;
}
if (s2 > 9) {
s2 = s2 - 7;
}
dest[i] = s1 * 16 + s2;
}
}
static void hex_to_str(char *dest, const uint8_t *src, int len)
{
char ddl = 0;
char ddh = 0;
int i = 0;
for (i = 0; i < len; i++) {
ddh = 48 + src[i] / 16;
ddl = 48 + src[i] % 16;
if (ddh > 57) {
ddh = ddh + 7;
}
if (ddl > 57) {
ddl = ddl + 7;
}
dest[i * 2] = ddh;
dest[i * 2 + 1] = ddl;
}
dest[len * 2] = '\0';
}
static int char_to_int(char *data,int *out)
{
*out = 0;
while(*data) {
if(*data < '0' || *data > '9')
return -1;
*out = *out * 10 + (*data - '0');
++data;
}
return 0;
}
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
void oem_nv_factory_recovery_process(char *cmd_parameter, char *response)
{
int ret = 0;
int flag = 0;
ret = char_to_int(cmd_parameter,&flag);
if (ret != 0) {
strcpy(response,"ERROR FLAG INVALID");
return;
}
ret = sys_action(flag,response);
if (ret != 0) {
strcpy(response,"ERROR SYS ACTION FAILED");
return;
}
}
void oem_nv_get_proccess(char *cmd_parameter, char *response)
{
char *sep = NULL;
char offset[MAX_NV_NUMBER_SIZE] = {0};
char len[MAX_NV_NUMBER_SIZE] = {0};
int sep_pos = 0;
uint8_t nv_data[MAX_NV_DATA_SIZE + 32] = {0};
char nv_data_str[MAX_NV_DATA_SIZE * 2 + 1] = {0};
int ret;
int offset_int = 0;
int len_int = 0;
sep = strstr(cmd_parameter, ":");
if (sep == NULL) {
strcpy(response,"ERROR INVALID PARAM");
return;
}
sep_pos = sep - cmd_parameter;
memcpy(offset,cmd_parameter,sep - cmd_parameter);
memcpy(len,cmd_parameter + (sep - cmd_parameter) + 1,strlen(cmd_parameter) - sep_pos - 1);
ret = char_to_int(offset,&offset_int);
if (ret != 0) {
strcpy(response,"ERROR OFFSET INVALID");
return;
}
ret = char_to_int(len,&len_int);
if (ret != 0) {
strcpy(response,"ERROR LEN INVALID");
return;
}
if (len_int > MAX_NV_DATA_SIZE) {
strcpy(response,"ERROR NV SIZE TOO LARGE");
return;
}
ret = nv_get(nv_data, offset_int, len_int);
if (ret != 0) {
printf("nv_get failed:%d\n",ret);
strcpy(response,"ERROR NV GET FAILED");
return;
}
hex_to_str(nv_data_str,nv_data,len_int);
strcpy(response,"SUCCESS:");
strcat(response,nv_data_str);
}
void oem_nv_set_proccess(char *cmd_parameter, char *response)
{
char *sep = NULL;
char offset[MAX_NV_NUMBER_SIZE] = {0};
uint8_t nv_data[MAX_NV_DATA_SIZE + 32] = {0};
char *nv_data_str;
int data_len;
int ret;
int offset_int = 0;
sep = strstr(cmd_parameter, ":");
if (sep == NULL) {
strcpy(response,"ERROR INVALID PARAM");
return;
}
memcpy(offset,cmd_parameter,sep - cmd_parameter);
nv_data_str = cmd_parameter + (sep - cmd_parameter) + 1;
data_len = strlen(nv_data_str) / 2;
ret = char_to_int(offset,&offset_int);
if (ret != 0) {
strcpy(response,"ERROR OFFSET INVALID");
return;
}
if (data_len > MAX_NV_DATA_SIZE) {
strcpy(response,"ERROR NV SIZE TOO LARGE");
return;
}
str_to_hex(nv_data,nv_data_str,data_len);
ret = nv_set(nv_data, offset_int, data_len);
if (ret != 0) {
strcpy(response,"ERROR NV SET FAILED");
return;
}
strcpy(response,"OKAY");
}
#endif