Merge "[Feature][S300AI][task-view-1714]When the wifi anomaly causes the system to freeze, restart the solution"
diff --git a/lynq/R305/ap/app/goahead/interface5.0/zte_web_mgmt.c b/lynq/R305/ap/app/goahead/interface5.0/zte_web_mgmt.c
index f0767ce..73af4c3 100755
--- a/lynq/R305/ap/app/goahead/interface5.0/zte_web_mgmt.c
+++ b/lynq/R305/ap/app/goahead/interface5.0/zte_web_mgmt.c
@@ -164,31 +164,6 @@
 		return;
 	}
 
-	if (user != NULL) {
-		slog(MISC_PRINT, SLOG_DEBUG," zte_mgmt_login  user = %s\n", user);
-		pUser = (char *)zte_base64_decode((const unsigned char *)user, strlen(user), (unsigned int*)&user_name_len);
-		if (NULL == pUser) {
-			zte_write_result_to_web(wp, LOGIN_FAIL);
-			return;
-		}
-
-		//strncpy(user_name, pUser, user_name_len);
-		if(user_name_len < sizeof(user_name))
-			snprintf(user_name,user_name_len+1,"%s",pUser);
-		else
-			snprintf(user_name,sizeof(user_name),"%s",pUser);
-		free(pUser);
-
-		slog(MISC_PRINT, SLOG_DEBUG," zte_mgmt_login  user_name = %s\n", user_name);
-		cfg_get_item("admin_user", buf, sizeof(buf));
-		if (0 != strcmp(user_name, buf)) {
-			slog(MISC_PRINT, SLOG_ERR," zte_mgmt_login user_name fail \n");
-			zte_write_result_to_web(wp, LOGIN_USER_NAME_NOT_EXSIT);
-			return;
-		}
-		slog(MISC_PRINT, SLOG_DEBUG," zte_mgmt_login uername correct \n");
-	}
-	slog(MISC_PRINT, SLOG_DEBUG,"[login] login1 -> zte_password_encode:%s.\n", psw); /*lint !e26*/
 #ifdef WEBS_SECURITY
 	zte_password = js_aes_decode(psw, strlen(psw), (unsigned int*)&zte_password_len);
 #else
@@ -217,6 +192,33 @@
 		return;
 	}
 
+	if (user != NULL) {
+		slog(MISC_PRINT, SLOG_DEBUG," zte_mgmt_login  user = %s\n", user);
+		pUser = (char *)zte_base64_decode((const unsigned char *)user, strlen(user), (unsigned int*)&user_name_len);
+		if (NULL == pUser) {
+			zte_write_result_to_web(wp, LOGIN_FAIL);
+			return;
+		}
+
+		//strncpy(user_name, pUser, user_name_len);
+		if(user_name_len < sizeof(user_name))
+			snprintf(user_name,user_name_len+1,"%s",pUser);
+		else
+			snprintf(user_name,sizeof(user_name),"%s",pUser);
+		free(pUser);
+
+		slog(MISC_PRINT, SLOG_DEBUG," zte_mgmt_login  user_name = %s\n", user_name);
+		cfg_get_item("admin_user", buf, sizeof(buf));
+		if (0 != strcmp(user_name, buf)) {
+			slog(MISC_PRINT, SLOG_ERR," zte_mgmt_login user_name fail \n");
+			zte_reduct_login_times();
+			zte_write_result_to_web(wp, LOGIN_USER_NAME_NOT_EXSIT);
+			return;
+		}
+		slog(MISC_PRINT, SLOG_DEBUG," zte_mgmt_login uername correct \n");
+	}
+	slog(MISC_PRINT, SLOG_DEBUG,"[login] login1 -> zte_password_encode:%s.\n", psw); /*lint !e26*/
+
 	//get request ip addr
 	ip_address = websGetRequestIpaddr(wp);
 #if 0 // kw 3	
diff --git a/lynq/R305/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/R305/ap/app/zte_webui/i18n/Messages_en.properties
index 7fd8a9a..b0aa772 100755
--- a/lynq/R305/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/R305/ap/app/zte_webui/i18n/Messages_en.properties
@@ -536,6 +536,7 @@
 sms_save_tip = Saving...

 

 #login

