Skip to content

Commit

Permalink
Merge pull request #16 from shadansari/master
Browse files Browse the repository at this point in the history
#12 - multithreding enbsim
  • Loading branch information
shadansari authored Nov 12, 2019
2 parents 0bbf0b6 + 79bbd2c commit 47ef282
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 25 deletions.
8 changes: 8 additions & 0 deletions enbsim/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef _context_H
#define _context_H

#include <pthread.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
Expand All @@ -26,6 +27,8 @@
* Struct to carry around context (context)-specific data.
*/
typedef struct context {
pthread_t thread;

/* The context's socket. */
int fd;

Expand All @@ -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);
Expand Down
93 changes: 68 additions & 25 deletions enbsim/enbsim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <event2/bufferevent.h>
#include <event2/buffer.h>

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
Expand Down Expand Up @@ -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 <ip> <port> <num-enbs>\n");
fprintf(stderr, "Usage: enbsim <ip> <port> <num-enbs> <num-ues>\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);
Expand Down

0 comments on commit 47ef282

Please sign in to comment.