| #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"
|
|
|
|
|
|
|
| #define LYNQ_OTA_INPROCESS 3
|
| #define LYNQ_OTA_SUCCESS 4
|
| #define LYNQ_OTA_FAILED 5
|
|
|
| #ifndef LOG_ERR_LEVEL |
| #define LOG_ERR_LEVEL 3 /* error conditions */ |
| #endif |
| #ifndef LOG_WARN_LEVEL |
| #define LOG_WARN_LEVEL 4 /* warning conditions */ |
| #endif |
| #ifndef LOG_INFO_LEVEL |
| #define LOG_INFO_LEVEL 6 /* informational */ |
| #endif |
| #ifndef LOG_DEBUG_LEVEL |
| #define LOG_DEBUG_LEVEL 7 /* debug-level messages */ |
| #endif |
| #ifndef LOG_VERBOSE_LEVEL |
| #define LOG_VERBOSE_LEVEL 8 |
| #endif
|
|
|
|
|
| #define LIB_PATH "/lib/libmbtk_lib.so"
|
|
|
| #define GSW_OTA "[HAL][GSW_OTA]"
|
|
|
| #define StatFunc(x,y) stat(x,y)
|
|
|
| #define LOGV(fmt, args ...) \ |
| do{ \ |
| char *file_ptr_1001 = __FILE__; \ |
| char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \ |
| char line_1001[10] = {0}; \ |
| sprintf(line_1001, "%d", __LINE__); \ |
| while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \ |
| if(*ptr_1001 == '/') \ |
| break; \ |
| ptr_1001--; \ |
| } \ |
| fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_OTA"" fmt, ptr_1001 + 1, line_1001, ##args); \
|
| } while(0) |
| |
| #define LOGI(fmt, args...) \ |
| do{ \ |
| char *file_ptr_1001 = __FILE__; \ |
| char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \ |
| char line_1001[10] = {0}; \ |
| sprintf(line_1001, "%d", __LINE__); \ |
| while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \ |
| if(*ptr_1001 == '/') \ |
| break; \ |
| ptr_1001--; \ |
| } \ |
| fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_OTA"" fmt, ptr_1001 + 1, line_1001, ##args); \
|
| } while(0) |
| |
| #define LOGD(fmt, args...) \ |
| do{ \ |
| char *file_ptr_1001 = __FILE__; \ |
| char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \ |
| char line_1001[10] = {0}; \ |
| sprintf(line_1001, "%d", __LINE__); \ |
| while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \ |
| if(*ptr_1001 == '/') \ |
| break; \ |
| ptr_1001--; \ |
| } \ |
| fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_OTA"" fmt, ptr_1001 + 1, line_1001, ##args); \
|
| } while(0) |
| |
| #define LOGW(fmt, args...) \ |
| do{ \ |
| char *file_ptr_1001 = __FILE__; \ |
| char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \ |
| char line_1001[10] = {0}; \ |
| sprintf(line_1001, "%d", __LINE__); \ |
| while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \ |
| if(*ptr_1001 == '/') \ |
| break; \ |
| ptr_1001--; \ |
| } \ |
| fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_OTA"" fmt, ptr_1001 + 1, line_1001, ##args); \
|
| } while(0) |
| |
| #define LOGE(fmt, args...) \ |
| do{ \ |
| char *file_ptr_1001 = __FILE__; \
|
| char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \ |
| char line_1001[10] = {0}; \ |
| sprintf(line_1001, "%d", __LINE__); \ |
| while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \ |
| if(*ptr_1001 == '/') \ |
| break; \ |
| ptr_1001--; \ |
| } \ |
| fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_OTA"" fmt, ptr_1001 + 1, line_1001, ##args); \
|
| } while(0)
|
|
|
|
|
| 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);
|
|
|
| typedef void (*mbtk_log)(int level, const char *format,...);
|
|
|
| static int segment_size =0;
|
| static int Process_flag = 0;
|
| char addr_buf[256] = {0};
|
| static void *handle = NULL;
|
| static mbtk_log fun_ptr_log = 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("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;
|
| }
|
| if(fun_ptr_log == NULL)
|
| {
|
| fun_ptr_log = (mbtk_log)dlsym(handle, "mbtk_log");
|
| if(fun_ptr_log == 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("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("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("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("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("Error: %s", dlerror());
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
|
|
|
|
| if(s_ota_flag == -1)
|
| {
|
| ret = func_ptr_init(fota_cb);
|
| if(ret < 0)
|
| {
|
| LOGE("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("Bad file path ");
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
| else
|
| {
|
| if(access(file_path,F_OK) !=0)
|
| {
|
| LOGE("update file no exist");
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
| }
|
|
|
| ret = funstat(file_path);
|
| if (ret) |
| { |
| LOGE("get segment_size fail");
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
| ret = func_ptr_update(file_path, segment_size);
|
| if(ret < 0)
|
| {
|
| LOGE("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("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("Error: %s\n", dlerror());
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
| ret = func_ptr_get_result();
|
| if(ret < 0 && ret !=-1)
|
| {
|
| LOGE("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("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("Error: %s", dlerror());
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
| ret = func_ptr();
|
| if(ret < 0)
|
| {
|
| LOGE("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("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("Error: %s\n", dlerror());
|
| return GSW_HAL_NORMAL_FAIL;
|
| }
|
| ret = func_ptr_get_info();
|
| if(ret < 0 && ret != -1)
|
| {
|
| LOGE("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;
|
| }
|