Add toolchain and mbtk source

Change-Id: Ie12546301367ea59240bf23d5e184ad7e36e40b3
diff --git a/mbtk/mbtk_lib/src/mbtk_info.c b/mbtk/mbtk_lib/src/mbtk_info.c
new file mode 100755
index 0000000..7ff9345
--- /dev/null
+++ b/mbtk/mbtk_lib/src/mbtk_info.c
@@ -0,0 +1,1068 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "mbtk_info.h"
+#include "mbtk_list.h"
+#include "mbtk_utils.h"
+
+static int sock_read(int fd, uint8 *msg, int data_len)
+{
+    memset(msg, 0, data_len);
+    int len = 0;
+    int read_len = 0;
+    while(1)
+    {
+        len = read(fd, msg + read_len, data_len - read_len);
+        if(len > 0)
+        {
+            read_len += len;
+        }
+        else if(len == 0)
+        {
+            LOG("read() end.");
+            break;
+        }
+        else
+        {
+            if(EAGAIN == errno)
+            {
+                LOG("Read end, lenght = %d", read_len);
+            }
+            else
+            {
+                LOG("read() error[%d].", errno);
+            }
+            break;
+        }
+    }
+
+    if(read_len > 0)
+    {
+        log_hex("DATA_RECV", msg, read_len);
+        return read_len;
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+static int sock_write(int fd, uint8 *msg, int data_len)
+{
+    int len = 0;
+    int write_len = 0;
+    while(write_len < data_len)
+    {
+        len = write(fd, msg + write_len, data_len - write_len);
+        if(len > 0)
+        {
+            write_len += len;
+        }
+        else if(len == 0)
+        {
+            LOG("write() end.");
+            break;
+        }
+        else
+        {
+            LOG("write() error[%d].", errno);
+            break;
+        }
+    }
+
+    if(write_len > 0)
+    {
+        log_hex("DATA_SEND", msg, write_len);
+        return write_len;
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+static int pack_num_check(const void* data, int data_len)
+{
+    int count = 0;
+    int pack_len;
+    const uint8* ptr = (const uint8*)data;
+    while(ptr < (const uint8*)data + data_len)
+    {
+        if(MBTK_INFO_PACKET_FLAG != byte_2_uint32(ptr, true))
+        {
+            LOG("pack_num_check() - TAG error.");
+            break;
+        }
+        ptr += sizeof(uint32);
+
+        pack_len = byte_2_uint16(ptr, false);
+        if(pack_len < SOCK_PACK_LEN_MIN - SOCK_PACK_EXTRA_LEN)
+        {
+            LOG("pack_num_check() - Packet length error.");
+            break;
+        }
+        ptr += sizeof(uint16);
+        ptr += pack_len;
+
+        count++;
+    }
+
+    return count;
+}
+
+char* type2str(mbtk_info_type_enum type)
+{
+    switch(type)
+    {
+        case MBTK_INFO_TYPE_REQ:
+            return "REQ";
+        case MBTK_INFO_TYPE_RSP:
+            return "RSP";
+        case MBTK_INFO_TYPE_IND:
+            return "IND";
+        default:
+        {
+            return "UNKNOWN";
+        }
+    }
+}
+
+char* apn2str(mbtk_ip_type_enum type)
+{
+    switch(type)
+    {
+        case MBTK_IP_TYPE_IP:
+            return "IP";
+        case MBTK_IP_TYPE_IPV6:
+            return "IPV6";
+        case MBTK_IP_TYPE_IPV4V6:
+            return "IPV4V6";
+        case MBTK_IP_TYPE_PPP:
+            return "PPP";
+        default:
+        {
+            return "UNKNOWN";
+        }
+    }
+}
+
+/*
+IPv6 : 254.128.0.0.0.0.0.0.0.1.0.2.144.5.212.239 -> uint128
+*/
+int str_2_ipv6(const void *ip_str, void *ipv6)
+{
+    const uint8 *ptr = (const uint8*)ip_str;
+    uint8 *ipv6_ptr = (uint8*)ipv6;
+    ipv6_ptr[0] = (uint8)atoi(ptr);
+    int i = 1;
+    while(i < 16) {
+        ptr = (const uint8*)strstr(ptr, ".");
+        if(ptr == NULL)
+            return -1;
+        ptr++;
+        ipv6_ptr[i] = (uint8)atoi(ptr);
+        i++;
+    }
+
+    return 0;
+}
+
+/*
+IPv6 : uint128 -> fe80::215:1dff:fe81:484c
+*/
+int ipv6_2_str(const void *ipv6, void *ipv6_str)
+{
+    const uint8 *ptr = (const uint8*)ipv6;
+    uint8 *ipv6_ptr = (uint8*)ipv6_str;
+    int i = 0;
+    int index = 0;
+    while(i < 16) {
+        index += sprintf(ipv6_ptr + index, "%02x%02x", ptr[i], ptr[i + 1]);
+        index += sprintf(ipv6_ptr + index, ":");
+        i += 2;
+    }
+
+    ipv6_ptr[index - 1] = '\0'; // Delete last ':'
+
+    return 0;
+}
+
+
+
+char* id2str(int id)
+{
+    switch(id)
+    {
+        // <string> IMEI
+        case MBTK_INFO_ID_DEV_IMEI_REQ:
+        case MBTK_INFO_ID_DEV_IMEI_RSP:
+            return "IMEI";
+        // <string> SN
+        case MBTK_INFO_ID_DEV_SN_REQ:
+        case MBTK_INFO_ID_DEV_SN_RSP:
+            return "SN";
+        // <string> MEID
+        case MBTK_INFO_ID_DEV_MEID_REQ:
+        case MBTK_INFO_ID_DEV_MEID_RSP:
+            return "MEID";
+        // <string> VERSION
+        case MBTK_INFO_ID_DEV_VERSION_REQ:
+        case MBTK_INFO_ID_DEV_VERSION_RSP:
+            return "VERSION";
+        // <uint8> 0:Close 1:Open
+        case MBTK_INFO_ID_DEV_VOLTE_REQ:
+        case MBTK_INFO_ID_DEV_VOLTE_RSP:
+            return "VOLTE";
+        // <string> Temperature
+        case MBTK_INFO_ID_DEV_TEMP_REQ:  // Temperature
+        case MBTK_INFO_ID_DEV_TEMP_RSP:
+            return "TEMPERATURE";
+        case MBTK_INFO_ID_DEV_TIME_REQ:  // Time
+        case MBTK_INFO_ID_DEV_TIME_RSP:
+            return "Time";
+        // Sim Information
+        // <uint8> 0:NOT_EXIST 1:READY ...
+        case MBTK_INFO_ID_SIM_STATE_REQ:
+        case MBTK_INFO_ID_SIM_STATE_RSP:
+            return "SIM_STATE";
+        // <string> PIN
+        case MBTK_INFO_ID_SIM_PIN_REQ:
+        case MBTK_INFO_ID_SIM_PIN_RSP:
+            return "SIM_PIN";
+        // <string> PUK
+        case MBTK_INFO_ID_SIM_PUK_REQ:
+        case MBTK_INFO_ID_SIM_PUK_RSP:
+            return "SIM_PUK";
+        // <string> IMSI
+        case MBTK_INFO_ID_SIM_IMSI_REQ:
+        case MBTK_INFO_ID_SIM_IMSI_RSP:
+            return "IMSI";
+        // <string> ICCID
+        case MBTK_INFO_ID_SIM_ICCID_REQ:
+        case MBTK_INFO_ID_SIM_ICCID_RSP:
+            return "ICCID";
+        // <string> Phone Number
+        case MBTK_INFO_ID_SIM_PN_REQ:
+        case MBTK_INFO_ID_SIM_PN_RSP:
+            return "PHONE_NUMBER";
+        // Network Information
+        // <uint8> 0:OFF 1:ON
+        case MBTK_INFO_ID_NET_RADIO_REQ:
+        case MBTK_INFO_ID_NET_RADIO_RSP:
+            return "RADIO_STATE";
+        case MBTK_INFO_ID_NET_AVAILABLE_REQ:
+        case MBTK_INFO_ID_NET_AVAILABLE_RSP:
+            return "NET_AVAILABLE";
+        case MBTK_INFO_ID_NET_SEL_MODE_REQ:
+        case MBTK_INFO_ID_NET_SEL_MODE_RSP:
+            return "NET_SEL_MODE";
+        case MBTK_INFO_ID_NET_BAND_REQ:
+        case MBTK_INFO_ID_NET_BAND_RSP:
+            return "NET_BNAD";
+        // <uint16>[4]  rssi,rscp,rsrp,snr
+        case MBTK_INFO_ID_NET_SIGNAL_REQ:
+        case MBTK_INFO_ID_NET_SIGNAL_RSP:
+            return "SIGNAL";
+        case MBTK_INFO_ID_NET_REG_REQ:
+        case MBTK_INFO_ID_NET_REG_RSP:
+            return "NET_REG";
+        // <string> cmnet/ctnet/3gnet/...
+        case MBTK_INFO_ID_NET_APN_REQ:
+        case MBTK_INFO_ID_NET_APN_RSP:
+            return "APN";
+        // Lock net/cell/frequency
+        case MBTK_INFO_ID_NET_CELL_REQ:
+        case MBTK_INFO_ID_NET_CELL_RSP:
+            return "NET_CELL";
+        case MBTK_INFO_ID_NET_DATA_CALL_REQ:
+        case MBTK_INFO_ID_NET_DATA_CALL_RSP:
+            return "DATA_CALL";
+        // Call Information
+        case MBTK_INFO_ID_CALL_STATE_REQ:
+        case MBTK_INFO_ID_CALL_STATE_RSP:
+            return "CALL_STATE";
+        // SMS Information
+        case MBTK_INFO_ID_SMS_STATE_REQ:
+        case MBTK_INFO_ID_SMS_STATE_RSP:
+            return "SMS_STATE";
+        // PhoneBook Information
+        case MBTK_INFO_ID_PB_STATE_REQ:
+        case MBTK_INFO_ID_PB_STATE_RSP:
+            return "PB_STATE";
+        // IND Information
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_NET_STATE_CHANGE:
+            return "IND_NET_STATE";
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_CALL_STATE_CHANGE:
+            return "IND_CALL_STATE";
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_SMS_STATE_CHANGE:
+            return "IND_SMS_STATE";
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_RADIO_STATE_CHANGE:
+            return "IND_RADIO_STATE";
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_SIM_STATE_CHANGE:
+            return "IND_SIM_STATE";
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_PDP_STATE_CHANGE:
+            return "IND_PDP_STATE";
+        // <uint8>  State
+        case MBTK_INFO_ID_IND_SERVER_STATE_CHANGE:
+            return "IND_SERVER_STATE";
+        default:
+        {
+            return "UNKNOWN";
+        }
+    }
+}
+
+char* err2str(mbtk_info_err_enum err)
+{
+    switch(err)
+    {
+        case MBTK_INFO_ERR_SUCCESS:
+            return "SUCCESS";
+        case MBTK_INFO_ERR_FORMAT:
+            return "ERR_FORMAT";
+        case MBTK_INFO_ERR_REQ_UNKNOWN:
+            return "ERR_REQ_UNKNOWN";
+        case MBTK_INFO_ERR_REQ_PARAMETER:
+            return "ERR_REQ_PARAMETER";
+        case MBTK_INFO_ERR_UNSUPPORTED:
+            return "ERR_UNSUPPORTED";
+        case MBTK_INFO_ERR_MEMORY:
+            return "ERR_MEMORY";
+        case MBTK_INFO_ERR_IND_FULL:
+            return "ERR_IND_FULL";
+        case MBTK_INFO_ERR_IND_UNKNOWN:
+            return "ERR_IND_UNKNOWN";
+        case MBTK_INFO_ERR_CID_EXIST:
+            return "ERR_CID_EXIS";
+        case MBTK_INFO_ERR_CID_NO_EXIST:
+            return "ERR_CID_NO_EXIST";
+        case MBTK_INFO_ERR_NET_NO_INIT:
+            return "ERR_CID_NO_EXIST";
+        default:
+        {
+            if(err >= MBTK_INFO_ERR_CME) {
+                return "CME ERROR";
+            }
+
+            return "UNKNOWN";
+        }
+    }
+}
+
+/*
+0   GSM
+1   GSM_COMPACT
+2   UTRAN
+3   GSM_EGPRS
+4   UTRAN_HSDPA
+5   UTRAN_HSUPA
+6   UTRAN_HSDPA_HSUPA
+7   EUTRAN
+8   ECGSM
+*/
+mbtk_net_type_enum mbtk_net_type_get(mbtk_radio_technology_enum radio_tech)
+{
+    switch(radio_tech)
+    {
+        case MBTK_RADIO_TECH_GSM:
+        case MBTK_RADIO_TECH_GSM_COMPACT:
+        case MBTK_RADIO_TECH_GSM_EGPRS:
+        case MBTK_RADIO_TECH_UTRAN_HSPA:
+        {
+            return MBTK_NET_TYPE_GSM;
+        }
+        case MBTK_RADIO_TECH_UTRAN:
+        case MBTK_RADIO_TECH_UTRAN_HSDPA:
+        case MBTK_RADIO_TECH_UTRAN_HSUPA:
+        case MBTK_RADIO_TECH_UTRAN_HSDPA_HSUPA:
+        {
+            return MBTK_NET_TYPE_UMTS;
+        }
+        case MBTK_RADIO_TECH_E_UTRAN:
+        {
+            return MBTK_NET_TYPE_LTE;
+        }
+        default:
+        {
+            return MBTK_NET_TYPE_UNKNOWN;
+        }
+    }
+}
+
+
+#if 0
+void net_list_free(void *data)
+{
+    if (data)
+    {
+        mbtk_net_info_t *info = (mbtk_net_info_t*) data;
+        LOG("Free net [%s].", info->plmn);
+        free(info);
+    }
+}
+#endif
+
+mbtk_info_type_enum mbtk_info_type_get(int info_id)
+{
+    if(info_id > MBTK_INFO_ID_IND_BEGIN && info_id < MBTK_INFO_ID_IND_END)
+    {
+        return MBTK_INFO_TYPE_IND;
+    }
+    else if(info_id == MBTK_INFO_ID_DEV_BEGIN ||
+            info_id == MBTK_INFO_ID_DEV_END ||
+            info_id == MBTK_INFO_ID_SIM_BEGIN ||
+            info_id == MBTK_INFO_ID_SIM_END ||
+            info_id == MBTK_INFO_ID_NET_BEGIN ||
+            info_id == MBTK_INFO_ID_NET_END ||
+            info_id == MBTK_INFO_ID_CALL_BEGIN ||
+            info_id == MBTK_INFO_ID_CALL_END ||
+            info_id == MBTK_INFO_ID_SMS_BEGIN ||
+            info_id == MBTK_INFO_ID_SMS_END ||
+            info_id == MBTK_INFO_ID_PB_BEGIN ||
+            info_id == MBTK_INFO_ID_PB_END ||
+            info_id == MBTK_INFO_ID_REQ_UNKNOWN)
+    {
+        return MBTK_INFO_TYPE_UNKNOWN;
+    }
+    else if(info_id % 2 == 1)
+    {
+        return MBTK_INFO_TYPE_REQ;
+    }
+    else
+    {
+        return MBTK_INFO_TYPE_RSP;
+    }
+}
+
+mbtk_info_pack_t* mbtk_info_pack_creat(int info_id)
+{
+    mbtk_info_pack_t *pack = (mbtk_info_pack_t *)malloc(sizeof(mbtk_info_pack_t));
+    if(!pack)
+    {
+        LOG("malloc() error[%d]", errno);
+        return NULL;
+    }
+
+    pack->info_id = (uint16)info_id;
+    pack->info_err = (uint16)0;
+    pack->data_len = (uint16)0;
+    pack->data = NULL;
+
+    return pack;
+}
+
+#if 0
+int mbtk_info_pack_data_set(mbtk_info_pack_t *pack, const void *data, int data_len)
+{
+    if(!pack)
+    {
+        LOG("Packet is NULL.");
+        return -1;
+    }
+
+    mbtk_info_type_enum info_type = mbtk_info_type_get(pack->info_id);
+    // IND
+    if(info_type == MBTK_INFO_TYPE_IND)
+    {
+        switch(pack->info_id)
+        {
+            // <uint8>  State
+            case MBTK_INFO_ID_IND_NET_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_CALL_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_SMS_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_RADIO_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_SIM_STATE_CHANGE:
+            {
+                pack->data_len = (uint16)data_len;
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+            default:
+            {
+                LOG("Unknown IND : %s", id2str(pack->info_id));
+                break;
+            }
+        }
+    }
+    //else if(pack->info_id % 2 == 1)     // REQ (Set Data)
+    else if(info_type == MBTK_INFO_TYPE_REQ || info_type == MBTK_INFO_TYPE_RSP) // REQ or RSP
+    {
+        switch(pack->info_id)
+        {
+            case MBTK_INFO_ID_DEV_VOLTE_REQ:    // <uint8> 0:Close 1:Open
+            case MBTK_INFO_ID_DEV_VOLTE_RSP:
+            case MBTK_INFO_ID_SIM_STATE_REQ:    // <uint8> 0:NOT_EXIST 1:READY ...
+            case MBTK_INFO_ID_SIM_STATE_RSP:
+            case MBTK_INFO_ID_NET_RADIO_REQ:    // <uint8> 0:OFF 1:ON
+            case MBTK_INFO_ID_NET_RADIO_RSP:
+            case MBTK_INFO_ID_NET_BAND_REQ:     // mbtk_band_info_t
+            case MBTK_INFO_ID_NET_BAND_RSP:
+            case MBTK_INFO_ID_NET_CELL_REQ:     // Lock net/cell/frequency
+            case MBTK_INFO_ID_NET_CELL_RSP:
+            case MBTK_INFO_ID_DEV_IMEI_REQ:     // <string> SN
+            case MBTK_INFO_ID_DEV_IMEI_RSP:
+            case MBTK_INFO_ID_DEV_SN_REQ:       // <string> SN
+            case MBTK_INFO_ID_DEV_SN_RSP:
+            case MBTK_INFO_ID_DEV_MEID_REQ:     // <string> MEID
+            case MBTK_INFO_ID_DEV_MEID_RSP:
+            case MBTK_INFO_ID_DEV_VERSION_REQ:  // <string> VERSION
+            case MBTK_INFO_ID_DEV_VERSION_RSP:
+            case MBTK_INFO_ID_DEV_TEMP_REQ:     // <string> Temperature
+            case MBTK_INFO_ID_DEV_TEMP_RSP:
+            case MBTK_INFO_ID_SIM_PIN_REQ:      // <string> PIN
+            case MBTK_INFO_ID_SIM_PIN_RSP:
+            case MBTK_INFO_ID_SIM_PUK_REQ:      // <string> PUK
+            case MBTK_INFO_ID_SIM_PUK_RSP:
+            case MBTK_INFO_ID_SIM_IMSI_REQ:     // <string> IMSI
+            case MBTK_INFO_ID_SIM_IMSI_RSP:
+            case MBTK_INFO_ID_SIM_ICCID_REQ:    // <string> ICCID
+            case MBTK_INFO_ID_SIM_ICCID_RSP:
+            case MBTK_INFO_ID_NET_APN_REQ:      // <string> cmnet/ctnet/3gnet/...
+            case MBTK_INFO_ID_NET_APN_RSP:
+            case MBTK_INFO_ID_NET_SEL_MODE_REQ: // mbtk_net_info_t
+            case MBTK_INFO_ID_NET_SEL_MODE_RSP:
+            case MBTK_INFO_ID_NET_AVAILABLE_REQ: // mbtk_net_info_t[]
+            case MBTK_INFO_ID_NET_AVAILABLE_RSP:
+            {
+                pack->data_len = (uint16)data_len;
+#if 1
+                pack->data = (uint8*)memdup(data, pack->data_len);
+#else
+                LOG("%d -> %d", data_len, pack->data_len);
+                log_hex("pack1", pack, sizeof(mbtk_info_pack_t));
+                #if 0
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                #else
+
+                LOG("1 pack->%p,data->%p", pack, pack->data);
+                pack->data = (uint8*)calloc(pack->data_len, sizeof(uint8));
+                LOG("2 pack->%p,data->%p", pack, pack->data);
+
+                memcpy(pack->data, data, data_len);
+                #endif
+
+                LOG("data_len - %d", pack->data_len);
+                log_hex("pack2", pack, sizeof(mbtk_info_pack_t));
+#endif
+                break;
+            }
+            case MBTK_INFO_ID_NET_SIGNAL_REQ:   // <sint16>[4]  rssi,rscp,rsrp,snr
+            case MBTK_INFO_ID_NET_SIGNAL_RSP:
+            {
+                // const mbtk_net_signal_t* signal = (const mbtk_net_signal_t*)data;
+                pack->data_len = (uint16)sizeof(mbtk_net_signal_t);
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+            case MBTK_INFO_ID_NET_IPV4_DNS_REQ: // <uint32>[2]  Preferred DNS,Alternate DNS
+            case MBTK_INFO_ID_NET_IPV4_DNS_RSP:
+            {
+                // const mbtk_net_dns_ipv4_t* dns_ipv4 = (const mbtk_net_dns_ipv4_t*)data;
+                pack->data_len = (uint16)sizeof(mbtk_net_dns_ipv4_t);
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+            case MBTK_INFO_ID_NET_IPV6_DNS_REQ: // <uint32>[8]  Preferred DNS,Alternate DNS
+            case MBTK_INFO_ID_NET_IPV6_DNS_RSP:
+            {
+                // const mbtk_net_dns_ipv6_t* dns_ipv6 = (const mbtk_net_dns_ipv6_t*)data;
+                pack->data_len = (uint16)sizeof(mbtk_net_dns_ipv6_t);
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+            case MBTK_INFO_ID_NET_IPV4_REQ:     // <uint32> IPv4
+            case MBTK_INFO_ID_NET_IPV4_RSP:
+            {
+                pack->data_len = (uint16)sizeof(uint32);
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+            case MBTK_INFO_ID_NET_IPV6_REQ:     // <uint32>[4] IPv6
+            case MBTK_INFO_ID_NET_IPV6_RSP:
+            {
+                pack->data_len = (uint16)(sizeof(uint32) * 4);
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+            case MBTK_INFO_ID_NET_LOCAL_REQ:    // <uint16>[2] tag,earfcn
+            case MBTK_INFO_ID_NET_LOCAL_RSP:
+            {
+                pack->data_len = (uint16)sizeof(mbtk_local_info_t);
+                pack->data = (uint8*)memdup(data, pack->data_len);
+                break;
+            }
+#if 0
+            case MBTK_INFO_ID_NET_SEL_MODE_REQ:
+            case MBTK_INFO_ID_NET_SEL_MODE_RSP: // sel_mode(uint8)type(uint8)plmn(uint32)
+            {
+                const mbtk_net_info_t* net = (const mbtk_net_info_t*)data;
+                pack->data_len = sizeof(uint8) + sizeof(uint8) + sizeof(uint32);
+                pack->data = (uint8*)malloc(pack->data_len);
+                if(pack->data == NULL) {
+                    LOG("malloc() fail.");
+                    return -1;
+                }
+
+                pack->data[0] = net->net_sel_mode;
+                pack->data[1] = net->net_type;
+                uint32_2_byte((uint32)atoi((char*)net->plmn), pack->data + 2,false);
+                break;
+            }
+#endif
+#if 0
+            case MBTK_INFO_ID_NET_AVAILABLE_REQ:
+            case MBTK_INFO_ID_NET_AVAILABLE_RSP: // sel_mode(uint8)type(uint8)plmn(uint32)...sel_mode(uint8)type(uint8)plmn(uint32)
+            {
+                const mbtk_net_array_info_t* nets = (const mbtk_net_array_info_t*)data;
+                mbtk_net_info_t *net = NULL;
+                //LOG("MBTK_INFO_ID_NET_AVAILABLE_RSP set");
+                //sleep(1);
+                list_first(nets->net_list);
+                pack->data_len = nets->count * sizeof(mbtk_net_info_t);
+                if(pack->data_len > 0) {
+                    int i = 0;
+                    pack->data = (uint8*)malloc(pack->data_len);
+                    if(pack->data == NULL) {
+                        LOG("malloc() fail.");
+                        return -1;
+                    }
+                    memset(pack->data, 0, pack->data_len);
+
+                    while ((net = (mbtk_net_info_t*) list_next(nets->net_list)))
+                    {
+                        #if 0
+                        memcpy(pack->data + i, net, sizeof(mbtk_net_info_t));
+                        i += sizeof(mbtk_net_info_t);
+                        #else
+                        pack->data[i++] = net->net_sel_mode;
+                        pack->data[i++] = net->net_type;
+                        //uint32_2_byte((uint32)atoi((char*)net->plmn), pack->data + i,false);
+                        uint32_2_byte(net->plmn, pack->data + i,false);
+                        i += sizeof(uint32);
+                        #endif
+                    }
+                }
+                break;
+            }
+#endif
+            default:
+            {
+                LOG("Unknown REQ/RSP : %s", id2str(pack->info_id));
+                break;
+            }
+        }
+    }
+    else
+    {
+        LOG("Unknown info : %s", id2str(pack->info_id));
+        return -1;
+    }
+    return 0;
+}
+
+void* mbtk_info_pack_data_get(mbtk_info_pack_t *pack, int *data_len)
+{
+    if(pack == NULL || pack->data_len == 0 || pack->data == NULL)
+    {
+        LOG("Packet is NULL.");
+        return NULL;
+    }
+
+    mbtk_info_type_enum info_type = mbtk_info_type_get(pack->info_id);
+    // IND
+    if(info_type == MBTK_INFO_TYPE_IND)
+    {
+        switch(pack->info_id)
+        {
+            // <uint8>  State
+            case MBTK_INFO_ID_IND_NET_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_CALL_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_SMS_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_RADIO_STATE_CHANGE:
+            case MBTK_INFO_ID_IND_SIM_STATE_CHANGE:
+            {
+                return pack->data;
+            }
+            default:
+            {
+                LOG("Unknown IND : %s", id2str(pack->info_id));
+                break;
+            }
+        }
+    }
+    //else if(pack->info_id % 2 == 1)     // REQ (Set Data)
+    else if(info_type == MBTK_INFO_TYPE_REQ || info_type == MBTK_INFO_TYPE_RSP) // REQ or RSP
+    {
+        switch(pack->info_id)
+        {
+            case MBTK_INFO_ID_DEV_VOLTE_REQ:    // <uint8> 0:Close 1:Open
+            case MBTK_INFO_ID_DEV_VOLTE_RSP:
+            case MBTK_INFO_ID_SIM_STATE_REQ:    // <uint8> 0:NOT_EXIST 1:READY ...
+            case MBTK_INFO_ID_SIM_STATE_RSP:
+            case MBTK_INFO_ID_NET_RADIO_REQ:    // <uint8> 0:OFF 1:ON
+            case MBTK_INFO_ID_NET_RADIO_RSP:
+            case MBTK_INFO_ID_DEV_IMEI_REQ:     // <string> SN
+            case MBTK_INFO_ID_DEV_IMEI_RSP:
+            case MBTK_INFO_ID_DEV_SN_REQ:       // <string> SN
+            case MBTK_INFO_ID_DEV_SN_RSP:
+            case MBTK_INFO_ID_DEV_MEID_REQ:     // <string> MEID
+            case MBTK_INFO_ID_DEV_MEID_RSP:
+            case MBTK_INFO_ID_DEV_VERSION_REQ:  // <string> VERSION
+            case MBTK_INFO_ID_DEV_VERSION_RSP:
+            case MBTK_INFO_ID_DEV_TEMP_REQ:     // <string> Temperature
+            case MBTK_INFO_ID_DEV_TEMP_RSP:
+            case MBTK_INFO_ID_SIM_PIN_REQ:      // <string> PIN
+            case MBTK_INFO_ID_SIM_PIN_RSP:
+            case MBTK_INFO_ID_SIM_PUK_REQ:      // <string> PUK
+            case MBTK_INFO_ID_SIM_PUK_RSP:
+            case MBTK_INFO_ID_SIM_IMSI_REQ:     // <string> IMSI
+            case MBTK_INFO_ID_SIM_IMSI_RSP:
+            case MBTK_INFO_ID_SIM_ICCID_REQ:    // <string> ICCID
+            case MBTK_INFO_ID_SIM_ICCID_RSP:
+            case MBTK_INFO_ID_NET_APN_REQ:      // <string> cmnet/ctnet/3gnet/...
+            case MBTK_INFO_ID_NET_APN_RSP:
+            case MBTK_INFO_ID_NET_BAND_REQ:     // mbtk_band_info_t
+            case MBTK_INFO_ID_NET_BAND_RSP:
+            case MBTK_INFO_ID_NET_CELL_REQ:     // Lock net/cell/frequency
+            case MBTK_INFO_ID_NET_CELL_RSP:
+            case MBTK_INFO_ID_NET_SEL_MODE_REQ:  // mbtk_net_info_t
+            case MBTK_INFO_ID_NET_SEL_MODE_RSP:
+            case MBTK_INFO_ID_NET_AVAILABLE_REQ: // mbtk_net_info_t[]
+            case MBTK_INFO_ID_NET_AVAILABLE_RSP:
+            {
+                return pack->data;
+            }
+            case MBTK_INFO_ID_NET_SIGNAL_REQ:   // <sint16>[4]  rssi,rscp,rsrp,snr
+            case MBTK_INFO_ID_NET_SIGNAL_RSP:
+            {
+                mbtk_net_signal_t* signal = (mbtk_net_signal_t*)malloc(sizeof(mbtk_net_signal_t));
+                if(!signal)
+                {
+                    LOG("malloc() error[%d]", errno);
+                    return NULL;
+                }
+
+                signal->rssi = (sint16)byte_2_uint16(pack->data, false);
+                signal->rscp = (sint16)byte_2_uint16(pack->data + sizeof(uint16), false);
+                signal->rsrp = (sint16)byte_2_uint16(pack->data + sizeof(uint16) * 2, false);
+                signal->snr = (sint16)byte_2_uint16(pack->data + sizeof(uint16) * 3, false);
+                return signal;
+            }
+            case MBTK_INFO_ID_NET_IPV4_DNS_REQ: // <uint32>[2]  Preferred DNS,Alternate DNS
+            case MBTK_INFO_ID_NET_IPV4_DNS_RSP:
+            {
+                mbtk_net_dns_ipv4_t* dns_ipv4 = (mbtk_net_dns_ipv4_t*)malloc(sizeof(mbtk_net_dns_ipv4_t));
+                if(!dns_ipv4)
+                {
+                    LOG("malloc() error[%d]", errno);
+                    return NULL;
+                }
+
+                dns_ipv4->preferred_dns = byte_2_uint32(pack->data, false);
+                dns_ipv4->alternate_dns = byte_2_uint32(pack->data + sizeof(uint32), false);
+                return dns_ipv4;
+            }
+            case MBTK_INFO_ID_NET_IPV6_DNS_REQ: // <uint32>[8]  Preferred DNS,Alternate DNS
+            case MBTK_INFO_ID_NET_IPV6_DNS_RSP:
+            {
+                return memdup(pack->data, sizeof(mbtk_net_dns_ipv6_t));
+            }
+            case MBTK_INFO_ID_NET_IPV4_REQ:     // <uint32> IPv4
+            case MBTK_INFO_ID_NET_IPV4_RSP:
+            {
+                return memdup(pack->data, sizeof(uint32));
+                break;
+            }
+            case MBTK_INFO_ID_NET_IPV6_REQ:     // <uint32>[4] IPv6
+            case MBTK_INFO_ID_NET_IPV6_RSP:
+            {
+                return memdup(pack->data, sizeof(uint32) * 4);
+                break;
+            }
+            case MBTK_INFO_ID_NET_LOCAL_REQ:    // <uint16>[2] tag,earfcn
+            case MBTK_INFO_ID_NET_LOCAL_RSP:
+            {
+                mbtk_local_info_t* local = (mbtk_local_info_t*)malloc(sizeof(mbtk_local_info_t));
+                if(!local)
+                {
+                    LOG("malloc() error[%d]", errno);
+                    return NULL;
+                }
+
+                local->tag = (sint16)byte_2_uint16(pack->data, false);
+                local->earfcn = (sint16)byte_2_uint16(pack->data + sizeof(uint16), false);
+                return local;
+            }
+#if 0
+            case MBTK_INFO_ID_NET_SEL_MODE_REQ:
+            case MBTK_INFO_ID_NET_SEL_MODE_RSP: // sel_mode(uint8)type(uint8)plmn(uint32)
+            {
+                mbtk_net_info_t* net = (mbtk_net_info_t*)malloc(sizeof(mbtk_net_info_t));
+                if(!net)
+                {
+                    LOG("malloc() error[%d]", errno);
+                    return NULL;
+                }
+                memset(net, 0, sizeof(mbtk_net_info_t));
+                net->net_sel_mode = pack->data[0];
+                net->net_type = pack->data[1];
+                //itoa(byte_2_uint32(pack->data + 2, false), net->plmn, 10);
+                sprintf(net->plmn, "%d", byte_2_uint32(pack->data + 2, false));
+
+                return net;
+            }
+#endif
+#if 0
+            case MBTK_INFO_ID_NET_AVAILABLE_REQ:
+            case MBTK_INFO_ID_NET_AVAILABLE_RSP: // sel_mode(uint8)type(uint8)plmn(uint32)...sel_mode(uint8)type(uint8)plmn(uint32)
+            {
+                mbtk_net_array_info_t* nets = (mbtk_net_array_info_t*)malloc(sizeof(mbtk_net_array_info_t));
+                if(!nets)
+                {
+                    LOG("malloc() error[%d]", errno);
+                    return NULL;
+                }
+                nets->count = 0;
+                nets->net_list = list_create(NULL);
+                if(nets->net_list == NULL)
+                {
+                    LOG("list_create() fail.");
+                    free(nets);
+                    return NULL;
+                }
+
+                int i = 0;
+                while(i < pack->data_len) {
+                    LOG("MBTK_INFO_ID_NET_AVAILABLE_RSP get 1");
+                    sleep(1);
+                    mbtk_net_info_t* net = (mbtk_net_info_t*)malloc(sizeof(mbtk_net_info_t));
+                    LOG("MBTK_INFO_ID_NET_AVAILABLE_RSP get 2");
+                    sleep(1);
+                    if(!net)
+                    {
+                        LOG("malloc() error[%d]", errno);
+                        sleep(3);
+                        //list_free(nets->net_list);
+                        //free(nets);
+                        return NULL;
+                    }
+                    memset(net, 0, sizeof(mbtk_net_info_t));
+
+                    LOG("MBTK_INFO_ID_NET_AVAILABLE_RSP get 3");
+                    sleep(1);
+#if 1
+                    #if 1
+                    #if 0
+                    memcpy(net, pack->data + i, sizeof(mbtk_net_info_t));
+                    i += sizeof(mbtk_net_info_t);
+                    #else
+                    net->net_sel_mode = pack->data[i++];
+                    net->net_type = pack->data[i++];
+                    //sprintf(net->plmn, "%d", byte_2_uint32(pack->data + i, false));
+                    net->plmn = byte_2_uint32(pack->data + i, false);
+                    i += sizeof(uint32);
+                    #endif
+                    #endif
+
+                    LOG("MBTK_INFO_ID_NET_AVAILABLE_RSP get 5");
+                    log_hex("NET 2", net, sizeof(mbtk_net_info_t));
+                    sleep(1);
+
+                    list_add(nets->net_list, net);
+
+#endif
+                    LOG("list_add");
+                    sleep(1);
+                }
+
+                sleep(10);
+
+                // Data lenght changed.
+                *data_len = sizeof(mbtk_net_array_info_t);
+                return nets;
+            }
+#endif
+            default:
+            {
+                LOG("Unknown REQ/RSP : %s", id2str(pack->info_id));
+                break;
+            }
+        }
+    }
+    else
+    {
+        LOG("Unknown info : %s", id2str(pack->info_id));
+    }
+
+    return NULL;
+}
+#endif
+
+int mbtk_info_pack_send(int fd, mbtk_info_pack_t *pack)
+{
+    if(!pack)
+    {
+        LOG("Packet is NULL.");
+        return -1;
+    }
+    uint8 data[SOCK_MSG_LEN_MAX] = {0};
+    uint8* data_ptr = data + SOCK_PACK_EXTRA_LEN;
+
+    data_ptr += uint16_2_byte(pack->info_id, data_ptr, false);
+    data_ptr += uint16_2_byte(pack->info_err, data_ptr, false);
+    data_ptr += uint16_2_byte(pack->data_len, data_ptr, false);
+    //log_hex("DATA1", data, 40);
+    if(pack->data_len > 0)
+    {
+        memcpy(data_ptr, pack->data, pack->data_len);
+        data_ptr += pack->data_len;
+        //log_hex("DATA2", data, 40);
+    }
+
+    // Set flag and packet length.
+    uint32_2_byte(MBTK_INFO_PACKET_FLAG, data, true);
+    uint16_2_byte(data_ptr - data - SOCK_PACK_EXTRA_LEN, data + sizeof(uint32), false);
+
+    //log_hex("DATA3", data, 40);
+    return sock_write(fd, data, data_ptr - data);
+}
+
+mbtk_info_pack_t** mbtk_info_pack_recv(int fd, bool is_server, mbtk_info_err_enum *err)
+{
+    uint8 msg[SOCK_MSG_LEN_MAX + 1];
+    *err = MBTK_INFO_ERR_SUCCESS;
+    int len = sock_read(fd, msg, SOCK_MSG_LEN_MAX + 1);
+    if(len < SOCK_PACK_LEN_MIN)
+    {
+        if(len > 0)
+        {
+            *err = MBTK_INFO_ERR_FORMAT;
+            LOG("Insufficient packet data.");
+        }
+        return NULL;
+    }
+
+    int pack_count = pack_num_check(msg, len);
+    LOG("Packet number : %d", pack_count);
+    if(pack_count < 1)
+    {
+        *err = MBTK_INFO_ERR_FORMAT;
+        LOG("Packet not found.");
+        return NULL;
+    }
+    uint8 *ptr = msg;
+    mbtk_info_pack_t** packs = (mbtk_info_pack_t**)malloc(sizeof(mbtk_info_pack_t*) * (pack_count + 1));
+    int i = 0;
+    while(i < pack_count)
+    {
+        // TAG
+        if(MBTK_INFO_PACKET_FLAG != byte_2_uint32(ptr, true))
+        {
+            *err = MBTK_INFO_ERR_FORMAT;
+            LOG("Packet TAG error.");
+            goto error;
+        }
+        ptr += sizeof(uint32);
+
+        // Jump packet length.
+        ptr += sizeof(uint16);
+
+        mbtk_info_id_enum info_id = (mbtk_info_id_enum)byte_2_uint16(ptr, false);
+        mbtk_info_type_enum info_type = mbtk_info_type_get(info_id);
+        if(is_server)
+        {
+            // For server,"info_type" must by REQ or IND(Register IND).
+            if(info_type != MBTK_INFO_TYPE_REQ && info_type != MBTK_INFO_TYPE_IND)
+            {
+                *err = MBTK_INFO_ERR_FORMAT;
+                LOG("Packet Type error.");
+                goto error;
+            }
+        }
+        else
+        {
+            // For client,"info_type" must by RSP or IND.
+            if(info_type != MBTK_INFO_TYPE_RSP && info_type != MBTK_INFO_TYPE_IND)
+            {
+                *err = MBTK_INFO_ERR_FORMAT;
+                LOG("Packet Type error.");
+                goto error;
+            }
+        }
+        ptr += sizeof(uint16);
+
+        mbtk_info_pack_t* pack = mbtk_info_pack_creat(info_id);
+        if(pack == NULL)
+        {
+            *err = MBTK_INFO_ERR_MEMORY;
+            LOG("Packet malloc() fail.");
+            goto error;
+        }
+
+        // "info_err"
+        pack->info_err = byte_2_uint16(ptr, false);
+        ptr += sizeof(uint16);
+
+        // "data_len"
+        pack->data_len = byte_2_uint16(ptr, false);
+        ptr += sizeof(uint16);
+
+        if(pack->data_len > 0)
+        {
+            pack->data = (uint8*)memdup(ptr, pack->data_len);
+            ptr += pack->data_len;
+        }
+
+        packs[i++] = pack;
+    }
+    packs[i] = NULL;
+
+    return packs;
+
+error:
+    LOG("mbtk_info_pack_recv error, will free().");
+    if(packs)
+    {
+        mbtk_info_pack_t** pack_ptr = packs;
+        while(*pack_ptr)
+        {
+            mbtk_info_pack_free(pack_ptr);
+            pack_ptr++;
+        }
+
+        free(packs);
+    }
+    return NULL;
+}
+
+int mbtk_info_pack_free(mbtk_info_pack_t **pack)
+{
+    if(pack == NULL || *pack == NULL)
+    {
+        LOG("Packet is NULL.");
+        return -1;
+    }
+
+    // LOG("Free packet : %s", id2str((*pack)->info_id));
+#if 0
+    if((*pack)->data)
+    {
+        free((*pack)->data);
+    }
+#endif
+    free(*pack);
+    *pack = NULL;
+    return 0;
+}
+
+