[Feature][R307][task-view-604][fota] R307,add manual fota upgrade functionality

Change-Id: Ic57ec2e1b8c745d77aab4b72df05aefe0222086a
diff --git a/lynq/R307/ap/app/goahead/interface5.0/Makefile b/lynq/R307/ap/app/goahead/interface5.0/Makefile
index 87a8b72..e6d24a8 100755
--- a/lynq/R307/ap/app/goahead/interface5.0/Makefile
+++ b/lynq/R307/ap/app/goahead/interface5.0/Makefile
@@ -145,6 +145,9 @@
 
 CFLAGS += -I$(zte_lib_path)/libssl/install/include
 LDLIBS += -L$(zte_lib_path)/libssl/install/lib -lcrypto
+
+CFLAGS += -I$(zte_lib_path)/libcurl/install/include
+LDLIBS += -L$(zte_lib_path)/libcurl/install/lib -lcurl
 #*******************************************************************************
 # targets
 #*******************************************************************************
diff --git a/lynq/R307/ap/app/goahead/interface5.0/zte_web_interface.h b/lynq/R307/ap/app/goahead/interface5.0/zte_web_interface.h
index a1a5c73..6bb9991 100755
--- a/lynq/R307/ap/app/goahead/interface5.0/zte_web_interface.h
+++ b/lynq/R307/ap/app/goahead/interface5.0/zte_web_interface.h
@@ -369,6 +369,7 @@
 /*FOTA module start*/
 #define GOFORM_SET_FOTAAUTOUPDATE "IF_UPGRADE"
 #define GOFORM_SET_FOTASETTINGS "SetUpgAutoSetting"
+#define GOFORM_SET_FOTAMANUALUPG "SetUpgManualSetting"
 /*FOTA module end*/
 
 /*ping test*/
@@ -1055,6 +1056,7 @@
 * @warning
 */
 extern void zte_fota_settings(webs_t wp);
+extern void zte_fota_manual_upgrade(webs_t wp);
 
 
 extern void zte_init_login_psw_time(void);
diff --git a/lynq/R307/ap/app/goahead/interface5.0/zte_web_mgmt.c b/lynq/R307/ap/app/goahead/interface5.0/zte_web_mgmt.c
index 1b5372c..a16a653 100755
--- a/lynq/R307/ap/app/goahead/interface5.0/zte_web_mgmt.c
+++ b/lynq/R307/ap/app/goahead/interface5.0/zte_web_mgmt.c
@@ -32,6 +32,7 @@
 #include <sys/msg.h>
 
 #include <openssl/aes.h>
+#include <curl/curl.h>
 
 #include "zte_web_interface.h"
 #include "zte_web_get_fw_para.h"
@@ -2753,6 +2754,179 @@
 	zte_write_result_to_web(wp, SUCCESS);
 }
 
