Skip to content

Commit

Permalink
Merge pull request #15 from shadansari/master
Browse files Browse the repository at this point in the history
initial support for multiple enbs
  • Loading branch information
shadansari authored Nov 6, 2019
2 parents 5ea788b + cee29f0 commit 0bbf0b6
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 117 deletions.
11 changes: 8 additions & 3 deletions enbsim/cell_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ void copy_ecgi(ECGI_t *dest, ECGI_t *src) {
dest->eUTRANcellIdentifier.size = src->eUTRANcellIdentifier.size;
}

void cell_config_request(XRANCPDU *req, context_t *ctx) {
int cell_config_request(XRANCPDU *req, char *resp_buf, int resp_buf_size) {
// TODO
asn_enc_rval_t er;
XRANCPDU *resp;
struct Cell cell;
int ret;
Expand Down Expand Up @@ -83,7 +82,13 @@ void cell_config_request(XRANCPDU *req, context_t *ctx) {

xer_fprint(stdout, &asn_DEF_XRANCPDU, resp);

context_send(resp, ctx);
asn_enc_rval_t er = asn_encode_to_buffer(0, ATS_BER, &asn_DEF_XRANCPDU, resp, resp_buf, resp_buf_size);
if(er.encoded > resp_buf_size) {
fprintf(stderr, "Buffer of size %d is too small for %s, need %zu\n",
resp_buf_size, asn_DEF_XRANCPDU.name, er.encoded);
}

ASN_STRUCT_FREE(asn_DEF_XRANCPDU, resp);

return er.encoded;
}
2 changes: 1 addition & 1 deletion enbsim/cell_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
#include <XRANCPDU.h>
#include "context.h"

void cell_config_request(XRANCPDU *pdu, context_t *ctx);
int cell_config_request(XRANCPDU *req, char *resp_buf, int resp_buf_size);
#endif
26 changes: 0 additions & 26 deletions enbsim/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,3 @@ void closecontext(context_t *context) {
}
}
}

/*
void context_timers_add(context_t *context) {
cell_config_timer_add(context);
}
*/

void context_send(XRANCPDU *pdu, context_t *context) {
char buffer[4096];
int buf_size = 4096;
asn_enc_rval_t er;

er = asn_encode_to_buffer(0, ATS_BER, &asn_DEF_XRANCPDU, pdu, buffer, buf_size);
if(er.encoded > buf_size) {
fprintf(stderr, "Buffer of size %d is too small for %s, need %zu\n",
buf_size, asn_DEF_XRANCPDU.name, er.encoded);
}

struct evbuffer *tmp = evbuffer_new();
evbuffer_add(tmp, buffer, er.encoded);
if (bufferevent_write_buffer(context->buf_ev, tmp)) {
printf("Error sending data to context on fd %d\n", context->fd);
closecontext(context);
}
evbuffer_free(tmp);
}
33 changes: 24 additions & 9 deletions enbsim/dispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,31 @@
#include "dispatch.h"
#include "context.h"
#include "cell_config.h"
//#include "handler.h"

void dispatch(uint8_t *buffer, size_t buf_size, context_t *context) {
XRANCPDU *pdu = 0;
XRANCPDU *req_pdu = 0;
asn_dec_rval_t rval;
rval = asn_decode(0, ATS_BER, &asn_DEF_XRANCPDU, (void **)&pdu, buffer, buf_size);

int resp_buf_size = 4096;
char resp_buf[resp_buf_size];
int nbytes = 0;

rval = asn_decode(0, ATS_BER, &asn_DEF_XRANCPDU, (void **)&req_pdu, buffer, buf_size);
switch (rval.code) {
case RC_OK:
break;
case RC_WMORE:
case RC_FAIL:
default:
ASN_STRUCT_FREE(asn_DEF_XRANCPDU, pdu);
ASN_STRUCT_FREE(asn_DEF_XRANCPDU, req_pdu);
return;
}

xer_fprint(stdout, &asn_DEF_XRANCPDU, pdu);
switch (pdu->hdr.api_id) {
xer_fprint(stdout, &asn_DEF_XRANCPDU, req_pdu);

switch (req_pdu->hdr.api_id) {
case XRANC_API_ID_cellConfigRequest:
cell_config_request(pdu, context);
nbytes = cell_config_request(req_pdu, resp_buf, resp_buf_size);
break;
/*
case XRANC_API_ID_uEAdmissionRequest:
Expand All @@ -60,8 +65,18 @@ void dispatch(uint8_t *buffer, size_t buf_size, context_t *context) {
break;
*/
default:
printf("Message %lu not handled\n", pdu->hdr.api_id);
printf("Message %lu not handled\n", req_pdu->hdr.api_id);
}

ASN_STRUCT_FREE(asn_DEF_XRANCPDU, pdu);
ASN_STRUCT_FREE(asn_DEF_XRANCPDU, req_pdu);

if (nbytes) {
struct evbuffer *tmp = evbuffer_new();
evbuffer_add(tmp, resp_buf, nbytes);
if (bufferevent_write_buffer(context->buf_ev, tmp)) {
printf("Error sending data to context on fd %d\n", context->fd);
closecontext(context);
}
evbuffer_free(tmp);
}
}
100 changes: 40 additions & 60 deletions enbsim/enbsim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,29 @@ static void set_tcp_no_delay(evutil_socket_t fd)
TCP_NODELAY, &one, sizeof one);
}

