Fix auto data call for ril v2

Change-Id: I753b1c8ac7bcbeabd316734b54b4e79224537dea
diff --git a/mbtk/include/mbtk/mbtk_file.h b/mbtk/include/mbtk/mbtk_file.h
index 6d17fa1..e3924eb 100755
--- a/mbtk/include/mbtk/mbtk_file.h
+++ b/mbtk/include/mbtk/mbtk_file.h
@@ -69,4 +69,21 @@
 // Close file.
 int file_close(int fd);
 
+/*===========================================================================
+FUNCTION file_link()
+
+DESCRIPTION:
+  Create soft link.
+
+PARAMETERS:
+  oldpath [IN]: Local original file,it may not exist.
+  newpath [IN]: Soft link file. If the file exists, it will be replaced.
+
+RETURN VALUE:
+  Return 0 if success,other for error.
+
+===========================================================================*/
+int file_link(const void* oldpath, const void* newpath);
+
+
 #endif /* _MBTK_FILE_H */
diff --git a/mbtk/include/mbtk/mbtk_ril_api.h b/mbtk/include/mbtk/mbtk_ril_api.h
index 5315ab1..bd4c7f4 100755
--- a/mbtk/include/mbtk/mbtk_ril_api.h
+++ b/mbtk/include/mbtk/mbtk_ril_api.h
@@ -598,6 +598,9 @@
     uint16 action;
     uint16 reason;
     uint16 auto_change;
+
+    uint16 ip_info_valid;
+    mbtk_ip_info_t ip_info;
 } mbtk_ril_pdp_state_info_t;
 
 typedef enum {
diff --git a/mbtk/libmbtk_lib/common/mbtk_file.c b/mbtk/libmbtk_lib/common/mbtk_file.c
index 44f3954..235ccd2 100755
--- a/mbtk/libmbtk_lib/common/mbtk_file.c
+++ b/mbtk/libmbtk_lib/common/mbtk_file.c
@@ -126,3 +126,73 @@
     }
     return result;
 }
+
+/*===========================================================================
+FUNCTION file_link()
+
+DESCRIPTION:
+  Create soft link.
+
+PARAMETERS:
+  oldpath [IN]: Local original file,it may not exist.
+  newpath [IN]: Soft link file. If the file exists, it will be replaced.
+
+RETURN VALUE:
+  Return 0 if success,other for error.
+
+===========================================================================*/
+int file_link(const void* oldpath, const void* newpath)
+{
+    if(oldpath == NULL || newpath == NULL) {
+        LOGE("File not be NULL.");
+        return -1;
+    }
+
+    struct stat file_stat;
+    int ret = lstat((const char*)newpath, &file_stat);
+    if (ret) {
+        if (errno != ENOENT) {
+            LOGE("lstat(%s) fail:%d", (char*)newpath, errno);
+            return -1;
+        }
+
+        // Link file not exist, Create link file directly.
+    } else {
+        if (S_ISLNK(file_stat.st_mode)) {
+            // The file is a symbolic link
+            char buf[1024] = {0};
+            ssize_t len = readlink((char*)newpath, buf, sizeof(buf));
+            if (len == -1) {
+                LOGE("Error reading the link file, errno - %d", errno);
+                return -1;
+            }
+            buf[len] = '\0';
+            LOGD("Link target is: %s", buf);
+            if(strcmp(buf, (const char*)oldpath) == 0) {
+                LOGD("The link target is same,do nothing.");
+                return 0;
+            } else {
+                ret = unlink((const char*)newpath);
+                if(ret) {
+                    LOGE("unlink(%s) fail:%d", (char*)newpath, errno);
+                    return -1;
+                }
+
+                // Delete link file success.
+            }
+        } else {
+            LOGE("%s exist,but no link file.", (char*)newpath);
+            return -1;
+        }
+    }
+
+    // Start create link file.
+    ret = symlink((const char*)oldpath, (const char*)newpath);
+    if(ret){
+        LOGE("symlink(%s->%s) fail:%d", (char*)newpath, (const char*)newpath, errno);
+        return -1;
+    } else {
+        LOGE("symlink(%s->%s) success.", (char*)newpath, (const char*)newpath);
+        return 0;
+    }
+}
diff --git a/mbtk/libmbtk_lib_v2/common/mbtk_file.c b/mbtk/libmbtk_lib_v2/common/mbtk_file.c
index 44f3954..235ccd2 100755
--- a/mbtk/libmbtk_lib_v2/common/mbtk_file.c
+++ b/mbtk/libmbtk_lib_v2/common/mbtk_file.c
@@ -126,3 +126,73 @@
     }
     return result;
 }