+static int fota_is_file_exist(const char* path)
+{
+	if ( (path == NULL) || (*path == '\0') )
+		return FALSE;
+	if (access(path, R_OK) != 0)
+		return FALSE;
+
+	return TRUE;
+}
+
+static int fota_read_file(const char*path, char*buf, size_t sz)
+{
+	int fd = -1;
+	size_t cnt;
+
+	fd = open(path, O_RDONLY, 0);
+	if(fd < 0)
+	{
+		slog(MISC_PRINT, SLOG_DEBUG,"fota_read_file failed to open %s: %s\n", path, strerror(errno));
+		cnt = -1;
+		return cnt;
+	}
+	cnt = read(fd, buf, sz - 1);
+	if(cnt <= 0)
+	{
+		slog(MISC_PRINT, SLOG_DEBUG, "failed to read %s: %s\n", path, strerror(errno));
+		close(fd);
+		cnt = -1;
+		return cnt;
+	}
+	buf[cnt] = '\0';
+	if(buf[cnt - 1] == '\n')
+	{
+		cnt--;
+		buf[cnt] = '\0';
+	}
+	close(fd);
+
+	return cnt;
+}
+
+static int fota_read_file_int(const char* path, int *val)
+{
+	char buf[32];
+	char *end;
+	int ret;
+	int tmp;
+
+	ret = fota_read_file(path, buf, sizeof(buf));
+	if(ret < 0)
+		return -1;
+
+	errno = 0;
+	tmp = strtol(buf, &end, 0);
+	if (errno == ERANGE) {
+		slog(MISC_PRINT, SLOG_DEBUG, "strtol errno %d: %s\n", errno, strerror(errno));
+	}
+
+	if ((end == buf) || ((end < buf + sizeof(buf)) && (*end != '\0')))
+	{
+		return -1;
+	}
+
+	*val = tmp;
+
+	return 0;
+}
+
+static int fota_get_update_status(int *fota_status)
+{
+
+	int status = 0;
+	int ret = 0;
+	if(!fota_is_file_exist(FOTA_UPDATE_STATUS_FILE)) {
+		*fota_status = -1;
+		return -1;
+	}
+	ret = fota_read_file_int(FOTA_UPDATE_STATUS_FILE, &status);
+	if(ret < 0) {
+		*fota_status = -1;
+		return -1;
+	}
+	*fota_status = status;
+	return 0;
+}
+
+// »Øµ÷º¯Êý£¬ÓÃÓÚ½«ÏÂÔØµÄÊý¾ÝдÈëÎļþ
+size_t fota_upgrade_write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+	size_t written = fwrite(ptr, size, nmemb, stream);
+
+	return written;
+}
+
+void zte_fota_manual_upgrade(webs_t wp)
+{
+	int result;
+    int upgradeStatus;
+	char_t *url = NULL;
+	zte_topsw_state_e_type status = ZTE_NVIO_MAX;
+	CURL *curl;
+	CURLcode res;
+	FILE *fp;
+
+	if (NULL == wp) {
+		return;
+	}
+	url = websGetVar(wp, T("UpgURL"), T(""));
+	slog(MISC_PRINT, SLOG_DEBUG,"zte_fota_manual_upgrade web para:[UpgURL] is [%s].\n", url);
+	if ('\0' == (*url)) {
+		zte_write_result_to_web(wp, FAILURE);
+		return;
+	}
+
+	status = zte_web_write("fota_manualUpgradeURL", url);
+	if (ZTE_NVIO_DONE != status) {
+		zte_write_result_to_web(wp, FAILURE);
+		return;
+	}
+
+	curl_global_init(CURL_GLOBAL_DEFAULT);
+	curl = curl_easy_init();
+	if(curl)
+	{
+		system("rm -rf /cache/zte_fota");
+		system("mkdir /cache/zte_fota");
+		fp = fopen("/cache/zte_fota/delta.package", "w");
+		if (fp == NULL)
+		{
+			zte_write_result_to_web(wp, FAILURE);
+			curl_easy_cleanup(curl);
+			curl_global_cleanup();
+			return;
+		}
+		curl_easy_setopt(curl, CURLOPT_URL, url);
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fota_upgrade_write_data);
+		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
+		// Ö´ÐÐÏÂÔØ
+		res = curl_easy_perform(curl);
+		if(res != CURLE_OK)
+		{
+			slog(MISC_PRINT, SLOG_DEBUG, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+			fclose(fp);
+			curl_easy_cleanup(curl);
+			curl_global_cleanup();
+			zte_write_result_to_web(wp, FAILURE);
+			return;
+		}
+		fclose(fp);
+		curl_easy_cleanup(curl);
+	}
+
+	curl_global_cleanup();
+	system("fota_upi -u verify");
+	result = fota_get_update_status(&upgradeStatus);
+	if(result < 0)
+	{
+		slog(MISC_PRINT, SLOG_DEBUG, "failed to read the update_status file\n");
+		zte_write_result_to_web(wp, FAILURE);
+	}
+	else if(upgradeStatus != 0)
+	{
+		slog(MISC_PRINT, SLOG_DEBUG, "verify failed\n");
+		zte_write_result_to_web(wp, FAILURE);
+	}
+	else
+	{
+		zte_write_result_to_web(wp, SUCCESS);
+		sleep(1);
+		system("fota_upi -u recovery");
+	}
+}
+
 #if 0
 
 /**********************************************************************
diff --git a/lynq/R307/ap/app/goahead/interface5.0/zte_web_util.c b/lynq/R307/ap/app/goahead/interface5.0/zte_web_util.c
index f24251c..d29ea0f 100755
--- a/lynq/R307/ap/app/goahead/interface5.0/zte_web_util.c
+++ b/lynq/R307/ap/app/goahead/interface5.0/zte_web_util.c
@@ -256,6 +256,7 @@
 	/**********  fota module ***********/
 	{GOFORM_SET_FOTAAUTOUPDATE, zte_fota_update},                                  //Óû§Ñ¡ÔñÊÇ·ñ½øÐÐÉý¼¶ºÍÉý¼¶ÖÐÈ¡Ïû
 	{GOFORM_SET_FOTASETTINGS, zte_fota_settings},                                  //×Ô¶¯¼ì²â
