[Feature] Add the AT directive for FOTA

Change-Id: Idf53126794b11e3af5de59f7d3cfc88f6a60431b
diff --git a/meta/meta-mediatek-mt2731/recipes-lynq/lynq-atsvc/lynq-atsvc.bb b/meta/meta-mediatek-mt2731/recipes-lynq/lynq-atsvc/lynq-atsvc.bb
old mode 100644
new mode 100755
index 3c18329..43832dc
--- a/meta/meta-mediatek-mt2731/recipes-lynq/lynq-atsvc/lynq-atsvc.bb
+++ b/meta/meta-mediatek-mt2731/recipes-lynq/lynq-atsvc/lynq-atsvc.bb
@@ -3,7 +3,7 @@
 DESCRIPTION = "lynq ril service"

 LICENSE = "MediaTekProprietary"

 LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"

-DEPENDS += "platform-libs audio-mixer-ctrl libvendor-ril libpal gstreamer1.0 glib-2.0 dtmf libapn dbus liblynq-protcl liblynq-logdata-handle liblynq-log"

+DEPENDS += "platform-libs audio-mixer-ctrl libvendor-ril libpal gstreamer1.0 glib-2.0 dtmf libapn dbus liblynq-protcl liblynq-logdata-handle liblynq-log liblynq-fota nandapi bootctrl"

 inherit workonsrc

 WORKONSRC = "${TOPDIR}/../src/lynq/framework/lynq-atsvc/src"

 

diff --git a/src/lynq/framework/lynq-atsvc/src/factory/lynq_factory.cpp b/src/lynq/framework/lynq-atsvc/src/factory/lynq_factory.cpp
index 5b41bee..a8ef998 100755
--- a/src/lynq/framework/lynq-atsvc/src/factory/lynq_factory.cpp
+++ b/src/lynq/framework/lynq-atsvc/src/factory/lynq_factory.cpp
@@ -414,11 +414,13 @@
         fp=popen(lynq_set_gpio_arr, "r");
         bzero(lynq_get_gpio_state, 512);
         fgets(lynq_get_gpio_state,sizeof(lynq_get_gpio_state),fp);
