| #include <stdio.h> | 
 | #include <stdint.h> | 
 | #include <sys/types.h> | 
 | #include <arpa/inet.h> | 
 | #include <string.h> | 
 | #include <stdlib.h> | 
 | #include <unistd.h> | 
 | #include <log/log.h> | 
 | #include <libdata/lynq_data.h> | 
 | #include <liblog/lynq_deflog.h> | 
 | #include <pthread.h> | 
 | #include <libxml/tree.h> | 
 | #include <libxml/parser.h> | 
 | #include "lynq-qser-data.h" | 
 |  | 
 | #define USER_LOG_TAG "LYNQ_QSER_DATA" | 
 |  | 
 | #define RESULT_OK (0) | 
 | #define RESULT_ERROR (-1) | 
 |  | 
 | static pthread_t s_cb_tid = -1; | 
 | static int s_qser_data_cb_thread_status = 0; | 
 | static pthread_mutex_t s_qser_data_cb_mutex = PTHREAD_MUTEX_INITIALIZER; | 
 | static pthread_cond_t s_qser_data_cb_cond = PTHREAD_COND_INITIALIZER; | 
 |  | 
 | #define data_xml_path "/data/lynq_qser_data_apn.xml" | 
 |  | 
 | static qser_data_call_evt_cb_t s_data_call_cb = NULL; | 
 | const int apndb_offset = 683; | 
 |  | 
 | void lynq_ipv4_aton_urc(lynq_data_call_response_v11_t *libdata,qser_data_call_state_s *data_res) | 
 | { | 
 |     inet_aton(libdata->addresses,&(data_res->v4.ip)); | 
 |     inet_aton(libdata->gateways,&(data_res->v4.gateway)); | 
 |     inet_aton(libdata->dnses,&(data_res->v4.pri_dns)); | 
 |     inet_aton(libdata->dnses,&(data_res->v4.sec_dns)); | 
 |     return ; | 
 | } | 
 |  | 
 | void lynq_ipv6_inet_pton_urc(lynq_data_call_response_v11_t *libdata,qser_data_call_state_s *data_res) | 
 | { | 
 |     inet_pton(AF_INET6,libdata->addresses,&(data_res->v6.ip)); | 
 |     inet_pton(AF_INET6,libdata->gateways,&(data_res->v6.gateway)); | 
 |     inet_pton(AF_INET6,libdata->dnses,&(data_res->v6.pri_dns)); | 
 |     inet_pton(AF_INET6,libdata->dnses,&(data_res->v6.sec_dns)); | 
 |     return ; | 
 | } | 
 |  | 
 | void lynq_ipv4_aton_getinfo(lynq_data_call_response_v11_t *libdata,qser_data_call_info_s *data_res) | 
 | { | 
 |     inet_aton(libdata->addresses,&(data_res->v4.addr.ip)); | 
 |     inet_aton(libdata->gateways,&(data_res->v4.addr.gateway)); | 
 |     inet_aton(libdata->dnses,&(data_res->v4.addr.pri_dns)); | 
 |     inet_aton(libdata->dnses,&(data_res->v4.addr.sec_dns)); | 
 |     data_res->v4.stats.pkts_tx = 0; | 
 |     data_res->v4.stats.pkts_rx = 0; | 
 |     data_res->v4.stats.bytes_tx = 0; | 
 |     data_res->v4.stats.bytes_rx = 0; | 
 |     data_res->v4.stats.pkts_dropped_tx = 0; | 
 |     data_res->v4.stats.pkts_dropped_rx = 0; | 
 |     return ; | 
 | } | 
 |  | 
 | void lynq_ipv6_inet_pton_getinfo(lynq_data_call_response_v11_t *libdata,qser_data_call_info_s *data_res) | 
 | { | 
 |     inet_pton(AF_INET6,libdata->addresses,&(data_res->v6.addr.ip)); | 
 |     inet_pton(AF_INET6,libdata->gateways,&(data_res->v6.addr.gateway)); | 
 |     inet_pton(AF_INET6,libdata->dnses,&(data_res->v6.addr.pri_dns)); | 
 |     inet_pton(AF_INET6,libdata->dnses,&(data_res->v6.addr.sec_dns)); | 
 |     data_res->v6.stats.pkts_tx = 0; | 
 |     data_res->v6.stats.pkts_rx = 0; | 
 |     data_res->v6.stats.bytes_tx = 0; | 
 |     data_res->v6.stats.bytes_rx = 0; | 
 |     data_res->v6.stats.pkts_dropped_tx = 0; | 
 |     data_res->v6.stats.pkts_dropped_rx = 0; | 
 |     return ; | 
 | } | 
 |  | 
 | void datacall_ipv4_status_judge(int state,qser_data_call_info_s *data_res) | 
 | { | 
 |     if (state != 0) | 
 |     { | 
 |         data_res->v4.state = QSER_DATA_CALL_CONNECTED; | 
 |         data_res->v4.reconnect = 1; | 
 |     } | 
 |     else | 
 |     { | 
 |         data_res->v4.state = QSER_DATA_CALL_DISCONNECTED; | 
 |         data_res->v4.reconnect = 0; | 
 |     } | 
 |     return ; | 
 | } | 
 |  | 
 | void datacall_ipv6_status_judge(int state,qser_data_call_info_s *data_res) | 
 | { | 
 |     if (state != 0) | 
 |     { | 
 |         data_res->v6.state = QSER_DATA_CALL_CONNECTED; | 
 |         data_res->v6.reconnect = 1; | 
 |     } | 
 |     else | 
 |     { | 
 |         data_res->v6.state = QSER_DATA_CALL_DISCONNECTED; | 
 |         data_res->v6.reconnect = 0; | 
 |     } | 
 |     return ; | 
 | } | 
 |  | 
 |  | 
 | int apn_xml_add(qser_apn_add_s *apn,unsigned char *apn_num) | 
 | { | 
 |     int node_num = 0; | 
 |     char temp_buff[12]; | 
 |     xmlDocPtr pdoc = NULL; | 
 |     xmlNodePtr node = NULL; | 
 |     xmlNodePtr tmp_node = NULL; | 
 |     xmlNodePtr sum_node = NULL; | 
 |     pdoc = xmlReadFile(data_xml_path ,"UTF-8",XML_PARSE_RECOVER); | 
 |     if(NULL == pdoc) | 
 |     { | 
 |         LYERRLOG("open xml file error"); | 
 |         goto FAILED; | 
 |     } | 
 |      | 
 |     node = xmlDocGetRootElement(pdoc); | 
 |     if (NULL == node) | 
 |     { | 
 |         LYERRLOG("xmlDocGetRootElement() error"); | 
 |         goto FAILED; | 
 |     } | 
 |     sum_node = node->xmlChildrenNode; | 
 |     sum_node = sum_node->next; | 
 |     while (sum_node != NULL) | 
 |     { | 
 |         if (xmlGetProp(sum_node, "profile_idx") == NULL)  //Null Node | 
 |         { | 
 |             sum_node = sum_node->next; | 
 |             continue; | 
 |         } | 
 |         node_num++; | 
 |         sum_node = sum_node->next; | 
 |     } | 
 |     tmp_node = xmlNewNode(NULL,BAD_CAST"apn"); | 
 |     *apn_num = node_num; | 
 |     LYERRLOG("apn_num%d ",node_num); | 
 |     bzero(temp_buff,12); | 
 |     snprintf(temp_buff,sizeof(temp_buff),"%d",*apn_num); | 
 |     xmlNewProp(tmp_node,BAD_CAST"profile_idx",(xmlChar *)temp_buff); | 
 |     bzero(temp_buff,12); | 
 |     snprintf(temp_buff,sizeof(temp_buff),"%d",apn->pdp_type); | 
 |     xmlNewProp(tmp_node,BAD_CAST"pdp_type",(xmlChar *)temp_buff); | 
 |     bzero(temp_buff,12); | 
 |     snprintf(temp_buff,sizeof(temp_buff),"%d",apn->auth_proto); | 
 |     xmlNewProp(tmp_node,BAD_CAST"auth_proto",(xmlChar *)temp_buff); | 
 |     xmlNewProp(tmp_node,BAD_CAST"apn_name",(xmlChar *)apn->apn_name); | 
 |     xmlNewProp(tmp_node,BAD_CAST"username",(xmlChar *)apn->username); | 
 |     xmlNewProp(tmp_node,BAD_CAST"password",(xmlChar *)apn->password); | 
 |     xmlNewProp(tmp_node,BAD_CAST"apn_type",(xmlChar *)apn->apn_type); | 
 |     xmlAddChild(node,tmp_node); | 
 |     xmlSaveFormatFileEnc(data_xml_path, pdoc, "UTF-8", 1); | 
 |     xmlFreeDoc(pdoc); | 
 |     return RESULT_OK; | 
 |      | 
 |     FAILED: | 
 |     if (pdoc) | 
 |     { | 
 |         xmlFreeDoc(pdoc); | 
 |     } | 
 |     return RESULT_ERROR; | 
 | } | 
 |  | 
 | int apn_xml_delete(unsigned char profile_idx) | 
 | { | 
 |     int node_num = 0; | 
 |     char temp_buff[12]; | 
 |     xmlDocPtr pdoc = NULL; | 
 |     xmlNodePtr node = NULL; | 
 |     xmlNodePtr modify_node = NULL; | 
 |     pdoc = xmlReadFile(data_xml_path ,"UTF-8",XML_PARSE_RECOVER); | 
 |     if(NULL == pdoc) | 
 |     { | 
 |         LYERRLOG("open xml file error"); | 
 |         goto FAILED; | 
 |     } | 
 |      | 
 |     node = xmlDocGetRootElement(pdoc); | 
 |     if (NULL == node) | 
 |     { | 
 |         LYERRLOG("xmlDocGetRootElement() error"); | 
 |         goto FAILED; | 
 |     } | 
 |     modify_node = node->xmlChildrenNode; | 
 |     modify_node = modify_node->next; | 
 |     for (node_num=0 ;node_num<(int)profile_idx ; node_num++) | 
 |     { | 
 |         if (xmlGetProp(modify_node, "profile_idx") == NULL)  //Null Node | 
 |         { | 
 |             modify_node = modify_node->next; | 
 |             node_num--; | 
 |             continue; | 
 |         } | 
 |         modify_node = modify_node->next; | 
 |     } | 
 |     xmlUnlinkNode(modify_node); | 
 |     xmlFreeNode(modify_node); | 
 |     modify_node = NULL; | 
 |     node_num = 0; | 
 |     modify_node = node->xmlChildrenNode; | 
 |     modify_node = modify_node->next; | 
 |     while (modify_node != NULL) | 
 |     { | 
 |         if (xmlGetProp(modify_node, "profile_idx") == NULL)  //Null Node | 
 |         { | 
 |             modify_node = modify_node->next; | 
 |             continue; | 
 |         } | 
 |         bzero(temp_buff,12); | 
 |         snprintf(temp_buff,sizeof(temp_buff),"%d",node_num); | 
 |         xmlSetProp(modify_node,BAD_CAST"profile_idx",(xmlChar *)temp_buff); | 
 |         modify_node = modify_node->next; | 
 |         node_num++; | 
 |     } | 
 |     xmlSaveFormatFileEnc(data_xml_path, pdoc, "UTF-8", 1); | 
 |     xmlFreeDoc(pdoc); | 
 |     return RESULT_OK; | 
 |  | 
 |     FAILED: | 
 |     if (pdoc) | 
 |     { | 
 |         xmlFreeDoc(pdoc); | 
 |     } | 
 |     return RESULT_ERROR; | 
 | } | 
 |  | 
 | int apn_xml_modify(qser_apn_info_s *apn) | 
 | { | 
 |     int node_num = 0; | 
 |     char temp_buff[12]; | 
 |     xmlDocPtr pdoc = NULL; | 
 |     xmlNodePtr node = NULL; | 
 |     xmlNodePtr modify_node = NULL; | 
 |     pdoc = xmlReadFile(data_xml_path ,"UTF-8",XML_PARSE_RECOVER); | 
 |     if(NULL == pdoc) | 
 |     { | 
 |         LYERRLOG("open xml file error"); | 
 |         goto FAILED; | 
 |     } | 
 |      | 
 |     node = xmlDocGetRootElement(pdoc); | 
 |     if (NULL == node) | 
 |     { | 
 |         LYERRLOG("xmlDocGetRootElement() error"); | 
 |         goto FAILED; | 
 |     } | 
 |     modify_node = node->xmlChildrenNode; | 
 |     modify_node = modify_node->next; | 
 |     for (node_num=0; node_num<(int)apn->profile_idx;node_num++) | 
 |     { | 
 |         if (xmlGetProp(modify_node, "profile_idx") == NULL)  //Null Node | 
 |         { | 
 |             modify_node = modify_node->next; | 
 |             node_num--; | 
 |             continue; | 
 |         } | 
 |         modify_node = modify_node->next; | 
 |     } | 
 |     bzero(temp_buff,12); | 
 |     snprintf(temp_buff,sizeof(temp_buff),"%d",node_num); | 
 |     xmlSetProp(modify_node,BAD_CAST"profile_idx",(xmlChar *)temp_buff); | 
 |     bzero(temp_buff,12); | 
 |     snprintf(temp_buff,sizeof(temp_buff),"%d",apn->pdp_type); | 
 |     xmlSetProp(modify_node,BAD_CAST"pdp_type",(xmlChar *)temp_buff); | 
 |     bzero(temp_buff,12); | 
 |     snprintf(temp_buff,sizeof(temp_buff),"%d",apn->auth_proto); | 
 |     xmlSetProp(modify_node,BAD_CAST"auth_proto",(xmlChar *)temp_buff); | 
 |     xmlSetProp(modify_node,BAD_CAST"apn_name",(xmlChar *)apn->apn_name); | 
 |     xmlSetProp(modify_node,BAD_CAST"username",(xmlChar *)apn->username); | 
 |     xmlSetProp(modify_node,BAD_CAST"password",(xmlChar *)apn->password); | 
 |     xmlSetProp(modify_node,BAD_CAST"apn_type",(xmlChar *)apn->apn_type); | 
 |     xmlSaveFormatFileEnc(data_xml_path, pdoc, "UTF-8", 1); | 
 |     xmlFreeDoc(pdoc); | 
 |     return RESULT_OK; | 
 |  | 
 |     FAILED: | 
 |     if (pdoc) | 
 |     { | 
 |         xmlFreeDoc(pdoc); | 
 |     } | 
 |     return RESULT_ERROR; | 
 | } | 
 |  | 
 |  | 
 | int apn_xml_query(unsigned char profile_idx,qser_apn_info_s *apn) | 
 | { | 
 |     int node_num = 0; | 
 |     xmlDocPtr pdoc = NULL; | 
 |     xmlNodePtr node = NULL; | 
 |     xmlNodePtr modify_node = NULL; | 
 |     unsigned char temp = NULL; | 
 |     pdoc = xmlReadFile(data_xml_path ,"UTF-8",XML_PARSE_RECOVER); | 
 |     if(NULL == pdoc) | 
 |     { | 
 |         LYERRLOG("open xml file error"); | 
 |         goto FAILED; | 
 |     } | 
 |      | 
 |     node = xmlDocGetRootElement(pdoc); | 
 |     if (NULL == node) | 
 |     { | 
 |         LYERRLOG("xmlDocGetRootElement() error"); | 
 |         goto FAILED; | 
 |     } | 
 |     modify_node = node->xmlChildrenNode; | 
 |     modify_node = modify_node->next; | 
 |     for (node_num = 0;node_num<(int)profile_idx;node_num++) | 
 |     { | 
 |         if (xmlGetProp(modify_node, "profile_idx") == NULL)  //Null Node | 
 |         { | 
 |             modify_node = modify_node->next; | 
 |             node_num--; | 
 |             continue; | 
 |         } | 
 |         modify_node = modify_node->next; | 
 |     } | 
 |     apn->profile_idx = (unsigned char)atoi(xmlGetProp(modify_node, "profile_idx")); | 
 |     apn->pdp_type = (qser_apn_pdp_type_e)atoi(xmlGetProp(modify_node, "pdp_type")); | 
 |     apn->auth_proto = (qser_apn_auth_proto_e)atoi(xmlGetProp(modify_node, "auth_proto")); | 
 |     strcpy(apn->apn_name,(char *)xmlGetProp(modify_node, "apn_name")); | 
 |     strcpy(apn->username,(char *)xmlGetProp(modify_node, "username")); | 
 |     strcpy(apn->password,(char *)xmlGetProp(modify_node, "password")); | 
 |     strcpy(apn->apn_type,(char *)xmlGetProp(modify_node, "apn_type")); | 
 |     xmlSaveFormatFileEnc(data_xml_path, pdoc, "UTF-8", 1); | 
 |     xmlFreeDoc(pdoc); | 
 |     return RESULT_OK; | 
 |  | 
 |     FAILED: | 
 |     if (pdoc) | 
 |     { | 
 |         xmlFreeDoc(pdoc); | 
 |     } | 
 |     return RESULT_ERROR; | 
 | } | 
 |  | 
 | int apn_xml_query_list(qser_apn_info_list_s *apn_list) | 
 | { | 
 |     int node_num = 0; | 
 |     xmlDocPtr pdoc = NULL; | 
 |     xmlNodePtr node = NULL; | 
 |     xmlNodePtr modify_node = NULL; | 
 |     xmlChar *temp_char; | 
 |     char temp[64]; | 
 |     pdoc = xmlReadFile(data_xml_path ,"UTF-8",XML_PARSE_RECOVER); | 
 |     if(NULL == pdoc) | 
 |     { | 
 |         LYERRLOG("open xml file error"); | 
 |         goto FAILED; | 
 |     } | 
 |      | 
 |     node = xmlDocGetRootElement(pdoc); | 
 |     if (NULL == node) | 
 |     { | 
 |         LYERRLOG("xmlDocGetRootElement() error"); | 
 |         goto FAILED; | 
 |     } | 
 |     modify_node = node->xmlChildrenNode; | 
 |     modify_node = modify_node->next; | 
 |     while (modify_node != NULL) | 
 |     { | 
 |         temp_char = xmlGetProp(modify_node, "profile_idx"); | 
 |         if (temp_char == NULL)  | 
 |         { | 
 |             modify_node = modify_node->next; | 
 |             continue; | 
 |         } | 
 |         sprintf(temp,"%s",temp_char); | 
 |         apn_list->apn[node_num].profile_idx = (unsigned char)atoi(temp); | 
 |         apn_list->apn[node_num].pdp_type = (qser_apn_pdp_type_e)atoi(xmlGetProp(modify_node, "pdp_type")); | 
 |         apn_list->apn[node_num].auth_proto = (qser_apn_auth_proto_e)atoi(xmlGetProp(modify_node, "auth_proto")); | 
 |         strcpy(apn_list->apn[node_num].apn_name,(char *)xmlGetProp(modify_node, "apn_name")); | 
 |         strcpy(apn_list->apn[node_num].username,(char *)xmlGetProp(modify_node, "username")); | 
 |         strcpy(apn_list->apn[node_num].password,(char *)xmlGetProp(modify_node, "password")); | 
 |         node_num ++; | 
 |         modify_node = modify_node->next; | 
 |     } | 
 |     apn_list->cnt = node_num; | 
 |     xmlSaveFormatFileEnc(data_xml_path, pdoc, "UTF-8", 1); | 
 |     xmlFreeDoc(pdoc); | 
 |     return RESULT_OK; | 
 |  | 
 |     FAILED: | 
 |     if (pdoc) | 
 |     { | 
 |         xmlFreeDoc(pdoc); | 
 |     } | 
 |     return RESULT_ERROR; | 
 | } | 
 |  | 
 | void judge_pdp_type(qser_apn_pdp_type_e pdp_type,char *out_pdp_type) | 
 | { | 
 |     switch (pdp_type) | 
 |     { | 
 |     case QSER_APN_PDP_TYPE_IPV4: | 
 |         strcpy(out_pdp_type,"IPV4"); | 
 |         break; | 
 |     case QSER_APN_PDP_TYPE_PPP: | 
 |         strcpy(out_pdp_type,"PPP"); | 
 |         break; | 
 |     case QSER_APN_PDP_TYPE_IPV6: | 
 |         strcpy(out_pdp_type,"IPV6"); | 
 |         break; | 
 |     case QSER_APN_PDP_TYPE_IPV4V6: | 
 |         strcpy(out_pdp_type,"IPV4V6"); | 
 |         break; | 
 |     default: | 
 |         strcpy(out_pdp_type,"NULL"); | 
 |         break; | 
 |     } | 
 |     return; | 
 | } | 
 | void judge_authtype(qser_apn_auth_proto_e auth_proto,char *out_proto) | 
 | { | 
 |     switch (auth_proto) | 
 |     { | 
 |     case QSER_APN_AUTH_PROTO_DEFAULT: | 
 |         strcpy(out_proto,"NULL;authType=0"); | 
 |         break; | 
 |     case QSER_APN_AUTH_PROTO_NONE: | 
 |         strcpy(out_proto,"NULL;authType=1"); | 
 |         break; | 
 |     case QSER_APN_AUTH_PROTO_PAP: | 
 |         strcpy(out_proto,"NULL;authType=2"); | 
 |         break; | 
 |     case QSER_APN_AUTH_PROTO_CHAP: | 
 |         strcpy(out_proto,"NULL;authtype=3"); | 
 |         break; | 
 |     case QSER_APN_AUTH_PROTO_PAP_CHAP: | 
 |         strcpy(out_proto,"NULL;authtype=4"); | 
 |         break; | 
 |     default: | 
 |         strcpy(out_proto,"NULL;authType=NULL"); | 
 |         break; | 
 |     } | 
 |     return ; | 
 | } | 
 |  | 
 | int data_call_handle_get(const char profile_idx,int *handle) | 
 | { | 
 |     int num = LYNQ_APN_CHANNEL_MAX; | 
 |     int table_num = 0; | 
 |     lynq_apn_info **apn_table = NULL; | 
 |     qser_apn_info_s apn; | 
 |     apn_table = (lynq_apn_info **)malloc(sizeof(lynq_apn_info *)*LYNQ_APN_CHANNEL_MAX); | 
 |     if (NULL == apn_table) | 
 |     { | 
 |         LYERRLOG("malloc apn_table fail "); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     for(int i =0;i<10;i++) | 
 |     { | 
 |         apn_table[i] = (lynq_apn_info*)malloc(sizeof(lynq_apn_info)); | 
 |         if (apn_table[i]==NULL) | 
 |         { | 
 |             for (int n=0;n<i;n++) | 
 |             { | 
 |                 free(apn_table[n]); | 
 |             } | 
 |             return RESULT_ERROR; | 
 |         } | 
 |         memset(apn_table[i],0,sizeof(lynq_apn_info)); | 
 |     } | 
 |     lynq_get_apn_table(&table_num,apn_table); | 
 |     memset(&apn,0,sizeof(qser_apn_info_s)); | 
 |     apn_xml_query(profile_idx,&apn); | 
 |     for (int j = 0;j < table_num;j++) | 
 |     { | 
 |         if (strcmp(apn.apn_type,apn_table[j]->apnType) == 0) | 
 |         { | 
 |             *handle = apn_table[j]->index; | 
 |             LYINFLOG("apn_table->index:%d,handle:%d ",apn_table[j]->index,*handle); | 
 |             break; | 
 |         } | 
 |     } | 
 |  | 
 |     for (int i = 0; i < LYNQ_APN_CHANNEL_MAX; i++)  | 
 |     { | 
 |         if (apn_table[i]!=NULL) | 
 |         {    | 
 |             free(apn_table[i]); | 
 |             apn_table[i]=NULL; | 
 |         } | 
 |     } | 
 |     free(apn_table); | 
 |     apn_table=NULL; | 
 |     LYINFLOG("data_call_handle_get end"); | 
 |     return RESULT_OK; | 
 | } | 
 |  | 
 | void *thread_wait_cb_status(void) | 
 | { | 
 |     int handle = -1; | 
 |     lynq_data_call_response_v11_t data_urc_info; | 
 |     qser_data_call_state_s data_cb_state; | 
 |     while (s_qser_data_cb_thread_status) | 
 |     { | 
 |         lynq_wait_data_call_state_change(&handle); | 
 |         lynq_get_data_call_list(&handle,&data_urc_info); | 
 |         /*compare paramter*/ | 
 |         data_cb_state.profile_idx = (char)handle; | 
 |  | 
 |         memcpy(data_cb_state.name,data_urc_info.ifname,strlen(data_urc_info.ifname)+1); | 
 |         if (!strcmp(data_urc_info.type,"IPV4")) | 
 |         { | 
 |             data_cb_state.ip_family = QSER_DATA_CALL_TYPE_IPV4; | 
 |         } | 
 |         else if (!strcmp(data_urc_info.type,"IPV6")) | 
 |         { | 
 |             data_cb_state.ip_family = QSER_DATA_CALL_TYPE_IPV6; | 
 |         } | 
 |         else if (strcmp(data_urc_info.type,"IPV4V6")) | 
 |         { | 
 |             data_cb_state.ip_family = QSER_DATA_CALL_TYPE_IPV4V6; | 
 |         } | 
 |         else | 
 |         { | 
 |             LYERRLOG("unknow data call type"); | 
 |             continue; | 
 |         } | 
 |  | 
 |         if (data_urc_info.status != 0) | 
 |         { | 
 |             data_cb_state.state = QSER_DATA_CALL_CONNECTED; | 
 |         } | 
 |         else | 
 |         { | 
 |             data_cb_state.state = QSER_DATA_CALL_DISCONNECTED; | 
 |         } | 
 |         if (data_cb_state.ip_family == QSER_DATA_CALL_TYPE_IPV4) | 
 |         { | 
 |             lynq_ipv4_aton_urc(&data_urc_info,&data_cb_state); | 
 |         } | 
 |         else if (data_cb_state.ip_family == QSER_DATA_CALL_TYPE_IPV6) | 
 |         { | 
 |             lynq_ipv6_inet_pton_urc(&data_urc_info,&data_cb_state); | 
 |         } | 
 |         else if (data_cb_state.ip_family == QSER_DATA_CALL_TYPE_IPV4V6) | 
 |         { | 
 |             lynq_ipv6_inet_pton_urc(&data_urc_info,&data_cb_state); | 
 |         } | 
 |         else | 
 |         { | 
 |             LYERRLOG("unknow ip_family"); | 
 |             continue; | 
 |         } | 
 |         if (s_data_call_cb != NULL) | 
 |         { | 
 |          s_data_call_cb(&data_cb_state); | 
 |         } | 
 |     } | 
 |     return NULL; | 
 | } | 
 |  | 
 | int qser_cb_pthread_create() | 
 | { | 
 |     int ret; | 
 |     s_qser_data_cb_thread_status = 1; | 
 |     ret = pthread_create(&s_cb_tid,NULL,thread_wait_cb_status,NULL); | 
 |     if (ret < 0) | 
 |     { | 
 |         LYERRLOG("pthread create fail"); | 
 |         s_qser_data_cb_thread_status = 0; | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     return RESULT_OK; | 
 | } | 
 |  | 
 | void qser_cb_pthread_cancel() | 
 | { | 
 |     int ret; | 
 |     s_qser_data_cb_thread_status = 0; | 
 |     if (s_cb_tid != -1) | 
 |     { | 
 |         ret = pthread_cancel(s_cb_tid); | 
 |         LYDBGLOG("pthread cancel ret = %d",ret); | 
 |         ret = pthread_join(s_cb_tid,NULL); | 
 |         LYDBGLOG("pthread join ret = %d",ret); | 
 |         s_cb_tid = -1; | 
 |     } | 
 |     return; | 
 | } | 
 |  | 
 | int qser_data_call_init(qser_data_call_evt_cb_t evt_cb) | 
 | {    | 
 |     int ret = 0; | 
 |     int utoken = 0; | 
 |     if (NULL == evt_cb) | 
 |     { | 
 |         LYERRLOG("init incoming paramters error"); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     s_data_call_cb = evt_cb; | 
 |     qser_cb_pthread_create(); | 
 |     ret = lynq_init_data(utoken); | 
 |     if (ret != RESULT_OK) | 
 |     { | 
 |         qser_cb_pthread_cancel(); | 
 |         s_data_call_cb = NULL; | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     return RESULT_OK; | 
 | } | 
 |  | 
 | void qser_data_call_destroy(void) | 
 | { | 
 |     qser_cb_pthread_cancel(); | 
 |     lynq_deinit_data(); | 
 |     s_data_call_cb = NULL; | 
 |     return ; | 
 | } | 
 |  | 
 | int qser_data_call_start(qser_data_call_s *data_call, qser_data_call_error_e *err) | 
 | { | 
 |     int ret = -1; | 
 |     int handle = 0; | 
 |     if (NULL == data_call || NULL == err) | 
 |     { | 
 |         LYERRLOG("call start incoming paramters error"); | 
 |         return ret; | 
 |     } | 
 |     if (data_call->profile_idx == 0) | 
 |     { | 
 |         ret = lynq_setup_data_call(&handle); | 
 |     } | 
 |     else | 
 |     { | 
 |         char pdptype[16]; | 
 |         qser_apn_info_s apn_info; | 
 |         qser_apn_get(data_call->profile_idx,&apn_info); | 
 |         judge_pdp_type(apn_info.pdp_type,pdptype); | 
 |         ret = lynq_setup_data_call_sp(&handle,apn_info.apn_name,apn_info.apn_type,apn_info.username,apn_info.password,NULL,pdptype,pdptype); | 
 |     } | 
 |     if (ret < 0) | 
 |     { | 
 |         *err = QSER_DATA_CALL_ERROR_INVALID_PARAMS; | 
 |     } | 
 |     return ret; | 
 | } | 
 |  | 
 | int qser_data_call_stop(char profile_idx, qser_data_call_ip_family_e ip_family, qser_data_call_error_e *err) | 
 | { | 
 |     int ret = 0; | 
 |     int handle = -1; | 
 |  | 
 |     if (NULL == err) | 
 |     { | 
 |         LYERRLOG("call stop incoming paramters error"); | 
 |         return ret; | 
 |     } | 
 |     data_call_handle_get(profile_idx,&handle); | 
 |     ret = lynq_deactive_data_call(&handle); | 
 |     if (ret < 0) | 
 |     { | 
 |         *err = QSER_DATA_CALL_ERROR_INVALID_PARAMS; | 
 |     } | 
 |     return RESULT_OK; | 
 | } | 
 | 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) | 
 | { | 
 |     int ret = 0; | 
 |     int handle = -1; | 
 |     lynq_data_call_response_v11_t data_call_info; | 
 |     data_call_handle_get(profile_idx,&handle); | 
 |     ret = lynq_get_data_call_list(&handle,&data_call_info); | 
 |     if (ret == 0) | 
 |     { | 
 |         info->profile_idx = profile_idx; | 
 |         info->ip_family = ip_family; | 
 |         if (strcmp(data_call_info.type,"IPV4")) | 
 |         { | 
 |             strcpy(info->v4.name,data_call_info.ifname); | 
 |             datacall_ipv4_status_judge(data_call_info.status,info); | 
 |             LYINFLOG("[IPV4]addresses:%s,gateways:%s,dnses:%s",data_call_info.addresses,data_call_info.gateways,data_call_info.dnses); | 
 |             lynq_ipv4_aton_getinfo(&data_call_info,info); | 
 |         } | 
 |         else if (strcmp(data_call_info.type,"IPV6")) | 
 |         { | 
 |             strcpy(info->v6.name,data_call_info.ifname); | 
 |  | 
 |             datacall_ipv6_status_judge(data_call_info.status,info); | 
 |             LYINFLOG("[IPV6]addresses:%s,gateways:%s,dnses:%s",data_call_info.addresses,data_call_info.gateways,data_call_info.dnses); | 
 |             lynq_ipv6_inet_pton_getinfo(&data_call_info,info); | 
 |         } | 
 |         else if (strcmp(data_call_info.type,"IPV4V6")) | 
 |         { | 
 |             strcpy(info->v4.name,data_call_info.ifname); | 
 |             datacall_ipv4_status_judge(data_call_info.status,info); | 
 |             LYINFLOG("[IPV4V6]addresses:%s,gateways:%s,dnses:%s",data_call_info.addresses,data_call_info.gateways,data_call_info.dnses); | 
 |             lynq_ipv4_aton_getinfo(&data_call_info,info); | 
 |             strcpy(info->v6.name,data_call_info.ifname); | 
 |             datacall_ipv6_status_judge(data_call_info.status,info); | 
 |             LYINFLOG("[IPV4V6]addresses:%s,gateways:%s,dnses:%s",data_call_info.addresses,data_call_info.gateways,data_call_info.dnses); | 
 |             lynq_ipv6_inet_pton_getinfo(&data_call_info,info); | 
 |         } | 
 |         else | 
 |         { | 
 |             LYERRLOG("useless qser_data_call_ip_family_e"); | 
 |         } | 
 |     } | 
 |     return ret; | 
 | } | 
 | int qser_apn_set(qser_apn_info_s *apn) | 
 | { | 
 |     int ret = 0; | 
 |     if (NULL == apn) | 
 |     { | 
 |         LYERRLOG("apn set incoming paramters error"); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     ret = apn_xml_modify(apn); | 
 |     if (ret < 0) | 
 |     { | 
 |         LYERRLOG("apn_xml_modify error"); | 
 |         return ret; | 
 |     } | 
 |     int apn_id = 0; | 
 |     char tmp_id[12]; | 
 |     char *outinfo = NULL; | 
 |     char normalprotocol[16]; | 
 |     char authtype[32]; | 
 |     outinfo = (char *)malloc(sizeof(char)*512); | 
 |     bzero(tmp_id,12); | 
 |     bzero(outinfo,512); | 
 |     apn_id = apn->profile_idx + apndb_offset; | 
 |     snprintf(tmp_id,sizeof(tmp_id),"%d",apn_id); | 
 |     judge_pdp_type(apn->pdp_type,normalprotocol); | 
 |     judge_authtype(apn->auth_proto,authtype); | 
 |     lynq_modify_apn_db(3,tmp_id,NULL,NULL,apn->apn_name,apn->apn_type,apn->username,apn->password,normalprotocol,normalprotocol,authtype,outinfo); | 
 |     LYINFLOG("[output]:%s",outinfo); | 
 |     free(outinfo); | 
 |     outinfo = NULL; | 
 |     return RESULT_OK; | 
 | } | 
 |  | 
 | int qser_apn_get(unsigned char profile_idx, qser_apn_info_s *apn) | 
 | { | 
 |     if (profile_idx < 0 || profile_idx > 24 || NULL == apn) | 
 |     { | 
 |         LYERRLOG("apn get incoming paramters error"); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     int ret = 0; | 
 |     ret = apn_xml_query(profile_idx,apn); | 
 |     if (ret < 0) | 
 |     { | 
 |         LYERRLOG("apn_xml_query error"); | 
 |         return ret; | 
 |     } | 
 |     return ret; | 
 | } | 
 |  | 
 | int qser_apn_add(qser_apn_add_s *apn, unsigned char *profile_idx) | 
 | { | 
 |     int ret = 0; | 
 |     if (NULL == apn || NULL == profile_idx) | 
 |     { | 
 |         LYERRLOG("apn add incoming paramters error"); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     ret = apn_xml_add(apn,profile_idx); | 
 |     if (ret < 0) | 
 |     { | 
 |         LYERRLOG("apn_xml_add error"); | 
 |         return ret; | 
 |     } | 
 |     int apn_id = 0; | 
 |     char tmp_id[12]; | 
 |     char *outinfo = NULL; | 
 |     char normalprotocol[16]; | 
 |     char authtype[32]; | 
 |     outinfo = (char *)malloc(sizeof(char)*512); | 
 |     bzero(tmp_id,12); | 
 |     bzero(outinfo,512); | 
 |     snprintf(tmp_id,sizeof(tmp_id),"%d",apn_id); | 
 |     judge_pdp_type(apn->pdp_type,normalprotocol); | 
 |     judge_authtype(apn->auth_proto,authtype); | 
 |     lynq_modify_apn_db(0,tmp_id,NULL,NULL,apn->apn_name,apn->apn_type,apn->username,apn->password,normalprotocol,normalprotocol,authtype,outinfo); | 
 |     LYINFLOG("[output]:%s",outinfo); | 
 |     free(outinfo); | 
 |     outinfo = NULL; | 
 |     return RESULT_OK; | 
 | } | 
 |  | 
 | int qser_apn_del(unsigned char profile_idx) | 
 | { | 
 |     if (profile_idx < 0 || profile_idx > 24) | 
 |     { | 
 |         LYERRLOG("apn del incoming paramters error"); | 
 |         return RESULT_OK; | 
 |     } | 
 |     int ret = 0; | 
 |     ret = apn_xml_delete(profile_idx); | 
 |     if (ret < 0) | 
 |     { | 
 |         LYERRLOG("apn_xml_delete error"); | 
 |         return ret; | 
 |     } | 
 |     int apn_id = 0; | 
 |     char tmp_id[12]; | 
 |     char *outinfo = NULL; | 
 |     outinfo = (char *)malloc(sizeof(char)*512); | 
 |     bzero(tmp_id,12); | 
 |     bzero(outinfo,512); | 
 |     apn_id = profile_idx+apndb_offset; | 
 |     snprintf(tmp_id,sizeof(tmp_id),"%d",apn_id); | 
 |     lynq_modify_apn_db(1,tmp_id,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,outinfo); | 
 |     LYINFLOG("[output]:%s",outinfo); | 
 |     free(outinfo); | 
 |     outinfo = NULL; | 
 |     return ret; | 
 | } | 
 |  | 
 | int qser_apn_get_list(qser_apn_info_list_s *apn_list) | 
 | { | 
 |     if (NULL == apn_list) | 
 |     { | 
 |         LYERRLOG("apn_list incoming paramters error"); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     int ret = 0; | 
 |     ret = apn_xml_query_list(apn_list); | 
 |     if (ret < 0) | 
 |     { | 
 |         LYERRLOG("apn_xml_query_list error"); | 
 |         return ret; | 
 |     } | 
 |     return ret; | 
 | } |