+username = Username

 password = Password

 puk = PUK

 login = Login

@@ -543,8 +544,8 @@
 new_pin = New PIN

 confirm_pin = Confirm New PIN

 puk_locked = Your SIM card is locked permanently. Please contact your operator.

-password_error = Password is incorrect!

-password_error_left = Password is incorrect!<br/>You have {0} attempt(s) left.

+password_error = Username or password is incorrect!

+password_error_left = Username or password is incorrect!<br/>You have {0} attempt(s) left.

 password_error_account_lock = Your account is locked. <br/>Remaining time:

 password_error_five_times = You''ve input 5 times incorrectly. Retry in 5 minutes.

 password_error_account_lock_time = Your account is locked. <br/>Please try later.

diff --git a/lynq/R305/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/R305/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index fc9c37a..4334a6c 100755
--- a/lynq/R305/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/R305/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -538,6 +538,7 @@
 sms_save_tip = 保存草稿中...

 

 #login

+username = 用户名

 password = 密码

 puk = PUK

 login = 登录

@@ -545,8 +546,8 @@
 new_pin = 新 PIN

 confirm_pin = 确认新 PIN

 puk_locked = 您的 SIM卡已彻底锁定。请联系您的运营商。

-password_error = 密码不正确!

-password_error_left = 密码不正确!<br/>您的剩余尝试次数:{0}。

+password_error = 用户名或密码不正确!

+password_error_left = 用户名或密码不正确!<br/>您的剩余尝试次数:{0}。

 password_error_account_lock = 你的账户被锁定。<br/>剩余时间:

 password_error_five_times = 您已经输错5次。请5分钟后再试。

 password_error_account_lock_time = 您的账户已被锁定。<br/>请稍后再试。

diff --git a/lynq/R305/ap/app/zte_webui/js/com.js b/lynq/R305/ap/app/zte_webui/js/com.js
index cc93b65..6f3f0a1 100755
--- a/lynq/R305/ap/app/zte_webui/js/com.js
+++ b/lynq/R305/ap/app/zte_webui/js/com.js
@@ -91,7 +91,8 @@
         function prepare(values, isPost) {

             var obj = {

                 goformId: "LOGIN",

-                password: config.PASSWORD_ENCODE ? Base64.encode(values.password) : values.password

+                password: config.PASSWORD_ENCODE ? Base64.encode(values.password) : values.password,

+                username: config.PASSWORD_ENCODE ? Base64.encode(values.username) : values.username

             };

             return obj;

         }

@@ -8165,6 +8166,7 @@
             target.loginSecuritySupport = ko.observable(config.LOGIN_SECURITY_SUPPORT);

             target.newPIN               = ko.observable();			

             target.password             = ko.observable();

+            target.username             = ko.observable();

             target.PIN                  = ko.observable();

             target.pinNumber            = ko.observable(data.pinnumber);			

             target.PUK                  = ko.observable();