-        /*       if(strlen(lynq_get_gpio_state) > 0)
+/*     
+        if(strlen(lynq_get_gpio_state) > 0)
         {
-          lynq_factory_response_ttyGS3(lynq_get_gpio_state);
-          lynq_factory_response_ttyGS3("\n");
-        }*/
+            lynq_factory_response_ttyGS3(lynq_get_gpio_state);
+            lynq_factory_response_ttyGS3("\n");
+        }
+*/
         pclose(fp);
         if(lynq_get_gpio_state[8] == '1')
         {
@@ -434,11 +436,13 @@
         fp=popen(lynq_set_gpio_arr, "r");
         bzero(lynq_get_gpio_state, 512);
         fgets(lynq_get_gpio_state,sizeof(lynq_get_gpio_state),fp);
- /*      if(strlen(lynq_get_gpio_state) > 0)
+/*      
+        if(strlen(lynq_get_gpio_state) > 0)
         {
-              lynq_factory_response_ttyGS3(lynq_get_gpio_state);
-              lynq_factory_response_ttyGS3("\n");
-        }*/
+            lynq_factory_response_ttyGS3(lynq_get_gpio_state);
+            lynq_factory_response_ttyGS3("\n");
+        }
+*/
         pclose(fp);
         if(lynq_get_gpio_state[8] == '0')
         {
diff --git a/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.cpp b/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.cpp
old mode 100644
new mode 100755
index 591a532..d509ca1
--- a/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.cpp
+++ b/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.cpp
@@ -15,16 +15,24 @@
 #ifdef __cplusplus
 extern "C" {
 #endif

-

 #include <log/log.h>

 #include "lynq_send_log_data.h"

-

 #include "lynq_logdata_handle.h"

 #include "lynq_deal_logrotate.h"

 #include "ftp/lynq_ftp.h"

+#include "mtk_device_wrap.h"

+#include "include/iot_rock.h"

 

 //extern int ttyGS3_fd;

-lynq_ftp_socker_info ftp_logrotate_info;

+static lynq_ftp_socker_info ftp_logrotate_info;

+static lynq_ftp_socker_info ftp_atfota_info;

+

+#define UPDATA_ADDR "/tmp/fota.delta"

+#define READ_BLOCK_SIZE 0x40000

+

+int lynq_fota_md5_flag = -1;

+

+#define FLASH_DEV_DELTA       "/dev/disk/by-partlabel/delta"	

 

 void lynq_response_ttyGS3(char *log_buf)

 {

@@ -35,19 +43,18 @@
 

 static int lynq_ftp_login_logmodule(char **lynq_logsend_buf) //lt add @2021.12.23 for ftp login 

 {

-   

-   sprintf(ftp_logrotate_info.sevname,lynq_logsend_buf[1]);

-   ftp_logrotate_info.portnum = atoi(lynq_logsend_buf[2]);

-   sprintf(ftp_logrotate_info.username,lynq_logsend_buf[3]);

-   sprintf(ftp_logrotate_info.pw,lynq_logsend_buf[4]);

+    sprintf(ftp_logrotate_info.sevname,lynq_logsend_buf[1]);

+    ftp_logrotate_info.portnum = atoi(lynq_logsend_buf[2]);

+    sprintf(ftp_logrotate_info.username,lynq_logsend_buf[3]);

+    sprintf(ftp_logrotate_info.pw,lynq_logsend_buf[4]);

 

-   sprintf(ftp_logrotate_info.is_pasv_mode,lynq_logsend_buf[5]);

-   sprintf(ftp_logrotate_info.file_type,lynq_logsend_buf[6]);

-   sprintf(ftp_logrotate_info.put_opt,lynq_logsend_buf[7]);

+    sprintf(ftp_logrotate_info.is_pasv_mode,lynq_logsend_buf[5]);

+    sprintf(ftp_logrotate_info.file_type,lynq_logsend_buf[6]);

+    sprintf(ftp_logrotate_info.put_opt,lynq_logsend_buf[7]);

 

-   sprintf(ftp_logrotate_info.putfilename_path,lynq_logsend_buf[8]);

+    sprintf(ftp_logrotate_info.putfilename_path,lynq_logsend_buf[8]);

 

-   return lynq_ftp_login(&ftp_logrotate_info);

+    return lynq_ftp_login(&ftp_logrotate_info);

 //   lynq_ftp_download(&ftp_logrotate_info);

    

 }

@@ -55,148 +62,272 @@
 

 static int lynq_ftp_upload_logdata(int log_moudle) //lt add @2021.12.23 for deal with upload log data

 {

-	int ret = -1;

-	char lynq_log_file_path[64] = {0};

-	char log_file_name[64] = {0};

-	char log_buf[1024];

-	

-	chdir("/var/log/");/*Ìø×ªµ½/var/log/¹¤×÷Ŀ¼ÏÂ*/

-	switch(log_moudle)

-	{

-		case MD_LOG:

-			memset(lynq_log_file_path,0,sizeof(lynq_log_file_path));

-			memset(log_file_name,0,sizeof(log_file_name));

-			ret = lynq_get_current_mtklog_path(lynq_log_file_path);

-			if(ret >= 0)

-			{

-/*				bzero(log_buf, 1024);

-				sprintf(log_buf,"log_file_path:%s\n",lynq_log_file_path);

-				lynq_response_ttyGS3(log_buf);*/

-				sscanf(lynq_log_file_path,"/var/log/%s",log_file_name);

-				sprintf(ftp_logrotate_info.putfilename,log_file_name);

-	/*			bzero(log_buf, 1024);

-				sprintf(log_buf,"log_file_name:%s\n",log_file_name);

-				lynq_response_ttyGS3(log_buf);*/

-				return lynq_ftp_up(&ftp_logrotate_info);

-			}

-			else

-			{

-				bzero(log_buf, 1024);

-				sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

-				lynq_response_ttyGS3(log_buf);

-			}

-		 	break;

-		case AP_LOG:

-			memset(lynq_log_file_path,0,sizeof(lynq_log_file_path));

-			memset(log_file_name,0,sizeof(log_file_name));

-			ret = lynq_get_current_syslog_path(lynq_log_file_path);

-			if(ret >= 0)

-			{

-/*				bzero(log_buf, 1024);

-				sprintf(log_buf,"log_file_path:%s\n",lynq_log_file_path);

-				lynq_response_ttyGS3(log_buf);*/

-				sscanf(lynq_log_file_path,"/var/log/%s",log_file_name);

-				sprintf(ftp_logrotate_info.putfilename,log_file_name);

-/*				bzero(log_buf, 1024);

-				sprintf(log_buf,"log_file_name:%s\n",log_file_name);

-				lynq_response_ttyGS3(log_buf);*/

-				return lynq_ftp_up(&ftp_logrotate_info);

-			}	

-			else

-			{

-				bzero(log_buf, 1024);

-				sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

-				lynq_response_ttyGS3(log_buf);

-			}

-			break;

-		case MCU_LOG:

-			memset(lynq_log_file_path,0,sizeof(lynq_log_file_path));

-			memset(log_file_name,0,sizeof(log_file_name));

-			ret = lynq_get_current_mculog_path(lynq_log_file_path);

-			if(ret >= 0)

-			{

-/*				bzero(log_buf, 1024);

-				sprintf(log_buf,"log_file_path:%s\n",lynq_log_file_path);

-				lynq_response_ttyGS3(log_buf);*/

-				sscanf(lynq_log_file_path,"/var/log/%s",log_file_name);

-				sprintf(ftp_logrotate_info.putfilename,log_file_name);

-/*				bzero(log_buf, 1024);

-				sprintf(log_buf,"log_file_name:%s\n",log_file_name);

-				lynq_response_ttyGS3(log_buf);*/

-				return lynq_ftp_up(&ftp_logrotate_info);

-			}

-			else

-			{

-				bzero(log_buf, 1024);

-				sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

-				lynq_response_ttyGS3(log_buf);

-			}

-			break;

-			default:

-			bzero(log_buf, 1024);

-			sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

-			lynq_response_ttyGS3(log_buf);

-			return -1;

-	}

-	return -1;

+    int ret = -1;

+    char lynq_log_file_path[64] = {0};

+    char log_file_name[64] = {0};

+    char log_buf[1024];

+

+    chdir("/var/log/");/*Ìø×ªµ½/var/log/¹¤×÷Ŀ¼ÏÂ*/

+    switch(log_moudle)

+    {

+        case MD_LOG:

+        memset(lynq_log_file_path,0,sizeof(lynq_log_file_path));

+        memset(log_file_name,0,sizeof(log_file_name));

+        ret = lynq_get_current_mtklog_path(lynq_log_file_path);

+        if(ret >= 0)

+        {

+            /*bzero(log_buf, 1024);

+            sprintf(log_buf,"log_file_path:%s\n",lynq_log_file_path);

+            lynq_response_ttyGS3(log_buf);*/

+            sscanf(lynq_log_file_path,"/var/log/%s",log_file_name);

+            sprintf(ftp_logrotate_info.putfilename,log_file_name);

+            /*bzero(log_buf, 1024);

+            sprintf(log_buf,"log_file_name:%s\n",log_file_name);

+            lynq_response_ttyGS3(log_buf);*/

+            return lynq_ftp_up(&ftp_logrotate_info);

+        }

+        else

+        {

+            bzero(log_buf, 1024);

+            sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

+            lynq_response_ttyGS3(log_buf);

+        }

+        break;

+        case AP_LOG:

+        memset(lynq_log_file_path,0,sizeof(lynq_log_file_path));

+        memset(log_file_name,0,sizeof(log_file_name));

+        ret = lynq_get_current_syslog_path(lynq_log_file_path);

+        if(ret >= 0)

+        {

+            /*bzero(log_buf, 1024);

+            sprintf(log_buf,"log_file_path:%s\n",lynq_log_file_path);

+            lynq_response_ttyGS3(log_buf);*/

+            sscanf(lynq_log_file_path,"/var/log/%s",log_file_name);

+            sprintf(ftp_logrotate_info.putfilename,log_file_name);

+            /*bzero(log_buf, 1024);

+            sprintf(log_buf,"log_file_name:%s\n",log_file_name);

+            lynq_response_ttyGS3(log_buf);*/

+            return lynq_ftp_up(&ftp_logrotate_info);

+        }	

+        else

+        {

+            bzero(log_buf, 1024);

+            sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

+            lynq_response_ttyGS3(log_buf);

+        }

+        break;

+    case MCU_LOG:

+        memset(lynq_log_file_path,0,sizeof(lynq_log_file_path));

+        memset(log_file_name,0,sizeof(log_file_name));

+        ret = lynq_get_current_mculog_path(lynq_log_file_path);

+        if(ret >= 0)

+        {

+            /*bzero(log_buf, 1024);

+            sprintf(log_buf,"log_file_path:%s\n",lynq_log_file_path);

+            lynq_response_ttyGS3(log_buf);*/

+            sscanf(lynq_log_file_path,"/var/log/%s",log_file_name);

+            sprintf(ftp_logrotate_info.putfilename,log_file_name);

+            /*bzero(log_buf, 1024);

+            sprintf(log_buf,"log_file_name:%s\n",log_file_name);

+            lynq_response_ttyGS3(log_buf);*/

+            return lynq_ftp_up(&ftp_logrotate_info);

+        }

+        else

+        {

+            bzero(log_buf, 1024);

+            sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

+            lynq_response_ttyGS3(log_buf);

+        }

+     break;

+    default:

+        bzero(log_buf, 1024);

+        sprintf(log_buf,"+CME: ERROR %d\n",LYNQ_E_GET_LOG_FAIL);

+        lynq_response_ttyGS3(log_buf);

+        return -1;

+    }

+    return -1;

 }

 

 int lynq_deal_with_log_at(char **lynq_argv)//lt add @2021.12.23 for deal with AT

 {

 

 /*	

-	for(int i = 0;i < 10; i++)

-	{

-		lynq_response_ttyGS3(lynq_argv[i]);

-		lynq_response_ttyGS3("\n");

-

-	}

+    for(int i = 0;i < 10; i++)

+    {

+        lynq_response_ttyGS3(lynq_argv[i]);

+        lynq_response_ttyGS3("\n");

+    }

 */

-	char lynq_log_buf[1024];

-	if(0 == strcmp(lynq_argv[0], "ftp"))

-	{

-		if(1 == lynq_ftp_login_logmodule(lynq_argv))

-		{

-				

-			int lynq_logsend_test_moudle = atoi(lynq_argv[9]);

-			if(lynq_ftp_upload_logdata(lynq_logsend_test_moudle) == 0)

-			{

-				bzero(lynq_log_buf, 1024);

-				sprintf(lynq_log_buf,"+LOGS\nOK\n");

-				lynq_response_ttyGS3(lynq_log_buf);

-			}

-			else

-			{

-				bzero(lynq_log_buf, 1024);

-				sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_FTP_SEND_FAIL);

-				lynq_response_ttyGS3(lynq_log_buf);

-			}

-		}

-		else

-		{

-				bzero(lynq_log_buf, 1024);

-				sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_FTP_LOGIN_FAIL);

-				lynq_response_ttyGS3(lynq_log_buf);

-		}

-	}

-	else if(!strcmp(lynq_argv[0], "usb"))

-	{

-//		lynq_response_ttyGS3("!strcmp(lynq_argv[0], usb)\n");

-		bzero(lynq_log_buf, 1024);

-		sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_LOG_CMD_ERROR);

-		lynq_response_ttyGS3(lynq_log_buf);

-	}

-	else

-	{

-//		lynq_response_ttyGS3("parase fail\n");

-		bzero(lynq_log_buf, 1024);

-		sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_LOG_CMD_ERROR);

-		lynq_response_ttyGS3(lynq_log_buf);

-	}

