Add mbtk_ril V2 (Default close)

Change-Id: Iaa5921fd74aeeb394771110f0cec7aa7742dc83a
diff --git a/mbtk/mbtk_rild_v2/src/ril_net.c b/mbtk/mbtk_rild_v2/src/ril_net.c
new file mode 100755
index 0000000..3f02965
--- /dev/null
+++ b/mbtk/mbtk_rild_v2/src/ril_net.c
@@ -0,0 +1,1856 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <cutils/properties.h>
+#include <arpa/inet.h>
+
+#include "mbtk_type.h"
+#include "mbtk_ril.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "ril_info.h"
+#include "mbtk_str.h"
+
+extern ril_band_info_t band_info;
+void ril_rsp_pack_send(int fd, int ril_id, int msg_index, const void* data, int data_len);
+static int req_apn_get(mbtk_apn_info_array_t *apns, int *cme_err);
+static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err);
+static void apn_prop_get(ril_apn_info_array_t *apns);
+
+void apn_auto_conf_from_prop()
+{
+    ril_apn_info_array_t apns;
+    int i = 0;
+    memset(&apns, 0, sizeof(ril_apn_info_array_t));
+    apn_prop_get(&apns);
+    while(i < apns.num) {
+        int cme_err = MBTK_RIL_ERR_CME_NON;
+        if(req_apn_set(&(apns.apns[i]), &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+        {
+            LOGD("Set APN fail.");
+        }
+        else
+        {
+            LOGD("Set APN - %d success.", apns.apns[i].cid);
+        }
+        i++;
+    }
+}
+
+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 TRUE;
+}
+
+static int apn_cid_reset(mbtk_apn_info_t *apn)
+{
+    // Delete apn
+    if(str_empty(apn->apn)) {
+        if(apn->cid == MBTK_RIL_CID_NUL)
+            return -1;
+
+        if(!apn_conf_support(MBTK_RIL_CID_DEF) && apn->cid == MBTK_RIL_CID_DEF)
+            return -1;
+
+        mbtk_apn_info_array_t apns;
+        int cme_err = MBTK_RIL_ERR_CME_NON;
+        memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+        if(req_apn_get(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+        {
+            LOGW("Get APN fail.");
+            return 0;
+        }
+        else
+        {
+            int index = 0;
+            while(index < apns.num) {
+                if(apns.apns[index].cid == apn->cid)
+                    return 0;
+                index++;
+            }
+            return -1;
+        }
+    } else {
+        if(apn->cid == MBTK_RIL_CID_NUL) {
+            int start_cid;
+            bool asr_auto_call_open = !apn_conf_support(MBTK_RIL_CID_DEF);
+            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(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+            {
+                LOGW("Get APN fail.");
+                apn->cid = start_cid;
+            }
+            else
+            {
+                for(; start_cid <= MBTK_APN_CID_MAX; start_cid++) {
+                    int index = 0;
+                    while(index < apns.num) {
+                        if(apns.apns[index].cid == start_cid)
+                            break;
+                        index++;
+                    }
+
+                    if(index == apns.num) { // Found not used cid : start_cid.
+                        LOGD("Change CID : %d -> %d", apn->cid, start_cid);
+                        apn->cid = start_cid;
+                        return 0;
+                    }
+                }
+
+                if(start_cid > MBTK_APN_CID_MAX) {
+                    LOGE("APN full.");
+                    return -1;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+static void apn_prop_get(ril_apn_info_array_t *apns)
+{
+    char prop_name[20] = {0};
+    char prop_data[300] = {0};
+    int cid;
+    memset(apns, 0, sizeof(ril_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;
+        cid = MBTK_RIL_CID_2;
+    } else {
+        if(property_get(MBTK_DEF_ROUTE_CID, prop_data, "") > 0 && !str_empty(prop_data)) {
+            apns->cid_for_def_route = (mbtk_ril_cid_enum)atoi(prop_data);
+        }
+        cid = MBTK_APN_CID_MIN;
+    }
+    for(; cid <= MBTK_APN_CID_MAX; cid++) {
+        memset(prop_name, 0, 20);
+        memset(prop_data, 0, 300);
+
+        sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+        // ip_type,auth,auto_data_call,apn,user,pass
+        if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+            apns->apns[apns->num].cid = (mbtk_ril_cid_enum)cid;
+            char *ptr_1 = prop_data;
+            apns->apns[apns->num].ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+            ptr_1 = strstr(ptr_1, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            ptr_1++; // Jump ',' to auth
+
+            apns->apns[apns->num].auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+            ptr_1 = strstr(ptr_1, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            ptr_1++; // Jump ',' to auto_data_call
+
+            apns->apns[apns->num].auto_boot_call = (uint8)atoi(ptr_1);
+            ptr_1 = strstr(ptr_1, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            ptr_1++; // Jump ',' to apn
+
+            char *ptr_2 = strstr(ptr_1, ",");
+            if(!ptr_2) {
+                continue;
+            }
+            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].apn, ptr_1, ptr_2 - ptr_1); // apn
+            }
+
+            ptr_2++; // Jump ',' to user
+            ptr_1 = strstr(ptr_2, ",");
+            if(!ptr_1) {
+                continue;
+            }
+            if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].user, ptr_2, ptr_1 - ptr_2); // user
+            }
+
+            ptr_1++; // Jump ',' to pass
+            if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+                memcpy(apns->apns[apns->num].pass, ptr_1, strlen(ptr_1)); // pass
+            }
+
+            apns->num++;
+        }
+    }
+}
+
+static int apn_prop_get_by_cid(mbtk_ril_cid_enum cid, mbtk_apn_info_t *apn)
+{
+    char prop_name[20] = {0};
+    char prop_data[300] = {0};
+    memset(apn, 0, sizeof(mbtk_apn_info_t));
+
+    sprintf(prop_name, "%s_%d",MBTK_APN_PROP,cid);
+    // ip_type,auth,auto_data_call,apn,user,pass
+    if(property_get(prop_name, prop_data, "") > 0 && !str_empty(prop_data)) {
+        apn->cid = cid;
+        apn->auto_save = (uint8)1;
+        char *ptr_1 = prop_data;
+        apn->ip_type = (mbtk_ip_type_enum)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to auth
+
+        apn->auth = (mbtk_apn_auth_type_enum)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to auto_data_call
+
+        apn->auto_boot_call = (uint8)atoi(ptr_1);
+        ptr_1 = strstr(ptr_1, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        ptr_1++; // Jump ',' to apn
+
+        char *ptr_2 = strstr(ptr_1, ",");
+        if(!ptr_2) {
+            return -1;
+        }
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->apn, ptr_1, ptr_2 - ptr_1); // apn
+        }
+
+        ptr_2++; // Jump ',' to user
+        ptr_1 = strstr(ptr_2, ",");
+        if(!ptr_1) {
+            return -1;
+        }
+        if(memcmp(ptr_2, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->user, ptr_2, ptr_1 - ptr_2); // user
+        }
+
+        ptr_1++; // Jump ',' to pass
+        if(memcmp(ptr_1, "NULL", 4)) { // Not "NULL"
+            memcpy(apn->pass, ptr_1, strlen(ptr_1)); // pass
+        }
+        return 0;
+    }
+    return -1;
+}
+
+static int apn_prop_set(mbtk_apn_info_t *apn)
+{
+    char prop_name[20] = {0};
+    char prop_data[300] = {0};
+    int ret = -1;
+    if(apn->auto_save) {
+        sprintf(prop_name, "%s_%d", MBTK_APN_PROP, apn->cid);
+        // Delete apn
+        if(!str_empty(apn->apn)) {
+            snprintf(prop_data, 300, "%d,%d,%d,%s,%s,%s", apn->ip_type, apn->auth, apn->auto_boot_call,
+                apn->apn,
+                str_empty(apn->user) ? "NULL" : apn->user,
+                str_empty(apn->pass) ? "NULL" : apn->pass);
+        }
+
+        ret = property_set(prop_name, prop_data);
+    }
+
+    if(apn->def_route) {
+        memset(prop_data, 0, sizeof(prop_data));
+        prop_data[0] = '0' + apn->cid;
+        ret = property_set(MBTK_DEF_ROUTE_CID, prop_data);
+    }
+    return ret;
+}
+
+static int apn_prop_reset(mbtk_data_call_info_t *data_info)
+{
+    mbtk_apn_info_t apn;
+    if(apn_prop_get_by_cid(data_info->cid, &apn)) {
+        return -1;
+    } else {
+        apn.auto_boot_call = data_info->auto_boot_call;
+        apn.def_route = data_info->def_route;
+        return apn_prop_set(&apn);
+    }
+}
+
+
+/*
+AT+COPS=?
+
++COPS: (2, "CHN-CT", "CT", "46011", 7),(3, "CHN-UNICOM", "UNICOM", "46001", 7),(3, "CHINA MOBILE", "CMCC", "46000", 0),(3, "CHINA MOBILE", "CMCC", "46000", 7),(3, "China Broadnet", "CBN", "46015", 7),,(0,1,2,3,4),(0,1,2)
+
+OK
+*/
+static int req_available_net_get(mbtk_net_info_array_t* nets, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command_singleline("AT+COPS=?", "+COPS:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+    char *line_ptr = response->p_intermediates->line;
+    if(line_ptr == NULL) {
+        LOG("line is NULL");
+        err = -1;
+        goto exit;
+    }
+    //LOG("Line:%s",line_ptr);
+    line_ptr = strstr(line_ptr, "(");
+    while(line_ptr) {
+        line_ptr++;
+        // Only for available/current net.
+        if(*line_ptr == '1' || *line_ptr == '2' || *line_ptr == '3') {
+            nets->net_info[nets->num].net_state = (uint8)atoi(line_ptr); // net_state
+
+            line_ptr = strstr(line_ptr, ",");
+            if(line_ptr == NULL) {
+                err = -1;
+                goto exit;
+            }
+            line_ptr++;
+
+            line_ptr = strstr(line_ptr, ",");
+            if(line_ptr == NULL) {
+                err = -1;
+                goto exit;
+            }
+            line_ptr++;
+
+            line_ptr = strstr(line_ptr, ",");
+            if(line_ptr == NULL) {
+                err = -1;
+                goto exit;
+            }
+
+            while(*line_ptr != '\0' && (*line_ptr == ',' || *line_ptr == ' ' || *line_ptr == '"'))
+                line_ptr++;
+
+            // set sel_mode to 0
+            nets->net_info[nets->num].net_sel_mode = (uint8)0;
+            // Point to "46000"
+            //LOG("PLMN:%s",line_ptr);
+            //sleep(1);
+            //uint32_2_byte((uint32)atoi(line_ptr), buff_ptr + 3, false); // plmn
+            nets->net_info[nets->num].plmn = (uint32)atoi(line_ptr);
+
+            line_ptr = strstr(line_ptr, ",");
+            if(line_ptr == NULL) {
+                err = -1;
+                goto exit;
+            }
+
+            while(*line_ptr != '\0' && (*line_ptr == ',' || *line_ptr == ' '))
+                line_ptr++;
+
+            // Point to "7"
+            if(*line_ptr == '\0') {
+                err = -1;
+                goto exit;
+            }
+            //LOG("Type:%s",line_ptr);
+            //sleep(1);
+            nets->net_info[nets->num].net_type = (uint8)atoi(line_ptr); // net_type
+
+            nets->num++;
+        }
+
+        line_ptr = strstr(line_ptr, "(");
+    }
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+COPS?
++COPS: 1
+
+OK
+
+or
+
+AT+COPS?
++COPS: 0,2,"46001",7
+
+OK
+
+*/
+static int req_net_sel_mode_get(mbtk_net_info_t *net, int *cme_err)
+{
+    //LOG("req_net_sel_mode_get() 0");
+    //sleep(1);
+    ATResponse *response = NULL;
+    int tmp_int;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT+COPS?", "+COPS:", &response);
+    //LOG("req_net_sel_mode_get() 00");
+    //sleep(1);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err != NULL)
+            *cme_err = at_get_cme_error(response);
+        err = -1;
+        goto exit;
+    }
+    //LOG("req_net_sel_mode_get() 1");
+    //sleep(1);
+    char *line = response->p_intermediates->line;
+    if(line == NULL) {
+        LOG("line is NULL");
+        goto exit;
+    }
+    //LOG("req_net_sel_mode_get() 2");
+    //sleep(1);
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    //LOG("req_net_sel_mode_get() 3");
+    //sleep(1);
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    net->net_sel_mode = (uint8)tmp_int;
+    //LOG("req_net_sel_mode_get() 4");
+    //sleep(1);
+    // +COPS: 1
+    if(!at_tok_hasmore(&line)) {
+        goto exit;
+    }
+    //LOG("req_net_sel_mode_get() 5");
+    //sleep(1);
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    //LOG("req_net_sel_mode_get() 6");
+    //sleep(1);
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    // memcpy(net->plmn, tmp_ptr, strlen(tmp_ptr));
+    net->plmn = (uint32)atoi(tmp_ptr);
+    //LOG("req_net_sel_mode_get() 7");
+    //sleep(1);
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    net->net_type = (uint8)tmp_int;
+
+    net->net_state = (uint8)MBTK_NET_AVIL_STATE_CURRENT;
+
+exit:
+    //LOG("req_net_sel_mode_get() 8");
+    //sleep(1);
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+COPS=0
+or
+AT+COPS=1,2,"46000",7
+
+OK
+
+*/
+static int req_net_sel_mode_set(mbtk_net_info_t* net, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[50] = {0};
+    char* cmp_ptr = cmd;
+    if(net == NULL) {
+        cmp_ptr += sprintf(cmp_ptr, "AT+COPS=0");
+     } else {
+        if(net->net_sel_mode == 0) {
+            cmp_ptr += sprintf(cmp_ptr, "AT+COPS=0");
+        } else if(net->net_type == 0xFF) {
+            cmp_ptr += sprintf(cmp_ptr, "AT+COPS=1,2,\"%d\"",net->plmn);
+        } else {
+            cmp_ptr += sprintf(cmp_ptr, "AT+COPS=1,2,\"%d\",%d",net->plmn, net->net_type);
+        }
+     }
+
+    int err = at_send_command(cmd, &response);
+
+    if (err < 0 || response->success == 0) {
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*BAND=15
+OK
+
+*/
+static int req_band_set(mbtk_band_info_t* band, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    int err = -1;
+
+    if(band->gsm_band == 0 && band->umts_band == 0
+        && band->tdlte_band == 0 && band->fddlte_band == 0) {
+        sprintf(cmd, "AT*BAND=%d", band->net_pref);
+    } else {
+        log_hex("BAND_SUPPORT", &band_info.band_support, sizeof(mbtk_band_info_t));
+        log_hex("BAND", band, sizeof(mbtk_band_info_t));
+
+        if(band->gsm_band == 0) {
+            band->gsm_band = band_info.band_support.gsm_band;
+        }
+        if(band->umts_band == 0) {
+            band->umts_band = band_info.band_support.umts_band;
+        }
+        if(band->tdlte_band == 0) {
+            band->tdlte_band = band_info.band_support.tdlte_band;
+        }
+        if(band->fddlte_band == 0) {
+            band->fddlte_band = band_info.band_support.fddlte_band;
+        }
+
+        if((band->gsm_band & band_info.band_support.gsm_band) != band->gsm_band) {
+            LOG("GSM band error.");
+            goto exit;
+        }
+
+        if((band->umts_band & band_info.band_support.umts_band) != band->umts_band) {
+            LOG("UMTS band error.");
+            goto exit;
+        }
+
+        if((band->tdlte_band & band_info.band_support.tdlte_band) != band->tdlte_band) {
+            LOG("TDLTE band error.");
+            goto exit;
+        }
+
+        if((band->fddlte_band & band_info.band_support.fddlte_band) != band->fddlte_band) {
+            LOG("FDDLTE band error.");
+            goto exit;
+        }
+
+        if((band->lte_ext_band & band_info.band_support.lte_ext_band) != band->lte_ext_band) {
+            LOG("EXT_LTE band error.");
+            goto exit;
+        }
+
+        if(band->net_pref == 0xFF) { // No change net_pref.
+            int tmp_int;
+            err = at_send_command_singleline("AT*BAND?", "*BAND:", &response);
+            if (err < 0 || response->success == 0 || !response->p_intermediates){
+                if(cme_err) {
+                    *cme_err = at_get_cme_error(response);
+                }
+                goto exit;
+            }
+
+            char *line = response->p_intermediates->line;
+            err = at_tok_start(&line);
+            if (err < 0)
+            {
+                goto exit;
+            }
+
+            err = at_tok_nextint(&line, &tmp_int);
+            if (err < 0)
+            {
+                goto exit;
+            }
+            band->net_pref = (uint8)tmp_int; // Set to current net_pref.
+
+            at_response_free(response);
+        }
+
+        if(band->lte_ext_band > 0) {
+            sprintf(cmd, "AT*BAND=%d,%d,%d,%d,%d,,,,%d", band->net_pref, band->gsm_band, band->umts_band, band->tdlte_band, band->fddlte_band, band->lte_ext_band);
+        } else {
+            sprintf(cmd, "AT*BAND=%d,%d,%d,%d,%d", band->net_pref, band->gsm_band, band->umts_band, band->tdlte_band, band->fddlte_band);
+        }
+    }
+    err = at_send_command(cmd, &response);
+
+    if (err < 0 || response->success == 0){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+    err = 0;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+// ???????
+AT*BAND=?
+*BAND:(0-18),79,147,482,524503
+
+OK
+
+// ???????????
+AT*BAND?
+*BAND: 15, 78, 147, 482, 524503, 0, 2, 2, 0, 0
+
+OK
+
+// ?????????
+AT*BAND=5,79,147,128,1
+OK
+
+net_prefferred??
+    0 : GSM only
+    1 : UMTS only
+    2 : GSM/UMTS(auto)
+    3 : GSM/UMTS(GSM preferred)
+    4 : GSM/UMTS(UMTS preferred)
+    5 : LTE only
+    6 : GSM/LTE(auto)
+    7 : GSM/LTE(GSM preferred)
+    8 : GSM/LTE(LTE preferred)
+    9 : UMTS/LTE(auto)
+    10 : UMTS/LTE(UMTS preferred)
+    11 : UMTS/LTE(LTE preferred)
+    12 : GSM/UMTS/LTE(auto)
+    13 : GSM/UMTS/LTE(GSM preferred)
+    14 : GSM/UMTS/LTE(UMTS preferred)
+    15 : GSM/UMTS/LTE(LTE preferred)
+GSM band??
+    1 ?C PGSM 900 (standard or primary)
+    2 ?C DCS GSM 1800
+    4 ?C PCS GSM 1900
+    8 ?C EGSM 900 (extended)
+    16 ?C GSM 450
+    32 ?C GSM 480
+    64 ?C GSM 850
+    512 - BAND_LOCK_BIT // used for GSM band setting
+UMTS band??
+    1 ?C UMTS_BAND_1
+    2 ?C UMTS_BAND_2
+    4 ?C UMTS_BAND_3
+    8 ?C UMTS_BAND_4
+    16 ?C UMTS_BAND_5
+    32 ?C UMTS_BAND_6
+    64 ?C UMTS_BAND_7
+    128 ?C UMTS_BAND_8
+    256 ?C UMTS_BAND_9
+LTEbandH(TDD-LTE band)
+    32 ?C TDLTE_BAND_38
+    64 ?C TDLTE_BAND_39
+    128 ?C TDLTE_BAND_40
+    256 ?C TDLTE_BAND_41
+LTEbandL(FDD-LTE band)
+    1 ?C FDDLTE_BAND_1
+    4 ?C FDDLTE _BAND_3
+    8 ?C FDDLTE _BAND_4
+    64 ?C FDDLTE _BAND_7
+    65536 ?C FDDLTE _BAND_17
+    524288 ?C FDDLTE _BAND_20
+*/
+static int req_band_get(mbtk_band_info_t *band, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int tmp_int;
+
+    log_hex("BAND_SUPPORT", &band_info.band_support, sizeof(mbtk_band_info_t));
+    int err = at_send_command_singleline("AT*BAND?", "*BAND:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    band->net_pref = (uint8)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    band->gsm_band = (uint16)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    band->umts_band = (uint16)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    band->tdlte_band = (uint32)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    band->fddlte_band = (uint32)tmp_int;
+
+    // roamingConfig
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    // srvDomain
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    // bandPriorityFlag
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    //
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    // ltebandExt
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    band->lte_ext_band = (uint32)tmp_int;
+
+    log_hex("BAND", band, sizeof(mbtk_band_info_t));
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CSQ
++CSQ: 31,99
+
+OK
+
+AT+CESQ
++CESQ: 60,99,255,255,20,61
+
+OK
+
+AT+COPS?
++COPS: 0,2,"46001",7
+
+OK
+
+*/
+static int req_net_signal_get(mbtk_signal_info_t *signal, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int tmp_int;
+    char *tmp_ptr = NULL;
+    // AT+EEMOPT=1 in the first.
+    int err = at_send_command_singleline("AT+CSQ", "+CSQ:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err != NULL)
+            *cme_err = at_get_cme_error(response);
+        err = -1;
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->rssi = (uint8)tmp_int;
+    at_response_free(response);
+
+    err = at_send_command_singleline("AT+CESQ", "+CESQ:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err != NULL)
+            *cme_err = at_get_cme_error(response);
+        err = -1;
+        goto exit;
+    }
+
+    line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->rxlev = (uint8)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->ber = (uint8)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->rscp = (uint8)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->ecno = (uint8)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->rsrq = (uint8)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->rsrp = (uint8)tmp_int;
+
+    at_response_free(response);
+    err = at_send_command_singleline("AT+COPS?", "+COPS:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err != NULL)
+            *cme_err = at_get_cme_error(response);
+        err = -1;
+        goto exit;
+    }
+    line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    if(!at_tok_hasmore(&line)) {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    signal->type = (uint8)tmp_int;
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CREG=3
+OK
+
+AT+CREG?
++CREG: 3,1,"8330","06447340",7
+
+OK
+
+AT+CREG?
++CREG: 3,0
+
+OK
+
+AT+CEREG?
++CEREG: 3,1,"8330","06447340",7
+
+OK
+
+
+AT+CIREG?
++CIREG: 2,1,15
+
+OK
+
+AT+CIREG?
++CIREG: 0
+
+OK
+
+
+*/
+static int req_net_reg_get(mbtk_net_reg_info_t *reg, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int tmp_int;
+    char *tmp_str = NULL;
+    int err = at_send_command("AT+CREG=3", &response);
+    if (err < 0 || response->success == 0){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+    at_response_free(response);
+
+    err = at_send_command_multiline("AT+CREG?", "+CREG:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+    char *line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int); // n
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);// stat
+    if (err < 0)
+    {
+        goto exit;
+    }
+    reg->call_state = (uint8)tmp_int;
+
+    if(at_tok_hasmore(&line)) {
+        err = at_tok_nextstr(&line, &tmp_str); // lac
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->lac = strtol(tmp_str, NULL, 16);
+
+        err = at_tok_nextstr(&line, &tmp_str); // ci
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->ci = strtol(tmp_str, NULL, 16);
+
+        err = at_tok_nextint(&line, &tmp_int);// AcT
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->type = (uint8)tmp_int;
+    }
+    at_response_free(response);
+
+    err = at_send_command_multiline("AT+CEREG?", "+CEREG:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+    line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int); // n
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int);// stat
+    if (err < 0)
+    {
+        goto exit;
+    }
+    reg->data_state = (uint8)tmp_int;
+
+    if(reg->lac == 0 && at_tok_hasmore(&line)) {
+        err = at_tok_nextstr(&line, &tmp_str); // lac
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->lac = strtol(tmp_str, NULL, 16);
+
+        err = at_tok_nextstr(&line, &tmp_str); // ci
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->ci = strtol(tmp_str, NULL, 16);
+
+        err = at_tok_nextint(&line, &tmp_int);// AcT
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->type = (uint8)tmp_int;
+    }
+    at_response_free(response);
+
+    err = at_send_command_multiline("AT+CIREG?", "+CIREG:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        reg->ims_state = (uint8)0;
+        err = 0;
+        goto exit;
+    }
+    line = response->p_intermediates->line;
+    err = at_tok_start(&line);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    err = at_tok_nextint(&line, &tmp_int); // n/stat
+    if (err < 0)
+    {
+        goto exit;
+    }
+    if(at_tok_hasmore(&line)) {
+        err = at_tok_nextint(&line, &tmp_int);// stat
+        if (err < 0)
+        {
+            goto exit;
+        }
+        reg->ims_state = (uint8)tmp_int;
+    } else {
+        reg->ims_state = (uint8)tmp_int;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGDCONT?
+
++CGDCONT: 1,"IPV4V6","ctnet","10.142.64.116 254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,0,0
+
++CGDCONT: 8,"IPV4V6","IMS","254.128.0.0.0.0.0.0.0.0.0.0.0.0.0.1",0,0,0,2,1,1
+
+OK
+
+*/
+static int req_apn_get(mbtk_apn_info_array_t *apns, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command_multiline("AT+CGDCONT?", "+CGDCONT:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+    ATLine* lines_ptr = response->p_intermediates;
+    char *line = NULL;
+    int tmp_int;
+    char *tmp_str = NULL;
+    /*
+    <apn_num[1]><cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>...
+                <cid[1]><ip_type[1]><apn_len[2]><apn><user_len[2]><user><pass_len[2]><pass><auth_len[2]><auth>
+    */
+    while(lines_ptr)
+    {
+        line = lines_ptr->line;
+        err = at_tok_start(&line);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int); // cid
+        if (err < 0)
+        {
+            goto exit;
+        }
+        // Only get CID 1-7
+        if(tmp_int >= MBTK_APN_CID_MIN && tmp_int <= MBTK_APN_CID_MAX) {
+            apns->apns[apns->num].cid = (mbtk_ril_cid_enum)tmp_int;
+
+            err = at_tok_nextstr(&line, &tmp_str);// ip type
+            if (err < 0)
+            {
+                goto exit;
+            }
+            if(!strcasecmp(tmp_str, "IP")) {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IP;
+            } else if(!strcasecmp(tmp_str, "IPV6")) {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV6;
+            } else if(!strcasecmp(tmp_str, "IPV4V6")) {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_IPV4V6;
+            } else {
+                apns->apns[apns->num].ip_type = MBTK_IP_TYPE_PPP;
+            }
+
+            err = at_tok_nextstr(&line, &tmp_str); // apn
+            if (err < 0)
+            {
+                goto exit;
+            }
+            if(!str_empty(tmp_str)) {
+                memcpy(apns->apns[apns->num].apn, tmp_str, strlen(tmp_str));
+            }
+
+            apns->num++;
+        }
+
+        lines_ptr = lines_ptr->p_next;
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGDCONT=1,"IPV4V6","cmnet"
+OK
+
+AT*AUTHReq=1,1,marvell,123456
+OK
+
+*/
+static int req_apn_set(mbtk_apn_info_t *apn, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[400] = {0};
+    int index = 0;
+    int err = 0;
+
+    // Delete apn
+    if(str_empty(apn->apn)) {
+        sprintf(cmd, "AT+CGDCONT=%d", apn->cid);
+        err = at_send_command(cmd, &response);
+        if (err < 0 || response->success == 0){
+            if(cme_err) {
+                *cme_err = at_get_cme_error(response);
+            }
+            goto exit;
+        }
+    } else {
+        index += sprintf(cmd, "AT+CGDCONT=%d,", apn->cid);
+        switch(apn->ip_type) {
+            case MBTK_IP_TYPE_IP: {
+                index += sprintf(cmd + index,"\"IP\",");
+                break;
+            }
+            case MBTK_IP_TYPE_IPV6: {
+                index += sprintf(cmd + index,"\"IPV6\",");
+                break;
+            }
+            case MBTK_IP_TYPE_IPV4V6: {
+                index += sprintf(cmd + index,"\"IPV4V6\",");
+                break;
+            }
+            default: {
+                index += sprintf(cmd + index,"\"PPP\",");
+                break;
+            }
+        }
+        if(strlen(apn->apn) > 0) {
+            index += sprintf(cmd + index,"\"%s\"", apn->apn);
+        }
+
+        err = at_send_command(cmd, &response);
+        if (err < 0 || response->success == 0){
+            if(cme_err) {
+                *cme_err = at_get_cme_error(response);
+            }
+            goto exit;
+        }
+
+        if(!str_empty(apn->user) || !str_empty(apn->pass)) {
+            at_response_free(response);
+
+            memset(cmd,0,400);
+            int cmd_auth=0;
+            if(apn->auth == MBTK_APN_AUTH_PROTO_NONE)
+                cmd_auth = 0;
+            else if(apn->auth == MBTK_APN_AUTH_PROTO_PAP)
+                cmd_auth = 1;
+            else if(apn->auth == MBTK_APN_AUTH_PROTO_CHAP)
+                cmd_auth = 2;
+            else
+                goto exit;
+
+            sprintf(cmd, "AT*AUTHREQ=%d,%d,%s,%s",apn->cid,cmd_auth,apn->user,apn->pass);
+            err = at_send_command(cmd, &response);
+            if (err < 0 || response->success == 0){
+                if(cme_err) {
+                    *cme_err = at_get_cme_error(response);
+                }
+                goto exit;
+            }
+        }
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGACT?
++CGACT: 1,1
++CGACT: 8,1
+OK
+
+AT+CGACT=1,<cid>
+OK
+
+*/
+static int req_data_call_start(mbtk_ril_cid_enum cid, bool def_route,
+                int retry_interval, int timeout, mbtk_ip_info_t *ip_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[400] = {0};
+    int err = 0;
+
+    sprintf(cmd, "AT+CGACT=1,%d", cid);
+    err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGACT=0,<cid>
+OK
+
+*/
+static int req_data_call_stop(mbtk_ril_cid_enum cid, int timeout, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[400] = {0};
+    int err = 0;
+
+    sprintf(cmd, "AT+CGACT=0,%d", cid);
+    err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        if(cme_err) {
+            *cme_err = at_get_cme_error(response);
+        }
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CGCONTRDP=1
++CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","10.255.74.26","","223.87.253.100","223.87.253.253","","",0,0
++CGCONTRDP: 1,7,"cmnet-2.MNC000.MCC460.GPRS","254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239","","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.1","36.9.128.98.32.0.0.2.0.0.0.0.0.0.0.2","","",0,0
+
+OK
+
+*/
+static int req_data_call_state_get(mbtk_ril_cid_enum cid, mbtk_ip_info_t *ip_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[50] = {0};
+    int err = 0;
+
+    sprintf(cmd, "AT+CGCONTRDP=%d", cid);
+
+    err = at_send_command_multiline(cmd, "+CGCONTRDP:", &response);
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+    ATLine* lines_ptr = response->p_intermediates;
+    char *line = NULL;
+    int tmp_int;
+    char *tmp_ptr = NULL;
+    while(lines_ptr)
+    {
+        line = lines_ptr->line;
+        err = at_tok_start(&line);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int); // cid
+        if (err < 0)
+        {
+            goto exit;
+        }
+        err = at_tok_nextint(&line, &tmp_int); // bearer_id
+        if (err < 0)
+        {
+            goto exit;
+        }
+        err = at_tok_nextstr(&line, &tmp_ptr); // APN
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // IP
+        if (err < 0 || str_empty(tmp_ptr))
+        {
+            goto exit;
+        }
+        if(is_ipv4(tmp_ptr)) {
+            if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.IPAddr)) < 0) {
+                LOGE("inet_pton() fail.");
+                err = -1;
+                goto exit;
+            }
+
+            ip_info->ipv4.valid = true;
+            //log_hex("IPv4", &(ipv4->IPAddr), sizeof(struct in_addr));
+        } else {
+            if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.IPV6Addr))) {
+                LOGE("str_2_ipv6() fail.");
+                err = -1;
+                goto exit;
+            }
+
+            ip_info->ipv6.valid = true;
+            //log_hex("IPv6", &(ipv6->IPV6Addr), 16);
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // Gateway
+        if (err < 0)
+        {
+            goto exit;
+        }
+        if(!str_empty(tmp_ptr)) { // No found gateway
+            if(is_ipv4(tmp_ptr)) {
+                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.GateWay)) < 0) {
+                    LOGE("inet_pton() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv4", &(ipv4->GateWay), sizeof(struct in_addr));
+            } else {
+                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.GateWay))) {
+                    LOGE("str_2_ipv6() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv6", &(ipv6->GateWay), 16);
+            }
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // prim_DNS
+        if (err < 0)
+        {
+            goto exit;
+        }
+        if(!str_empty(tmp_ptr)) { // No found Primary DNS
+            if(is_ipv4(tmp_ptr)) {
+                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.PrimaryDNS)) < 0) {
+                    LOGE("inet_pton() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv4", &(ipv4->PrimaryDNS), sizeof(struct in_addr));
+            } else {
+                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.PrimaryDNS))) {
+                    LOGE("str_2_ipv6() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv6", &(ipv6->PrimaryDNS), 16);
+            }
+        }
+
+        err = at_tok_nextstr(&line, &tmp_ptr); // sec_DNS
+        if (err < 0)
+        {
+            goto exit;
+        }
+        if(!str_empty(tmp_ptr)) { // No found Secondary DNS
+            if(is_ipv4(tmp_ptr)) {
+                if(inet_pton(AF_INET, tmp_ptr, &(ip_info->ipv4.SecondaryDNS)) < 0) {
+                    LOGE("inet_pton() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv4", &(ipv4->SecondaryDNS), sizeof(struct in_addr));
+            } else {
+                if(str_2_ipv6(tmp_ptr, &(ip_info->ipv6.SecondaryDNS))) {
+                    LOGE("str_2_ipv6() fail.");
+                    err = -1;
+                    goto exit;
+                }
+
+                //log_hex("IPv6", &(ipv6->SecondaryDNS), 16);
+            }
+        }
+
+        lines_ptr = lines_ptr->p_next;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+
+//void net_list_free(void *data);
+// Return MBTK_INFO_ERR_SUCCESS,will call pack_error_send() to send RSP.
+// Otherwise, do not call pack_error_send().
+mbtk_ril_err_enum net_pack_req_process(sock_cli_info_t* cli_info, ril_msg_pack_info_t* pack)
+{
+    mbtk_ril_err_enum err = MBTK_RIL_ERR_SUCCESS;
+    int cme_err = MBTK_RIL_ERR_CME_NON;
+    switch(pack->msg_id)
+    {
+        case RIL_MSG_ID_NET_AVAILABLE:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_net_info_array_t net_array;
+                memset(&net_array, 0, sizeof(mbtk_net_info_array_t));
+                if(req_available_net_get(&net_array, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get Available Net fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &net_array, sizeof(mbtk_net_info_array_t));
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+                LOGW("Unsupport set available net.");
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_SEL_MODE:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_net_info_t info;
+                memset(&info, 0, sizeof(mbtk_net_info_t));
+                if(req_net_sel_mode_get(&info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get Net sel mode fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &info, sizeof(mbtk_net_info_t));
+                }
+            }
+            else     // Set
+            {
+                mbtk_net_info_t *info = (mbtk_net_info_t*)pack->data;
+                if(req_net_sel_mode_set(info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Set Net sel mode fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_BAND:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_REQ_PARAMETER;
+                LOG("No data found.");
+            }
+            else     // Set
+            {
+                if(pack->data_len == sizeof(uint8)) {
+                    if(*(pack->data)) { // Get current bands.
+                        mbtk_band_info_t band;
+                        memset(&band, 0x0, sizeof(mbtk_band_info_t));
+                        if(req_band_get(&band, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                err = MBTK_RIL_ERR_CME + cme_err;
+                            } else {
+                                err = MBTK_RIL_ERR_UNKNOWN;
+                            }
+                            LOG("Get net band fail.");
+                        }
+                        else
+                        {
+                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &band, sizeof(mbtk_band_info_t));
+                        }
+                    } else { // Get support bands.
+                        ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &band_info.band_support , sizeof(mbtk_band_info_t));
+                    }
+                } else { // Set current bands.
+                    mbtk_band_info_t* band = (mbtk_band_info_t*)pack->data;
+                    if(pack->data_len != sizeof(mbtk_band_info_t))
+                    {
+                        err = MBTK_RIL_ERR_REQ_PARAMETER;
+                        LOG("Set net band error.");
+                        break;
+                    }
+
+                    if(req_band_set(band, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                            err = MBTK_RIL_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_RIL_ERR_UNKNOWN;
+                        }
+                        LOG("Set net band fail.");
+                    }
+                    else
+                    {
+                        ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                    }
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_SIGNAL:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_signal_info_t signal;
+                memset(&signal, 0, sizeof(mbtk_signal_info_t));
+                if(req_net_signal_get(&signal, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get net signal fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &signal, sizeof(mbtk_signal_info_t));
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+                LOGW("Unsupport set net signal.");
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_REG:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_net_reg_info_t net_reg;
+                memset(&net_reg, 0, sizeof(mbtk_net_reg_info_t));
+                if(req_net_reg_get(&net_reg, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get Net reg info fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &net_reg, sizeof(mbtk_net_reg_info_t));
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+                LOGW("Unsupport set net reg info.");
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_CELL:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_net_info_array_t net_array;
+                memset(&net_array, 0, sizeof(mbtk_net_info_array_t));
+                if(req_available_net_get(&net_array, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get Available Net fail.");
+                }
+                else
+                {
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &net_array, sizeof(mbtk_net_info_array_t));
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+                LOGW("Unsupport set available net.");
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_APN:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_apn_info_array_t apns;
+                memset(&apns, 0, sizeof(mbtk_apn_info_array_t));
+                if(req_apn_get(&apns, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                        err = MBTK_RIL_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_RIL_ERR_UNKNOWN;
+                    }
+                    LOGD("Get APN fail.");
+                }
+                else
+                {
+                    LOGD("size - %d", sizeof(mbtk_apn_info_array_t));
+                    ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &apns, sizeof(mbtk_apn_info_array_t));
+                }
+            }
+            else     // Set
+            {
+                mbtk_apn_info_t *apn = (mbtk_apn_info_t*)pack->data;
+                if(apn_cid_reset(apn)) {
+                    err = MBTK_RIL_ERR_CID;
+                } else {
+                    if(apn_conf_support(apn->cid)) {
+                        if(req_apn_set(apn, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                err = MBTK_RIL_ERR_CME + cme_err;
+                            } else {
+                                err = MBTK_RIL_ERR_UNKNOWN;
+                            }
+                            LOGD("Set APN fail.");
+                        }
+                        else
+                        {
+                            if(apn_prop_set(apn)) {
+                                LOGE("Save APN fail.");
+                            }
+                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                        }
+                    } else {
+                        err = MBTK_RIL_ERR_UNSUPPORTED;
+                        LOGD("Can not set APN for CID : %d", apn->cid);
+                    }
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_NET_DATA_CALL:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_RIL_ERR_UNSUPPORTED;
+            }
+            else     // Set
+            {
+                mbtk_data_call_info_t *call_info = (mbtk_data_call_info_t*)pack->data;
+                if(call_info->type == MBTK_DATA_CALL_START) {
+                    mbtk_ip_info_t ip_info;
+                    memset(&ip_info, 0, sizeof(ip_info));
+                    if(apn_prop_reset(call_info)) {
+                        err = MBTK_RIL_ERR_REQ_UNKNOWN;
+                        LOG("apn_prop_reset() fail.");
+                    } else {
+                        if(req_data_call_start(call_info->cid, call_info->def_route,
+                                call_info->retry_interval, call_info->timeout, &ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                        {
+                            if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                                err = MBTK_RIL_ERR_CME + cme_err;
+                            } else {
+                                err = MBTK_RIL_ERR_UNKNOWN;
+                            }
+                            LOGD("Start data call fail.");
+                        }
+                        else
+                        {
+                            ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
+                        }
+                    }
+                } else if(call_info->type == MBTK_DATA_CALL_STOP) {
+                    if(req_data_call_stop(call_info->cid, call_info->timeout, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                            err = MBTK_RIL_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_RIL_ERR_UNKNOWN;
+                        }
+                        LOGD("Stop data call fail.");
+                    }
+                    else
+                    {
+                        ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, NULL, 0);
+                    }
+                } else {
+                    mbtk_ip_info_t ip_info;
+                    memset(&ip_info, 0, sizeof(ip_info));
+                    if(req_data_call_state_get(call_info->cid ,&ip_info, &cme_err) || cme_err != MBTK_RIL_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_RIL_ERR_CME_NON) {
+                            err = MBTK_RIL_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_RIL_ERR_UNKNOWN;
+                        }
+                        LOGD("Get data call state fail.");
+                    }
+                    else
+                    {
+                        ril_rsp_pack_send(cli_info->fd, pack->msg_id, pack->msg_index, &ip_info, sizeof(mbtk_ip_info_t));
+                    }
+                }
+            }
+            break;
+        }
+        default:
+        {
+            err = MBTK_RIL_ERR_REQ_UNKNOWN;
+            LOG("Unknown request : %s", id2str(pack->msg_id));
+            break;
+        }
+    }
+
+    return err;
+}
+
+
+
+
+
+