| #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; | 
 | } | 
 |  | 
 |  |