| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <dlfcn.h> |
| #include <stdint.h> |
| |
| #include <errno.h> |
| #include <stdbool.h> |
| |
| #include "gsw_ota_ua_interface.h" |
| #include "gsw_log_interface.h" |
| |
| |
| #define LYNQ_OTA_INPROCESS 3 |
| #define LYNQ_OTA_SUCCESS 4 |
| #define LYNQ_OTA_FAILED 5 |
| |
| |
| |
| #define LIB_PATH "/lib/libmbtk_lib.so" |
| |
| #define GSW_OTA "[HAL][GSW_OTA]" |
| |
| #define StatFunc(x,y) stat(x,y) |
| |
| typedef enum |
| { |
| GSW_UPDATE_SUCCEED = 0, //update succeed |
| GSW_UPDATE_INPROGRESS, //update in progress |
| GSW_UPDATE_BACKUP, //A/B partition sync in progress |
| GSW_UPDATE_FAILED, //update failed |
| GSW_UPDATE_WAITEDONE, //update in-active part finished,not switch update part. |
| GSW_UPDATE_NEEDSYNC, //switch update part, need sync A/B part |
| GSW_UPDATE_CANCEL //updata cancel success |
| }gsw_update_state_t; |
| |
| typedef enum |
| { |
| GSW_UPDATE_NOERROR=0, //升级成功 |
| GSW_UPDATE_ARGUMENTERROR, //升级程序启动参数错误 |
| GSW_UPDATE_SDCARDNOEXIST, //未挂载外置FLASH等存储设备 |
| GSW_UPDATE_PACKAGENOEXIST, //升级包不存在 |
| GSW_UPDATE_UNZIPFAILED, //解压升级包出错 |
| GSW_UPDATE_PARTITIONFLUSHERROR,//写入分区出错 |
| GSW_UPDATE_XMLPARSEERROR, //解析 fotaconfig.xml 文件出错 |
| GSW_UPDATE_DIFFUBIUNATTACH, //差分升级 UBI 分区挂载异常 |
| GSW_UPDATE_NOSPACELEFT, //空间不足 |
| GSW_UPDATE_FILECHECKFAILED, //MD5 值校验失败 |
| GSW_UPDATE_BSPATCHFAILED, //bspatch 合成新文件夹失败 |
| GSW_UPDATE_NOFINDPARTITION, //待升级分区不存在 |
| GSW_UPDATE_UBIVOLUMEERROR, //差分升级,待升级 UBI 卷不存在 |
| GSW_UPDATE_NOFOTACONFIGFILE, //升级包中无 fotaconfig.xml 文件 |
| GSW_UPDATE_GETOLDSOFTWAREFAILED,//读取原始版本固件失败 |
| GSW_UPDATE_FILENOTEXIST, //文件不存在 |
| GSW_UPDATE_UPGRADECANCELED, //升级或分区同步被取消 |
| GSW_UPDATE_NONEEDCANCEL, //取消升级失败 |
| GSW_UPDATE_NOGOING //升级或分区同步正在进行,不可重复操作 |
| }gsw_update_exit_code_t; |
| |
| |
| typedef struct |
| { |
| unsigned int percentage; //update progress0-100 |
| gsw_update_state_t update_state; |
| gsw_update_exit_code_t exit_code; |
| }gsw_update_info_s; |
| |
| typedef struct |
| { |
| gsw_update_state_t update_state; |
| uint8_t is_damaged; //TURE: damaged FALSE:no damaged |
| uint8_t damaged_partname[16]; |
| }gsw_system_status_s; |
| |
| typedef int (*mbtk_fota_get_active_absys_type)(void); |
| typedef int (*mbtk_fota_fw_write)(char* fname, int segment_size); |
| typedef int (*mbtk_fota_fw_write_by_url)(char* url, int segment_size, |
| int conn_timeout, int download_timeout); |
| |
| typedef int(*fota_callback)(int state, int percent); |
| typedef int (*mbtk_fota_init)(fota_callback cb); |
| typedef int (*mbtk_fota_status)(void); |
| |
| static int segment_size =0; |
| static int Process_flag = 0; |
| char addr_buf[256] = {0}; |
| static void *handle = NULL; |
| |
| |
| static int s_ota_flag = -1; |
| |
| int fota_cb(int status, int percent) |
| { |
| Process_flag = percent; |
| return 0; |
| } |
| |
| static int funstat( char *filename) |
| { |
| int ret = 0; |
| struct stat tmep_s; |
| |
| memset(&tmep_s, 0, sizeof(stat)); |
| ret = StatFunc(filename, &tmep_s); |
| |
| if (ret) |
| { |
| LOGE(GSW_OTA, "stat %s failed! error_code:%s", filename ,strerror(errno)); |
| return -1; |
| } |
| |
| if (tmep_s.st_size > 0) |
| { |
| segment_size = tmep_s.st_size; |
| } |
| |
| return 0; |
| } |
| |
| int32_t init_handle() |
| { |
| if(handle == NULL) |
| { |
| handle = dlopen(LIB_PATH, RTLD_NOW ); |
| if(handle == NULL) |
| { |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| } |
| |
| return GSW_HAL_SUCCESS; |
| } |
| |
| /** |
| * @brief Start install modem software |
| * @param [in] char* file_path |
| * @param [out] NULL |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_start_autobackup(char* file_path) |
| { |
| |
| if(file_path == NULL) |
| { |
| LOGE(GSW_OTA, "invalid file_path \n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| |
| mbtk_fota_fw_write func_ptr_update = NULL; |
| mbtk_fota_init func_ptr_init= NULL; |
| mbtk_fota_fw_write_by_url func_ptr_update_url = NULL; |
| |
| |
| |
| int ret = -1; |
| ret = init_handle(); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "init_handle fail"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| func_ptr_update_url = (mbtk_fota_fw_write_by_url)dlsym(handle, "mbtk_fota_fw_write_by_url"); |
| if(func_ptr_update_url == NULL) |
| { |
| LOGE(GSW_OTA, "Error: %s", dlerror()); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| |
| // Get the function pointer |
| func_ptr_update = (mbtk_fota_fw_write)dlsym(handle, "mbtk_fota_fw_write"); |
| if (func_ptr_update == NULL) |
| { |
| LOGE(GSW_OTA, "Error: %s", dlerror()); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| func_ptr_init = (mbtk_fota_init)dlsym(handle, "mbtk_fota_init"); |
| if(func_ptr_init == NULL) |
| { |
| LOGE(GSW_OTA, "Error: %s", dlerror()); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| |
| if(s_ota_flag == -1) |
| { |
| ret = func_ptr_init(fota_cb); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "Error: mbtk_fota_init failed"); |
| |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| else |
| { |
| s_ota_flag = 0; |
| } |
| } |
| |
| if(strncmp(file_path, "http", 4) == 0) |
| { |
| segment_size = 62914560; |
| ret = func_ptr_update_url(file_path, segment_size,10, 600); |
| } |
| else |
| { |
| if(strstr(file_path,"fota.delta") == NULL) |
| { |
| LOGE(GSW_OTA, "Bad file path "); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| else |
| { |
| if(access(file_path,F_OK) !=0) |
| { |
| LOGE(GSW_OTA, "update file no exist"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| } |
| |
| ret = funstat(file_path); |
| if (ret) |
| { |
| LOGE(GSW_OTA, "get segment_size fail"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| ret = func_ptr_update(file_path, segment_size); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "Error: mbtk_fota_fw_write failed\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| } |
| return GSW_HAL_SUCCESS; |
| |
| } |
| |
| /** |
| * @brief check the modem update condition |
| * @param [in] NULL |
| * @param [out] NULL |
| * @retval TRUE/FALSE |
| */ |
| bool gsw_update_modem_check_condition(void) |
| { |
| char command[32] = {0}; |
| char buffer[64] = {0}; |
| const char *process_ota = "{otad}"; |
| |
| snprintf(command,sizeof(command), "ps | grep %s | grep -v grep", process_ota); |
| FILE *fp = popen(command, "r"); |
| if (fp == NULL) |
| { |
| return false; |
| } |
| |
| if(fgets(buffer, sizeof(buffer), fp)!= NULL) |
| { |
| pclose(fp); |
| return true; |
| } |
| pclose(fp); |
| return false; |
| |
| } |
| |
| /** |
| * @brief get update modem result |
| * @param [in] NULL |
| * @param [out] NULL |
| * @retval E_GSW_OTA_RET |
| */ |
| int32_t gsw_update_modem_result_query(void) |
| { |
| |
| mbtk_fota_status func_ptr_get_result = NULL; |
| int ret = -1; |
| |
| ret = init_handle(); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "init_handle fail"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| // Get the function pointer |
| func_ptr_get_result = (mbtk_fota_status)dlsym(handle, "mbtk_fota_status"); |
| if (func_ptr_get_result == NULL) |
| { |
| LOGE(GSW_OTA, "Error: %s\n", dlerror()); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| ret = func_ptr_get_result(); |
| if(ret < 0 && ret !=-1) |
| { |
| LOGE(GSW_OTA, "Error: mbtk_fota_status failed\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| |
| if(ret == LYNQ_OTA_INPROCESS) |
| { |
| return GSW_OTA_INPROCESS; |
| |
| } |
| else if(ret == LYNQ_OTA_SUCCESS) |
| { |
| return GSW_OTA_SUCCESS; |
| } |
| else if(ret == -1) |
| { |
| return GSW_OTA_NO_TASK; |
| } |
| |
| return GSW_OTA_FAILURE; |
| |
| |
| } |
| |
| /** |
| * @brief Start install modem software |
| * @param [in] char* file_path |
| * @param [out] NULL |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_start_nobackup(char* file_path) |
| { |
| |
| return GSW_HAL_SUCCESS; |
| } |
| |
| |
| /** |
| * @brief get current system |
| * @param [in] NULL |
| * @param [out] NULL |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_get_system(void) |
| { |
| int ret = -1; |
| |
| mbtk_fota_get_active_absys_type func_ptr; |
| ret = init_handle(); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "init_handle fail"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| // Get the function pointer |
| func_ptr = (mbtk_fota_get_active_absys_type)dlsym(handle, "mbtk_fota_get_active_absys_type"); |
| if (func_ptr == NULL) |
| { |
| LOGE(GSW_OTA, "Error: %s", dlerror()); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| ret = func_ptr(); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "Error: mbtk_fota_get_active_absys_type failed"); |
| return GSW_HAL_NORMAL_FAIL; |
| |
| } |
| |
| |
| return ret; |
| |
| } |
| |
| /** |
| * @brief cancel update |
| * @param [in] NULL |
| * @param [out] NULL |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_cancel(void) |
| { |
| |
| return GSW_HAL_SUCCESS; |
| } |
| |
| /** |
| * @brief get modem update info |
| * @param [in] NULL |
| * @param [out] gsw_update_info_s |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_get_info(gsw_update_info_s *update_info) |
| { |
| int ret = -1; |
| |
| mbtk_fota_status func_ptr_get_info = NULL; |
| |
| ret = init_handle(); |
| if(ret < 0) |
| { |
| LOGE(GSW_OTA, "init_handle fail"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| // Get the function pointer |
| func_ptr_get_info = (mbtk_fota_status)dlsym(handle, "mbtk_fota_status"); |
| if (func_ptr_get_info == NULL) |
| { |
| LOGE(GSW_OTA, "Error: %s\n", dlerror()); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| ret = func_ptr_get_info(); |
| if(ret < 0 && ret != -1) |
| { |
| LOGE(GSW_OTA, "Error: mbtk_fota_status failed\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| //升级成功之后,未重启,不可重复升级 |
| if(ret == LYNQ_OTA_INPROCESS) |
| { |
| update_info->exit_code = GSW_UPDATE_NOGOING; |
| update_info->percentage = Process_flag; |
| update_info->update_state = GSW_UPDATE_INPROGRESS; |
| } |
| if(ret == LYNQ_OTA_SUCCESS) |
| { |
| update_info->exit_code = GSW_UPDATE_NOERROR; |
| update_info->percentage = Process_flag; |
| update_info->update_state = GSW_UPDATE_WAITEDONE; |
| } |
| |
| |
| if(ret == LYNQ_OTA_FAILED || ret == -1) |
| { |
| update_info->exit_code = GSW_UPDATE_GETOLDSOFTWAREFAILED; |
| update_info->percentage = Process_flag; |
| update_info->update_state = GSW_UPDATE_FAILED; |
| } |
| |
| return GSW_HAL_SUCCESS; |
| |
| } |
| |
| |
| /** |
| * @brief get modem system status |
| * @param [in] NULL |
| * @param [out] gsw_system_status_s |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_get_status(gsw_system_status_s *system_status) |
| { |
| return GSW_HAL_SUCCESS; |
| } |
| |
| /** |
| * @brief A/B system sync |
| * @param [in] NULL |
| * @param [out] NULL |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_sync(void) |
| { |
| return GSW_HAL_SUCCESS; |
| |
| } |
| |
| /** |
| * @brief A/B system switch |
| * @param [in] NULL |
| * @param [out] NULL |
| * @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL |
| */ |
| int32_t gsw_update_modem_switch(void) |
| { |
| return GSW_HAL_SUCCESS; |
| } |
| |
| int32_t gsw_update_modem_process(void *bufdata) |
| { |
| return gsw_update_modem_start_autobackup(UPDATE_MODEM_PACKAGE); |
| } |
| |
| int32_t gsw_get_ab_system(gsw_system_type *type) |
| { |
| int32_t ret = GSW_HAL_NORMAL_FAIL; |
| |
| ret = gsw_update_modem_get_system(); |
| if (GSW_HAL_NORMAL_FAIL != ret) |
| { |
| *type = (gsw_system_type)ret; |
| } |
| |
| return ret; |
| } |
| |
| |