static void timeoutcb(evutil_socket_t fd, short what, void *arg)
{
struct event_base *base = (struct event_base *)arg;
printf("timeout\n");
static int create_bind_socket(int enb_id) {

char ip[18];
int fd;
struct sockaddr_in localaddr;

fd = socket(AF_INET, SOCK_STREAM,
#ifdef USE_SCTP
IPPROTO_SCTP
#else
IPPROTO_TCP
#endif
);

event_base_loopexit(base, NULL);

sprintf(ip, "127.0.0.%d", enb_id);
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr(ip);
localaddr.sin_port = 0; // Any local port will do

bind(fd, (struct sockaddr *)&localaddr, sizeof(localaddr));

return fd;
}

static void readcb(struct bufferevent *bev, void *arg)
Expand All @@ -61,14 +78,6 @@ static void readcb(struct bufferevent *bev, void *arg)
}

dispatch((uint8_t *)data, tbytes, ctx);

struct evbuffer *output = bufferevent_get_output(bev);

++total_messages_read;
total_bytes_read += tbytes;

/* Copy all the data from the input buffer to the output buffer. */
evbuffer_add_buffer(output, input);
}

static void eventcb(struct bufferevent *bev, short events, void *ptr)
Expand All @@ -85,85 +94,56 @@ int enbsim_main(int argc, char **argv, const Config& config)
{
//struct bufferevent **bevs;
struct sockaddr_in sin;
struct event *evtimeout;
struct timeval timeout;
int i;

if (argc != 5) {
fprintf(stderr, "Usage: client <ip> <port> <sessions> <time>\n");
fprintf(stderr, "Usage: enbsim <ip> <port> <num-enbs>\n");
return 1;
}

char *server_ip = argv[1];
int port = atoi(argv[2]);
int session_count = atoi(argv[3]);
int seconds = atoi(argv[4]);
timeout.tv_sec = seconds;
timeout.tv_usec = 0;

/* Create a context object. */
context_t *context;
if ((context = (context_t*)malloc(sizeof(*context))) == NULL) {
printf("failed to allocate memory for client state");
return 1;
}

context->fd = socket(AF_INET, SOCK_STREAM,
#ifdef USE_SCTP
IPPROTO_SCTP
#else
IPPROTO_TCP
#endif
);

context->evbase = event_base_new();
if (!context->evbase) {
puts("Couldn't open event base");
return 1;
}

evtimeout = evtimer_new(context->evbase, timeoutcb, context->evbase);
evtimer_add(evtimeout, &timeout);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
inet_pton(AF_INET, server_ip, &(sin.sin_addr));
sin.sin_port = htons(port);

//bevs = (struct bufferevent **)malloc(session_count * sizeof(struct bufferevent *));
for (i = 0; i < session_count; ++i) {
context->buf_ev = bufferevent_socket_new(context->evbase, context->fd, BEV_OPT_CLOSE_ON_FREE);
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);
//evbuffer_add(bufferevent_get_output(context->buf_ev), message, block_size);

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;
}
//bevs[i] = context->buf_ev;
}

event_base_dispatch(context->evbase);
event_base_dispatch(evbase);

for (i = 0; i < session_count; ++i) {
//bufferevent_free(bevs[i]);
}
//free(bevs);
event_free(evtimeout);
event_base_free(context->evbase);
//free(message);
event_base_free(evbase);

printf("%zd total bytes read\n", total_bytes_read);
printf("%zd total messages read\n", total_messages_read);
printf("%.3f average messages size\n",
(double)total_bytes_read / total_messages_read);
printf("%.3f MiB/s throughtput\n",
(double)total_bytes_read / (timeout.tv_sec * 1024 * 1024));

return 0;
}

55 changes: 41 additions & 14 deletions enbsim/enbsim.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"cell_config" : {
"nodes": [
{
"ip_addr": "127.0.0.1",
"plmn_id": "000001",
"eci": "00000010",
"pci": 51,
Expand All @@ -8,17 +10,42 @@
"pci": 51,
"earfcn_dl": 51
}
],
"earfcn_dl": 51,
"earfcn_ul": 38000,
"rbs_per_tti_dl": 40,
"rbs_per_tti_ul": 40,
"num_tx_antenna": 2,
"duplex_mode": "fdd",
"max_num_connected_ues": 1000,
"max_num_connected_bearers": 2000,
"max_num_ues_sched_per_tti_dl": 10,
"max_num_ues_sched_per_tti_ul": 10,
"dlfs_sched_enable": true
}
]
},
{
"ip_addr": "127.0.0.2",
"plmn_id": "000002",
"eci": "00000020",
"pci": 51,
"c_and_s_cells": [
{
"pci": 51,
"earfcn_dl": 51
}
]
},
{
"ip_addr": "127.0.0.3",
"plmn_id": "000003",
"eci": "00000030",
"pci": 51,
"c_and_s_cells": [
{
"pci": 51,
"earfcn_dl": 51
}
]
}
],
"earfcn_dl": 51,
"earfcn_ul": 38000,
"rbs_per_tti_dl": 40,
"rbs_per_tti_ul": 40,
"num_tx_antenna": 2,
"duplex_mode": "fdd",
"max_num_connected_ues": 1000,
"max_num_connected_bearers": 2000,
"max_num_ues_sched_per_tti_dl": 10,
"max_num_ues_sched_per_tti_ul": 10,
"dlfs_sched_enable": true
}
8 changes: 4 additions & 4 deletions xranc/xran-cfg.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
{
"plmn_id": "000001",
"eci": "00000010",
"ip_addr": "1.1.1.2"
"ip_addr": "127.0.0.1"
},
{
"plmn_id": "000002",
"eci": "00000020",
"ip_addr": "1.1.1.3"
"ip_addr": "127.0.0.2"
},
{
"plmn_id": "000003",
"eci": "00000030",
"ip_addr": "127.0.0.1"
},
"ip_addr": "127.0.0.3"
}
],
"l2_meas_report_interval_ms": 5000,
"rx_signal_meas_report_interval_ms": 7000,
Expand Down

0 comments on commit 0bbf0b6

Please sign in to comment.