diff --git a/enbsim/context.h b/enbsim/context.h index afd2311..f9cbd00 100644 --- a/enbsim/context.h +++ b/enbsim/context.h @@ -17,6 +17,7 @@ #ifndef _context_H #define _context_H +#include #include #include #include @@ -26,6 +27,8 @@ * Struct to carry around context (context)-specific data. */ typedef struct context { + pthread_t thread; + /* The context's socket. */ int fd; @@ -44,6 +47,11 @@ typedef struct context { /* IP address of this context */ char ip[INET_ADDRSTRLEN]; + + char server_ip[INET_ADDRSTRLEN]; + int port; + int num_ues; + int enb_index; } context_t; void closecontext(context_t *context); diff --git a/enbsim/enbsim.cpp b/enbsim/enbsim.cpp index d0d420f..b8343da 100644 --- a/enbsim/enbsim.cpp +++ b/enbsim/enbsim.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -90,52 +91,94 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) } } +static void *worker_function(void *arg) { + context_t *context = (context_t *)arg; + struct sockaddr_in sin; + struct event_base *evbase; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + inet_pton(AF_INET, context->server_ip, &(sin.sin_addr)); + sin.sin_port = htons(context->port); + + evbase = event_base_new(); + if (!evbase) { + puts("Couldn't open event base"); + //return; + } + context->evbase = evbase; + context->fd = create_bind_socket(context->enb_index); + context->buf_ev = bufferevent_socket_new(context->evbase, context->fd, BEV_OPT_CLOSE_ON_FREE); + bufferevent_setcb(context->buf_ev, readcb, NULL, eventcb, context); + bufferevent_enable(context->buf_ev, EV_READ|EV_WRITE); + if (bufferevent_socket_connect(context->buf_ev, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + /* Error starting connection */ + bufferevent_free(context->buf_ev); + puts("error connect"); + //return; + } + + event_base_dispatch(context->evbase); + +} + +static int workers_init(char *server_ip, int port, int session_count, int num_ues) { + context_t *context; + + for (int i = 0; i < session_count; ++i) { + if ((context = (context_t*)malloc(sizeof(*context))) == NULL) { + printf("failed to allocate memory for client state"); + return 1; + } + strncpy(context->server_ip, server_ip, INET_ADDRSTRLEN); + context->port = port; + context->num_ues = num_ues; + context->enb_index = i + 1; + if (pthread_create(&context->thread, NULL, worker_function, (void *)context)) { + perror("Failed to start all worker threads"); + free(context); + return 1; + } + } +} + +static void timercb(int fd, short event, void *arg) { + // do housekeeping here +} + int enbsim_main(int argc, char **argv, const Config& config) { //struct bufferevent **bevs; - struct sockaddr_in sin; int i; + struct event_base *evbase; + struct event *timer = NULL; if (argc != 5) { - fprintf(stderr, "Usage: enbsim \n"); + fprintf(stderr, "Usage: enbsim \n"); return 1; } char *server_ip = argv[1]; int port = atoi(argv[2]); int session_count = atoi(argv[3]); + int num_ues = atoi(argv[4]); - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - inet_pton(AF_INET, server_ip, &(sin.sin_addr)); - sin.sin_port = htons(port); - - struct event_base *evbase; evbase = event_base_new(); if (!evbase) { puts("Couldn't open event base"); return 1; } - for (i = 0; i < session_count; ++i) { - context_t *context; - if ((context = (context_t*)malloc(sizeof(*context))) == NULL) { - printf("failed to allocate memory for client state"); - return 1; - } - context->evbase = evbase; - context->fd = create_bind_socket(i + 1); - context->buf_ev = bufferevent_socket_new(context->evbase, context->fd, BEV_OPT_CLOSE_ON_FREE); - bufferevent_setcb(context->buf_ev, readcb, NULL, eventcb, context); - bufferevent_enable(context->buf_ev, EV_READ|EV_WRITE); - if (bufferevent_socket_connect(context->buf_ev, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - /* Error starting connection */ - bufferevent_free(context->buf_ev); - puts("error connect"); - return -1; - } + + { + struct timeval tv = {1, 0}; + + timer = event_new(evbase, -1, EV_PERSIST, timercb, NULL); + evtimer_add(timer, &tv); } + workers_init(server_ip, port, session_count, num_ues); + event_base_dispatch(evbase); event_base_free(evbase);