[Feature][T8TSK-41] config oos recovery timer interval and add timeout mechanism

Change-Id: I7521914a8130c88965b5551fce530ae12f6a6afb
diff --git a/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h b/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h
index 60c4ae2..505fdc9 100755
--- a/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h
+++ b/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h
@@ -3,8 +3,9 @@
 #ifdef __cplusplus

 extern "C" {

 #endif

-

+#define MODEM_GEN97 1

 #define CELLINFO_MAX_NUM  10

+#define LY_RECOVER_TIMER_INTERVAL 128

 /*T800 platform support gsm,wcdma lte,nr */

 typedef struct{

     int gw_sig_valid; /*1 valid,1 invalid*/

@@ -70,7 +71,41 @@
 int lynq_set_ims(const int ims_mode);

 int lynq_wait_signalchanges(int *handle);

 int lynq_get_urc_info(const int handle,signalStrength_t *solSigStren,int *slot_id);

+#ifdef MODEM_GEN97

+/**@brief set or get OOS recover timer interval

+* @param mode [IN] <mode>:

+*  0:set

+*  1:get

+* @param interval [IN] <interval>: the recovery timer interval.

+*  field:

+*    T1,T2,...,T23:integer value 0~0xFFFFFFFF

+*    The length of time in seconds.

+*    defualt interval: 20,20,60,60,60,60,90,90,90,90,90,90,180,180,180,180,180,180,360,360,360,360,360

+* @param result [OUT] <result>: the recovery timer interval,when the mode is 1, this parameter is valid.

 

+* @return

+*  0:success

+*  other:failure

+*/

+int lynq_oos_recover_timer_interval(int mode, char interval[LY_RECOVER_TIMER_INTERVAL],char result[LY_RECOVER_TIMER_INTERVAL]);

+/**@brief set deep sleep recover timer interval

+

+* @param recovery_threshold [IN] <recovery_threshold>: valid range 2-10  //After performing several rounds of normal recovery, deep sleep mode optimization will be applied

+

+* @param fullband_timer [IN] <fullband_timer>:valid range 90-360 //fullband intervarl length in deep sleep mode

+

+* @param sniffer_timer [IN] <sniffer_timer>:valid range 10-60 // sniffe intervarl length in deep sleep mode.

+

+* @param inactive_mode [IN] <inactive_mode>:

+*  0 Exit inactive mode 

+*  1 enter inactive mode

+

+* @return

+*  0:success

+*  other:failure

+*/

+int lynq_oos_deep_sleep_recover_timer_interval(int recovery_threshold,int fullband_timer,int sniffer_timer,int inactive_mode);

+#endif

 #ifdef __cplusplus

 }

 #endif

diff --git a/src/lynq/lib/liblynq-network/lynq_network.cpp b/src/lynq/lib/liblynq-network/lynq_network.cpp
index 90ded4b..3b092e8 100755
--- a/src/lynq/lib/liblynq-network/lynq_network.cpp
+++ b/src/lynq/lib/liblynq-network/lynq_network.cpp
@@ -93,6 +93,67 @@
     LYNQ_E_NULL_ANONALY=9001

 }LYNQ_E;

 

+

+/**@brief get response and write msg to parcel

+* @param p [IN] <p>: the parcel

+*

+* @param time_out [IN] <time_out>: timeout.

+*  < 0:use defult timeout(5s)

+*  >=0:use this timeout

+* @return

+*  0:success

+*  other:failure

+*/

+int get_response(Parcel &p,int time_out)