-	return 1;

+    char lynq_log_buf[1024];

+    if(0 == strcmp(lynq_argv[0], "ftp"))

+    {

+        if(1 == lynq_ftp_login_logmodule(lynq_argv))

+        {

+

+            int lynq_logsend_test_moudle = atoi(lynq_argv[9]);

+            if(lynq_ftp_upload_logdata(lynq_logsend_test_moudle) == 0)

+            {

+            bzero(lynq_log_buf, 1024);

+            sprintf(lynq_log_buf,"+LOGS\nOK\n");

+            lynq_response_ttyGS3(lynq_log_buf);

+            }

+            else

+            {

+                bzero(lynq_log_buf, 1024);

+                sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_FTP_SEND_FAIL);

+                lynq_response_ttyGS3(lynq_log_buf);

+            }

+        }

+        else

+        {

+            bzero(lynq_log_buf, 1024);

+            sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_FTP_LOGIN_FAIL);

+            lynq_response_ttyGS3(lynq_log_buf);

+        }

+    }

+    else if(!strcmp(lynq_argv[0], "usb"))

+    {

+        //lynq_response_ttyGS3("!strcmp(lynq_argv[0], usb)\n");

+        bzero(lynq_log_buf, 1024);

+        sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_LOG_CMD_ERROR);

