#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; | |
} |