trxcon: rework L1CTL socket API to support multiple clients
Change-Id: I1cfc49f36ead6e2ba0a6110b0fb65c55412ef5e3
This commit is contained in:
parent
a89492a4dd
commit
506e9085e3
|
@ -7,21 +7,21 @@
|
|||
#include <osmocom/bb/trxcon/l1ctl_proto.h>
|
||||
|
||||
/* Event handlers */
|
||||
int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg);
|
||||
int l1ctl_rx_cb(struct l1ctl_client *l1c, struct msgb *msg);
|
||||
|
||||
int l1ctl_tx_fbsb_conf(struct l1ctl_link *l1l, uint8_t result,
|
||||
int l1ctl_tx_fbsb_conf(struct l1ctl_client *l1c, uint8_t result,
|
||||
const struct l1ctl_info_dl *dl_info, uint8_t bsic);
|
||||
int l1ctl_tx_ccch_mode_conf(struct l1ctl_link *l1l, uint8_t mode);
|
||||
int l1ctl_tx_pm_conf(struct l1ctl_link *l1l, uint16_t band_arfcn,
|
||||
int l1ctl_tx_ccch_mode_conf(struct l1ctl_client *l1c, uint8_t mode);
|
||||
int l1ctl_tx_pm_conf(struct l1ctl_client *l1c, uint16_t band_arfcn,
|
||||
int dbm, int last);
|
||||
int l1ctl_tx_reset_conf(struct l1ctl_link *l1l, uint8_t type);
|
||||
int l1ctl_tx_reset_ind(struct l1ctl_link *l1l, uint8_t type);
|
||||
int l1ctl_tx_reset_conf(struct l1ctl_client *l1c, uint8_t type);
|
||||
int l1ctl_tx_reset_ind(struct l1ctl_client *l1c, uint8_t type);
|
||||
|
||||
int l1ctl_tx_dt_ind(struct l1ctl_link *l1l,
|
||||
int l1ctl_tx_dt_ind(struct l1ctl_client *l1c,
|
||||
const struct l1ctl_info_dl *dl_info,
|
||||
const uint8_t *l2, size_t l2_len,
|
||||
bool traffic);
|
||||
int l1ctl_tx_dt_conf(struct l1ctl_link *l1l,
|
||||
int l1ctl_tx_dt_conf(struct l1ctl_client *l1c,
|
||||
struct l1ctl_info_dl *data, bool traffic);
|
||||
int l1ctl_tx_rach_conf(struct l1ctl_link *l1l,
|
||||
int l1ctl_tx_rach_conf(struct l1ctl_client *l1c,
|
||||
uint16_t band_arfcn, uint32_t fn);
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/fsm.h>
|
||||
|
||||
#define L1CTL_LENGTH 256
|
||||
#define L1CTL_HEADROOM 32
|
||||
|
@ -17,22 +16,49 @@
|
|||
*/
|
||||
#define L1CTL_MSG_LEN_FIELD 2
|
||||
|
||||
enum l1ctl_fsm_states {
|
||||
L1CTL_STATE_IDLE = 0,
|
||||
L1CTL_STATE_CONNECTED,
|
||||
struct l1ctl_client;
|
||||
|
||||
typedef int l1ctl_conn_data_func(struct l1ctl_client *, struct msgb *);
|
||||
typedef void l1ctl_conn_state_func(struct l1ctl_client *);
|
||||
|
||||
struct l1ctl_server_cfg {
|
||||
/* UNIX socket path to listen on */
|
||||
const char *sock_path;
|
||||
/* talloc context to be used for new clients */
|
||||
void *talloc_ctx;
|
||||
/* maximum number of connected clients */
|
||||
unsigned int num_clients_max;
|
||||
/* functions to be called on various events */
|
||||
l1ctl_conn_data_func *conn_read_cb; /* mandatory */
|
||||
l1ctl_conn_state_func *conn_accept_cb; /* optional */
|
||||
l1ctl_conn_state_func *conn_close_cb; /* optional */
|
||||
};
|
||||
|
||||
struct l1ctl_link {
|
||||
struct osmo_fsm_inst *fsm;
|
||||
struct osmo_fd listen_bfd;
|
||||
struct osmo_wqueue wq;
|
||||
struct l1ctl_server {
|
||||
/* list of connected clients */
|
||||
struct llist_head clients;
|
||||
/* number of connected clients */
|
||||
unsigned int num_clients;
|
||||
/* socket on which we listen for connections */
|
||||
struct osmo_fd ofd;
|
||||
/* server configuration */
|
||||
const struct l1ctl_server_cfg *cfg;
|
||||
};
|
||||
|
||||
/* Some private data */
|
||||
struct l1ctl_client {
|
||||
/* list head in l1ctl_server.clients */
|
||||
struct llist_head list;
|
||||
/* struct l1ctl_server we belong to */
|
||||
struct l1ctl_server *server;
|
||||
/* client's write queue */
|
||||
struct osmo_wqueue wq;
|
||||
/* some private data */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct l1ctl_link *l1ctl_link_init(void *tall_ctx, const char *sock_path);
|
||||
void l1ctl_link_shutdown(struct l1ctl_link *l1l);
|
||||
int l1ctl_server_start(struct l1ctl_server *server,
|
||||
const struct l1ctl_server_cfg *cfg);
|
||||
void l1ctl_server_shutdown(struct l1ctl_server *server);
|
||||
|
||||
int l1ctl_link_send(struct l1ctl_link *l1l, struct msgb *msg);
|
||||
int l1ctl_link_close_conn(struct l1ctl_link *l1l);
|
||||
int l1ctl_client_send(struct l1ctl_client *client, struct msgb *msg);
|
||||
void l1ctl_client_conn_close(struct l1ctl_client *client);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
struct l1sched_state;
|
||||
struct trx_instance;
|
||||
struct l1ctl_link;
|
||||
struct l1ctl_client;
|
||||
|
||||
enum trxcon_fsm_states {
|
||||
TRXCON_STATE_IDLE = 0,
|
||||
|
@ -28,7 +28,7 @@ struct trxcon_inst {
|
|||
struct l1sched_state *sched;
|
||||
/* L1/L2 interfaces */
|
||||
struct trx_instance *trx;
|
||||
struct l1ctl_link *l1l;
|
||||
struct l1ctl_client *l1c;
|
||||
|
||||
/* TODO: implement this as an FSM state with timeout */
|
||||
struct osmo_timer_list fbsb_timer;
|
||||
|
|
|
@ -77,7 +77,7 @@ static struct msgb *l1ctl_alloc_msg(uint8_t msg_type)
|
|||
return msg;
|
||||
}
|
||||
|
||||
int l1ctl_tx_pm_conf(struct l1ctl_link *l1l, uint16_t band_arfcn,
|
||||
int l1ctl_tx_pm_conf(struct l1ctl_client *l1c, uint16_t band_arfcn,
|
||||
int dbm, int last)
|
||||
{
|
||||
struct l1ctl_pm_conf *pmc;
|
||||
|
@ -101,10 +101,10 @@ int l1ctl_tx_pm_conf(struct l1ctl_link *l1l, uint16_t band_arfcn,
|
|||
l1h->flags |= L1CTL_F_DONE;
|
||||
}
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
int l1ctl_tx_reset_ind(struct l1ctl_link *l1l, uint8_t type)
|
||||
int l1ctl_tx_reset_ind(struct l1ctl_client *l1c, uint8_t type)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct l1ctl_reset *res;
|
||||
|
@ -118,10 +118,10 @@ int l1ctl_tx_reset_ind(struct l1ctl_link *l1l, uint8_t type)
|
|||
res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
|
||||
res->type = type;
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
int l1ctl_tx_reset_conf(struct l1ctl_link *l1l, uint8_t type)
|
||||
int l1ctl_tx_reset_conf(struct l1ctl_client *l1c, uint8_t type)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct l1ctl_reset *res;
|
||||
|
@ -134,7 +134,7 @@ int l1ctl_tx_reset_conf(struct l1ctl_link *l1l, uint8_t type)
|
|||
res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
|
||||
res->type = type;
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
static struct l1ctl_info_dl *put_dl_info_hdr(struct msgb *msg,
|
||||
|
@ -164,10 +164,10 @@ static struct l1ctl_fbsb_conf *fbsb_conf_make(struct msgb *msg, uint8_t result,
|
|||
return conf;
|
||||
}
|
||||
|
||||
int l1ctl_tx_fbsb_conf(struct l1ctl_link *l1l, uint8_t result,
|
||||
int l1ctl_tx_fbsb_conf(struct l1ctl_client *l1c, uint8_t result,
|
||||
const struct l1ctl_info_dl *dl_info, uint8_t bsic)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_fbsb_conf *conf;
|
||||
struct msgb *msg;
|
||||
|
||||
|
@ -189,10 +189,10 @@ int l1ctl_tx_fbsb_conf(struct l1ctl_link *l1l, uint8_t result,
|
|||
if (osmo_timer_pending(&trxcon->fbsb_timer))
|
||||
osmo_timer_del(&trxcon->fbsb_timer);
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
int l1ctl_tx_ccch_mode_conf(struct l1ctl_link *l1l, uint8_t mode)
|
||||
int l1ctl_tx_ccch_mode_conf(struct l1ctl_client *l1c, uint8_t mode)
|
||||
{
|
||||
struct l1ctl_ccch_mode_conf *conf;
|
||||
struct msgb *msg;
|
||||
|
@ -204,13 +204,13 @@ int l1ctl_tx_ccch_mode_conf(struct l1ctl_link *l1l, uint8_t mode)
|
|||
conf = (struct l1ctl_ccch_mode_conf *) msgb_put(msg, sizeof(*conf));
|
||||
conf->ccch_mode = mode;
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles both L1CTL_DATA_IND and L1CTL_TRAFFIC_IND.
|
||||
*/
|
||||
int l1ctl_tx_dt_ind(struct l1ctl_link *l1l,
|
||||
int l1ctl_tx_dt_ind(struct l1ctl_client *l1c,
|
||||
const struct l1ctl_info_dl *dl_info,
|
||||
const uint8_t *l2, size_t l2_len,
|
||||
bool traffic)
|
||||
|
@ -232,10 +232,10 @@ int l1ctl_tx_dt_ind(struct l1ctl_link *l1l,
|
|||
}
|
||||
|
||||
/* Put message to upper layers */
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
int l1ctl_tx_rach_conf(struct l1ctl_link *l1l,
|
||||
int l1ctl_tx_rach_conf(struct l1ctl_client *l1c,
|
||||
uint16_t band_arfcn, uint32_t fn)
|
||||
{
|
||||
struct l1ctl_info_dl *dl;
|
||||
|
@ -251,14 +251,14 @@ int l1ctl_tx_rach_conf(struct l1ctl_link *l1l,
|
|||
dl->band_arfcn = htons(band_arfcn);
|
||||
dl->frame_nr = htonl(fn);
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles both L1CTL_DATA_CONF and L1CTL_TRAFFIC_CONF.
|
||||
*/
|
||||
int l1ctl_tx_dt_conf(struct l1ctl_link *l1l,
|
||||
int l1ctl_tx_dt_conf(struct l1ctl_client *l1c,
|
||||
struct l1ctl_info_dl *data, bool traffic)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
@ -271,7 +271,7 @@ int l1ctl_tx_dt_conf(struct l1ctl_link *l1l,
|
|||
/* Copy DL frame header from source message */
|
||||
put_dl_info_hdr(msg, data);
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
static enum gsm_phys_chan_config l1ctl_ccch_mode2pchan_config(enum ccch_mode mode)
|
||||
|
@ -297,8 +297,8 @@ static enum gsm_phys_chan_config l1ctl_ccch_mode2pchan_config(enum ccch_mode mod
|
|||
/* FBSB expire timer */
|
||||
static void fbsb_timer_cb(void *data)
|
||||
{
|
||||
struct l1ctl_link *l1l = (struct l1ctl_link *) data;
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct l1ctl_client *l1c = (struct l1ctl_client *) data;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_info_dl *dl;
|
||||
struct msgb *msg;
|
||||
|
||||
|
@ -319,12 +319,12 @@ static void fbsb_timer_cb(void *data)
|
|||
/* Ask SCH handler not to send L1CTL_FBSB_CONF anymore */
|
||||
trxcon->fbsb_conf_sent = true;
|
||||
|
||||
l1ctl_link_send(l1l, msg);
|
||||
l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
static int l1ctl_rx_fbsb_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_fbsb_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
enum gsm_phys_chan_config ch_config;
|
||||
struct l1ctl_fbsb_req *fbsb;
|
||||
uint16_t band_arfcn;
|
||||
|
@ -372,7 +372,7 @@ static int l1ctl_rx_fbsb_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
trx_if_cmd_poweron(trxcon->trx);
|
||||
|
||||
/* Start FBSB expire timer */
|
||||
trxcon->fbsb_timer.data = l1l;
|
||||
trxcon->fbsb_timer.data = l1c;
|
||||
trxcon->fbsb_timer.cb = fbsb_timer_cb;
|
||||
LOGP(DL1C, LOGL_INFO, "Starting FBSB timer %u ms\n", timeout * GSM_TDMA_FN_DURATION_uS / 1000);
|
||||
osmo_timer_schedule(&trxcon->fbsb_timer, 0,
|
||||
|
@ -383,10 +383,10 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_pm_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_pm_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
uint16_t band_arfcn_start, band_arfcn_stop;
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_pm_req *pmr;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -415,9 +415,9 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_reset_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_reset_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_reset *res;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -448,14 +448,14 @@ static int l1ctl_rx_reset_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
}
|
||||
|
||||
/* Confirm */
|
||||
rc = l1ctl_tx_reset_conf(l1l, res->type);
|
||||
rc = l1ctl_tx_reset_conf(l1c, res->type);
|
||||
|
||||
exit:
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_echo_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_echo_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct l1ctl_hdr *l1h;
|
||||
|
||||
|
@ -467,12 +467,12 @@ static int l1ctl_rx_echo_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
l1h->msg_type = L1CTL_ECHO_CONF;
|
||||
msg->data = msg->l1h;
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
static int l1ctl_rx_ccch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_ccch_mode_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
enum gsm_phys_chan_config ch_config;
|
||||
struct l1ctl_ccch_mode_req *req;
|
||||
struct l1sched_ts *ts;
|
||||
|
@ -506,16 +506,16 @@ static int l1ctl_rx_ccch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
|
||||
/* Confirm reconfiguration */
|
||||
if (!rc)
|
||||
rc = l1ctl_tx_ccch_mode_conf(l1l, req->ccch_mode);
|
||||
rc = l1ctl_tx_ccch_mode_conf(l1c, req->ccch_mode);
|
||||
|
||||
exit:
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_rach_req(struct l1ctl_link *l1l, struct msgb *msg, bool ext)
|
||||
static int l1ctl_rx_rach_req(struct l1ctl_client *l1c, struct msgb *msg, bool ext)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_info_ul *ul;
|
||||
struct l1sched_ts_prim *prim;
|
||||
struct l1sched_ts_prim_rach rach;
|
||||
|
@ -631,9 +631,9 @@ static int l1ctl_proc_est_req_h1(struct trx_instance *trx, struct l1ctl_h1 *h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_dm_est_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_dm_est_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
enum gsm_phys_chan_config config;
|
||||
struct l1ctl_dm_est_req *est_req;
|
||||
struct l1ctl_info_ul *ul;
|
||||
|
@ -691,9 +691,9 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_dm_rel_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_dm_rel_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
|
||||
LOGP(DL1C, LOGL_NOTICE, "Received L1CTL_DM_REL_REQ, resetting scheduler\n");
|
||||
|
||||
|
@ -707,10 +707,10 @@ static int l1ctl_rx_dm_rel_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
/**
|
||||
* Handles both L1CTL_DATA_REQ and L1CTL_TRAFFIC_REQ.
|
||||
*/
|
||||
static int l1ctl_rx_dt_req(struct l1ctl_link *l1l,
|
||||
static int l1ctl_rx_dt_req(struct l1ctl_client *l1c,
|
||||
struct msgb *msg, bool traffic)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_info_ul *ul;
|
||||
struct l1sched_ts_prim *prim;
|
||||
uint8_t chan_nr, link_id;
|
||||
|
@ -742,9 +742,9 @@ static int l1ctl_rx_dt_req(struct l1ctl_link *l1l,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_param_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_param_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_par_req *par_req;
|
||||
struct l1ctl_info_ul *ul;
|
||||
|
||||
|
@ -766,9 +766,9 @@ static int l1ctl_rx_param_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l1ctl_rx_tch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_tch_mode_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_tch_mode_req *req;
|
||||
struct l1sched_lchan_state *lchan;
|
||||
struct l1sched_ts *ts;
|
||||
|
@ -807,12 +807,12 @@ static int l1ctl_rx_tch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data;
|
||||
l1h->msg_type = L1CTL_TCH_MODE_CONF;
|
||||
|
||||
return l1ctl_link_send(l1l, msg);
|
||||
return l1ctl_client_send(l1c, msg);
|
||||
}
|
||||
|
||||
static int l1ctl_rx_crypto_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
static int l1ctl_rx_crypto_req(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
struct l1ctl_crypto_req *req;
|
||||
struct l1ctl_info_ul *ul;
|
||||
struct l1sched_ts *ts;
|
||||
|
@ -849,7 +849,7 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
int l1ctl_rx_cb(struct l1ctl_client *l1c, struct msgb *msg)
|
||||
{
|
||||
struct l1ctl_hdr *l1h;
|
||||
|
||||
|
@ -858,33 +858,33 @@ int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
|
||||
switch (l1h->msg_type) {
|
||||
case L1CTL_FBSB_REQ:
|
||||
return l1ctl_rx_fbsb_req(l1l, msg);
|
||||
return l1ctl_rx_fbsb_req(l1c, msg);
|
||||
case L1CTL_PM_REQ:
|
||||
return l1ctl_rx_pm_req(l1l, msg);
|
||||
return l1ctl_rx_pm_req(l1c, msg);
|
||||
case L1CTL_RESET_REQ:
|
||||
return l1ctl_rx_reset_req(l1l, msg);
|
||||
return l1ctl_rx_reset_req(l1c, msg);
|
||||
case L1CTL_ECHO_REQ:
|
||||
return l1ctl_rx_echo_req(l1l, msg);
|
||||
return l1ctl_rx_echo_req(l1c, msg);
|
||||
case L1CTL_CCCH_MODE_REQ:
|
||||
return l1ctl_rx_ccch_mode_req(l1l, msg);
|
||||
return l1ctl_rx_ccch_mode_req(l1c, msg);
|
||||
case L1CTL_RACH_REQ:
|
||||
return l1ctl_rx_rach_req(l1l, msg, false);
|
||||
return l1ctl_rx_rach_req(l1c, msg, false);
|
||||
case L1CTL_EXT_RACH_REQ:
|
||||
return l1ctl_rx_rach_req(l1l, msg, true);
|
||||
return l1ctl_rx_rach_req(l1c, msg, true);
|
||||
case L1CTL_DM_EST_REQ:
|
||||
return l1ctl_rx_dm_est_req(l1l, msg);
|
||||
return l1ctl_rx_dm_est_req(l1c, msg);
|
||||
case L1CTL_DM_REL_REQ:
|
||||
return l1ctl_rx_dm_rel_req(l1l, msg);
|
||||
return l1ctl_rx_dm_rel_req(l1c, msg);
|
||||
case L1CTL_DATA_REQ:
|
||||
return l1ctl_rx_dt_req(l1l, msg, false);
|
||||
return l1ctl_rx_dt_req(l1c, msg, false);
|
||||
case L1CTL_TRAFFIC_REQ:
|
||||
return l1ctl_rx_dt_req(l1l, msg, true);
|
||||
return l1ctl_rx_dt_req(l1c, msg, true);
|
||||
case L1CTL_PARAM_REQ:
|
||||
return l1ctl_rx_param_req(l1l, msg);
|
||||
return l1ctl_rx_param_req(l1c, msg);
|
||||
case L1CTL_TCH_MODE_REQ:
|
||||
return l1ctl_rx_tch_mode_req(l1l, msg);
|
||||
return l1ctl_rx_tch_mode_req(l1c, msg);
|
||||
case L1CTL_CRYPTO_REQ:
|
||||
return l1ctl_rx_crypto_req(l1l, msg);
|
||||
return l1ctl_rx_crypto_req(l1c, msg);
|
||||
|
||||
/* Not (yet) handled messages */
|
||||
case L1CTL_NEIGH_PM_REQ:
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
* OsmocomBB <-> SDR connection bridge
|
||||
* GSM L1 control socket (/tmp/osmocom_l2) handlers
|
||||
* UNIX socket server for L1CTL
|
||||
*
|
||||
* (C) 2013 by Sylvain Munaut <tnt@246tNt.com>
|
||||
* (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||
* (C) 2022 by by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
|
@ -24,60 +25,33 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <osmocom/core/fsm.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
|
||||
#include <osmocom/bb/trxcon/trxcon.h>
|
||||
#include <osmocom/bb/trxcon/logging.h>
|
||||
#include <osmocom/bb/trxcon/l1ctl_link.h>
|
||||
#include <osmocom/bb/trxcon/l1ctl.h>
|
||||
|
||||
static struct value_string l1ctl_evt_names[] = {
|
||||
{ 0, NULL } /* no events? */
|
||||
};
|
||||
|
||||
static struct osmo_fsm_state l1ctl_fsm_states[] = {
|
||||
[L1CTL_STATE_IDLE] = {
|
||||
.out_state_mask = GEN_MASK(L1CTL_STATE_CONNECTED),
|
||||
.name = "IDLE",
|
||||
},
|
||||
[L1CTL_STATE_CONNECTED] = {
|
||||
.out_state_mask = GEN_MASK(L1CTL_STATE_IDLE),
|
||||
.name = "CONNECTED",
|
||||
},
|
||||
};
|
||||
|
||||
static struct osmo_fsm l1ctl_fsm = {
|
||||
.name = "l1ctl_link_fsm",
|
||||
.states = l1ctl_fsm_states,
|
||||
.num_states = ARRAY_SIZE(l1ctl_fsm_states),
|
||||
.log_subsys = DL1C,
|
||||
.event_names = l1ctl_evt_names,
|
||||
};
|
||||
|
||||
static int l1ctl_link_read_cb(struct osmo_fd *bfd)
|
||||
static int l1ctl_client_read_cb(struct osmo_fd *ofd)
|
||||
{
|
||||
struct l1ctl_link *l1l = (struct l1ctl_link *) bfd->data;
|
||||
struct l1ctl_client *client = (struct l1ctl_client *)ofd->data;
|
||||
struct msgb *msg;
|
||||
uint16_t len;
|
||||
int rc;
|
||||
|
||||
/* Attempt to read from socket */
|
||||
rc = read(bfd->fd, &len, L1CTL_MSG_LEN_FIELD);
|
||||
rc = read(ofd->fd, &len, L1CTL_MSG_LEN_FIELD);
|
||||
if (rc < L1CTL_MSG_LEN_FIELD) {
|
||||
LOGP(DL1D, LOGL_NOTICE, "L1CTL has lost connection\n");
|
||||
LOGP(DL1D, LOGL_NOTICE, "L1CTL server has lost connection\n");
|
||||
if (rc >= 0)
|
||||
rc = -EIO;
|
||||
l1ctl_link_close_conn(l1l);
|
||||
l1ctl_client_conn_close(client);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -97,7 +71,7 @@ static int l1ctl_link_read_cb(struct osmo_fd *bfd)
|
|||
}
|
||||
|
||||
msg->l1h = msgb_put(msg, len);
|
||||
rc = read(bfd->fd, msg->l1h, msgb_l1len(msg));
|
||||
rc = read(ofd->fd, msg->l1h, msgb_l1len(msg));
|
||||
if (rc != len) {
|
||||
LOGP(DL1D, LOGL_ERROR, "Can not read data: len=%d < rc=%d: "
|
||||
"%s\n", len, rc, strerror(errno));
|
||||
|
@ -110,19 +84,19 @@ static int l1ctl_link_read_cb(struct osmo_fd *bfd)
|
|||
osmo_hexdump(msg->data, msg->len));
|
||||
|
||||
/* Call L1CTL handler */
|
||||
l1ctl_rx_cb(l1l, msg);
|
||||
client->server->cfg->conn_read_cb(client, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l1ctl_link_write_cb(struct osmo_fd *bfd, struct msgb *msg)
|
||||
static int l1ctl_client_write_cb(struct osmo_fd *ofd, struct msgb *msg)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (bfd->fd <= 0)
|
||||
if (ofd->fd <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
len = write(bfd->fd, msg->data, msg->len);
|
||||
len = write(ofd->fd, msg->data, msg->len);
|
||||
if (len != msg->len) {
|
||||
LOGP(DL1D, LOGL_ERROR, "Failed to write data: "
|
||||
"written (%d) < msg_len (%d)\n", len, msg->len);
|
||||
|
@ -133,53 +107,64 @@ static int l1ctl_link_write_cb(struct osmo_fd *bfd, struct msgb *msg)
|
|||
}
|
||||
|
||||
/* Connection handler */
|
||||
static int l1ctl_link_accept(struct osmo_fd *bfd, unsigned int flags)
|
||||
static int l1ctl_server_conn_cb(struct osmo_fd *sfd, unsigned int flags)
|
||||
{
|
||||
struct l1ctl_link *l1l = (struct l1ctl_link *) bfd->data;
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
struct osmo_fd *conn_bfd = &l1l->wq.bfd;
|
||||
struct sockaddr_un un_addr;
|
||||
socklen_t len;
|
||||
int cfd;
|
||||
struct l1ctl_server *server = (struct l1ctl_server *)sfd->data;
|
||||
struct l1ctl_client *client;
|
||||
int rc, client_fd;
|
||||
|
||||
len = sizeof(un_addr);
|
||||
cfd = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
|
||||
if (cfd < 0) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Failed to accept a new connection\n");
|
||||
return -1;
|
||||
client_fd = accept(sfd->fd, NULL, NULL);
|
||||
if (client_fd < 0) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Failed to accept() a new connection: "
|
||||
"%s\n", strerror(errno));
|
||||
return client_fd;
|
||||
}
|
||||
|
||||
/* Check if we already have an active connection */
|
||||
if (conn_bfd->fd != -1) {
|
||||
LOGP(DL1C, LOGL_NOTICE, "A new connection rejected: "
|
||||
"we already have another active\n");
|
||||
close(cfd);
|
||||
return 0;
|
||||
if (server->cfg->num_clients_max > 0 /* 0 means unlimited */ &&
|
||||
server->num_clients >= server->cfg->num_clients_max) {
|
||||
LOGP(DL1C, LOGL_NOTICE, "L1CTL server cannot accept more "
|
||||
"than %u connection(s)\n", server->cfg->num_clients_max);
|
||||
close(client_fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
osmo_wqueue_init(&l1l->wq, 100);
|
||||
INIT_LLIST_HEAD(&conn_bfd->list);
|
||||
|
||||
l1l->wq.write_cb = l1ctl_link_write_cb;
|
||||
l1l->wq.read_cb = l1ctl_link_read_cb;
|
||||
osmo_fd_setup(conn_bfd, cfd, OSMO_FD_READ, osmo_wqueue_bfd_cb, l1l, 0);
|
||||
|
||||
if (osmo_fd_register(conn_bfd) != 0) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Failed to register new connection fd\n");
|
||||
close(conn_bfd->fd);
|
||||
conn_bfd->fd = -1;
|
||||
return -1;
|
||||
client = talloc_zero(server->cfg->talloc_ctx, struct l1ctl_client);
|
||||
if (client == NULL) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Failed to allocate an L1CTL client\n");
|
||||
close(client_fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_dispatch(trxcon->fi, L1CTL_EVENT_CONNECT, l1l);
|
||||
osmo_fsm_inst_state_chg(l1l->fsm, L1CTL_STATE_CONNECTED, 0, 0);
|
||||
/* Init the client's write queue */
|
||||
osmo_wqueue_init(&client->wq, 100);
|
||||
INIT_LLIST_HEAD(&client->wq.bfd.list);
|
||||
|
||||
LOGP(DL1C, LOGL_NOTICE, "L1CTL has a new connection\n");
|
||||
client->wq.write_cb = &l1ctl_client_write_cb;
|
||||
client->wq.read_cb = &l1ctl_client_read_cb;
|
||||
osmo_fd_setup(&client->wq.bfd, client_fd, OSMO_FD_READ, &osmo_wqueue_bfd_cb, client, 0);
|
||||
|
||||
/* Register the client's write queue */
|
||||
rc = osmo_fd_register(&client->wq.bfd);
|
||||
if (rc != 0) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Failed to register a new connection fd\n");
|
||||
close(client->wq.bfd.fd);
|
||||
talloc_free(client);
|
||||
return rc;
|
||||
}
|
||||
|
||||
LOGP(DL1C, LOGL_NOTICE, "L1CTL server got a new connection\n");
|
||||
|
||||
llist_add_tail(&client->list, &server->clients);
|
||||
client->server = server;
|
||||
server->num_clients++;
|
||||
|
||||
if (client->server->cfg->conn_accept_cb != NULL)
|
||||
client->server->cfg->conn_accept_cb(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l1ctl_link_send(struct l1ctl_link *l1l, struct msgb *msg)
|
||||
int l1ctl_client_send(struct l1ctl_client *client, struct msgb *msg)
|
||||
{
|
||||
uint8_t *len;
|
||||
|
||||
|
@ -194,7 +179,7 @@ int l1ctl_link_send(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
len = msgb_push(msg, L1CTL_MSG_LEN_FIELD);
|
||||
osmo_store16be(msg->len - L1CTL_MSG_LEN_FIELD, len);
|
||||
|
||||
if (osmo_wqueue_enqueue(&l1l->wq, msg) != 0) {
|
||||
if (osmo_wqueue_enqueue(&client->wq, msg) != 0) {
|
||||
LOGP(DL1D, LOGL_ERROR, "Failed to enqueue msg!\n");
|
||||
msgb_free(msg);
|
||||
return -EIO;
|
||||
|
@ -203,105 +188,70 @@ int l1ctl_link_send(struct l1ctl_link *l1l, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int l1ctl_link_close_conn(struct l1ctl_link *l1l)
|
||||
void l1ctl_client_conn_close(struct l1ctl_client *client)
|
||||
{
|
||||
struct osmo_fd *conn_bfd = &l1l->wq.bfd;
|
||||
struct trxcon_inst *trxcon = l1l->priv;
|
||||
|
||||
if (conn_bfd->fd <= 0)
|
||||
return -EINVAL;
|
||||
if (client->server->cfg->conn_close_cb != NULL)
|
||||
client->server->cfg->conn_close_cb(client);
|
||||
|
||||
/* Close connection socket */
|
||||
osmo_fd_unregister(conn_bfd);
|
||||
close(conn_bfd->fd);
|
||||
conn_bfd->fd = -1;
|
||||
osmo_fd_unregister(&client->wq.bfd);
|
||||
close(client->wq.bfd.fd);
|
||||
client->wq.bfd.fd = -1;
|
||||
|
||||
/* Clear pending messages */
|
||||
osmo_wqueue_clear(&l1l->wq);
|
||||
osmo_wqueue_clear(&client->wq);
|
||||
|
||||
osmo_fsm_inst_dispatch(trxcon->fi, L1CTL_EVENT_DISCONNECT, l1l);
|
||||
osmo_fsm_inst_state_chg(l1l->fsm, L1CTL_STATE_IDLE, 0, 0);
|
||||
client->server->num_clients--;
|
||||
llist_del(&client->list);
|
||||
talloc_free(client);
|
||||
}
|
||||
|
||||
int l1ctl_server_start(struct l1ctl_server *server,
|
||||
const struct l1ctl_server_cfg *cfg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
LOGP(DL1C, LOGL_NOTICE, "Init L1CTL server (sock_path=%s)\n", cfg->sock_path);
|
||||
|
||||
*server = (struct l1ctl_server) {
|
||||
.clients = LLIST_HEAD_INIT(server->clients),
|
||||
.cfg = cfg,
|
||||
};
|
||||
|
||||
/* conn_read_cb shall not be NULL */
|
||||
OSMO_ASSERT(cfg->conn_read_cb != NULL);
|
||||
|
||||
/* Bind connection handler */
|
||||
osmo_fd_setup(&server->ofd, -1, OSMO_FD_READ, &l1ctl_server_conn_cb, server, 0);
|
||||
|
||||
rc = osmo_sock_unix_init_ofd(&server->ofd, SOCK_STREAM, 0,
|
||||
cfg->sock_path, OSMO_SOCK_F_BIND);
|
||||
if (rc < 0) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Could not create UNIX socket: %s\n",
|
||||
strerror(errno));
|
||||
talloc_free(server);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct l1ctl_link *l1ctl_link_init(void *tall_ctx, const char *sock_path)
|
||||
void l1ctl_server_shutdown(struct l1ctl_server *server)
|
||||
{
|
||||
struct l1ctl_link *l1l;
|
||||
struct osmo_fd *bfd;
|
||||
int rc;
|
||||
LOGP(DL1C, LOGL_NOTICE, "Shutdown L1CTL server\n");
|
||||
|
||||
LOGP(DL1C, LOGL_NOTICE, "Init L1CTL link (%s)\n", sock_path);
|
||||
|
||||
l1l = talloc_zero(tall_ctx, struct l1ctl_link);
|
||||
if (!l1l) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Failed to allocate memory\n");
|
||||
return NULL;
|
||||
/* Close all client connections */
|
||||
while (!llist_empty(&server->clients)) {
|
||||
struct l1ctl_client *client = llist_entry(server->clients.next,
|
||||
struct l1ctl_client,
|
||||
list);
|
||||
l1ctl_client_conn_close(client);
|
||||
}
|
||||
|
||||
/* Allocate a new dedicated state machine */
|
||||
l1l->fsm = osmo_fsm_inst_alloc(&l1ctl_fsm, l1l,
|
||||
NULL, LOGL_DEBUG, "l1ctl_link");
|
||||
if (l1l->fsm == NULL) {
|
||||
LOGP(DTRX, LOGL_ERROR, "Failed to allocate an instance "
|
||||
"of FSM '%s'\n", l1ctl_fsm.name);
|
||||
talloc_free(l1l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a socket and bind handlers */
|
||||
bfd = &l1l->listen_bfd;
|
||||
|
||||
/* Bind connection handler */
|
||||
osmo_fd_setup(bfd, -1, OSMO_FD_READ, l1ctl_link_accept, l1l, 0);
|
||||
|
||||
rc = osmo_sock_unix_init_ofd(bfd, SOCK_STREAM, 0, sock_path,
|
||||
OSMO_SOCK_F_BIND);
|
||||
if (rc < 0) {
|
||||
LOGP(DL1C, LOGL_ERROR, "Could not create UNIX socket: %s\n",
|
||||
strerror(errno));
|
||||
osmo_fsm_inst_free(l1l->fsm);
|
||||
talloc_free(l1l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be able to accept first connection and
|
||||
* drop others, it should be set to -1
|
||||
*/
|
||||
l1l->wq.bfd.fd = -1;
|
||||
|
||||
return l1l;
|
||||
}
|
||||
|
||||
void l1ctl_link_shutdown(struct l1ctl_link *l1l)
|
||||
{
|
||||
struct osmo_fd *listen_bfd;
|
||||
|
||||
/* May be unallocated due to init error */
|
||||
if (!l1l)
|
||||
return;
|
||||
|
||||
LOGP(DL1C, LOGL_NOTICE, "Shutdown L1CTL link\n");
|
||||
|
||||
listen_bfd = &l1l->listen_bfd;
|
||||
|
||||
/* Check if we have an established connection */
|
||||
if (l1l->wq.bfd.fd != -1)
|
||||
l1ctl_link_close_conn(l1l);
|
||||
|
||||
/* Unbind listening socket */
|
||||
if (listen_bfd->fd != -1) {
|
||||
osmo_fd_unregister(listen_bfd);
|
||||
close(listen_bfd->fd);
|
||||
listen_bfd->fd = -1;
|
||||
if (server->ofd.fd != -1) {
|
||||
osmo_fd_unregister(&server->ofd);
|
||||
close(server->ofd.fd);
|
||||
server->ofd.fd = -1;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_free(l1l->fsm);
|
||||
talloc_free(l1l);
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load(void)
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&l1ctl_fsm) == 0);
|
||||
}
|
||||
|
|
|
@ -387,7 +387,7 @@ static void trx_if_measure_rsp_cb(struct trx_instance *trx, char *resp)
|
|||
}
|
||||
|
||||
/* Send L1CTL_PM_CONF */
|
||||
l1ctl_tx_pm_conf(trxcon->l1l, band_arfcn, dbm,
|
||||
l1ctl_tx_pm_conf(trxcon->l1c, band_arfcn, dbm,
|
||||
band_arfcn == trx->pm_band_arfcn_stop);
|
||||
|
||||
/* Schedule a next measurement */
|
||||
|
|
|
@ -157,16 +157,16 @@ int l1sched_handle_data_ind(struct l1sched_lchan_state *lchan,
|
|||
switch (dt) {
|
||||
case L1SCHED_DT_TRAFFIC:
|
||||
case L1SCHED_DT_PACKET_DATA:
|
||||
rc = l1ctl_tx_dt_ind(trxcon->l1l, &dl_hdr, data, data_len, true);
|
||||
rc = l1ctl_tx_dt_ind(trxcon->l1c, &dl_hdr, data, data_len, true);
|
||||
break;
|
||||
case L1SCHED_DT_SIGNALING:
|
||||
rc = l1ctl_tx_dt_ind(trxcon->l1l, &dl_hdr, data, data_len, false);
|
||||
rc = l1ctl_tx_dt_ind(trxcon->l1c, &dl_hdr, data, data_len, false);
|
||||
break;
|
||||
case L1SCHED_DT_OTHER:
|
||||
if (lchan->type == L1SCHED_SCH) {
|
||||
if (trxcon->fbsb_conf_sent)
|
||||
return 0;
|
||||
rc = l1ctl_tx_fbsb_conf(trxcon->l1l, 0, &dl_hdr, sched->bsic);
|
||||
rc = l1ctl_tx_fbsb_conf(trxcon->l1c, 0, &dl_hdr, sched->bsic);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
@ -209,12 +209,12 @@ int l1sched_handle_data_cnf(struct l1sched_lchan_state *lchan,
|
|||
switch (dt) {
|
||||
case L1SCHED_DT_TRAFFIC:
|
||||
case L1SCHED_DT_PACKET_DATA:
|
||||
rc = l1ctl_tx_dt_conf(trxcon->l1l, &dl_hdr, true);
|
||||
rc = l1ctl_tx_dt_conf(trxcon->l1c, &dl_hdr, true);
|
||||
data_len = lchan->prim->payload_len;
|
||||
data = lchan->prim->payload;
|
||||
break;
|
||||
case L1SCHED_DT_SIGNALING:
|
||||
rc = l1ctl_tx_dt_conf(trxcon->l1l, &dl_hdr, false);
|
||||
rc = l1ctl_tx_dt_conf(trxcon->l1c, &dl_hdr, false);
|
||||
data_len = lchan->prim->payload_len;
|
||||
data = lchan->prim->payload;
|
||||
break;
|
||||
|
@ -224,7 +224,7 @@ int l1sched_handle_data_cnf(struct l1sched_lchan_state *lchan,
|
|||
|
||||
rach = (struct l1sched_ts_prim_rach *)lchan->prim->payload;
|
||||
|
||||
rc = l1ctl_tx_rach_conf(trxcon->l1l, trxcon->trx->band_arfcn, fn);
|
||||
rc = l1ctl_tx_rach_conf(trxcon->l1c, trxcon->trx->band_arfcn, fn);
|
||||
if (lchan->prim->type == L1SCHED_PRIM_RACH11) {
|
||||
ra_buf[0] = (uint8_t)(rach->ra >> 3);
|
||||
ra_buf[1] = (uint8_t)(rach->ra & 0x07);
|
||||
|
@ -331,13 +331,6 @@ struct trxcon_inst *trxcon_inst_alloc(void *ctx)
|
|||
trxcon, LOGL_DEBUG, NULL);
|
||||
OSMO_ASSERT(trxcon->fi != NULL);
|
||||
|
||||
/* Init L1CTL server */
|
||||
trxcon->l1l = l1ctl_link_init(trxcon, app_data.bind_socket);
|
||||
if (trxcon->l1l == NULL) {
|
||||
trxcon_inst_free(trxcon);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Init transceiver interface */
|
||||
trxcon->trx = trx_if_open(trxcon,
|
||||
app_data.trx_bind_ip,
|
||||
|
@ -348,8 +341,6 @@ struct trxcon_inst *trxcon_inst_alloc(void *ctx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
trxcon->l1l->priv = trxcon;
|
||||
|
||||
/* Init scheduler */
|
||||
trxcon->sched = l1sched_alloc(trxcon, app_data.trx_fn_advance, trxcon);
|
||||
if (trxcon->sched == NULL) {
|
||||
|
@ -366,8 +357,8 @@ void trxcon_inst_free(struct trxcon_inst *trxcon)
|
|||
if (trxcon->sched != NULL)
|
||||
l1sched_free(trxcon->sched);
|
||||
/* Close active connections */
|
||||
if (trxcon->l1l != NULL)
|
||||
l1ctl_link_shutdown(trxcon->l1l);
|
||||
if (trxcon->l1c != NULL)
|
||||
l1ctl_client_conn_close(trxcon->l1c);
|
||||
if (trxcon->trx != NULL)
|
||||
trx_if_close(trxcon->trx);
|
||||
|
||||
|
@ -379,6 +370,32 @@ void trxcon_inst_free(struct trxcon_inst *trxcon)
|
|||
talloc_free(trxcon);
|
||||
}
|
||||
|
||||
static void l1ctl_conn_accept_cb(struct l1ctl_client *l1c)
|
||||
{
|
||||
struct trxcon_inst *trxcon;
|
||||
|
||||
trxcon = trxcon_inst_alloc(l1c);
|
||||
if (trxcon == NULL) {
|
||||
l1ctl_client_conn_close(l1c);
|
||||
return;
|
||||
}
|
||||
|
||||
l1c->priv = trxcon;
|
||||
trxcon->l1c = l1c;
|
||||
}
|
||||
|
||||
static void l1ctl_conn_close_cb(struct l1ctl_client *l1c)
|
||||
{
|
||||
struct trxcon_inst *trxcon = l1c->priv;
|
||||
|
||||
if (trxcon == NULL)
|
||||
return;
|
||||
|
||||
/* l1c is free()ed by the caller */
|
||||
trxcon->l1c = NULL;
|
||||
trxcon_inst_free(trxcon);
|
||||
}
|
||||
|
||||
static void print_usage(const char *app)
|
||||
{
|
||||
printf("Usage: %s\n", app);
|
||||
|
@ -489,7 +506,8 @@ static void signal_handler(int signum)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct trxcon_inst *trxcon = NULL;
|
||||
struct l1ctl_server_cfg server_cfg;
|
||||
struct l1ctl_server server;
|
||||
int rc = 0;
|
||||
|
||||
printf("%s", COPYRIGHT);
|
||||
|
@ -535,10 +553,20 @@ int main(int argc, char **argv)
|
|||
/* Register the trxcon state machine */
|
||||
OSMO_ASSERT(osmo_fsm_register(&trxcon_fsm_def) == 0);
|
||||
|
||||
/* Allocate the trxcon instance (only one for now) */
|
||||
trxcon = trxcon_inst_alloc(tall_trxcon_ctx);
|
||||
if (trxcon == NULL)
|
||||
/* Start the L1CTL server */
|
||||
server_cfg = (struct l1ctl_server_cfg) {
|
||||
.sock_path = app_data.bind_socket,
|
||||
.talloc_ctx = tall_trxcon_ctx,
|
||||
.num_clients_max = 1, /* only one connection for now */
|
||||
.conn_read_cb = &l1ctl_rx_cb,
|
||||
.conn_accept_cb = &l1ctl_conn_accept_cb,
|
||||
.conn_close_cb = &l1ctl_conn_close_cb,
|
||||
};
|
||||
|
||||
if (l1ctl_server_start(&server, &server_cfg) != 0) {
|
||||
rc = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
LOGP(DAPP, LOGL_NOTICE, "Init complete\n");
|
||||
|
||||
|
@ -557,9 +585,7 @@ int main(int argc, char **argv)
|
|||
osmo_select_main(0);
|
||||
|
||||
exit:
|
||||
/* Release the trxcon instance */
|
||||
if (trxcon != NULL)
|
||||
trxcon_inst_free(trxcon);
|
||||
l1ctl_server_shutdown(&server);
|
||||
|
||||
/* Deinitialize logging */
|
||||
log_fini();
|
||||
|
|
Loading…
Reference in New Issue