blob: c6d5aebe80ac9152b789f4dc4b980aa36b5bb025 [file] [log] [blame]
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <string.h>
#include <sys/un.h>
#define SERVERNAME "/tmp/socket-demoapp"
#define STARTKEEPALIVE "RIL_REQUEST_START_KEEPALIVE_PRO"
#define STOPKEEPALIVE "RIL_REQUEST_STOP_KEEPALIVE_PRO"
#define KEEPALIVESTATUS "RIL_UNSOL_KEEPALIVE_STATUS_PRO"
typedef enum {
IPV4_TCP = 0,
IPV4_UDP = 1,
IPV6_TCP = 2,
IPV6_UDP = 3
} PacketType;
#define MAX_INADDR_LEN 16
typedef struct {
PacketType type; /* Type of keepalive packet */
char sourceAddress[MAX_INADDR_LEN]; /* Source address in network-byte order */
int sourcePort; /* Source port if applicable, or 0x7FFFFFFF;
the maximum value is 65535 */
char destinationAddress[MAX_INADDR_LEN]; /* Destination address in network-byte order */
int destinationPort; /* Destination port if applicable or 0x7FFFFFFF;
the maximum value is 65535 */
int netif_id;
int keepIdleTime; /*Sec. If no data during these time, start detecting, */
int keepIntervalTime; /*seconds between two packets*/
int retryCount; /*Detecting counts*/
} Keepalive_Pro;
typedef enum{
KEEPALIVE_ACTIVE,
KEEPALIVE_INACTIVE,
KEEPALIVE_PENDING
} KeepaliveStatusCode;
typedef struct{
uint32_t sessionHandle;
KeepaliveStatusCode code;
} KeepaliveStatus;
int TCPkeepaliveonoff(int sockfd,int onoff,Keepalive_Pro *KLpro)
{
setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &(KLpro->retryCount), sizeof(KLpro->retryCount));
setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &(KLpro->keepIdleTime), sizeof(KLpro->keepIdleTime));
setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &(KLpro->keepIntervalTime), sizeof(KLpro->keepIntervalTime));
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &onoff, sizeof(onoff));
}
int createsock(char *serverip,int server_port)
{
int clientSocket;
struct sockaddr_in serverAddr;
if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("create socket error");
return 1;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(server_port);
serverAddr.sin_addr.s_addr = inet_addr(serverip);
if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
{
printf("connect to server error");
return 1;
}
return clientSocket;
}
int getipif(char* ip,char *iface)
{
struct ifaddrs *addrs, *iap;
struct sockaddr_in *sa;
char buf[32];
getifaddrs(&addrs);
for (iap = addrs; iap != NULL; iap = iap->ifa_next)
{
if (iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == AF_INET)
{
sa = (struct sockaddr_in *)(iap->ifa_addr);
inet_ntop(iap->ifa_addr->sa_family, (void *)&(sa->sin_addr), buf, sizeof(buf));
if (!strcmp(ip, buf))
{
strcpy(iface,iap->ifa_name);
}
}
}
freeifaddrs(addrs);
return 0;
}
int printsockinfo(int sockfd)
{
struct sockaddr_in local_addr;
char local_ip[MAX_INADDR_LEN];
int local_port=0;
char iface[10];
socklen_t local_addr_len=sizeof(local_addr);
getsockname(sockfd,(struct sockaddr *)&local_addr,&local_addr_len);
inet_ntop(AF_INET,&local_addr.sin_addr,local_ip,sizeof(local_ip));
local_port=ntohs(local_addr.sin_port);
getipif(local_ip,iface);
printf("local ip %s port %d interface %s\n",local_ip,local_port,iface);
}
int getKLpara(int sockfd,Keepalive_Pro *KLpro)
{
struct sockaddr_in source_addr;
char iface[10];
socklen_t source_addr_len=sizeof(source_addr);
getsockname(sockfd,(struct sockaddr *)&source_addr,&source_addr_len);
//get source ip
inet_ntop(AF_INET,&source_addr.sin_addr,KLpro->sourceAddress,sizeof(KLpro->sourceAddress));
//get source port
KLpro->sourcePort=ntohs(source_addr.sin_port);
getipif(KLpro->sourceAddress,iface);
if(strstr(iface,"ccmni"))
{
KLpro->netif_id=atoi(iface+5);
}
printf(" ip %s port %d interface %s\n",KLpro->sourceAddress,KLpro->sourcePort,iface);
}
int sendinfotoserver(int sockfd)
{
int ret=0;
ret=send(sockfd,"\0",1,0);
if(ret<=0)
{
printf("send info to server error\n");
return -1;
}
printf("send info to server\n");
return 0;
}
int setkeepaliveenable(int *sockfd,Keepalive_Pro *KLpro)
{
int sessionhandle=0;
struct sockaddr_un client;
//create unix domain socket to connection demoapp
*sockfd = socket(AF_UNIX,SOCK_STREAM,0);
client.sun_family = AF_UNIX;
strcpy(client.sun_path,SERVERNAME);
bind(*sockfd,(struct sockaddr *)&client,sizeof(client));
int result = 0;
result = connect(*sockfd,(struct sockaddr *)&client,sizeof(client));
if(result <0){
printf("error in connect to demoapp\n");
return 0;
}
char buf[256];
memset(buf,0,sizeof(buf));
snprintf(buf,256,"%s,%d,%s,%d,%s,%d,%d,%d,%d,%d",
STARTKEEPALIVE,
0,
KLpro->sourceAddress,
KLpro->sourcePort,
KLpro->destinationAddress,
KLpro->destinationPort,
KLpro->netif_id,
KLpro->keepIdleTime,
KLpro->keepIntervalTime,
KLpro->retryCount);
printf("send buf %s\n",buf);
if( write(*sockfd,buf,sizeof(buf))>0)
{
printf("send buf to demoapp\n");
}
int ret=0;
memset(buf,0,sizeof(buf));
if( ret=read(*sockfd,buf,256) >0)
{
printf("recv buf %s\n",buf);
if(strstr(buf,STARTKEEPALIVE))
{
if(strstr(buf,"ok"))
{
char *newbuf=buf+sizeof(STARTKEEPALIVE)+3;
char *p=strtok(newbuf,",");
char *q=strtok(NULL,",");
sessionhandle=atoi(p);
printf("code is %s\n",q);
}
else
{
return -1;
}
}
}
else
{
printf("read buf from demoapp fail\n");
return -1;
}
printf("sessionhandle is %d\n",sessionhandle);
return sessionhandle;
}
int keepalivestatuswait(int clientfd)
{
char buf[256];
int ret;
while(1)
{
memset(buf,0,256);
if( (ret=read(clientfd,buf,256)) >0)
{
buf[ret]='\0';
printf("recv buf %s\n",buf);
if(strstr(buf,KEEPALIVESTATUS))
{
char *newbuf=buf+sizeof(KEEPALIVESTATUS);
printf("newbuf %s\n",newbuf);
char *p=strtok(newbuf,",");
char *q=strtok(NULL,",");
int sessionhandle=atoi(p);
int code= atoi(q);
printf("code is %d\n",code);
if(code==KEEPALIVE_INACTIVE)
{
printf("keepalive is fail\n");
break;
}
}
}
}
return 0;
}
int setkeepalivedisable(int sessionhandle)
{
struct sockaddr_un client;
//create unix domain socket to connection demoapp
int sockfd = socket(AF_UNIX,SOCK_STREAM,0);
client.sun_family = AF_UNIX;
strcpy(client.sun_path,SERVERNAME);
bind(sockfd,(struct sockaddr *)&client,sizeof(client));
int result = 0;
result = connect(sockfd,(struct sockaddr *)&client,sizeof(client));
if(result <0){
return 0;
}
char buf[256];
memset(buf,0,sizeof(buf));
snprintf(buf,256,"%s,%d",
STOPKEEPALIVE,
sessionhandle);
if( write(sockfd,buf,sizeof(buf))>0)
{
printf("send buf to demoapp");
}
int ret=0;
memset(buf,0,sizeof(buf));
if( ret=read(sockfd,buf,256) >0)
{
printf("recv buf %s\n",buf);
if(strstr(buf,STOPKEEPALIVE))
{
if(strstr(buf,"ok"))
{
printf("stop keepalive ok\n");
}
else
{
return -1;
printf("stop keepalive fail\n");
}
}
}
return 0;
}
int main(int argc,char *argv[])
{
if(argc<3)
{
printf("keepalivedemo 1 destinationAddress destinationPort keepIdleTime keepIntervalTime retryCount\n");
printf("keepalivedemo 0 sessionhandle\n");
return 0;
}
printf("argv %s %s \n",argv[1],argv[2]);
if(atoi(argv[1])==1)
{
Keepalive_Pro KLdemo;
strcpy(KLdemo.destinationAddress,argv[2]);
KLdemo.destinationPort=atoi(argv[3]);
if(argv[4]!=NULL)
KLdemo.keepIdleTime=atoi(argv[4]);
if(argv[5]!=NULL)
KLdemo.keepIntervalTime=atoi(argv[5]);
if(argv[6]!=NULL)
KLdemo.retryCount=atoi(argv[6]);
//create socket connect to destinationAddress
int sockfd=createsock(KLdemo.destinationAddress,KLdemo.destinationPort);
#if DEBUG
TCPkeepaliveonoff(sockfd,1,&KLdemo);
#endif
//get keepalive parameter
getKLpara(sockfd,&KLdemo);
//set keepalive enable to MD
int clientfd;
int sessionhandle=setkeepaliveenable(&clientfd,&KLdemo);
//send a data to server to ensure MD get the information for keepalive
sendinfotoserver(sockfd);
//MD do keepalive,wait infomation
keepalivestatuswait(clientfd);
close(clientfd);
close(sockfd);
return 0;
}
else if(atoi(argv[1])==0)
{
setkeepalivedisable(atoi(argv[2]));
return 0;
}
}