Merge "[Feature][T106]version update to T106-W-V2.01.01.02P56U06.AP.15.06_CAP.15.06"
diff --git a/ap/lib/libps/220A1_vehicle_dc/ps/com.a b/ap/lib/libps/220A1_vehicle_dc/ps/com.a
index 06b9fb3..de25c26 100755
--- a/ap/lib/libps/220A1_vehicle_dc/ps/com.a
+++ b/ap/lib/libps/220A1_vehicle_dc/ps/com.a
Binary files differ
diff --git a/ap/lib/libps/220A1_vehicle_dc/ps/nas.a b/ap/lib/libps/220A1_vehicle_dc/ps/nas.a
index fda4d81..c1b52c3 100755
--- a/ap/lib/libps/220A1_vehicle_dc/ps/nas.a
+++ b/ap/lib/libps/220A1_vehicle_dc/ps/nas.a
Binary files differ
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
index 7472cc2..8400655 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
+++ b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
@@ -133,9 +133,9 @@
 SECURITY_STACK_PROTECTOR = " -fstack-protector-all"
 #CUSTOM_MACRO += " -D_USE_CODEC_TI3100 "
 #CUSTOM_MACRO += " -D_USE_CODEC_NAU8810 "
-CUSTOM_MACRO += " -D_USE_CODEC_TI3104 "
+#CUSTOM_MACRO += " -D_USE_CODEC_TI3104 "
 #CUSTOM_MACRO += " -D_USE_CODEC_MAX9867 "
-#CUSTOM_MACRO += " -D_USE_CODEC_ES8311 "
+CUSTOM_MACRO += " -D_USE_CODEC_ES8311 "
 CUSTOM_MACRO += "${@bb.utils.contains('DISTRO_FEATURES', 'voice_alsa', '-D_USE_VOICE_ALSA', '', d)}"
 CUSTOM_MACRO += "${@bb.utils.contains('DISTRO_FEATURES', 'use_voice_buffer', '-D_USE_VOICE_BUFFER', '', d)}"
 #CONFIG_VB_TRANSMIT_INTF = "RTP"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc_ref/fs/normal/rootfs/etc_ro/default/default_parameter_user b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc_ref/fs/normal/rootfs/etc_ro/default/default_parameter_user
index 90a1d43..d43a308 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc_ref/fs/normal/rootfs/etc_ro/default/default_parameter_user
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc_ref/fs/normal/rootfs/etc_ro/default/default_parameter_user
@@ -14,9 +14,7 @@
 at_snap_flag=3
 at_wifi_mac=0
 auto_apn_index=0
-#xf.li@20240111 modify for T106BUG-480 start
-cid_reserved=0
-#xf.li@20240111 modify for T106BUG-480 end
+cid_reserved=1
 clear_pb_when_restore=no
 clear_sms_when_restore=no
 default_apn=3gnet
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp
index a9d44b2..4e79af6 100755
--- a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/data/data.cpp
@@ -822,7 +822,7 @@
             memcpy(lynq_apn_cid_table[i].apntype, apntype, strlen(apntype) + 1);
             lynq_apn_cid_table[i].dialing = 1;
             lynq_apn_cid_table[i].uToken = pRI->uToken;
-            RLOGD("DATA: apn_table[%d].apn = %s, apntype = %s, dialing = %d, utoken = %d\n", i, lynq_apn_cid_table[i].apn, lynq_apn_cid_table[i].apntype, lynq_apn_cid_table[i].dialing, lynq_apn_cid_table[i].uToken = pRI->uToken);
+            RLOGD("DATA: apn_table[%d].apn = %s, apntype = %s, dialing = %d, utoken = %d\n", i, lynq_apn_cid_table[i].apn, lynq_apn_cid_table[i].apntype, lynq_apn_cid_table[i].dialing, lynq_apn_cid_table[i].uToken);
             break;
         }
     }
@@ -1181,6 +1181,7 @@
 #ifdef MOBILETEK_TARGET_PLATFORM_T106
     char reason[8];
     const char *cid = argv[1];