@@ -8224,6 +8226,7 @@
                 var ciphertext = "";

                 if (config.PASSWORD_ENCODE) {

 		    ciphertext = target.password();

+            var username = target.username();

 		} else {

                     var kparam = service.getDeviceInfoLow();

                     var tkey = CryptoJS.enc.Latin1.parse(kparam.skey);

@@ -8235,7 +8238,8 @@
                         }).toString();

 		}

                 service.login({

-                    password:ciphertext

+                    password:ciphertext,

+                    username: username

                 }, function (info) {

                     setTimeout(function () {

                         timer = loginStatusCheckingTimer();

@@ -8252,6 +8256,7 @@
                         logout.init();

                     } else {

                         target.password("");

+                        target.username("");

                         if(config.LOGIN_SECURITY_SUPPORT){

                             target.checkLoginData(function(){

                                 if (target.loginCount() == config.MAX_LOGIN_COUNT) {

@@ -8336,9 +8341,12 @@
             function setFocus(){

                 setTimeout(function () {

                     var txtAdmin = $('#txtAdmin:visible');

+                    var txtUser = $('#txtUser:visible');

                     var txtPIN = $('#txtPIN:visible');

                     var txtPUK = $('#txtPUK:visible');

-                    if (txtAdmin.length > 0) {

+                    if(txtUser.length > 0) {

+                        txtUser.focus();

+                    } else if (txtAdmin.length > 0) {

                         txtAdmin.focus();

                     } else if (txtPIN.length > 0) {

                         txtPIN.focus();

diff --git a/lynq/R305/ap/app/zte_webui/subpg/entry.html b/lynq/R305/ap/app/zte_webui/subpg/entry.html
new file mode 100755
index 0000000..53df5c4
--- /dev/null
+++ b/lynq/R305/ap/app/zte_webui/subpg/entry.html
@@ -0,0 +1,110 @@
+<div id="loginForms">

+    <div class="row margin-top-160 padding-bottom-50">

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

+        <div class="col-xs-6" id="login-form-container">

+	<div id="loginContainer" class="login_frame form-horizontal margin-top-50 margin-bottom-50" data-bind="visible:pageState()!=4">

+		<form id="frmLogin" data-bind="visible:pageState()==0">

+            <div data-bind="visible: loginSecuritySupport() && accountLocked()" class="row form-group colorRed">

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

+                    <span data-trans="password_error_account_lock"></span> <span data-bind="text: leftUnlockTime"></span>

+                </div>

+            </div>

+            <div style="display: none;" class="row form-group">

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

+                    <label data-trans="password" for="txtAdmin"></label>

+                </div>

+			</div>

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

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

+                    <input id="txtUser" autocomplete="off" data-placeholder="username" data-bind="value:username, valueUpdate: 'keypress'"  maxlength="32" name="txtUser" style="border:2px solid rgb(221, 221, 221);" class="required form-control"/>

+                </div>

+            </div>

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

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

+                    <input id="txtAdmin" autocomplete="off" data-placeholder="password" data-bind="value:password, valueUpdate: 'keypress'"  maxlength="32" name="txtAdmin" style="border:2px solid rgb(221, 221, 221);" type="password" class="required form-control"/>

+                </div>

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

+                    <input id="btnLogin" class="btn btn-primary btn-block" data-trans="login" type="submit" formmethod="post" />

+                </div>

+            </div>

+            <div class="row form-group" data-bind="visible: showEntrance">

+                <div data-bind="visible: !sharePathInvalid()" class="col-xs-12">

+                    <span class="icon"><img src="pic/pic_red.png"></span>

+                    <span class="scan">

+                        <a data-trans="browse_sdcard" href="#httpshare_guest"></a>

+                    </span>

+                </div>

+                <div data-trans="sd_share_path_invalid" data-bind="visible: sharePathInvalid()" class="col-xs-12 colorRed"></div>

+                <div class="clear"></div>

+            </div>

+		</form>

+		<form id="frmPIN" data-bind="visible:pageState()==1">

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

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

+                    <p data-trans="enter_pin"></p>

+                    <p data-bind="visible:pinNumber()>1" class="important-prompt marginbottom15">

+                        <span data-trans="attempts_left"></span> <span data-bind='text:pinNumber'></span>

+                    </p>

+                    <p class="important-prompt" data-bind="visible:pinNumber()==1" data-trans="last_enter_pin"></p>

+                </div>

+            </div>

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

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

+                    <label data-trans='pin' for='txtPIN'></label>

+                    <input id='txtPIN' name="txtPIN" autocomplete="off" data-bind="value:PIN, valueUpdate: 'keypress'" maxlength='8' type="password" class="required form-control" />

+                </div>

+            </div>

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

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

+                    <input id="btnPinApply" data-trans="next_step" type="submit" formmethod="post" class="btn btn-primary" />

+                </div>

+            </div>

+		</form>

+		<form id="frmPUK" data-bind="visible:pageState()==2">

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

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

+                    <p data-trans="enter_puk"></p>

+                    <p data-bind="visible:pukNumber()>1" class="important-prompt">

+                        <span data-trans="attempts_left"></span> <span data-bind='text:pukNumber'></span>

+                    </p>

+                    <p data-bind="visible:pukNumber()==1" data-trans="last_enter_puk" class="important-prompt"></p>

+                </div>

+            </div>

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

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

+                    <label data-trans='puk' for='txtPUK'></label>

+					<input id='txtPUK' name="txtPUK" autocomplete="off" data-bind="value:PUK, valueUpdate: 'keypress'" maxlength='8' type="password" class="required form-control" />

+                </div>

+			</div>

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

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

+                    <label data-trans='new_pin' for='txtNewPIN'></label>

+					<input id='txtNewPIN' name="txtNewPIN" autocomplete="off" data-bind="value:newPIN, valueUpdate: 'keypress'" maxlength='8' type="password" class="required form-control" />

+                </div>

+			</div>

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

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

+                    <label data-trans='confirm_pin' for='txtConfirmPIN'></label>

+					<input id='txtConfirmPIN' name="txtConfirmPIN" autocomplete="off"

+						data-bind="value:confirmPIN, valueUpdate: 'keypress'" maxlength='8' type="password" class="required form-control"

+					/>

+                </div>

+			</div>

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

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

+					<input id="btnPUKApply" data-trans="next_step" type="submit" formmethod="post" class="btn btn-primary" />

+                </div>

+			</div>

+		</form>

+        <div data-bind="visible:pageState()==5" style="text-align: center;">

+            <img id="loadingImg" src="pic/res_loading.gif"/>

+        </div>

+		<div id="puk_locked" data-trans="puk_locked" data-bind="visible:pageState()==3" class="important-prompt prompt"></div>

+		<div class="login_bottom"></div>

+	</div>

+

+

+        </div>

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

+    </div>

+</div>
\ No newline at end of file
diff --git a/lynq/R306BR/ap/app/ccapp/cc_proc.c b/lynq/R306BR/ap/app/ccapp/cc_proc.c
index 7d5a910..1b2cc5b 100755
--- a/lynq/R306BR/ap/app/ccapp/cc_proc.c
+++ b/lynq/R306BR/ap/app/ccapp/cc_proc.c
@@ -2188,6 +2188,9 @@
             msgBuf.usMsgCmd = ZCC_RELEASE_E;

             msgBuf.src_id = MODULE_ID_SLIC;

             zCc_SendMsgToSub(&msgBuf);

+			

+			/*fix the issue of probability callback failure, call has not been established yet, with a probability of hanging up*/

+			sleep(1);

             

             zCc_SendAtHangupReq();

             zte_log_append(__FILE__, __LINE__, "zte_ccapp.log","%s  zCc_MRingingState: ZCC_RELEASE_E <---\n",__FUNCTION__);

diff --git a/lynq/R306BR/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/R306BR/ap/app/zte_webui/i18n/Messages_en.properties
index 06a218c..917a947 100755
--- a/lynq/R306BR/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/R306BR/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1821,6 +1821,7 @@
 call_back_explain = If the number is in the callback list, picking up the phone will automatically hang up the call and then call back.

 calling_limit_explain = Limit Outgoing Calls Duration: Limit the duration of outgoing calls, if the set time is exceeded, the phone will hang up.

 called_limit_explain = Limit Received Calls Duration: Limit the duration of reveived calls, if the set time is exceeded, the phone will hang up.

+call_forward_explain = To use the call forwarding, you need to contact the operator to activate it. To cancel the call forwarding, you need to clear the number and apply.

 call_forward_all_explain = Forward all calls to phone number: Forward all calls to the specified phone number.

 call_forward_noanswer_explain = Forward if not answered to phone number: Forward calls to the specified phone number if not answered.

 call_forward_noreach_explain = Forward if out of reach to phone number: Forward calls to the specified phone number if out of reach.

diff --git a/lynq/R306BR/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/R306BR/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index e5c7fbe..21332f2 100755
--- a/lynq/R306BR/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/R306BR/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1825,6 +1825,7 @@
 call_back_explain = 如果来电号码在回拨号码列表中,拿起话机后会自动挂断,并自动回拨该号码。

 calling_limit_explain = 主叫时长限制:限制主叫通话时长,超过限制时,将自动挂断。

 called_limit_explain = 被叫时长限制:限制被叫通话时长,超过限制时,将自动挂断。

+call_forward_explain = 要使用呼叫转移功能,需要联系运营商开通方可设置,取消呼叫转移需要将号码清空后应用。

 call_forward_all_explain = 转移所有号码:所有呼叫都将转移到指定的号码。

 call_forward_noanswer_explain = 转移无应答:呼叫无法应答时转移到指定的号码。

 call_forward_noreach_explain = 转移不可达:呼叫不可达时转移到指定的号码。

diff --git a/lynq/R306BR/ap/app/zte_webui/subpg/voice_call_forwarding.html b/lynq/R306BR/ap/app/zte_webui/subpg/voice_call_forwarding.html
index 690f997..394ac25 100755
--- a/lynq/R306BR/ap/app/zte_webui/subpg/voice_call_forwarding.html
+++ b/lynq/R306BR/ap/app/zte_webui/subpg/voice_call_forwarding.html
@@ -83,6 +83,7 @@
                     <div class="form-note">

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

                         <ul class="notes-content">

+                            <li data-trans="call_forward_explain"></li>

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

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

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

diff --git a/lynq/S300AI/allbins/zx297520v3/prj_cpe/nv_230a/Ref_nvrw_0x26C00.bin b/lynq/S300AI/allbins/zx297520v3/prj_cpe/nv_230a/Ref_nvrw_0x26C00.bin
index 9c7329e..fe2b986 100644
--- a/lynq/S300AI/allbins/zx297520v3/prj_cpe/nv_230a/Ref_nvrw_0x26C00.bin
+++ b/lynq/S300AI/allbins/zx297520v3/prj_cpe/nv_230a/Ref_nvrw_0x26C00.bin
Binary files differ
diff --git a/lynq/S300AI/ap/app/ccapp/cc_proc.c b/lynq/S300AI/ap/app/ccapp/cc_proc.c
index 7d5a910..1b2cc5b 100755
--- a/lynq/S300AI/ap/app/ccapp/cc_proc.c
+++ b/lynq/S300AI/ap/app/ccapp/cc_proc.c
@@ -2188,6 +2188,9 @@
             msgBuf.usMsgCmd = ZCC_RELEASE_E;

             msgBuf.src_id = MODULE_ID_SLIC;

             zCc_SendMsgToSub(&msgBuf);

+			

+			/*fix the issue of probability callback failure, call has not been established yet, with a probability of hanging up*/

+			sleep(1);

             

             zCc_SendAtHangupReq();

             zte_log_append(__FILE__, __LINE__, "zte_ccapp.log","%s  zCc_MRingingState: ZCC_RELEASE_E <---\n",__FUNCTION__);

diff --git a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_interface.h b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_interface.h
index f2d53b7..3e5aba8 100755
--- a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_interface.h
+++ b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_interface.h
@@ -250,6 +250,7 @@
 #define GOFORM_MGMT_SNTP "SNTP"
 #define GOFORM_MGMT_SYSLOG  "SYSLOG"
 #define GOFORM_MGMT_SCHEDULE_SETTING "SCHEDULE_SETTING"
+#define GOFORM_MGMT_BATTERY_VOICE_SETTING "BATTERY_VOICE_SETTING"
 //#define GOFORM_HTTP_REDIRECT "HTTP_REDIRECT"
 /*management end*/
 
diff --git a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.c b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.c
index cbb5143..769e9bc 100755
--- a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.c
+++ b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.c
@@ -1376,6 +1376,18 @@
 	return;
 }
 
+void zte_goform_mgmt_battery_voice_setting_process(webs_t wp)
+{
+	char *battery_voice_voltage = NULL;
+
+	battery_voice_voltage = websGetVar(wp, T("battery_voice_voltage"), T(""));
+	cfg_set("battery_voice_voltage", battery_voice_voltage);
+	cfg_save();
+
+	zte_write_result_to_web(wp, SUCCESS);
+	return;
+}
+
 void zte_goform_mamt_cwmp_process(webs_t wp)
 {
 	char *cwmp_enable = NULL;
diff --git a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.h b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.h
index 478be40..a99c32d 100755
--- a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.h
+++ b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_mgmt.h
@@ -81,6 +81,7 @@
 extern void zte_mgmt_set_devicemode(webs_t wp);
 
 extern void zte_goform_mgmt_schedule_setting_process(webs_t wp);
+extern void zte_goform_mgmt_battery_voice_setting_process(webs_t wp);
 extern void zte_goform_mamt_cwmp_process(webs_t wp);
 
 extern void zte_goform_mgmt_sntp_process(webs_t wp);
diff --git a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_util.c b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_util.c
index 2b086b2..3a675b7 100755
--- a/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_util.c
+++ b/lynq/S300AI/ap/app/goahead/interface5.0/zte_web_util.c
@@ -158,6 +158,7 @@
 	//{GOFORM_MGMT_SET_EXTERNAL_NV, zte_goform_set_external_nv},
 	{GOFORM_MGMT_SCHEDULE_SETTING, zte_goform_mgmt_schedule_setting_process},
 	{GOFORM_MGMT_SNTP, zte_goform_mgmt_sntp_process},                           //SNTPÉèÖÃ
+	{GOFORM_MGMT_BATTERY_VOICE_SETTING, zte_goform_mgmt_battery_voice_setting_process},
 	{GOFORM_SNTP_GETDATASTATIC, zte_goform_sntp_getdatastatic_process},         //´¥·¢serverУ׼ʱ¼ä
 	//{GOFORM_MGMT_SYSLOG, zte_goform_mgmt_syslog_process},                       //ϵͳLOG
 
diff --git a/lynq/S300AI/ap/app/zte_comm/at_ctl/src/atconfig/extat_softap_register.c b/lynq/S300AI/ap/app/zte_comm/at_ctl/src/atconfig/extat_softap_register.c
index df1395a..1219e0d 100755
--- a/lynq/S300AI/ap/app/zte_comm/at_ctl/src/atconfig/extat_softap_register.c
+++ b/lynq/S300AI/ap/app/zte_comm/at_ctl/src/atconfig/extat_softap_register.c
@@ -922,6 +922,41 @@
 	return AT_END;

 }

 

+int ext_at_gpio_in_func(char *at_paras, void ** res_msg)

+{

+	if(at_paras && strlen(at_paras) > 0 && strlen(at_paras) < 5)

+	{

+		int gpio_num = 0;

+		char cmd[128] = {0};

+		char gpio_dir[12] = {0};

+		char *at_str = malloc(64);

+

+		gpio_num = atoi(at_paras);

+		snprintf(cmd, sizeof(cmd), "echo \"%d\" > /sys/class/gpio/export", gpio_num);

+		system(cmd);

+		snprintf(cmd, sizeof(cmd), "echo in > /sys/class/gpio/gpio%d/direction", gpio_num);

+		system(cmd);

+

+		snprintf(cmd, sizeof(cmd), "grep \"GPIO%d_\" /sys/kernel/debug/zx29_gpio | awk '{print $2}'", gpio_num);

+		executeCommand(cmd, gpio_dir, sizeof(gpio_dir));

+

+		if(strlen(gpio_dir) > 0)

+		{

+			sprintf(at_str, "\r\n+GPIO%d: %s\r\nOK\r\n", gpio_num, gpio_dir);

+		}

+		else

+		{

+			sprintf(at_str, "\r\n+GPIO%d: NO SUCH GPIO\r\nERROR\r\n", gpio_num);

+		}

+

+		*res_msg = at_str;

+		return AT_END;

+	}

+

+	*res_msg = at_err_build(ATERR_PARAM_INVALID);

+	return AT_END;

+}

+

 static int extract_ss_data(const char *filename, int *avg_num1, int *avg_num2)

 {

     FILE *file = popen(filename, "r");

@@ -1011,6 +1046,22 @@
 	return AT_END;

 }

 

+int ext_at_battery_voice_voltage_func(char *at_paras, void ** res_msg)

+{

+	if(at_paras && strlen(at_paras) == 4)

+	{

+		char *at_str = malloc(32);

+		cfg_set("battery_voice_voltage", at_paras);

+		snprintf(at_str, 32, "\r\n+BATTERY_VOICE: %s\r\nOK\r\n", at_paras);

+

+		*res_msg = at_str;

+		return AT_END;

+	}

+

+	*res_msg = at_err_build(ATERR_PARAM_INVALID);

+	return AT_END;

+}

+

 void ext_notelcom_regist()

 {

     register_serv_func2("ZWIFI=", MODULE_ID_WIFI, 

@@ -1051,8 +1102,10 @@
 	register_serv_func("LAN_IP?", 0, ext_at_lan_ip_func);

 	register_serv_func("ATV_GPIO?", 0, ext_at_atv_gpio_func);

 	register_serv_func("GPIO=", 0, ext_at_gpio_func);

+	register_serv_func("GPIO_IN=", 0, ext_at_gpio_in_func);

 	register_serv_func("WLAN_SS", 0, ext_at_wlan_ss_func);

 	register_serv_func("FMTEST=", 0, ext_at_delay_shut_down_func);

+	register_serv_func("BATTERY_VOICE=", 0, ext_at_battery_voice_voltage_func);

 }

 

 void at_comm_init(void)

diff --git a/lynq/S300AI/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/S300AI/ap/app/zte_webui/i18n/Messages_en.properties
index d013ac3..142c81f 100755
--- a/lynq/S300AI/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/S300AI/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1817,3 +1817,11 @@
 calling_white_number_list = Whitelist of Outgoing Calls

 add_called_white_number_list = Add Number to Whitelist of Received Calls

 called_white_number_list = Whitelist of Received Calls

+battery_voice_set = Voice Configuration

+battery_voice_info = If battery voltage below set, mute voice, only effective powered by battery

+close_voice_voltage = Close Voice Voltage(mV)

+close_voice_select_0 = Always effective

+close_voice_select_3600 = 3600

+close_voice_select_3700 = 3700

+close_voice_select_3800 = 3800

+close_voice_select_3900 = 3900

diff --git a/lynq/S300AI/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/S300AI/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 6bae806..681dcbd 100755
--- a/lynq/S300AI/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/S300AI/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1821,3 +1821,11 @@
 calling_white_number_list = 主叫白名单号码列表

 add_called_white_number_list = 添加被叫白名单号码

 called_white_number_list = 被叫白名单号码列表

+battery_voice_set = 语音配置

+battery_voice_info = 电池电量低于设定值时,关闭语音功能,仅在电池供电时生效

+close_voice_voltage = 关闭语音电压(mV)

+close_voice_select_0 = 直接生效

+close_voice_select_3600 = 3600

+close_voice_select_3700 = 3700

+close_voice_select_3800 = 3800

+close_voice_select_3900 = 3900

diff --git a/lynq/S300AI/ap/app/zte_webui/js/com.js b/lynq/S300AI/ap/app/zte_webui/js/com.js
index e3432ad..68023f1 100755
--- a/lynq/S300AI/ap/app/zte_webui/js/com.js
+++ b/lynq/S300AI/ap/app/zte_webui/js/com.js
@@ -4317,6 +4317,41 @@
             }

         }

     }

+

+    function getBatteryVoiceSetting() {

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

+        function prepare(values, isPost) {

+            var valueReq = {};

+            valueReq.cmd = "battery_voice_voltage";

+            return valueReq;

+        }

+        function deal(paramD) {

+            if (paramD) {

+                var result = {};

+                result.battery_voice_voltage = paramD.battery_voice_voltage;

+                return result;

+            } else {

+                return errUnknownObj;

+            }

+        }

+    }

+    function setBatteryVoiceSetting() {

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

+        function prepare(values, isPost) {

+            var valueReq = {};

+            valueReq.goformId = "BATTERY_VOICE_SETTING";

+            valueReq.battery_voice_voltage = values.battery_voice_voltage;

+            return valueReq;

+        }

+        function deal(paramD) {

+            if (paramD) {

+                return paramD;

+            } else {

+                return errUnknownObj;

+            }

+        }

+    }

+    

     function getCwmpSetting() {

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

         function prepare(values, isPost) {

@@ -6447,6 +6482,8 @@
         restart: restart,

         getScheduleSetting: getScheduleSetting,

         setScheduleSetting: setScheduleSetting,

+        getBatteryVoiceSetting: getBatteryVoiceSetting,

+        setBatteryVoiceSetting: setBatteryVoiceSetting,

         getCwmpSetting: getCwmpSetting,

         setCwmpSetting: setCwmpSetting,

         updateTimerFlag: updateTimerFlag,

@@ -7058,6 +7095,10 @@
 			return new Option(item.name, item.value);

 		});

 

+        var batteryVoiceModes = _.map(config.batteryVoiceSetModes, function(item) {

+			return new Option(item.name, item.value);

+		});

+

 		var sv_sntpYears    = [];

 		var sv_sntpMonths   = [];

 		var sv_sntpDates    = [];  //���ݴ�С����������

@@ -7395,7 +7436,22 @@
 				!target.isOther2() && $("#sntp_server2").find(".error").hide();

 			}

 

+            var sv_batteryVoiceInfo = service.getBatteryVoiceSetting();

+            target.batteryVoiceModes = ko.observableArray(batteryVoiceModes);

+            target.currentVoiceMode = ko.observable(sv_batteryVoiceInfo.battery_voice_voltage);

 

+            target.batteryVoiceSave = function () {

+                showLoading();

+                var params = {};

+                params.battery_voice_voltage = target.currentVoiceMode();

+                service.setBatteryVoiceSetting(params, function (result) {

+                    if (result.result != "success") {

+                        errorOverlay();

+                    } else {

+                        successOverlay();

+                    }

+                });

+            };

         }

 

 	    // ��ʼ�� ViewModel����������ͼ��

diff --git a/lynq/S300AI/ap/app/zte_webui/js/ext/set_aic8800d40i.js b/lynq/S300AI/ap/app/zte_webui/js/ext/set_aic8800d40i.js
index 8a83356..b69d09e 100755
--- a/lynq/S300AI/ap/app/zte_webui/js/ext/set_aic8800d40i.js
+++ b/lynq/S300AI/ap/app/zte_webui/js/ext/set_aic8800d40i.js
@@ -72,6 +72,23 @@
                 name: '3G Only',

                 value: 'Only_WCDMA'

             }

+        ],

+        batteryVoiceSetModes: [{

+                name: "Always on",

+                value: "0"

+            }, {

+                name: "3600 mV",

+                value: "3600"

+            }, {

+                name: "3700 mV",

+                value: "3700"

+            }, {

+                name: "3800 mV",

+                value: "3800"

+            }, {

+                name: "3900 mV",

+                value: "3900"

+            }

         ]

     };

 

diff --git a/lynq/S300AI/ap/app/zte_webui/subpg/adm_others.html b/lynq/S300AI/ap/app/zte_webui/subpg/adm_others.html
index 112b09f..f6ec9d4 100755
--- a/lynq/S300AI/ap/app/zte_webui/subpg/adm_others.html
+++ b/lynq/S300AI/ap/app/zte_webui/subpg/adm_others.html
@@ -202,6 +202,24 @@
 			</div>

 		</form>

 

+		<form id="frmBatteryVoiceSet" style="display: none;">

+            <div class="form-body">

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

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

+                    <div data-trans="battery_voice_info" class="col-xs-12"></div>

+                </div>

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

+                    <label class="col-xs-4 side-right" data-trans='close_voice_voltage' for="batteryVoiceSetting"></label>

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

+						<select id="batteryVoiceSetting" class="form-control" data-transid="close_voice_select" data-bind="options: batteryVoiceModes, value: currentVoiceMode, optionsText: transOption('close_voice_select'), optionsValue: 'value'"></select>

+					</div>

+                </div>

+				<div class="form-buttons">

+					<input data-bind="click:batteryVoiceSave" data-trans="apply" type="submit" formmethod="post" class="btn btn-primary margin-right-20"/>

+				</div>

+            </div>

+        </form>

+

         <div class="form-body">

             <div class="content margin-top-20 line-height-30">

                 <div class="row">

diff --git a/lynq/S300AI/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user b/lynq/S300AI/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user
index aeb47f3..36d785d 100755
--- a/lynq/S300AI/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user
+++ b/lynq/S300AI/ap/project/zx297520v3/prj_cpe/fs/normal/rootfs/etc_ro/default/default_parameter_user
@@ -557,3 +557,4 @@
 call_csp_number=
 #for voice end
 wifi_switch_status=
+battery_voice_voltage=0