Add mbtk ecall v1 API.

Change-Id: Icfdb8ccf399a4e052484f6419e44755780c04725
diff --git a/mbtk/mbtk_rild/src/atchannel.c b/mbtk/mbtk_rild/src/atchannel.c
index a1a9f21..56b1d08 100755
--- a/mbtk/mbtk_rild/src/atchannel.c
+++ b/mbtk/mbtk_rild/src/atchannel.c
@@ -36,7 +36,7 @@
 #define MAX_AT_RESPONSE (8 * 1024)
 #define HANDSHAKE_RETRY_COUNT 20
 #define HANDSHAKE_TIMEOUT_MSEC 500
-#define AT_BUFF_MAX 100
+#define AT_BUFF_MAX 1024
 
 static pthread_t s_tid_reader;
 static int s_at_fd = -1;    /* fd of the AT channel */
diff --git a/mbtk/mbtk_rild/src/mbtk_info_server.c b/mbtk/mbtk_rild/src/mbtk_info_server.c
index f09e33c..27d08d4 100755
--- a/mbtk/mbtk_rild/src/mbtk_info_server.c
+++ b/mbtk/mbtk_rild/src/mbtk_info_server.c
@@ -65,6 +65,7 @@
 
 static mbtk_signal_info_t signal_globe;
 
+mbtk_info_err_enum ecall_pack_req_process(sock_client_info_t* cli_info, mbtk_info_pack_t* pack);
 
 /*
 AT*POWERIND=0"
@@ -596,7 +597,7 @@
         ret = MBTK_SIM_NOT_READY;
         goto done;
     }
-    
+
     /* CPIN? has succeeded, now look at the result */
 
     cpinLine = p_response->p_intermediates->line;
@@ -1220,27 +1221,27 @@
     {
         line = lines_ptr->line;
         char *start = strstr(line, "FALCON_CP_SDK");
-        if(start) 
+        if(start)
         {
             char *end = strstr(start, "_Linux");
-            if(end) 
+            if(end)
             {
-                end += strlen("_Linux"); 
+                end += strlen("_Linux");
                 int length = end - start;
                 if (length)
                 {
                     strncpy(data, start, length);
                     ((char*)data)[length] = '\0';
                     break;
-                } 
+                }
                 else
                 {
                     err = -1;
                     goto exit;
-                    
+
                 }
-            } 
-            else 
+            }
+            else
             {
                 err = -1;
                 goto exit;
@@ -1248,7 +1249,7 @@
         }
         lines_ptr = lines_ptr->p_next;
     }
-    
+
     goto exit;
 exit:
     at_response_free(response);
@@ -1862,7 +1863,7 @@
 {
     ATResponse *response = NULL;
     char cmd[64]={0};
-    
+
     int err = at_send_command_singleline("AT+CLCK=SC,2", "+CLCK:", &response);
     if (err < 0 || response == NULL || response->success == 0 || !response->p_intermediates)
     {
@@ -1886,7 +1887,7 @@
         LOGE("[req_get_pin_state] at_tok_start fail.[%d]", err);
         goto exit;
     }
-    
+
     int clck;
     err = at_tok_nextint(&line, &clck);
     if (err < 0)
@@ -4182,6 +4183,8 @@
         return sms_pack_req_process(cli_info, pack);
     } else if(pack->info_id > MBTK_INFO_ID_PB_BEGIN && pack->info_id < MBTK_INFO_ID_PB_END) {
         return pb_pack_req_process(cli_info, pack);
+    } else if(pack->info_id > RIL_MSG_ID_ECALL_BEGIN && pack->info_id < RIL_MSG_ID_ECALL_END) {
+        return ecall_pack_req_process(cli_info, pack);
     } else {
         mbtk_info_err_enum err = MBTK_INFO_ERR_SUCCESS;
         int cme_err = MBTK_INFO_ERR_CME_NON;
@@ -6773,7 +6776,7 @@
                 strftime(tmp, 50, "%F %T", tm_t);
                 snprintf(buff, sizeof(buff), "%s:%d,%d,%d,%d,%d,%d,%d,%d", tmp, signal.type, signal.rssi, signal.rxlev, signal.ber, signal.rscp, signal.ecno,
                     signal.rsrq, signal.rsrp);
-                mbtk_signal_log(buff);             
+                mbtk_signal_log(buff);
             }
 
             if(signal_globe.type != signal.type)
