Add ril v2 support.

Change-Id: I14f4d5f3650f0d397c38a72e8bea2600c17b07de
diff --git a/mbtk/libmbtk_lib_v2/Makefile b/mbtk/libmbtk_lib_v2/Makefile
index 295f873..2883152 100755
--- a/mbtk/libmbtk_lib_v2/Makefile
+++ b/mbtk/libmbtk_lib_v2/Makefile
@@ -16,11 +16,12 @@
 	-I$(LOCAL_PATH)/mqtt/MQTTPacket \
 	-I$(LOCAL_PATH)/net \
 	-I$(LOCAL_PATH)/tcpip \
-	-I$(LOCAL_PATH)/ril
+	-I$(LOCAL_PATH)/ril \
+	-I$(LOCAL_PATH)/wifi
 
 LIB_DIR +=
 
-LIBS += -llog -lubus -lubox -luci -lprop2uci -lrilutil -lblobmsg_json -ldl -lcutils -laudio-apu  -lssl -lcrypto
+LIBS += -llog -lubus -lubox -luci -lprop2uci -lrilutil -lblobmsg_json -ldl -lcutils -laudio-apu  -lssl -lcrypto -lwpa_client
 
 ifeq ($(BUILD_LIB_TYPE), shared)
 CFLAGS += -shared -Wl,-shared,-Bsymbolic
@@ -64,6 +65,7 @@
 	common/mbtk_device_info.c \
 	common/mbtk_version.c \
 	common/mbtk_gpio.c \
+	common/mbtk_adc.c \
 	common/mbtk_debug.c
 
 # audio
@@ -134,6 +136,11 @@
 # tcpip
 LOCAL_SRC_FILES += \
     tcpip/mbtk_tcpip_at.c
+    
+#wifi
+LOCAL_SRC_FILES += \
+    wifi/sta_cli.c \
+	wifi/sta_ctrl.c 
 
 
 OBJS = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(LOCAL_SRC_FILES)))
diff --git a/mbtk/libmbtk_lib_v2/common/mbtk_adc.c b/mbtk/libmbtk_lib_v2/common/mbtk_adc.c
new file mode 100755
index 0000000..55cce7c
--- /dev/null
+++ b/mbtk/libmbtk_lib_v2/common/mbtk_adc.c
@@ -0,0 +1,102 @@
+/**
+ *   \file mbtk_adc.c
+ *   \brief A Documented file.
+ *
+ *  Detailed description
+ *   \Author:  js.wang <js.wang@mobiletek.cn>
+ *   \Version: 1.0.0
+ *   \Date: 2022-04-22
+ */
+#include <fcntl.h>
+#include <stdint.h>
+#include <limits.h>
+#include <termios.h>
+#include <stdarg.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include "mbtk_log.h"
+#include "mbtk_type.h"
+#include "mbtk_adc.h"
+
+int mbtk_adc_close(const char* adc_dev)
+{
+    int ret = 0;
+    int fd = 0;
+    char adc = '3';
+    //system("echo 3 > /sys/kernel/debug/adc");
+    if(adc_dev != NULL && !access(adc_dev, R_OK))
+    {
+        //LOGI("DEV:%s", ADC_DEVICE_803);
+        fd = open(adc_dev, O_RDWR|O_CREAT|O_TRUNC, 0644);
+    }
+    else
+    {
+        LOGE("No found ADC devices.");
+        return -1;
+    }
+
+    if(fd < 0) {
+        LOGE("[%s]  file open error\n", __FUNCTION__);
+        return -2;
+    }
+    ret = write(fd, &adc, 1);
+    if (ret < 0) {
+        LOGE("%s: error writing to file!\n", __FUNCTION__);
+        close(fd);
+        return -2;
+    }
+    close(fd);
+    return 0;
+}
+
+int mbtk_adc_get(const char* adc_dev, mbtk_adc_enum channle)
+{
+    int ret = 0;
+    int fd = 0;
+    char adc_buf[24] = {0};
+    char *adc_value = NULL;
+    char adc =(channle == MBTK_ADC0 ? '0' : (channle == MBTK_ADC1 ? '1' : '2'));
+
+
+    if(adc_dev != NULL && !access(adc_dev, R_OK))
+    {
+        LOGI("[adc] DEV:%s", adc_dev);
+        fd = open(adc_dev, O_RDWR|O_CREAT|O_TRUNC, 0644);
+    }
+    else
+    {
+        LOGE("No found ADC devices : %s", adc_dev ? adc_dev : "NULL");
+        return -1;
+    }
+
+    if(fd < 0) {
+        LOGE("[%s]  file open error\n", __FUNCTION__);
+        return -2;
+    }
+    ret = write(fd, &adc, 1);
+    if (ret < 0) {
+        LOGE("%s: error writing to file!\n", __FUNCTION__);
+        close(fd);
+        return -2;
+    }
+    ret = read(fd, adc_buf, 24);
+    if (ret < 0) {
+        LOGE("%s: error writing to file!\n", __FUNCTION__);
+        close(fd);
+        return -2;
+    }else{
+        //LOGI("%s %d adc:%s\n", __FUNCTION__, __LINE__, adc_buf);
+        adc_value = strstr(adc_buf, "channel");
+    }
+    close(fd);
+    if(adc_value)
+    {
+        //LOGI("%s adc: %s\n", __FUNCTION__, adc_value);
+    }
+    else
+        return -2;
+
+    return atoi(&adc_value[9]);
+}
diff --git a/mbtk/libmbtk_lib_v2/common/mbtk_gpio.c b/mbtk/libmbtk_lib_v2/common/mbtk_gpio.c
index 0116f60..d80b014 100755
--- a/mbtk/libmbtk_lib_v2/common/mbtk_gpio.c
+++ b/mbtk/libmbtk_lib_v2/common/mbtk_gpio.c
@@ -12,7 +12,7 @@
 #include "mbtk_gpio.h"
 
 
-static int gpio_export(int gpio)
+int gpio_export(int gpio)
 {
     int fd = -1;
     char buffer[50];
@@ -44,7 +44,7 @@
     return 0;
 }
 
-static int gpio_unexport(int gpio)
+int gpio_unexport(int gpio)
 {
     int fd = -1;
     char buffer[50];
diff --git a/mbtk/libmbtk_lib_v2/ril/mbtk_ril.h b/mbtk/libmbtk_lib_v2/ril/mbtk_ril.h
index 04b5623..b8b21b5 100755
--- a/mbtk/libmbtk_lib_v2/ril/mbtk_ril.h
+++ b/mbtk/libmbtk_lib_v2/ril/mbtk_ril.h
@@ -13,6 +13,10 @@
 #define RIL_SOCK_NAME "/tmp/mbtk_ril_sock"
 #define RIL_SOCK_MSG_LEN_MAX (1024 * 6)
 
+#define IND_REGISTER_MAX 20
+#define PACK_PROCESS_QUEUE_MAX 20
+
+
 // Tag(4) + Packet_Length(2)
 #define RIL_SOCK_PACK_EXTRA_LEN 6
 // RIL_SOCK_PACK_EXTRA_LEN + Index(2) + Type(2) + Id(2) + Error(2) + data_len(2)
@@ -31,7 +35,7 @@
 typedef enum
 {
     // Device Information
-    RIL_MSG_ID_DEV_BEGIN = 0,
+    RIL_MSG_ID_DEV_BEGIN = 0x0,
     // <string> IMEI
     RIL_MSG_ID_DEV_IMEI,
     // <string> SN
@@ -54,7 +58,7 @@
     RIL_MSG_ID_DEV_END,
 
     // Sim Information
-    RIL_MSG_ID_SIM_BEGIN = 1000,
+    RIL_MSG_ID_SIM_BEGIN = 0x100,
     // <uint8> 0:NOT_EXIST 1:READY ...
     RIL_MSG_ID_SIM_STATE,
     // <uint8> 0: SIM 1: USIM 2: TEST SIM 3: TEST USIM 4: UNKNOWN
@@ -75,7 +79,7 @@
     RIL_MSG_ID_SIM_END,
 
     // Network Information
-    RIL_MSG_ID_NET_BEGIN = 2000,
+    RIL_MSG_ID_NET_BEGIN = 0x200,
     // sel_mode(uint8)type(uint8)plmn(uint32)...sel_mode(uint8)type(uint8)plmn(uint32)
     RIL_MSG_ID_NET_AVAILABLE,
     // <uint8> 0: automatic 1: manual
@@ -90,8 +94,14 @@
     RIL_MSG_ID_NET_REG,
     // mbtk_cell_info_t[]
     RIL_MSG_ID_NET_CELL,
+
+    RIL_MSG_ID_NET_END,
+
+
+    // Network Information
+    RIL_MSG_ID_DATA_CALL_BEGIN = 0x300,
     // mbtk_apn_info_t
-    RIL_MSG_ID_NET_APN,
+    RIL_MSG_ID_DATA_CALL_APN,
     // REQ:
     // <call_type[1]><cid[1]><timeout[1]>
     //  call_type : mbtk_data_call_type_enum
@@ -102,13 +112,13 @@
     //  type : 0-IPV4   1-IPV6  2-IPV4V6
     //  ipv4 : mbtk_ipv4_info_t
     //  ipv6 : mbtk_ipv6_info_t
-    RIL_MSG_ID_NET_DATA_CALL,
+    RIL_MSG_ID_DATA_CALL_OPT,
 
-    RIL_MSG_ID_NET_END,
+    RIL_MSG_ID_DATA_CALL_END,
 
 
     // Call Information
-    RIL_MSG_ID_CALL_BEGIN = 3000,
+    RIL_MSG_ID_CALL_BEGIN = 0x400,
     RIL_MSG_ID_CALL_STATE,
 
     // Start call.
@@ -132,7 +142,7 @@
     RIL_MSG_ID_CALL_END,
 
     // SMS Information
-    RIL_MSG_ID_SMS_BEGIN = 4000,
+    RIL_MSG_ID_SMS_BEGIN = 0x500,
     RIL_MSG_ID_SMS_STATE,
     RIL_MSG_ID_SMS_CMGF,
     RIL_MSG_ID_SMS_CPMS,
@@ -150,33 +160,71 @@
     RIL_MSG_ID_SMS_END,
 
     // PhoneBook Information
-    RIL_MSG_ID_PB_BEGIN = 5000,
+    RIL_MSG_ID_PB_BEGIN = 0x600,
     RIL_MSG_ID_PB_STATE,
 
     RIL_MSG_ID_PB_END,
 
-    // IND Information
-    RIL_MSG_ID_IND_BEGIN = 10000,
+    // Ecall Information
+    RIL_MSG_ID_ECALL_BEGIN = 0x700,
+    // mbtk_ecall_msd_cfg_info_t
+    RIL_MSG_ID_ECALL_MSDCFG,
     // NULL
-    RIL_MSG_ID_IND_SER_READY,
-    // <uint8>  State
-    RIL_MSG_ID_IND_NET_STATE_CHANGE,
+    RIL_MSG_ID_ECALL_MSDGEN,
+    // uint8[]
+    RIL_MSG_ID_ECALL_MSD,
+    // NULL
+    RIL_MSG_ID_ECALL_PUSH,
+    // mbtk_ecall_only_info_t
+    RIL_MSG_ID_ECALL_ONLY,
+    // reg <uint8>
+    RIL_MSG_ID_ECALL_REG,
+    // mbtk_ecall_dial_type_enum
+    RIL_MSG_ID_ECALL_DIAL,
+    // mbtk_ecall_mode_type_enum
+    RIL_MSG_ID_ECALL_MODE,
+    // mbtk_ecall_cfg_item_enum / mbtk_ecall_cfg_info_t
+    RIL_MSG_ID_ECALL_CFG,
+    // uint8[]
+    RIL_MSG_ID_ECALL_SMS_NUM,
+    // uint8
+    RIL_MSG_ID_ECALL_MUTESPK,
+    // mbtk_ecall_gain_info_t
+    RIL_MSG_ID_ECALL_DSP_GAIN,
+
+    RIL_MSG_ID_ECALL_END,
+
+    // IND Information
+    RIL_MSG_ID_IND_BEGIN = 0x1000,
+    // mbtk_ril_ser_state_enum
+    RIL_MSG_ID_IND_SER_STATE_CHANGE,
+    // mbtk_ril_net_reg_state_info_t
+    RIL_MSG_ID_IND_NET_REG_STATE_CHANGE,
     // <uint8>  State
     RIL_MSG_ID_IND_CALL_STATE_CHANGE,
     // <uint8>  State
     RIL_MSG_ID_IND_SMS_STATE_CHANGE,
-    // <uint8>  State
+    // mbtk_ril_radio_state_info_t
     RIL_MSG_ID_IND_RADIO_STATE_CHANGE,
-    // <uint8>  State
+    // mbtk_ril_sim_state_info_t
     RIL_MSG_ID_IND_SIM_STATE_CHANGE,
-    // <uint8>  State
+    // mbtk_ril_pdp_state_info_t
     RIL_MSG_ID_IND_PDP_STATE_CHANGE,
-    // <uint8> State
+    // mbtk_ril_signal_state_info_t
     RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE,
+    // mbtk_ril_ecall_state_info_t
+    RIL_MSG_ID_IND_ECALL_STATE_CHANGE,
 
 
     RIL_MSG_ID_IND_END,
-    RIL_MSG_ID_UNKNOWN        // Unknown information.
+
+    // URC message
+    RIL_URC_MSG_BEGIN = 0x2000,
+    RIL_URC_MSG_GET_SIM_STATE,     //check sim status
+    RIL_URC_MSG_NET_STATE_LOG,      // Save Network state into file.
+    RIL_URC_MSG_END,
+
+    RIL_MSG_ID_UNKNOWN = 0xFFFF        // Unknown information.
 } ril_msg_id_enum;
 
 typedef struct {
diff --git a/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c b/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c
index 93efd84..b6b61ca 100755
--- a/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c
+++ b/mbtk/libmbtk_lib_v2/ril/mbtk_ril_api.c
@@ -21,6 +21,7 @@
     int cli_fd;
     bool ril_ready;
     int exit_fd[2];
+    mbtk_ril_callback_func cb[IND_REGISTER_MAX];
     pthread_t read_thread_id;
     pthread_mutex_t send_mutex;
     list_node_t* msg_list;           // ril_msg_info_t
@@ -110,13 +111,24 @@
 
 static int ril_ind_process(ril_msg_pack_info_t* pack)
 {
+    LOGD("IND - %d", id2str(pack->msg_id));
+    if(pack->msg_id > RIL_MSG_ID_IND_BEGIN && pack->msg_id < RIL_MSG_ID_IND_END) {
+        if(ril_cli.cb[pack->msg_id - RIL_MSG_ID_IND_BEGIN - 1])
+            ril_cli.cb[pack->msg_id - RIL_MSG_ID_IND_BEGIN - 1](pack->data, pack->data_len);
+    }
+
     switch(pack->msg_id) {
-        case RIL_MSG_ID_IND_SER_READY: // rild service ready.
+        case RIL_MSG_ID_IND_SER_STATE_CHANGE: // rild service ready.
         {
-            ril_cli.ril_ready = TRUE;
+            if(pack->data && pack->data_len > 0) {
+                mbtk_ril_ser_state_enum state = (mbtk_ril_ser_state_enum)pack->data[0];
+                if(state == MBTK_RIL_SER_STATE_READY) {
+                    ril_cli.ril_ready = TRUE;
+                }
+            }
             return 0;
         }
-        case RIL_MSG_ID_IND_NET_STATE_CHANGE:
+        case RIL_MSG_ID_IND_NET_REG_STATE_CHANGE:
         {
             return 0;
         }
@@ -255,6 +267,10 @@
                 if(epoll_events[i].events & EPOLLHUP)   // Closed by server.
                 {
                     LOGD("Closed by server.");
+                    if(ril_cli.cb[RIL_MSG_ID_IND_SER_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1]) {
+                        mbtk_ril_ser_state_enum state = MBTK_RIL_SER_STATE_EXIT;
+                        ril_cli.cb[RIL_MSG_ID_IND_SER_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1](&state, 1);
+                    }
                     goto read_thread_exit;
                 }
                 else if(epoll_events[i].events & EPOLLIN)
@@ -1256,7 +1272,7 @@
         return MBTK_RIL_ERR_PARAMETER;
     }
 
-    return ril_req_process(RIL_MSG_ID_NET_APN, NULL, 0, apns, FALSE);
+    return ril_req_process(RIL_MSG_ID_DATA_CALL_APN, NULL, 0, apns, FALSE);
 }
 
 
@@ -1286,14 +1302,15 @@
         }
     }
 
