blob: 04ef676ba83743c505305d9f11a1f60c19e4a285 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include "ql_fota_api.h"
#include "fota_info.h"
#include "ql_fota.h"
//#include "ql_fota_log.h"
#include "ql_absys_api.h"
//#include "test_utils.h"
typedef void (*item_handler_f)(void);
typedef int (*init_handler_f)(void);
typedef int (*deinit_handler_f)(void);
#define T_ARRAY_SIZE(items) (sizeof(items)/sizeof(items[0]))
typedef struct
{
const char *name;
item_handler_f handle;
} t_item_t;
typedef struct
{
const char *name;
int item_len;
t_item_t *item_list;
} t_module_t;
typedef struct
{
const char *name;
init_handler_f init_handle;
deinit_handler_f deinit_handle;
} t_init_t;
int t_get_int(int *val);
int t_get_hex(uint32_t *val);
int t_get_char(int *val);
int t_get_string(char *str_buf, int str_len);
int t_get_int_list(int *dat_buf, int *dat_len);
int t_get_float_list(float *dat_buf, int *dat_len);
/*-----------------------------------------------------------------------------------------------*/
/**
@brief Read a int value from stdin
@param[out] val, Return read data
@return
0 - successful
1 - read an enter
-1 - invalid input
*/
/*-----------------------------------------------------------------------------------------------*/
int t_get_int(int *val)
{
int dat;
char *ptr_end = NULL;
char buf[256] = {0};
if(NULL == fgets(buf, sizeof(buf)-1, stdin))
{
return -1;
}
if(0 == buf[0])
{
return -1;
}
if(buf[0] == '\n')
{
return 1;
}
dat = strtol(buf, &ptr_end, 10);
if(ptr_end!=NULL && ptr_end[0]!='\n')
{
return -1;
}
if(val)
{
val[0] = dat;
}
return 0;
}
/*-----------------------------------------------------------------------------------------------*/
/**
@brief Read a uint32 value from stdin
@param[out] val, Return read data
@return
0 - successful
1 - read an enter
-1 - invalid input
*/
/*-----------------------------------------------------------------------------------------------*/
int t_get_hex(uint32_t *val)
{
int dat;
char *ptr_end = NULL;
char buf[256] = {0};
if(fgets(buf, sizeof(buf)-1, stdin) == NULL)
{
return -1;
}
if(0 == buf[0])
{
return -1;
}
if(buf[0] == '\n')
{
return 1;
}
dat = strtol(buf, &ptr_end, 16);
if(ptr_end!=NULL && ptr_end[0]!='\n')
{
return -1;
}
if(val)
{
val[0] = dat;
}
return 0;
}
/*-----------------------------------------------------------------------------------------------*/
/**
@brief Read a char value from stdin
@param[out] val, Return read data
@return
0 - successful
1 - read an enter
-1 - invalid input
*/
/*-----------------------------------------------------------------------------------------------*/
int t_get_char(int *val)
{
char buf[256] = {0};
if(fgets(buf, sizeof(buf)-1, stdin) == NULL)
{
return -1;
}
if(0 == buf[0])
{
return -1;
}
if(buf[0] == '\n')
{
return 1;
}
if(buf[1]!='\n')
{
return -1;
}
if(val)
{
val[0] = buf[0];
}
return 0;
}
/*-----------------------------------------------------------------------------------------------*/
/**
@brief Read a string value from stdin
@param[out] val, Return read data
@return
0 - successful
1 - read an enter
-1 - invalid input
*/
/*-----------------------------------------------------------------------------------------------*/
int t_get_string(char *str_buf, int str_len)
{
char *ptr;
char buf[256] = {0};
if(fgets(buf, sizeof(buf)-1, stdin) == NULL)
{
return -1;
}
if(0 == buf[0])
{
return -1;
}
if(buf[0] == '\n')
{
return 1;
}
ptr = strchr(buf, '\n');
if(ptr)
{
ptr[0] = 0;
}
strncpy(str_buf, buf, str_len-1);
return 0;
}
/*-----------------------------------------------------------------------------------------------*/
/**
@brief Read a list of int values from stdin
@param[out] val, Return read datas
@param[out&in] val, Input buffer length, output the number of read
@return
0 - successful
1 - read an enter
-1 - invalid input
*/
/*-----------------------------------------------------------------------------------------------*/
int t_get_int_list(int *dat_buf, int *dat_len)
{
int idx = 0;
int len;
int dat;
char *ptr, *ptr_save;
char *ptr_end;
char buf[256] = {0};
if(!dat_buf || !dat_len)
{
return -1;
}
len = dat_len[0];
if(fgets(buf, sizeof(buf)-1, stdin) == NULL)
{
return -1;
}
if(0 == buf[0])
{
return -1;
}
if(buf[0] == '\n')
{
return 1;
}
for(ptr=strtok_r(buf, ",.: \t\r\n", &ptr_save);
ptr!=NULL;
ptr=strtok_r(NULL, ",.: \t\r\n", &ptr_save))
{
dat = strtol(ptr, &ptr_end, 10);
if(ptr_end!=NULL && ptr_end[0]!=0)
{
return -1;
}
if(idx >= len)
{
return 0;
}
dat_buf[idx] = dat;
idx++;
}
dat_len[0] = idx;
return 0;
}
/*-----------------------------------------------------------------------------------------------*/
/**
@brief Read a list of float values from stdin
@param[out] val, Return read datas
@param[out&in] val, Input buffer length, output the number of read
@return
0 - successful
1 - read an enter
-1 - invalid input
*/
/*-----------------------------------------------------------------------------------------------*/
int t_get_float_list(float *dat_buf, int *dat_len)
{
int idx = 0;
int len;
float dat;
char *ptr, *ptr_save;
char *ptr_end;
char buf[256] = {0};
if(!dat_buf || !dat_len)
{
return -1;
}
len = dat_len[0];
if(fgets(buf, sizeof(buf)-1, stdin) == NULL)
{
return -1;
}
if(0 == buf[0])
{
return -1;
}
if(buf[0] == '\n')
{
return 1;
}
for(ptr=strtok_r(buf, ",: \t\r\n", &ptr_save);
ptr!=NULL;
ptr=strtok_r(NULL, ",: \t\r\n", &ptr_save))
{
dat = strtof(ptr, &ptr_end);
if(ptr_end!=NULL && ptr_end[0]!=0)
{
return -1;
}
if(idx >= len)
{
return 0;
}
dat_buf[idx] = dat;
idx++;
}
dat_len[0] = idx;
return 0;
}
#if 0
#define DEBUG_INFO
#ifdef DEBUG_INFO
#define LOG_DBG(fmt, ...) printf("[DBG][%s_%d][%ld] "fmt"\n", __FUNCTION__, __LINE__, time(NULL), ##__VA_ARGS__)
#else
#define LOG_DBG(fmt, ...)
#endif
#define LOG_ERR(fmt, ...) printf("[DBG][%s_%d][%ld] "fmt"\n", __FUNCTION__, __LINE__, time(NULL), ##__VA_ARGS__)
#endif
#define ITEM_NUM (sizeof(g_items)/sizeof(g_items[0]))
void test_ota_api_start(void);
void test_get_fota_upgrade_info(void);
void test_ql_absys_switch(void);
void test_ql_absys_get_cur_active_part(void);
void test_ql_absys_sync(void);
void test_ql_absys_getstatus(void);
void test_ql_fota_fw_write_by_url(void);
t_item_t g_items[] = {
{"API : ql_abfota_start_update", test_ota_api_start},
{"API : ql_abfota_get_update_status", test_get_fota_upgrade_info},
{"API : ql_absys_switch", test_ql_absys_switch},
{"API : ql_absys_sync", test_ql_absys_sync},
{"API : ql_absys_get_cur_active_part", test_ql_absys_get_cur_active_part},
{"API : ql_absys_getstatus", test_ql_absys_getstatus}
};
void dump_items(void)
{
int i;
printf("\n");
for(i=0; i<ITEM_NUM; i++)
{
printf("%d\t%s\n", i, g_items[i].name);
}
printf("-1\texit\n");
}
int main(int argc, const char **argv)
{
int ret = -1;
int idx = 0;
printf("Quectel OTA API test sample, version : v0.0.1\n");
dump_items();
while(1) {
printf("Please enter your choice: ");
ret = t_get_int(&idx);
printf("\n");
if(ret < 0) {
printf("Invalid input\n");
continue;
} else if(ret == 1) {
dump_items();
continue;
}
if(idx == -1) {
break;
}
if(idx<0 || idx>=ITEM_NUM) {
printf("Not support idx: %d\n", idx);
continue;
}
g_items[idx].handle();
}
return 0;
}
void test_ota_api_start(void)
{
char package_file[128] = {0};
int ret = -1;
printf("please input the fota fbf package file dir: \n");
printf("eg: /user_data/\n");
//fota包同时已经放入该路径下
memset(package_file, 0x0, sizeof(package_file));
scanf("%s", package_file);
fflush(stdin);
ret = t_get_string((char*)package_file, sizeof(package_file));
if (ret < 0 || package_file[0] == 0) {
printf("Invalid package file\n");
return;
}
ret = ql_abfota_start_update((char*)package_file);
if (ret != 0) {
printf("run ql_abfota_start_update failed, api return: %d\n", ret);
return;
}
printf("Update in-active partition SUCCEED\n");
return;
}
void test_ql_absys_getstatus(void)
{
int status = 0;
// char stat_buf[16] = {0};
sysstatus_t sys_state;
status = ql_absys_getstatus(&sys_state);
if (status < 0) {
printf("failed to get absys status!!!\n");
return;
}
if (sys_state.is_damaged == 0)
{
printf("absys partition status : succeed\n");
}
else
{
printf("absys partition status : damaged\n");
printf("absys partition damaged position : %s\n", sys_state.damaged_partname);
printf("absys needsync!!!\n");
}
return;
}
void test_get_fota_upgrade_info(void)
{
int ret = -1;
char stat_buf[16] = {0};
update_info_t update_info;
ret = ql_abfota_get_update_status(&update_info);
if ( ret != 0) {
printf("run ql_abfota_start_update failed, api return: %d\n", ret);
return;
}
memset(stat_buf, 0, sizeof(stat_buf));
switch (update_info.ota_state) {
case SUCCEED:
strncpy(stat_buf, "SUCCEED", strlen("SUCCEED")+1);
break;
case UPDATE:
strncpy(stat_buf, "UPDATE", strlen("UPDATE")+1);
break;
case BACKUP:
strncpy(stat_buf, "BACKUP", strlen("BACKUP")+1);
break;
case FAILED:
strncpy(stat_buf, "FAILED", strlen("FAILED")+1);
break;
case WRITEDONE:
strncpy(stat_buf, "WRITEDONE", strlen("WRITEDONE")+1);
break;
case NEEDSYNC:
strncpy(stat_buf, "NEEDSYNC", strlen("NEEDSYNC")+1);
break;
case UNKNOWN_STATUS:
default:
strncpy(stat_buf, "UNKNOWN_STATUS", strlen("UNKNOWN_STATUS")+1);
break;
}
printf("Current fota progress: %d\n", update_info.percentage);
printf("Current fota state: %s\n", stat_buf);
printf("Current fota exit code: %d\n", update_info.exit_code);
return;
}
void test_ql_absys_switch(void)
{
int ret = -1;
ret = ql_absys_switch();
if (ret != 0) {
printf("run ql_absys_switch failed, api return: %d\n", ret);
return;
}
printf("It is okay to swith AB part to run\n");
sleep(1);
system("reboot");
return;
}
void test_ql_absys_sync(void)
{
int ret = -1;
ret = ql_absys_sync();
if (ret != 0) {
printf("run ql_absys_sync failed, api return: %d\n", ret);
return;
}
printf("do AB sync succeed\n");
return;
}
void test_ql_absys_get_cur_active_part(void)
{
int ret = -1;
absystem_t cur_system;
ret = ql_absys_get_cur_active_part(&cur_system);
if (ret != 0) {
printf("run ql_absys_get_cur_active_part failed, api return: %d\n", ret);
return;
}
printf("Current active part is %c\n", (cur_system ? 'B': 'A'));
return;
}