+        lynq_response_ttyGS3(lynq_log_buf);

+    }

+    else

+    {

+        //lynq_response_ttyGS3("parase fail\n");

+        bzero(lynq_log_buf, 1024);

+        sprintf(lynq_log_buf,"+CME: ERROR %d\n",LYNQ_E_LOG_CMD_ERROR);

+        lynq_response_ttyGS3(lynq_log_buf);

+    }

+    return 1;

 }

 

 

+

+int lynq_ftp_download_atfota_package(char *string[])

+{

+    int ret = 0;

+    sprintf(ftp_atfota_info.sevname,"%s",string[0]);

+

+    ftp_atfota_info.portnum = atoi(string[1]);

+

+    sprintf(ftp_atfota_info.username,"%s",string[2]);

+    sprintf(ftp_atfota_info.pw,"%s",string[3]);

+

+

+    sprintf(ftp_atfota_info.is_pasv_mode,"%s",string[4]);

+    sprintf(ftp_atfota_info.file_type,"%s",string[5]);

+    sprintf(ftp_atfota_info.put_opt,"%s",string[6]);

+

+    sprintf(ftp_atfota_info.getfilename_path,"%s",string[7]);

+    sprintf(ftp_atfota_info.getfilename,"%s",string[8]);

+    chdir("/tmp/");

+    if(1 == lynq_ftp_login(&ftp_atfota_info))

+    {

+        if(0 == lynq_ftp_download(&ftp_atfota_info))

+        {

+            lynq_response_ttyGS3("+LYNQFOTA:\nGET FOTA FILE OK\n");

+            ret = 0;

+        }

+        else

+        {

+            lynq_response_ttyGS3("+CME: GET FOTA FILE FAIL\n");

+            ret = 1;

+        }

+    }

+    else

+    {

+        lynq_response_ttyGS3("+CME: FOTA LOGIN FAIL\n");

+        ret = 1;

+    }

+    return ret;

+}