-    return ril_req_process(RIL_MSG_ID_NET_APN, apn, sizeof(mbtk_apn_info_t), NULL, FALSE);
+    return ril_req_process(RIL_MSG_ID_DATA_CALL_APN, apn, sizeof(mbtk_apn_info_t), NULL, FALSE);
 }
 
 /*
 * Start data call.
 */
 mbtk_ril_err_enum mbtk_data_call_start(mbtk_ril_cid_enum cid, bool auto_boot_call,
-            bool def_route, bool as_dns, int retry_interval, int timeout, mbtk_ip_info_t *rsp_info)
+            bool def_route, bool as_dns, int *retry_interval, int retry_interval_num,
+            int timeout, mbtk_ip_info_t *rsp_info)
 {
     if(!ril_cli.ril_ready)
     {
@@ -1311,12 +1328,18 @@
     info.auto_boot_call = (uint8)auto_boot_call;
     info.def_route = (uint8)def_route;
     info.as_dns = (uint8)as_dns;
-    info.retry_interval = (uint16)retry_interval;
+    int i = 0;
+    while(i < retry_interval_num && i < RIL_DATA_CALL_RETRY_MAX) {
+        info.retry_interval[i] = (uint16)retry_interval[i];
+        i++;
+    }
     if(timeout > 0) {
         info.timeout = (uint16)timeout;
+    } else {
+        info.timeout = (uint16)10;
     }
 
-    return ril_req_process(RIL_MSG_ID_NET_DATA_CALL, &info, sizeof(mbtk_data_call_info_t), rsp_info, FALSE);
+    return ril_req_process(RIL_MSG_ID_DATA_CALL_OPT, &info, sizeof(mbtk_data_call_info_t), rsp_info, FALSE);
 }
 
 /*
@@ -1340,7 +1363,7 @@
     if(timeout > 0) {
         info.timeout = (uint16)timeout;
     }
-    return ril_req_process(RIL_MSG_ID_NET_DATA_CALL, &info, sizeof(mbtk_data_call_info_t), NULL, FALSE);
+    return ril_req_process(RIL_MSG_ID_DATA_CALL_OPT, &info, sizeof(mbtk_data_call_info_t), NULL, FALSE);
 }
 
 /*
@@ -1368,7 +1391,7 @@
     info.type = MBTK_DATA_CALL_STATE;
     info.cid = cid;
 
-    return ril_req_process(RIL_MSG_ID_NET_DATA_CALL, &info, sizeof(mbtk_data_call_info_t), ip, FALSE);
+    return ril_req_process(RIL_MSG_ID_DATA_CALL_OPT, &info, sizeof(mbtk_data_call_info_t), ip, FALSE);
 }
 
 /*
@@ -2108,6 +2131,344 @@
     return ril_req_process(RIL_MSG_ID_CALL_DTMF, dtmf_character, sizeof(mbtk_call_dtmf_info_t), NULL, FALSE);
 }
 
+/*
+* Set msd item.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_msd_item_set(const mbtk_ecall_msd_cfg_info_t *msd_cfg)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(msd_cfg == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MSDCFG, msd_cfg, sizeof(mbtk_ecall_msd_cfg_info_t), NULL, FALSE);
+}
+
+/*
+* Generate msd after msd item set.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_msd_gen()
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MSDGEN, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Set ecall msd.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_msd_set(const void* msd)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(str_empty(msd))
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MSD, msd, strlen(msd), NULL, FALSE);
+}
+
+/*
+* Get ecall msd.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_msd_get(void* msd)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(msd == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MSD, NULL, 0, msd, FALSE);
+}
+
+
+/*
+* Set ecall msd item.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_push()
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_PUSH, NULL, 0, NULL, FALSE);
+}
+
+/*
+* Set ecall only configs.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_only_set(const mbtk_ecall_only_info_t* info)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(info == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_ONLY, info, sizeof(mbtk_ecall_only_info_t), NULL, FALSE);
+}
+
+/*
+* Get ecall only configs.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_only_get(mbtk_ecall_only_info_t* info)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(info == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_ONLY, NULL, 0, info, FALSE);
+}
+
+/*
+* Set ecall network reg.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_reg_set(int reg)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(reg != 0 && reg != 1)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+    return ril_req_process(RIL_MSG_ID_ECALL_REG, &reg, 1, NULL, FALSE);
+}
+
+/*
+* Start ecall dial start.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_dial_start(mbtk_ecall_dial_type_enum type)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_DIAL, &type, 1, NULL, FALSE);
+}
+
+/*
+* Get ecall dial state.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_dial_state_get(mbtk_ecall_dial_type_enum* type)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(type == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+    memset(type, 0, sizeof(mbtk_ecall_dial_type_enum));
+
+    return ril_req_process(RIL_MSG_ID_ECALL_DIAL, NULL, 0, type, FALSE);
+}
+
+/*
+* Set ecall mode.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_mode_set(mbtk_ecall_mode_type_enum mode)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MODE, &mode, 1, NULL, FALSE);
+}
+
+/*
+* Get ecall mode.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_mode_get(mbtk_ecall_mode_type_enum *mode)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(mode == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+    memset(mode, 0, sizeof(mbtk_ecall_mode_type_enum));
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MODE, NULL, 0, mode, FALSE);
+}
+
+/*
+* Set ecall configs.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_cfg_set(const mbtk_ecall_cfg_info_t *cfg)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(cfg == NULL || cfg->type >= MBTK_ECALL_CFG_ITEM_MAX)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_CFG, cfg, sizeof(mbtk_ecall_cfg_info_t), NULL, FALSE);
+}
+
+/*
+* Get ecall configs.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_cfg_get(mbtk_ecall_cfg_info_t* cfg)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(cfg == NULL || cfg->type >= MBTK_ECALL_CFG_ITEM_MAX)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+    mbtk_ecall_cfg_item_enum type = cfg->type;
+
+    return ril_req_process(RIL_MSG_ID_ECALL_CFG, &type, 1, cfg, FALSE);
+}
+
+/*
+* Set ecall sms number.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_sms_number_set(const void *number)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(str_empty(number))
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_SMS_NUM, number, strlen(number), NULL, FALSE);
+}
+
+/*
+* Get ecall sms number.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_sms_number_get(void *number)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(number == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_SMS_NUM, NULL, 0, number, FALSE);
+}
+
+/*
+* Set ecall mute speaker.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_mute_spk_set(int mute)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(mute != 0 && mute != 1)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_MUTESPK, &mute, 1, NULL, FALSE);
+}
+
+/*
+* Set ecall dsp gain.
+*
+*/
+mbtk_ril_err_enum mbtk_ecall_dsp_gain_set(const mbtk_ecall_gain_info_t *gain_info)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    if(gain_info == NULL)
+    {
+        LOGE("ARG error.");
+        return MBTK_RIL_ERR_PARAMETER;
+    }
+
+    return ril_req_process(RIL_MSG_ID_ECALL_DSP_GAIN, gain_info, sizeof(mbtk_ecall_gain_info_t), NULL, FALSE);
+}
 
 #if 0
 /*
@@ -2156,151 +2517,163 @@
 
 #endif
 
-#if 0
 /*
-* Set pdp state change callback function.
+* Set ril server state change callback function.
 */
