requirement: TS <----->UE<---->NB TS and NB are two network nodes, they communicate with UE. UE make its all effort to balance the different communication with the TS and NB separately
ue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>
#define TS_IP "127.0.0.1"
#define NB_IP "109.105.2.136"
#define UE_PORT 7000
#define TS_PORT 5000
#define NB_PORT 6000
#define MAX 65536+16
struct argument{
int fd;
int enable;
pthread_mutex_t mut;
};
int check_cmd(unsigned char data[MAX], int sum){
int length;
length = data[2] * 256 + data[3];
if((sum - 4 == length) && !(data[0] == 0x03 && data[1] == 0x02))
return 1;
if((sum - 4 == length) && !(data[0] == 0x03 && data[1] == 0x03))
return 1;
if(sum - 16 == length)
return 1;
return 0;
}
void receive_from_TSorNB_thread(void *arg_thread){
int id;
int i;
int sock;
struct sockaddr_in socket_addr;
int socket_addr_len;
unsigned char data[MAX] = {0};
unsigned char data_TS[MAX] = {0};
unsigned char data_NB[MAX] = {0};
int length_TS = 0;
int length_NB = 0;
int sum_TS = 0;
int sum_NB = 0;
int ret = 0;
struct argument *arg;
arg = ( struct argument * )arg_thread;
bzero(&socket_addr,sizeof(socket_addr));
socket_addr.sin_family = AF_INET;
socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
socket_addr.sin_port = htons(UE_PORT);
socket_addr_len = sizeof(socket_addr);
if((sock = socket(AF_INET,SOCK_DGRAM, 0)) < 0){
perror("Socket");
return ;
}
bind(sock, (struct sockaddr *)&socket_addr, sizeof(socket_addr));
while(1){
ret = recvfrom(sock, data, sizeof(data), 0, (struct sockaddr *)&socket_addr, &socket_addr_len);
//from TS
if(strcmp(inet_ntoa(socket_addr.sin_addr), TS_IP) == 0 ){
for(i = 0; i < ret; i++){
data_TS[sum_TS+i] = data[i];
}
sum_TS = sum_TS + ret;
if(check_cmd(data_TS, sum_TS) == 1){ //full package
if(data_TS[0] == 0x01 && data_TS[1] == 0x10){
arg->enable = 1;
}
write(arg->fd, data_TS, sum_TS);
sum_TS = 0;
memset(data_TS, 0, sizeof(data_TS));
}
}
//from NB
if(strcmp(inet_ntoa(socket_addr.sin_addr), NB_IP) == 9 ){
for(i = 0; i < ret; i++){ //not full
data_NB[sum_NB+i] = data[i];
}
sum_NB = sum_NB + ret;
if(check_cmd(data_NB, sum_NB) == 1){ //full package
write(arg->fd, data_NB, sum_NB);
sum_NB = 0;
memset(data_NB, 0, sizeof(data_NB));
}
}
memset(data, 0, ret);
sleep(1);
}
return ;
}
void send_to_TSorNB_thread(void *arg_thread){
int id;
int i;
unsigned char data[MAX] = {0};
unsigned char buffer[MAX] = {0};
struct argument *arg;
int flag = 0;
int ret = 0;
int sock = 0;
int sum = 0;
int length = 0;
struct sockaddr_in socket_addr_TS;
struct sockaddr_in socket_addr_NB;
struct sockaddr_in addr_me;
arg = ( struct argument * )arg_thread;
//TS socket
bzero(&socket_addr_TS, sizeof(socket_addr_TS));
socket_addr_TS.sin_family = AF_INET;
socket_addr_TS.sin_port = htons(TS_PORT);
socket_addr_TS.sin_addr.s_addr = inet_addr(TS_IP);
//NB socket
bzero(&socket_addr_NB, sizeof(socket_addr_NB));
socket_addr_NB.sin_family = AF_INET;
socket_addr_NB.sin_port = htons(NB_PORT);
socket_addr_NB.sin_addr.s_addr = inet_addr(NB_IP);
//bind UE port
bzero(&addr_me, sizeof(addr_me));
addr_me.sin_family = AF_INET;
addr_me.sin_port = htons(UE_PORT);
addr_me.sin_addr.s_addr = htonl(INADDR_ANY);
if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("socket");
return ;
}
bind(sock, (struct sockaddr *)&addr_me, sizeof(addr_me));
while(1){
while(1)
{
ret = read(arg->fd, data+sum, sizeof(data)-1-sum);
sum = sum + ret;
if(check_cmd(data, sum) == 1){
break;
}
}
if(data[0] == 0x01 && data[1] == 0x10){ //header 0x0110
arg->enable = 0;
}
if(arg->enable == 1){
if (data[0] == 0x03 && data[1] == 0x01 )
sendto(sock, data, sum, 0, (struct sockaddr *)&socket_addr_TS, sizeof(socket_addr_TS));
if (data[0] == 0x03 && data[1] == 0x03)
sendto(sock, data, sum, 0, (struct sockaddr *)&socket_addr_NB, sizeof(socket_addr_NB));
}
sum = 0;
memset(data, 0, sizeof(data));
sleep(1);
}
return ;
}
void main(void){
int fd;
struct argument arg;
pthread_t thread[2];
fd = open("/dev/my_misc_dev", O_RDWR);
if(fd != -1){
arg.fd = fd;
arg.enable = 0;
pthread_create(&thread[0], NULL, (void *)(&receive_from_TSorNB_thread), (void*)&arg);
pthread_create(&thread[1], NULL, (void *)(&send_to_TSorNB_thread), (void*)&arg);
}
sleep(1000000);
return ;
}
Makefile:
pcie:pc.c
gcc -o pc pc.c -lpthread
clean:
rm -fr *.o *~