+    int deactive_cid = -1;
 
     if(argc != 2)
     {
@@ -1188,8 +1189,16 @@
         RLOGD("the paremeters numbers isn't right , so return");
         return -1;
     }
-    RLOGD("cid = %S",cid);
-    RLOGD("deactivateDataCall %d: " , pRI->pCI->requestNumber);
+    deactive_cid = atoi(cid);
+    RLOGD("deactive_cid = %d, utoken = %d", deactive_cid, pRI->uToken);
+    for(int i = 0; i < LYNQ_APN_CHANNEL_MAX; i++)
+    {
+        if(lynq_apn_cid_table[i].cid == deactive_cid)
+        {
+            lynq_apn_cid_table[i].deactive_utoken = pRI->uToken;
+            break;
+        }
+    }
     sprintf(reason,"%d",DEACTIVATE_REASON_NONE);
     android::Parcel p;
     size_t pos = p.dataPosition();
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
index ad0cfad..04e8d5a 100755
--- a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
@@ -34,14 +34,14 @@
 //xf.il@20230610 modify for T106 data start
 #ifdef MOBILETEK_TARGET_PLATFORM_T106
 extern lynq_apn_cid_table_t lynq_apn_cid_table[LYNQ_APN_CHANNEL_MAX] = {
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""}, \
-    {-1, "", "", "", -1, -1, -1, -1, ""},
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""}, \
+    {-1, "", "", "", -1, -1, -1, -1, -1, ""},
 };
 #endif
 //xf.il@20230610 modify for T106 data end
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h
index c8d56cf..ceb46f9 100755
--- a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/lynq_common.h
@@ -110,6 +110,7 @@
     int dialing;
     int status;
     int uToken;
+    int deactive_utoken;
     //int apnstatus;//1:has enable;0:need disable.
     //int pdpstate;//lei add for at+elapnact?  refer to T800 AT COMMANDS:+lapnact
     char address[LYNQ_ADDRESS_LEN_MAX];
diff --git a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp
index 26f34a7..bc7d265 100755
--- a/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp
+++ b/cap/zx297520v3/src/lynq/framework/lynq-ril-service/src/ril.cpp
@@ -4178,6 +4178,47 @@
 
         p.writeInt32 (e);
         #ifdef MOBILETEK_TARGET_PLATFORM_T106