+

+int lynq_md5_atfota_package(char *string[])

+{

+    int ret = 0;

+    int fd_down,size,fd_target;

+    char delta_data[READ_BLOCK_SIZE];

+    char input_md5_data[64] = {0};

+

+    sprintf(input_md5_data,"%s",string[0]);

+    lynq_fota_md5_flag = lynq_md5_file_verfy(UPDATA_ADDR, input_md5_data);

+    if(lynq_fota_md5_flag == 0)

+    {

+        lynq_response_ttyGS3("+LYNQFOTA:\nMD5 OK\n");

+    }

+    else

+    {

+        lynq_response_ttyGS3("MD5 FAIL\n");

+        return 1;

+    }

+

+    fd_down = open(UPDATA_ADDR,O_RDONLY);

+    if (fd_down < 0) {

+        lynq_response_ttyGS3("open source  error\n");

+        return 1;

+    }

+

+    fd_target = mtk_device_wrap_open(FLASH_DEV_DELTA,O_RDWR);

+

+    if (fd_target < 0) {

+        close(fd_down);

+        lynq_response_ttyGS3("open target  error\n");

+        return 1;

+    } 

+

+    while(( size = read(fd_down,delta_data,READ_BLOCK_SIZE))>0) {

+        mtk_device_wrap_write(fd_target,delta_data,READ_BLOCK_SIZE);

+        memset(delta_data,0,READ_BLOCK_SIZE);

+    }

+

+//    lynq_response_ttyGS3("Store upgrade data to delta success\n");

+

+    mtk_device_wrap_close(fd_target);

+    close(fd_down);

+

+    return 0;

+}

