#include "lynq-qser-data.h"
#include "mbtk_type.h"
#include "mbtk_info_api.h"

#include <pthread.h>
#include <cutils/properties.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <sys/scoket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/****************************DEFINE***************************************/
#define QSER_RESULT_SUCCESS 0
#define QSER_RESULT_FAIL -1

#define MBTK_INFO_ERR_CID_EXIST 311
#define MBTK_INFO_ERR_CID_NO_EXIST 312
#define MBTK_INFO_ERR_NO_APN 500

#define QSER_APN_NUM 8

#define QSER_APN_NAME_MAX_LEN 64
#define QSER_APN_USER_MAX_LEN 32
#define QSER_APN_PAWD_MAX_LEN 32
#define QSER_APN_TYPE_MAX_LEN 16

//default  range: 0 - 7
//AT+CGACT range: 1 - 8
//1 default IDX, 8 IMS IDX
#define QSER_PROFILE_IDX_MIN 1
#define QSER_PROFILE_IDX_MAX 6

/****************************DEFINE***************************************/

/****************************VARIABLE***************************************/
mbtk_info_handle_t* qser_info_handle = NULL;
int qser_info_handle_num = 0;
static bool inited = FALSE;
static qser_data_call_evt_cb_t qser_net_status_cb = NULL;
/****************************VARIABLE***************************************/

/******************************FUNC*****************************************/
static int qser_apn_info_param_convert(int profile_idx, qser_apn_info_s *new_apn, mbtk_qser_apn_info_s *old_apn)
{
    if(new_apn == NULL || old_apn == NULL)
    {
        LOGE("[qser_data] qser_apn_info_param_convert apn param is NULL.");
        return QSER_RESULT_FAIL;
    }

    memset(new_apn, 0x0, sizeof(qser_apn_info_s));
    new_apn->profile_idx = old_apn->cid - 1;
    //get ip type
    if(old_apn->ip_type == MBTK_IP_TYPE_IPV4V6) // IPV4V6
    {
        new_apn->pdp_type = QSER_APN_PDP_TYPE_IPV4V6;
    }
    else if(old_apn->ip_type == MBTK_IP_TYPE_IP) // IPV4
    {
        new_apn->pdp_type = QSER_APN_PDP_TYPE_IPV4;
    }
    else if(old_apn->ip_type == MBTK_IP_TYPE_IPV6) // IPV6
    {
        new_apn->pdp_type = QSER_APN_PDP_TYPE_IPV6;
    }
    else
    {
        new_apn->pdp_type = QSER_APN_PDP_TYPE_PPP;
    }

    //get apn name
    if(strlen((char *)old_apn->apn_name) > QSER_APN_NAME_SIZE)
    {
        LOGE("[qser_data] apn_nmea length verylong.");
        return QSER_RESULT_FAIL;
    }
    else
    {
        if(strlen((char *)old_apn->apn_name) > 0)
        {
            memcpy(new_apn->apn_name, old_apn->apn_name,strlen((char *)old_apn->apn_name));
        }
    }

    //get apn user
    if(strlen((char *)old_apn->user_name) > QSER_APN_USERNAME_SIZE)
    {
        LOGE("[qser_data] apn_user length verylong.");
        return QSER_RESULT_FAIL;
    }
    else
    {
        if(strlen((char *)old_apn->user_name) > 0)
        {
            memcpy(new_apn->username, old_apn->user_name, strlen((char *)old_apn->user_name));
        }
    }

    //get apn password
    if(strlen((char *)old_apn->user_pass) > QSER_APN_PASSWORD_SIZE)
    {
        LOGE("[qser_data] apn_password length verylong.");
        return QSER_RESULT_FAIL;
    }
    else
    {
        if(strlen((char *)old_apn->user_pass) > 0)
        {
            memcpy(new_apn->password, old_apn->user_pass, strlen((char *)old_apn->user_pass));
        }
    }

    //get apn proto
    new_apn->auth_proto = (qser_apn_auth_proto_e)old_apn->auth_proto;

    //get apn type
    if(strlen((char *)old_apn->apn_type) > QSER_APN_PASSWORD_SIZE)
    {
        LOGE("[qser_data] apn_type length verylong.");
        return QSER_RESULT_FAIL;
    }
    else
    {
        if(strlen((char *)old_apn->apn_type) > 0)
        {
            memcpy(new_apn->apn_type, old_apn->apn_type, strlen((char *)old_apn->apn_type));
        }
    }

    return QSER_RESULT_SUCCESS;
}

