Change test makefile.

Change-Id: I27eef2cdb86b220dd03e9be79d5bef7f9303258b
diff --git a/mbtk/test/libql_lib/Makefile b/mbtk/test/libql_lib/Makefile
new file mode 100755
index 0000000..3acd13c
--- /dev/null
+++ b/mbtk/test/libql_lib/Makefile
@@ -0,0 +1,34 @@
+ROOT = $(shell pwd)/../../..
+include $(ROOT)/mbtk/Make.defines
+
+INC_DIR +=
+
+LIB_DIR +=
+
+LIBS += -lmbtk_lib -lmbtk_net -lmbtk_ril -lql_lib -lmbtk_audio -lmbtk_http -lmbtk_fota -lmbtk_factory
+
+CFLAGS += 
+
+DEFINE +=
+
+LOCAL_SRC_FILES = $(wildcard *.c) $(wildcard *.cpp)
+
+$(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES))
+
+OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(LOCAL_SRC_FILES)))
+BINS = $(patsubst %.o,%,$(OBJS))
+
+all: $(BINS)
+
+$(BINS):$(OBJS)
+	@echo "  BIN     $@"
+	$(CC) $(CFLAGS) $(LIB_DIR) $(LIBS) $@.o -o $(OUT_DIR)/bin/$@
+
+%.o:%.c
+	$(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+%.o:%.cpp
+	$(CC) $(CFLAGS) $(INC_DIR) $(DEFINE) -c $< -o $@
+
+clean:
+	rm -f $(OBJS)
diff --git a/mbtk/test/libql_lib/ql_DSI_ConnectManager_test.c b/mbtk/test/libql_lib/ql_DSI_ConnectManager_test.c
new file mode 100755
index 0000000..ae7edcc
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_DSI_ConnectManager_test.c
@@ -0,0 +1,364 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "ql/DSI_ConnectManager.h"
+#include "mbtk_log.h"
+
+static void help()
+{
+    printf("apn_get <cid> : Get current apns.\n");
+    printf("apn <cid> <0/1/2> <apn> [<user> <pass> <auth>] : Set apn (IPV4V6/IPV4/IPV6).\n");
+    printf("data_call <0/1/2> <cid> <timeout>: Stop/Start/State data call.\n");
+    printf("data_call_ex <0/1/2> <cid> <timeout>: Stop/Start/State data call.\n");
+}
+
+static int proc_exit()
+{
+    int err = ql_wan_release();
+    if(err)
+    {
+        printf("ql_wan_release fail.");
+        return -1;
+    }
+    return 0;
+}
+
+static void sig_process(int sig)
+{
+    LOGI("I got signal %d\n", sig);
+    switch(sig)
+    {
+        case SIGINT: // Ctrl + C
+        {
+            LOGI("Exit by SIGINT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGQUIT: // Ctrl + \ (类似 SIGINT ,但要产生core文件)
+        {
+            LOGI("Exit by SIGQUIT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTERM:// 默认kill   (同 SIGKILL ,但 SIGKILL 不可捕获)
+        {
+            LOGI("Exit by SIGTERM.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTSTP:// Ctrl + Z (同 SIGSTOP ,但 SIGSTOP 不可捕获)
+        {
+            LOGI("Exit by SIGTSTP.\n");
+            exit(0);
+        }
+        case SIGSEGV: // 如空指针
+        {
+            LOGI("Exit by SIGSEGV.\n");
+            exit(0);
+        }
+        default:
+        {
+            LOGI("Unknown sig:%d\n",sig);
+            break;
+        }
+    }
+}
+
+static void data_call_status_cb(int status)
+{
+    printf("DATA_CALL_STATE:%d\n", status);
+}
+
+static void data_call_ex_status_cb(int cid,int iptype,int status,int cause)
+{
+    printf("DATA_CALL_EX_STATE:%d, %d, %d, %d\n", cid, iptype, status, cause);
+}
+
+int main(int argc, char *argv[])
+{
+    signal(SIGINT, sig_process);
+    signal(SIGQUIT, sig_process);
+    signal(SIGTERM, sig_process);
+    //signal(SIGTSTP, sig_process);
+    //signal(SIGSEGV, sig_process);
+
+    mbtk_log_init(NULL,"MBTK_QL_TEST");
+
+    //test2(0, "192.168.1.198");
+    //test2(1, "2409:8162:140:cd3c:1:2:1494:72ba");
+    //test2(1, "254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239");
+    //test2(1, "2400:3200::1");
+
+    int err = ql_wan_init();
+    if(err)
+    {
+        printf("ql_wan_init fail.");
+        return -1;
+    }
+
+    printf(">>>>>>>>>>>>>>>>>>>>>>>>Enter cmd:\n");
+    char cmd[100];
+    while(1)
+    {
+        memset(cmd, 0, 100);
+        if(fgets(cmd, 100, stdin))
+        {
+            char *ptr = cmd + strlen(cmd) - 1;
+            while(ptr >= cmd && (*ptr == '\r' || *ptr == '\n'))
+            {
+                *ptr-- = '\0';
+            }
+
+            if(!strncasecmp(cmd, "apn", 3)){
+                if(!strncasecmp(cmd, "apn_get", 7)) { // Get apn
+                    char *ptr = strstr(cmd, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    int cid = atoi(ptr);
+                    int ip_type = -1;
+                    char apn[128] = {0};
+                    char userName[128] = {0};
+                    char password[128] = {0};
+                    int auth = -1;
+                    err = ql_wan_getapn(cid, &ip_type, apn, 128, userName, 128, password, 128, &auth);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("APN : %d, %d, %s, %s, %s, %d\n", cid, ip_type, apn, userName, password, auth);
+                    }
+                } else { // apn <cid> <0/1/2> <apn> [<user> <pass> <auth>]
+                    char *ptr = strstr(cmd, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    int cid = atoi(ptr);
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    int ip_type = atoi(ptr);
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    char apn[128] = {0};
+                    memcpy(apn, ptr, strlen(ptr));
+                    char *tmp = apn;
+                    while(*tmp) {
+                        if(*tmp == ' ') {
+                            *tmp = '\0';
+                            break;
+                        }
+                        tmp++;
+                    }
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL) {
+                        err = ql_wan_setapn(cid, ip_type, apn, NULL, NULL, QL_DSI_AUTH_PREF_NULL);
+                    } else {
+                        while(*ptr != '\0' && *ptr == ' ')
+                            ptr++;
+                        char user[128] = {0};
+                        memcpy(user, ptr, strlen(ptr));
+                        tmp = user;
+                        while(*tmp) {
+                            if(*tmp == ' ') {
+                                *tmp = '\0';
+                                break;
+                            }
+                            tmp++;
+                        }
+
+                        ptr = strstr(ptr, " ");
+                        if(ptr == NULL)
+                            continue;
+                        while(*ptr != '\0' && *ptr == ' ')
+                            ptr++;
+                        char pass[128] = {0};
+                        memcpy(pass, ptr, strlen(ptr));
+                        tmp = pass;
+                        while(*tmp) {
+                            if(*tmp == ' ') {
+                                *tmp = '\0';
+                                break;
+                            }
+                            tmp++;
+                        }
+
+                        ptr = strstr(ptr, " ");
+                        if(ptr == NULL)
+                            continue;
+                        while(*ptr != '\0' && *ptr == ' ')
+                            ptr++;
+                        QL_DSI_AUTH_PREF_T auth  = (QL_DSI_AUTH_PREF_T)atoi(ptr);
+
+                        err = ql_wan_setapn(cid, ip_type, apn, user, pass, auth);
+                    }
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("APN set success\n");
+                    }
+                }
+            } else if(!strncasecmp(cmd, "data_call_ex", 12)){ // data_call_ex <0/1/2> <cid> <timeout>
+                // data_call <0/1/2> <cid> <timeout>
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                int type = atoi(ptr);
+
+                ptr = strstr(ptr, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                int cid = atoi(ptr);
+
+                ptr = strstr(ptr, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                int timeout = atoi(ptr);
+
+                switch (type)
+                {
+                    case 0:
+                        err = ql_wan_stop(cid);
+                        break;
+                    case 1:
+                        err = ql_wan_start_ex(cid, 1, data_call_ex_status_cb);
+                        break;
+                    case 2: {
+                        ql_data_call_info info;
+                        err = ql_get_data_call_info(cid, &info);
+                        if(!err) {
+                            printf("cid : %d, ip_type : %d\n", info.profile_idx, info.ip_type);
+                            if(info.v4.state) {
+                                printf("%s: %s, %s, %s\n", info.v4.addr.name, info.v4.addr.ip, info.v4.addr.pri_dns, info.v4.addr.sec_dns);
+                            } else {
+                                printf("IPV4 not available.\n");
+                            }
+
+                            if(info.v6.state) {
+                                printf("%s: %s, %s, %s\n", info.v6.addr.name, info.v6.addr.ip, info.v6.addr.pri_dns, info.v6.addr.sec_dns);
+                            } else {
+                                printf("IPV6 not available.\n");
+                            }
+                        }
+                        break;
+                    }
+                    default:
+                        printf("Type error:%d\n", type);
+                        break;
+                }
+
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("DATA_CALL success\n");
+                }
+            } else if(!strncasecmp(cmd, "data_call", 9)){ // data_call <0/1/2> <cid> <timeout>
+                // data_call <0/1/2> <cid> <timeout>
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                int type = atoi(ptr);
+
+                ptr = strstr(ptr, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                int cid = atoi(ptr);
+
+                ptr = strstr(ptr, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                int timeout = atoi(ptr);
+
+                switch (type)
+                {
+                    case 0:
+                        err = ql_wan_stop(cid);
+                        break;
+                    case 1:
+                        err = ql_wan_start(cid, 1, data_call_status_cb);
+                        break;
+                    case 2: {
+                        ql_data_call_info info;
+                        err = ql_get_data_call_info(cid, &info);
+                        if(!err) {
+                            printf("cid : %d, ip_type : %d\n", info.profile_idx, info.ip_type);
+                            if(info.v4.state) {
+                                printf("%s: %s, %s, %s\n", info.v4.addr.name, info.v4.addr.ip, info.v4.addr.pri_dns, info.v4.addr.sec_dns);
+                            } else {
+                                printf("IPV4 not available.\n");
+                            }
+
+                            if(info.v6.state) {
+                                printf("%s: %s, %s, %s\n", info.v6.addr.name, info.v6.addr.ip, info.v6.addr.pri_dns, info.v6.addr.sec_dns);
+                            } else {
+                                printf("IPV6 not available.\n");
+                            }
+                        }
+                        break;
+                    }
+                    default:
+                        printf("Type error:%d\n", type);
+                        break;
+                }
+
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("DATA_CALL success\n");
+                }
+            }
+            else if(!strcasecmp(cmd, "h") || !strcasecmp(cmd, "help")) {
+                help();
+            } else if(!strcasecmp(cmd, "q")) {
+                break;
+            } else {
+                printf("\n");
+            }
+        }
+    }
+
+    proc_exit();
+
+    LOGI("Client exec complete.");
+#if 1
+    while(1)
+    {
+        sleep(1000 * 365 * 24 * 60 * 60);
+    }
+#else
+    sleep(1);
+#endif
+    return 0;
+}
+
diff --git a/mbtk/test/libql_lib/ql_adc_test.c b/mbtk/test/libql_lib/ql_adc_test.c
new file mode 100755
index 0000000..6eb83f6
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_adc_test.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+#include "ql/ql_adc.h"
+
+int main(int argc, char *argv[])
+{
+    int adc = ql_adc_show(ADC0);
+    if(adc > 0) {
+        printf("ADC0 = %d\n", adc);
+    } else {
+        printf("Get ADC0 fail.\n");
+    }
+
+    adc = ql_adc_show(ADC1);
+    if(adc > 0) {
+        printf("ADC1 = %d\n", adc);
+    } else {
+        printf("Get ADC1 fail.\n");
+    }
+    return 0;
+}
+
diff --git a/mbtk/test/libql_lib/ql_call_test.c b/mbtk/test/libql_lib/ql_call_test.c
new file mode 100755
index 0000000..3d41fed
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_call_test.c
@@ -0,0 +1,283 @@
+#include "mbtk_type.h"
+#include "ql/ql_at.h"
+#include "ql/ql_vcall.h"
+#include "ql/ql_mcm_call.h"
+
+typedef struct
+{
+    int  cmdIdx;
+    char *funcName;
+} st_api_test_case;
+
+//for server test
+st_api_test_case at_api_testcases[] =
+{
+    {0,   "print_help"},
+    {1,   "QL_Voice_Call_Ecall"},
+    {2,   "QL_Voice_Call_Ecall_HangUp"},
+
+    {-1,    NULL}
+};
+
+void print_help(void)
+{
+    int i;
+
+    printf("Supported test cases:\n");
+    for(i = 0; ; i++)
+    {
+        if(at_api_testcases[i].cmdIdx == -1)
+        {
+            break;
+        }
+        printf("%d:\t%s\n", at_api_testcases[i].cmdIdx, at_api_testcases[i].funcName);
+    }
+}
+
+static void ql_voice_call_ind_func(unsigned int ind_id,
+                                   void* ind_data,
+                                   uint32_t ind_data_len)
+{
+    if(NULL == ind_data)
+    {
+        return;
+    }
+
+    switch(ind_id)
+    {
+        case E_QL_MCM_VOICE_CALL_IND:
+        {
+            if(ind_data_len != sizeof(ql_mcm_voice_call_ind))
+            {
+                break;
+            }
+
+            ql_mcm_voice_call_ind *pVoiceCallInd = (ql_mcm_voice_call_ind*)ind_data;
+
+            char *call_state[] = {"INCOMING", "DIALING", "ALERTING", "ACTIVE", "HOLDING", "END", "WAITING"};
+
+            int i = 0;
+            for(i = 0; i < pVoiceCallInd->calls_len; i++)
+            {
+                printf("######### Call id=%d, PhoneNum:%s, event=%s!  ######\n",
+                            pVoiceCallInd->calls[i].call_id, pVoiceCallInd->calls[i].number, call_state[pVoiceCallInd->calls[i].state]);
+            }
+
+            break;
+        }
+
+        case E_QL_MCM_VOICE_ECALL_STATUE_IND:
+        {
+            if(ind_data_len != sizeof(ql_mcm_voice_ecall_status_ind))
+            {
+                break;
+            }
+
+            ql_mcm_voice_ecall_status_ind *pEcallStatusInd
+                                           = (ql_mcm_voice_ecall_status_ind*)ind_data;
+
+            if (pEcallStatusInd->ecall_msd_tx_status_valid)
+            {
+                if (pEcallStatusInd->ecall_msd_tx_status == E_QL_MCM_VOICE_ECALL_MSD_TRANSMISSION_STATUS_SUCCESS)
+                {
+                    printf("========== Ecall status  call_id =%d ,   ecall msd tx success.\r\n", pEcallStatusInd->call_id);
+                }
+                else
+                {
+                    printf("========== Ecall status  call_id =%d ,   ecall msd tx failure.\r\n",  pEcallStatusInd->call_id);
+                }
+            }
+            else
+            {
+                printf("========== Ecall status  call_id =%d  \r\n", pEcallStatusInd->call_id);
+            }
+
+            break;
+        }
+
+        case E_QL_MCM_VOICE_UNKOWN_IND:
+        default:
+            break;
+    }
+}
+
+#if 0
+int main(int argc, char *argv[])
+{
+    int    cmdIdx  = 0;
+    int    ret     = E_QL_OK;
+    char   phoneNum[32] = {0};
+    voice_client_handle_type    h_voice     = 0;
+    int                         voice_call_id = 0;
+
+    printf("QL_Voice_Call_Client_Init .....\n");
+    ret = QL_Voice_Call_Client_Init(&h_voice);
+    if(ret < 0)
+    {
+        printf("QL_Voice_Call_Client_Init FAIL.	ret:%d\n",ret);
+        return -1;
+    }
+    printf("QL_Voice_Call_Client_Init ret = %d, with h_voice=%d\n", ret, h_voice);
+
+    ret = QL_Voice_Call_AddCommonStateHandler(h_voice, (QL_VoiceCall_CommonStateHandlerFunc_t)ql_voice_call_ind_func);
+    if(ret < 0)
+    {
+        printf("QL_Voice_Call_AddCommonStateHandler FAIL.		ret:%d\n",ret);
+        return -1;
+    }
+    printf("QL_Voice_Call_AddCommonStateHandler ret = %d\n", ret);
+
+    print_help();
+
+    while(1)
+    {
+        printf("please input cmd index(-1 exit): ");
+        scanf("%d", &cmdIdx);
+        if(cmdIdx == -1)
+        {
+            break;
+        }
+
+        switch(cmdIdx)
+        {
+        case 0://"print_help"
+        {
+            print_help();
+            break;
+        }
+       	case 1://"QL_Voice_Call_Ecall"
+        {
+            char    PhoneNum[32]                  = {0};
+            printf("please input dest phone number: \n");
+            scanf("%s", PhoneNum);
+
+			char    msd[140+1]                  = {0};
+            printf("please input msd content: \n");
+            scanf("%s", msd);
+
+            E_QL_MCM_ECALL_VARIANT_T ecall_mode;
+            printf("please input ecall mode(1:test 2:emergency): \n");
+            scanf("%d", &ecall_mode);
+            QL_Voice_Call_Start(h_voice, E_QL_VCALL_EXTERNAL_SLOT_1, PhoneNum, NULL);
+            // ret = QL_Voice_Call_Ecall(h_voice, E_QL_VCALL_EXTERNAL_SLOT_1, PhoneNum,
+            //                           ecall_mode, &voice_call_id);
+			printf(" voice_call_id = %d\n", voice_call_id);
+            printf(" ret = %d\n", ret);
+            break;
+        }
+        case 2://QL_Voice_Call_Ecall_HangUp
+        {
+            ret = QL_Voice_Call_Ecall_HangUp(h_voice);
+            printf(" ret = %d\n", ret);
+            break;
+        }
+
+       default:
+            print_help();
+            break;
+        }
+    }
+
+    ret = QL_Voice_Call_RemoveCommonStateHandler(h_voice);
+    if(ret < 0)
+    {
+        printf("QL_Voice_Call_RemoveCommonStateHandler.	ret:%d\n",ret);
+        return -1;
+    }
+    printf("QL_Voice_Call_RemoveCommonStateHandler ret = %d\n", ret);
+
+    ret = QL_Voice_Call_Client_Deinit(h_voice);
+    if(ret < 0)
+    {
+        printf("QL_Voice_Call_Client_Deinit FAIL.	ret:%d\n",ret);
+        return -1;
+    }
+    printf("QL_Voice_Call_Client_Deinit ret = %d, with h_voice=%d\n", ret, h_voice);
+
+    return 0;
+}
+#else
+
+int main(int argc, char *argv[])
+{
+    char operator[10];
+    int opt;
+    int    ret     = E_QL_OK;
+    char   phoneNum[32] = {0};
+    voice_client_handle_type    h_voice     = 0;
+
+    while(1)
+    {
+        printf("=========call main=========\n"
+            "\t0 exit\n"
+            "\t1 call init\n"
+            "\t2 call register handle\n"
+            "\t3 call start\n"
+            "\t4 call end\n"
+            "\t5 call answer\n"
+            "\t6 call set auto answer\n"
+            "\t7 call hold\n"
+            "\t8 call unhold\n"
+            "\t9 call deinit\n"
+            "operator: >> ");
+
+        fgets(operator, sizeof(operator), stdin);
+        fflush(stdin);
+        opt = atoi(operator);
+        switch (opt)
+        {
+        case 0:
+            printf("main exit\n");
+            return 0;
+        case 1:
+            ret = QL_Voice_Call_Client_Init(&h_voice);
+            if(ret < 0)
+            {
+                printf("QL_Voice_Call_Client_Init FAIL.	ret:%d\n",ret);
+                return -1;
+            }
+            printf("QL_Voice_Call_Client_Init ret = %d, with h_voice=%d\n", ret, h_voice);
+
+            break;
+        case 2:
+            ret = QL_Voice_Call_AddCommonStateHandler(h_voice, (QL_VoiceCall_CommonStateHandlerFunc_t)ql_voice_call_ind_func);
+            if(ret < 0)
+            {
+                printf("QL_Voice_Call_AddCommonStateHandler FAIL.		ret:%d\n",ret);
+                return -1;
+            }
+            break;
+        case 3:
+            QL_Voice_Call_Start(h_voice, 0, "15982066434", NULL);
+            break;
+        case 4:
+            QL_Voice_Call_End(h_voice, 0);
+            break;
+        case 5:
+            QL_Voice_Call_Answer(h_voice, 0);
+            break;
+        case 6:
+            QL_Voice_Call_SetAutoAnswer(h_voice, E_QL_MCM_VOICE_AUTO_ANSWER_ENABLE, 6000);
+            break;
+        case 7:
+            QL_Voice_Call_Hold(h_voice);
+            break;
+        case 8:
+            QL_Voice_Call_UnHold(h_voice);
+            break;
+        case 9:
+            QL_Voice_Call_Client_Deinit(h_voice);
+            break;
+        case 10:
+            // QL_Voice_Call_UnHold;
+            break;
+        default:
+            break;
+        }
+
+        sleep(1);
+    }
+
+    return 0;
+}
+#endif
diff --git a/mbtk/test/libql_lib/ql_dev_test.c b/mbtk/test/libql_lib/ql_dev_test.c
new file mode 100755
index 0000000..105f460
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_dev_test.c
@@ -0,0 +1,201 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "ql/ql_dev.h"
+#include "mbtk_log.h"
+
+static void help()
+{
+    printf("version: Get version.\n");
+    printf("imei: Get IMEI.\n");
+    printf("sn: Get SN.\n");
+    printf("model: Get Model.\n");
+    printf("cfun: Get radio state.\n");
+    printf("cfun <state> <rest>: Set radio state.\n");
+}
+
+static int proc_exit()
+{
+    QL_DEV_ERROR_CODE err = ql_dev_release();
+    if(QL_DEV_SUCCESS != err)
+    {
+        printf("ql_dev_release fail.");
+        return -1;
+    }
+    return 0;
+}
+
+static void sig_process(int sig)
+{
+    LOGI("I got signal %d\n", sig);
+    switch(sig)
+    {
+        case SIGINT: // Ctrl + C
+        {
+            LOGI("Exit by SIGINT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGQUIT: // Ctrl + \ (类似 SIGINT ,但要产生core文件)
+        {
+            LOGI("Exit by SIGQUIT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTERM:// 默认kill   (同 SIGKILL ,但 SIGKILL 不可捕获)
+        {
+            LOGI("Exit by SIGTERM.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTSTP:// Ctrl + Z (同 SIGSTOP ,但 SIGSTOP 不可捕获)
+        {
+            LOGI("Exit by SIGTSTP.\n");
+            exit(0);
+        }
+        case SIGSEGV: // 如空指针
+        {
+            LOGI("Exit by SIGSEGV.\n");
+            exit(0);
+        }
+        default:
+        {
+            LOGI("Unknown sig:%d\n",sig);
+            break;
+        }
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    signal(SIGINT, sig_process);
+    signal(SIGQUIT, sig_process);
+    signal(SIGTERM, sig_process);
+    //signal(SIGTSTP, sig_process);
+    //signal(SIGSEGV, sig_process);
+
+    mbtk_log_init(NULL,"MBTK_QL_TEST");
+
+    //test2(0, "192.168.1.198");
+    //test2(1, "2409:8162:140:cd3c:1:2:1494:72ba");
+    //test2(1, "254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239");
+    //test2(1, "2400:3200::1");
+
+    QL_DEV_ERROR_CODE err = ql_dev_init();
+    if(QL_DEV_SUCCESS != err)
+    {
+        printf("ql_dev_init fail.");
+        return -1;
+    }
+
+    printf(">>>>>>>>>>>>>>>>>>>>>>>>Enter cmd:\n");
+    char cmd[100];
+    while(1)
+    {
+        memset(cmd, 0, 100);
+        if(fgets(cmd, 100, stdin))
+        {
+            char *ptr = cmd + strlen(cmd) - 1;
+            while(ptr >= cmd && (*ptr == '\r' || *ptr == '\n'))
+            {
+                *ptr-- = '\0';
+            }
+
+            if(!strncasecmp(cmd, "version", 7))
+            {
+                char version[50] = {0};
+                err = ql_dev_get_firmware_version(version);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Version : %s\n", version);
+                }
+            } else if(!strncasecmp(cmd, "imei", 4)){
+                char imei[50] = {0};
+                err = ql_dev_get_imei(imei);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("IMEI : %s\n", imei);
+                }
+            } else if(!strncasecmp(cmd, "sn", 2)){
+                char sn[50] = {0};
+                err = ql_dev_get_sn(sn);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("SN : %s\n", sn);
+                }
+            } else if(!strncasecmp(cmd, "model", 5)){
+                char model[50] = {0};
+                err = ql_dev_get_model(model);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Model : %s\n", model);
+                }
+            } else if(!strncasecmp(cmd, "cfun", 4)){
+                int cfun;
+                if(!strcasecmp(cmd, "cfun")) { // Get
+                    err = ql_dev_get_modem_fun(&cfun);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("Cfun : %d\n", cfun);
+                    }
+                } else { // Set
+                    char *ptr = strstr(cmd, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    cfun = atoi(ptr);
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    int rst = atoi(ptr);
+                    err = ql_dev_set_modem_fun((QL_DEV_MODEM_FUNCTION)cfun, rst);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("cfun set success\n");
+                    }
+                }
+            }
+            else if(!strcasecmp(cmd, "h") || !strcasecmp(cmd, "help")) {
+                help();
+            } else if(!strcasecmp(cmd, "q")) {
+                break;
+            } else {
+                printf("\n");
+            }
+        }
+    }
+
+    proc_exit();
+
+    LOGI("Client exec complete.");
+#if 1
+    while(1)
+    {
+        sleep(1000 * 365 * 24 * 60 * 60);
+    }
+#else
+    sleep(1);
+#endif
+    return 0;
+}
+
diff --git a/mbtk/test/libql_lib/ql_gpio_test.c b/mbtk/test/libql_lib/ql_gpio_test.c
new file mode 100755
index 0000000..c2b2754
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_gpio_test.c
@@ -0,0 +1,44 @@
+#include "ql/ql_gpio.h"
+#include "mbtk_log.h"
+
+int main(int argc, char *argv[])
+{
+    mbtk_log_init("radio", "MBTK_GPIO");
+
+    if(argc != 2) {
+        printf("./gpio_test <gpio>\n");
+        return -1;
+    }
+
+    int tmp_gpio = atoi(argv[1]);
+    if(tmp_gpio <= 0) {
+        printf("GPIO error : %d\n", tmp_gpio);
+        return -1;
+    }
+
+    Enum_PinName gpio = (Enum_PinName)tmp_gpio;
+    if(Ql_GPIO_Init(gpio, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_DISABLE)) {
+        printf("Ql_GPIO_Init() fail.\n");
+        return -1;
+    }
+
+    printf("GPIO : %d, dir : %s, level : %d\n", gpio, Ql_GPIO_GetDirection(gpio) == PINDIRECTION_IN ? "in" : "out",
+        Ql_GPIO_GetLevel(gpio));
+
+    if(Ql_GPIO_SetLevel(gpio, PINLEVEL_HIGH)) {
+        printf("Ql_GPIO_SetLevel() fail.\n");
+        return -1;
+    }
+
+    printf("GPIO : %d, dir : %s, level : %d\n", gpio, Ql_GPIO_GetDirection(gpio) == PINDIRECTION_IN ? "in" : "out",
+        Ql_GPIO_GetLevel(gpio));
+
+    if(Ql_GPIO_Uninit(gpio)) {
+        printf("Ql_GPIO_Uninit() fail.\n");
+        return -1;
+    }
+
+    printf("Success!!!\n");
+    return 0;
+}
+
diff --git a/mbtk/test/libql_lib/ql_i2c_test.c b/mbtk/test/libql_lib/ql_i2c_test.c
new file mode 100755
index 0000000..04aed4d
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_i2c_test.c
@@ -0,0 +1,31 @@
+#include "ql/ql_i2c.h"
+
+
+int main(int argc, char *argv[])
+{
+	int fd = -1;
+    if(argc != 2) {
+        printf("./i2c_test <dev>\n");
+        return -1;
+    }
+    char send_data[64] = {0};
+	send_data[0] = 0x55;
+	send_data[1] = 0x00;
+	send_data[2] = 0x84;
+    fd= Ql_I2C_Init(argv[1]);
+    if(fd <= 0) {
+        printf("Ql_I2C_Init() fail.\n");
+        return -1;
+    }
+
+	if(Ql_I2C_Write(fd, 0x12, 0x10,send_data, 3) < 0) {
+        printf("Ql_I2C_Write() fail.\n");
+        return -1;
+	}
+
+    Ql_I2C_Deinit(fd);
+
+    printf("Success!!!\n");
+
+    return 0;
+}
diff --git a/mbtk/test/libql_lib/ql_nw_test.c b/mbtk/test/libql_lib/ql_nw_test.c
new file mode 100755
index 0000000..81acb5c
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_nw_test.c
@@ -0,0 +1,334 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "ql/ql_nw.h"
+#include "mbtk_log.h"
+
+static void help()
+{
+    printf("net_pref : Get net prefferred.\n");
+    printf("net_pref <net_pref> <roaming> : Set net prefferred.\n");
+    printf("net_time : Get network time.\n");
+    printf("operator : Get current operator information.\n");
+    printf("net_avail : Get available networks.\n");
+    printf("reg : Get current reg info.\n");
+    printf("sel_mode: Get network select mode.\n");
+    printf("sel_mode <sel_mode> <net_type> <plmn>: Set network select mode.\n");
+    printf("signal : Get current signal.\n");
+    printf("cell : Get cell info.\n");
+    printf("volte : Get VOLTE state.\n");
+    printf("csq_signal : Get current csq signal.\n");
+}
+
+static int proc_exit()
+{
+    QL_NW_ERROR_CODE err = ql_nw_release();
+    if(QL_NW_SUCCESS != err)
+    {
+        printf("ql_nw_release fail.");
+        return -1;
+    }
+    return 0;
+}
+
+static void sig_process(int sig)
+{
+    LOGI("I got signal %d\n", sig);
+    switch(sig)
+    {
+        case SIGINT: // Ctrl + C
+        {
+            LOGI("Exit by SIGINT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGQUIT: // Ctrl + \ (类似 SIGINT ,但要产生core文件)
+        {
+            LOGI("Exit by SIGQUIT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTERM:// 默认kill   (同 SIGKILL ,但 SIGKILL 不可捕获)
+        {
+            LOGI("Exit by SIGTERM.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTSTP:// Ctrl + Z (同 SIGSTOP ,但 SIGSTOP 不可捕获)
+        {
+            LOGI("Exit by SIGTSTP.\n");
+            exit(0);
+        }
+        case SIGSEGV: // 如空指针
+        {
+            LOGI("Exit by SIGSEGV.\n");
+            exit(0);
+        }
+        default:
+        {
+            LOGI("Unknown sig:%d\n",sig);
+            break;
+        }
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    signal(SIGINT, sig_process);
+    signal(SIGQUIT, sig_process);
+    signal(SIGTERM, sig_process);
+    //signal(SIGTSTP, sig_process);
+    //signal(SIGSEGV, sig_process);
+
+    mbtk_log_init(NULL,"MBTK_QL_TEST");
+
+    //test2(0, "192.168.1.198");
+    //test2(1, "2409:8162:140:cd3c:1:2:1494:72ba");
+    //test2(1, "254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239");
+    //test2(1, "2400:3200::1");
+
+    QL_NW_ERROR_CODE err = ql_nw_init();
+    if(QL_NW_SUCCESS != err)
+    {
+        printf("ql_nw_init fail.");
+        return -1;
+    }
+
+    printf(">>>>>>>>>>>>>>>>>>>>>>>>Enter cmd:\n");
+    char cmd[100];
+    while(1)
+    {
+        memset(cmd, 0, 100);
+        if(fgets(cmd, 100, stdin))
+        {
+            char *ptr = cmd + strlen(cmd) - 1;
+            while(ptr >= cmd && (*ptr == '\r' || *ptr == '\n'))
+            {
+                *ptr-- = '\0';
+            }
+
+            if(!strncasecmp(cmd, "net_pref", 8)){
+                QL_NW_CONFIG_INFO_T net_pref;
+                if(!strcasecmp(cmd, "net_pref")) { // Get
+                    err = ql_nw_get_config(&net_pref);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("net_pref : %d, roaming : %d\n", net_pref.preferred_nw_mode, net_pref.roaming_pref);
+                    }
+                } else { // Set
+                    char *ptr = strstr(cmd, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    net_pref.preferred_nw_mode = atoi(ptr);
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    net_pref.roaming_pref = atoi(ptr);
+
+                    err = ql_nw_set_config(&net_pref);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("net_pref set success\n");
+                    }
+                }
+            } else if(!strncasecmp(cmd, "net_time", 8)){
+                QL_NW_NITZ_TIME_INFO_T time;
+                err = ql_nw_get_nitz_time_info(&time);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Time : %s, %ld, %d\n", time.nitz_time, time.abs_time, time.leap_sec);
+                }
+            } else if(!strncasecmp(cmd, "operator", 8)){
+                QL_NW_OPERATOR_INFO_T operator;
+                err = ql_nw_get_operator_name(&operator);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Operator : %s, %s, %s, %s\n", operator.long_eons, operator.short_eons, operator.mcc, operator.mnc);
+                }
+            } else if(!strncasecmp(cmd, "net_avail", 9)){
+                QL_NW_SCAN_RESULT_LIST_INFO_T nets;
+                err = ql_nw_perform_scan(&nets);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    if(nets.entry_len > 0) {
+                        int i = 0;
+                        for(; i < nets.entry_len; i++) {
+                            printf("Net %d: %d, %d, %s, %s, %s, %s\n", i+1, nets.entry[i].status, nets.entry[i].act,
+                                nets.entry[i].operator_name.long_eons, nets.entry[i].operator_name.short_eons,
+                                nets.entry[i].operator_name.mcc, nets.entry[i].operator_name.mnc);
+                        }
+                    }
+                }
+            } else if(!strncasecmp(cmd, "reg", 3)){
+                QL_NW_REG_STATUS_INFO_T reg;
+                err = ql_nw_get_reg_status(&reg);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Data Reg:%d, %d, %x, %x\n", reg.data_reg.state, reg.data_reg.rat, reg.data_reg.lac, reg.data_reg.cid);
+                    printf("Voice Reg:%d, %d, %x, %x\n", reg.voice_reg.state, reg.voice_reg.rat, reg.voice_reg.lac, reg.voice_reg.cid);
+                }
+            } else if(!strncasecmp(cmd, "sel_mode", 8)){ // "sel_mode" or "sel_mode 460 00 7"
+                QL_NW_SELECTION_INFO_T net;
+                memset(&net, 0, sizeof(QL_NW_SELECTION_INFO_T));
+                if(!strcasecmp(cmd, "sel_mode")) { // Get
+                    err = ql_nw_get_selection(&net);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("Net : %d, %s, %s, %d\n", net.nw_selection_mode , net.mcc , net.mnc , net.act);
+                    }
+                } else { // Set
+                    char *ptr = strstr(cmd, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    net.nw_selection_mode = atoi(ptr);
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    //net.mcc = (uint8)atoi(ptr);
+                    memcpy(net.mcc, ptr, 4);
+                    int i = 0;
+                    while(i < 4) {
+                        if(net.mcc[i] == ' ') {
+                            net.mcc[i] = '\0';
+                            break;
+                        }
+                        i++;
+                    }
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    //net.mnc = (uint32)atoi(ptr);
+                    memcpy(net.mnc, ptr, 4);
+                    i = 0;
+                    while(i < 4) {
+                        if(net.mnc[i] == ' ') {
+                            net.mnc[i] = '\0';
+                            break;
+                        }
+                        i++;
+                    }
+
+                    ptr = strstr(ptr, " ");
+                    if(ptr == NULL)
+                        continue;
+                    while(*ptr != '\0' && *ptr == ' ')
+                        ptr++;
+                    net.act = (QL_NW_ACCESS_TECHNOLOGY)atoi(ptr);
+
+                    err = ql_nw_set_selection(&net);
+                    if(err) {
+                        printf("Error : %d\n", err);
+                    } else {
+                        printf("Net select mode set success\n");
+                    }
+                }
+            } else if(!strncasecmp(cmd, "signal", 6)){
+                QL_NW_SIGNAL_STRENGTH_INFO_T sig;
+                err = ql_nw_get_signal_strength(&sig);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Signal GSM:%d, %d, %d, %d\n", sig.GW_SignalStrength.rscp, sig.GW_SignalStrength.bitErrorRate, sig.GW_SignalStrength.rscp, sig.GW_SignalStrength.ecio);
+                    printf("Signal LTE:%d, %d, %d, %d, %d\n", sig.LTE_SignalStrength.rssi , sig.LTE_SignalStrength.rsrp, sig.LTE_SignalStrength.rsrq, sig.LTE_SignalStrength.rssnr, sig.LTE_SignalStrength.cqi);
+                }
+            } else if(!strncasecmp(cmd, "cell", 4)){
+                QL_NW_CELL_INFO_T cell;
+                err = ql_nw_get_cell_info(&cell);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    int i = 0;
+                    if(cell.gsm_info_valid) {
+                        while(i < cell.gsm_info_num) {
+                            printf("GSM cell %d: %d, %x, %d, %d, %x, %d, %d\n", i + 1, cell.gsm_info[i].flag, cell.gsm_info[i].cid, cell.gsm_info[i].mcc, cell.gsm_info[i].mnc, cell.gsm_info[i].lac, cell.gsm_info[i].arfcn, cell.gsm_info[i].bsic);
+                            i++;
+                        }
+                    }
+
+                    if(cell.umts_info_valid) {
+                        i = 0;
+                        while(i < cell.umts_info_num) {
+                            printf("UMTS cell %d: %d, %x, %x, %d, %d, %x, %d, %d\n", i + 1, cell.umts_info[i].flag , cell.umts_info[i].cid, cell.umts_info[i].lcid, cell.umts_info[i].mcc, cell.umts_info[i].mnc, cell.umts_info[i].lac, cell.umts_info[i].uarfcn, cell.umts_info[i].psc);
+                            i++;
+                        }
+                    }
+
+                    if(cell.lte_info_valid) {
+                        i = 0;
+                        while(i < cell.lte_info_num) {
+                            printf("LTE cell %d: %d, %x, %d, %d, %x, %d, %d\n", i + 1, cell.lte_info[i].flag, cell.lte_info[i].cid, cell.lte_info[i].mcc, cell.lte_info[i].mnc, cell.lte_info[i].tac, cell.lte_info[i].pci, cell.lte_info[i].earfcn);
+                            i++;
+                        }
+                    }
+                }
+            } else if(!strncasecmp(cmd, "volte", 5)){
+                VOLTE_STATE state;
+                err = ql_nw_get_volte_state(&state);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("VOLTE state : %d\n", state.reg_state);
+                }
+            } else if(!strncasecmp(cmd, "csq_signal", 10)){
+                QL_NW_CSQ_SIGNAL_STRENGTH_INFO_T signal;
+                err = ql_nw_csq_get_signal_strength(&signal);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("+CSQ : %d, %d\n", signal.rssi, signal.bitErrorRate);
+                }
+            }
+            else if(!strcasecmp(cmd, "h") || !strcasecmp(cmd, "help")) {
+                help();
+            } else if(!strcasecmp(cmd, "q")) {
+                break;
+            } else {
+                printf("\n");
+            }
+        }
+    }
+
+    proc_exit();
+
+    LOGI("Client exec complete.");
+#if 1
+    while(1)
+    {
+        sleep(1000 * 365 * 24 * 60 * 60);
+    }
+#else
+    sleep(1);
+#endif
+    return 0;
+}
+
diff --git a/mbtk/test/libql_lib/ql_sim_test.c b/mbtk/test/libql_lib/ql_sim_test.c
new file mode 100755
index 0000000..f907ab3
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_sim_test.c
@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "ql/ql_sim.h"
+#include "mbtk_log.h"
+
+static void help()
+{
+    printf("imsi : Get IMSI.\n");
+    printf("iccid : Get ICCID.\n");
+    printf("pn : Get phone number.\n");
+    printf("pin_en <pin> : Enable pin.\n");
+    printf("pin_dis <pin> : Disable pin.\n");
+    printf("pin_ch <old_pin> <new_pin> : Change pin.\n");
+    printf("pin_verify <pin> : Verify pin.\n");
+    printf("puk_unlock <puk> <new_pin> : Unlock using PUK.\n");
+    printf("sim : Get sim state.\n");
+}
+
+static int proc_exit()
+{
+    QL_SIM_ERROR_CODE err = ql_sim_release();
+    if(QL_SIM_SUCCESS != err)
+    {
+        printf("ql_sim_release fail.");
+        return -1;
+    }
+    return 0;
+}
+
+static void sig_process(int sig)
+{
+    LOGI("I got signal %d\n", sig);
+    switch(sig)
+    {
+        case SIGINT: // Ctrl + C
+        {
+            LOGI("Exit by SIGINT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGQUIT: // Ctrl + \ (类似 SIGINT ,但要产生core文件)
+        {
+            LOGI("Exit by SIGQUIT.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTERM:// 默认kill   (同 SIGKILL ,但 SIGKILL 不可捕获)
+        {
+            LOGI("Exit by SIGTERM.\n");
+            proc_exit();
+            exit(0);
+        }
+        case SIGTSTP:// Ctrl + Z (同 SIGSTOP ,但 SIGSTOP 不可捕获)
+        {
+            LOGI("Exit by SIGTSTP.\n");
+            exit(0);
+        }
+        case SIGSEGV: // 如空指针
+        {
+            LOGI("Exit by SIGSEGV.\n");
+            exit(0);
+        }
+        default:
+        {
+            LOGI("Unknown sig:%d\n",sig);
+            break;
+        }
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    signal(SIGINT, sig_process);
+    signal(SIGQUIT, sig_process);
+    signal(SIGTERM, sig_process);
+    //signal(SIGTSTP, sig_process);
+    //signal(SIGSEGV, sig_process);
+
+    mbtk_log_init(NULL,"MBTK_QL_TEST");
+
+    //test2(0, "192.168.1.198");
+    //test2(1, "2409:8162:140:cd3c:1:2:1494:72ba");
+    //test2(1, "254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239");
+    //test2(1, "2400:3200::1");
+
+    QL_SIM_ERROR_CODE err = ql_sim_init();
+    if(QL_SIM_SUCCESS != err)
+    {
+        printf("ql_sim_init fail.");
+        return -1;
+    }
+
+    printf(">>>>>>>>>>>>>>>>>>>>>>>>Enter cmd:\n");
+    char cmd[100];
+    while(1)
+    {
+        memset(cmd, 0, 100);
+        if(fgets(cmd, 100, stdin))
+        {
+            char *ptr = cmd + strlen(cmd) - 1;
+            while(ptr >= cmd && (*ptr == '\r' || *ptr == '\n'))
+            {
+                *ptr-- = '\0';
+            }
+
+            if(!strncasecmp(cmd, "imsi", 4)){
+                char imsi[30];
+                err = ql_sim_get_imsi(imsi, 30);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("IMSI : %s\n", imsi);
+                }
+            }else if(!strncasecmp(cmd, "iccid", 5)){
+                char iccid[30];
+                err = ql_sim_get_iccid(iccid, 30);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("ICCID : %s\n", iccid);
+                }
+            }else if(!strncasecmp(cmd, "pn", 2)){
+                char phonenumber[30];
+                err = ql_sim_get_phonenumber(phonenumber, 30);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("PhoneNumber : %s\n", phonenumber);
+                }
+            }else if(!strncasecmp(cmd, "pin_en", 6)){ // pin_en <pin>
+                QL_SIM_VERIFY_PIN_INFO pin = {0};
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                memcpy(pin.pin_value, ptr, strlen(ptr));
+
+                err = ql_sim_enable_pin(&pin);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Enable PIN(%s) success.\n", pin.pin_value);
+                }
+            }else if(!strncasecmp(cmd, "pin_dis", 7)){ // pin_dis <pin>
+                QL_SIM_VERIFY_PIN_INFO pin = {0};
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                memcpy(pin.pin_value, ptr, strlen(ptr));
+
+                err = ql_sim_disable_pin(&pin);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Disable PIN(%s) success.\n", pin.pin_value);
+                }
+            }else if(!strncasecmp(cmd, "pin_ch", 6)){ // pin_ch <old_pin> <new_pin>
+                QL_SIM_CHANGE_PIN_INFO pin = {0};
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+
+                char *tmp = pin.old_pin_value;
+                while(*ptr != '\0' && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
+                    *tmp++ = *ptr++;
+                }
+                *tmp = '\0';
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+
+                tmp = pin.new_pin_value;
+                while(*ptr != '\0' && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
+                    *tmp++ = *ptr++;
+                }
+                *tmp = '\0';
+
+                err = ql_sim_change_pin(&pin);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Change PIN(%s -> %s) success.\n", pin.old_pin_value, pin.new_pin_value);
+                }
+            }else if(!strncasecmp(cmd, "pin_verify", 10)){ // pin_verify <pin>
+                QL_SIM_VERIFY_PIN_INFO pin = {0};
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+                memcpy(pin.pin_value, ptr, strlen(ptr));
+
+                err = ql_sim_verify_pin(&pin);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Verify PIN(%s) success.\n", pin.pin_value);
+                }
+            }else if(!strncasecmp(cmd, "puk_unlock", 10)){ // puk_unlock <puk> <new_pin>
+                QL_SIM_UNBLOCK_PIN_INFO pin = {0};
+                char *ptr = strstr(cmd, " ");
+                if(ptr == NULL)
+                    continue;
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+
+                char *tmp = pin.puk_value;
+                while(*ptr != '\0' && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
+                    *tmp++ = *ptr++;
+                }
+                *tmp = '\0';
+                while(*ptr != '\0' && *ptr == ' ')
+                    ptr++;
+
+                tmp = pin.new_pin_value;
+                while(*ptr != '\0' && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
+                    *tmp++ = *ptr++;
+                }
+                *tmp = '\0';
+
+                err = ql_sim_unblock_pin(&pin);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("PUI unlock(PUK:%s   PIN:%s) success.\n", pin.puk_value, pin.new_pin_value);
+                }
+            }else if(!strncasecmp(cmd, "sim", 3)){
+                QL_SIM_CARD_STATUS_INFO sim;
+                err = ql_sim_get_card_status(&sim);
+                if(err) {
+                    printf("Error : %d\n", err);
+                } else {
+                    printf("Sim type:%d, state:%d, PIN:%d,%d,%d,%d\n", sim.card_type, sim.card_state, sim.card_pin_info.pin1_num_retries, sim.card_pin_info.pin2_num_retries, sim.card_pin_info.puk1_num_retries, sim.card_pin_info.puk2_num_retries);
+                }
+            }
+            else if(!strcasecmp(cmd, "h") || !strcasecmp(cmd, "help")) {
+                help();
+            } else if(!strcasecmp(cmd, "q")) {
+                break;
+            } else {
+                printf("\n");
+            }
+        }
+    }
+
+    proc_exit();
+
+    LOGI("Client exec complete.");
+#if 1
+    while(1)
+    {
+        sleep(1000 * 365 * 24 * 60 * 60);
+    }
+#else
+    sleep(1);
+#endif
+    return 0;
+}
+
diff --git a/mbtk/test/libql_lib/ql_sms_test.c b/mbtk/test/libql_lib/ql_sms_test.c
new file mode 100755
index 0000000..2d07d80
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_sms_test.c
@@ -0,0 +1,120 @@
+/**

+ *   \file dtmf_test.c

+ *   \brief A Documented file.

+ *

+ *  Detailed description

+ *   \Author:  jinLuo

+ *   \Version: 1.0.0

+ *   \Date: 2022-12-1

+ */

+

+/******************************************************************************\

+ *   Include files

+\******************************************************************************/

+#include <pthread.h>

+#include <time.h>

+#include <sys/ioctl.h>

+#include <fcntl.h>

+#include <unistd.h>

+#include <sys/types.h>

+#include <sys/stat.h>

+#include <fcntl.h>

+#include <string.h>

+#include <stdio.h>

+#include <signal.h>

+#include <unistd.h>

+#include <fcntl.h>

+#include <errno.h>

+#include <string.h>

+#include <stdlib.h>

+#include <poll.h>

+#include <stdlib.h>

+

+#include <sys/ioctl.h>

+#include <sys/types.h>

+#include <sys/stat.h>

+#include "ql/ql_sms.h"

+

+

+int main(int argc, char *argv[])

+{

+    char operator[10];

+    char serNum[50] = {0};

+    char phonenumter[20] ={0};

+    int opt;

+    int ret, uToken; 

+

+    while(1)

+    {

+        printf("=========audio main=========\n"

+            "\t0 exit\n"

+            "\t1 sms init\n"

+            "\t2 send sms\n"

+            "\t3 wait receive new sms\n"

+            "\t4 delete sms(int index);\n"

+            "\t5 list sms\n"

+            "\t6 query sms storage status\n"

+            "\t7 query service number\n"

+            "\t8 set service number\n"

+            "\t9 deinit sms\n"

+            "operator: >> ");

+        fgets(operator, sizeof(operator), stdin);

+        fflush(stdin);

+        opt = atoi(operator);

+        switch (opt)

+        {

+        case 0:

+            printf("main exit\n");

+            return 0;

+        case 1:

+            ql_sms_init();

+            break;

+        case 2:

+            ql_sms_send_text_msg("+8615775690697", "hello world", 1);

+            break;

+        case 3:

+            ql_sms_add_event_handler(NULL, NULL);

+            break;

+		case 4:

+            ql_sms_send_pdu_msg("+8615775690697","你好",1);

+            break;

+       //     printf("please input volume (0~100): \n");

+       //     fgets(operator, sizeof(operator), stdin);

+       //     fflush(stdin);

+       //     opt = atoi(operator);

+		//	lynq_delete_sms(opt);

+            break;

+		case 5:

+			printf("please input index (0~50): \n");

+            fgets(operator, sizeof(operator), stdin);

+            fflush(stdin);

+            opt = atoi(operator);

+       //     lynq_list_sms(1, opt, "ALL" );

+			break;

+		case 6:

+        //    lynq_query_sms_storage_status();

+			break;

+        case 7:

+            ret = ql_sms_get_sms_center_address(serNum);

+            if(!ret)

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

+            break;

+        case 8:

+        //    printf("please input service num: \n");

+        //    fgets(phonenumter, sizeof(phonenumter), stdin);

+        //    fflush(stdin);

+        //    memcpy(phonenumter, "+8613800280500", "+8613800280500");

+            

+        //    ret= ql_sms_set_sms_center_address(phonenumter);

+            ret= ql_sms_set_sms_center_address("+8613800280500");

+            break;

+        case 9:

+            ql_sms_release();

+            break;

+        default:

+            break;

+        }

+    }

+

+    return 0;

+}

diff --git a/mbtk/test/libql_lib/ql_spi_test.c b/mbtk/test/libql_lib/ql_spi_test.c
new file mode 100755
index 0000000..dff5208
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_spi_test.c
@@ -0,0 +1,92 @@
+#include "ql/ql_spi.h"
+
+
+int main(int argc, char *argv[])
+{
+    char send_data[64] = {0};
+	char read_data[64] = {0};
+	char crc = 0;
+	int i = 0;
+	int j = 0;
+
+    //system("echo PB6 > /sys/kernel/debug/sunxi_pinctrl/sunxi_pin");
+    //system("echo PB6 1 > /sys/kernel/debug/sunxi_pinctrl/function");
+    //system("echo PB6 0 > /sys/kernel/debug/sunxi_pinctrl/data");
+
+#if 0
+static const char *device = "/dev/spidev1.0\0";
+static uint8_t mode = 3; /* SPI通信使用全双工,设置CPOL=0,CPHA=0。 */
+static uint8_t bits = 8; /* 8bits读写,MSB first。*/
+static uint32_t speed = 100 * 1000;/* 设置0.5M传输速度 */
+static uint16_t delay = 500;
+#endif
+    int fd = -1;
+	/* spi 初始化程序 */
+	if((fd = Ql_SPI_Init("/dev/spidev1.0", SPIMODE3, 8, S_13M)) <= 0)
+	{
+        printf("Ql_SPI_Init() fail.\n");
+        return -1;
+	}
+
+	send_data[0] = 0x55;
+	send_data[1] = 0x00;
+	send_data[2] = 0x84;
+	send_data[3] = 0x00;
+	send_data[4] = 0x08;
+	send_data[5] = 0x00;
+	send_data[6] = 0x00;
+
+	crc = send_data[1];
+	for (i = 2; i < 7; i++)
+	{
+		crc ^= send_data[i];
+	}
+	crc = ~crc;
+
+	send_data[7] = crc;
+
+	printf("send data:");
+	for (i = 0; i < 8; i++)
+	{
+		printf("%#x, ", send_data[i]);
+	}
+	printf("\n");
+
+	/* spi 发送数据 */
+	if(Ql_SPI_Write_Read(fd, send_data,read_data, 8)) {
+        printf("Ql_SPI_Write_Read() fail.\n");
+        return -1;
+	}
+
+#if 0
+	printf("read data:");
+	for (j = 0; j < 20; j++)
+	{
+		printf("%#x, ", read_data[j]);
+	}
+
+	usleep(10000);
+
+	memset(read_data, 0, sizeof(read_data));
+	memset(send_data, 0, sizeof(send_data));
+	/* spi 读取数据 */
+	if(Ql_SPI_Write_Read(fd, send_data,read_data, 16)) {
+        printf("Ql_SPI_Write_Read() fail.\n");
+        return -1;
+	}
+
+	printf("read data:");
+	for (j = 0; j < 20; j++)
+	{
+		printf("%#x, ", read_data[j]);
+	}
+#endif
+
+    if(Ql_SPI_DeInit(fd)) {
+        printf("Ql_SPI_DeInit() fail.\n");
+        return -1;
+    }
+
+    printf("success!!!\n");
+    return 0;
+}
diff --git a/mbtk/test/libql_lib/ql_uart_test.c b/mbtk/test/libql_lib/ql_uart_test.c
new file mode 100755
index 0000000..2bef6ac
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_uart_test.c
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "ql/ql_uart.h"
+
+int fd;
+pthread_mutex_t mutexsum;	//创建mutex锁
+
+typedef struct {
+    char *node;
+    char *rate;
+} thread_arg;
+
+void *read_function(void *arg) {
+    thread_arg *args = (thread_arg *)arg;
+    printf("read_function() node = %s rate = %s\n", args->node, args->rate);
+
+    ST_UARTDCB dcb;
+    memset(&dcb, 0x0, sizeof(ST_UARTDCB));
+    dcb.databit = DB_CS8;
+    dcb.parity = PB_NONE;
+    dcb.flowctrl = FC_NONE;
+
+    if(Ql_UART_SetDCB(fd, &dcb)) {
+        printf("Ql_UART_SetDCB() fail.\n");
+        return -1;
+    }
+
+    char buff[1024];
+    int len;
+    while(1) {
+        // pthread_mutex_lock(&mutexsum);
+        memset(buff, 0x0 ,1024);
+        len = Ql_UART_Read(fd, buff, 1024);
+        if(len > 0) {
+            if(memcmp(buff, "exit", 4) == 0) {
+                Ql_UART_Write(fd, "exit\r\n", 6);
+                break;
+            } else {
+                printf("<%s\n", buff);
+
+                Ql_UART_Write(fd, "Module received data!\r\n", 23);
+            }
+        }
+        // pthread_mutex_unlock(&mutexsum);
+    }
+    Ql_UART_Close(fd);
+    return NULL;
+}
+
+void *write_function(void *arg) {
+    char str[20] = "write success!\r\n";
+    while (1)
+    {
+        sleep(3);
+        // pthread_mutex_lock(&mutexsum);
+        Ql_UART_Write(fd, str, strlen(str));
+        // pthread_mutex_unlock(&mutexsum);
+    }
+    Ql_UART_Close(fd);
+    return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+    printf("main() start \n");
+    mbtk_log_init("radio", "MBTK_UART");
+    if(argc != 3) {
+        printf("./uart_test <dev> <baudrate>\n");
+        return -1;
+    }
+
+    printf("main() start  node = %s rate = %s\n", argv[1], argv[2]);
+    fd = Ql_UART_Open(argv[1], (Enum_BaudRate)atoi(argv[2]), FC_NONE);
+    if(fd < 0) {
+        printf("Ql_UART_Open() fail.\n");
+        return -1;
+    }
+
+    // pthread_mutex_init(&mutexsum, NULL);
+    pthread_t read_thread, write_thread;
+
+    thread_arg args = {argv[1], argv[2]};
+    printf("start read_thread node = %s rate = %s\n", args.node, args.rate);
+    pthread_create(&read_thread, NULL, read_function, &args);
+
+    printf("start write_thread \n");
+    pthread_create(&write_thread, NULL, write_function, NULL);
+
+    pthread_join(read_thread, NULL);
+    pthread_join(write_thread, NULL);
+
+    printf("main() end \n");
+    return 0;
+}
\ No newline at end of file
diff --git a/mbtk/test/libql_lib/ql_voice_test.c b/mbtk/test/libql_lib/ql_voice_test.c
new file mode 100755
index 0000000..43af279
--- /dev/null
+++ b/mbtk/test/libql_lib/ql_voice_test.c
@@ -0,0 +1,91 @@
+#include "mbtk_type.h"
+//#include "ql/ql_vcall.h"
+//#include "ql/ql_mcm_call.h"
+#include "ql/ql_voice.h"
+
+
+
+
+int main(int argc, char *argv[])
+{
+    char operator[10] = {0};
+    int opt;
+    int    ret     = 0;
+    char   phoneNum[32] = {0};
+    int    h_voice     = 0;
+
+    while(1)
+    {
+        printf("=========call main=========\n"
+            "\t0 exit\n"
+            "\t1 call init\n"
+            "\t2 call register handle\n"
+            "\t3 call start\n"
+            "\t4 call end\n"
+            "\t5 call answer\n"
+            "\t6 call set auto answer\n"
+            "\t7 call hold\n"
+            "\t8 call unhold\n"
+            "\t9 call deinit\n"
+            "operator: >> ");
+
+        fgets(operator, sizeof(operator), stdin);
+        fflush(stdin);
+        opt = atoi(operator);
+        switch (opt)
+        {
+        case 0:
+            printf("main exit\n");
+            return 0;
+        case 1:
+            ret = ql_voice_call_init();
+            if(ret < 0)
+            {
+                printf("ql_voice_call_init FAIL.	ret:%d\n",ret);
+                return -1;
+            }
+            printf("ql_voice_call_init ret = %d, with h_voice=%d\n", ret, h_voice);
+
+            break;
+        case 2:
+            ret = ql_voice_call_event_register(NULL, NULL);
+            if(ret < 0)
+            {
+                printf("ql_voice_call_event_register FAIL.		ret:%d\n",ret);
+                return -1;
+            }
+            break;
+        case 3:
+            ql_voice_call_start("15775690697");
+            break;
+        case 4:
+            ql_voice_call_end();
+            break;
+        case 5:
+            ql_voice_call_answer();
+            break;
+        case 6:
+            ql_voice_auto_answer(6000);
+            break;
+        case 7:
+            ql_voice_call_hold();
+            break;
+        case 8:
+            ql_voice_call_unhold();
+            break;
+        case 9:
+            ql_voice_call_release();
+            break;
+        case 10:
+            // QL_Voice_Call_UnHold;
+            break;
+        default:
+            break;
+        }
+
+        sleep(1);
+    }
+
+    return 0;
+}
+