+	{GOFORM_SET_FOTAMANUALUPG, zte_fota_manual_upgrade},                           // ÊÖ¶¯otaÉý¼¶
 
 	/**********  ping test   ***********/
 	{GOFORM_PING_DIAGNOSTICS_START, zte_ping_diagnostics_start},					// ping°ü¼ì²â¹¦ÄÜ¿ªÆô
diff --git a/lynq/R307/ap/app/goahead/server/Makefile b/lynq/R307/ap/app/goahead/server/Makefile
index 1e209f7..2a29d2d 100755
--- a/lynq/R307/ap/app/goahead/server/Makefile
+++ b/lynq/R307/ap/app/goahead/server/Makefile
@@ -142,6 +142,8 @@
 
 CFLAGS += -I$(zte_lib_path)/libssl/install/include
 LDLIBS += -L$(zte_lib_path)/libssl/install/lib -lcrypto
+CFLAGS += -I$(zte_lib_path)/libcurl/install/include
+LDLIBS += -L$(zte_lib_path)/libcurl/install/lib -lcurl
 
 #*******************************************************************************
 # library path
diff --git a/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties
index 98505e9..d3f28a0 100755
--- a/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1094,6 +1094,7 @@
 ota_new_version_checking = Checking new version...

 ota_update_running = Checking is ongoing...

 ota_check_fail = Check new version failed!

+ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

diff --git a/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 7660614..42327f1 100755
--- a/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1096,6 +1096,7 @@
 ota_new_version_checking = 新版本检测中...

 ota_update_running = 检测已经在进行...

 ota_check_fail = 检测新版本失败!

+ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

diff --git a/lynq/R307/ap/app/zte_webui/js/com.js b/lynq/R307/ap/app/zte_webui/js/com.js
index 203ce25..a4de910 100755
--- a/lynq/R307/ap/app/zte_webui/js/com.js
+++ b/lynq/R307/ap/app/zte_webui/js/com.js
@@ -4515,6 +4515,40 @@
             }

         }

     }

+    function getManualOTAUpdateSetting() {

+        return stuffMake(arguments, {}, prepare, deal, null, false);

+        function prepare(values, isPost) {

+            var valueReq = {};

+            valueReq.cmd = "fota_manualUpgradeURL";

+            valueReq.multi_data = 1;

+            return valueReq;

+        }

+        function deal(paramD) {

+            if (paramD) {

+                return {

+                    updateURL: paramD.fota_manualUpgradeURL

+                };

+            } else {

+                return errUnknownObj;

+            }

+        }

+    }