static void qser_state_init(qser_data_call_state_s *state)
{
    if(state != NULL)
    {
        state->profile_idx = 0;
        memset(state->name, 0x0, 16);
        state->ip_family = QSER_DATA_CALL_TYPE_IPV4V6;
        state->state = QSER_DATA_CALL_DISCONNECTED;
        state->err = QSER_DATA_CALL_ERROR_NONE;
        inet_aton("0.0.0.0", &(state->v4.ip));
        inet_aton("0.0.0.0", &(state->v4.gateway));
        inet_aton("0.0.0.0", &(state->v4.pri_dns));
        inet_aton("0.0.0.0", &(state->v4.sec_dns));
        inet_pton(AF_INET6, "::", &(state->v6.ip));
        inet_pton(AF_INET6, "::", &(state->v6.gateway));
        inet_pton(AF_INET6, "::", &(state->v6.pri_dns));
        inet_pton(AF_INET6, "::", &(state->v6.sec_dns));
    }
}

void qser_wan_net_state_change_cb(const void* data, int data_len)
{
    if(data == NULL || data_len == 0)
    {
        return;
    }

    uint8 *net_data = NULL;
    net_data = (uint8 *)data;

    if(*net_data > 100 && *net_data < 200)
    {
        int idx = *net_data - 101;
        if(idx <= QSER_PROFILE_IDX_MAX)
        {
            qser_data_call_state_s state = {0};
            qser_state_init(&state);
            state.profile_idx = idx;
            state.state = QSER_DATA_CALL_DISCONNECTED;
            if(qser_net_status_cb != NULL)
            {
                qser_net_status_cb(&state);
            }
        }
        else
        {
            LOGE("[qser_data] cb fail,idx is %d.", idx);
        }

    }
    else if(*net_data > 200 && *net_data < 220)
    {
        LOGE("[qser_data] cid[%d] is open.", *net_data - 201);
    }
    else if(*net_data > 220)
    {
        LOGE("[qser_data] cid[%d] is reopen.", *net_data - 221);
        int idx = *net_data - 221;
        if(idx <= QSER_PROFILE_IDX_MAX)
        {
            qser_data_call_state_s state = {0};
            qser_state_init(&state);
            state.profile_idx = idx;
            state.state = QSER_DATA_CALL_CONNECTED;
            snprintf(state.name, 16, "ccinet%d", idx);
            if(qser_net_status_cb != NULL)
            {
                qser_net_status_cb(&state);
            }
        }
    }
    else if(*net_data == 1)
    {
        LOGE("[qser_data] pdp is open.");
    }
    else
    {
        LOGE("[qser_data] unkonwn param [%d].", *net_data);
    }
}

static void* data_call_async_thread(void* arg)
{
    LOGE("[qser_data] entry data_call_async_thread.");
    qser_data_call_error_e err = QSER_DATA_CALL_ERROR_NONE;

    qser_data_call_s qser_data_backup = {0};
    qser_data_call_info_s info = {0};
    if(arg != NULL)
    {
        memcpy(&qser_data_backup, (qser_data_call_s *)arg, sizeof(qser_data_call_s));
    }
    else
    {
        LOGE("[qser_data] arg is NULL.");
    }

    qser_data_call_state_s state = {0};
    qser_state_init(&state);
    state.profile_idx = qser_data_backup.profile_idx;
    snprintf(state.name, 16, "ccinet%d", qser_data_backup.profile_idx);
    state.ip_family = qser_data_backup.ip_family;

    int ret = qser_data_call_start(&qser_data_backup, &err);
    if(ret != QSER_RESULT_SUCCESS)
    {
        LOGE("[qser_data] qser_data_call_start() fail.");
        state.err = err;
    }
    else
    {
        state.state = QSER_DATA_CALL_CONNECTED;
        ret = qser_data_call_info_get(qser_data_backup.profile_idx, qser_data_backup.ip_family, &info, &err);
        if(ret != QSER_RESULT_SUCCESS)
        {
            LOGE("[qser_data] qser_data_call_info_get() fail.");
            state.err = err;
        }
        else
        {
            memcpy(&(state.v4), &(info.v4.addr), sizeof(struct v4_address_status));
            memcpy(&(state.v6), &(info.v6.addr), sizeof(struct v6_address_status));
        }
    }

    if(qser_net_status_cb != NULL)
    {
        qser_net_status_cb(&state);
    }
    return NULL;
}