-int mbtk_pdp_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_ril_ser_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_PDP_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_SER_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_SER_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
-    {
-        handle->pdp_state_cb = cb;
-        return 0;
-    }
+    return ret;
 }
 
 /*
-* Set network state change callback function.
+* Set net reg state change callback function.
 */
-int mbtk_net_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_net_reg_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_NET_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_NET_REG_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_NET_REG_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
-    {
-        handle->net_state_cb = cb;
-        return 0;
-    }
+    return ret;
 }
 
 /*
 * Set call state change callback function.
 */
-int mbtk_call_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_call_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_CALL_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_CALL_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_CALL_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
-    {
-        handle->call_state_cb = cb;
-        return 0;
-    }
+    return ret;
 }
 
 /*
 * Set sms state change callback function.
 */
-int mbtk_sms_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_sms_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_SMS_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_SMS_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_SMS_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
-    {
-        handle->sms_state_cb = cb;
-        return 0;
-    }
+    return ret;
 }
 
 /*
 * Set radio state change callback function.
 */
-int mbtk_radio_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_radio_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_RADIO_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_RADIO_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_RADIO_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
-    {
-        handle->radio_state_cb = cb;
-        return 0;
-    }
+    return ret;
 }
 
 /*
 * Set sim state change callback function.
 */
