| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <dlfcn.h> | |
| #include <pthread.h> | |
| #include <sys/types.h> | |
| #include <unistd.h> | |
| #undef LOG_TAG | |
| #define LOG_TAG "DATA_DEMO" | |
| void *dlHandle_data; | |
| void *dlHandle_log; | |
| #define LYNQ_APN_CHANNEL_MAX 10 | |
| #define LYNQ_PDP_TYPE_MAX_LEN 16 | |
| #define LYNQ_IFACE_NAME_MAX_LEN 50 | |
| #define LYNQ_APN_MAX_LEN 50 | |
| #define LYNQ_APN_TYPE_MAX_LEN 50 | |
| #define LYNQ_PDP_ADDR_MAX_LEN 64 | |
| #define LYNQ_DNS_ADDR_MAX_LEN 64 | |
| #define LYNQ_GETWAYS_ADDR_MAX_LEN 64 | |
| #define LYNQ_POXY_ADDR_MAX_LEN 64 | |
| typedef struct { | |
| int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ | |
| int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry | |
| back-off timer value RIL wants to override the one | |
| pre-configured in FW. | |
| The unit is miliseconds. | |
| The value < 0 means no value is suggested. | |
| The value 0 means retry should be done ASAP. | |
| The value of INT_MAX(0x7fffffff) means no retry. */ | |
| int cid; /* Context ID, uniquely identifies this call */ | |
| int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ | |
| char type[LYNQ_PDP_TYPE_MAX_LEN]; /* One of the PDP_type values in TS 27.007 section 10.1.1. | |
| For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is | |
| PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported | |
| such as "IP" or "IPV6" */ | |
| char ifname[LYNQ_IFACE_NAME_MAX_LEN]; /* The network interface name */ | |
| char addresses[LYNQ_PDP_ADDR_MAX_LEN]; /* A space-delimited list of addresses with optional "/" prefix length, | |
| e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". | |
| May not be empty, typically 1 IPv4 or 1 IPv6 or | |
| one of each. If the prefix length is absent the addresses | |
| are assumed to be point to point with IPv4 having a prefix | |
| length of 32 and IPv6 128. */ | |
| char dnses[LYNQ_DNS_ADDR_MAX_LEN]; /* A space-delimited list of DNS server addresses, | |
| e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". | |
| May be empty. */ | |
| char gateways[LYNQ_GETWAYS_ADDR_MAX_LEN]; /* A space-delimited list of default gateway addresses, | |
| e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". | |
| May be empty in which case the addresses represent point | |
| to point connections. */ | |
| char pcscf[LYNQ_POXY_ADDR_MAX_LEN]; /* the Proxy Call State Control Function address | |
| via PCO(Protocol Configuration Option) for IMS client. */ | |
| int mtu; /* MTU received from network | |
| Value <= 0 means network has either not sent a value or | |
| sent an invalid value */ | |
| } lynq_data_call_response_v11_t; | |
| int (*lynq_init_data)(int uToken); | |
| int (*lynq_deinit_data)(void); | |
| int (*lynq_setup_data_call)(int *); | |
| int (*lynq_deactive_data_call)(int *); | |
| int (*lynq_setup_data_call_sp)(int *,char *apn,char *apnType,char *user,char *password,char *authType,char *normalProtocol,char *roamingProtocol); | |
| int (*lynq_get_data_call_list)(int *,lynq_data_call_response_v11_t *dataCallList); | |
| int (*lynq_wait_data_call_state_change)(int *); | |
| int (*lynq_modify_apn_db)(const int cmd,char *id,char *mcc,char *mnc,char *apn,char *apntype,char *user,char *password,char *normalprotocol,char *roamingprotocol,char *carrier,char *out); | |
| void *triggerUrcEvent(void *parg) | |
| { | |
| int ret = -1; | |
| int handle = -1;//data call state change handle | |
| lynq_data_call_response_v11_t data_call_list; | |
| memset(&data_call_list,0,sizeof(data_call_list)); | |
| printf("wait data call start!!!!"); | |
| while(1) | |
| { | |
| lynq_wait_data_call_state_change = (int (*)(int *handle))dlsym(dlHandle_data,"lynq_wait_data_call_state_change"); | |
| if(NULL != lynq_wait_data_call_state_change) | |
| { | |
| ret = lynq_wait_data_call_state_change(&handle);//wait data call state change,and get handle. | |
| if(ret == 0) | |
| { | |
| printf("lynq_wait_data_call_state_change success!!!\n"); | |
| }else{ | |
| printf("lynq_wait_data_call_state_change error\n"); | |
| } | |
| }else{ | |
| printf("lynq_wait_data_call_state_change dlsym error\n"); | |
| } | |
| printf("data event handle=%d",handle); | |
| lynq_get_data_call_list = (int (*)(int *handle,lynq_data_call_response_v11_t *dataCallList))dlsym(dlHandle_data,"lynq_get_data_call_list"); | |
| if(NULL != lynq_get_data_call_list) | |
| { | |
| ret = lynq_get_data_call_list(&handle, &data_call_list);//Query data call info list according to handle. | |
| if(ret == 0) | |
| { | |
| printf("lynq_get_data_call_list success!!!\n"); | |
| }else{ | |
| printf("lynq_get_data_call_list error\n"); | |
| } | |
| }else{ | |
| printf("lynq_get_data_call_list dlsym error\n"); | |
| } | |
| if(ret == 0) | |
| { | |
| printf("cid:%d,iface:%s,IP:%s",data_call_list.cid,data_call_list.ifname,data_call_list.addresses); | |
| } | |
| memset(&data_call_list,0,sizeof(data_call_list)); | |
| } | |
| return NULL; | |
| } | |
| /** | |
| * @brief 修改 APN 记录 | |
| * | |
| * 根据给定的参数,在数据库中修改 APN 记录。 | |
| * | |
| * @param id 记录 ID | |
| * @param mcc 移动国家码 | |
| * @param mnc 移动网络码 | |
| * @param apn 接入点名称 | |
| * @param apntype APN 类型 | |
| * @param user 用户名 | |
| * @param password 密码 | |
| * @param normalprotocol 本地协议 | |
| * @param roamingprotocol 漫游协议 | |
| * @param carrier 运营商 | |
| * | |
| * @return 修改结果,0 表示成功,非 0 表示失败 | |
| */ | |
| int modify_apn(char *id,char *mcc,char *mnc,char *apn,char *apntype,char *user,char *password,char *normalprotocol,char *roamingprotocol,char *carrier) | |
| { | |
| char out[512] = {0}; | |
| int ret = 0; | |
| //check record | |
| ret = lynq_modify_apn_db(2,id,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,out); | |
| if(ret == 0) | |
| { | |
| printf("out = %s\n",out); | |
| if(strstr(out,"No record found!") == NULL) | |
| { | |
| printf("check whether record correct\n"); | |
| ret = lynq_modify_apn_db(2,id,mcc,mnc,apn,apntype,user,password,normalprotocol,roamingprotocol,carrier,out); | |
| if(ret == 0) | |
| { | |
| printf("out = %s\n",out); | |
| if(strstr(out,"No record found!") != NULL) | |
| { | |
| printf("has record but not correct,need to modify record\n"); | |
| ret = lynq_modify_apn_db(3,id,mcc,mnc,apn,apntype,user,password,normalprotocol,roamingprotocol,carrier,out); | |
| if(ret == 0) | |
| { | |
| printf("update success,out = %s\n",out); | |
| return 0; | |
| } | |
| else | |
| { | |
| printf("lynq_modify_apn_db modify failed,ret = %d\n",ret); | |
| return ret; | |
| } | |
| } | |
| else | |
| { | |
| printf("correct record,don't need insert or update, just return\n"); | |
| return 0; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| printf("no any record,insert record\n"); | |
| ret = lynq_modify_apn_db(0,id,mcc,mnc,apn,apntype,user,password,normalprotocol,roamingprotocol,carrier,out); | |
| if(ret == 0) | |
| { | |
| printf("insert success,out = %s\n",out); | |
| return 0; | |
| } | |
| else | |
| { | |
| printf("lynq_modify_apn_db insert failed,ret = %d\n",ret); | |
| return ret; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| printf("lynq_modify_apn_db query failed,ret = %d\n",ret); | |
| return ret; | |
| } | |
| } | |
| //此demo 示例建立两路APN,以中国移动SIM卡为例。默认每一个API 执行都成功,依次往下执行。 | |
| int main(int argc, char *argv[]) | |
| { | |
| printf("[LYNQ_DATA_DEMO]--------->[%s,%d] start",__FUNCTION__,__LINE__); | |
| int ret = -1; | |
| int32_t requestId = 0; | |
| int32_t status = 0; | |
| char apn[100] = {0}; | |
| char apnType[50] = {0}; | |
| char iface[50] = {0}; | |
| int handle_1 = -1;//第一路APN 句柄 | |
| int handle_2 = -1;//第二路APN 句柄 | |
| int handle_3 = 10; | |
| char *argv_t[10]={0}; | |
| argv_t[0] = "cmwap"; | |
| argv_t[1] = "wap"; | |
| argv_t[2] = "IPV4V6"; | |
| argv_t[3] = "IPV4V6"; | |
| pthread_t tid; | |
| pthread_attr_t attr; | |
| pthread_attr_init(&attr); | |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
| const char *lynq_libpath_data = "/lib64/liblynq-data.so"; | |
| const char *lynq_libpath_log = "/lib64/liblynq-log.so"; | |
| dlHandle_data = dlopen(lynq_libpath_data,RTLD_NOW); | |
| if(dlHandle_data == NULL) | |
| { | |
| printf("dlopen dlHandle_data failed: %s", dlerror()); | |
| exit(EXIT_FAILURE); | |
| } | |
| dlHandle_log = dlopen(lynq_libpath_log,RTLD_NOW); | |
| if(dlHandle_log == NULL) | |
| { | |
| printf("dlopen dlHandle_log failed: %s", dlerror()); | |
| exit(EXIT_FAILURE); | |
| } | |
| lynq_init_data = (int(*)(int))dlsym(dlHandle_data,"lynq_init_data"); | |
| if(NULL == lynq_init_data) | |
| { | |
| printf("lynq_init_data not defined or exported in %s\r\n", lynq_libpath_data); | |
| exit(EXIT_FAILURE); | |
| } | |
| lynq_modify_apn_db = (int(*)(const int cmd, char *id, char *mcc, char *mnc, char *apn, char *apntype, char *user, char *password, char *normalprotocol, char *roamingprotocol, char *carrier, char *out))dlsym(dlHandle_data,"lynq_modify_apn_db"); | |
| if (lynq_modify_apn_db == NULL) | |
| { | |
| printf("lynq_modify_apn_db not defined or exported in %s\r\n", lynq_libpath_data); | |
| exit(EXIT_FAILURE); | |
| } | |
| ret = lynq_init_data(2022);//初始化数据业务。 | |
| sleep(1); | |
| if(ret == 0) | |
| { | |
| printf("init data call success!!!\n"); | |
| } | |
| else | |
| { | |
| printf("init data call fail!!!\n"); | |
| return -1; | |
| } | |
| //插入预设的apn记录 | |
| ret = modify_apn("-1","460","00","cmwap","wap",NULL,NULL,"IPV4V6","IPV4V6","China Mobile"); | |
| if(ret == 0) | |
| { | |
| printf("modify apn success"); | |
| }else{ | |
| printf("modify apn fail,ret = %d\n",ret); | |
| //do something | |
| //进行插入失败的处理,如重试等。 | |
| } | |
| sleep(1);//等待插入完成。 | |
| ret = pthread_create(&tid,&attr,triggerUrcEvent,NULL);//创建一个线程用来处理data call改变事件。 | |
| sleep(1);//等待线程tid 开始执行。 | |
| lynq_setup_data_call = (int (*)(int *))dlsym(dlHandle_data,"lynq_setup_data_call"); | |
| if(NULL != lynq_setup_data_call) | |
| { | |
| ret = lynq_setup_data_call(&handle_1);//默认APN 参数拨号上网。 | |
| if(ret == 0) | |
| { | |
| printf("setup data call success!!!\n"); | |
| }else{ | |
| printf("setup data call error\n"); | |
| } | |
| }else{ | |
| printf("lynq_setup_data_call dlsym error\n"); | |
| } | |
| sleep(10); //等待handle_1 建立好 | |
| //带APN 参数进行拨号上网 | |
| lynq_setup_data_call_sp = (int (*)(int *,char *apn,char *apnType,char *user,char *password,char *authType,char *normalProtocol,char *roamingProtocol))dlsym(dlHandle_data,"lynq_setup_data_call_sp"); | |
| if(NULL != lynq_setup_data_call_sp) | |
| { | |
| ret = lynq_setup_data_call_sp(&handle_2,argv_t[0],argv_t[1],NULL,NULL,NULL,argv_t[2],argv_t[3]);//sp APN 参数拨号上网。 | |
| if(ret == 0) | |
| { | |
| printf("setup data call sp success!!!\n"); | |
| }else{ | |
| printf("setup data call sp error\n"); | |
| } | |
| }else{ | |
| printf("lynq_setup_data_call_sp dlsym error\n"); | |
| } | |
| sleep(10);//等待handle_1 建立好 | |
| printf("start lynq_deactive_data_call handle_1"); | |
| lynq_deactive_data_call = (int (*)(int *))dlsym(dlHandle_data,"lynq_deactive_data_call"); | |
| if(NULL != lynq_deactive_data_call) | |
| { | |
| ret = lynq_deactive_data_call(&handle_1);//去激活第一路data call | |
| if(ret == 0) | |
| { | |
| printf("deactive data call handle_1 success!!!\n"); | |
| }else{ | |
| printf("deactive data call error\n"); | |
| } | |
| }else{ | |
| printf("lynq_deactive_data_call dlsym error\n"); | |
| } | |
| sleep(5); | |
| printf("start lynq_deactive_data_call handle_2\n"); | |
| ret = lynq_deactive_data_call(&handle_2);//去激活第二路data call | |
| if(ret == 0) | |
| { | |
| printf("deactive data call handle_2 success!!!\n"); | |
| }else{ | |
| printf("deactive data call error\n"); | |
| } | |
| sleep(5); | |
| lynq_deinit_data = (int (*)(void))dlsym(dlHandle_data,"lynq_deinit_data"); | |
| if(NULL != lynq_deinit_data) | |
| { | |
| ret = lynq_deinit_data(); | |
| if(ret == 0) | |
| { | |
| printf("deinit data call success!!!\n"); | |
| }else{ | |
| printf("deinit data call error\n"); | |
| } | |
| }else{ | |
| printf("lynq_deinit_data dlsym error\n"); | |
| } | |
| sleep(5); | |
| return 0; | |
| } |