/******************************FUNC*****************************************/

/****************************API***************************************/
int qser_data_call_init(qser_data_call_evt_cb_t evt_cb)
{
    //UNUSED(evt_cb);
    if(!inited && qser_info_handle == NULL)
    {
        qser_info_handle = mbtk_info_handle_get();
        if(qser_info_handle)
        {
            qser_info_handle_num++;
            inited = TRUE;
            mbtk_pdp_state_change_cb_reg(qser_info_handle, qser_wan_net_state_change_cb);
        }
        else
        {
            LOGE("[qser_data] mbtk_info_handle_get() fail.");
            return QSER_RESULT_FAIL;
        }
    }
    else
    {
        if(!inited)
        {
            qser_info_handle_num++;
            inited = TRUE;
            mbtk_pdp_state_change_cb_reg(qser_info_handle, qser_wan_net_state_change_cb);
        }
    }
    qser_net_status_cb = evt_cb;

    LOGE("[qser_data] mbtk_info_handle_get() success.");
    return QSER_RESULT_SUCCESS;
}

void qser_data_call_destroy(void)
{
    if(qser_info_handle)
    {
        LOGE("[qser_data] qser_info_handle_num = %d", qser_info_handle_num);
        if(qser_info_handle_num == 1)
        { // 最后一个引用，可释放。
            int ret = mbtk_info_handle_free(&qser_info_handle);
            if(ret)
            {
                LOGE("[qser_data] mbtk_info_handle_free() fail.");
            }
            else
            {
                qser_info_handle_num = 0;
                qser_info_handle = NULL;
                qser_net_status_cb = NULL;
                inited = FALSE;
            }
        }
        else
        {
            qser_info_handle_num--;
            qser_net_status_cb = NULL;
        }
    }
    else
    {
        LOGE("[qser_data] handle not inited.");
    }
}

int qser_data_call_start(qser_data_call_s *data_call, qser_data_call_error_e *err)
{
    //UNUSED(data_call);
    //UNUSED(err);
    if(data_call == NULL || err == NULL)
    {
        LOGE("[qser_data] data_call or err is NULL.");
        if(err != NULL)
        {
            *err = QSER_DATA_CALL_ERROR_INVALID_PARAMS;
        }
        return QSER_RESULT_FAIL;
    }

    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        *err = QSER_DATA_CALL_ERROR_NO_INIT;
        return QSER_RESULT_FAIL;
    }

    int ret = -1;
    ret = mbtk_data_call_start(qser_info_handle, data_call->profile_idx + 1, 0, FALSE, 0);
    if(ret != 0)
    {
        LOGE("[qser_data] mbtk_data_call_start fail.[ret = %d]", ret);
        if(ret == MBTK_INFO_ERR_CID_EXIST)
        {
            *err = QSER_DATA_CALL_ERROR_PDP_ACTIVATE;
        }
        else
        {
            *err = QSER_DATA_CALL_ERROR_UNKNOWN;
        }
        return QSER_RESULT_FAIL;
    }
    else
    {
        *err = QSER_DATA_CALL_ERROR_NONE;
    }

    return QSER_RESULT_SUCCESS;
}

