trxcon: support handling of multiple L1CTL client connections

Change-Id: Id92e5b553487e4cf10ea291b487a3ef0c65d72ae
This commit is contained in:
Vadim Yanitskiy 2022-07-20 06:56:44 +07:00
parent 9734224875
commit cea02697a9
5 changed files with 45 additions and 15 deletions

View File

@ -37,6 +37,8 @@ struct l1ctl_server {
struct llist_head clients;
/* number of connected clients */
unsigned int num_clients;
/* used for client ID generation */
unsigned int next_client_id;
/* socket on which we listen for connections */
struct osmo_fd ofd;
/* server configuration */
@ -52,6 +54,8 @@ struct l1ctl_client {
struct osmo_wqueue wq;
/* logging context (used as prefix for messages) */
const char *log_prefix;
/* unique client ID */
unsigned int id;
/* some private data */
void *priv;
};

View File

@ -21,6 +21,7 @@ enum trxcon_fsm_events {
struct trxcon_inst {
struct osmo_fsm_inst *fi;
unsigned int id;
/* Logging context for sched and l1c */
const char *log_prefix;
@ -36,5 +37,5 @@ struct trxcon_inst {
bool fbsb_conf_sent;
};
struct trxcon_inst *trxcon_inst_alloc(void *ctx);
struct trxcon_inst *trxcon_inst_alloc(void *ctx, unsigned int id);
void trxcon_inst_free(struct trxcon_inst *trxcon);

View File

@ -51,7 +51,9 @@ static int l1ctl_client_read_cb(struct osmo_fd *ofd)
/* Attempt to read from socket */
rc = read(ofd->fd, &len, L1CTL_MSG_LEN_FIELD);
if (rc < L1CTL_MSG_LEN_FIELD) {
LOGP_CLI(client, DL1D, LOGL_NOTICE, "L1CTL server has lost connection\n");
LOGP_CLI(client, DL1D, LOGL_NOTICE,
"L1CTL server has lost connection (id=%u)\n",
client->id);
if (rc >= 0)
rc = -EIO;
l1ctl_client_conn_close(client);
@ -157,12 +159,13 @@ static int l1ctl_server_conn_cb(struct osmo_fd *sfd, unsigned int flags)
return rc;
}
LOGP(DL1C, LOGL_NOTICE, "L1CTL server got a new connection\n");
llist_add_tail(&client->list, &server->clients);
client->id = server->next_client_id++;
client->server = server;
server->num_clients++;
LOGP(DL1C, LOGL_NOTICE, "L1CTL server got a new connection (id=%u)\n", client->id);
if (client->server->cfg->conn_accept_cb != NULL)
client->server->cfg->conn_accept_cb(client);
@ -194,8 +197,10 @@ int l1ctl_client_send(struct l1ctl_client *client, struct msgb *msg)
void l1ctl_client_conn_close(struct l1ctl_client *client)
{
if (client->server->cfg->conn_close_cb != NULL)
client->server->cfg->conn_close_cb(client);
struct l1ctl_server *server = client->server;
if (server->cfg->conn_close_cb != NULL)
server->cfg->conn_close_cb(client);
/* Close connection socket */
osmo_fd_unregister(&client->wq.bfd);
@ -208,6 +213,11 @@ void l1ctl_client_conn_close(struct l1ctl_client *client)
client->server->num_clients--;
llist_del(&client->list);
talloc_free(client);
/* If this was the last client, reset the client IDs generator to 0.
* This way avoid assigning huge unreadable client IDs like 26545. */
if (llist_empty(&server->clients))
server->next_client_id = 0;
}
struct l1ctl_server *l1ctl_server_alloc(void *ctx, const struct l1ctl_server_cfg *cfg)

View File

@ -697,11 +697,12 @@ struct trx_instance *trx_if_open(struct trxcon_inst *trxcon,
const char *local_host, const char *remote_host,
uint16_t base_port)
{
const unsigned int offset = trxcon->id * 2;
struct trx_instance *trx;
int rc;
LOGPFSML(trxcon->fi, LOGL_NOTICE, "Init transceiver interface "
"(%s:%u)\n", remote_host, base_port);
"(%s:%u/%u)\n", remote_host, base_port, trxcon->id);
/* Try to allocate memory */
trx = talloc_zero(trxcon, struct trx_instance);
@ -723,13 +724,17 @@ struct trx_instance *trx_if_open(struct trxcon_inst *trxcon,
INIT_LLIST_HEAD(&trx->trx_ctrl_list);
/* Open sockets */
rc = trx_udp_open(trx, &trx->trx_ofd_ctrl, local_host,
base_port + 101, remote_host, base_port + 1, trx_ctrl_read_cb);
rc = trx_udp_open(trx, &trx->trx_ofd_ctrl, /* TRXC */
local_host, base_port + 101 + offset,
remote_host, base_port + 1 + offset,
trx_ctrl_read_cb);
if (rc < 0)
goto udp_error;
rc = trx_udp_open(trx, &trx->trx_ofd_data, local_host,
base_port + 102, remote_host, base_port + 2, trx_data_rx_cb);
rc = trx_udp_open(trx, &trx->trx_ofd_data, /* TRXD */
local_host, base_port + 102 + offset,
remote_host, base_port + 2 + offset,
trx_data_rx_cb);
if (rc < 0)
goto udp_error;

View File

@ -65,6 +65,7 @@ static struct {
int quit;
/* L1CTL specific */
unsigned int max_clients;
const char *bind_socket;
/* TRX specific */
@ -77,6 +78,7 @@ static struct {
struct gsmtap_inst *gsmtap;
const char *gsmtap_ip;
} app_data = {
.max_clients = 1, /* only one L1CTL client by default */
.bind_socket = "/tmp/osmocom_l2",
.trx_remote_ip = "127.0.0.1",
.trx_bind_ip = "0.0.0.0",
@ -322,7 +324,7 @@ static struct osmo_fsm trxcon_fsm_def = {
.event_names = trxcon_fsm_event_names,
};
struct trxcon_inst *trxcon_inst_alloc(void *ctx)
struct trxcon_inst *trxcon_inst_alloc(void *ctx, unsigned int id)
{
struct trxcon_inst *trxcon;
@ -333,6 +335,9 @@ struct trxcon_inst *trxcon_inst_alloc(void *ctx)
trxcon, LOGL_DEBUG, NULL);
OSMO_ASSERT(trxcon->fi != NULL);
osmo_fsm_inst_update_id_f(trxcon->fi, "%u", id);
trxcon->id = id;
/* Logging context to be used by both l1ctl and l1sched modules */
trxcon->log_prefix = talloc_asprintf(trxcon, "%s: ", osmo_fsm_inst_name(trxcon->fi));
@ -383,7 +388,7 @@ static void l1ctl_conn_accept_cb(struct l1ctl_client *l1c)
{
struct trxcon_inst *trxcon;
trxcon = trxcon_inst_alloc(l1c);
trxcon = trxcon_inst_alloc(l1c, l1c->id);
if (trxcon == NULL) {
l1ctl_client_conn_close(l1c);
return;
@ -422,6 +427,7 @@ static void print_help(void)
printf(" -f --trx-advance Uplink burst scheduling advance (default 3)\n");
printf(" -s --socket Listening socket for layer23 (default /tmp/osmocom_l2)\n");
printf(" -g --gsmtap-ip The destination IP used for GSMTAP (disabled by default)\n");
printf(" -C --max-clients Maximum number of L1CTL connections (default 1)\n");
printf(" -D --daemonize Run as daemon\n");
}
@ -441,11 +447,12 @@ static void handle_options(int argc, char **argv)
{"trx-port", 1, 0, 'p'},
{"trx-advance", 1, 0, 'f'},
{"gsmtap-ip", 1, 0, 'g'},
{"max-clients", 1, 0, 'C'},
{"daemonize", 0, 0, 'D'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "d:b:i:p:f:s:g:Dh",
c = getopt_long(argc, argv, "d:b:i:p:f:s:g:C:Dh",
long_options, &option_index);
if (c == -1)
break;
@ -477,6 +484,9 @@ static void handle_options(int argc, char **argv)
case 'g':
app_data.gsmtap_ip = optarg;
break;
case 'C':
app_data.max_clients = atoi(optarg);
break;
case 'D':
app_data.daemonize = 1;
break;
@ -567,7 +577,7 @@ int main(int argc, char **argv)
/* Start the L1CTL server */
server_cfg = (struct l1ctl_server_cfg) {
.sock_path = app_data.bind_socket,
.num_clients_max = 1, /* only one connection for now */
.num_clients_max = app_data.max_clients,
.conn_read_cb = &l1ctl_rx_cb,
.conn_accept_cb = &l1ctl_conn_accept_cb,
.conn_close_cb = &l1ctl_conn_close_cb,