+        if(pRI->pCI->requestNumber == RIL_REQUEST_DEACTIVATE_DATA_CALL)
+        {
+            if(e == 0)
+            {
+                RLOGD("[DATA]: deactive datacall success\n");
+                for(int j = 0; j < LYNQ_APN_CHANNEL_MAX; j++)
+                {
+                    RLOGD("lynq_apn_cid_table[j].uToken =%d, pRI->uToken = %d", lynq_apn_cid_table[j].deactive_utoken, pRI->uToken);
+                    if(lynq_apn_cid_table[j].used == 1 && lynq_apn_cid_table[j].deactive_utoken == pRI->uToken)
+                    {
+                        RLOGD("[DATA]delete cid is %d", lynq_apn_cid_table[j].cid);
+                        //delete
+                        bzero(lynq_apn_cid_table[j].apn,LYNQ_APN_LEN_MAX);
+                        bzero(lynq_apn_cid_table[j].apntype,LYNQ_APNTPYE_LEN_MAX);
+                        bzero(lynq_apn_cid_table[j].ifaceName,LYNQ_IFNAME_LEN_MAX);
+                        bzero(lynq_apn_cid_table[j].address,LYNQ_ADDRESS_LEN_MAX);
+                        lynq_apn_cid_table[j].cid = -1;
+                        lynq_apn_cid_table[j].used = -1;
+                        lynq_apn_cid_table[j].status = -1;
+                        lynq_apn_cid_table[j].dialing = -1;
+                        lynq_apn_cid_table[j].uToken = -1;
+                        lynq_apn_cid_table[j].deactive_utoken = -1;
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                RLOGD("[DATA]: deactive datacall fail\n");
+                for(int j = 0; j < LYNQ_APN_CHANNEL_MAX; j++)
+                {
+                    RLOGD("lynq_apn_cid_table[j].uToken =%d, pRI->uToken = %d", lynq_apn_cid_table[j].deactive_utoken, pRI->uToken);
+                    if(lynq_apn_cid_table[j].used == 1 && lynq_apn_cid_table[j].deactive_utoken == pRI->uToken)
+                    {
+                        lynq_apn_cid_table[j].deactive_utoken = -1;
+                        break;
+                    }
+                }
+            }
+
+        }
         //xf.li@20231102 add for t106 data start
         if(pRI->pCI->requestNumber == RIL_REQUEST_SETUP_DATA_CALL)
         {
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data.cpp
index 7b29791..f64f900 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data.cpp
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <vector>
 #include "lynq_data_urc.h"
+#include "lynq_data_list_buffer.h"
 
 #define LYNQ_SERVICE_PORT 8088
 #define LYNQ_REC_BUF 8192
@@ -632,6 +633,7 @@
     {
         case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
             LYINFLOG("LIBLYNQ_DATA receive RIL_UNSOL_DATA_CALL_LIST_CHANGED\n");
+            set_list_buffer_valid(false);
             p->readInt32(&version);
             p->readInt32(&num);
         /* update apn start*/
@@ -1024,6 +1026,8 @@
     data_timelimit = 0;
     lynq_data_call_change_id = -1;
 
+    init_data_timer_all();
+
     result = lynq_socket_client_start();
     pthread_mutex_init(&g_lynq_data_sendto_mutex, NULL);
     if(result!=0)
@@ -1096,6 +1100,7 @@
     pthread_mutex_lock(&s_lynq_urc_vector_mutex);
     s_data_urc_wait_list.clear();
     pthread_mutex_unlock(&s_lynq_urc_vector_mutex);
+    deinit_data_timer_all();
     LYINFLOG("[%s] end [%d]",__FUNCTION__,__LINE__);
     return 0;
 }
@@ -1261,7 +1266,7 @@
             }
             continue;
         }
-
+        set_list_buffer_valid(false);
 
         bzero(type,LYNQ_TYPE_MAX_LEN);
         bzero(ifaceName,LYNQ_IFACE_NAME_MAX_LEN);
@@ -1439,8 +1444,13 @@
     JumpHeader(p,&resp_type,&client.uToken,&request,&slot_id,&error);
     LYINFLOG("resp_type=%d,uToken=%d,request=%d,slot_id=%d,error_code=%d",resp_type,client.uToken,request,slot_id,error);
     free_parcel(p);
-#ifndef MOBILETEK_TARGET_PLATFORM_T106
     cleanOnceApnTable(lynq_data_call_id);
+#ifdef MOBILETEK_TARGET_PLATFORM_T106
+    set_list_buffer_valid(false);
+    pthread_mutex_lock(&s_lynq_urc_vector_mutex);
+    s_data_urc_wait_list.push_back(lynq_data_call_id);
+    pthread_mutex_unlock(&s_lynq_urc_vector_mutex);
+    sendSignalPdnChange();
 #endif
     printf_apn_table_debug(__FUNCTION__,__LINE__);
     return error;
@@ -1677,7 +1687,7 @@
         return error;
     }
     pthread_mutex_unlock(&g_lynq_data_sendto_mutex);
-
+    set_list_buffer_valid(false);
     bzero(type,LYNQ_TYPE_MAX_LEN);
     bzero(ifaceName,LYNQ_IFACE_NAME_MAX_LEN);
 
@@ -2077,7 +2087,12 @@
     }
     LYINFLOG("[lynq_get_data_call_list] incoming handle value: %d",*handle);
     memset(&interDataCallList,0,sizeof(interDataCallList));