+    function setManualOTAUpdateSetting() {

+        return stuffMake(arguments, {}, prepare, deal, null, true);

+        function prepare(values, isPost) {

+            var valueReq = {};

+            valueReq.goformId = "SetUpgManualSetting";

+            valueReq.UpgURL = values.updateURL;

+            return valueReq;

+        }

+        function deal(paramD) {

+            if (paramD && paramD.result == "success") {

+                return paramD;

+            } else {

+                return errUnknownObj;

+            }

+        }

+    }

     function getOTAlastCheckTime() {

         return getParams({

             nv: ['dm_last_check_time']

@@ -5479,6 +5513,8 @@
         getMandatory: getMandatory,

         getOTAUpdateSetting: getOTAUpdateSetting,

         setOTAUpdateSetting: setOTAUpdateSetting,

+        getManualOTAUpdateSetting: getManualOTAUpdateSetting,

+        setManualOTAUpdateSetting: setManualOTAUpdateSetting,

         getSignalStrength: getSignalStrength,

         getOTAlastCheckTime: getOTAlastCheckTime,

         clearUpdateResult: clearUpdateResult,

diff --git a/lynq/R307/ap/app/zte_webui/js/sim_device.js b/lynq/R307/ap/app/zte_webui/js/sim_device.js
index 5be4f99..633e2e6 100755
--- a/lynq/R307/ap/app/zte_webui/js/sim_device.js
+++ b/lynq/R307/ap/app/zte_webui/js/sim_device.js
@@ -230,6 +230,7 @@
     function FotaUpdateViewModel() {

         var target    = this;

         var setting = service.getOTAUpdateSetting();		

+        var upgUrl = service.getManualOTAUpdateSetting();

 

         target.allowRoamingUpdate = ko.observable(setting.allowRoamingUpdate);		

 		target.hasDdns            = config.DDNS_SUPPORT;

@@ -240,6 +241,22 @@
         target.updateIntervalDay  = ko.observable(setting.updateIntervalDay);		

         target.updateMode         = ko.observable(setting.updateMode);

 		target.updateType         = ko.observable(service.getUpdateType().update_type);

+        target.updateURL          = ko.observable(upgUrl.updateURL);

+

+        // 手动ota升级事件

+        target.ota_upgrade_apply = function () {

+            var otaUpdateURLInfo = {

+                updateURL: target.updateURL()

+            };

+            showLoading();

+            service.setManualOTAUpdateSetting(otaUpdateURLInfo, function (settingInfo) {

+                if (settingInfo && settingInfo.result == "success") {

+                    successOverlay();

+                } else {

+                    errorOverlay();

+                }

+            });

+        };

 

 

         // 自动检测设置按钮事件

diff --git a/lynq/R307/ap/app/zte_webui/subpg/ota_update.html b/lynq/R307/ap/app/zte_webui/subpg/ota_update.html
index f7a84de..20efa98 100755
--- a/lynq/R307/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/R307/ap/app/zte_webui/subpg/ota_update.html
@@ -30,13 +30,13 @@
 

 <div class="col-xs-10">

 <form id="frmOTAUpdate" role="form" data-bind="visible: updateType() == 'mifi_fota'">

-    <h3 data-trans="ota_update_manual" class="form-title"></h3>

+     <!-- <h3 data-trans="ota_update_manual" class="form-title"></h3 --> 

     <div class="form-body margin-top-20">

-        <div class="content">

+        <!--div class="content">

             <div class="row">

                 <div class="col-xs-6">

-                    <!--span data-trans="ota_last_update_check"></span>

-                    <span data-bind="text: lastCheckTime"></span-->

+                    <span data-trans="ota_last_update_check"></span>

+                    <span data-bind="text: lastCheckTime"></span>

                 </div>

                 <div class="col-xs-6 align-right">

                     <input id="btnCheckNewVersion" data-bind="click:checkNewVersion" data-trans="ota_check_new_version" type="button" class="btn btn-primary margin-right-20"/>

@@ -48,7 +48,7 @@
                     <li data-trans="ota_check_new_version_desc"></li>

                 </ul>

 		    </div>

-        </div>

+        </div-->

 

         <!--div class="form-title" data-trans='ota_update_manual'></div>

         <div class="content">

@@ -60,6 +60,7 @@
         </div>

         <div class="form-title" data-trans='ota_update_setting'></div-->

         <div class="content">

+			<!--

             <h3 data-trans="ota_update_setting" class="form-title"></h3>

             <div class="row">

                 <label data-trans="ota_auto_update_switch" class="col-xs-4 side-right"></label>

@@ -99,15 +100,26 @@
 

             <div class="form-buttons">

                 <input id="btnApply" data-trans="apply" type="submit" formmethod="post" class="btn btn-primary"/>

+            </div-->

+

+            <div class="row form-group">

+                <label data-trans="ota_manual_upgrade_url" class="col-xs-4 side-right"></label>

+                    <div class="col-xs-3">

+                        <input id="upgrade_url" type="text" size="128" data-bind="value:updateURL" class="required form-control">

+                    </div>

             </div>

-            <div class="form-note">

+            <div class="form-buttons">

+                <input id="btnOtaUpgApply" data-bind="click:ota_upgrade_apply" data-trans="download" type="submit" formmethod="post" class="btn btn-primary"/>

+            </div>

+

+            <!--div class="form-note">

                 <div class="notes-title">&nbsp;</div>

                 <ul class="notes-content">

                     <li data-trans="fota_note1"></li>

                 </ul>

-		    </div>

+		    </div-->

 		</div>

-        

+

 	</div>

 </form>

 <!--form id="frmNativeUpdate" data-bind="visible: updateType() == 'mifi_local'" method="post" name="UploadFile" id="UploadFile" action="../../cgi-bin/upload.cgi" enctype="multipart/form-data" target="ifr">