int qser_data_call_start_async(qser_data_call_s *data_call, qser_data_call_error_e *err)
{
    //UNUSED(data_call);
    UNUSED(err);
    if(data_call == NULL || err == NULL)
    {
        LOGE("[qser_data] data_call or err is NULL.");
        if(err != NULL)
        {
            *err = QSER_DATA_CALL_ERROR_INVALID_PARAMS;
        }
        return QSER_RESULT_FAIL;
    }

    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        *err = QSER_DATA_CALL_ERROR_NO_INIT;
        return QSER_RESULT_FAIL;
    }

    pthread_attr_t thread_attr;
    pthread_t data_call_thread_id;
    pthread_attr_init(&thread_attr);
    if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
    {
        LOGE("[qser_data] pthread_attr_setdetachstate() fail.");
        *err = QSER_DATA_CALL_ERROR_UNKNOWN;
        return QSER_RESULT_FAIL;
    }

    //memcpy(&qser_data_backup, data_call, sizeof(qser_data_call_s));
    if(pthread_create(&data_call_thread_id, &thread_attr, data_call_async_thread, (void *) data_call))
    {
        LOGE("[qser_data] pthread_create() fail.");
        *err = QSER_DATA_CALL_ERROR_UNKNOWN;
        return QSER_RESULT_FAIL;
    }
    pthread_attr_destroy(&thread_attr);

    return QSER_RESULT_SUCCESS;
}

int qser_data_call_stop(char profile_idx, qser_data_call_ip_family_e ip_family, qser_data_call_error_e *err)
{
    //UNUSED(profile_idx);
    UNUSED(ip_family);
    //UNUSED(err);
    if(err == NULL)
    {
        LOGE("[qser_data] err is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        *err = QSER_DATA_CALL_ERROR_NO_INIT;
        return QSER_RESULT_FAIL;
    }

    int ret = -1;
    ret = mbtk_data_call_stop(qser_info_handle, profile_idx + 1, 15);
    if(ret != 0)
    {
        LOGE("[qser_data] mbtk_data_call_stop fail.[ret = %d]", ret);
        if(ret == MBTK_INFO_ERR_CID_NO_EXIST)
        {
            *err = QSER_DATA_CALL_ERROR_PDP_NO_ACTIVATE;
        }
        else
        {
            *err = QSER_DATA_CALL_ERROR_UNKNOWN;
        }
        return QSER_RESULT_FAIL;
    }
    else
    {
        *err = QSER_DATA_CALL_ERROR_NONE;
    }

    return QSER_RESULT_SUCCESS;
}

int qser_data_call_info_get(char profile_idx,qser_data_call_ip_family_e ip_family,
        qser_data_call_info_s *info, qser_data_call_error_e *err)
{
    //UNUSED(profile_idx);
    UNUSED(ip_family);
    //UNUSED(info);
    //UNUSED(err);

    if(info == NULL || err == NULL)
    {
        LOGE("[qser_data] info or err is NULL.");
        if(err != NULL)
        {
            *err = QSER_DATA_CALL_ERROR_INVALID_PARAMS;
        }
        return QSER_RESULT_FAIL;
    }

    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        *err = QSER_DATA_CALL_ERROR_NO_INIT;
        return QSER_RESULT_FAIL;
    }

    int ret = -1;
    mbtk_ipv4_info_t ipv4;
    mbtk_ipv6_info_t ipv6;
#ifdef QSER_TEST
    char v4_buff[32] = {0};
    char v6_buff[128] = {0};
#endif
    memset(info, 0, sizeof(qser_data_call_info_s));
    ret = mbtk_data_call_state_get(qser_info_handle, profile_idx + 1, &ipv4, &ipv6);
    if(ret != 0)
    {
        LOGE("[qser_data] mbtk_data_call_state_get fail.[ret = %d]", ret);
        if(ret == MBTK_INFO_ERR_CID_NO_EXIST)
        {
            *err = QSER_DATA_CALL_ERROR_PDP_NO_ACTIVATE;
        }
        else
        {
            *err = QSER_DATA_CALL_ERROR_UNKNOWN;
        }
        return QSER_RESULT_FAIL;
    }
    else
    {
        info->profile_idx = profile_idx;
        if(ipv4.valid)
        {
            info->ip_family = QSER_DATA_CALL_TYPE_IPV4;
            info->v4.state = QSER_DATA_CALL_CONNECTED;
            sprintf(info->v4.name, "ccinet%d", profile_idx);
            info->v4.addr.ip.s_addr = ipv4.IPAddr;
            info->v4.addr.pri_dns.s_addr = ipv4.PrimaryDNS;
            info->v4.addr.sec_dns.s_addr = ipv4.SecondaryDNS;
            info->v4.reconnect = 1;

#ifdef QSER_TEST
            //LOGE("[qser_data] IP: %x pri_DNS: %x sec_DNS: %x.", ipv4.IPAddr, ipv4.PrimaryDNS, ipv4.SecondaryDNS);
            if(inet_ntop(AF_INET, &(info->v4.addr.ip), v4_buff, 32) == NULL) {
                LOGE("[qser_data] IP error.");
            } else {
                LOGE("[qser_data] IP : %s", v4_buff);
            }
            if(inet_ntop(AF_INET, &(info->v4.addr.pri_dns), v4_buff, 32) == NULL) {
                LOGE("[qser_data] PrimaryDNS error.");
            } else {
                LOGE("[qser_data] PrimaryDNS : %s", v4_buff);
            }
            if(inet_ntop(AF_INET, &(info->v4.addr.sec_dns), v4_buff, 32) == NULL) {
                LOGE("[qser_data] SecondaryDNS error.");
            } else {
                LOGE("[qser_data] SecondaryDNS : %s", v4_buff);
            }
#endif
        }

        if(ipv6.valid)
        {
            info->ip_family = QSER_DATA_CALL_TYPE_IPV6;
            info->v6.state = QSER_DATA_CALL_CONNECTED;
            sprintf(info->v6.name, "ccinet%d", profile_idx);
            memcpy(&(info->v6.addr.ip), &(ipv6.IPV6Addr), sizeof(ipv6.IPV6Addr));
            memcpy(&(info->v6.addr.pri_dns), &(ipv6.PrimaryDNS), sizeof(ipv6.PrimaryDNS));
            memcpy(&(info->v6.addr.sec_dns), &(ipv6.SecondaryDNS), sizeof(ipv6.SecondaryDNS));
            info->v6.reconnect = 1;

#ifdef QSER_TEST
			if(ipv6_2_str(&(info->v6.addr.ip), v6_buff))
            {
				LOGE("[qser_data] IP error.");
			} else {
				LOGE("[qser_data] IP : %s", v6_buff);
			}
			if(ipv6_2_str(&(info->v6.addr.pri_dns), v6_buff))
            {
				LOGE("[qser_data] PrimaryDNS error.");
			} else {
				LOGE("[qser_data] PrimaryDNS : %s", v6_buff);
			}
			if(ipv6_2_str(&(info->v6.addr.sec_dns), v6_buff))
            {
				LOGE("[qser_data] SecondaryDNS error.");
			} else {
				LOGE("[qser_data] SecondaryDNS : %s", v6_buff);
            }
#endif
        }

        if(ipv4.valid && ipv6.valid)
        {
            info->ip_family = QSER_DATA_CALL_TYPE_IPV4V6;
        }

        if(!ipv4.valid && !ipv6.valid)
        {
            info->v4.state = QSER_DATA_CALL_DISCONNECTED;
            info->v6.state = QSER_DATA_CALL_DISCONNECTED;
        }
    }

    *err = QSER_DATA_CALL_ERROR_NONE;
    return QSER_RESULT_SUCCESS;
}