-    error = getDataCallLists(interDataCallList,&number);
+    if(get_list_from_buf(interDataCallList, &number) != 0)
+    {
+        error = getDataCallLists(interDataCallList, &number);
+        set_list_to_buf(interDataCallList, number);
+    }
+
     if(error == 0)
     {
         for(int i = 0;i < number;i++)
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data_list_buffer.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data_list_buffer.cpp
new file mode 100755
index 0000000..6a1356d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data_list_buffer.cpp
@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <climits>
+#include <stdlib.h>
+#include "liblog/lynq_deflog.h"
+#include "lynq_data.h"
+#include "lynq_data_list_buffer.h"
+#include <include/lynq_uci.h>
+
+#define LOG_UCI_FILE "lynq_uci"
+#define LOG_UCI_MODULE "lynq_data"
+#define USER_LOG_TAG "LYNQ_DATA_BUFFER"
+#define DEFAULT_PERIOD 5    //default 5s
+
+static timer_t s_list_buffer_timer;
+static int s_list_buffer_valid = false;
+static int s_state_buffer_valid_period;
+lynq_data_call_response_v11_t dataCallList_buffer[LYNQ_APN_CHANNEL_MAX];
+static int number_buffer=0;
+
+void start_data_timer(timer_t timer, int milliseconds) 
+{
+    LYINFLOG("start_data_timer(), timer_id=%ld, time=%d",(long)timer, milliseconds);
+
+    struct itimerspec expire;
+    expire.it_interval.tv_sec = 0;
+    expire.it_interval.tv_nsec = 0;
+    expire.it_value.tv_sec = milliseconds/1000;
+    expire.it_value.tv_nsec = (milliseconds%1000)*1000000;
+    if (timer_settime(timer, 0, &expire, NULL) == -1) {
+        LYERRLOG("timer_settime  failed reason=[%s]", strerror(errno));
+    }
+}
+void stop_data_timer(timer_t timer) 
+{
+    LYINFLOG("stop_data_timer(), timer_id=%ld", (long)timer);
+    struct itimerspec timespec;
+    if(timer_gettime(timer, &timespec) == -1) {
+        LYERRLOG("stop_data_timer(), get time fail(%s)", strerror(errno));
+        return;
+    }
+    LYINFLOG("stop_data_timer(), tv_sec=%ld, tv_nsec=%ld",timespec.it_value.tv_sec, timespec.it_value.tv_nsec);
+    if((timespec.it_value.tv_sec == 0)  && (timespec.it_value.tv_nsec == 0) ) {
+        LYINFLOG("stop_data_timer(), timer_id(%ld) had stopped, just return", (long)timer);
+        return;
+    } else {
+        start_data_timer(timer, 0);
+    }
+}
+
+void data_timer_handler(sigval_t sig) 
+{    
+    LYINFLOG("[%s] entry\n",__FUNCTION__);
+    s_list_buffer_valid = false; 
+}
+
+int is_period_equal_not_valid(int period)
+{
+    return period<=0 || (period > INT_MAX/1000);
+}
+
+void init_data_timer_all()
+{
+    int ret;
+    char tmp[20]={0};
+    char lynq_state_buffer_valid_period[20]={0};
+    struct sigevent sevp;
+    memset(&sevp, 0, sizeof(sevp));
+    sevp.sigev_notify = SIGEV_THREAD;
+    sevp.sigev_notify_function = data_timer_handler;
+    
+    ret = lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "data_list_valid_period", tmp);
+    LYINFLOG("[%s] ret=%d, tmp is %s", __FUNCTION__, ret, tmp);
+    if(ret == 0)
+    {
+        s_state_buffer_valid_period = atoi(tmp);
+        if(is_period_equal_not_valid(s_state_buffer_valid_period))
+        {
+            s_state_buffer_valid_period = DEFAULT_PERIOD;
+            snprintf(lynq_state_buffer_valid_period,sizeof(lynq_state_buffer_valid_period),"%d",DEFAULT_PERIOD);
+            lynq_set_section(LOG_UCI_MODULE, LOG_UCI_MODULE);
+            lynq_set_value(LOG_UCI_MODULE, "data_list_valid_period", lynq_state_buffer_valid_period);
+        }
+    }
+    else 
+    {
+        s_state_buffer_valid_period = DEFAULT_PERIOD;
+        snprintf(lynq_state_buffer_valid_period,sizeof(lynq_state_buffer_valid_period),"%d",DEFAULT_PERIOD);
+        lynq_set_section(LOG_UCI_MODULE, LOG_UCI_MODULE);
+        lynq_set_value(LOG_UCI_MODULE, "data_list_valid_period", lynq_state_buffer_valid_period);
+    }
+    LYINFLOG("[%s] s_state_buffer_valid_period = %d\n", __FUNCTION__, s_state_buffer_valid_period);
+    if(timer_create(CLOCK_MONOTONIC, &sevp, &s_list_buffer_timer) == -1) {
+        LYERRLOG("init_data_timer_all()  failed reason=[%s]", strerror(errno));
+    }
+    LYINFLOG("init_data_timer_all(), timer_Id = %ld\n", (long)(s_list_buffer_timer));
+    s_list_buffer_valid = false;
+    return;
+}
+void deinit_data_timer_all()
+{
+    stop_data_timer(s_list_buffer_timer);
+    s_list_buffer_valid = false;
+
+    return;
+}
+
+void set_list_buffer_valid(int valid)
+{
+    LYINFLOG("[%s] entry\n",__FUNCTION__);
+
+    s_list_buffer_valid = valid;
+    if(s_list_buffer_valid==false)
+    {
+        stop_data_timer(s_list_buffer_timer);
+    }
+    else 
+    {
+        start_data_timer(s_list_buffer_timer, s_state_buffer_valid_period*1000);
+    }
+    LYINFLOG("[%s] valid is %d",__FUNCTION__,valid); 
+    return;
+}
+void set_list_to_buf(lynq_data_call_response_v11_t dataCallList[LYNQ_APN_CHANNEL_MAX],int number)
+{
+    int ret;
+    int i;
+
+    LYINFLOG("[%s] entry\n",__FUNCTION__);
+    number_buffer = number;
+    memcpy(dataCallList_buffer, dataCallList, sizeof(lynq_data_call_response_v11_t)*LYNQ_APN_CHANNEL_MAX);
+    set_list_buffer_valid(true);
+
+    return;
+}
+int get_list_from_buf(lynq_data_call_response_v11_t dataCallList[LYNQ_APN_CHANNEL_MAX],int *number)
+{
+    if(s_list_buffer_valid == false)
+    {
+        LYINFLOG("%s buffer not valid",__FUNCTION__);
+        return 1;
+    }
+    *number = number_buffer;
+    memcpy(dataCallList, dataCallList_buffer, sizeof(lynq_data_call_response_v11_t)*LYNQ_APN_CHANNEL_MAX);
+
+    return 0;
+}
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data_list_buffer.h b/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data_list_buffer.h
new file mode 100755
index 0000000..db7b213
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-data/lynq_data_list_buffer.h
@@ -0,0 +1,18 @@
+#ifndef LYNQ_DATA_LIST_BUFFER_H
+#define LYNQ_DATA_LIST_BUFFER_H 
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "lynq_data.h"
+
+void set_list_buffer_valid(int valid);
+void set_list_to_buf(lynq_data_call_response_v11_t dataCallList[LYNQ_APN_CHANNEL_MAX],int number);
+int get_list_from_buf(lynq_data_call_response_v11_t dataCallList[LYNQ_APN_CHANNEL_MAX],int *number);
+void init_data_timer_all();
+void deinit_data_timer_all();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-data/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-data/makefile
index c36e038..a0c3e46 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-data/makefile
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-data/makefile
@@ -30,6 +30,7 @@
 LOCAL_LIBS := \
     -L. \
     -ldl \