+

+int lynq_atfota_func_test(void)

+{

+    int first_run = 1; 

+    if(lynq_fota_md5_flag == 0)

+    {

+        lynq_rock_main(first_run);

+    }

+    else

+    {

+        lynq_response_ttyGS3("MD5 verify fail\n");

+        return 1;

+    }

+    return 0;

+}

+

+int lynq_atfota_test(char *argv[]) 

+{

+    if(!strcmp(argv[3], "download"))

+    {

+        if(!(strcmp(argv[4], "ftp")))

+        {

+            lynq_ftp_download_atfota_package(&argv[5]);

+        }

+    }

+    else if(!(strcmp(argv[3], "md5")))

+    {

+        lynq_md5_atfota_package(&argv[4]);

+    }

+    else if(!(strcmp(argv[3], "upgrade")))

+    {

+        lynq_atfota_func_test();

+    }

+    else

+    {

+        lynq_response_ttyGS3("fota api error!!!\n");

+    }

+    return 0;

+}

+

 #ifdef __cplusplus
 }
 #endif

diff --git a/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.h b/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.h
old mode 100644
new mode 100755
index bbea9b1..fa3bf6e
--- a/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.h
+++ b/src/lynq/framework/lynq-atsvc/src/log/lynq_send_log_data.h
@@ -12,6 +12,7 @@
 #define LYNQ_E_LOG_CMD_ERROR 9005 /*cmd error*/

 

 int lynq_deal_with_log_at(char **lynq_argv);

+int lynq_atfota_test(char *argv[]);

 

 #ifdef __cplusplus
 }
diff --git a/src/lynq/framework/lynq-atsvc/src/lynq_at_transfer_table.h b/src/lynq/framework/lynq-atsvc/src/lynq_at_transfer_table.h
index 0a09900..0ee18b9 100755
--- a/src/lynq/framework/lynq-atsvc/src/lynq_at_transfer_table.h
+++ b/src/lynq/framework/lynq-atsvc/src/lynq_at_transfer_table.h
@@ -14,4 +14,5 @@
 {LYNQ_REQUEST_RNDIS,"LRNDISHANDLE",7},

 {LYNQ_REQUEST_FACTORY,"LYNQFACTORY",7},

 {LYNQ_REQUEST_LINFO,"LINFO",7},

+{LYNQ_REQUEST_FOTA,"LYNQFOTA",7},

 {-1,NULL,0},
\ No newline at end of file
diff --git a/src/lynq/framework/lynq-atsvc/src/lynq_common.cpp b/src/lynq/framework/lynq-atsvc/src/lynq_common.cpp
index 9540d87..a6737de 100755
--- a/src/lynq/framework/lynq-atsvc/src/lynq_common.cpp
+++ b/src/lynq/framework/lynq-atsvc/src/lynq_common.cpp
@@ -105,6 +105,8 @@
             return LYNQ_GOTO_LINFO_REQ;
         case LYNQ_REQUEST_FACTORY:
             return LYNQ_GOTO_FACTORY;
+        case LYNQ_REQUEST_FOTA:
+            return LYNQ_GOTO_FOTA;
         default:
             return -1;
     }
diff --git a/src/lynq/framework/lynq-atsvc/src/lynq_common.h b/src/lynq/framework/lynq-atsvc/src/lynq_common.h
index 0672529..513431b 100755
--- a/src/lynq/framework/lynq-atsvc/src/lynq_common.h
+++ b/src/lynq/framework/lynq-atsvc/src/lynq_common.h
@@ -31,6 +31,8 @@
 #define LYNQ_GOTO_FACTORY 6
 /*info output*/
 #define LYNQ_GOTO_LINFO_REQ 7
