#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include "include/libat/lynq_at_fota.h" | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
#include <log/log.h> | |
#include "mtk_device_wrap.h" | |
#include "include/iot_rock.h" | |
#define UPDATA_ADDR "/tmp/fota.delta" | |
#define READ_BLOCK_SIZE 0x40000 | |
#define FLASH_DEV_DELTA "/dev/mtd41" | |
#define LOG_TAG "AT-FOTA" | |
lynq_atsvc_outcb g_handle_output; | |
char str[128]; | |
char g_buffer[128] = {0}; | |
int Response = 0; | |
int g_lynq_fota_md5_flag = -1; | |
char g_put_addr[64]; | |
char g_put_path[35]; | |
char g_cmd[128]; | |
void *deal_download() | |
{ | |
int ret; | |
RLOGD("start deal_download !!!\n"); | |
ret = system(g_cmd); | |
RLOGD("ret:%d \n", ret); | |
if(ret != 0) | |
{ | |
strcpy(str, "+FOTA: fota download fail\n"); | |
g_handle_output(str, strlen(str), Response); | |
return NULL; | |
} | |
else | |
{ | |
strcpy(str, "+FOTA: fota download success\n"); | |
g_handle_output(str, strlen(str), Response); | |
} | |
return NULL; | |
} | |
int lynq_download_package(char (*string)[35]) | |
{ | |
int ret = 0; | |
int str_num = -1; | |
pthread_t tid; | |
RLOGD("function %s start\n", __FUNCTION__); | |
for(int i = 0; i < 9; i++) | |
{ | |
if(string[i] == NULL) | |
{ | |
strcpy(str, "+FOTA: download data null\n"); | |
g_handle_output(str, strlen(str), Response); | |
return 1; | |
} | |
} | |
if(strlen(string[9]) == 0) | |
{ | |
ret = chdir("/tmp/"); | |
if( 0 != ret) | |
{ | |
RLOGD("/tmp/ is error\n"); | |
strcpy(str, "+FOTA: the tmp is error\n"); | |
g_handle_output(str, strlen(str), Response); | |
return ret; | |
} | |
strcpy(g_put_path, "/tmp/"); | |
} | |
else | |
{ | |
ret = chdir(string[9]); | |
if( 0 != ret) | |
{ | |
RLOGD("%s is error directory \n", string[9]); | |
strcpy(str, "+FOTA: NO such directory\n"); | |
g_handle_output(str, strlen(str), Response); | |
return ret; | |
} | |
strcpy(g_put_path, string[9]); | |
} | |
sprintf(g_cmd,"wget ftp://%s:%s@%s:%s%s%s",string[2],string[3],string[0],string[1],string[7],string[8]); | |
RLOGD("g_cmd:%s\n", g_cmd); | |
str_num = strlen(g_put_path); | |
if(g_put_path[str_num - 1] == '/') | |
{ | |
sprintf(g_put_addr,"%s%s", g_put_path, string[8]); | |
} | |
else | |
{ | |
sprintf(g_put_addr,"%s/%s", g_put_path, string[8]); | |
} | |
RLOGD("g_put_addr: %s\n", g_put_addr); | |
if(lynq_fota_set_addr_value(g_put_addr,strlen(g_put_addr))) | |
{ | |
strcpy(str, "+FOTA: set fota addr fail\n"); | |
g_handle_output(str, strlen(str), Response); | |
} | |
pthread_create(&tid,NULL,deal_download,NULL); | |
pthread_detach(tid); | |
return ret; | |
} | |
/* | |
* @brief Differential subcontracting MD5 check | |
* | |
* @param string:MD5 value,Subcontracting address,Refer to the fota documentation | |
*/ | |
int lynq_md5_package(char (*string)[35]) | |
{ | |
char input_md5_data[64] = {0}; | |
RLOGD("function %s start\n", __FUNCTION__); | |
for(int i = 0; i < 2; i++) | |
{ | |
if(string[i] == NULL) | |
{ | |
strcpy(str, "+FOTA: md5 value null\n"); | |
g_handle_output(str, strlen(str), Response); | |
return 1; | |
} | |
} | |
sprintf(input_md5_data,"%s",string[0]); | |
RLOGD("input_md5_data: %s\n", string[0]); | |
g_lynq_fota_md5_flag = lynq_md5_file_verfy(g_put_addr, input_md5_data); | |
if(g_lynq_fota_md5_flag != 0) | |
{ | |
strcpy(str, "+FOTA: md5 fail\n"); | |
g_handle_output(str, strlen(str), Response); | |
return 1; | |
} | |
return 0; | |
} | |
/** | |
* @brief fota | |
* | |
* @param void | |
*/ | |
int lynq_fota_try(void) | |
{ | |
RLOGD("function %s start\n", __FUNCTION__); | |
if(g_lynq_fota_md5_flag == 0) //upgrade success ,device reboot ,lynq_fota_md5_flag no need to reset | |
{ | |
if(0 != lynq_rock_main(1)) | |
{ | |
g_lynq_fota_md5_flag = -1; | |
strcpy(str, "+FOTA: update fail\n"); | |
g_handle_output(str, strlen(str), Response); | |
return 1; | |
} | |
} | |
else | |
{ | |
strcpy(str, "+FOTA: md5 verify fail\n"); | |
g_handle_output(str, strlen(str), Response); | |
return 1; | |
} | |
return 0; | |
} | |
void lynq_at_fota(char (*argv)[35]) | |
{ | |
int result; | |
RLOGD("function %s start\n", __FUNCTION__); | |
RLOGD("buffer: %s",g_buffer); | |
if(!(strcmp(argv[0], "AT+FOTA?"))) | |
{ | |
if(strlen(g_buffer) == 0) | |
{ | |
strcpy(str, "+FOTA: OK\n"); | |
} | |
else | |
{ | |
sprintf(str, "+FOTA: %s\n",g_buffer); | |
} | |
g_handle_output(str, strlen(str), Response); | |
return ; | |
} | |
else if(!(strcmp(argv[0], "AT+FOTA=?"))) | |
{ | |
strcpy(str, "+FOTA:(0-2),""\n"); | |
g_handle_output(str, strlen(str), Response); | |
return ; | |
} | |
if(!(strcmp(argv[0], "AT+FOTA=0")) || !(strcmp(argv[0], "AT+LYNQFOTA=download"))) | |
{ | |
RLOGD("argv[0]: %s\n", argv[0]); | |
if(!(strcmp(argv[1], "ftp"))) | |
{ | |
result = lynq_download_package(&argv[2]); | |
if(result != 0) | |
{ | |
strcpy(str, "+FOTA: DOWNLOAD FAIL\n"); | |
} | |
else | |
{ | |
strcpy(str, "+FOTA: DOWNLOAD START\n"); | |
} | |
} | |
else | |
{ | |
strcpy(str, "+FOTA: NO FTP DOWNLOAD\n"); | |
} | |
} | |
else if(!(strcmp(argv[0], "AT+FOTA=1")) || !(strcmp(argv[0], "AT+LYNQFOTA=md5"))) | |
{ | |
RLOGD("argv[0]: %s\n", argv[0]); | |
result = lynq_md5_package(&argv[1]); | |
if(result != 0) | |
{ | |
strcpy(str, "+FOTA: MD5 FAIL\n"); | |
} | |
else | |
{ | |
strcpy(str, "+FOTA: MD5 SUCCESS\n"); | |
} | |
} | |
else if(!(strcmp(argv[0], "AT+FOTA=2")) || !(strcmp(argv[0], "AT+LYNQFOTA=upgrade"))) | |
{ | |
RLOGD("argv[0]: %s\n", argv[0]); | |
result = lynq_fota_try(); | |
if(result == 0) | |
{ | |
strcpy(str, "+FOTA: UPDATE SUCCESS\n"); | |
} | |
else | |
{ | |
strcpy(str, "+FOTA: UPDATE FAIL\n"); | |
} | |
} | |
else | |
{ | |
strcpy(str, "+CME: ERROR: 100\n"); | |
} | |
g_handle_output(str, strlen(str), Response); | |
} | |
void lynq_at_fota_cb(char *input, int input_max_size) | |
{ | |
char arry[20][35]={}; | |
char *p = NULL; | |
int i = 0; | |
if(input[8] == '0') | |
{ | |
strcpy(g_buffer, input); | |
} | |
if(g_handle_output != NULL) | |
{ | |
RLOGD("function %s start,input: %s \n", __FUNCTION__, input); | |
if(input != NULL) | |
{ | |
while(( p = strsep(&input,",")) != NULL) | |
{ | |
strcpy(arry[i],p); | |
i++; | |
} | |
lynq_at_fota(arry); | |
} | |
} | |
} | |
lynq_atsvc_incb lynq_register_fota(lynq_atsvc_outcb out_cb) | |
{ | |
if(out_cb != NULL) | |
{ | |
g_handle_output = out_cb; | |
RLOGD("function %s start\n", __FUNCTION__); | |
return lynq_at_fota_cb; | |
} | |
} | |
#ifdef __cplusplus | |
} | |
#endif | |