+    -lrt \
     -lstdc++ \
     -llog \
     -lcutils \
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
index aabd1ba..aef436c 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
@@ -40,3 +40,6 @@
 config  lynq_led_rw  'lynq_led'

         option lynq_statusled_on '0'

         option lynq_netled_on '0'

+

+config  lynq_data  'lynq_data'

+        option data_list_valid_period '5'

diff --git a/cap/zx297520v3/zxic_code/zxic_source/zxic_app_open/platform/libtinyalsa/audio_mixer_ctrl.c b/cap/zx297520v3/zxic_code/zxic_source/zxic_app_open/platform/libtinyalsa/audio_mixer_ctrl.c
index 1dfa9e2..0ff24e3 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/zxic_app_open/platform/libtinyalsa/audio_mixer_ctrl.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/zxic_app_open/platform/libtinyalsa/audio_mixer_ctrl.c
@@ -379,6 +379,7 @@
 	}
 }
 
+
 static int input_vol_conversion(int vol)
 {
 	switch(vol) {
@@ -785,18 +786,86 @@
 	{"DAC DEM  MUTE", {"0"}},
 };
 
+/* yu.dong@20240627 [T106BUG-615]CODEC 8311 using voice_demo to set codec volume has no effect start */
 
+/*
 static int output_vol_conversion(int vol)
 {
 	return 255;
 
 }
+*/
+
 static int input_vol_conversion(int vol)
 {
 	return 255;
 
 }
- 
+
+enum t_output_vol {
+    T_OUTPUT_VOL_MINUS_96DB = 0,
+    T_OUTPUT_VOL_MINUS_95DB = 2,
+    T_OUTPUT_VOL_MINUS_90DB = 12,
+    T_OUTPUT_VOL_MINUS_85DB = 22,
+    T_OUTPUT_VOL_MINUS_80DB = 32,
+    T_OUTPUT_VOL_MINUS_75DB = 42,
+    T_OUTPUT_VOL_MINUS_70DB = 52,
+    T_OUTPUT_VOL_MINUS_65DB = 62,
+    T_OUTPUT_VOL_MINUS_60DB = 72,
+    T_OUTPUT_VOL_MINUS_55DB = 82,
+    T_OUTPUT_VOL_MINUS_50DB = 92,
+    T_OUTPUT_VOL_MINUS_45DB = 102,
+    T_OUTPUT_VOL_MINUS_40DB = 112,
+    T_OUTPUT_VOL_MINUS_35DB = 122,
+    T_OUTPUT_VOL_MINUS_30DB = 132,
+    T_OUTPUT_VOL_MINUS_25DB = 142,
+    T_OUTPUT_VOL_MINUS_20DB = 152,
+    T_OUTPUT_VOL_MINUS_15DB = 162,
+    T_OUTPUT_VOL_MINUS_10DB = 172,
+    T_OUTPUT_VOL_MINUS_7DB  = 178,
+    T_OUTPUT_VOL_MINUS_6DB  = 180,
+    T_OUTPUT_VOL_MINUS_5DB  = 182,
+    T_OUTPUT_VOL_MINUS_4DB  = 184,
+    T_OUTPUT_VOL_MINUS_3DB  = 186,
+    T_OUTPUT_VOL_MINUS_2DB  = 188,
+    T_OUTPUT_VOL_MINUS_1DB  = 190,
+    T_OUTPUT_VOL_0DB        = 192
+};
+
+ static int output_vol_conversion(int vol)
+{
+    switch(vol){
+    case T_AUDIO_OUTPUT_VOL_LEVEL_0:
+        return T_OUTPUT_VOL_MINUS_96DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_1:
+        return T_OUTPUT_VOL_MINUS_45DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_2:
+        return T_OUTPUT_VOL_MINUS_40DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_3:
+        return T_OUTPUT_VOL_MINUS_35DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_4:
+        return T_OUTPUT_VOL_MINUS_30DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_5:
+        return T_OUTPUT_VOL_MINUS_25DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_6:
+        return T_OUTPUT_VOL_MINUS_20DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_7:
+        return T_OUTPUT_VOL_MINUS_15DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_8:
+        return T_OUTPUT_VOL_MINUS_10DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_9:
+        return T_OUTPUT_VOL_MINUS_6DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_10:
+        return T_OUTPUT_VOL_MINUS_3DB;
+    case T_AUDIO_OUTPUT_VOL_LEVEL_11:
+        return T_OUTPUT_VOL_0DB;
+    default:
+        return T_OUTPUT_VOL_0DB;
+    }
+}
+
+/* yu.dong@20240627 [T106BUG-615]CODEC 8311 using voice_demo to set codec volume has no effect end */
+
 #elif defined _USE_CODEC_ES8374