+
+/*===========================================================================
+FUNCTION file_link()
+
+DESCRIPTION:
+  Create soft link.
+
+PARAMETERS:
+  oldpath [IN]: Local original file,it may not exist.
+  newpath [IN]: Soft link file. If the file exists, it will be replaced.
+
+RETURN VALUE:
+  Return 0 if success,other for error.
+
+===========================================================================*/
+int file_link(const void* oldpath, const void* newpath)
+{
+    if(oldpath == NULL || newpath == NULL) {
+        LOGE("File not be NULL.");
+        return -1;
+    }
+
+    struct stat file_stat;
+    int ret = lstat((const char*)newpath, &file_stat);
+    if (ret) {
+        if (errno != ENOENT) {
+            LOGE("lstat(%s) fail:%d", (char*)newpath, errno);
+            return -1;
+        }
+
+        // Link file not exist, Create link file directly.
+    } else {
+        if (S_ISLNK(file_stat.st_mode)) {
+            // The file is a symbolic link
+            char buf[1024] = {0};
+            ssize_t len = readlink((char*)newpath, buf, sizeof(buf));
+            if (len == -1) {
+                LOGE("Error reading the link file, errno - %d", errno);
+                return -1;
+            }
+            buf[len] = '\0';
+            LOGD("Link target is: %s", buf);
+            if(strcmp(buf, (const char*)oldpath) == 0) {
+                LOGD("The link target is same,do nothing.");
+                return 0;
+            } else {
+                ret = unlink((const char*)newpath);
+                if(ret) {
+                    LOGE("unlink(%s) fail:%d", (char*)newpath, errno);
+                    return -1;
+                }
+
+                // Delete link file success.
+            }
+        } else {
+            LOGE("%s exist,but no link file.", (char*)newpath);
+            return -1;
+        }
+    }
+
+    // Start create link file.
+    ret = symlink((const char*)oldpath, (const char*)newpath);
+    if(ret){
+        LOGE("symlink(%s->%s) fail:%d", (char*)newpath, (const char*)newpath, errno);
+        return -1;
+    } else {
+        LOGE("symlink(%s->%s) success.", (char*)newpath, (const char*)newpath);
+        return 0;
+    }
+}
diff --git a/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c b/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c
index ae35fd4..c102991 100755
--- a/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c
+++ b/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c
@@ -118,7 +118,7 @@
 
 static int ril_ind_process(ril_msg_pack_info_t* pack)
 {
-    LOGD("IND - %d", id2str(pack->msg_id));
+    LOGD("IND - %s", id2str(pack->msg_id));
     if(pack->msg_id > RIL_MSG_ID_IND_BEGIN && pack->msg_id < RIL_MSG_ID_IND_END) {
         if(ril_cli.cb[pack->msg_id - RIL_MSG_ID_IND_BEGIN - 1])
             ril_cli.cb[pack->msg_id - RIL_MSG_ID_IND_BEGIN - 1](pack->data, pack->data_len);
diff --git a/mbtk/libmbtk_lib_v2/ril/ril_utils.c b/mbtk/libmbtk_lib_v2/ril/ril_utils.c
index 6928a1d..b77046f 100755
--- a/mbtk/libmbtk_lib_v2/ril/ril_utils.c
+++ b/mbtk/libmbtk_lib_v2/ril/ril_utils.c
@@ -268,12 +268,78 @@
         // Call Information
         case RIL_MSG_ID_CALL_STATE:
             return "CALL_STATE";
+        case RIL_MSG_ID_CALL_START:
+            return "CALL_START";
+        case RIL_MSG_ID_CALL_ANSWER:
+            return "CALL_ANSWER";
+        case RIL_MSG_ID_CALL_HANGUP:
+            return "CALL_HANGUP";
+        case RIL_MSG_ID_CALL_HANGUP_A:
+            return "CALL_HANGUP_A";
+        case RIL_MSG_ID_CALL_HANGUP_B:
+            return "CALL_HANGUP_B";
+        case RIL_MSG_ID_CALL_HANGUP_C:
+            return "CALL_HANGUP_C";
+        case RIL_MSG_ID_CALL_WAITIN:
+            return "CALL_WAITIN";
+        case RIL_MSG_ID_CALL_MUTE:
+            return "CALL_MUTE";
+        case RIL_MSG_ID_CALL_DTMF:
+            return "CALL_DTMF";
         // SMS Information
         case RIL_MSG_ID_SMS_STATE:
             return "SMS_STATE";
+        case RIL_MSG_ID_SMS_CMGF:
+        	return "SMS_CMGF";
+        case RIL_MSG_ID_SMS_CPMS:
+        	return "SMS_CPMS";
+        case RIL_MSG_ID_SMS_CMGS:
+        	return "SMS_CMGS";
+        case RIL_MSG_ID_SMS_CMSS:
+        	return "SMS_CMSS";
+        case RIL_MSG_ID_SMS_CMGR:
+        	return "SMS_CMGR";
+        case RIL_MSG_ID_SMS_CMGW:
+        	return "SMS_CMGW";
+        case RIL_MSG_ID_SMS_CMGD:
+        	return "SMS_CMGD";
+        case RIL_MSG_ID_SMS_CMGL:
+        	return "SMS_CMGL";
+        case RIL_MSG_ID_SMS_CSCA:
+        	return "SMS_CSCA";
+        case RIL_MSG_ID_SMS_CSMP:
+        	return "SMS_CSMP";
+        case RIL_MSG_ID_SMS_CSCB:
+        	return "SMS_CSCB";
+        case RIL_MSG_ID_SMS_CNMI:
+        	return "SMS_CNMI";
         // PhoneBook Information
         case RIL_MSG_ID_PB_STATE:
             return "PB_STATE";
+        case RIL_MSG_ID_ECALL_MSDCFG:
+            return "ECALL_MSDCFG";
+        case RIL_MSG_ID_ECALL_MSDGEN:
+            return "ECALL_MSDGEN";
+        case RIL_MSG_ID_ECALL_MSD:
+            return "ECALL_MSD";
+        case RIL_MSG_ID_ECALL_PUSH:
+            return "ECALL_PUSH";
+        case RIL_MSG_ID_ECALL_ONLY:
+            return "ECALL_ONLY";
+        case RIL_MSG_ID_ECALL_REG:
+            return "ECALL_REG";
+        case RIL_MSG_ID_ECALL_DIAL:
+            return "ECALL_DIAL";
+        case RIL_MSG_ID_ECALL_MODE:
+            return "ECALL_MODE";
+        case RIL_MSG_ID_ECALL_CFG:
+            return "ECALL_CFG";
+        case RIL_MSG_ID_ECALL_SMS_NUM:
+            return "ECALL_SMS_NUM";
+        case RIL_MSG_ID_ECALL_MUTESPK:
+            return "ECALL_MUTESPK";
+        case RIL_MSG_ID_ECALL_DSP_GAIN:
+            return "ECALL_DSP_GAIN";
         // IND Information
          // <uint8>  State
         case RIL_MSG_ID_IND_SER_STATE_CHANGE:
@@ -299,6 +365,8 @@
         // <uint8>  State
         case RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE:
             return "IND_SIGNAL_STATE";
+        case RIL_MSG_ID_IND_ECALL_STATE_CHANGE:
+            return "IND_ECALL_STATE_CHANGE";
         default:
         {
             return "UNKNOWN";
diff --git a/mbtk/mbtk_rild_v2/src/atchannel.c b/mbtk/mbtk_rild_v2/src/atchannel.c
index 8a19159..f959a59 100755
--- a/mbtk/mbtk_rild_v2/src/atchannel.c
+++ b/mbtk/mbtk_rild_v2/src/atchannel.c
@@ -478,11 +478,11 @@
             /* read error encountered or EOF reached */
             if(count == 0)
             {
-                LOGD("atchannel: EOF reached");
+                LOGD("atchannel[Port-%d]: EOF reached", port);
             }
             else
             {
-                LOGD("atchannel: read error %s", strerror(errno));
+                LOGD("atchannel[Port-%d]: read error %s", port, strerror(errno));
             }
             return NULL;
         }
@@ -495,11 +495,11 @@
     s_ATBufferCur[port] = p_eol + 1; /* this will always be <= p_read,    */
     /* and there will be a \0 at *p_read */
 
-    LOGD("AT< %s", ret);
+    LOGD("[Port-%d]AT< %s", port, ret);
     return ret;
 }
 
-static const char *readlineUrc()
+static const char *readlineUrc(ATPortType_enum port)
 {
     ssize_t count;
 
@@ -597,7 +597,7 @@
     s_UartBufferCur = p_eol + 1; /* this will always be <= p_read,    */
     /* and there will be a \0 at *p_read */
 
-    LOGD("URC< %s", ret);
+    LOGD("[Port-%d]URC< %s", port, ret);
     return ret;
 }
 
@@ -641,6 +641,8 @@
 
         if (line == NULL)
         {
+            //usleep(50000);
+            //continue;
             break;
         }
 
@@ -697,7 +699,7 @@
     {
         const char *line;
 
-        line = readlineUrc();
+        line = readlineUrc(*port);
 
         if (line == NULL)
         {
@@ -733,7 +735,7 @@
         return AT_ERROR_CHANNEL_CLOSED;
     }
 
-    LOGD("AT> %s", s);
+    LOGD("[Port-%d]AT> %s", port, s);
 
     AT_DUMP( ">> ", s, strlen(s) );
 
@@ -865,12 +867,14 @@
         return -1;
     }
 
-    pthread_t uart_tid_reader;
-    ret = pthread_create(&uart_tid_reader, &attr, readerUrcLoop, urc_port_ptr);
-    if (ret < 0)
-    {
-        LOGE("Uart thread create fail.");
-        return -1;
+    if(port == ATPORTTYPE_0) { // URC only for ATPORTTYPE_0
+        pthread_t uart_tid_reader;
+        ret = pthread_create(&uart_tid_reader, &attr, readerUrcLoop, urc_port_ptr);
+        if (ret < 0)
+        {
+            LOGE("Uart thread create fail.");
+            return -1;
+        }
     }
 
     return 0;
diff --git a/mbtk/mbtk_rild_v2/src/main.c b/mbtk/mbtk_rild_v2/src/main.c
index 34d5656..0068bd3 100755
--- a/mbtk/mbtk_rild_v2/src/main.c
+++ b/mbtk/mbtk_rild_v2/src/main.c
@@ -1,3 +1,25 @@
+/*

+*    main.c

+*

+*    mbtk_rild main file.

+*

+* The main functions are as follows:

+* 1. Execute boot script /etc/init.d/mbtk_boot_server_ready after AT is ready(Only execute one time).

+* 2. Execute boot script /etc/init.d/mbtk_boot_net_ready after network is ready(Only execute one time).

+* 3. Set the frequency band based on the relevant information in the "device_info" partition.

+* 4. Create socket server(The client implementation in API).

+* 5. Create 3 connections between atcmdsrv, related devices: /tmp/atcmd_at ,

+*                           /tmp/atcmd_at_1 , /tmp/atcmd_at_2

+*/

+/******************************************************************************

+

+                          EDIT HISTORY FOR FILE

+

+  WHEN        WHO       WHAT,WHERE,WHY

+--------    --------    -------------------------------------------------------

+2024/08/13     LiuBin      Initial version

+

+******************************************************************************/

 #include <stdio.h>

 #include <stdlib.h>

 #include <unistd.h>

@@ -31,6 +53,7 @@
 #include "mbtk_ril.h"

 #include "mbtk_str.h"

 #include "mbtk_queue.h"

+#include "mbtk_file.h"

 

 #ifndef TEMP_FAILURE_RETRY

 #define TEMP_FAILURE_RETRY(exp) ({         \

@@ -57,6 +80,7 @@
 static mbtk_ril_call_state_info_t call_list[RIL_CALL_NUM_MAX];

 extern mbtk_cell_pack_info_t cell_info;

 extern ril_cgact_wait_t cgact_wait;

+extern int ril_cid_start;

 

 // int urc_msg_distribute(bool async_process, info_urc_msg_id_enum msg, void *data, int data_len);

 // int mbtk_signal_log(char *data);

@@ -80,6 +104,8 @@
 {

     LOGI("AT channel timeout; closing\n");

     at_close(ATPORTTYPE_0);

+    at_close(ATPORTTYPE_1);

+    at_close(ATPORTTYPE_2);

 }

 

 /* Called on command or reader thread */

@@ -87,6 +113,8 @@
 {

     LOGI("AT channel closed\n");

     at_close(ATPORTTYPE_0);

+    at_close(ATPORTTYPE_1);

+    at_close(ATPORTTYPE_2);

 }

 

 static void sock_cli_free_func(void *data)
@@ -99,6 +127,23 @@
     }
 }

 