+{

+    int len = 0;
+    char recvline[LYNQ_REC_BUF];
+    bzero(recvline,LYNQ_REC_BUF);

+    LYINFLOG("get response");

+    /* receive data from server */

+    struct timeval timeOut;

+    timeOut.tv_sec = 5;    //defualt 5s

+    timeOut.tv_usec = 0;

+    if(time_out >= 0)

+    {

+        LYINFLOG("use time out %d",time_out);

+        timeOut.tv_sec = time_out;    //just set second

+    }

+    if(setsockopt(network_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)

+    {

+        LYERRLOG("time out setting failed");

+        return -1;

+    }

+    len = recvfrom(network_sock_fd,recvline,sizeof(recvline),0,(struct sockaddr *)&network_addr_serv,(socklen_t *)&network_len_addr_serv);

+    if(len == -1 && errno == EAGAIN)

+    {

+        LYERRLOG("read error,maybe timeout: %s",strerror(errno));

+        return LYNQ_E_TIME_OUT;

+    }
+    if (recvline != NULL) 

+    {

+        p.setData((uint8_t *)recvline,len); // p.setData((uint8_t *) buffer, buflen);
+        p.setDataPosition(0);
+    }
+    return 0;
+}
+int JumpHeader(Parcel &p,int *resp_type,int *request,int *slot_id,int *error)
+{

+    LYINFLOG("jump header");

+    if(p.dataAvail() > 0)
+    {
+        p.readInt32(resp_type);
+        p.readInt32(request);
+        p.readInt32(slot_id);
+        p.readInt32(error);
+        return 0;
+    }
+    else
+    {
+        return -1;
+    }
+}

+

 int wait_signal_changes()

 {

     int ret = 0;

@@ -232,12 +293,21 @@
 

 int lynq_server_socket_start()

 {

+    struct timeval timeOut;

     network_sock_fd = socket(AF_INET, SOCK_DGRAM, 0);

     if(-1 == network_sock_fd)

     {

         LYERRLOG("socket open error");

         return -1;

     }

+

+    timeOut.tv_sec = 5;

+    timeOut.tv_usec = 0;

+    if (setsockopt(network_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)

+    {

+        LYERRLOG("time out setting failed\n");

+        return -1;

+    }

     LYINFLOG("network_sock_fd = %d",network_sock_fd);

 

     memset(&network_addr_serv, 0, sizeof(network_addr_serv));

@@ -245,6 +315,8 @@
     network_addr_serv.sin_addr.s_addr = inet_addr(LYNQ_ADDRESS);

     network_addr_serv.sin_port = htons(LYNQ_SERVICE_PORT);

     network_len_addr_serv = sizeof(network_addr_serv);

+

+

     return 0;

 }

 

@@ -1476,3 +1548,268 @@
     }

     return 0;

 }

+

+/**@brief parse at response,return error code,and the response

+* @param response [IN] <response>:original at response,This parameter must be a character array.

+

+* @param value [OUT] <value>: Used to receive the parsed value, if multiple values are separated by ";".

+*  field:

+*    eg:

+*       "+cnum: 123456\n+cnum: 456"

+*       value:12345;456;

+* @param value_len [IN] <value_len>: The value length.

+

+* @return:AT error code

+*/

+static int parse_at_result(char response[],char value[],int value_len)

+{

+    if(response == NULL || value == NULL)

+    {

+        LYERRLOG("parameter invalid");

+        return -1;

+    }

+    if(strstr(response,"ERROR"))

+    {

+        int i;

+        for(i = 0;i < strlen(response);i++)

+        {

+            if(response[i]==':')

+            {

+                break;

+            }

+        }

+        if(i < strlen(response))

+        {

+            LYINFLOG("parse_result:%d\n",atoi(response+i+1));

+            return atoi(response+i+1);

+        }

+        else

+        {

+            LYINFLOG("%s parse_result:fail,this response invalid\n",response);

+            return 100; //unknown

+        }

+    }

+    else if(strstr(response,"OK"))

+    {

+        /** parse the at response value

+        * eg:

+        * --> at+cnum

+        * <-- +CNUM:"1243452"

+        * need parse the "1243452" to <value>

+        *@  To-Do

+        */

+        int count;

+        int resp_addr[32] = {0};

+        char temp_buf[1024] = {0};

+        char *dest;

+        dest = NULL;

+        count = 0;

+        int res_len = strlen(response);

+        LYINFLOG("res_len:%d",res_len);

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

+        {

+            if(response[i]==':')

+            {

+                resp_addr[count] = i;

+                count++;

+            }

+            if(response[i] == '\n')

+            {

+                response[i] = '\0';

+            }

+        }

+        LYINFLOG("count:%d",count);

+        if(count > 0)

+        {

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

+            {

+                if((strlen(temp_buf) + strlen(response+resp_addr[i]+2)) >= 1023)

+                {

+                    LYINFLOG("2 will be out of range\n");

+                    break;

+                }

+                if(strlen(temp_buf) >= 1023)

+                {

+                    LYINFLOG("1 will be out of range\n");

+                    break;

+                }

+                strcat(temp_buf,response+resp_addr[i]+2);

+

+                if(strlen(temp_buf) >= 1023)

+                {

+                    LYINFLOG("1 will be out of range\n");

+                    break;

+                }

+                strcat(temp_buf,";");

+                printf("parse_result[%d]:%s,strcated:%s\n",i,response+resp_addr[i]+2,temp_buf);

+            }

+            LYINFLOG("parse_result:%s\n",temp_buf);

+            if(strlen(temp_buf) > value_len)

+            {

+                printf("result length over value:%ld,%d\n",strlen(temp_buf),value_len);

+                memcpy(value,temp_buf,value_len);

+            }

+            else

+            {

+                memcpy(value,temp_buf,strlen(temp_buf));

+            }

+        }

+        return 0;

+    }

+    else

+    {

+        LYINFLOG("%s this response invalid\n",response);

+        return -1;

+    }

+}

+#ifdef MODEM_GEN97

+

+int lynq_oos_recover_timer_interval(int mode, char interval[LY_RECOVER_TIMER_INTERVAL],char result[LY_RECOVER_TIMER_INTERVAL])

+{

+    int ret;

+    int send_num;

+    int recv_len;

+    Parcel p;

+    char res_data[LY_RECOVER_TIMER_INTERVAL] = {0};

+    lynq_client_t client_t;

+    char response_interval[LY_RECOVER_TIMER_INTERVAL*2] = {0};

+

+    ret = -1;

+    send_num = -1;

+    recv_len = -1;

+

+    LYINFLOG("lynq_oos_recover_timer_interval start");

+    if((mode < 0) || (mode >1) || (NULL == interval) || (NULL == result))

+    {

+        LYERRLOG("lynq_oos_recover_timer_interval paramter fail!!!");

+        return ret;

+    }

+

+    memset(&client_t,0,sizeof(client_t));

+    client_t.request = RIL_REQUEST_OEM_HOOK_RAW;    //LYNQ_REQUEST_OOS_RECOVER_TIMER_INTERVAL

+    client_t.paramLen = 1;

+    client_t.uToken = network_Global_uToken;

+    if(mode == 0)

+    {

+        sprintf(client_t.param,"AT+ERSCFG=%s",interval);

+    }

+    else

+    {

+        sprintf(client_t.param,"AT+ERSCFG?",interval);

+    }

+    pthread_mutex_lock(&g_lynq_network_sendto_mutex);

+    send_num = sendto(network_sock_fd,&client_t,sizeof(client_t),0,(struct sockaddr *)&network_addr_serv,network_len_addr_serv);

+    if(send_num < 0)

+    {

+        LYERRLOG("sendto error:%s",strerror(errno));

+        return ret;

+    }

+    ret = get_response(p,-1);    //use defualt time (5s)

+    if(ret != 0)

+    {

+        return ret;

+    }

+    JumpHeader(p, &response.resp_type, &response.request, &response.slot_id, &response.error);

+    LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",response.resp_type, response.request, response.slot_id, response.error);

+    if(0 == response.error)

+    {

+        pthread_mutex_unlock(&g_lynq_network_sendto_mutex);

+        LYINFLOG("get recover timer interval");

+        p.readInt32(&recv_len);

+        if(recv_len == -1)

+        {

+            LYINFLOG("no responset");

+            return -1;

+        }

+        else

+        {

+            LYINFLOG("recv_len:%d",recv_len);

+            p.read(response_interval,recv_len);

+        }

+        LYINFLOG("response_interval:%s",response_interval);

+        ret = parse_at_result(response_interval,res_data,LY_RECOVER_TIMER_INTERVAL);

+        if(mode == 1)

+        {

+            if(strlen(res_data) <= LY_RECOVER_TIMER_INTERVAL)

+            {

+                memcpy(result,res_data,strlen(res_data));

+            }

+        }

+        LYINFLOG("ret:%d",ret);

+        return ret;

+    }

+    else

+    {

+        pthread_mutex_unlock(&g_lynq_network_sendto_mutex);

+        return response.error;

+    }

+}

+

+int lynq_oos_deep_sleep_recover_timer_interval(int recovery_threshold,int fullband_timer,int sniffer_timer,int inactive_mode)

+{

+    int ret;

+    int send_num;

+    int recv_len;

+    Parcel p;

+    char res_data[LY_RECOVER_TIMER_INTERVAL] = {0};

+    lynq_client_t client_t;

+    char response_interval[LY_RECOVER_TIMER_INTERVAL*2] = {0};

+

+    ret = -1;

+    send_num = -1;

+    recv_len = -1;

+

+    LYINFLOG("lynq_oos_deep_sleep_recover_timer_interval start");

+    if(((recovery_threshold < 2) || (recovery_threshold > 10)) || ((fullband_timer < 90) || (fullband_timer > 360)) || 

+    ((sniffer_timer < 10) || (sniffer_timer > 60)) || ((inactive_mode < 0) || (inactive_mode > 1)))

+    {

+        LYERRLOG("lynq_oos_deep_sleep_recover_timer_interval paramter fail!!!");

+        return ret;

+    }

+

+    memset(&client_t,0,sizeof(client_t));

+    client_t.request = RIL_REQUEST_OEM_HOOK_RAW;    //LYNQ_REQUEST_OOS_DEEP_SLEEP_RECOVER_TIMER_INTERVAL

+    client_t.paramLen = 1;

+    client_t.uToken = network_Global_uToken;

+    sprintf(client_t.param,"AT+ESRVREC=%d,%d,%d,%d",recovery_threshold,fullband_timer,sniffer_timer,inactive_mode);

+    pthread_mutex_lock(&g_lynq_network_sendto_mutex);

+    send_num = sendto(network_sock_fd,&client_t,sizeof(client_t),0,(struct sockaddr *)&network_addr_serv,network_len_addr_serv);

+    if(send_num<0)

+    {

+        LYERRLOG("sendto error:%s",strerror(errno));

+        return ret;

+    }

+    ret = get_response(p,-1);    //use defualt time (5s)

+    if(ret != 0)

+    {

+        return ret;

+    }

+    JumpHeader(p, &response.resp_type, &response.request, &response.slot_id, &response.error);

+    LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",response.resp_type, response.request, response.slot_id, response.error);

+    if(0 == response.error)

+    {

+        pthread_mutex_unlock(&g_lynq_network_sendto_mutex);

+        LYINFLOG("set deep sleep recover timer interval response");

+        p.readInt32(&recv_len);

+        if(recv_len == -1)

+        {

+            LYINFLOG("no responset");

+            return -1;

+        }

+        else

+        {

+            LYINFLOG("recv_len:%d",recv_len);

+            p.read(response_interval,recv_len);

+        }

+        LYINFLOG("response_interval:%s",response_interval);

+        ret = parse_at_result(response_interval,res_data,LY_RECOVER_TIMER_INTERVAL);

+        return ret;

+    }

+    else

+    {

+        pthread_mutex_unlock(&g_lynq_network_sendto_mutex);

+        return response.error;

+    }

+}

+#endif

+