blob: 148214cc3e0d5d8d102151967d98397749517113 [file] [log] [blame]
#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