+bool asr_auto_data_call_enable()

+{

+    /*

+    uci show wan_default.default.enable

+    wan_default.default.enable='1'

+

+    uci get wan_default.default.enable

+    1

+    */

+    char buff[128] = {0};

+    if(mbtk_cmd_line("uci get wan_default.default.enable", buff, sizeof(buff)) && strlen(buff) > 0) {

+        return buff[0] == '1' ? TRUE : FALSE;

+    } else {

+        return FALSE;

+    }

+}

+

 /*

 * Will exec mbtk_boot_server_ready and mbtk_boot_net_ready if is_first_boot is true.

 */

@@ -294,7 +339,7 @@
     }
 }

 

-static void ril_state_change(ril_msg_id_enum msg_id, const void *data, int data_len)

+void ril_state_change(ril_msg_id_enum msg_id, const void *data, int data_len)

 {
     sock_cli_info_t *cli = NULL;

     list_first(ril_info.sock_client_list);

@@ -316,7 +361,16 @@
 {

     // Send urc msg to client.

     if(msg_id > RIL_MSG_ID_IND_BEGIN && msg_id < RIL_MSG_ID_IND_END) {

-        ril_state_change(msg_id, data, data_len);

+        if(msg_id == RIL_MSG_ID_IND_PDP_STATE_CHANGE) {

+            mbtk_ril_pdp_state_info_t *info = (mbtk_ril_pdp_state_info_t*)data;

+            if(info->action && !info->ip_info_valid) {

+                LOGD("PDP action but no IP information, not send.");

+            } else {

+                ril_state_change(msg_id, data, data_len);

+            }

+        } else {

+            ril_state_change(msg_id, data, data_len);

+        }

     }

 

     // Async process urc msg.

@@ -350,7 +404,7 @@
     memset(&state, 0, sizeof(mbtk_ril_sim_state_info_t));

     state.sim_type = MBTK_UNKNOWN;

 

-    char* tmp_s = memdup(s,strlen(s));

+    char* tmp_s = memdup(s,strlen(s) + 1);

     char *line = tmp_s;

     int tmp_int;

     char *tmp_str;

@@ -459,7 +513,7 @@
         state.sim_type = ril_info.sim_type;

         ril_info.sim_state = state.sim_state;

 

-        urc_msg_distribute(false, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));

+        urc_msg_distribute(true, RIL_MSG_ID_IND_SIM_STATE_CHANGE, &state, sizeof(mbtk_ril_sim_state_info_t));

     } else if(strStartsWith(s, "*EUICC:")){

         if (at_tok_start(&line) < 0)

         {

@@ -483,7 +537,7 @@
 // +CPAS: 4

 static void urc_call_state_change_process(const char *s, const char *sms_pdu)

 {

-    char* tmp_s = memdup(s,strlen(s));

+    char* tmp_s = memdup(s,strlen(s) + 1);

     char *line = tmp_s;

     int tmp_int;

     char *tmp_str;

@@ -598,7 +652,7 @@
     mbtk_ril_ecall_state_info_t ecall_state;

     memset(&ecall_state, 0, sizeof(mbtk_ril_ecall_state_info_t));

 

-    char* tmp_s = memdup(s,strlen(s));

+    char* tmp_s = memdup(s,strlen(s) + 1);

     char *line = tmp_s;

     int tmp_int;

     char *tmp_str;

@@ -653,7 +707,7 @@
         state.type = MBTK_NET_REG_TYPE_DATA_LTE;

     }

 

-    char* tmp_s = memdup(s,strlen(s));

+    char* tmp_s = memdup(s,strlen(s) + 1);

     char *line = tmp_s;

     int tmp_int;

     char *tmp_str;

@@ -672,14 +726,17 @@
         {

             goto CGREG_EXIT;

         }

+

         if (at_tok_nextstr(&line, &tmp_str) < 0)

         {

             goto CGREG_EXIT;

         }

+

         if (at_tok_nextint(&line, &tmp_int) < 0)

         {

             goto CGREG_EXIT;

         }

+

         state.tech = (mbtk_radio_technology_enum)tmp_int; // AcT

     }

 

@@ -1025,7 +1082,7 @@
         if(cell_info.running) {

             int tmp_int;

             int i = 0;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1122,7 +1179,7 @@
         // phyCellId,euArfcn,rsrp,rsrq

         if(cell_info.running) {

             int tmp_int;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1212,7 +1269,7 @@
         if(cell_info.running) {

             int tmp_int;

             int i = 0;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1296,7 +1353,7 @@
         if(cell_info.running) {

             int tmp_int;

             int i = 0;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1349,7 +1406,7 @@
         if(cell_info.running) {

             int tmp_int;

             int i = 0;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1425,7 +1482,7 @@
         if(cell_info.running) {

             int tmp_int;

             int i = 0;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1538,7 +1595,7 @@
         if(cell_info.running) {

             int tmp_int;

             int i = 0;

-            char* tmp_s = memdup(s,strlen(s));

+            char* tmp_s = memdup(s,strlen(s) + 1);

             char* free_ptr = tmp_s;

             char *line = tmp_s;

             if (at_tok_start(&line) < 0)

@@ -1637,7 +1694,7 @@
 

 static void onUnsolicited(const char *s, const char *sms_pdu)

 {

-    LOGD("URC : %s", s);

+    LOGV("URC : %s", s);

     // MBTK_AT_READY

     if (strStartsWith(s, "MBTK_AT_READY")) // AT ready.

     {

@@ -2207,6 +2264,17 @@
             LOGD("Radio state : %d", state->radio_state);

             break;
         }

+        case RIL_MSG_ID_IND_SIM_STATE_CHANGE:

+        {

+            mbtk_ril_sim_state_info_t *state = (mbtk_ril_sim_state_info_t*)msg->data;

+            if(state->sim_state == MBTK_SIM_STATE_READY) {

+                LOGD("SIM READY!");

+                at_send_command(ATPORTTYPE_0, "AT+COPS=3", NULL);

+

+                // Set APN from prop.

+                apn_auto_conf_from_prop(ATPORTTYPE_0);

+            }

+        }

         case RIL_MSG_ID_IND_NET_REG_STATE_CHANGE:

         {

             mbtk_ril_net_reg_state_info_t *reg_state = (mbtk_ril_net_reg_state_info_t*)msg->data;

@@ -2380,9 +2448,9 @@
     {
         if(mbtk_queue_empty(&(ril_info.msg_queue[*port])))

         {
-            LOG("[Port - %d]Packet process wait...", *port);

+            LOG("[Port-%d]Packet process wait...", *port);

             pthread_cond_wait(&(ril_info.msg_cond[*port]), &(ril_info.msg_mutex[*port]));

-            LOG("[Port - %d]Packet process continue...", *port);

+            LOG("[Port-%d]Packet process continue...", *port);

         }
         else
         {
@@ -2584,15 +2652,15 @@
         LOGE("pthread_create() fail.");

         goto error;
     }

-
+

     ATPortType_enum *port_2 = (ATPortType_enum*)malloc(sizeof(ATPortType_enum));

     *port_2 = ATPORTTYPE_2;

     if(pthread_create(&pack_pid, &thread_attr, ril_process_thread, port_2))

-    {

+    {
         LOGE("pthread_create() fail.");

-        goto error;

+        goto error;
     }

-

+
     // Set Band
     // AT*BAND=15,78,147,482,134742231
     char buff[10];
@@ -2606,9 +2674,30 @@
         }
     }
 
-    pthread_attr_destroy(&thread_attr);
+    pthread_attr_destroy(&thread_attr);

+

+    if(asr_auto_data_call_enable()) {

+        ril_cid_start = MBTK_RIL_CID_2;

+

+        char def_cid[10] = {0};

+        char prop_data[100] = {0};

+        int cid = -1;

+        sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);   // Default route and DNS is CID 1.

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

+        if(property_get(MBTK_DEF_DNS_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {

+            cid = atoi(prop_data);

+        }

+

+        if(cid == MBTK_RIL_CID_DEF) {

+            if(file_link("/tmp/resolv.conf", "/etc/resolv.conf")) {

+                LOGE("Create link file fail.");

+            }

+        }

+    } else {

+        ril_cid_start = MBTK_RIL_CID_DEF;

+    }

 
-    LOGD("MBTK Ril Server Start...");

+    LOGD("MBTK Ril Server Start[CID start with : %d]...", ril_cid_start);

 
     return 0;
 error:

diff --git a/mbtk/mbtk_rild_v2/src/ril_data_call.c b/mbtk/mbtk_rild_v2/src/ril_data_call.c
index 210141b..9cb630a 100755
--- a/mbtk/mbtk_rild_v2/src/ril_data_call.c
+++ b/mbtk/mbtk_rild_v2/src/ril_data_call.c
@@ -1,3 +1,22 @@
+/*
+*    ril_data_call.c
+*
+*  Implementation of APN and Data Call related functions.
+*
+*  The general structure is as follows:
+*    API --- mbtk_rild --- atcmdsrv --- modem
+*
+*/
+/******************************************************************************
+
+                          EDIT HISTORY FOR FILE
+
+  WHEN        WHO       WHAT,WHERE,WHY
+--------    --------    -------------------------------------------------------
+2024/10/10    LiuBin     Initial version
+2024/11/13    LiuBin     Add auto data call while network changed.
+
+******************************************************************************/
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -20,9 +39,12 @@
 #include "ril_info.h"
 #include "mbtk_ifc.h"
 #include "mbtk_str.h"
+#include "mbtk_file.h"
 
 ril_cgact_wait_t cgact_wait;
 static ril_data_call_info_t info_list[MBTK_APN_CID_MAX];
+int ril_cid_start = MBTK_APN_CID_MIN;
+
 
 static int req_apn_get(ATPortType_enum port, bool get_def_cid, mbtk_apn_info_array_t *apns, int *cme_err);
 static int req_apn_set(ATPortType_enum port, mbtk_apn_info_t *apn, int *cme_err);
@@ -30,6 +52,8 @@
 void ril_rsp_pack_send(ATPortType_enum port, int fd, int ril_id, int msg_index, const void* data, int data_len);
 static int req_data_call_start(ATPortType_enum port, mbtk_ril_cid_enum cid, int *cme_err);
 static int req_data_call_state_get(ATPortType_enum port, mbtk_ril_cid_enum cid, mbtk_ip_info_t *ip_info, int *cme_err);
+void ril_state_change(ril_msg_id_enum msg_id, const void *data, int data_len);
+bool asr_auto_data_call_enable();
 
 /*
 IPv4 : 10.255.74.26
@@ -52,6 +76,19 @@
     }
 }
 
+static int dns_cid_get()
+{
+    int cid = MBTK_RIL_CID_DEF;
+    char def_cid[10] = {0};
+    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);   // Default route and DNS is CID 1.
+    char buffer[20] = {0};
+    if(property_get(MBTK_DEF_DNS_CID, buffer, def_cid) > 0 && !str_empty(buffer)) {
+        cid = atoi(buffer);
+    }
+
+    return cid;
+}
+
 static void net_if_as_def_route(mbtk_ril_cid_enum cid)
 {
     if(cid != MBTK_RIL_CID_NUL) {
@@ -64,6 +101,8 @@
         memset(buf, 0, sizeof(buf));
         sprintf(buf, "route add default dev ccinet%d", cid - 1);
         mbtk_system(buf);
+
+        LOGD("Add CID %d to default route.", cid);
     }
 }
 
@@ -115,22 +154,45 @@
 
     if(offset > 0)
     {
-        fd = open("/tmp/resolv.conf", O_WRONLY | O_TRUNC);
-        if(fd < 0)
-        {
-            LOGE("/tmp/resolv.conf : open fail.");
-            return -1;
-        }
+        int dns_cid = dns_cid_get();
+        char *dns_file_path = NULL;
 
-        int ret = write(fd, buf, offset);
-        if(ret < 0)
-        {
-            LOGE("/tmp/resolv.conf : write fail.");
-            close(fd);
-            return -1;
-        }
+        // ASR auto data call enable and DNS server not change by MBTK.
+        if(asr_auto_data_call_enable() && dns_cid == MBTK_RIL_CID_DEF) {
+            dns_file_path = "/tmp/resolv.conf";
 
-        close(fd);
+            if(file_link(dns_file_path, "/etc/resolv.conf")) {
+                LOGE("Create link file fail.");
+                return -1;
+            }
+        } else {
+            dns_file_path = "/tmp/mbtk_resolv.conf";
+
+            if(file_link(dns_file_path, "/etc/resolv.conf")) {
+                LOGE("Create link file fail.");
+                return -1;
+            } else {
+                // mbtk_system("chmod 644 /tmp/mbtk_resolv.conf");
+                fd = open(dns_file_path, O_WRONLY | O_TRUNC | O_CREAT, 0644);
+                if(fd < 0)
+                {
+                    LOGE("%s : open fail.", dns_file_path);
+                    return -1;
+                }
+
+                int ret = write(fd, buf, offset);
+                if(ret < 0)
+                {
+                    LOGE("%s : write fail.", dns_file_path);
+                    close(fd);
+                    return -1;
+                }
+
+                LOGD("Update DNS success.");
+                close(fd);
+                // mbtk_system("chmod 444 /tmp/mbtk_resolv.conf");
+            }
+        }
     }
     return 0;
 }
@@ -268,7 +330,6 @@
     }
 }
 
-
 void apn_auto_conf_from_prop(ATPortType_enum port)
 {
     mbtk_apn_info_array_t apns;
@@ -304,19 +365,10 @@
 static bool apn_conf_support(mbtk_ril_cid_enum cid)
 {
     if(cid == MBTK_RIL_CID_DEF) {
-        /*
-        uci show wan_default.default.enable
-        wan_default.default.enable='1'
-
-        uci get wan_default.default.enable
-        1
-        */
-        char buff[128] = {0};
-        if(mbtk_cmd_line("uci get wan_default.default.enable", buff, sizeof(buff)) && strlen(buff) > 0) {
-            return buff[0] == '1' ? FALSE : TRUE;
-        }
+        return !asr_auto_data_call_enable();
+    } else {
+        return TRUE;
     }
-    return TRUE;
 }
 
 static int apn_check_and_cid_reset(ATPortType_enum port, mbtk_apn_info_t *apn)
@@ -326,7 +378,7 @@
         if(apn->cid == MBTK_RIL_CID_NUL)
             return -1;
 
-        if(!apn_conf_support(MBTK_RIL_CID_DEF) && apn->cid == MBTK_RIL_CID_DEF)
+        if(asr_auto_data_call_enable() && apn->cid == MBTK_RIL_CID_DEF)
             return -1;
 
         // The cid no use,so can not delete.
@@ -349,16 +401,10 @@
             return -1;
         }
     } else { // Add or change APN.
-        int start_cid;
-        bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
+        int start_cid = ril_cid_start;;
         mbtk_apn_info_array_t apns;
         int cme_err = MBTK_RIL_ERR_CME_NON;
 
-        if(asr_auto_call_open) {
-            start_cid = MBTK_RIL_CID_2;
-        } else {
-            start_cid = MBTK_APN_CID_MIN;
-        }
         memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
         if(req_apn_get(port, TRUE, &apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
         {
@@ -405,6 +451,17 @@
                 }
             }
 
+            if(apn->cid == MBTK_RIL_CID_1) {
+#if 1
+                apn->auto_boot_call = 0;    // Reset to 0 for CID 1.
+#else
+                if(apn->auto_boot_call) {
+                    LOGE("CID 1 not support auto boot data call(Please open \"wan_default.default.enable\").");
+                    return -1;
+                }
+#endif
+            }
+
             // Is add,the APN can't same.
             if(!is_change) {
                 index = 0;
@@ -425,21 +482,11 @@
 {
     char prop_name[128] = {0};
     char prop_data[1024] = {0};
-    int cid;
+    int cid = ril_cid_start;
     memset(apns, 0, sizeof(mbtk_apn_info_array_t));
-    bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
-
-    // If auto data call is open,the default route is CID 1.
-    if(asr_auto_call_open) {
-        //apns->cid_for_def_route = MBTK_RIL_CID_DEF;
-        //apns->cid_for_def_dns = MBTK_RIL_CID_DEF;
-        cid = MBTK_RIL_CID_2;
-    } else {
-        cid = MBTK_APN_CID_MIN;
-    }
 
     char def_cid[10] = {0};
-    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);
+    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);   // Default route and DNS is CID 1.
     if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
         apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
     }
@@ -490,6 +537,11 @@
             }
             ptr_1++; // Jump ',' to apn
 
+            // Reset auto_boot_call to 0 for CID 1.
+            if(apns->apns[apns->num].cid == MBTK_RIL_CID_1) {
+                apns->apns[apns->num].auto_boot_call = 0;
+            }
+
             char *ptr_2 = strstr(ptr_1, ",");
             if(!ptr_2) {
                 continue;
@@ -563,6 +615,11 @@
         }
         ptr_1++; // Jump ',' to apn
 
+        // Reset auto_boot_call to 0 for CID 1.
+        if(apn->cid == MBTK_RIL_CID_1) {
+            apn->auto_boot_call = 0;
+        }
+
         char *ptr_2 = strstr(ptr_1, ",");
         if(!ptr_2) {
             return -1;
@@ -634,6 +691,11 @@
         }
         ptr_1++; // Jump ',' to apn
 
+        // Reset auto_boot_call to 0 for CID 1.
+        if(cid == MBTK_RIL_CID_1) {
+            apn->auto_boot_call = 0;
+        }
+
         char *ptr_2 = strstr(ptr_1, ",");
         if(!ptr_2) {
             return -1;
@@ -666,6 +728,7 @@
         if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
             memcpy(apn->type, ptr_2, strlen(ptr_2)); // pass
         }
+
         return 0;
     } else {
         apn->auto_save = (uint8)0;
@@ -679,6 +742,11 @@
     char prop_data[1024] = {0};
     int ret = -1;
     if(apn->auto_save) {
+        // auto_boot_call must be 0 for CID 1.
+        if(apn->cid == MBTK_RIL_CID_1) {
+            apn->auto_boot_call = 0;
+        }
+
         sprintf(prop_name, "%s_%d", MBTK_APN_PROP, apn->cid);
         // Delete apn
         if(!str_empty(apn->apn)) {
@@ -700,15 +768,45 @@
 #endif
     }
 
-    if(!ret && apn->def_route) {
+    if(!ret) {
         memset(prop_data, 0, sizeof(prop_data));
-        prop_data[0] = '0' + apn->cid;
-        ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
+        if(apn->def_route) {
+            prop_data[0] = '0' + apn->cid;
+            ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
+        } else {
+            char def_cid[10] = {0};
+            int cid = -1;
+            sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);   // Default route and DNS is CID 1.
+            memset(prop_data, 0, sizeof(prop_data));
+            if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
+                cid = atoi(prop_data);
+            }
+
+            if(apn->cid == cid) { // The route cid should reset to default.
+                prop_data[0] = '0' + MBTK_RIL_CID_DEF;
+                ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
+            }
+        }
     }
-    if(!ret && apn->as_dns) {
+    if(!ret) {
         memset(prop_data, 0, sizeof(prop_data));
-        prop_data[0] = '0' + apn->cid;
-        ret = property_set(MBTK_DEF_DNS_CID, prop_data);
+        if(apn->as_dns) {
+            prop_data[0] = '0' + apn->cid;
+            ret = property_set(MBTK_DEF_DNS_CID, prop_data);
+        } else {
+            char def_cid[10] = {0};
+            int cid = -1;
+            sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);   // Default route and DNS is CID 1.
+            memset(prop_data, 0, sizeof(prop_data));
+            if(property_get(MBTK_DEF_DNS_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
+                cid = atoi(prop_data);
+            }
+
+            if(apn->cid == cid) { // The dns cid should reset to default.
+                prop_data[0] = '0' + MBTK_RIL_CID_DEF;
+                ret = property_set(MBTK_DEF_DNS_CID, prop_data);
+            }
+        }
     }
 
     // Update apn info in buffer.
@@ -773,12 +871,24 @@
         if(reg_state->tech >= MBTK_RADIO_TECH_UTRAN) { // No for GSM(No GPRS)
             if(reg_state->reg_state == MBTK_NET_REG_STATE_HOME
                 || reg_state->reg_state == MBTK_NET_REG_STATE_ROAMING) { // Only Home and Roaming network.
-                int cid = MBTK_APN_CID_MIN;
-                mbtk_ip_info_t ip_info;
+                int cid = ril_cid_start;
+                // mbtk_ip_info_t ip_info;
+                mbtk_ril_pdp_state_info_t pdp_info;
                 for(; cid <= MBTK_APN_CID_MAX; cid++) {
                     LOGV("cid - %d, valid - %d, act_state - %d", cid, info_list[cid - 1].valid,
                         info_list[cid - 1].act_state);
-                    if(info_list[cid - 1].valid && info_list[cid - 1].act_state == RIL_ACT_STATE_CONNECTED_RETRY) {
+                    if(info_list[cid - 1].valid &&
+                        (info_list[cid - 1].act_state == RIL_ACT_STATE_CONNECTED_RETRY
+                        || info_list[cid - 1].apn_info.auto_boot_call)) {   // Auto data call when boot.
+                        memset(&pdp_info, 0, sizeof(mbtk_ril_pdp_state_info_t));
+                        pdp_info.action = TRUE;
+                        pdp_info.cid = cid;
+
+                        if(!apn_conf_support(pdp_info.cid)) {
+                            LOGD("Can not data call for CID : %d", pdp_info.cid);
+                            continue;
+                        }
+
                         // Reset ip information.
                         char dev[20] = {0};
                         sprintf(dev, "ccinet%d", cid - 1);
@@ -804,9 +914,9 @@
                             }
 
                             // Get Ip informations.
-                            memset(&ip_info, 0, sizeof(ip_info));
+                            // memset(&ip_info, 0, sizeof(ip_info));
                             cme_err = MBTK_RIL_ERR_CME_NON;
-                            if(req_data_call_state_get(port, cid, &ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                            if(req_data_call_state_get(port, cid, &(pdp_info.ip_info), &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
                             {
                                 LOGE("Get net informations fail.");
                                 return;
@@ -814,15 +924,21 @@
                             else
                             {
                                 // Config network informations.
-                                LOGV("def_route - %d, as_dns - %d", info_list[cid - 1].apn_info.def_route,
-                                    info_list[cid - 1].apn_info.as_dns);
+                                LOGD("def_route - %d, as_dns - %d, ipv4_valid - %d, ipv6_valid - %d",
+                                    info_list[cid - 1].apn_info.def_route,
+                                    info_list[cid - 1].apn_info.as_dns,
+                                    pdp_info.ip_info.ipv4.valid, pdp_info.ip_info.ipv6.valid);
                                 if(net_ifc_reconfig(cid, info_list[cid - 1].apn_info.def_route,
-                                    info_list[cid - 1].apn_info.as_dns, &ip_info)) {
+                                    info_list[cid - 1].apn_info.as_dns, &(pdp_info.ip_info))) {
                                     LOGE("Set net informations fail.");
                                     return;
                                 }
 
                                 info_list[cid - 1].act_state = RIL_ACT_STATE_CONNECTED;
+
+                                pdp_info.ip_info_valid = TRUE;
+
+                                ril_state_change(RIL_MSG_ID_IND_PDP_STATE_CHANGE, &pdp_info, sizeof(mbtk_ril_pdp_state_info_t));
                             }
                         }
                     }
@@ -859,14 +975,10 @@
     int tmp_int;
     char *tmp_str = NULL;
     int cid_start;
-    if(apn_conf_support(MBTK_RIL_CID_DEF)) {
+    if(get_def_cid) {
         cid_start = MBTK_RIL_CID_DEF;
     } else {
-        if(get_def_cid) {
-            cid_start = MBTK_RIL_CID_DEF;
-        } else {
-            cid_start = MBTK_RIL_CID_2;
-        }
+        cid_start = ril_cid_start;
     }
     /*
     <apn_num[1]><cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>...
@@ -926,7 +1038,7 @@
  //   char prop_name[128] = {0};
     char prop_data[1024] = {0};
     char def_cid[10] = {0};
-    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);
+    sprintf(def_cid, "%d", MBTK_RIL_CID_DEF);  // Default route and DNS is CID 1.
 
     if(property_get(MBTK_DEF_ROUTE_CID, prop_data, def_cid) > 0 && !str_empty(prop_data)) {
         apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
diff --git a/mbtk/mbtk_rild_v2/src/ril_ecall.c b/mbtk/mbtk_rild_v2/src/ril_ecall.c
index 60b64c5..a3ff510 100755
--- a/mbtk/mbtk_rild_v2/src/ril_ecall.c
+++ b/mbtk/mbtk_rild_v2/src/ril_ecall.c
@@ -1,3 +1,24 @@
+/*
+*    ril_ecall.c
+*
+*  Implementation of ecall related functions.
+*
+*  The general structure is as follows:
+*    API --- mbtk_rild --- atcmdsrv --- modem
+*                             |
+                              |
+*                        ecall_daemon
+*
+*/
+/******************************************************************************
+
+                          EDIT HISTORY FOR FILE
+
+  WHEN        WHO       WHAT,WHERE,WHY
+--------    --------    -------------------------------------------------------
+2024/11/04     LiuBin      Initial version
+
+******************************************************************************/
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
diff --git a/mbtk/test/libmbtk_ril/mbtk_ril_test.c b/mbtk/test/libmbtk_ril/mbtk_ril_test.c
index 1f4ac7a..ffa83c6 100755
--- a/mbtk/test/libmbtk_ril/mbtk_ril_test.c
+++ b/mbtk/test/libmbtk_ril/mbtk_ril_test.c
@@ -164,6 +164,87 @@
         mbtk_ril_pdp_state_info_t *state = (mbtk_ril_pdp_state_info_t*)data;
         printf("pdp state change : cid - %d, action - %d, reason-%d, auto_change - %d\n",
             state->cid, state->action, state->reason, state->auto_change);
+        if(state->ip_info_valid) {
+            if(state->ip_info.ipv4.valid) {
+                // log_hex("IPv4", &ipv4, sizeof(mbtk_ipv4_info_t));
+                char ip_tmp[20];
+
+                memset(ip_tmp, 0, 20);
+                if(inet_ntop(AF_INET, &(state->ip_info.ipv4.IPAddr), ip_tmp, 20) == NULL) {
+                    printf("IP error.\n");
+                } else {
+                    printf("IP : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 20);
+                if(inet_ntop(AF_INET, &(state->ip_info.ipv4.PrimaryDNS), ip_tmp, 20) == NULL) {
+                    printf("PrimaryDNS error.\n");
+                } else {
+                    printf("PrimaryDNS : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 20);
+                if(inet_ntop(AF_INET, &(state->ip_info.ipv4.SecondaryDNS), ip_tmp, 20) == NULL) {
+                    printf("SecondaryDNS error.\n");
+                } else {
+                    printf("SecondaryDNS : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 20);
+                if(inet_ntop(AF_INET, &(state->ip_info.ipv4.GateWay), ip_tmp, 20) == NULL) {
+                    printf("GateWay error.\n");
+                } else {
+                    printf("GateWay : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 20);
+                if(inet_ntop(AF_INET, &(state->ip_info.ipv4.NetMask), ip_tmp, 20) == NULL) {
+                    printf("NetMask error.\n");
+                } else {
+                    printf("NetMask : %s\n", ip_tmp);
+                }
+            }
+
+            if(state->ip_info.ipv6.valid) {
+                // log_hex("IPv6", &ipv6, sizeof(mbtk_ipv6_info_t));
+                char ip_tmp[50];
+
+                memset(ip_tmp, 0, 50);
+                if(ipv6_2_str(&(state->ip_info.ipv6.IPV6Addr), ip_tmp)) {
+                    printf("IP error.\n");
+                } else {
+                    printf("IP : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 50);
+                if(ipv6_2_str(&(state->ip_info.ipv6.PrimaryDNS), ip_tmp)) {
+                    printf("PrimaryDNS error.\n");
+                } else {
+                    printf("PrimaryDNS : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 50);
+                if(ipv6_2_str(&(state->ip_info.ipv6.SecondaryDNS), ip_tmp)) {
+                    printf("SecondaryDNS error.\n");
+                } else {
+                    printf("SecondaryDNS : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 50);
+                if(ipv6_2_str(&(state->ip_info.ipv6.GateWay), ip_tmp)) {
+                    printf("GateWay error.\n");
+                } else {
+                    printf("GateWay : %s\n", ip_tmp);
+                }
+
+                memset(ip_tmp, 0, 50);
+                if(ipv6_2_str(&(state->ip_info.ipv6.NetMask), ip_tmp)) {
+                    printf("NetMask error.\n");
+                } else {
+                    printf("NetMask : %s\n", ip_tmp);
+                }
+            }
+        }
     }
 }