+/*fota*/
+#define LYNQ_GOTO_FOTA 8
 
 #define LYNQ_APN_LEN_MAX 100
 #define LYNQ_APNTPYE_LEN_MAX 50
@@ -57,6 +59,7 @@
 #define LYNQ_REQUEST_FACTORY (LYNQ_VERSION +16)
 #define LYNQ_REQUEST_LINFO (LYNQ_VERSION +17)
 #define LYNQ_REQUEST_SCREEN_STATE (LYNQ_VERSION +18)
+#define LYNQ_REQUEST_FOTA (LYNQ_VERSION +19)
 #define LYNQ_USER_REQUEST_GNSS (LYNQ_VERSION +100)
 #define LYNQ_USER_REQUEST_OTHRE (LYNQ_VERSION +101)
 
diff --git a/src/lynq/framework/lynq-atsvc/src/makefile b/src/lynq/framework/lynq-atsvc/src/makefile
index f7bdb2e..4f685e7 100755
--- a/src/lynq/framework/lynq-atsvc/src/makefile
+++ b/src/lynq/framework/lynq-atsvc/src/makefile
@@ -67,6 +67,7 @@
   -I$(LOCAL_PATH)/log \
   -I$(LOCAL_PATH)/rndis \
   -I$(LOCAL_PATH)/factory \
+  -I$(LOCAL_PATH)/fota \
   -I$(ROOT)$(includedir)/ \
   -I$(ROOT)$(includedir)/liblog \
   -I$(ROOT)$(includedir)/include  \
@@ -107,6 +108,8 @@
     -llynq-protcl \
     -llynq-logdata-handle \
     -llynq-log \
+    -llynq-fota \
+    -lnandapi  \
 
 ifeq ($(strip $(TARGET_PLATFORM)), mt2735)
 LOCAL_LIBS += -luciwrapper
@@ -115,7 +118,7 @@
 endif
 
 
-SOURCES = $(wildcard util/*.cpp *.cpp ecall/*.cpp ecall/gost/*.cpp ecall/gost/utils/*.cpp ecall/gost/sslp/*.cpp ecall/gost/sslp/auth/*.cpp ecall/gost/sslp/firmware/*.cpp ecall/gost/sslp/commands/*.cpp ecall/gost/sslp/ecall/*.cpp ecall/gost/sslp/teledata/*.cpp data/*.cpp  em/rfdesense/*.cpp em/networkinfo/*.cpp em/*.cpp sms/*.cpp sms/gsm/*.cpp sms/cdma/*.cpp atci/*.cpp stateManager/*.cpp log/*.cpp rndis/*.cpp factory/*.cpp)
+SOURCES = $(wildcard util/*.cpp *.cpp ecall/*.cpp ecall/gost/*.cpp ecall/gost/utils/*.cpp ecall/gost/sslp/*.cpp ecall/gost/sslp/auth/*.cpp ecall/gost/sslp/firmware/*.cpp ecall/gost/sslp/commands/*.cpp ecall/gost/sslp/ecall/*.cpp ecall/gost/sslp/teledata/*.cpp data/*.cpp  em/rfdesense/*.cpp em/networkinfo/*.cpp em/*.cpp sms/*.cpp sms/gsm/*.cpp sms/cdma/*.cpp atci/*.cpp stateManager/*.cpp log/*.cpp rndis/*.cpp factory/*.cpp )
 
 EXECUTABLE = lynq-atsvc
 
diff --git a/src/lynq/framework/lynq-atsvc/src/ril.cpp b/src/lynq/framework/lynq-atsvc/src/ril.cpp
index 097872d..7c3c9e5 100755
--- a/src/lynq/framework/lynq-atsvc/src/ril.cpp
+++ b/src/lynq/framework/lynq-atsvc/src/ril.cpp
@@ -6528,6 +6528,12 @@
                 case LYNQ_GOTO_FACTORY:
                 {
                     lynq_get_factory_data(argc,argv);
+                    break;
+                }
+                case LYNQ_GOTO_FOTA:
+                {
+                    lynq_atfota_test(argv);
+                    break;
                 }
                 default:
                     break;