blob: 3248e0da93a342ac862ad369904c82afd3f7452f [file] [log] [blame]
/******************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2020
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*******************************************************************************/
/******************************************************************************
* Filename:
* ---------
* mcf_cmd.c
*
* Project:
* --------
* Colgin
*
* Description:
* ------------
* MD Configuration Framework, opreation command, send by sAP/openWrt
*
*******************************************************************************/
/******************************************************************************
* Includes
******************************************************************************/
#include <stdbool.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include "mipc_msg_host.h"
/******************************************************************************
* Macro
******************************************************************************/
#define SPECIFIC_MIPC_PORT "/dev/ttyCMIPC9"
/******************************************************************************
* Typedefs
******************************************************************************/
typedef enum {
MCF_CMD_BIN_TYPE_DEFAULT_BIN = 0,
MCF_CMD_BIN_TYPE_CARRIER_BIN = 1,
MCF_CMD_BIN_TYPE_GENERAL_CARRIER_BIN = 2,
MCF_CMD_BIN_TYPE_MAX
} mcf_cmd_bin_type_enum;
typedef enum {
MCF_CMD_PATH_TYPE_OTA = 0,
MCF_CMD_PATH_TYPE_RUNTIME = 1,
MCF_CMD_PATH_TYPE_MAX
} mcf_cmd_path_type_enum;
typedef enum {
MCF_CMD_VARIABLE_ACT_READ_OTA = 0,
MCF_CMD_VARIABLE_ACT_READ_OPOTA = 1,
MCF_CMD_VARIABLE_ACT_WRITE_OTA = 2,
MCF_CMD_VARIABLE_ACT_WRITE_OPOTA = 3,
MCF_CMD_VARIABLE_ACT_MAX
} mcf_cmd_variable_act_enum;
typedef enum {
MCF_CMD_QUERY_VARIABLE_FORM_PATH = 0,
MCF_CMD_QUERY_VARIABLE_FORM_GID = 1,
}mcf_cmd_query_variable_form_enum;
typedef enum {
MCF_CMD_IS_TRIGGER_FALSE = 0,
MCF_CMD_IS_TRIGGER_TRUE = 1,
MCF_CMD_IS_APPEND_OTA = 0,
MCF_CMD_IS_RESET_LID = 1,
MCF_CMD_IS_UPDATE_WITH_NO_READ_INI = 0,
MCF_CMD_IS_UPDATE_WITH_READ_INI = 1,
MCF_PARA_IS_MAX = 2,
} mcf_para_is_enum;
typedef struct {
uint8_t num;
char str[7];
} mapping_table_t;
typedef struct {
/* required parameter */
uint8_t opnum;
uint8_t bin_type;
uint8_t path_folder_idx;
uint8_t appendOTA_resetLID;
/* optional parameter */
uint8_t is_trigger;
uint8_t is_with;
uint8_t record_id;
uint8_t data_length;
/* internal use variable */
uint8_t write_flag;
uint8_t real_write_length;
/* required parameter */
uint32_t gid;
char* file_name;
char* write_value;
/* optional parameter */
char* lid_str;
char* array_index;
/* internal use variable */
uint16_t run_cmd_ret;
uint16_t sim_ps_id;
} mcf_cmd_parameter_list_t;
/******************************************************************************
* Global variables
******************************************************************************/
#define PARA_INT8_ERROE_MAX 0xFF
#define RESULT_SUCCESS 0
#define WRITE_FLAG 90
extern char *optarg;
extern int optind, optopt, opterr;
static mipc_msg_t* msg_req_ptr = NULL;
static mipc_msg_t* msg_cnf_ptr = NULL;
static mcf_cmd_parameter_list_t mc;
/* NOTE: read and write are same opreation code 10 */
static mapping_table_t cmd_map[9] = {
{MIPC_SYS_MCF_OP_GET_APPLIED_FILE_PATH, "get"},
{MIPC_SYS_MCF_OP_DUMP_LID_DATA, "dump"},
{MIPC_SYS_MCF_OP_SET_FILE_PATH_AND_AUTO_SELECT_BIN, "set"},
{MIPC_SYS_MCF_OP_UPDATE_OPOTA_FILE, "update"},
{MIPC_SYS_MCF_OP_QUERY_VARIABLE_VALUE, "read"},
{MIPC_SYS_MCF_OP_QUERY_VARIABLE_VALUE + WRITE_FLAG, "write"},
{MIPC_SYS_MCF_OP_ASSIGN_COMBINED_PATH, "merge"},
{99,"reboot"},
};
static mapping_table_t path_map[2] = {
{MCF_CMD_PATH_TYPE_OTA, "mdota2"},
{MCF_CMD_PATH_TYPE_RUNTIME, "mdota"}
};
#define CMD_MAP_LEN (sizeof(cmd_map)/sizeof(cmd_map[0]))
#define PATH_MAP_LEN (sizeof(path_map)/sizeof(path_map[0]))
//#define USE_DEBUG_LOG
#ifdef USE_DEBUG_LOG
#define debug_log(format, ...) printf(format, ##__VA_ARGS__)
#else
#define debug_log(format, ...)
#endif
/******************************************************************************
* Feature: wait ind callback by linux signal
******************************************************************************/
#define USE_MCF_THREAD_WAIT_IND_CB
#ifdef USE_MCF_THREAD_WAIT_IND_CB
#define WAIT_IND_CB_TIMEOUT_SEC 5
static pthread_cond_t g_cond;
static pthread_mutex_t g_mutex;
static bool g_ind_cb_done = false;
static void mcf_thread_wait_ind_cb(void)
{
struct timeval now_time;
struct timespec out_time;
if (g_ind_cb_done == false) {
pthread_cond_init(&g_cond, NULL);
pthread_mutex_init(&g_mutex, NULL);
gettimeofday(&now_time, NULL);
out_time.tv_sec = now_time.tv_sec + WAIT_IND_CB_TIMEOUT_SEC;
out_time.tv_nsec = now_time.tv_usec * 1000;
debug_log("wait mcf ind cb\n");
pthread_mutex_lock(&g_mutex);
pthread_cond_timedwait(&g_cond, &g_mutex, &out_time);
pthread_mutex_unlock(&g_mutex);
debug_log("wait done\n");
pthread_cond_destroy(&g_cond);
pthread_mutex_destroy(&g_mutex);
}
}
static void mcf_thread_send_signal(void)
{
if (g_ind_cb_done == false) {
pthread_mutex_lock(&g_mutex);
pthread_cond_signal(&g_cond);
pthread_mutex_unlock(&g_mutex);
g_ind_cb_done = true;
}
}
#else
#define mcf_thread_wait_ind_cb()
#define mcf_thread_send_signal()
#endif /* THREAD_WAIT_MCF_IND_CB */
/******************************************************************************
* Functions
******************************************************************************/
static void printf_help(void)
{
char help_text[] = {"Usage:\n"
" mcf_cmd <-o get> <-b bin_type>\n"
" mcf_cmd <-o dump> [-d lid1,lid2,...,lid32]\n"
" mcf_cmd <-o set> <-b bin_type> <-p path_folder> <-f file_name> <-r appendOTA_resetLID> [-t trigger_dsbp] [-s sim_id]\n"
" mcf_cmd <-o update> [-w with_ini]\n"
" mcf_cmd <-o read> <-b bin_type> <-g GID> [-i record_id] [-y array_index] [-l length]\n"
" mcf_cmd <-o write> <-b bin_type> <-g GID> [-i record_id] [-y array_index] [-l length] <-v write_value>\n"
" mcf_cmd <-o merge> <-b bin_type> <-p path_folder> <-f file_name>\n"
" <> is required parameter; [] is optional parameter, notice its default value if not set\n"
" -o, operation (str): get/dump/set/update/read/write/merge\n"
" -b, bin type: 0:OTA, 1:OTA by OP, 2:general OTA by OP\n"
" -d, LID list (str): use \",\" to split, max num is 32; default dump all\n"
" -p, path folder (str): \"mdota\"/\"mdota2\"\n"
" -f, OTA file name (str)\n"
" -r, appendOTA_resetLID: Valid after running merge cmd, 0:append OTA file, 1:reset LIDs\n"
" -t, trigger dsbp: 0:not trigger, 1:trigger; default 0\n"
" -w, update with ini file: 0:no read ini, 1:read ini; default 0\n"
" -i, NVRAM item record id: default 1\n"
" -g, GID number\n"
" -y, array index (str): use \",\" to split; default \"\"\n"
" -l, data length\n"
" -v, write value (str): hex string, use \"3412\" for 0x1234\n"
" -s, send cmd by sim id, support all cmd: 0 for sim1, 1 for sim2, optional, defatul 0\n"
" note: if parameter is string, its \"\" can be omitted\n"
};
printf("%s", help_text);
}
static void mcf_ind_cb(mipc_msg_t *msg_ptr, void *priv_ptr)
{
uint32_t ret;
printf("MCF cmd CB type=%u result=%u\n", mipc_msg_get_val_uint8(msg_ptr, MIPC_SYS_MCF_IND_T_TYPE, 0xff),
ret = mipc_msg_get_val_uint8(msg_ptr, MIPC_SYS_MCF_IND_T_RESULT, 0xff));
if ((mc.opnum == MIPC_SYS_MCF_OP_DUMP_LID_DATA) && (ret == RESULT_SUCCESS)) {
mc.run_cmd_ret = RESULT_SUCCESS;
}
mcf_thread_send_signal();
}
static void mcf_mipc_init(void)
{
#ifdef SPECIFIC_MIPC_PORT
SETCOM(SPECIFIC_MIPC_PORT);
printf("MCF cmd SETCOM %s\n", SPECIFIC_MIPC_PORT);
#endif
mipc_init("mcf_cmd");
mipc_msg_register_ind(mc.sim_ps_id, MIPC_SYS_MCF_IND, mcf_ind_cb, NULL);
}
static void mcf_mipc_deinit(void)
{
mipc_msg_deinit(msg_req_ptr);
mipc_msg_deinit(msg_cnf_ptr);
mipc_deinit();
}
static char* mcf_get_map_str(uint8_t num, mapping_table_t *map, uint32_t map_len)
{
static char* null_str = "";
uint32_t i = 0;
for (i=0;i<map_len;i++) {
if (num == (map+i)->num) {
return (map+i)->str;
}
}
return null_str;
}
static uint8_t mcf_get_map_num(char* str, mapping_table_t *map, uint32_t map_len)
{
uint32_t i = 0;
for (i=0;i<map_len;i++) {
if (strcmp(str, (map+i)->str) == 0) {
if (strcmp(str, "write") == 0) {
mc.write_flag = WRITE_FLAG;
return (map+i)->num - mc.write_flag;
} else {
return (map+i)->num;
}
}
}
return PARA_INT8_ERROE_MAX;
}
static void log_op_error_parameter(uint8_t num)
{
printf("MCF op=\"%s\" error parameter, CHECK!\nRun mcf_cmd to see the format!", mcf_get_map_str(num, cmd_map, CMD_MAP_LEN));
}
static void log_mipc_result_fail(uint32_t result)
{
printf("MCF cmd FAIL, mipc result=%u\n", result);
}
static void mcf_cmd_parameters_init(void)
{
/* required parameter, will check them */
mc.opnum = PARA_INT8_ERROE_MAX;
mc.bin_type = PARA_INT8_ERROE_MAX;
mc.path_folder_idx = PARA_INT8_ERROE_MAX;
mc.appendOTA_resetLID = PARA_INT8_ERROE_MAX;
mc.gid = 0;
mc.file_name = NULL;
mc.write_value = NULL;
/* optional parameter, set default value */
mc.is_trigger = 0;
mc.is_with = 0;
mc.record_id = 1;
mc.data_length = 0;
mc.lid_str = "";
mc.array_index = "";
/* internal use variable */
mc.write_flag = 0;
mc.real_write_length = 0;
mc.run_cmd_ret = PARA_INT8_ERROE_MAX; // linux shell only get 0~255
mc.sim_ps_id = MIPC_MSG_PS0; // set default as MIPC_MSG_PS0
}
static void mcf_cmd_hex_string_to_bytes(char *input_string)
{
uint32_t length = strlen(input_string);
uint8_t temp[2];
uint32_t i,j;
if (length%2 != 0) {
printf("write_value str len need be even\n");
return;
}
char* pdata = malloc(length/2);
if (pdata == NULL) return;
for (i=0;i<length/2;i++) {
temp[0] = input_string[i*2];
temp[1] = input_string[i*2+1];
for (j=0; j<2; j++) {
if (temp[j] >= '0' && temp[j] <= '9') {
temp[j] = temp[j] - '0';
} else if (temp[j] >= 'a' && temp[j] <= 'f') {
temp[j] = temp[j] - 'a' + 10;
} else if (temp[j] >= 'A' && temp[j] <= 'F') {
temp[j] = temp[j] - 'A' + 10;
} else {
free(pdata);
return;
}
}
pdata[i] = (temp[0]<<4) | temp[1];
}
if (mc.write_value != NULL) free(mc.write_value);
mc.write_value = pdata;
mc.real_write_length = length/2;
}
static void mcf_cmd_parameters_parser(int argc, char *argv[])
{
uint32_t ch;
uint16_t sim_id;
char* opstr = "";
if (argc == 1) {
printf_help();
mc.run_cmd_ret = RESULT_SUCCESS;
return;
}
while ((ch = getopt(argc, argv, "o:b:d:p:f:t:r:w:g:i:y:l:v:s:")) != -1) {
switch(ch) {
case 'o':
mc.opnum = mcf_get_map_num(optarg, cmd_map, CMD_MAP_LEN);
opstr = optarg;
break;
case 'b':
mc.bin_type = atoi(optarg);
break;
case 'd':
mc.lid_str = optarg;
break;
case 'p':
mc.path_folder_idx = mcf_get_map_num(optarg, path_map, PATH_MAP_LEN);
break;
case 'f':
mc.file_name = optarg;
break;
case 't':
mc.is_trigger = atoi(optarg);
break;
case 'r':
mc.appendOTA_resetLID = atoi(optarg);
break;
case 'w':
mc.is_with = atoi(optarg);
break;
case 'g':
mc.gid = atoi(optarg);
break;
case 'i':
mc.record_id = atoi(optarg);
break;
case 'y':
mc.array_index = optarg;
break;
case 'l':
mc.data_length = atoi(optarg);
break;
case 'v':
mcf_cmd_hex_string_to_bytes(optarg);
break;
case 's':
sim_id = atoi(optarg);
if (sim_id == 0xFF) {
mc.sim_ps_id = MIPC_MSG_ALL;
} else if (sim_id <= 7) {
mc.sim_ps_id = (mipc_msg_sim_ps_id_enum)(1 << sim_id);
}
break;
default:
break;
}
}
if (mc.opnum == PARA_INT8_ERROE_MAX) {
printf("MCF unsupport: -o \"%s\"\n", opstr);
}
}
static void mcf_cmd_parameters_free(void)
{
if(mc.write_value != NULL)
free(mc.write_value);
}
/*******************************************************************************
* origin cmd: AT+EMCFC=4,<config_type>
* response: +EMCFC:4,<config_type>,<path_type>,<config1 str>
* ind cb: none
* mcf cmd: mcf_cmd <-o get> <-b bin_type>
*******************************************************************************/
static void mcf_cmd_op_get_applied_file_path(int argc, char *argv[])
{
uint32_t mipc_ret = 0;
if (mc.bin_type >= MCF_CMD_BIN_TYPE_MAX) {
log_op_error_parameter(MIPC_SYS_MCF_OP_GET_APPLIED_FILE_PATH);
return;
}
msg_req_ptr = mipc_msg_init(MIPC_SYS_MCF_REQ, mc.sim_ps_id);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_OP, MIPC_SYS_MCF_OP_GET_APPLIED_FILE_PATH);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_CONFIG_TYPE, mc.bin_type);
msg_cnf_ptr = mipc_msg_sync(msg_req_ptr);
mipc_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_T_RESULT, MIPC_RESULT_FAILURE);
if (mipc_ret == MIPC_RESULT_SUCCESS) {
printf("MCF cmd SUCCESS op=\"%s\" bin_type=%u path_folder=\"%s\" config_file=\"%s\"\n",
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_OP, 0xff), cmd_map, CMD_MAP_LEN),
mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_CONFIG_TYPE, 0xff),
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_PATH_TYPE, 0xff), path_map, PATH_MAP_LEN),
(char *)mipc_msg_get_val_ptr(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_CONFIG1, NULL));
mc.run_cmd_ret = RESULT_SUCCESS;
} else {
log_mipc_result_fail(mipc_ret);
}
}
/*******************************************************************************
* origin cmd: AT+EMCFC=5 [lid1,lid2,...,lid32]
* response: +EMCFC:5,<MCF result>
* ind cb: +EMCFRPT:<type>,<MCF result>
* mcf cmd: mcf_cmd <-o dump> [-d lid1,lid2,...,lid32]
*******************************************************************************/
static void mcf_cmd_op_dump_lid_data(int argc, char *argv[])
{
uint32_t mipc_ret = 0, mcf_ret = 0xffffffff;
msg_req_ptr = mipc_msg_init(MIPC_SYS_MCF_REQ, mc.sim_ps_id);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_OP, MIPC_SYS_MCF_OP_DUMP_LID_DATA);
if (strcmp(mc.lid_str, "") != 0) {
mipc_msg_add_tlv(msg_req_ptr, MIPC_SYS_MCF_REQ_T_DUMP_LIDS, strlen(mc.lid_str) + 1, mc.lid_str);
}
msg_cnf_ptr = mipc_msg_sync(msg_req_ptr);
mipc_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_T_RESULT, MIPC_RESULT_FAILURE);
if (mipc_ret == MIPC_RESULT_SUCCESS) {
printf("MCF cmd SUCCESS op=\"%s\" mcf_result=%u\n",
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_OP, 0xff), cmd_map, CMD_MAP_LEN),
mcf_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_MCF_RESULT, 0xffffffff));
} else {
log_mipc_result_fail(mipc_ret);
}
if(mcf_ret == RESULT_SUCCESS) {
mcf_thread_wait_ind_cb();
}
}
/*******************************************************************************
* origin cmd: AT+EMCFC=6,<config_type>,<path_type>,<config1 str>,<trigger_dsbp>,<is_reset>
* response: +EMCFC:6,<MCF result>,<DSBP result>
* ind cb: (if trigger_dsbp == 1) +EMCFRPT:<type>,<DSBP result>
* mcf cmd: mcf_cmd <-o set> <-b bin_type> <-p path_folder> <-f file_name> <-r append_resetLID> [-t trigger_dsbp]
*******************************************************************************/
static void mcf_cmd_op_set_file_path_and_auto_select_bin(int argc, char *argv[])
{
uint32_t mipc_ret = 0, mcf_ret = 0xffffffff, dsbp_ret = 0xffffffff;
if ((mc.bin_type >= MCF_CMD_BIN_TYPE_MAX) || (mc.path_folder_idx >= MCF_CMD_PATH_TYPE_MAX) || (mc.file_name == NULL ) ||
(mc.is_trigger >= MCF_PARA_IS_MAX )|| (mc.appendOTA_resetLID >= MCF_PARA_IS_MAX)) {
log_op_error_parameter(MIPC_SYS_MCF_OP_SET_FILE_PATH_AND_AUTO_SELECT_BIN);
return;
}
msg_req_ptr = mipc_msg_init(MIPC_SYS_MCF_REQ, mc.sim_ps_id);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_OP, MIPC_SYS_MCF_OP_SET_FILE_PATH_AND_AUTO_SELECT_BIN);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_CONFIG_TYPE, mc.bin_type);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_PATH_TYPE, mc.path_folder_idx);
mipc_msg_add_tlv(msg_req_ptr, MIPC_SYS_MCF_REQ_T_CONFIG1, strlen(mc.file_name)+1, mc.file_name);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_TRIGGER_DSBP, mc.is_trigger);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_IS_RESET, mc.appendOTA_resetLID);
msg_cnf_ptr = mipc_msg_sync(msg_req_ptr);
mipc_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_T_RESULT, MIPC_RESULT_FAILURE);
if (mipc_ret == MIPC_RESULT_SUCCESS) {
printf("MCF cmd SUCCESS op=\"%s\" mcf_result=%u dsbp_result=%u\n",
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_OP, 0xff), cmd_map, CMD_MAP_LEN),
mcf_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_MCF_RESULT, 0xffffffff),
dsbp_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_DSBP_RESULT, 0xffffffff));
} else {
log_mipc_result_fail(mipc_ret);
}
if (mcf_ret == RESULT_SUCCESS && dsbp_ret == RESULT_SUCCESS) {
mc.run_cmd_ret = RESULT_SUCCESS;
if(mc.is_trigger == MCF_CMD_IS_TRIGGER_TRUE) {
mcf_thread_wait_ind_cb();
}
}
}
/*******************************************************************************
* cmd: AT+EMCFC=7,<action>
* response: +EMCFC:7,<MCF result>
* ind cb: +EMCFRPT:<type>,<result>
* mcf cmd: mcf_cmd <-o update> [-w with_ini]
*******************************************************************************/
static void mcf_cmd_op_update_opota_file(int argc, char *argv[])
{
uint32_t mipc_ret = 0, mcf_ret = 0xffffffff;
if (mc.is_with >= MCF_PARA_IS_MAX) {
log_op_error_parameter(MIPC_SYS_MCF_OP_UPDATE_OPOTA_FILE);
return;
}
msg_req_ptr = mipc_msg_init(MIPC_SYS_MCF_REQ, mc.sim_ps_id);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_OP, MIPC_SYS_MCF_OP_UPDATE_OPOTA_FILE);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_ACTION, mc.is_with);
msg_cnf_ptr = mipc_msg_sync(msg_req_ptr);
mipc_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_T_RESULT, MIPC_RESULT_FAILURE);
if (mipc_ret == MIPC_RESULT_SUCCESS) {
printf("MCF cmd SUCCESS op=\"%s\" mcf_result=%u\n",
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_OP, 0xff), cmd_map, CMD_MAP_LEN),
mcf_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_MCF_RESULT, 0xffffffff));
} else {
log_mipc_result_fail(mipc_ret);
}
if (mcf_ret == RESULT_SUCCESS) {
mc.run_cmd_ret = RESULT_SUCCESS;
mcf_thread_wait_ind_cb();
}
}
/*******************************************************************************
* cmd: AT+EMCFC=10,<format>,<action>,<record ID>,<number>,<config str>[,<length>],[,<value>]]
* response: +EMCFC:10,<format>,<action>,<mcf result>,<length>,<value>
* ind cb: none
* mcf_cmd <-o read> <-b bin_type> <-g GID> [-i record_id] [-y array_index] [-l length]
* mcf_cmd <-o write> <-b bin_type> <-g GID> [-i record_id] [-y array_index] [-l length] <-v write_value>
*******************************************************************************/
static void mcf_cmd_op_query_variable_value(int argc, char *argv[])
{
uint32_t mipc_ret = 0, mcf_ret = 0xffffffff;
uint8_t action, ret_len, i;
char *ret_str;
if ((mc.bin_type >= MCF_CMD_BIN_TYPE_MAX) || (mc.gid == 0) || (mc.write_flag == WRITE_FLAG && mc.write_value == NULL)) {
log_op_error_parameter(MIPC_SYS_MCF_OP_QUERY_VARIABLE_VALUE);
return;
}
if (mc.write_flag != WRITE_FLAG) {
action = (mc.bin_type == MCF_CMD_BIN_TYPE_DEFAULT_BIN) ? MCF_CMD_VARIABLE_ACT_READ_OTA : MCF_CMD_VARIABLE_ACT_READ_OPOTA;
} else {
action = (mc.bin_type == MCF_CMD_BIN_TYPE_DEFAULT_BIN) ? MCF_CMD_VARIABLE_ACT_WRITE_OTA : MCF_CMD_VARIABLE_ACT_WRITE_OPOTA;
}
msg_req_ptr = mipc_msg_init(MIPC_SYS_MCF_REQ, mc.sim_ps_id);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_OP, MIPC_SYS_MCF_OP_QUERY_VARIABLE_VALUE);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_FORMAT, MCF_CMD_QUERY_VARIABLE_FORM_GID);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_ACTION, action);
mipc_msg_add_tlv_uint32(msg_req_ptr, MIPC_SYS_MCF_REQ_T_NUM, mc.gid);
mipc_msg_add_tlv_uint16(msg_req_ptr, MIPC_SYS_MCF_REQ_T_REC_ID, mc.record_id);
mipc_msg_add_tlv(msg_req_ptr, MIPC_SYS_MCF_REQ_T_CONFIG, strlen(mc.array_index)+1, mc.array_index);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_LEN, mc.data_length);
if (mc.write_flag == WRITE_FLAG) {
mipc_msg_add_tlv(msg_req_ptr, MIPC_SYS_MCF_REQ_T_VALUE, mc.real_write_length, mc.write_value);
}
msg_cnf_ptr = mipc_msg_sync(msg_req_ptr);
mipc_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_T_RESULT, MIPC_RESULT_FAILURE);
if (mipc_ret == MIPC_RESULT_SUCCESS) {
printf("MCF cmd SUCCESS op=\"%s\" mcf_result=%u bin_type=%u",
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_OP, 0xff)+mc.write_flag, cmd_map, CMD_MAP_LEN),
mcf_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_MCF_RESULT, 0xffffffff),
(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_ACTION, 0xff)%2 == 0) ? MCF_CMD_BIN_TYPE_DEFAULT_BIN : MCF_CMD_BIN_TYPE_CARRIER_BIN);
if (mcf_ret == RESULT_SUCCESS) {
mc.run_cmd_ret = RESULT_SUCCESS;
ret_len = mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_LEN, 0xff);
printf(" length=%u", ret_len);
if (mc.write_flag != WRITE_FLAG) {
ret_str = (char*)mipc_msg_get_val_ptr(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_VALUE, NULL);
printf(" value=\"");
for (i=0;i<ret_len;i++) {
printf("%02X", *(ret_str + i));
}
printf("\"");
}
}
printf("\n");
} else {
log_mipc_result_fail(mipc_ret);
}
}
/*******************************************************************************
* cmd: AT+EMCFC=11,<config_type>,<path_type>,<config1 str>
* response: +EMCFC:11,<MCF result>
* ind cb: none
* mcf cmd: mcf_cmd <-o merge> <-b bin_type> <-p path_folder> <-f file_name>
*******************************************************************************/
static void mcf_cmd_op_assign_combined_path(int argc, char *argv[])
{
uint32_t mipc_ret = 0, mcf_ret = 0xffffffff;
if ((mc.bin_type >= MCF_CMD_BIN_TYPE_MAX) || (mc.path_folder_idx >= MCF_CMD_PATH_TYPE_MAX) || (mc.file_name == NULL)) {
log_op_error_parameter(MIPC_SYS_MCF_OP_ASSIGN_COMBINED_PATH);
return;
}
msg_req_ptr = mipc_msg_init(MIPC_SYS_MCF_REQ, mc.sim_ps_id);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_OP, MIPC_SYS_MCF_OP_ASSIGN_COMBINED_PATH);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_CONFIG_TYPE, mc.bin_type);
mipc_msg_add_tlv_uint8(msg_req_ptr, MIPC_SYS_MCF_REQ_T_PATH_TYPE, mc.path_folder_idx);
mipc_msg_add_tlv(msg_req_ptr, MIPC_SYS_MCF_REQ_T_CONFIG1, strlen(mc.file_name)+1, mc.file_name);
msg_cnf_ptr = mipc_msg_sync(msg_req_ptr);
mipc_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_T_RESULT, MIPC_RESULT_FAILURE);
if (mipc_ret == MIPC_RESULT_SUCCESS) {
printf("MCF cmd SUCCESS op=\"%s\" mcf_result=%u\n",
mcf_get_map_str(mipc_msg_get_val_uint8(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_OP, 0xff), cmd_map, CMD_MAP_LEN),
mcf_ret = mipc_msg_get_val_uint32(msg_cnf_ptr, MIPC_SYS_MCF_CNF_T_MCF_RESULT, 0xffffffff));
if (mcf_ret == RESULT_SUCCESS) {
mc.run_cmd_ret = RESULT_SUCCESS;
}
} else {
log_mipc_result_fail(mipc_ret);
}
}
static void mcf_system_reboot(void)
{
printf("MCF system reboot\n");
system("reboot");
}
int main(int argc, char *argv[])
{
mcf_cmd_parameters_init();
mcf_cmd_parameters_parser(argc, argv);
if (mc.opnum != PARA_INT8_ERROE_MAX)
{
mcf_mipc_init();
switch (mc.opnum) {
case MIPC_SYS_MCF_OP_GET_APPLIED_FILE_PATH:
mcf_cmd_op_get_applied_file_path(argc, argv);
break;
case MIPC_SYS_MCF_OP_DUMP_LID_DATA:
mcf_cmd_op_dump_lid_data(argc, argv);
break;
case MIPC_SYS_MCF_OP_SET_FILE_PATH_AND_AUTO_SELECT_BIN:
mcf_cmd_op_set_file_path_and_auto_select_bin(argc, argv);
break;
case MIPC_SYS_MCF_OP_UPDATE_OPOTA_FILE:
mcf_cmd_op_update_opota_file(argc, argv);
break;
case MIPC_SYS_MCF_OP_QUERY_VARIABLE_VALUE:
mcf_cmd_op_query_variable_value(argc, argv);
break;
case MIPC_SYS_MCF_OP_ASSIGN_COMBINED_PATH:
mcf_cmd_op_assign_combined_path(argc, argv);
break;
case 99:
mcf_system_reboot();
default:
break;
}
mcf_mipc_deinit();
}
mcf_cmd_parameters_free();
return mc.run_cmd_ret;
}