int qser_apn_set(qser_apn_info_s *apn)
{
    //UNUSED(apn);
    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(apn == NULL)
    {
        LOGE("[qser_data] apn param is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(strlen(apn->apn_name) > QSER_APN_NAME_MAX_LEN || strlen(apn->username) > QSER_APN_USER_MAX_LEN
               || strlen(apn->password) > QSER_APN_PAWD_MAX_LEN  || strlen(apn->apn_type) > QSER_APN_TYPE_MAX_LEN)
    {
        LOGE("[qser_data] apn length out of range.");
        return QSER_RESULT_FAIL;
    }

    int ret = 0;
    mbtk_qser_apn_info_s apninfo;
    memset(&apninfo, 0x0, sizeof(mbtk_qser_apn_info_s));
    apninfo.cid = apn->profile_idx + 1;

    if(apn->pdp_type == QSER_APN_PDP_TYPE_IPV4)
    {
        apninfo.ip_type = MBTK_IP_TYPE_IP;
    }
    else if(apn->pdp_type == QSER_APN_PDP_TYPE_IPV6)
    {
        apninfo.ip_type = MBTK_IP_TYPE_IPV6;
    }
    else if(apn->pdp_type == QSER_APN_PDP_TYPE_IPV4V6)
    {
        apninfo.ip_type = MBTK_IP_TYPE_IPV4V6;
    }
    else if(apn->pdp_type == QSER_APN_PDP_TYPE_PPP)
    {
        apninfo.ip_type = MBTK_IP_TYPE_PPP;
    }
    else
    {
        LOGE("[qser_data] pdp_type error.");
        return QSER_RESULT_FAIL;
    }


    apninfo.req_type = MBTK_APN_REQ_TYPE_SET;
    apninfo.auth_proto = (mbtk_apn_auth_proto_enum)apn->auth_proto;
    if(strlen(apn->apn_name))
    {
        memcpy(apninfo.apn_name, apn->apn_name, strlen(apn->apn_name));
    }
    else
    {
        LOGE("[qser_data] apn_name is NULL.");
        return QSER_RESULT_FAIL;
    }
    if(strlen(apn->username))
    {
        memcpy(apninfo.user_name, apn->username, strlen(apn->username));
    }
    if(strlen(apn->password))
    {
        memcpy(apninfo.user_pass, apn->password, strlen(apn->password));
    }
    if(strlen(apn->apn_type))
    {
        memcpy(apninfo.apn_type, apn->apn_type, strlen(apn->apn_type));
    }
    ret = mbtk_qser_apn_set(qser_info_handle, &apninfo, NULL);
    if(ret != 0)
    {
        LOGE("[qser_data] mbtk_qser_apn_set fail.");
        return QSER_RESULT_FAIL;
    }

    return QSER_RESULT_SUCCESS;
}

int qser_apn_get(unsigned char profile_idx, qser_apn_info_s *apn)
{
    //UNUSED(profile_idx);
    //UNUSED(apn);
    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(apn == NULL)
    {
        LOGE("[qser_data] apn param is NULL.");
        return QSER_RESULT_FAIL;
    }

    //get apn info
    mbtk_qser_apn_info_s apns[10] = {0};
    int apn_num = 10;
    int ret = mbtk_qser_apn_get(qser_info_handle, &apn_num, apns);
    if(ret != 0)
    {
        LOGE("[qser_data] mbtk_apn_get fail. [ret = %d]",ret);
        return QSER_RESULT_FAIL;
    }
    else
    {
        int i = 0;
        for(i = 0; i < apn_num; i++)
        {
            if(apns[i].cid == profile_idx + 1)
            {
                LOGE("[qser_data] find IDX.");
                break;
            }
        }

        if(i == apn_num)
        {
            LOGE("[qser_data] not find IDX.[apn_num = %d]", apn_num);
            return QSER_RESULT_FAIL;
        }

        if(qser_apn_info_param_convert(profile_idx, apn, &apns[i]) != 0)
        {
            LOGE("[qser_data] qser_apn_info_param_convert fail");
            return QSER_RESULT_FAIL;
        }
    }
    return QSER_RESULT_SUCCESS;
}

int qser_apn_add(qser_apn_add_s *apn, unsigned char *profile_idx)
{
    //UNUSED(apn);
    //UNUSED(profile_idx);
    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(apn == NULL || profile_idx == NULL)
    {
        LOGE("[qser_data] apn param is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(strlen(apn->apn_name) > QSER_APN_NAME_MAX_LEN || strlen(apn->username) > QSER_APN_USER_MAX_LEN
               || strlen(apn->password) > QSER_APN_PAWD_MAX_LEN  || strlen(apn->apn_type) > QSER_APN_TYPE_MAX_LEN)
    {
        LOGE("[qser_data] apn length out of range.");
        return QSER_RESULT_FAIL;
    }

    int ret = 0;
    unsigned char idx[2] = {0};
    mbtk_qser_apn_info_s apninfo;
    memset(&apninfo, 0x0, sizeof(mbtk_qser_apn_info_s));
    apninfo.cid = 0;

    if(apn->pdp_type == QSER_APN_PDP_TYPE_IPV4)
    {
        apninfo.ip_type = MBTK_IP_TYPE_IP;
    }
    else if(apn->pdp_type == QSER_APN_PDP_TYPE_IPV6)
    {
        apninfo.ip_type = MBTK_IP_TYPE_IPV6;
    }
    else if(apn->pdp_type == QSER_APN_PDP_TYPE_IPV4V6)
    {
        apninfo.ip_type = MBTK_IP_TYPE_IPV4V6;
    }
    else if(apn->pdp_type == QSER_APN_PDP_TYPE_PPP)
    {
        apninfo.ip_type = MBTK_IP_TYPE_PPP;
    }
    else
    {
        LOGE("[qser_data] pdp_type error.");
        return QSER_RESULT_FAIL;
    }

    apninfo.req_type = MBTK_APN_REQ_TYPE_ADD;
    apninfo.auth_proto = (mbtk_apn_auth_proto_enum)apn->auth_proto;
    if(strlen(apn->apn_name))
    {
        memcpy(apninfo.apn_name, apn->apn_name, strlen(apn->apn_name));
    }

    if(strlen(apn->username))
    {
        memcpy(apninfo.user_name, apn->username, strlen(apn->username));
    }
    if(strlen(apn->password))
    {
        memcpy(apninfo.user_pass, apn->password, strlen(apn->password));
    }
    if(strlen(apn->apn_type))
    {
        memcpy(apninfo.apn_type, apn->apn_type, strlen(apn->apn_type));
    }
    ret = mbtk_qser_apn_set(qser_info_handle, &apninfo, idx);
    if(ret != 0)
    {
        LOGE("[qser_data] mbtk_qser_apn_set fail.");
        return QSER_RESULT_FAIL;
    }
    *profile_idx = idx[0] - 1;
    return QSER_RESULT_SUCCESS;
}

int qser_apn_del(unsigned char profile_idx)
{
    int ret = 0;
    qser_apn_info_s qser_apn = {0};

    //UNUSED(profile_idx);
    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        return QSER_RESULT_FAIL;
    }

    ret = qser_apn_get(profile_idx, &qser_apn);
    if (ret < 0)
    {
        LOGE("[qser_data] mbtk_apn_del idx no find!");
        return QSER_RESULT_FAIL;
    }

    ret = mbtk_apn_del(qser_info_handle, profile_idx);
    if(ret < 0)
    {
        LOGE("[qser_data] mbtk_apn_del fail!");
        return QSER_RESULT_FAIL;
    }
    return QSER_RESULT_SUCCESS;
}

int qser_apn_get_list(qser_apn_info_list_s *apn_list)
{
    //UNUSED(apn_list);

    if(qser_info_handle == NULL)
    {
        LOGE("[qser_data] handle is NULL.");
        return QSER_RESULT_FAIL;
    }

    if(apn_list == NULL)
    {
        LOGE("[qser_data] apn_list param is NULL.");
        return QSER_RESULT_FAIL;
    }

    mbtk_qser_apn_info_s apns[10] = {0};
    int apn_num = 10;
    int ret = mbtk_qser_apn_get(qser_info_handle, &apn_num, apns);
    if(ret != 0)
    {
        if(ret == MBTK_INFO_ERR_NO_APN)
        {
            apn_list->cnt = 0;
            return QSER_RESULT_SUCCESS;
        }
        LOGE("[qser_data] mbtk_apn_get fail. [ret = %d]",ret);
        return QSER_RESULT_FAIL;
    }
    else
    {
        if(apn_num > 0 && apn_num <= QSER_APN_MAX_LIST)
        {
            int i = 0;
            apn_list->cnt = 0;
            for(i = 0; i < apn_num; i++)
            {
                if(qser_apn_info_param_convert(apns[i].cid - 1, &apn_list->apn[apn_list->cnt], &apns[i]) != 0)
                {
                    LOGE("[qser_data] qser_apn_info_param_convert fail");
                    return QSER_RESULT_FAIL;
                }
                apn_list->cnt++;
            }
        }
        else if(apn_num > QSER_APN_MAX_LIST)
        {
            LOGE("[qser_data] apn_num overlong");
            return QSER_RESULT_FAIL;
        }
        else
        {
            apn_list->cnt = 0;
        }
    }
    return QSER_RESULT_SUCCESS;
}
/****************************API***************************************/