diff --git a/mbtk/mbtk_rild/src/ril_ecall.c b/mbtk/mbtk_rild/src/ril_ecall.c
new file mode 100755
index 0000000..8d7a5e8
--- /dev/null
+++ b/mbtk/mbtk_rild/src/ril_ecall.c
@@ -0,0 +1,1141 @@
+#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 "mbtk_type.h"
+#include "info_data.h"
+#include "atchannel.h"
+#include "at_tok.h"
+#include "mbtk_utils.h"
+#include "mbtk_info.h"
+
+static mbtk_ecall_mode_type_enum ecall_mode = MBTK_ECALL_MODE_TYPE_EU;
+
+void pack_rsp_send(int fd, int info_id, const void* data, int data_len);
+
+static int req_ecall_msdcfg(mbtk_ecall_msd_cfg_info_t *cfg_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT*ECALLMSDCFG=%d,\"%s\",0", cfg_info->item_type, cfg_info->data);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_msdgen(int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command("AT*ECALLMSDGEN", &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_msd_set(const uint8 *msd, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT*ECALLMSD=\"%s\"", msd);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_msd_get(uint8 *msd, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT*ECALLMSD?", "*ECALLMSD:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *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_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(msd, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+static int req_ecall_push(int *cme_err)
+{
+    ATResponse *response = NULL;
+    int err = at_send_command("AT*ECALLPUSH", &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLONLY?
+*ECALLONLY: 0,0,18981911691,18981911691
+
+OK
+
+*/
+static int req_ecall_only_get(mbtk_ecall_only_info_t *only_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int tmp_int;
+    int err = at_send_command_singleline("AT*ECALLONLY?", "*ECALLONLY:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *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;
+    }
+    only_info->active = (mbtk_ecall_only_type_enum)tmp_int;
+
+    err = at_tok_nextint(&line, &tmp_int);
+    if (err < 0)
+    {
+        goto exit;
+    }
+    only_info->sim_type = (mbtk_ecall_sim_type_enum)tmp_int;
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(only_info->test_num, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    err = at_tok_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(only_info->reconfig_num, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLONLY?
+*ECALLONLY: 0,0,18981911691,18981911691
+
+OK
+
+*/
+static int req_ecall_only_set(const mbtk_ecall_only_info_t *only_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT*ECALLONLY=%d,%s,%s", only_info->active,only_info->test_num,only_info->reconfig_num);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLREG=0/1
+
+*/
+static int req_ecall_reg_set(uint8 reg, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[30] = {0};
+    sprintf(cmd, "AT*ECALLREG=%d", reg);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CECALL?
++CECALL: 4
+
+OK
+
+*/
+static int req_ecall_dial_state_get(mbtk_ecall_dial_type_enum *type, int *cme_err)
+{
+    ATResponse *response = NULL;
+    int tmp_int;
+    int err = at_send_command_singleline("AT+CECALL?", "+CECALL:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *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;
+    }
+    *type = (mbtk_ecall_dial_type_enum)tmp_int;
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT+CECALL=<ecalltype>
+OK
+*/
+static int req_ecall_dial_start(mbtk_ecall_dial_type_enum type, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    sprintf(cmd, "AT+CECALL=%d", type);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+
+/*
+AT*ECALLMODE?
+*ECALLMODE: "ERA"
+
+OK
+
+*/
+static int req_ecall_mode_get(mbtk_ecall_mode_type_enum *mode, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT*ECALLMODE?", "*ECALLMODE:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *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_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        if(strcmp(tmp_ptr, "ERA") == 0) {
+            *mode = MBTK_ECALL_MODE_TYPE_ERA;
+        } else {
+            *mode = MBTK_ECALL_MODE_TYPE_EU;
+        }
+
+        ecall_mode = *mode;
+    } else {
+        err =  -1;
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLMODE="ERA"
+OK
+
+*/
+static int req_ecall_mode_set(mbtk_ecall_mode_type_enum mode, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    if(mode == MBTK_ECALL_MODE_TYPE_EU) {
+        sprintf(cmd, "AT*ECALLMODE=\"EU\"");
+    } else {
+        sprintf(cmd, "AT*ECALLMODE=\"ERA\"");
+    }
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+    ecall_mode = mode;
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLDATA=5,2
+*ECALLDATA: 5,2,250
+
+OK
+
+AT*ECALLTIMER?
+*ECALLTIMER: ERA mode, callback timer: 1200s, dial setup timer: 30s, NAD deregister timer: 7200s, cleardown timer: 3600s, redial attempts count: 10, redial wait timer: 30s, smsprocess: 1, SMS resend timer: 3600s, sms msd send count: 10.
+
+OK
+
+*/
+static int req_ecall_cfg_get(mbtk_ecall_cfg_item_enum type, mbtk_ecall_cfg_info_t *cfg, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int tmp_int;
+    char cmd[1024] = {0};
+    int err = 0;
+
+    cfg->type = type;
+    switch(type)
+    {
+        case MBTK_ECALL_CFG_ITEM_T3:
+        case MBTK_ECALL_CFG_ITEM_T5:
+        case MBTK_ECALL_CFG_ITEM_T6:
+        case MBTK_ECALL_CFG_ITEM_T7:
+        case MBTK_ECALL_CFG_ITEM_TH:
+            snprintf(cmd, sizeof(cmd), "AT*ECALLDATA=5,%d", type);
+
+            err = at_send_command_singleline(cmd, "*ECALLDATA:", &response);
+            break;
+        default:
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER?");
+
+            err = at_send_command_singleline(cmd, "*ECALLTIMER:", &response);
+            break;
+    }
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *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;
+    }
+
+    if(strstr(cmd, "AT*ECALLDATA")) {
+        err = at_tok_nextint(&line, &tmp_int);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        err = at_tok_nextint(&line, &tmp_int);
+        if (err < 0)
+        {
+            goto exit;
+        }
+
+        cfg->data = (uint32)(tmp_int * 20);   // ms
+    } else {
+        // *ECALLTIMER: ERA mode, callback timer: 1200s,
+        // dial setup timer: 30s, NAD deregister timer: 7200s,
+        // cleardown timer: 3600s, redial attempts count: 10,
+        // redial wait timer: 30s, smsprocess: 1, SMS resend timer: 3600s,
+        // sms msd send count: 10.
+
+        if(strstr(line, "ERA mode") != NULL) {
+            ecall_mode = MBTK_ECALL_MODE_TYPE_ERA;
+        } else {
+            ecall_mode = MBTK_ECALL_MODE_TYPE_EU;
+        }
+
+        switch(type)
+        {
+            case MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK:
+            {
+                if((tmp_ptr = strstr(line, "callback timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 16);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN:
+            {
+                if((tmp_ptr = strstr(line, "cleardown timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 17);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_DEREG:
+            {
+                if((tmp_ptr = strstr(line, "deregister timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 18);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_DIAL:
+            {
+                if((tmp_ptr = strstr(line, "dial setup timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 18);   // s
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_REDIAL:
+            {
+                if((tmp_ptr = strstr(line, "redial wait timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 19);   // s
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_TIMER_SMS:
+            {
+                if((tmp_ptr = strstr(line, "SMS resend timer: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 18);
+                    cfg->data *= 1000; // s -> ms
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_REDIALCNT:
+            {
+                if((tmp_ptr = strstr(line, "redial attempts count: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 23);
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_SMSPROCESS:
+            {
+                if((tmp_ptr = strstr(line, "smsprocess: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 12);
+                }
+                break;
+            }
+            case MBTK_ECALL_CFG_ITEM_SMSMSDCNT:
+            {
+                if((tmp_ptr = strstr(line, "sms msd send count: ")) != NULL) {
+                    cfg->data = (uint32)atoi(tmp_ptr + 20);
+                }
+                break;
+            }
+            default:
+                LOGE("Unknown config item : %d", type);
+                err = -1;
+                break;
+        }
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLDATA=5,2,250
+OK
+
+AT*ECALLTIMER=dereg,300
+OK
+*/
+static int req_ecall_cfg_set(const mbtk_ecall_cfg_info_t *cfg_info, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[1024] = {0};
+    int err = 0;
+
+    if(ecall_mode == MBTK_ECALL_MODE_TYPE_EU) {
+        if(cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK
+            && cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_DIAL
+            && cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_DEREG
+            && cfg_info->type != MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN){
+            LOGW("No support for EU.");
+            return -1;
+        }
+    }
+
+    switch(cfg_info->type)
+    {
+        case MBTK_ECALL_CFG_ITEM_T3:
+        case MBTK_ECALL_CFG_ITEM_T5:
+        case MBTK_ECALL_CFG_ITEM_T6:
+        case MBTK_ECALL_CFG_ITEM_T7:
+        case MBTK_ECALL_CFG_ITEM_TH:
+            snprintf(cmd, sizeof(cmd), "AT*ECALLDATA=5,%d,%d", cfg_info->type, cfg_info->data / 20);
+            break;
+        case MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=callback,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=cleardown,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_DEREG:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=dereg,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_DIAL:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=dial,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_REDIAL:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=redialtmr,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_TIMER_SMS:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=sms,%d", cfg_info->data / 1000);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_REDIALCNT:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=redialcnt,%d", cfg_info->data);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_SMSPROCESS:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=smsprocess,%d", cfg_info->data);
+            break;
+        }
+        case MBTK_ECALL_CFG_ITEM_SMSMSDCNT:
+        {
+            snprintf(cmd, sizeof(cmd), "AT*ECALLTIMER=smsmsdcnt,%d", cfg_info->data);
+            break;
+        }
+        default:
+            LOGE("Unknown config item : %d", cfg_info->type);
+            err = -1;
+            goto exit;
+    }
+
+    err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLMUTESPK=1
+OK
+
+*/
+static int req_ecall_spkmute_set(int mute, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    sprintf(cmd, "AT*ECALLMUTESPK=%d", mute);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+
+/*
+AT*ECALLSMSNUM?
+*ECALLSMSNUM: "18981991452"
+
+OK
+
+*/
+static int req_ecall_sms_num_get(uint8 *number, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char *tmp_ptr = NULL;
+    int err = at_send_command_singleline("AT*ECALLSMSNUM?", "*ECALLSMSNUM:", &response);
+
+    if (err < 0 || response->success == 0 || !response->p_intermediates){
+        *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_nextstr(&line, &tmp_ptr);
+    if (err < 0)
+    {
+        goto exit;
+    }
+
+    if(tmp_ptr && strlen(tmp_ptr) > 0) {
+        memcpy(number, tmp_ptr, strlen(tmp_ptr));
+    }
+
+    goto exit;
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*ECALLSMSNUM=18981991452
+OK
+
+*/
+static int req_ecall_sms_num_set(const uint8 *number, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    sprintf(cmd, "AT*ECALLSMSNUM=%s", number);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+exit:
+    at_response_free(response);
+    return err;
+}
+
+/*
+AT*AUDGAIN=8,1 // Set Rx voice gain = 8dB
+OK
+
+*/
+static int req_ecall_gain_set(mbtk_ecall_gain_info_t *gain, int *cme_err)
+{
+    ATResponse *response = NULL;
+    char cmd[100] = {0};
+    sprintf(cmd, "AT*AUDGAIN=%d,%d", gain->gain, gain->mode);
+    int err = at_send_command(cmd, &response);
+    if (err < 0 || response->success == 0){
+        *cme_err = at_get_cme_error(response);
+        goto exit;
+    }
+
+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_info_err_enum ecall_pack_req_process(sock_client_info_t* cli_info, mbtk_info_pack_t* pack)
+{
+    mbtk_info_err_enum err = MBTK_INFO_ERR_SUCCESS;
+    int cme_err = MBTK_INFO_ERR_CME_NON;
+    switch(pack->info_id)
+    {
+        case RIL_MSG_ID_ECALL_MSDCFG_REQ:       // mbtk_ecall_msd_cfg_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            else     // Set
+            {
+                mbtk_ecall_msd_cfg_info_t *cfg_info = (mbtk_ecall_msd_cfg_info_t*)(pack->data);
+                if(req_ecall_msdcfg(cfg_info, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLMSDCFG fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MSDCFG_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MSDGEN_REQ:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_msdgen(&cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLMSDGEN fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MSDGEN_RSP, NULL, 0);
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MSD_REQ: // uint8[]
+        {
+            uint8 msd[MBTK_ECALL_MSD_LEN_MAX];
+            memset(msd, 0, sizeof(msd));
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_msd_get(msd, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Get MSD fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MSD_RSP, msd, strlen(msd));
+                }
+            }
+            else     // Set
+            {
+                memcpy(msd, pack->data, pack->data_len);
+                if(req_ecall_msd_set(msd, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLMSD fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MSD_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_PUSH_REQ:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_push(&cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLPUSH fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_PUSH_RSP, NULL, 0);
+                }
+            }
+            else     // Set
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_ONLY_REQ:     // mbtk_ecall_only_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_ecall_only_info_t only_info;
+                memset(&only_info, 0, sizeof(mbtk_ecall_only_info_t));
+                if(req_ecall_only_get(&only_info, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall only mode fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_ONLY_RSP, &only_info, sizeof(mbtk_ecall_only_info_t));
+                }
+            }
+            else     // Set
+            {
+                mbtk_ecall_only_info_t *only_info = (mbtk_ecall_only_info_t*)(pack->data);
+                if(req_ecall_only_set(only_info, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("AT*ECALLONLY fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_ONLY_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_REG_REQ:  // reg <uint8>
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            else
+            {
+                uint8 reg = pack->data[0];
+                if(req_ecall_reg_set(reg, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("ecall reg(%d) fail.", reg);
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_REG_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_DIAL_REQ: // mbtk_ecall_dial_type_enum
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_ecall_dial_type_enum type;
+                if(req_ecall_dial_state_get(&type, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall type fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_DIAL_RSP, &type, sizeof(uint8));
+                }
+            }
+            else
+            {
+                mbtk_ecall_dial_type_enum type = (mbtk_ecall_dial_type_enum)pack->data[0];
+                if(req_ecall_dial_start(type, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Start ecall %d fail.", type);
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_DIAL_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MODE_REQ:  // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                mbtk_ecall_mode_type_enum mode;
+                if(req_ecall_mode_get(&mode, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall mode fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MODE_RSP, &mode, sizeof(uint8));
+                }
+            }
+            else
+            {
+                mbtk_ecall_mode_type_enum mode = (mbtk_ecall_mode_type_enum)pack->data[0];
+                if(req_ecall_mode_set(mode, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Set ecall mode %d fail.", mode);
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MODE_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_CFG_REQ:  // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            else
+            {
+                if(pack->data_len == sizeof(mbtk_ecall_cfg_info_t)) { // Set
+                    mbtk_ecall_cfg_info_t *cfg_info = (mbtk_ecall_cfg_info_t*)pack->data;
+                    if(req_ecall_cfg_set(cfg_info, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                            err = MBTK_INFO_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_INFO_ERR_UNKNOWN;
+                        }
+                        LOG("Set ecall config[%d] fail.", cfg_info->type);
+                    }
+                    else
+                    {
+                        pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_CFG_RSP, NULL, 0);
+                    }
+                } else { // Get
+                    mbtk_ecall_cfg_info_t cfg_info;
+                    memset(&cfg_info, 0, sizeof(mbtk_ecall_cfg_info_t));
+                    mbtk_ecall_cfg_item_enum type = (mbtk_ecall_cfg_item_enum)pack->data[0];
+                    if(req_ecall_cfg_get(type, &cfg_info, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                    {
+                        if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                            err = MBTK_INFO_ERR_CME + cme_err;
+                        } else {
+                            err = MBTK_INFO_ERR_UNKNOWN;
+                        }
+                        LOG("Get ecall config[%d] fail.", type);
+                    }
+                    else
+                    {
+                        pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_CFG_RSP, &cfg_info, sizeof(mbtk_ecall_cfg_info_t));
+                    }
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_SMS_NUM_REQ: // uint8[]
+        {
+            uint8 number[RIL_MAX_NUMBER_LEN];
+            memset(number, 0, sizeof(number));
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                if(req_ecall_sms_num_get(number, &cme_err) || strlen(number) == 0 || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Get ecall sms number fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_SMS_NUM_RSP, number, strlen(number));
+                }
+            }
+            else     // Set
+            {
+                memcpy(number, pack->data, pack->data_len);
+                if(req_ecall_sms_num_set(number, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Set ecall sms number fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_SMS_NUM_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_MUTESPK_REQ:
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            else     // Set mute state.
+            {
+                uint8 mute = pack->data[0];
+                if(pack->data_len != sizeof(uint8) || (mute != 0 && mute != 1))
+                {
+                    err = MBTK_INFO_ERR_REQ_PARAMETER;
+                    LOG("Set spk mute parameter error.");
+                    break;
+                }
+
+                if(req_ecall_spkmute_set(mute, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOG("Set spk mute state fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_MUTESPK_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        case RIL_MSG_ID_ECALL_DSP_GAIN_REQ: // mbtk_ecall_gain_info_t
+        {
+            if(pack->data_len == 0 || pack->data == NULL)
+            {
+                err = MBTK_INFO_ERR_UNSUPPORTED;
+            }
+            else     // Set
+            {
+                mbtk_ecall_gain_info_t *gain_info = (mbtk_ecall_gain_info_t *)pack->data;
+                if(req_ecall_gain_set(gain_info, &cme_err) || cme_err != MBTK_INFO_ERR_CME_NON)
+                {
+                    if(cme_err != MBTK_INFO_ERR_CME_NON) {
+                        err = MBTK_INFO_ERR_CME + cme_err;
+                    } else {
+                        err = MBTK_INFO_ERR_UNKNOWN;
+                    }
+                    LOGE("Set ecall gain fail.");
+                }
+                else
+                {
+                    pack_rsp_send(cli_info->fd, RIL_MSG_ID_ECALL_DSP_GAIN_RSP, NULL, 0);
+                }
+            }
+            break;
+        }
+        default:
+        {
+            err = MBTK_INFO_ERR_REQ_UNKNOWN;
+            LOG("Unknown request : %s", id2str(pack->info_id));
+            break;
+        }
+    }
+
+    return err;
+}
+
+
+