Add basic change for v1453

Change-Id: I9497a61bbc3717f66413794a4e7dee0347c0bc33
diff --git a/mbtk/test/libql_lib_v2/ql_sim_test.c b/mbtk/test/libql_lib_v2/ql_sim_test.c
new file mode 100755
index 0000000..f71d93e
--- /dev/null
+++ b/mbtk/test/libql_lib_v2/ql_sim_test.c
@@ -0,0 +1,1886 @@
+/*-----------------------------------------------------------------------------------------------*/
+/**
+  @file ql_sim_test.h 
+  @brief SIM service API 
+*/
+/*-----------------------------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------------------------------
+  Copyright (c) 2024 mobiletek Wireless Solution, Co., Ltd. All Rights Reserved.
+  mobiletek Wireless Solution Proprietary and Confidential.
+-------------------------------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------------------------------
+  EDIT HISTORY
+  This section contains comments describing changes made to the file.
+  Notice that changes are listed in reverse chronological order.
+  $Header: $
+  when       who          what, where, why
+  --------   ---------    -----------------------------------------------------------------
+  20241022    yq.wang      Created .
+-------------------------------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "ql_type.h"
+#include "ql_sim.h"
+#include "ql_test_utils.h"
+
+
+static void item_ql_sim_init(void)
+{
+    int ret = 0;
+    
+    printf("test ql_sim_init: ");
+    ret = ql_sim_init();
+    if(ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_deinit(void)
+{
+    int ret = 0;
+
+    printf("test ql_sim_deinit: ");
+    ret = ql_sim_deinit();
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_get_imsi(void)
+{
+    int ret = 0;
+    char imsi[QL_SIM_IMSI_LENGTH+1] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+
+    printf("test ql_sim_get_imsi: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+    
+    ret = ql_sim_get_imsi(slot, app_type, imsi, sizeof(imsi));
+    if (ret == QL_ERR_OK)
+    {
+        printf("IMSI: %s\n", imsi);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_get_iccid(void)
+{
+    int ret = 0;
+    char iccid[QL_SIM_ICCID_LENGTH+1] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+
+    printf("test ql_sim_get_iccid: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+    
+    ret = ql_sim_get_iccid(slot, iccid, sizeof(iccid));
+    if (ret == QL_ERR_OK)
+    {
+        printf("ICCID: %s\n", iccid);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_get_phone_num(void)
+{
+    int ret = 0;
+    char num[QL_SIM_PHONE_NUMBER_MAX+1] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+
+    printf("test ql_sim_get_phone_num: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+    
+    ret = ql_sim_get_phone_num(slot, app_type, num, sizeof(num));
+    if (ret == QL_ERR_OK)
+    {
+        printf("Phone number: %s\n", num);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void print_ascii(char *prefix, char *postfix, char *ascii, int len)
+{
+    int i = 0;
+    printf("%s", prefix);
+    for (i = 0; i < len; i++)
+    {
+        putchar(ascii[i]);
+    }
+    printf("%s",  postfix);
+}
+
+static void item_ql_sim_get_operators(void)
+{
+    int ret = 0;
+    ql_sim_operator_list_t list = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+
+    printf("test ql_sim_get_operators: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+    
+    ret = ql_sim_get_operators(slot, &list);
+    if (ret == QL_ERR_OK)
+    {
+        if (0 == list.len)
+        {
+            printf("No operators found\n");
+        }
+        else
+        {
+            int i = 0;
+            printf("found %d opertators:\n", list.len);
+            for (i = 0; i < list.len; i++)
+            {
+                printf(" #%02d: ", i + 1);
+                print_ascii("MCC: ", "", list.operators[i].mcc, (int)sizeof(list.operators[i].mcc));
+                print_ascii(", MNC: ", "\n",list.operators[i].mnc, list.operators[i].mnc_len);
+            }
+        }
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_enable_pin(void)
+{
+    int ret = 0;
+    int len = 0;
+    char c;
+    char pin_value[QL_SIM_PIN_MAX*2] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    QL_SIM_PIN_E pin;
+
+    printf("test ql_sim_enable_pin: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter pin(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        pin = QL_SIM_PIN_1;
+    }
+    else if (2 == input)
+    {
+        pin = QL_SIM_PIN_2;
+    }
+    else
+    {
+        printf("bad pin: %d\n", input);
+        return;
+    }
+
+    printf("please enter pin value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(pin_value, sizeof(pin_value), stdin))
+    {
+        printf("can not read pin value\n");
+        return;
+    }
+    len = strlen(pin_value);
+    if ('\n' == pin_value[len-1])
+    {
+        pin_value[len-1] = 0;
+        len--;
+    }
+    printf("pin value: %s\n", pin_value);
+    
+    printf("proceed? [y/n]: ");
+    c = getchar();
+    if ('\n' != c)
+    {
+        getchar();
+    }
+    if ('Y' != c && 'y' != c)
+    {
+        printf("abort\n");
+        return;
+    }
+    
+    ret = ql_sim_enable_pin(slot, app_type, pin, pin_value);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_disable_pin(void)
+{
+    int ret = 0;
+    int len = 0;
+    char c;
+    char pin_value[QL_SIM_PIN_MAX*2] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    QL_SIM_PIN_E pin;
+
+    printf("test ql_sim_disable_pin: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter pin(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        pin = QL_SIM_PIN_1;
+    }
+    else if (2 == input)
+    {
+        pin = QL_SIM_PIN_2;
+    }
+    else
+    {
+        printf("bad pin: %d\n", input);
+        return;
+    }
+
+    printf("please enter pin value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(pin_value, sizeof(pin_value), stdin))
+    {
+        printf("can not read pin value\n");
+        return;
+    }
+    len = strlen(pin_value);
+    if ('\n' == pin_value[len-1])
+    {
+        pin_value[len-1] = 0;
+        len--;
+    }
+    printf("pin value: %s\n", pin_value);
+    
+    printf("proceed? [y/n]: ");
+    c = getchar();
+    if ('\n' != c)
+    {
+        getchar();
+    }
+    if ('Y' != c && 'y' != c)
+    {
+        printf("abort\n");
+        return;
+    }
+    
+    ret = ql_sim_disable_pin(slot, app_type, pin, pin_value);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_verify_pin(void)
+{
+    int ret = 0;
+    int len = 0;
+    char c;
+    char pin_value[QL_SIM_PIN_MAX*2] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    QL_SIM_PIN_E pin;
+
+    printf("test ql_sim_verify_pin: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter pin(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        pin = QL_SIM_PIN_1;
+    }
+    else if (2 == input)
+    {
+        pin = QL_SIM_PIN_2;
+    }
+    else
+    {
+        printf("bad pin: %d\n", input);
+        return;
+    }
+
+    printf("please enter pin value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(pin_value, sizeof(pin_value), stdin))
+    {
+        printf("can not read pin value\n");
+        return;
+    }
+    len = strlen(pin_value);
+    if ('\n' == pin_value[len-1])
+    {
+        pin_value[len-1] = 0;
+        len--;
+    }
+    printf("pin value: %s\n", pin_value);
+    
+    printf("proceed? [y/n]: ");
+    c = getchar();
+    if ('\n' != c)
+    {
+        getchar();
+    }
+    if ('Y' != c && 'y' != c)
+    {
+        printf("abort\n");
+        return;
+    }
+    
+    ret = ql_sim_verify_pin(slot, app_type, pin, pin_value);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_change_pin(void)
+{
+    int ret = 0;
+    int old_len = 0;
+    int new_len = 0;
+    char c;
+    char old_pin_value[QL_SIM_PIN_MAX*2] = {0};
+    char new_pin_value[QL_SIM_PIN_MAX*2] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    QL_SIM_PIN_E pin;
+
+    printf("test ql_sim_change_pin: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter pin(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        pin = QL_SIM_PIN_1;
+    }
+    else if (2 == input)
+    {
+        pin = QL_SIM_PIN_2;
+    }
+    else
+    {
+        printf("bad pin: %d\n", input);
+        return;
+    }
+
+    printf("please enter old pin value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(old_pin_value, sizeof(old_pin_value), stdin))
+    {
+        printf("can not read old pin value\n");
+        return;
+    }
+    old_len = strlen(old_pin_value);
+    if ('\n' == old_pin_value[old_len-1])
+    {
+        old_pin_value[old_len-1] = 0;
+        old_len--;
+    }
+
+    printf("please enter new pin value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(new_pin_value, sizeof(new_pin_value), stdin))
+    {
+        printf("can not read new pin value\n");
+        return;
+    }
+    new_len = strlen(new_pin_value);
+    if ('\n' == new_pin_value[new_len-1])
+    {
+        new_pin_value[new_len-1] = 0;
+        new_len--;
+    }
+    printf("old pin value: %s\n", old_pin_value);
+    printf("new pin value: %s\n", new_pin_value);
+    
+    printf("proceed? [y/n]: ");
+    c = getchar();
+    if ('\n' != c)
+    {
+        getchar();
+    }
+    if ('Y' != c && 'y' != c)
+    {
+        printf("abort\n");
+        return;
+    }
+    
+    ret = ql_sim_change_pin(slot, app_type, pin, old_pin_value, new_pin_value);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_unblock_pin(void)
+{
+    int ret = 0;
+    int len = 0;
+    int new_len = 0;
+    char c;
+    char puk_value[QL_SIM_PIN_MAX*2] = {0};
+    char new_pin_value[QL_SIM_PIN_MAX*2] = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    QL_SIM_PIN_E pin;
+
+    printf("test ql_sim_unblock_pin: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter pin(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        pin = QL_SIM_PIN_1;
+    }
+    else if (2 == input)
+    {
+        pin = QL_SIM_PIN_2;
+    }
+    else
+    {
+        printf("bad pin: %d\n", input);
+        return;
+    }
+
+    printf("please enter puk value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(puk_value, sizeof(puk_value), stdin))
+    {
+        printf("can not read old pin value\n");
+        return;
+    }
+    len = strlen(puk_value);
+    if ('\n' == puk_value[len-1])
+    {
+        puk_value[len-1] = 0;
+        len--;
+    }
+
+    printf("please enter new pin value(at most %d digit): ", QL_SIM_PIN_MAX);
+    if (NULL == fgets(new_pin_value, sizeof(new_pin_value), stdin))
+    {
+        printf("can not read new pin value\n");
+        return;
+    }
+    new_len = strlen(new_pin_value);
+    if ('\n' == new_pin_value[new_len-1])
+    {
+        new_pin_value[new_len-1] = 0;
+        new_len--;
+    }
+    printf("    puk value: %s\n", puk_value);
+    printf("new pin value: %s\n", new_pin_value);
+    
+    printf("proceed? [y/n]: ");
+    c = getchar();
+    if ('\n' != c)
+    {
+        getchar();
+    }
+    if ('Y' != c && 'y' != c)
+    {
+        printf("abort\n");
+        return;
+    }
+    
+    ret = ql_sim_unblock_pin(slot, app_type, pin, puk_value, new_pin_value);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static char *card_state_desc(QL_SIM_CARD_STATE_E state)
+{
+    switch (state)
+    {
+        case QL_SIM_CARD_STATE_UNKNOWN:
+            return "unknown";
+        case QL_SIM_CARD_STATE_ABSENT:
+            return "absent";
+        case QL_SIM_CARD_STATE_PRESENT:
+            return "present";
+        case QL_SIM_CARD_STATE_ERROR_UNKNOWN:
+            return "unknown error";
+        case QL_SIM_CARD_STATE_ERROR_POWER_DOWN:
+            return "power down";
+        case QL_SIM_CARD_STATE_ERROR_POLL_ERROR:
+            return "poll error";
+        case QL_SIM_CARD_STATE_ERROR_NO_ATR_RECEIVED:
+            return "failed to receive an answer to reset";
+        case QL_SIM_CARD_STATE_ERROR_VOLT_MISMATCH:
+            return "voltage mismatch";
+        case QL_SIM_CARD_STATE_ERROR_PARITY_ERROR:
+            return "parity error";
+        case QL_SIM_CARD_STATE_ERROR_SIM_TECHNICAL_PROBLEMS:
+            return "technical problems";
+        default:
+            return "N/A";
+    }
+}
+
+static char *card_type_desc(QL_SIM_CARD_TYPE_E type)
+{
+    switch (type)
+    {
+        case QL_SIM_CARD_TYPE_UNKNOWN:
+            return "unknown";
+        case QL_SIM_CARD_TYPE_ICC:
+            return "ICC";
+        case QL_SIM_CARD_TYPE_UICC:
+            return "UICC";
+        default: 
+            return "N/A";
+    }
+}
+
+static char *card_subscription_desc(QL_SIM_SUBSCRIPTION_E subscription)
+{
+    switch (subscription)
+    {
+        case QL_SIM_SUBSCRIPTION_NONE:
+            return "nonprovisioning";
+        case QL_SIM_SUBSCRIPTION_PRI:
+            return "primary provisioning subscription";
+        case QL_SIM_SUBSCRIPTION_SEC:
+            return "secondary provisioning subscription";
+        default:
+            return "N/A";
+    }
+}
+
+static char *card_app_state_desc(QL_SIM_APP_STATE_E state)
+{
+    switch (state)
+    {
+        case QL_SIM_APP_STATE_UNKNOWN:
+            return "unknown";
+        case QL_SIM_APP_STATE_DETECTED:
+            return "detected";
+        case QL_SIM_APP_STATE_PIN1_REQ:
+            return "PIN1 required";
+        case QL_SIM_APP_STATE_PUK1_REQ:
+            return "PUK1 required";
+        case QL_SIM_APP_STATE_INITALIZATING:
+            return "initializing";
+        case QL_SIM_APP_STATE_PERSO_CK_REQ:
+            return "personalization control key required";
+        case QL_SIM_APP_STATE_PERSO_PUK_REQ:
+            return "personalization unblock key required";
+        case QL_SIM_APP_STATE_PERSO_PERMANENTLY_BLOCKED:
+            return "personalization is permanently blocked";
+        case QL_SIM_APP_STATE_PIN1_PERM_BLOCKED:
+            return "PIN1 is permanently blocked";
+        case QL_SIM_APP_STATE_ILLEGAL:
+            return "illegal";
+        case QL_SIM_APP_STATE_READY:
+            return "ready";
+        default:
+            return "N/A";
+    }
+}
+
+static char *card_perso_feature_desc(QL_SIM_PERSO_FEATURE_E feature)
+{
+    switch (feature)
+    {
+        case QL_SIM_PERSO_FEATURE_UNKNOWN:
+            return "unknown";
+        case QL_SIM_PERSO_FEATURE_3GPP_NETWORK:
+            return "featurization based on 3GPP MCC and MNC";
+        case QL_SIM_PERSO_FEATURE_3GPP_NETWORK_SUBSET:
+            return "featurization based on 3GPP MCC, MNC, and IMSI digits 6 and 7";
+        case QL_SIM_PERSO_FEATURE_3GPP_SERVICE_PROVIDER:
+            return "featurization based on 3GPP MCC, MNC, and GID1";
+        case QL_SIM_PERSO_FEATURE_3GPP_CORPORATE:
+            return "featurization based on 3GPP MCC, MNC, GID1, and GID2";
+        case QL_SIM_PERSO_FEATURE_3GPP_SIM:
+            return "featurization based on the 3GPP IMSI";
+        case QL_SIM_PERSO_FEATURE_3GPP2_NETWORK_TYPE_1:
+            return "featurization based on 3GPP2 MCC and MNC";
+        case QL_SIM_PERSO_FEATURE_3GPP2_NETWORK_TYPE_2:
+            return "featurization based on 3GPP2 IRM code";
+        case QL_SIM_PERSO_FEATURE_3GPP2_RUIM:
+            return "featurization based on 3GPP2 IMSI_M";
+        default:
+            return "N/A";
+    }
+}
+
+static char *card_pin_state_desc(QL_SIM_PIN_STATE_E state)
+{
+    switch (state)
+    {
+        case QL_SIM_PIN_STATE_UNKNOWN:
+            return "unknown";
+        case QL_SIM_PIN_STATE_ENABLED_NOT_VERIFIED:
+            return "PIN required, but has not been verified";
+        case QL_SIM_PIN_STATE_ENABLED_VERIFIED:
+            return "PIN required and has been verified";
+        case QL_SIM_PIN_STATE_DISABLED:
+            return "PIN not required";
+        case QL_SIM_PIN_STATE_BLOCKED:
+            return "PIN verification has failed too many times and is blocked. "
+                   "Recoverable through PUK verification";
+        case QL_SIM_PIN_STATE_PERMANENTLY_BLOCKED:
+            return "PUK verification has failed too many times and is not recoverable";
+        default:
+            return "N/A";
+    }
+}
+
+
+static void item_ql_sim_get_card_info(void)
+{
+    int ret = 0;
+    ql_sim_card_info_t info = {0};
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+
+    printf("test ql_sim_get_card_info: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+    
+    ret = ql_sim_get_card_info(slot, &info);
+    if (ret != QL_ERR_OK)
+    {
+        printf("failed, ret = %d\n", ret);
+        return;
+    }
+    printf("========= CARD INFO =========\n");
+    printf("state: %s\n", card_state_desc(info.state));
+    printf("type: %s\n", card_type_desc(info.type));
+    printf("3gpp:\n");
+    printf(" app state: %s\n", card_app_state_desc(info.app_3gpp.app_state));
+    printf(" PIN 1 retries: %hhu\n", info.app_3gpp.pin1_num_retries);
+    printf(" PUK 1 retries: %hhu\n", info.app_3gpp.puk1_num_retries);
+    printf(" PIN 2 retries: %hhu\n", info.app_3gpp.pin2_num_retries);
+    printf(" PUK 2 retries: %hhu\n", info.app_3gpp.puk2_num_retries);
+    printf("3gpp2:\n");
+    printf(" app state: %s\n", card_app_state_desc(info.app_3gpp2.app_state));
+    printf(" PIN 1 retries: %hhu\n", info.app_3gpp2.pin1_num_retries);
+    printf(" PUK 1 retries: %hhu\n", info.app_3gpp2.puk1_num_retries);
+    printf(" PIN 2 retries: %hhu\n", info.app_3gpp2.pin2_num_retries);
+    printf(" PUK 2 retries: %hhu\n", info.app_3gpp2.puk2_num_retries);
+    printf("isim:\n");
+    printf(" app state: %s\n", card_app_state_desc(info.app_isim.app_state));
+    printf(" PIN 1 retries: %hhu\n", info.app_isim.pin1_num_retries);
+    printf(" PUK 1 retries: %hhu\n", info.app_isim.puk1_num_retries);
+    printf(" PIN 2 retries: %hhu\n", info.app_isim.pin2_num_retries);
+    printf(" PUK 2 retries: %hhu\n", info.app_isim.puk2_num_retries);
+}
+
+#if 0
+static void item_ql_sim_read_file(void)
+{
+    int ret = 0;
+    int input = 0;
+    int len = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    ql_sim_file_t file = {0};
+
+    printf("test ql_sim_read_file: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter file path(at most %d hex[0·9A-F], e.g 3F002FE2): ", QL_SIM_PATH_MAX);
+    if (NULL == fgets(file.path, QL_SIM_PATH_MAX, stdin))
+    {
+        printf("can not read file path\n");
+        return;
+    }
+    len = strlen(file.path);
+    if ('\n' == file.path[len-1])
+    {
+        file.path[len-1] = 0;
+        len--;
+    }
+    file.path_len = (uint32_t)len;
+
+    printf("please enter record index(0 for transparent access): ");
+    scanf("%hhu", (uint8_t *)&file.record_idx);
+    getchar();
+    
+    ret = ql_sim_read_file(slot, app_type, &file);
+    if (ret == QL_ERR_OK)
+    {
+        printf("data length: %u\n", file.data_len);
+        uint32_t i = 0;
+        printf("data: ");
+        for (i = 0; i < file.data_len; i++)
+        {
+            printf("%02x ", file.data[i]);
+        }
+        printf("\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_write_file(void)
+{
+    int ret = 0;
+    int input = 0;
+    int len = 0;
+    uint8_t v;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    ql_sim_file_t file = {0};
+
+    printf("test ql_sim_write_file: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter file path(at most %d hex[0·9A-F], e.g 3F002FE2): ", QL_SIM_PATH_MAX);
+    if (NULL == fgets(file.path, QL_SIM_PATH_MAX, stdin))
+    {
+        printf("can not read file path\n");
+        return;
+    }
+    len = strlen(file.path);
+    if ('\n' == file.path[len-1])
+    {
+        file.path[len-1] = 0;
+        len--;
+    }
+    file.path_len = (uint32_t)len;
+
+    printf("please enter record index(0 for transparent access): ");
+    scanf("%hhu", (uint8_t *)&file.record_idx);
+    getchar();
+
+    printf("please enter data(hex, end with `q'): ");
+    while (1 == scanf("%hhx", &v))
+    {
+        file.data[file.data_len++] = v;
+    }
+    getchar();  // read `q'
+    getchar();  // read '\n'
+    
+    printf("please enter data offset: ");
+    scanf("%hu", &file.offset);
+    getchar();
+    
+    ret = ql_sim_write_file(slot, app_type, &file);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static char *file_type_desc(QL_SIM_FILE_TYPE_E type)
+{
+    switch (type)
+    {
+        case QL_SIM_FILE_TYPE_UNKNOWN:
+            return "unknown";
+        case QL_SIM_FILE_TYPE_TRANSPARENT:
+            return "transparent";
+        case QL_SIM_FILE_TYPE_CYCLIC:
+            return "cyclic";
+        case QL_SIM_FILE_TYPE_LINEAR_FIXED:
+            return "linear fixed";
+        default: 
+            return "N/A";
+    }
+}
+
+static void item_ql_sim_get_file_info(void)
+{
+    int ret = 0;
+    int input = 0;
+    int len = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    ql_sim_file_info_t info = {0};
+
+    printf("test ql_sim_get_file_info: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter file path(at most %d hex[0·9A-F], e.g 3F002FE2): ", QL_SIM_PATH_MAX);
+    if (NULL == fgets(info.path, QL_SIM_PATH_MAX, stdin))
+    {
+        printf("can not read file path\n");
+        return;
+    }
+    len = strlen(info.path);
+    if ('\n' == info.path[len-1])
+    {
+        info.path[len-1] = 0;
+        len--;
+    }
+    info.path_len = (uint32_t)len;
+    
+    ret = ql_sim_get_file_info(slot, app_type, &info);
+    if (ret == QL_ERR_OK)
+    {
+        printf("========= FILE INFO =========\n");
+        printf("path: %s\n", info.path);
+        printf("type: %s\n", file_type_desc(info.file_type));
+        printf("file size: %hu\n", info.file_size);
+        printf("record size: %hu\n", info.record_size);
+        printf("record count: %hu\n", info.record_count);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_read_phone_book(void)
+{
+    int ret = 0;
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    uint8_t record_idx = 0;
+    ql_sim_phone_book_record_t record;
+
+    memset(&record,0,sizeof(ql_sim_phone_book_record_t));
+    printf("test ql_sim_read_phone_book: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter record index: ");
+    scanf("%hhu", &record_idx);
+    getchar();
+    
+    
+    ret = ql_sim_read_phone_book(slot, app_type, QL_SIM_PB_DEFAULT_PATH, record_idx, &record);
+    if (ret == QL_ERR_OK)
+    {
+        printf("Name: %s\n", record.name);
+        printf("Number: %s\n", record.number);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_write_phone_book(void)
+{
+    int ret = 0;
+    int input = 0;
+    int len = 0;
+    QL_SIM_SLOT_E slot;
+    QL_SIM_APP_TYPE_E app_type;
+    uint8_t record_idx = 0;
+    ql_sim_phone_book_record_t record;
+
+    memset(&record,0,sizeof(ql_sim_phone_book_record_t));
+    printf("test ql_sim_write_phone_book: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter app type(0-unknown, 1-3gpp, 2-3gpp2, 3-isim): ");
+    scanf("%d", &input);
+    getchar();
+    switch (input)
+    {
+        case 0:
+            app_type = QL_SIM_APP_TYPE_UNKNOWN;
+            break;
+        case 1:
+            app_type = QL_SIM_APP_TYPE_3GPP;
+            break;
+        case 2:
+            app_type = QL_SIM_APP_TYPE_3GPP2;
+            break;
+        case 3:
+            app_type = QL_SIM_APP_TYPE_ISIM;
+            break;
+        default:
+            printf("bad app type: %d\n", input);
+            return;
+    }
+
+    printf("please enter record index: ");
+    scanf("%hhu", &record_idx);
+    getchar();
+
+    printf("please enter name(at most %d chars): ", QL_SIM_PHONE_BOOK_NAME_MAX - 1);
+    if (NULL == fgets(record.name, QL_SIM_PHONE_BOOK_NAME_MAX, stdin))
+    {
+        printf("\nname will be set to 0\n");
+    }
+    else
+    {
+        len = strlen(record.name);
+        if ('\n' == record.name[len-1])
+        {
+            record.name[len-1] = 0;
+        }
+    }
+    
+
+    printf("please enter number(at most %d digits): ", QL_SIM_PHONE_BOOK_NUMBER_MAX - 1);
+    if (NULL == fgets(record.number, QL_SIM_PHONE_BOOK_NUMBER_MAX, stdin))
+    {
+        printf("\nnumber will be set to 0\n");
+    }
+    else
+    {
+        len = strlen(record.number);
+        if ('\n' == record.number[len-1])
+        {
+            record.number[len-1] = 0;
+        }
+    }
+    
+    ret = ql_sim_write_phone_book(slot, app_type, QL_SIM_PB_DEFAULT_PATH, record_idx, &record);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_open_logical_channel(void)
+{
+    int ret = 0;
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    uint8_t channel_id = 0;
+
+    printf("test ql_sim_open_logical_channel: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+    
+    ret = ql_sim_open_logical_channel(slot, &channel_id);
+    if (ret == QL_ERR_OK)
+    {
+        printf("channel id: %hhu\n", channel_id);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_close_logical_channel(void)
+{
+    int ret = 0;
+    int input = 0;
+    QL_SIM_SLOT_E slot;
+    uint8_t channel_id = 0;
+
+    printf("test ql_sim_close_logical_channel: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+
+    printf("please enter channel id: ");
+    scanf("%hhu", &channel_id);
+    getchar();
+    
+    ret = ql_sim_close_logical_channel(slot, channel_id);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+static void item_ql_sim_send_apdu(void)
+{
+    int ret = 0;
+    int input = 0;
+    uint8_t v = 0;
+    QL_SIM_SLOT_E slot;
+    ql_sim_apdu_t *p_apdu = NULL;
+    uint8_t channel_id = 0;
+
+    printf("test ql_sim_send_apdu: \n");
+
+    p_apdu = calloc(1, sizeof(*p_apdu));
+    if (NULL == p_apdu)
+    {
+        printf("run out of memory\n");
+        return;
+    }
+    
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        slot = QL_SIM_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        slot = QL_SIM_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        free(p_apdu);
+        p_apdu = NULL;
+        return;
+    }
+
+    printf("please enter channel id: ");
+    scanf("%hhu", &channel_id);
+    getchar();
+
+    printf("please enter apdu data(hex, end with `q'): ");
+    while (1 == scanf("%hhx", &v))
+    {
+        p_apdu->req_apdu[p_apdu->req_apdu_len++] = v;
+    }
+    getchar();  // read `q'
+    getchar();  // read '\n'
+    
+    ret = ql_sim_send_apdu(slot, channel_id, p_apdu);
+    if (ret == QL_ERR_OK)
+    {
+        uint32_t i = 0;
+        printf("repsonse apdu: ");
+        for (i = 0; i < p_apdu->resp_apdu_len; i++)
+        {
+            printf("%c", p_apdu->resp_apdu[i]);
+        }
+        printf("\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+    free(p_apdu);
+    p_apdu = NULL;
+}
+#endif
+
+static void sim_card_status_cb(int slot, ql_sim_card_info_t *p_info)
+{
+    printf("========= CARD STATUS =========\n");
+    switch (slot)
+    {
+        case 0:
+            printf("slot: invalid\n");
+            break;
+        case 1:
+            printf("slot: 1\n");
+            break;
+        case 2:
+            printf("slot: 2\n");
+            break;
+    }
+    
+    if (NULL == p_info)
+    {
+        printf("status: unavailable\n");
+        return;
+    }
+    
+    printf("state: %s\n", card_state_desc(p_info->state));
+    printf("type: %s\n", card_type_desc(p_info->type));
+    printf("3gpp:\n");
+    printf(" app state: %s\n", card_app_state_desc(p_info->app_3gpp.app_state));
+    printf(" PIN 1 retries: %hhu\n", p_info->app_3gpp.pin1_num_retries);
+    printf(" PUK 1 retries: %hhu\n", p_info->app_3gpp.puk1_num_retries);
+    printf(" PIN 2 retries: %hhu\n", p_info->app_3gpp.pin2_num_retries);
+    printf(" PUK 2 retries: %hhu\n", p_info->app_3gpp.puk2_num_retries);
+    printf("3gpp2:\n");
+    printf(" app state: %s\n", card_app_state_desc(p_info->app_3gpp2.app_state));
+    printf(" PIN 1 retries: %hhu\n", p_info->app_3gpp2.pin1_num_retries);
+    printf(" PUK 1 retries: %hhu\n", p_info->app_3gpp2.puk1_num_retries);
+    printf(" PIN 2 retries: %hhu\n", p_info->app_3gpp2.pin2_num_retries);
+    printf(" PUK 2 retries: %hhu\n", p_info->app_3gpp2.puk2_num_retries);
+    printf("isim:\n");
+    printf(" app state: %s\n", card_app_state_desc(p_info->app_isim.app_state));
+    printf(" PIN 1 retries: %hhu\n", p_info->app_isim.pin1_num_retries);
+    printf(" PUK 1 retries: %hhu\n", p_info->app_isim.puk1_num_retries);
+    printf(" PIN 2 retries: %hhu\n", p_info->app_isim.pin2_num_retries);
+    printf(" PUK 2 retries: %hhu\n", p_info->app_isim.puk2_num_retries);
+}
+
+static void item_ql_sim_set_card_status_cb(void)
+{
+    int ret = 0;
+
+    printf("test ql_sim_set_card_status_cb: ");
+    ret = ql_sim_set_card_status_cb((ql_sim_card_status_cb_f)sim_card_status_cb);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+void sim_servicie_error_cb(int error)
+{
+    printf("===== SIM Service Abort =====\n");
+}
+
+void item_ql_sim_set_service_error_cb(void)
+{
+    int ret = 0;
+    printf("test ql_sim_set_service_error_cb: \n");
+
+    ret = ql_sim_set_service_error_cb(sim_servicie_error_cb);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+#if 0
+void item_ql_sim_switch_slot(void)
+{
+    int ret = 0;
+    int input = 0;
+    QL_SIM_PHY_SLOT_E phy_slot = 0;
+    printf("test item_ql_sim_switch_slot: \n");
+    printf("please enter slot(1 or 2): ");
+    scanf("%d", &input);
+    getchar();
+    if (1 == input)
+    {
+        phy_slot = QL_SIM_PHY_SLOT_1;
+    }
+    else if (2 == input)
+    {
+        phy_slot = QL_SIM_PHY_SLOT_2;
+    }
+    else
+    {
+        printf("bad slot: %d\n", input);
+        return;
+    }
+    ret = ql_sim_switch_slot(QL_SIM_SLOT_1, phy_slot);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+}
+
+void item_ql_sim_get_active_slots(void)
+{
+    int ret = 0;
+    ql_sim_active_slots_t *p_active_slots = (ql_sim_active_slots_t *)malloc(sizeof(ql_sim_active_slots_t));
+    if (p_active_slots == NULL) {  
+        printf("Memory allocation failed.\n");  
+        return -1;  
+    }
+    p_active_slots->active_slots_len = 0;
+    p_active_slots->active_slots[0] = 0;
+    printf("test item_ql_sim_get_active_slots: \n");
+    ret = ql_sim_get_active_slots(p_active_slots);
+    if (ret == QL_ERR_OK)
+    {
+        printf("ok\n");
+	printf("p_active_slots(QL_SIM_PHY_SLOT_1/2 = B01/B02) = %X \n",p_active_slots->active_slots[0]);
+    }
+    else
+    {
+        printf("failed, ret = %d\n", ret);
+    }
+    free(p_active_slots);
+}
+#endif
+
+static t_item_t ql_sim_items[] =
+{
+    {"ql_sim_init", item_ql_sim_init},
+    {"ql_sim_get_imsi", item_ql_sim_get_imsi},
+    {"ql_sim_get_iccid", item_ql_sim_get_iccid},
+    {"ql_sim_get_phone_num", item_ql_sim_get_phone_num},
+    {"ql_sim_get_operators", item_ql_sim_get_operators},
+    {"ql_sim_enable_pin", item_ql_sim_enable_pin},
+    {"ql_sim_disable_pin", item_ql_sim_disable_pin},
+    {"ql_sim_verify_pin", item_ql_sim_verify_pin},
+    {"ql_sim_change_pin", item_ql_sim_change_pin},
+    {"ql_sim_unblock_pin", item_ql_sim_unblock_pin},
+    {"ql_sim_get_card_info", item_ql_sim_get_card_info},
+//    {"ql_sim_read_file", item_ql_sim_read_file},
+//    {"ql_sim_write_file", item_ql_sim_write_file},
+//    {"ql_sim_get_file_info", item_ql_sim_get_file_info},
+//    {"ql_sim_read_phone_book", item_ql_sim_read_phone_book},
+//   {"ql_sim_write_phone_book", item_ql_sim_write_phone_book},
+//    {"ql_sim_open_logical_channel", item_ql_sim_open_logical_channel},
+//    {"ql_sim_close_logical_channel", item_ql_sim_close_logical_channel},
+//    {"ql_sim_send_apdu", item_ql_sim_send_apdu},
+    {"ql_sim_set_card_status_cb", item_ql_sim_set_card_status_cb},
+    {"ql_sim_set_service_error_cb", item_ql_sim_set_service_error_cb},
+//    {"ql_sim_switch_slot", item_ql_sim_switch_slot},
+//    {"ql_sim_get_active_slots", item_ql_sim_get_active_slots},
+    {"ql_sim_deinit", item_ql_sim_deinit},
+};
+
+t_module_t ql_sim_module =
+{
+    "sim",
+    T_ARRAY_SIZE(ql_sim_items),
+    ql_sim_items
+};
+
+/*-----------------------------------------------------------------------------------------------*/
+/** 
+  @brief Read a int value from stdin 
+  @param[out] val, Return read data
+  @return 
+  0 - successful
+  1 - read an enter 
+  -1 - invalid input
+  */
+/*-----------------------------------------------------------------------------------------------*/
+int t_get_int(int *val)
+{
+    int dat;
+    char *ptr_end = NULL;
+    char buf[256] = {0};
+
+    if(NULL == fgets(buf, sizeof(buf)-1, stdin))
+    {
+        return -1;
+    }
+#if 0    
+    if(0 == buf[0])
+    {
+        return -1;
+    }
+#endif
+    if(buf[0] == '\n')
+    {
+        return 1;
+    }
+
+    dat = strtol(buf, &ptr_end, 10);
+    if(ptr_end!=NULL && ptr_end[0]!='\n')
+    {
+        return -1;
+    }
+
+    if(val)
+    {
+        val[0] = dat;
+    }
+
+    return 0;
+}
+
+void dump_items()
+{
+    int i;
+
+    printf("\n");
+    printf("The current module is: \n");
+
+    for(i=0; i< ql_sim_module.item_len; i++)
+    {
+        printf("%d\t%s\n", i, ql_sim_module.item_list[i].name);
+    }
+    printf("-1\texit\n");
+}
+
+int main(int argc, char *argv[])
+{
+    int ret;
+    int idx;
+
+    dump_items();
+
+    while(1)
+    {
+        printf("Please enter your choice: ");
+        ret = t_get_int(&idx);
+        printf("\n");
+        if(ret < 0)
+        {
+            printf("Invalid input\n");
+            continue;
+        }
+        else if(ret == 1)
+        {
+            dump_items();
+            continue;
+        }
+
+        if(idx == -1)
+        {
+            break;
+        }
+
+        if(idx<0 || idx>=ql_sim_module.item_len)
+        {
+            printf("Not support idx: %d\n", idx);
+            continue;
+        }
+
+        printf("->Item : %s\n", ql_sim_module.item_list[idx].name);
+        ql_sim_module.item_list[idx].handle();
+    }
+
+    return 0;
+}
+
+
+