-int mbtk_sim_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_sim_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_SIM_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_SIM_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_SIM_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
+    return ret;
+}
+
+/*
+* Set pdp state change callback function.
+*/
+int mbtk_pdp_state_change_cb_reg(mbtk_ril_callback_func cb)
+{
+    if(!ril_cli.ril_ready)
     {
-        handle->sim_state_cb = cb;
-        return 0;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_PDP_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
+    {
+        ril_cli.cb[RIL_MSG_ID_IND_PDP_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
+    }
+    return ret;
 }
 
 /*
 * Set signal state change callback function.
 */
-int mbtk_signal_state_change_cb_reg(mbtk_info_handle_t* handle, mbtk_info_callback_func cb)
+int mbtk_signal_state_change_cb_reg(mbtk_ril_callback_func cb)
 {
-    if(handle == NULL)
+    if(!ril_cli.ril_ready)
     {
-        LOGE("ARG error.");
-        return -1;
+        return MBTK_RIL_ERR_NOT_INIT;
     }
-    if(info_item_process(handle, MBTK_INFO_ID_IND_SIGNAL_STATE_CHANGE, NULL, 0, NULL) < 0)
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
     {
-        return handle->info_err;
+        ril_cli.cb[RIL_MSG_ID_IND_SIGNAL_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
     }
-    else
-    {
-        handle->signal_state_cb = cb;
-        return 0;
-    }
+    return ret;
 }
-#endif
+
+int mbtk_ecall_state_change_cb_reg(mbtk_ril_callback_func cb)
+{
+    if(!ril_cli.ril_ready)
+    {
+        return MBTK_RIL_ERR_NOT_INIT;
+    }
+
+    int ret = ril_req_process(RIL_MSG_ID_IND_ECALL_STATE_CHANGE, NULL, 0, NULL, FALSE);
+    if(MBTK_RIL_ERR_SUCCESS == ret)
+    {
+        ril_cli.cb[RIL_MSG_ID_IND_ECALL_STATE_CHANGE - RIL_MSG_ID_IND_BEGIN - 1] = cb;
+    }
+    return ret;
+}
+
+
diff --git a/mbtk/libmbtk_lib_v2/ril/ril_utils.c b/mbtk/libmbtk_lib_v2/ril/ril_utils.c
index f71b2dd..371275d 100755
--- a/mbtk/libmbtk_lib_v2/ril/ril_utils.c
+++ b/mbtk/libmbtk_lib_v2/ril/ril_utils.c
@@ -258,12 +258,12 @@
         case RIL_MSG_ID_NET_REG:
             return "NET_REG";
         // <string> cmnet/ctnet/3gnet/...
-        case RIL_MSG_ID_NET_APN:
+        case RIL_MSG_ID_DATA_CALL_APN:
             return "APN";
         // Lock net/cell/frequency
         case RIL_MSG_ID_NET_CELL:
             return "NET_CELL";
-        case RIL_MSG_ID_NET_DATA_CALL:
+        case RIL_MSG_ID_DATA_CALL_OPT:
             return "DATA_CALL";
         // Call Information
         case RIL_MSG_ID_CALL_STATE:
@@ -279,8 +279,8 @@
         case RIL_MSG_ID_IND_SER_READY:
             return "IND_SER_READY";
         // <uint8>  State
-        case RIL_MSG_ID_IND_NET_STATE_CHANGE:
-            return "IND_NET_STATE";
+        case RIL_MSG_ID_IND_NET_REG_STATE_CHANGE:
+            return "IND_NET_REG_STATE";
         // <uint8>  State
         case RIL_MSG_ID_IND_CALL_STATE_CHANGE:
             return "IND_CALL_STATE";
diff --git a/mbtk/libmbtk_lib_v2/wifi/sta_cli.c b/mbtk/libmbtk_lib_v2/wifi/sta_cli.c
new file mode 100755
index 0000000..316d70f
--- /dev/null
+++ b/mbtk/libmbtk_lib_v2/wifi/sta_cli.c
@@ -0,0 +1,2008 @@
+#include <stdio.h>

+#include <pthread.h>

+#include <time.h>

+#include <sys/time.h>

+#include <unistd.h>

+#include <sys/un.h>

+#include <poll.h>

+#include <sys/socket.h>

+#include <netinet/in.h>

+#include <arpa/inet.h>

+#include <errno.h>

+#include <sys/ioctl.h>

+#include <net/if.h>

+#include <string.h>

+

+

+#include "sta_cli.h"

+#include "sta_ctrl.h"

+//#include "sta_log.h"

+//#include "mbtk_string.h"

+

+#define STA_CLI_TIMEOUT 15000   // 15s

+#define UNIXSTR_PATH "/data/sta_cli_sock"

+#define	SA	struct sockaddr

+#define	LISTENQ		1024	/* 2nd argument to listen() */

+#define STA_CMD_SEPARATED "#$#"

+#define STA_MAC_LEN 17	  // xx:xx:xx:xx:xx:xx

+#define STA_SSID_MAX_LEN (32 * 5)

+

+

+#ifndef INFTIM

+#define INFTIM          (-1)    /* infinite poll timeout */

+#endif

+

+#define STA_TAG_IND "IND"

+#define STA_TAG_CMD "CMD"

+#define STA_TAG_CMD_SUCCESS "SUCCESS"

+#define STA_TAG_CMD_FAIL "FAIL"

+#define STA_TAG_CMD_FAIL_BUSY "FAIL-BUSY"

+#define STA_CMD_OPEN "OPEN"

+//#define STA_CMD_EXIT "EXIT"

+#define STA_CMD_CLOSE "CLOSE"

+#define STA_CMD_SCAN "SCAN"

+#define STA_CMD_STATUS "STATUS"

+#define STA_CMD_MIB "MIB"

+#define STA_CMD_RECONFIGURE "RECONFIGURE"

+#define STA_CMD_DISCONNECT "DISCONNECT"

+#define STA_CMD_RECONNECT "RECONNECT"

+#define STA_CMD_SAVE_CONFIG "SAVE_CONFIG"

+#define STA_CMD_SET_NETWORK "SET_NETWORK"

+#define STA_CMD_GET_NETWORK "GET_NETWORK"

+#define STA_CMD_REMOVE_NETWORK "REMOVE_NETWORK"

+#define STA_CMD_ADD_NETWORK "ADD_NETWORK"

+#define STA_CMD_DISABLE_NETWORK "DISABLE_NETWORK"

+#define STA_CMD_ENABLE_NETWORK "ENABLE_NETWORK"

+#define STA_CMD_SELECT_NETWORK "SELECT_NETWORK"

+#define STA_CMD_LIST_NETWORKS "LIST_NETWORKS"

+#define STA_CMD_REASSOCIATE "REASSOCIATE"

+#define STA_CMD_REATTACH "REATTACH"

+

+// /var/run/wpa_supplicant

+static sta_cli_cmd_id_enum sta_cli_cmd_id = CMD_ID_NON;

+static char sta_cli_cmd_reply[STA_BUF_SIZE];

+static pthread_cond_t cond;

+static pthread_mutex_t mutex;

+static int sta_cli_conn_fd = -1;

+static char sta_cli_buf[STA_BUF_SIZE];

+static bool sta_should_send_connected_msg = TRUE;

+//static bool sta_connected = FALSE;

+static bool sta_disconnectting = FALSE;

+//static pthread_mutex_t sta_mutex;

+

+

+

+int sta_cli_ssid_get(char *ssid)

+{

+    FILE *fd_tmp = NULL;

+

+    fd_tmp = popen("cat /etc/wifi/sta_network.conf | grep -w 'SSID'   | cut -d '=' -f 2","r");

+  

+    if(fd_tmp){

+        char buf[200] = {0};

+        fgets(ssid,200,fd_tmp); 

+        pclose(fd_tmp);

+        if(strlen(ssid) > 0){

+           printf("test 100:%s, len:%d\n", ssid, strlen(ssid));

+            

+        }else{// Open wpa_supplicant

+            printf("test 101:%s\n", ssid);

+        }

+    }else{

+       

+            printf("test 102:%s\n");

+    }

+

+    return 0;

+}

+

+int sta_cli_psk_get(char *psk)

+{

+    FILE *fd_tmp = NULL;

+

+    fd_tmp = popen("cat /etc/wifi/sta_network.conf | grep -w 'PASSWORD'   | cut -d '=' -f 2","r");

+  

+    if(fd_tmp){

+        char buf[200] = {0};

+        fgets(psk,200,fd_tmp);

+        pclose(fd_tmp);

+        if(strlen(psk) > 0){

+           printf("test 100:%s\n", psk);

+            

+        }else{// Open wpa_supplicant

+            printf("test 101:%s\n", psk);

+        }

+    }else{

+       

+            printf("test 102:%s\n");

+    }

+

+    return 0;

+}

+

+

+

+static char*

+sta_cli_ssid_process

+(

+	const char *ssid,

+	char *result,

+	int len

+)

+{

+    bzero(result,len);

+    int ascii = 1;

+    int i;

+    for (i = 0; i < strlen(ssid); i++){

+        if (!isascii(ssid[i])){

+            //printf("0x%02x\n",(unsigned char)ssid[i]);

+            //return 0;

+            ascii = 0;

+            break;

+        }

+    }

+

+    if(ascii)

+    {

+        snprintf(result,len,

+                "\"%s\"",ssid);

+    }else{

+		int pos = 0;

+        for (i = 0; i < strlen(ssid); i++){

+            printf("0x%02x\n",(unsigned char)ssid[i]);

+        	snprintf(result + pos,len - pos,

+                "%02x",(unsigned char)ssid[i]);

+			pos += 2;

+        }

+    }

+    return result;

+}

+

+

+static char*

+sta_cli_mac_get

+(

+	char *ifname,

+	char *mac,

+	size_t mac_len

+)

+{

+    struct   ifreq   ifreq;

+    int   sock;

+	bzero(mac,mac_len);

+

+    if((sock=socket(AF_INET,SOCK_STREAM,0))<0)

+    {

+        printf("socket:errno(%d)\n",errno);

+        return NULL;

+    }

+    strcpy(ifreq.ifr_name,ifname);

+    if(ioctl(sock,SIOCGIFHWADDR,&ifreq) <0)

+    {

+		printf("ioctl:errno(%d)\n",errno);

+        return NULL;

+    }

+    snprintf(mac,mac_len,

+    	"%02x%02x%02x%02x%02x%02x",

+        (unsigned char)ifreq.ifr_hwaddr.sa_data[0],

+        (unsigned char)ifreq.ifr_hwaddr.sa_data[1],

+        (unsigned char)ifreq.ifr_hwaddr.sa_data[2],

+        (unsigned char)ifreq.ifr_hwaddr.sa_data[3],

+        (unsigned char)ifreq.ifr_hwaddr.sa_data[4],

+        (unsigned char)ifreq.ifr_hwaddr.sa_data[5]);

+	return mac;

+}

+

+

+static char*

+sta_cli_sta_name_get

+(

+	char *name,

+	size_t name_len

+)

+{

+	bzero(name,name_len);

+

+	// Get host name.

+    FILE *stream = NULL;

+	char host[100];

+	bzero(host,100);

+    stream = popen("hostname","r");

+    if(stream != NULL)

+    {

+		fgets(host, 100, stream);

+		pclose(stream);

+		int index = str_indexof(host,"\n");

+		if(strlen(host) > 0

+			&& index != 0)

+		{

+			if(index > 0)

+			{

+				host[index] = '\0';

+			}

+

+			// index < 0

+			// No "\n"

+		}

+		else // No data or empty line.

+		{

+			// Can not get host,set default to "MBTK".

+			memcpy(host,"MBTK",4);

+		}

+    }

+	else

+	{

+		// Can not get host,set default to "MBTK".

+		memcpy(host,"MBTK",4);

+	}

+

+	// Get mac address.

+	char mac[20];

+	if(NULL == sta_cli_mac_get("wlan0", mac, 20))

+	{

+		// Can not get mac,set default to current time.

+		time_t t;

+		t = time(NULL);

+		snprintf(mac,20,

+			"%ld",t);

+	}

+

+	snprintf(name,name_len,

+		"%s-%s",host,mac);

+

+	return name;

+}

+

+static void

+sta_cli_wpa_open_success

+(

+	void

+)

+{

+    char buf[100];

+    int len = snprintf(buf,100,

+        "%s-%s-%s"STA_CMD_SEPARATED,

+        STA_TAG_CMD,

+        STA_CMD_OPEN,

+        STA_TAG_CMD_SUCCESS);

+    buf[len] = '\0';

+    if(sta_cli_conn_fd != -1){

+        if(write(sta_cli_conn_fd,buf,len) != len){

+            printf("Send open msg to client fail.\n");

+        }else{

+            printf("Send open msg to client success.\n");

+        }

+    }else{

+        printf("No client connected.\n");

+    }

+	sta_should_send_connected_msg = FALSE;

+}

+

+

+static void

+sta_cli_wpa_msg_cb

+(

+    char *msg

+)

+{

+    printf("cmd_id = %d,[%s]\n",sta_cli_cmd_id,msg);

+

+//    if(sta_cli_conn_fd != -1){

+//        if(write(sta_cli_conn_fd,msg,strlen(msg)) != strlen(msg)){

+//            printf("Send msg to client fail.\n");

+//        }else{

+//            printf("Send msg to client success.\n");

+//        }

+//    }else{

+//        printf("No client connected.\n");

+//    }

+

+	// Send msg(CMD_OPEN_SUCCESS) to wifi_server.

+    if(sta_should_send_connected_msg) {

+		sta_cli_wpa_open_success();

+    }

+

+    // Connected to AP

+    if(str_contains(msg, "CTRL-EVENT-CONNECTED")){

+		//sta_connected = TRUE;

+		char sta_name[100];

+		sta_cli_sta_name_get(sta_name,100);

+		char cmd[200];

+		int size = snprintf(cmd,200,

+			"dhcpcd -h %s -o domain_name_servers --noipv4ll wlan0",sta_name);

+        //dhcpcd wlan0 -t 0 -o domain_name_servers --noipv4ll -b -G

+		cmd[size] = '\0';

+        if(sta_ctrl_system(cmd)){

+            char buf[100];

+            int len = snprintf(buf,100,

+                "%s-CONNECTED"STA_CMD_SEPARATED,

+                STA_TAG_IND);

+            buf[len] = '\0';

+            if(sta_cli_conn_fd != -1){

+				usleep(500);

+                if(write(sta_cli_conn_fd,buf,len) != len){

+                    printf("Send msg to client fail.\n");

+                }else{

+                    printf("Send msg to client success.\n");

+                }

+            }else{

+                printf("No client connected.\n");

+            }

+        }

+        return;

+    }

+#if 1

+	else if(str_contains(msg, "CTRL-EVENT-DISCONNECTED")

+		&& !str_contains(msg, "bssid=00:00:00:00:00:00")

+		&& !sta_disconnectting)

+	{

+		//pthread_mutex_lock(&sta_mutex);

+		//if(sta_connected){

+	        // Disconnected from AP

+	        char buf[100];

+	        int len = snprintf(buf,100,

+	            "%s-DISCONNECTED"STA_CMD_SEPARATED,

+	            STA_TAG_IND);

+	        buf[len] = '\0';

+	        if(sta_cli_conn_fd != -1){

+	            if(write(sta_cli_conn_fd,buf,len) != len){

+	                printf("Send msg to client fail.\n");

+	            }else{

+	                printf("Send msg to client success.\n");

+	            }

+	        }else{

+	            printf("No client connected.\n");

+	        }

+			//sta_connected = FALSE;

+			//pthread_mutex_unlock(&sta_mutex);

+	        return;

+		//}

+		//pthread_mutex_unlock(&sta_mutex);

+    }

+#endif

+

+    switch(sta_cli_cmd_id)

+    {

+        case CMD_ID_NON:

+        {

+

+            break;

+        }

+        case CMD_ID_SCAN:

+        {

+            if(str_contains(msg, "CTRL-EVENT-SCAN-RESULTS")){

+                printf("Start resume thread.\n");

+                pthread_mutex_lock(&mutex);

+                pthread_cond_signal(&cond);

+                //pthread_cond_broadcast(&cond);

+                pthread_mutex_unlock(&mutex);

+            }

+            break;

+        }

+        default:

+            printf("cmd_id[%d] unknown.\n",sta_cli_cmd_id);

+            break;

+    }

+}

+

+static void

+sta_cli_thread_pause

+(

+    long time /* ms */

+)

+{

+    struct timeval now_1;

+    struct timespec outtime;

+    int thread_id = pthread_self();

+    printf("Thread(%ld) pause.\n",thread_id);

+    pthread_mutex_lock(&mutex);

+    gettimeofday(&now_1, NULL);

+    outtime.tv_sec = now_1.tv_sec + time / 1000;

+    outtime.tv_nsec = now_1.tv_usec * 1000;

+    pthread_cond_timedwait(&cond, &mutex, &outtime);

+    pthread_mutex_unlock(&mutex);

+    printf("Thread(%ld) resume.\n",thread_id);

+}

+

+static bool

+sta_cli_is_empty_char(char ch)

+{

+    if(/*ch == ' ' || */ch == '\r' || ch == '\n'

+        || ch == '\t')

+        return TRUE;

+    else

+        return FALSE;

+}

+

+static char*

+sta_cli_value_get

+(

+	const char *data,

+	const char *key, // "key="

+	char *value,

+	int len

+)

+{

+	bzero(value,len);

+	char *ptr = strstr(data,key);

+	if(ptr)

+	{

+		ptr += strlen(key);

+		int i = 0;

+		while(*ptr != '\r' && *ptr != '\n')

+		{

+			if(i == len - 1)

+				return NULL;

+			value[i++] = *ptr++;

+		}

+		return value;

+	}else{

+		return NULL;

+	}

+}

+

+

+static sta_err_enum

+sta_cli_cmd_scan_parse

+(

+    const char *reply,

+    char *data,

+    size_t len

+)

+{

+	char *data_base = data;

+    printf("SCAN:\n%s\n",reply);

+    bzero(data,len);

+    const char *ptr = reply;

+    bool start = FALSE;

+    int count = 0; // count for ',' by every line.

+    while(*ptr){

+        if(!start && *ptr == '\n'){

+            start = TRUE;

+            ptr++;

+        }

+

+        if(start){

+            if(sta_cli_is_empty_char(*ptr)){

+                if(*ptr == '\r' || *ptr == '\n'){

+                    *data++ = '\r';

+                    *data++ = '\n';

+                    while(*++ptr == '\r' || *ptr == '\n')

+                        ;

+                    count = 0; // reset for next line.

+                }else{

+                    if(count < 4) {

+                        *data++ = ',';

+                        count++;

+                        while(*++ptr == ' ' || *ptr == '\t')

+                            ;

+                    } else {

+                        *data++ = *ptr++;

+                    }

+                }

+            }else{

+                *data++ = *ptr++;

+            }

+        }else{

+            ptr++;

+        }

+    }

+

+    printf("SCAN 0:\n%s\n",data_base);

+

+	// Delete empty ssid line.

+	char *tmp = (char*)calloc(len,1);

+	memcpy(tmp,data_base,strlen(data_base));

+	bzero(data_base,len);

+

+	char *ptr_pre = tmp;

+	ptr = strstr(ptr_pre,"\r\n");

+	printf("line:%s\n",ptr == NULL?"NULL":ptr);

+	char ssid[STA_BUF_SIZE] = {0};

+	char *p;

+	while(ptr)

+	{

+		printf("Get line.\n");

+		// Get ssid.

+		if(*(ptr - 1) == ',') // No ssid

+		{

+			printf("Delete one line.\n");

+		}else{

+			char s[STA_BUF_SIZE] = {0};

+			p = ptr - 1;

+			int len = 0;

+			while(*p-- != ','){

+				len++;

+			}

+			p += 2;

+			memcpy(s,p,len);

+			printf("ssid = %s;s = %s\n",ssid,s);

+			if(str_contains(ssid,s))

+			{

+				printf("Jump the same ssid:%s\n",s);

+				ptr_pre = ptr + 2;

+				ptr = strstr(ptr_pre,"\r\n");

+				continue;

+			}

+

+			if(strlen(ssid) > 0){

+				ssid[strlen(ssid)] = ',';

+			}

+			memcpy(ssid + strlen(ssid),s,len);

+

+			memcpy(data_base + strlen(data_base),ptr_pre,ptr + 2 - ptr_pre);

+			printf("Copy ssid:\"%s\"\n",s);

+		}

+		ptr_pre = ptr + 2;

+		ptr = strstr(ptr_pre,"\r\n");

+	}

+

+	printf("Scan parse end.\n");

+

+	free(tmp);

+	tmp = NULL;

+

+	printf("SCAN 1:\n%s\n",data_base);

+

+    return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_cli_cmd_status_parse

+(

+    const char *reply,

+    char *data,

+    size_t data_len

+)

+{

+    printf("STATUS:\n%s\n",reply);

+

+    bzero(data,data_len);

+

+//	  const char *ptr = reply;

+//    while(*ptr){

+//        if(*ptr == '\r' || *ptr == '\n'){

+//            *data++ = '\r';

+//            *data++ = '\n';

+//            while(*++ptr == '\r' || *ptr == '\n')

+//                ;

+//        }else{

+//            *data++ = *ptr++;

+//        }

+//    }

+

+#define BUF_SIZE 500

+	int len = 0;

+	char buf[BUF_SIZE];

+	char mac_ap[STA_MAC_LEN + 1];

+	int size;

+	if(sta_cli_value_get(reply,

+			"bssid=",

+			mac_ap,

+			STA_MAC_LEN + 1)) // Connected.

+	{

+		// State

+		memcpy(data + len,"1",1);

+		len += 1;

+

+		// mac_own

+		if(sta_cli_value_get(reply,

+			"\naddress=",

+			buf,

+			BUF_SIZE))

+		{

+			size = snprintf(data + len,data_len - len,

+				",%s",buf);

+			len += size;

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get own MAC address.\n");

+		}

+

+		// net_id

+		if(sta_cli_value_get(reply,

+			"\nid=",

+			buf,

+			BUF_SIZE))

+		{

+			size = snprintf(data + len,data_len - len,

+				",%s",buf);

+			len += size;

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get net id.\n");

+		}

+

+		// ssid

+		if(sta_cli_value_get(reply,

+			"\nssid=",

+			buf,

+			BUF_SIZE))

+		{

+			size = snprintf(data + len,data_len - len,

+				",%s",buf);

+			len += size;

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get ssid.\n");

+		}

+

+		// freq

+		if(sta_cli_value_get(reply,

+			"freq=",

+			buf,

+			BUF_SIZE))

+		{

+			int freq = atoi(buf);

+			int channel = (freq - 2412) / 5 + 1;

+			size = snprintf(data + len,data_len - len,

+				",%d,%s",channel,buf);

+			len += size;

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get freq.\n");

+		}

+

+		// auth

+		if(sta_cli_value_get(reply,

+			"key_mgmt=",

+			buf,

+			BUF_SIZE))

+		{

+			// WPA/WPA2

+			if(strncmp(buf,"WPA",3)== 0)

+			{

+				size = snprintf(data + len,data_len - len,

+					",%d",2);

+				len += size;

+			}else{

+				if(sta_cli_value_get(reply,

+					"group_cipher=",

+					buf,

+					BUF_SIZE))

+				{

+					// Open

+					if(strncmp(buf,"NONE",4) == 0)

+					{

+						size = snprintf(data + len,data_len - len,

+							",%d",0);

+						len += size;

+					}else{// WEP

+						size = snprintf(data + len,data_len - len,

+							",%d",1);

+						len += size;

+					}

+				}else{

+					memcpy(data + len,",",1);

+					len += 1;

+					printf("Not get group_cipher.\n");

+				}

+			}

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get key_mgmt.\n");

+		}

+

+		// mac_ap

+		size = snprintf(data + len,data_len - len,

+			",%s",mac_ap);

+		len += size;

+

+		// ip

+		if(sta_cli_value_get(reply,

+			"ip_address=",

+			buf,

+			BUF_SIZE))

+		{

+			size = snprintf(data + len,data_len - len,

+				",%s",buf);

+			len += size;

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get IP.\n");

+		}

+	}else{

+		memcpy(data + len,"0",1);

+		len += 1;

+

+		if(sta_cli_value_get(reply,

+			"\naddress=",

+			buf,

+			BUF_SIZE))

+		{

+			size = snprintf(data + len,data_len - len,

+				",%s",buf);

+			len += size;

+

+		}else{

+			memcpy(data + len,",",1);

+			len += 1;

+			printf("Not get MAC address.\n");

+		}

+

+		memcpy(data + len,",,,,,,,",7);

+		len += 7;

+	}

+

+	memcpy(data + len,"\r\n",2);

+	len += 2;

+	data[len] = '\0';

+

+    printf("STATUS:\n%s\n",data);

+#undef BUF_SIZE

+    return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_cli_cmd_mib_parse

+(

+    const char *reply,

+    char *data,

+    size_t len

+)

+{

+    printf("MIB:\n%s\n",reply);

+

+    memcpy(data,reply,strlen(reply));

+

+    return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_cli_cmd_list_network_parse

+(

+    const char *reply,

+    char *data,

+    size_t len

+)

+{

+    printf("LIST_NETWORK:\n%s\n",reply);

+

+    bzero(data,len);

+    const char *ptr = reply;

+    bool start = FALSE;

+    bool skip = FALSE;

+    int count = 0; // count for ',' by every line.

+    while(*ptr){

+        if(!start && *ptr == '\n'){

+            start = TRUE;

+            ptr++;

+        }

+

+        if(start){

+            if(sta_cli_is_empty_char(*ptr)){

+                if(*ptr == '\r' || *ptr == '\n'){

+                    *data++ = '\r';

+                    *data++ = '\n';

+                    while(*++ptr == '\r' || *ptr == '\n')

+                        ;

+                    count = 0;

+                    skip = FALSE;

+                }else{

+                    if(count < 1) {

+                        *data++ = ',';

+                        count++;

+                        while(*++ptr == ' ' || *ptr == '\t')

+                            ;

+                    } else {

+                        skip = TRUE;

+                        ptr++;

+                    }

+                }

+            }else{

+                if(!skip)

+                    *data++ = *ptr++;

+                else

+                    ptr++;

+            }

+        }else{

+            ptr++;

+        }

+    }

+

+    //memcpy(data,reply,strlen(reply));

+

+    printf("LIST_NETWORK:\n%s\n",data);

+

+    return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_cli_process_cmd

+(

+    const char *cmd

+)

+{

+    sta_err_enum err = sta_ctrl_cmd_process(cmd,sta_cli_cmd_reply,STA_BUF_SIZE);

+    if(err == STA_ERR_SUCCESS){

+        if(strncmp(cmd,STA_CMD_SCAN,strlen(STA_CMD_SCAN)) == 0

+            && strncmp(sta_cli_cmd_reply,STA_TAG_CMD_FAIL_BUSY,strlen(STA_TAG_CMD_FAIL_BUSY)) == 0){

+            printf("\"%s\" busy.\n",cmd);

+            return STA_ERR_SUCCESS;

+        }

+

+        if(strncmp(sta_cli_cmd_reply,STA_TAG_CMD_FAIL,strlen(STA_TAG_CMD_FAIL)) == 0){

+            printf("\"%s\" fail.\n",cmd);

+            return STA_ERR_UNKNOWN;

+        }

+        printf("[%s]:\n%s\n",cmd,sta_cli_cmd_reply);

+    }else{

+        printf("[%s]:FAIL\n",cmd);

+    }

+    return err;

+}

+

+static sta_err_enum

+sta_cli_cmd_scan

+(

+    const char *cmd,

+    char *data,

+    size_t len

+)

+{

+    bzero(data,len);

+    sta_cli_cmd_id = CMD_ID_SCAN;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0

+            || strncmp(sta_cli_cmd_reply,STA_TAG_CMD_FAIL_BUSY,strlen(STA_TAG_CMD_FAIL_BUSY)) == 0){// Is scanning ...

+            sta_cli_thread_pause(STA_CLI_TIMEOUT);

+

+            // Scan end.

+

+            sta_cli_cmd_id = CMD_ID_SCAN_RESULTS;

+            err = sta_cli_process_cmd("SCAN_RESULTS");

+            sta_cli_cmd_id = CMD_ID_NON;

+            if(STA_ERR_SUCCESS == err){

+                return sta_cli_cmd_scan_parse(sta_cli_cmd_reply,

+                    data,

+                    len);

+            }else{

+                printf("SCAN_RESULTS cmd fail.\n");

+                return STA_ERR_UNKNOWN;

+            }

+        }else{

+            sta_cli_cmd_id = CMD_ID_NON;

+            printf("SCAN cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("SCAN cmd fail.\n");

+        return err;

+    }

+}

+

+

+static char*

+sta_cli_flag_get

+(

+	const char *ssid,

+	char *flag,

+	size_t len

+)

+{

+	sta_err_enum err;

+    char data[STA_BUF_SIZE];

+	bzero(flag,len);

+    err = sta_cli_cmd_scan("SCAN", data,STA_BUF_SIZE);

+    if(err == STA_ERR_SUCCESS){

+		if(strlen(data) == 0)

+		{

+			return NULL;

+		}

+		ssize_t end = str_indexof(data,ssid) - 1; // Point to ','

+		if(end > 0)

+		{

+			char *ptr = data + end - 1;// Jump the ','

+			int len = 0;

+			while(*ptr != ',' && ptr != data)

+			{

+				ptr--;

+				len++;

+			}

+			ptr++; // Point to flag.

+

+			memcpy(flag,ptr,len);

+			printf("%s : %s\n",ssid,flag);

+			return flag;

+		}

+    }else{

+		printf("SCAN_RESULTS cmd fail.");

+		return NULL;

+    }

+    return NULL;

+}

+

+

+static sta_err_enum

+sta_cli_cmd_status

+(

+    const char *cmd,

+    char *data,

+    size_t len

+)

+{

+    bzero(data,len);

+    sta_cli_cmd_id = CMD_ID_STATUS;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    sta_cli_cmd_id = CMD_ID_NON;

+    if(STA_ERR_SUCCESS == err){

+        return sta_cli_cmd_status_parse(sta_cli_cmd_reply,

+            data,

+            len);

+    }else{

+        printf("STATUS cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_mib

+(

+    const char *cmd,

+    char *data,

+    size_t len

+)

+{

+    bzero(data,len);

+    sta_cli_cmd_id = CMD_ID_MIB;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    sta_cli_cmd_id = CMD_ID_NON;

+    if(STA_ERR_SUCCESS == err){

+        return sta_cli_cmd_mib_parse(sta_cli_cmd_reply,

+            data,

+            len);

+    }else{

+        printf("MIB cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_reconfigure

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_RECONFIGURE;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("RECONFIGURE cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("RECONFIGURE cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_disconnect

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_DISCONNECT;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("DISCONNECT cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("DISCONNECT cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_reconnect

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_RECONNECT;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("RECONNECT cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("RECONNECT cmd fail.\n");

+        return err;

+    }

+}

+

+

+static sta_err_enum

+sta_cli_cmd_save_config

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_SAVE_CONFIG;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("SAVE_CONFIG cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("SAVE_CONFIG cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_set_network_process

+(

+	char *c

+)

+{

+	printf("cmd = %s\n",c);

+	char *ptr = c;

+

+    sta_cli_cmd_id = CMD_ID_SET_NETWORK;

+	sta_err_enum err = STA_ERR_SUCCESS;

+	char cmd[100];

+	int index = str_indexof(ptr,"#");

+	bzero(cmd,100);

+	if(index > 0)

+	{

+		memcpy(cmd,ptr,index);

+		ptr += (index + 1);

+	}else

+	{

+		memcpy(cmd,ptr,strlen(ptr));

+		ptr = NULL;

+	}

+

+	while(TRUE)

+	{

+	    err = sta_cli_process_cmd(c);

+	    if(STA_ERR_SUCCESS == err){

+	        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+	            //return STA_ERR_SUCCESS;

+	            printf("Success:%s\n",cmd);

+	        }else{

+	            printf("Fail:%s\n",cmd);

+				sta_cli_cmd_id = CMD_ID_NON;

+	            return STA_ERR_UNKNOWN;

+	        }

+	    }else{

+	        sta_cli_cmd_id = CMD_ID_NON;

+	        printf("Fail:%s\n",cmd);

+	        return err;

+	    }

+

+		if(ptr == NULL)

+			break;

+

+		printf("ptr = %s",ptr);

+

+		index = str_indexof(ptr,"#");

+		bzero(cmd,100);

+		if(index > 0)

+		{

+			memcpy(cmd,ptr,index);

+			ptr += (index + 1);

+		}else

+		{

+			memcpy(cmd,ptr,strlen(ptr));

+			ptr = NULL;

+		}

+	}

+

+	sta_cli_cmd_id = CMD_ID_NON;

+	return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_cli_cmd_set_network

+(

+    const char *cmd,

+    const char *flag

+)

+{

+	printf("cmd = %s\n",cmd);

+	char buf[500];

+    printf("test11\n");

+	int index = str_indexof(cmd," psk ");

+    printf("test12\n");

+	int net_id = atoi(cmd + strlen(STA_CMD_SET_NETWORK) + 1);

+    printf("test13\n");

+	if(index > 0){ // Is set "psk"

+	    printf("test14\n");

+		char psk[64] = {0};

+		int start = index + 5; // " psk "

+		if(*(cmd + start) == '"')

+		{

+		    printf("test15\n");

+			memcpy(psk,cmd + start + 1,strlen(cmd) - start - 2);

+		}else{

+            printf("test16\n");

+			memcpy(psk,cmd + start,strlen(cmd) - start);

+		}

+		printf("psk = %s\n",psk);

+

+		// Set to OPEN (No psk)

+		// SET_NETWORK <net_id> key_mgmt NONE

+		if(strcmp(psk,"0") == 0)

+		{

+			int size = snprintf(buf,500,

+					"%s %d key_mgmt NONE",

+					STA_CMD_SET_NETWORK,

+					net_id);

+			buf[size] = '\0';

+			return sta_cli_cmd_set_network_process(buf);

+		}

+

+		// WEP

+		// key_mgmt=NONE

+		// auth_alg=OPEN SHARED

+		// wep_key0="0123456789abc"

+		if(flag && str_contains(flag, "WEP")

+			&&(strlen(psk) == 5

+				|| strlen(psk) == 13

+				|| strlen(psk) == 10

+				|| strlen(psk) == 26))

+		{

+			int size = 0;

+			if(strlen(psk) == 5

+				|| strlen(psk) == 13)

+			{

+				size = snprintf(buf,500,

+					"%s %d key_mgmt NONE#%s %d auth_alg SHARED#%s %d wep_key0 \"%s\"",

+					STA_CMD_SET_NETWORK,

+					net_id,

+					STA_CMD_SET_NETWORK,

+					net_id,

+					STA_CMD_SET_NETWORK,

+					net_id,

+					psk);

+			}else{

+				size = snprintf(buf,500,

+					"%s %d key_mgmt NONE#%s %d auth_alg SHARED#%s %d wep_key0 %s",

+					STA_CMD_SET_NETWORK,

+					net_id,

+					STA_CMD_SET_NETWORK,

+					net_id,

+					STA_CMD_SET_NETWORK,

+					net_id,

+					psk);

+			}

+

+			buf[size] = '\0';

+			return sta_cli_cmd_set_network_process(buf);

+		}

+

+		// Default is "WPA/WPA2"

+		int size = snprintf(buf,500,

+				"%s#%s %d key_mgmt WPA-PSK",

+				cmd,

+				STA_CMD_SET_NETWORK,

+				net_id);

+		buf[size] = '\0';

+		return sta_cli_cmd_set_network_process(buf);

+	}

+	else // SSID

+	{

+	    printf("test21\n");

+		index = str_indexof(cmd," ssid ");

+		char ssid[STA_BUF_SIZE] = {0};

+		int start = index + 6; // " ssid "

+		if(*(cmd + start) == '"')

+		{

+			memcpy(ssid,cmd + start + 1,strlen(cmd) - start - 2);

+		}else{

+			memcpy(ssid,cmd + start,strlen(cmd) - start);

+		}

+		printf("ssid = %s\n",ssid);

+

+

+		//char ssid_result[STA_SSID_MAX_LEN + 1];

+		//sta_cli_ssid_process(ssid,ssid_result,STA_SSID_MAX_LEN + 2 + 1);

+       // printf("test22, ssid_result: %s\n", ssid_result);

+		char cmd_result[STA_BUF_SIZE];

+		int size = snprintf(cmd_result,STA_BUF_SIZE,

+			"%s %d ssid %s",

+			STA_CMD_SET_NETWORK,

+			net_id,

+			ssid);

+		cmd_result[size] = '\0';

+		printf("cmd = %s\n",cmd_result);

+

+		return sta_cli_cmd_set_network_process(cmd);

+	}

+}

+

+

+static sta_err_enum

+sta_cli_cmd_get_network

+(

+    const char *cmd,

+    char *value,

+    int len

+)

+{

+    bzero(value,len);

+    sta_cli_cmd_id = CMD_ID_GET_NETWORK;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+

+        char *tmp = sta_cli_cmd_reply;

+        while(*tmp == '\"'){

+            tmp++;

+        }

+        // Copy with '\0'

+        memcpy(value,tmp,strlen(tmp) + 1);

+

+        tmp = value + strlen(value) -1;

+        while(*tmp == '\"'){

+            tmp = '\0';

+            tmp--;

+        }

+

+        printf("GET_NETWORK:%s.\n",value);

+        return STA_ERR_SUCCESS;

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("GET_NETWORK cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_remove_network

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_REMOVE_NETWORK;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("REMOVE_NETWORK cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("REMOVE_NETWORK cmd fail.\n");

+        return err;

+    }

+}

+

+

+static sta_err_enum

+sta_cli_cmd_add_network

+(

+    const char *cmd

+)

+{

+	printf("cmd = %s\n",cmd);

+    sta_cli_cmd_id = CMD_ID_ADD_NETWORK;

+    sta_err_enum err = sta_cli_process_cmd(STA_CMD_ADD_NETWORK);

+    printf("test1\n");

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        int net_id = atoi(sta_cli_cmd_reply);

+        printf("test2\n");

+        if(net_id >= 0){ // Add network success.

+            // Point to ssid

+            printf("test3\n");

+            /*

+            const char *ptr = cmd + strlen(STA_CMD_ADD_NETWORK) + 1;

+

+            //int index = str_indexof(ptr," ");

+

+            char *pass_ptr = cmd + strlen(cmd);

+            while(*--pass_ptr != ' ')

+                ;

+            pass_ptr++; // Point to pass.

+

+

+            char ssid[STA_BUF_SIZE] = {0};

+            printf("test4\n");

+            memcpy(ssid,ptr,pass_ptr - ptr - 1);

+            */

+

+            char buf[STA_BUF_SIZE] = {'\0'};

+            char ssid[STA_BUF_SIZE] = {'\0'};

+            char psk[STA_BUF_SIZE] = {'\0'};

+            int len = 0;

+            printf("test5\n");

+

+            sta_cli_ssid_get(ssid);

+            len = strlen(ssid);

+            ssid[len - 1] = '\0';

+            

+            sta_cli_psk_get(psk);

+            len = strlen(psk);

+            psk[len - 1] = '\0';

+

+            

+            int size = snprintf(buf,STA_BUF_SIZE,

+                "%s %d ssid \"%s\"",

+                STA_CMD_SET_NETWORK,

+                net_id,

+                ssid);

+            printf("test6\n");

+            buf[size] = '\0';

+

+         

+            err = sta_cli_cmd_set_network(buf,NULL);

+            printf("test7\n");

+            if(STA_ERR_SUCCESS == err){

+				char flag[50];

+				sta_cli_flag_get(ssid,flag,50);

+                size = snprintf(buf,100,

+                        "%s %d psk \"%s\"",

+                        STA_CMD_SET_NETWORK,

+                        net_id,

+                        psk);

+                buf[size] = '\0';

+                err = sta_cli_cmd_set_network(buf,flag);

+                if(STA_ERR_SUCCESS == err){

+                    return STA_ERR_SUCCESS;

+                }

+            }

+

+			if(err != STA_ERR_SUCCESS) // remove network

+			{

+				int size = snprintf(buf,STA_BUF_SIZE,

+	                "%s %d",

+	                STA_CMD_REMOVE_NETWORK,

+	                net_id);

+	            buf[size] = '\0';

+				sta_cli_process_cmd(buf);

+			}

+

+            return err;

+        }else{

+            printf("ADD_NETWORK cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        printf("ADD_NETWORK cmd fail.\n");

+        sta_cli_cmd_id = CMD_ID_NON;

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_disable_network

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_DISABLE_NETWORK;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("DISABLE_NETWORK cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("DISABLE_NETWORK cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_enable_network

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_ENABLE_NETWORK;

+    sta_err_enum err = sta_cli_process_cmd("ENABLE_NETWORK 1");

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("ENABLE_NETWORK cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("ENABLE_NETWORK cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_select_network

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_SELECT_NETWORK;

+    sta_err_enum err = sta_cli_process_cmd("SELECT_NETWORK 1");

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("SELECT_NETWORK cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("SELECT_NETWORK cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_list_networks

+(

+    const char *cmd,

+    char *data,

+    size_t len

+)

+{

+    bzero(data,len);

+    sta_cli_cmd_id = CMD_ID_LIST_NETWORKS;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    sta_cli_cmd_id = CMD_ID_NON;

+    if(STA_ERR_SUCCESS == err){

+        return sta_cli_cmd_list_network_parse(sta_cli_cmd_reply,

+            data,

+            len);

+    }else{

+        printf("LIST_NETWORKS cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_reassociate

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_REASSOCIATE;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("REASSOCIATE cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("REASSOCIATE cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_cmd_reattach

+(

+    const char *cmd

+)

+{

+    sta_cli_cmd_id = CMD_ID_REATTACH;

+    sta_err_enum err = sta_cli_process_cmd(cmd);

+    if(STA_ERR_SUCCESS == err){

+        sta_cli_cmd_id = CMD_ID_NON;

+        if(strncmp(sta_cli_cmd_reply,"OK",2) == 0){

+            return STA_ERR_SUCCESS;

+        }else{

+            printf("REATTACH cmd fail.\n");

+            return STA_ERR_UNKNOWN;

+        }

+    }else{

+        sta_cli_cmd_id = CMD_ID_NON;

+        printf("REATTACH cmd fail.\n");

+        return err;

+    }

+}

+

+static sta_err_enum

+sta_cli_init

+(

+    void

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    if((result = sta_ctrl_driver_init(TRUE)) != STA_ERR_SUCCESS){

+        printf("Driver init fail(%d).\n",result);

+        return result;

+    }

+

+    if((result = sta_ctrl_wpa_init(

+        "/etc/wifi/wpa_supplicant.conf",

+        "wlan0",

+        sta_cli_wpa_msg_cb)) != STA_ERR_SUCCESS){

+        printf("wpa_supplicant init fail(%d).\n",result);

+        return result;

+    }

+	//pthread_mutex_init(&sta_mutex,NULL);

+    return result;

+}

+

+static sta_err_enum

+sta_cli_deinit

+(

+    void

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    if((result = sta_ctrl_wpa_deinit()) != STA_ERR_SUCCESS){

+        printf("sta_ctrl_wpa_deinit fail(%d).",result);

+        return result;

+    }

+

+    if((result = sta_ctrl_driver_init(FALSE)) != STA_ERR_SUCCESS){

+        printf("Driver close fail(%d).\n",result);

+        return result;

+    }

+	//pthread_mutex_destroy(&sta_mutex);

+    return result;

+}

+

+/**

+* CMD-CLOSE-SUCCESS

+* CMD-CLOSE-FAIL:2

+*

+* CMD-SCAN-XXX

+*

+* IND-XXX

+*

+*/

+bool sta_cli_cmd_parse

+(

+    const char *cmd,

+    char *reply,

+    size_t reply_len

+)

+{

+	printf("cmd:%s\n",cmd);

+    bzero(reply,reply_len);

+    sta_err_enum err = STA_ERR_UNKNOWN;

+    if(strncmp(cmd,(STA_CMD_OPEN),strlen(STA_CMD_OPEN)) == 0){

+        // Will OPEN connection with wpa_supplicant.

+        err = sta_cli_init();

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+            sta_should_send_connected_msg = FALSE;

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_CLOSE,strlen(STA_CMD_CLOSE)) == 0){

+        err = sta_cli_deinit();

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+            sta_should_send_connected_msg = TRUE;

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_SCAN,strlen(STA_CMD_SCAN)) == 0){

+        char data[STA_BUF_SIZE];

+        err = sta_cli_cmd_scan(cmd, data,STA_BUF_SIZE);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                data);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_STATUS,strlen(STA_CMD_STATUS)) == 0){

+        char data[STA_BUF_SIZE];

+        err = sta_cli_cmd_status(cmd, data,STA_BUF_SIZE);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                data);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_MIB,strlen(STA_CMD_MIB)) == 0){

+        char data[STA_BUF_SIZE];

+        err = sta_cli_cmd_mib(cmd, data,STA_BUF_SIZE);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                data);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_RECONFIGURE,strlen(STA_CMD_RECONFIGURE)) == 0){

+        err = sta_cli_cmd_reconfigure(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_DISCONNECT,strlen(STA_CMD_DISCONNECT)) == 0){

+		sta_disconnectting = TRUE;

+		err = sta_cli_cmd_disconnect(cmd);

+		// Not reply(Reply after disconnecd).

+#if 0

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+#endif

+		if(err == STA_ERR_SUCCESS)

+		{

+			printf("sta_cli_cmd_disconnect success.\n");

+			//pthread_mutex_lock(&sta_mutex);

+			//if(sta_connected)

+			//{

+				#define GET_STATUS_MAX 5

+				int count = 0;

+				bool ok = FALSE;

+				usleep(500);

+				while(count++ < GET_STATUS_MAX)

+				{

+					sta_err_enum err = sta_cli_process_cmd(STA_CMD_STATUS);

+				    if(STA_ERR_SUCCESS == err){

+				        char mac_ap[STA_MAC_LEN + 1];

+						if(!sta_cli_value_get(sta_cli_cmd_reply,

+							"bssid=",

+							mac_ap,

+							STA_MAC_LEN + 1)) // Disconnected.

+						{

+							printf("Disconnected success.\n");

+							snprintf(reply,reply_len,

+								"%s-%s-%s"STA_CMD_SEPARATED,

+								STA_TAG_CMD,

+								cmd,

+								STA_TAG_CMD_SUCCESS);

+							ok = TRUE;

+							break;

+						}else{ // Connected.

+							printf("Not disconnected.Try again(STATUS).\n");

+							usleep(500);

+						}

+				    }else{

+				        printf("STATUS cmd fail.\n");

+				        break;

+				    }

+				}

+

+				if(!ok) // fail

+				{

+					printf("Disconnect fail.\n");

+		            snprintf(reply,reply_len,

+		                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+		                STA_TAG_CMD,

+		                cmd,

+		                STA_TAG_CMD_FAIL,

+		                STA_ERR_UNKNOWN);

+				}

+				//sta_connected = FALSE;

+			//}

+			//pthread_mutex_unlock(&sta_mutex);

+		}else{

+			printf("sta_cli_cmd_disconnect fail.\n");

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+		}

+		sta_disconnectting = FALSE;

+    }else if(strncmp(cmd,STA_CMD_RECONNECT,strlen(STA_CMD_RECONNECT)) == 0){

+        err = sta_cli_cmd_reconnect(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_SAVE_CONFIG,strlen(STA_CMD_SAVE_CONFIG)) == 0){

+        err = sta_cli_cmd_save_config(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_SET_NETWORK,strlen(STA_CMD_SET_NETWORK)) == 0){

+        err = sta_cli_cmd_set_network(cmd,NULL);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_GET_NETWORK,strlen(STA_CMD_GET_NETWORK)) == 0){

+        char data[100];

+        err = sta_cli_cmd_get_network(cmd,data,100);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                data);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_REMOVE_NETWORK,strlen(STA_CMD_REMOVE_NETWORK)) == 0){

+        err = sta_cli_cmd_remove_network(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_ADD_NETWORK,strlen(STA_CMD_ADD_NETWORK)) == 0){

+        err = sta_cli_cmd_add_network(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_DISABLE_NETWORK,strlen(STA_CMD_DISABLE_NETWORK)) == 0){

+        err = sta_cli_cmd_disable_network(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_ENABLE_NETWORK,strlen(STA_CMD_ENABLE_NETWORK)) == 0){

+        err = sta_cli_cmd_enable_network(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_SELECT_NETWORK,strlen(STA_CMD_SELECT_NETWORK)) == 0){

+        err = sta_cli_cmd_select_network(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_LIST_NETWORKS,strlen(STA_CMD_REASSOCIATE)) == 0){

+        char data[STA_BUF_SIZE];

+        err = sta_cli_cmd_list_networks(cmd, data,STA_BUF_SIZE);

+

+//		char reply_tmp[STA_BUF_SIZE];

+//		memset(reply_tmp,0,STA_BUF_SIZE);

+//		char *reply_ptr = data;

+//		int index = 0;

+//		int pos = 0;

+//		while(*reply_ptr != '\0'){

+//			if(*reply_ptr == ','){

+//				index++;

+//			}

+

+//			if(index == 3){

+//				if(*reply_ptr == '\n'){

+//					index = 0;

+//					reply_tmp[pos++] = '\r';

+//					reply_tmp[pos++] = '\n';

+//				}

+//			}else{

+//				reply_tmp[pos++] = *reply_ptr;

+//			}

+

+//			reply_ptr++;

+//		}

+

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                data);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_REASSOCIATE,strlen(STA_CMD_REASSOCIATE)) == 0){

+        err = sta_cli_cmd_reassociate(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else if(strncmp(cmd,STA_CMD_REATTACH,strlen(STA_CMD_REATTACH)) == 0){

+        err = sta_cli_cmd_reattach(cmd);

+        if(err == STA_ERR_SUCCESS){

+            snprintf(reply,reply_len,

+                "%s-%s-%s"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_SUCCESS);

+        }else{

+            snprintf(reply,reply_len,

+                "%s-%s-%s:%d"STA_CMD_SEPARATED,

+                STA_TAG_CMD,

+                cmd,

+                STA_TAG_CMD_FAIL,

+                err);

+        }

+    }else{

+        printf("Unknown cmd:%s\n",cmd);

+        return FALSE;

+    }

+    return TRUE;

+}

+

+

diff --git a/mbtk/libmbtk_lib_v2/wifi/sta_ctrl.c b/mbtk/libmbtk_lib_v2/wifi/sta_ctrl.c
new file mode 100755
index 0000000..66c55f5
--- /dev/null
+++ b/mbtk/libmbtk_lib_v2/wifi/sta_ctrl.c
@@ -0,0 +1,599 @@
+#include <string.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <pthread.h>

+#include <unistd.h>

+#include <sys/epoll.h>

+#include <errno.h>

+#include <sys/wait.h>

+#include <sys/types.h>

+

+#include "wpa_ctrl.h"

+#include "sta_ctrl.h"

+//#include "sta_log.h"

+

+#define WPA_SUPPLICANT_LOG_FILE "/data/wpa_supplicant.log"

+

+static void

+sta_ctrl_wpa_req_cb(char *msg, size_t len);

+

+static void*

+sta_ctrl_event_thread_run( void *arg );

+

+static sta_err_enum

+sta_ctrl_close_connection(void);

+

+static sta_err_enum

+sta_ctrl_open_connection(void);

+

+static sta_err_enum

+sta_ctrl_reconnect(void);

+

+static void

+sta_ctrl_recv_event(void);

+

+static sta_err_enum

+sta_ctrl_conf_file_parse

+(

+    const char *key,

+    char *value

+);

+

+extern struct wpa_ctrl;

+

+static struct wpa_ctrl *sta_ctrl_conn;

+static struct wpa_ctrl *sta_mon_conn;

+static int sta_ctrl_attached = 0;

+static pthread_t sta_event_thread_id = -1;

+static int sta_event_thread_is_running = 0;

+static char sta_ctrl_conf_file_path[50];

+static char sta_ctrl_ifname[10];

+static sta_ctrl_msg_cb sta_ctrl_msg = NULL;

+static int sta_ctrl_pipe_fd[2];

+

+static void

+sta_ctrl_wpa_req_cb(char *msg, size_t len)

+{

+	printf("%s\n", msg);

+}

+

+bool

+sta_ctrl_system

+(

+  const char   *command

+)

+{

+    int result = TRUE;

+    FILE *stream = NULL;

+

+    printf("system call: %s\n", command);

+

+    stream = popen( command, "w" );

+    if( stream == NULL )

+    {

+        printf("system command failed\n");

+        result = FALSE;

+    }

+    else if( 0 > pclose( stream ) )

+    {

+        printf("pclose command failed\n");

+    }

+

+    return result;

+}

+

+/*

+* Return TRUE if process <name> is not running after 2 second.

+*/

+bool

+sta_ctrl_kill_check(const char *name)

+{

+#define  PROCESS_KILL_RETRY  40

+    bool result;

+    int tmp = 0;

+    FILE *cmd;

+    char pid_s[STA_BUF_SIZE];

+    int pid;

+    tmp = snprintf(pid_s,STA_BUF_SIZE,

+        "pidof %s",name);

+    pid_s[tmp] = '\0';

+    tmp = 0;

+    while (tmp++ < PROCESS_KILL_RETRY)

+    {

+        usleep(50000);/*50 mili second*/

+        cmd = popen(pid_s, "r");

+        pid = 0;

+        bzero(pid_s, STA_BUF_SIZE);

+        if(cmd)

+        {

+            fgets(pid_s, STA_BUF_SIZE, cmd);

+            pclose(cmd);

+        }

+        pid = atoi(pid_s);

+        printf("%s pid =%d\n", name,pid);

+        /* If pid is zero we break from while*/

+        if(pid == 0)

+        {

+            result = TRUE;

+            goto exit_end;

+        }

+    }

+

+    printf("PID still running after waiting 2 second.\n");

+    result = FALSE;

+exit_end:

+#undef PROCESS_KILL_RETRY

+    return result;

+}

+

+/*

+* Return TRUE if process <name> is running.

+*/

+bool

+sta_ctrl_process_running(const char *name)

+{

+    char pid_s[STA_BUF_SIZE];

+    int tmp = snprintf(pid_s,STA_BUF_SIZE,

+        "pidof %s",name);

+    pid_s[tmp] = '\0';

+    FILE *cmd = popen(pid_s, "r");

+    bzero(pid_s, STA_BUF_SIZE);

+    if(cmd)

+    {

+        fgets(pid_s, STA_BUF_SIZE, cmd);

+        pclose(cmd);

+    }

+

+    int pid = atoi(pid_s);

+    printf("%s pid =%d\n", name,pid);

+    /* If pid is zero we break from while*/

+    if(pid == 0)

+    {

+        printf("%s not runnig.\n",name);

+        return FALSE;

+    }else{

+        printf("%s is runnig.\n",name);

+        return TRUE;

+    }

+}

+

+

+static void*

+sta_ctrl_event_thread_run( void *arg )

+{

+    printf("Thread[%ld] run().\n",pthread_self());

+

+    int nready;

+    struct epoll_event ev_sock,ev_pipe,events[20];

+    int epfd = epoll_create(256);

+    ev_sock.data.fd = wpa_ctrl_get_fd(sta_mon_conn);

+    ev_sock.events = EPOLLIN | EPOLLET;

+    epoll_ctl(epfd,EPOLL_CTL_ADD,wpa_ctrl_get_fd(sta_mon_conn),&ev_sock);

+

+    ev_pipe.data.fd = sta_ctrl_pipe_fd[0];

+    ev_pipe.events = EPOLLIN | EPOLLET;

+    epoll_ctl(epfd,EPOLL_CTL_ADD,sta_ctrl_pipe_fd[0],&ev_pipe);

+

+    for ( ; ; ) {

+        if(!sta_event_thread_is_running){

+            break;

+        }

+		printf("epoll_wait waitting...\n",nready);

+        nready = epoll_wait(epfd,events,20,-1);

+        printf("epoll_wait return.(count = %d)\n",nready);

+        int i;

+        for(i=0;i<nready;++i) {

+            if (events[i].events & EPOLLIN) {// Read

+                if (events[i].data.fd < 0)

+                    continue;

+

+                if(sta_mon_conn  // sta_mon_conn can not be NULL

+                    && events[i].data.fd == wpa_ctrl_get_fd(sta_mon_conn)){

+                    sta_ctrl_recv_event();

+                }else if(events[i].data.fd == sta_ctrl_pipe_fd[0]){

+                    printf("Thread end.[fd = %d]\n",events[i].data.fd);

+                    // End thread

+                    char buf_end[10] = {0};

+                    if(read(sta_ctrl_pipe_fd[0],buf_end,10) > 0

+                        && strcmp(buf_end,"0") == 0){

+                        sta_event_thread_is_running = 0;

+                        break;

+                    }

+                }else{

+                    printf("No such fd[%d].\n",events[i].data.fd);

+                }

+            } else {

+                printf("event error.\n");

+            }

+        }

+    }

+

+    close(epfd);

+    printf("Thread exit.\n");

+    return ((void*)0);

+}

+

+static sta_err_enum

+sta_ctrl_close_connection(void)

+{

+    printf("start.\n");

+    if (sta_ctrl_conn == NULL)

+        return STA_ERR_UNKNOWN;

+

+    if (sta_ctrl_attached) {

+        wpa_ctrl_detach(sta_mon_conn);

+        sta_ctrl_attached = 0;

+    }

+    wpa_ctrl_close(sta_ctrl_conn);

+    sta_ctrl_conn = NULL;

+    if (sta_mon_conn) {

+        wpa_ctrl_close(sta_mon_conn);

+        sta_mon_conn = NULL;

+    }

+

+    printf("end.\n");

+    return STA_ERR_SUCCESS;

+}

+

+static sta_err_enum

+sta_ctrl_open_connection(void)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+

+    if(sta_ctrl_conn){

+        return STA_ERR_UNKNOWN;

+    }

+

+    char ctrl_path[100] = {0};

+    result = sta_ctrl_conf_file_parse("ctrl_interface", ctrl_path);

+    if(STA_ERR_SUCCESS != result){

+        printf("sta_ctrl_conf_file_parse() fail(%d).\n",result);

+        return result;

+    }

+    snprintf(ctrl_path + strlen(ctrl_path),10,

+        "/%s",

+        sta_ctrl_ifname);

+

+	printf("ctrl_path = \"%s\"\n",ctrl_path);

+

+    sta_ctrl_conn = wpa_ctrl_open(ctrl_path);

+    if (sta_ctrl_conn == NULL) {

+        sleep(1);

+        return sta_ctrl_open_connection();

+    }

+

+    sta_mon_conn = wpa_ctrl_open(ctrl_path);

+    if (sta_mon_conn == NULL) {

+        return STA_ERR_UNKNOWN;

+    }

+

+    if (wpa_ctrl_attach(sta_mon_conn) == 0) {

+        sta_ctrl_attached = 1;

+    } else {

+        printf("Warning: Failed to attach to "

+               "wpa_supplicant.\n");

+        sta_ctrl_close_connection();

+        return STA_ERR_UNKNOWN;

+    }

+

+    if(!sta_event_thread_is_running) {

+        sta_event_thread_is_running = 1;

+        int ret = pthread_create(&sta_event_thread_id,

+            NULL,

+            sta_ctrl_event_thread_run,

+            NULL);

+        if( ret != 0 ) {

+            printf( "Create thread error!\n");

+        }

+    }else{

+        printf("sta_event_thread is running.\n");

+        return STA_ERR_UNKNOWN;

+    }

+    return result;

+}

+

+static sta_err_enum

+sta_ctrl_reconnect(void)

+{

+    if(STA_ERR_SUCCESS == sta_ctrl_close_connection()){

+        return sta_ctrl_open_connection();

+    }else{

+        return STA_ERR_UNKNOWN;

+    }

+}

+

+static void

+sta_ctrl_recv_event(void)

+{

+	printf("start.\n");

+    if (sta_ctrl_conn == NULL) {

+        sta_ctrl_reconnect();

+		printf("sta_ctrl_conn == NULL:end.\n");

+        return;

+    }

+

+    while (wpa_ctrl_pending(sta_mon_conn) > 0) {

+        char buf[4096];

+        size_t len = sizeof(buf) - 1;

+        if (wpa_ctrl_recv(sta_mon_conn, buf, &len) == 0) {

+            buf[len] = '\0';

+            printf("<<%s>>\n",buf);

+            if(sta_ctrl_msg)

+                sta_ctrl_msg(buf);

+        } else {

+            printf("Could not read pending message.\n");

+            break;

+        }

+    }

+

+    if (wpa_ctrl_pending(sta_mon_conn) < 0) {

+        printf("Connection to wpa_supplicant lost - trying to "

+               "reconnect\n");

+        sta_ctrl_reconnect();

+    }

+

+	printf("end.\n");

+}

+

+static sta_err_enum

+sta_ctrl_conf_file_parse

+(

+    const char *key,

+    char *value

+)

+{

+    sta_err_enum result = STA_ERR_UNKNOWN;

+    FILE *fd = fopen(sta_ctrl_conf_file_path,"r");

+    if(!fd){

+        printf("Open file(%s) fail(%d).\n",sta_ctrl_conf_file_path,errno);

+        return STA_ERR_UNKNOWN;

+    }

+

+    char buf[1024];

+    while(fgets(buf,1024,fd)){

+        char *start = strstr(buf,key);

+        if(start){ // Find key

+            char *tmp = start + strlen(start) -1;

+            while(*tmp){

+                if(*tmp == '\r'

+                    || *tmp == '\n'){

+                    *tmp = '\0';

+                }else{

+                    break;

+                }

+                *tmp--;

+            }

+

+            int size = snprintf(value,100,

+                "%s",

+                start + strlen(key) + 1);

+            value[size] = '\0';

+            result = STA_ERR_SUCCESS;

+            break;

+        }

+    }

+

+    fclose(fd);

+

+    return result;

+}

+

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

+/************************ Public Fuction ***********************/

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

+sta_err_enum

+sta_ctrl_cmd_process

+(

+    const char *cmd,

+    char *reply,

+    size_t reply_len

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    bzero(reply,reply_len);

+    reply_len = reply_len - 1;

+    int ret = wpa_ctrl_request(sta_ctrl_conn,

+        cmd,

+        strlen(cmd),

+        reply,

+        &reply_len,

+        sta_ctrl_wpa_req_cb);

+    if (ret == -2) {

+        printf("command timed out.\n");

+        result = STA_ERR_TIMEOUT;

+        goto end_fail;

+    } else if (ret < 0) {

+        printf("command failed.\n");

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    } else {

+        reply[reply_len] = '\0';

+        printf("1:%s\n", reply);

+

+        if(reply_len > 0 && reply[reply_len - 1] != '\n')

+            printf("\n");

+    }

+

+end_success:

+

+    return result;

+end_fail:

+

+    return result;

+}

+

+/**

+* Open or close wlan driver.

+*/

+sta_err_enum

+sta_ctrl_driver_init(bool open)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+

+    FILE *fd_tmp = NULL;

+    if(open){

+        fd_tmp = popen("/etc/wifi/mbtk_wifi_driver.sh sta start","r");

+    }else{

+        fd_tmp = popen("/etc/wifi/mbtk_wifi_driver.sh driver_rmmod","r");

+    }

+

+    if(fd_tmp){

+        char buf[200] = {0};

+        fgets(buf,200,fd_tmp);

+        pclose(fd_tmp);

+        if(strlen(buf) > 0){

+            printf("Driver %s fail.(%s)\n",(open?"open":"close"),buf);

+            result = STA_ERR_DRIVER;

+        }else{// Open wpa_supplicant

+            printf("Driver %s success.\n",(open?"open":"close"));

+        }

+    }else{

+        printf("Driver %s fail.(%s)\n",(open?"open":"close"));

+        result = STA_ERR_DRIVER;

+    }

+

+    return result;

+}

+

+sta_err_enum

+sta_ctrl_wpa_init

+(

+    const char *conf_file,

+    const char *interface,

+    sta_ctrl_msg_cb cb

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    if(!conf_file

+        || strlen(conf_file) == 0){

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    if(!interface

+        || strlen(interface) == 0){

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    sta_ctrl_msg = cb;

+

+    int size = snprintf(sta_ctrl_conf_file_path,

+        50,

+        "%s",

+        conf_file);

+    sta_ctrl_conf_file_path[size] = '\0';

+    size = snprintf(sta_ctrl_ifname,

+        10,

+        "%s",

+        interface);

+    sta_ctrl_ifname[size] = '\0';

+

+    if(pipe(sta_ctrl_pipe_fd)){

+        printf("pipe() fail(%d).\n",errno);

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    FILE *fd_tmp = popen("pidof wpa_supplicant","r");

+    if(fd_tmp){

+        char buf[200] = {0};

+        fgets(buf,200,fd_tmp);

+        pclose(fd_tmp);

+        if(strlen(buf) > 0){

+            printf("wpa_supplicant is running.(%s)\n",buf);

+        }else{// Open wpa_supplicant

+            bzero(buf,200);

+            

+            snprintf(buf,200,

+                "wpa_supplicant -Dnl80211 -c%s -i%s -f%s -ddd &",

+                conf_file,

+                interface,

+                WPA_SUPPLICANT_LOG_FILE);

+            

+            /*

+             snprintf(buf,200,

+                "wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wifi/wpa_supplicant.conf -B");

+                */

+            if (sta_ctrl_system(buf)){

+                printf("\"%s\" success.\n",buf);

+                sleep(1);

+            }else{

+                printf("\"%s\" fail.\n",buf);

+                result = STA_ERR_UNKNOWN;

+                goto end_fail;

+            }

+        }

+    }else{

+        printf("\"pidof wpa_supplicant\" fail\n");

+        result = STA_ERR_UNKNOWN;

+        goto end_fail;

+    }

+

+    result = sta_ctrl_open_connection();

+    if(STA_ERR_SUCCESS != result) {

+        printf("sta_ctrl_open_connection() fail(%d).\n",result);

+        goto end_fail;

+    }

+

+end_success:

+

+    return result;

+end_fail:

+

+    return result;

+}

+

+sta_err_enum

+sta_ctrl_wpa_deinit

+(

+    void

+)

+{

+    sta_err_enum result = STA_ERR_SUCCESS;

+    result = sta_ctrl_close_connection();

+    if(STA_ERR_SUCCESS != result){

+        goto end_fail;

+    }

+

+    bzero(sta_ctrl_conf_file_path,50);

+    bzero(sta_ctrl_ifname,10);

+

+    sta_event_thread_is_running = 0;

+    // End thread.

+    write(sta_ctrl_pipe_fd[1],"0",1);

+

+

+    printf("Waitting for thread(%ld) exit.\n",sta_event_thread_id);

+

+    pthread_join(sta_event_thread_id,NULL);

+

+    printf("pthread_join() return.\n");

+

+

+    close(sta_ctrl_pipe_fd[0]);

+    close(sta_ctrl_pipe_fd[1]);

+

+    sta_event_thread_id = -1;

+    sta_ctrl_msg = NULL;

+

+    // Stop process wpa_supplicant

+    if(sta_ctrl_system("killall -15 wpa_supplicant")

+        && sta_ctrl_kill_check("wpa_supplicant")){

+        printf("\"killall -15 wpa_supplicant\" success.\n");

+    }else{

+        if(sta_ctrl_system("killall -9 wpa_supplicant")){

+            printf("\"killall -9 wpa_supplicant\" success.\n");

+        }else{

+            printf("\"killall -9 wpa_supplicant\" fail.\n");

+        }

+    }

+

+end_success:

+    printf("sta_ctrl_wpa_deinit() end(success).\n");

+    return result;

+end_fail:

+    printf("sta_ctrl_wpa_deinit() end(fail)[%s].\n",result);

+    return result;

+}

+