fixeria has submitted this change. (
https://gerrit.osmocom.org/c/osmocom-bb/+/28667 )
Change subject: trxcon: introduce and use struct 'trxcon_inst'
......................................................................
trxcon: introduce and use struct 'trxcon_inst'
trxcon consists of the following three main components:
* the L1 TDMA scheduler (libl1sched),
* L1 interface (TRXC/TRXD over UDP),
* L2 interface (L1CTL).
In [1] and [2] the L1 scheduler was abstracted out from both L1
and L2 interfaces and separated into a library, so it does not
use the TRXC/TRXD nor L1CTL related API directly.
This change is the next step towards the goal of having all three
components abstracted from each other. Moreover, this patch brings
us closer to another goal of being able to support multiple L1CTL
connections (each having its own scheduler).
The idea is to give both L1 and L2 interfaces access to the
'trxcon_inst' structure, which basically groups all three components
mentioned above into a single piece. The end goal is to eliminate
direct interaction between the interfaces, and the scheduler, so that
one could easily replace TRXC/TRXD and/or L1CTL with something else.
Change-Id: I23319951c56577085e1092669b5534f9d6bda48d
Related: [1] I31f77976a7a225ef292fe6dcd583513aec97ed44
Related: [2] I001fb7bc2663eea308b5a8882746ed9863f2c2f8
---
M src/host/trxcon/include/osmocom/bb/trxcon/l1ctl_link.h
M src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
M src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
M src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
M src/host/trxcon/src/l1ctl.c
M src/host/trxcon/src/l1ctl_link.c
M src/host/trxcon/src/sched_trx.c
M src/host/trxcon/src/trx_if.c
M src/host/trxcon/src/trxcon.c
9 files changed, 188 insertions(+), 123 deletions(-)
Approvals:
Jenkins Builder: Verified
fixeria: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
osmith: Looks good to me, but someone else must approve
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/l1ctl_link.h
b/src/host/trxcon/include/osmocom/bb/trxcon/l1ctl_link.h
index 4604e27..5cfcc10 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/l1ctl_link.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/l1ctl_link.h
@@ -17,9 +17,6 @@
*/
#define L1CTL_MSG_LEN_FIELD 2
-/* Forward declaration to avoid mutual include */
-struct trx_instance;
-
enum l1ctl_fsm_states {
L1CTL_STATE_IDLE = 0,
L1CTL_STATE_CONNECTED,
@@ -30,11 +27,8 @@
struct osmo_fd listen_bfd;
struct osmo_wqueue wq;
- /* Scheduler for this interface */
- struct l1sched_state *sched;
-
- /* Bind TRX instance */
- struct trx_instance *trx;
+ /* Some private data */
+ void *priv;
/* L1CTL handlers specific */
struct osmo_timer_list fbsb_timer;
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
b/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
index 7b96f6d..2969410 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
@@ -366,6 +366,8 @@
struct l1sched_ts *ts[TRX_TS_COUNT];
/*! BSIC value learned from SCH bursts */
uint8_t bsic;
+ /*! Some private data */
+ void *priv;
};
extern const struct l1sched_lchan_desc l1sched_lchan_desc[_L1SCHED_CHAN_MAX];
@@ -373,7 +375,7 @@
enum gsm_phys_chan_config config, int tn);
/* Scheduler management functions */
-struct l1sched_state *l1sched_alloc(void *ctx, uint32_t fn_advance);
+struct l1sched_state *l1sched_alloc(void *ctx, uint32_t fn_advance, void *priv);
void l1sched_reset(struct l1sched_state *sched, bool reset_clock);
void l1sched_free(struct l1sched_state *sched);
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
b/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
index 4a59d67..e205c93 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trx_if.h
@@ -12,8 +12,7 @@
/* Forward declaration to avoid mutual include */
struct l1sched_burst_req;
-struct l1sched_state;
-struct l1ctl_link;
+struct trxcon_inst;
enum trx_fsm_states {
TRX_STATE_OFFLINE = 0,
@@ -23,6 +22,9 @@
};
struct trx_instance {
+ /* trxcon instance we belong to */
+ struct trxcon_inst *trxcon;
+
struct osmo_fd trx_ofd_ctrl;
struct osmo_fd trx_ofd_data;
@@ -40,12 +42,6 @@
uint16_t band_arfcn;
uint8_t tx_power;
int8_t ta;
-
- /* Scheduler for this interface */
- struct l1sched_state *sched;
-
- /* Bind L1CTL link */
- struct l1ctl_link *l1l;
};
struct trx_ctrl_msg {
@@ -56,7 +52,7 @@
int cmd_len;
};
-struct trx_instance *trx_if_open(void *tall_ctx,
+struct trx_instance *trx_if_open(struct trxcon_inst *trxcon,
const char *local_host, const char *remote_host, uint16_t port);
void trx_if_flush_ctrl(struct trx_instance *trx);
void trx_if_close(struct trx_instance *trx);
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
index f66a628..6cec162 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
@@ -2,7 +2,9 @@
#define GEN_MASK(state) (0x01 << state)
-extern struct osmo_fsm_inst *trxcon_fsm;
+struct l1sched_state;
+struct trx_instance;
+struct l1ctl_link;
enum trxcon_fsm_states {
TRXCON_STATE_IDLE = 0,
@@ -18,3 +20,16 @@
TRX_EVENT_RSP_ERROR,
TRX_EVENT_OFFLINE,
};
+
+struct trxcon_inst {
+ struct osmo_fsm_inst *fi;
+
+ /* The L1 scheduler */
+ struct l1sched_state *sched;
+ /* L1/L2 interfaces */
+ struct trx_instance *trx;
+ struct l1ctl_link *l1l;
+};
+
+struct trxcon_inst *trxcon_inst_alloc(void *ctx);
+void trxcon_inst_free(struct trxcon_inst *trxcon);
diff --git a/src/host/trxcon/src/l1ctl.c b/src/host/trxcon/src/l1ctl.c
index 5475290..3cf06e1 100644
--- a/src/host/trxcon/src/l1ctl.c
+++ b/src/host/trxcon/src/l1ctl.c
@@ -42,6 +42,7 @@
#include <osmocom/bb/trxcon/trx_if.h>
#include <osmocom/bb/trxcon/l1sched.h>
+#include <osmocom/bb/trxcon/trxcon.h>
static const char *arfcn2band_name(uint16_t arfcn)
{
@@ -296,6 +297,7 @@
static void fbsb_timer_cb(void *data)
{
struct l1ctl_link *l1l = (struct l1ctl_link *) data;
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_info_dl *dl;
struct msgb *msg;
@@ -303,12 +305,13 @@
if (msg == NULL)
return;
- LOGP(DL1C, LOGL_NOTICE, "FBSB timer fired for ARFCN %u\n",
l1l->trx->band_arfcn & ~ARFCN_FLAG_MASK);
+ LOGP(DL1C, LOGL_NOTICE, "FBSB timer fired for ARFCN %u\n",
+ trxcon->trx->band_arfcn & ~ARFCN_FLAG_MASK);
dl = put_dl_info_hdr(msg, NULL);
/* Fill in current ARFCN */
- dl->band_arfcn = htons(l1l->trx->band_arfcn);
+ dl->band_arfcn = htons(trxcon->trx->band_arfcn);
fbsb_conf_make(msg, 255, 0);
@@ -320,6 +323,7 @@
static int l1ctl_rx_fbsb_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
enum gsm_phys_chan_config ch_config;
struct l1ctl_fbsb_req *fbsb;
uint16_t band_arfcn;
@@ -343,28 +347,28 @@
band_arfcn & ~ARFCN_FLAG_MASK);
/* Reset scheduler and clock counter */
- l1sched_reset(l1l->sched, true);
+ l1sched_reset(trxcon->sched, true);
/* Configure a single timeslot */
- l1sched_configure_ts(l1l->sched, 0, ch_config);
+ l1sched_configure_ts(trxcon->sched, 0, ch_config);
/* Ask SCH handler to send L1CTL_FBSB_CONF */
l1l->fbsb_conf_sent = false;
/* Only if current ARFCN differs */
- if (l1l->trx->band_arfcn != band_arfcn) {
+ if (trxcon->trx->band_arfcn != band_arfcn) {
/* Update current ARFCN */
- l1l->trx->band_arfcn = band_arfcn;
+ trxcon->trx->band_arfcn = band_arfcn;
/* Tune transceiver to required ARFCN */
- trx_if_cmd_rxtune(l1l->trx, band_arfcn);
- trx_if_cmd_txtune(l1l->trx, band_arfcn);
+ trx_if_cmd_rxtune(trxcon->trx, band_arfcn);
+ trx_if_cmd_txtune(trxcon->trx, band_arfcn);
}
/* Transceiver might have been powered on before, e.g.
* in case of sending L1CTL_FBSB_REQ due to signal loss. */
- if (!l1l->trx->powered_up)
- trx_if_cmd_poweron(l1l->trx);
+ if (!trxcon->trx->powered_up)
+ trx_if_cmd_poweron(trxcon->trx);
/* Start FBSB expire timer */
l1l->fbsb_timer.data = l1l;
@@ -381,6 +385,7 @@
static int l1ctl_rx_pm_req(struct l1ctl_link *l1l, struct msgb *msg)
{
uint16_t band_arfcn_start, band_arfcn_stop;
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_pm_req *pmr;
int rc = 0;
@@ -402,7 +407,7 @@
band_arfcn_stop & ~ARFCN_FLAG_MASK);
/* Send measurement request to transceiver */
- rc = trx_if_cmd_measure(l1l->trx, band_arfcn_start, band_arfcn_stop);
+ rc = trx_if_cmd_measure(trxcon->trx, band_arfcn_start, band_arfcn_stop);
exit:
msgb_free(msg);
@@ -411,6 +416,7 @@
static int l1ctl_rx_reset_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_reset *res;
int rc = 0;
@@ -428,12 +434,12 @@
switch (res->type) {
case L1CTL_RES_T_FULL:
/* TODO: implement trx_if_reset() */
- trx_if_cmd_poweroff(l1l->trx);
- trx_if_cmd_echo(l1l->trx);
+ trx_if_cmd_poweroff(trxcon->trx);
+ trx_if_cmd_echo(trxcon->trx);
/* Fall through */
case L1CTL_RES_T_SCHED:
- l1sched_reset(l1l->sched, true);
+ l1sched_reset(trxcon->sched, true);
break;
default:
LOGP(DL1C, LOGL_ERROR, "Unknown L1CTL_RESET_REQ type\n");
@@ -465,6 +471,7 @@
static int l1ctl_rx_ccch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
enum gsm_phys_chan_config ch_config;
struct l1ctl_ccch_mode_req *req;
struct l1sched_ts *ts;
@@ -482,7 +489,7 @@
req->ccch_mode); /* TODO: add value-string for ccch_mode */
/* Make sure that TS0 is allocated and configured */
- ts = l1l->sched->ts[0];
+ ts = trxcon->sched->ts[0];
if (ts == NULL || ts->mf_layout == NULL) {
LOGP(DL1C, LOGL_ERROR, "TS0 is not configured");
rc = -EINVAL;
@@ -494,7 +501,7 @@
/* Do nothing if the current mode matches required */
if (ts->mf_layout->chan_config != ch_config)
- rc = l1sched_configure_ts(l1l->sched, 0, ch_config);
+ rc = l1sched_configure_ts(trxcon->sched, 0, ch_config);
/* Confirm reconfiguration */
if (!rc)
@@ -507,6 +514,7 @@
static int l1ctl_rx_rach_req(struct l1ctl_link *l1l, struct msgb *msg, bool ext)
{
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_info_ul *ul;
struct l1sched_ts_prim *prim;
struct l1sched_ts_prim_rach rach;
@@ -553,7 +561,7 @@
* Indicated timeslot needs to be configured.
*/
prim_type = ext ? L1SCHED_PRIM_RACH11 : L1SCHED_PRIM_RACH8;
- prim = l1sched_prim_push(l1l->sched, prim_type, ul->chan_nr, ul->link_id,
+ prim = l1sched_prim_push(trxcon->sched, prim_type, ul->chan_nr, ul->link_id,
(const uint8_t *)&rach, sizeof(rach));
if (prim == NULL)
rc = -ENOMEM;
@@ -624,6 +632,7 @@
static int l1ctl_rx_dm_est_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
enum gsm_phys_chan_config config;
struct l1ctl_dm_est_req *est_req;
struct l1ctl_info_ul *ul;
@@ -651,15 +660,15 @@
/* Frequency hopping? */
if (est_req->h)
- rc = l1ctl_proc_est_req_h1(l1l->trx, &est_req->h1);
+ rc = l1ctl_proc_est_req_h1(trxcon->trx, &est_req->h1);
else /* Single ARFCN */
- rc = l1ctl_proc_est_req_h0(l1l->trx, &est_req->h0);
+ rc = l1ctl_proc_est_req_h0(trxcon->trx, &est_req->h0);
if (rc)
goto exit;
/* Configure requested TS */
- rc = l1sched_configure_ts(l1l->sched, tn, config);
- ts = l1l->sched->ts[tn];
+ rc = l1sched_configure_ts(trxcon->sched, tn, config);
+ ts = trxcon->sched->ts[tn];
if (rc) {
rc = -EINVAL;
goto exit;
@@ -683,10 +692,12 @@
static int l1ctl_rx_dm_rel_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
+
LOGP(DL1C, LOGL_NOTICE, "Received L1CTL_DM_REL_REQ, resetting scheduler\n");
/* Reset scheduler */
- l1sched_reset(l1l->sched, false);
+ l1sched_reset(trxcon->sched, false);
msgb_free(msg);
return 0;
@@ -698,6 +709,7 @@
static int l1ctl_rx_dt_req(struct l1ctl_link *l1l,
struct msgb *msg, bool traffic)
{
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_info_ul *ul;
struct l1sched_ts_prim *prim;
uint8_t chan_nr, link_id;
@@ -720,7 +732,7 @@
chan_nr, link_id, payload_len);
/* Push this primitive to transmit queue */
- prim = l1sched_prim_push(l1l->sched, L1SCHED_PRIM_DATA,
+ prim = l1sched_prim_push(trxcon->sched, L1SCHED_PRIM_DATA,
chan_nr, link_id, ul->payload, payload_len);
if (prim == NULL)
rc = -ENOMEM;
@@ -731,6 +743,7 @@
static int l1ctl_rx_param_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_par_req *par_req;
struct l1ctl_info_ul *ul;
@@ -741,12 +754,12 @@
"(ta=%d, tx_power=%u)\n", par_req->ta, par_req->tx_power);
/* Instruct TRX to use new TA value */
- if (l1l->trx->ta != par_req->ta) {
- trx_if_cmd_setta(l1l->trx, par_req->ta);
- l1l->trx->ta = par_req->ta;
+ if (trxcon->trx->ta != par_req->ta) {
+ trx_if_cmd_setta(trxcon->trx, par_req->ta);
+ trxcon->trx->ta = par_req->ta;
}
- l1l->trx->tx_power = par_req->tx_power;
+ trxcon->trx->tx_power = par_req->tx_power;
msgb_free(msg);
return 0;
@@ -754,6 +767,7 @@
static int l1ctl_rx_tch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_tch_mode_req *req;
struct l1sched_lchan_state *lchan;
struct l1sched_ts *ts;
@@ -765,9 +779,9 @@
"(tch_mode=%u, audio_mode=%u)\n", req->tch_mode, req->audio_mode);
/* Iterate over timeslot list */
- for (tn = 0; tn < ARRAY_SIZE(l1l->sched->ts); tn++) {
+ for (tn = 0; tn < ARRAY_SIZE(trxcon->sched->ts); tn++) {
/* Timeslot is not allocated */
- ts = l1l->sched->ts[tn];
+ ts = trxcon->sched->ts[tn];
if (ts == NULL)
continue;
@@ -797,6 +811,7 @@
static int l1ctl_rx_crypto_req(struct l1ctl_link *l1l, struct msgb *msg)
{
+ struct trxcon_inst *trxcon = l1l->priv;
struct l1ctl_crypto_req *req;
struct l1ctl_info_ul *ul;
struct l1sched_ts *ts;
@@ -813,7 +828,7 @@
tn = ul->chan_nr & 0x7;
/* Make sure that required TS is allocated and configured */
- ts = l1l->sched->ts[tn];
+ ts = trxcon->sched->ts[tn];
if (ts == NULL || ts->mf_layout == NULL) {
LOGP(DL1C, LOGL_ERROR, "TS %u is not configured\n", tn);
rc = -EINVAL;
diff --git a/src/host/trxcon/src/l1ctl_link.c b/src/host/trxcon/src/l1ctl_link.c
index b10d9da..294ed6f 100644
--- a/src/host/trxcon/src/l1ctl_link.c
+++ b/src/host/trxcon/src/l1ctl_link.c
@@ -136,6 +136,7 @@
static int l1ctl_link_accept(struct osmo_fd *bfd, 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;
@@ -170,7 +171,7 @@
return -1;
}
- osmo_fsm_inst_dispatch(trxcon_fsm, L1CTL_EVENT_CONNECT, l1l);
+ osmo_fsm_inst_dispatch(trxcon->fi, L1CTL_EVENT_CONNECT, l1l);
osmo_fsm_inst_state_chg(l1l->fsm, L1CTL_STATE_CONNECTED, 0, 0);
LOGP(DL1C, LOGL_NOTICE, "L1CTL has a new connection\n");
@@ -205,6 +206,7 @@
int l1ctl_link_close_conn(struct l1ctl_link *l1l)
{
struct osmo_fd *conn_bfd = &l1l->wq.bfd;
+ struct trxcon_inst *trxcon = l1l->priv;
if (conn_bfd->fd <= 0)
return -EINVAL;
@@ -217,7 +219,7 @@
/* Clear pending messages */
osmo_wqueue_clear(&l1l->wq);
- osmo_fsm_inst_dispatch(trxcon_fsm, L1CTL_EVENT_DISCONNECT, l1l);
+ osmo_fsm_inst_dispatch(trxcon->fi, L1CTL_EVENT_DISCONNECT, l1l);
osmo_fsm_inst_state_chg(l1l->fsm, L1CTL_STATE_IDLE, 0, 0);
return 0;
diff --git a/src/host/trxcon/src/sched_trx.c b/src/host/trxcon/src/sched_trx.c
index d3a0a54..1c0910e 100644
--- a/src/host/trxcon/src/sched_trx.c
+++ b/src/host/trxcon/src/sched_trx.c
@@ -150,7 +150,7 @@
l1sched_handle_burst_req(sched, &br[tn]);
}
-struct l1sched_state *l1sched_alloc(void *ctx, uint32_t fn_advance)
+struct l1sched_state *l1sched_alloc(void *ctx, uint32_t fn_advance, void *priv)
{
struct l1sched_state *sched;
@@ -164,6 +164,7 @@
/* .clock_timer is set up in l1sched_clck_correct() */
.clock_cb = &sched_frame_clck_cb,
.fn_counter_advance = fn_advance,
+ .priv = priv,
};
return sched;
diff --git a/src/host/trxcon/src/trx_if.c b/src/host/trxcon/src/trx_if.c
index eec287c..3e1e4b1 100644
--- a/src/host/trxcon/src/trx_if.c
+++ b/src/host/trxcon/src/trx_if.c
@@ -161,6 +161,7 @@
static void trx_ctrl_timer_cb(void *data)
{
struct trx_instance *trx = (struct trx_instance *) data;
+ struct trxcon_inst *trxcon = trx->trxcon;
struct trx_ctrl_msg *tcm;
/* Queue may be cleaned at this moment */
@@ -173,7 +174,7 @@
if (++tcm->retry_cnt > 3) {
LOGP(DTRX, LOGL_NOTICE, "Transceiver offline\n");
osmo_fsm_inst_state_chg(trx->fsm, TRX_STATE_OFFLINE, 0, 0);
- osmo_fsm_inst_dispatch(trxcon_fsm, TRX_EVENT_OFFLINE, trx);
+ osmo_fsm_inst_dispatch(trxcon->fi, TRX_EVENT_OFFLINE, trx);
return;
}
@@ -366,6 +367,7 @@
static void trx_if_measure_rsp_cb(struct trx_instance *trx, char *resp)
{
+ struct trxcon_inst *trxcon = trx->trxcon;
unsigned int freq10;
uint16_t band_arfcn;
int dbm;
@@ -385,7 +387,7 @@
}
/* Send L1CTL_PM_CONF */
- l1ctl_tx_pm_conf(trx->l1l, band_arfcn, dbm,
+ l1ctl_tx_pm_conf(trxcon->l1l, band_arfcn, dbm,
band_arfcn == trx->pm_band_arfcn_stop);
/* Schedule a next measurement */
@@ -475,6 +477,7 @@
static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what)
{
struct trx_instance *trx = ofd->data;
+ struct trxcon_inst *trxcon = trx->trxcon;
struct trx_ctrl_msg *tcm;
int resp, rsp_len;
char buf[TRXC_BUF_SIZE], *p;
@@ -557,7 +560,7 @@
rsp_error:
/* Notify higher layers about the problem */
- osmo_fsm_inst_dispatch(trxcon_fsm, TRX_EVENT_RSP_ERROR, trx);
+ osmo_fsm_inst_dispatch(trxcon->fi, TRX_EVENT_RSP_ERROR, trx);
return -EIO;
}
@@ -586,6 +589,7 @@
static int trx_data_rx_cb(struct osmo_fd *ofd, unsigned int what)
{
struct trx_instance *trx = ofd->data;
+ struct trxcon_inst *trxcon = trx->trxcon;
struct l1sched_meas_set meas;
uint8_t buf[TRXD_BUF_SIZE];
sbit_t bits[148];
@@ -635,11 +639,11 @@
};
/* Poke scheduler */
- l1sched_handle_rx_burst(trx->sched, tn, fn, bits, 148, &meas);
+ l1sched_handle_rx_burst(trxcon->sched, tn, fn, bits, 148, &meas);
/* Correct local clock counter */
if (fn % 51 == 0)
- l1sched_clck_handle(trx->sched, fn);
+ l1sched_clck_handle(trxcon->sched, fn);
return 0;
}
@@ -686,7 +690,7 @@
}
/* Init TRX interface (TRXC, TRXD sockets and FSM) */
-struct trx_instance *trx_if_open(void *tall_ctx,
+struct trx_instance *trx_if_open(struct trxcon_inst *trxcon,
const char *local_host, const char *remote_host,
uint16_t base_port)
{
@@ -697,13 +701,14 @@
"(%s:%u)\n", remote_host, base_port);
/* Try to allocate memory */
- trx = talloc_zero(tall_ctx, struct trx_instance);
+ trx = talloc_zero(trxcon, struct trx_instance);
if (!trx) {
LOGP(DTRX, LOGL_ERROR, "Failed to allocate memory\n");
return NULL;
}
/* Allocate a new dedicated state machine */
+ /* TODO: allocate it as a child of trxcon->fi */
trx->fsm = osmo_fsm_inst_alloc(&trx_fsm, trx,
NULL, LOGL_DEBUG, "trx_interface");
if (trx->fsm == NULL) {
@@ -727,6 +732,8 @@
if (rc < 0)
goto udp_error;
+ trx->trxcon = trxcon;
+
return trx;
udp_error:
diff --git a/src/host/trxcon/src/trxcon.c b/src/host/trxcon/src/trxcon.c
index d72a4d3..4f7dd32 100644
--- a/src/host/trxcon/src/trxcon.c
+++ b/src/host/trxcon/src/trxcon.c
@@ -62,15 +62,10 @@
int daemonize;
int quit;
- /* The scheduler */
- struct l1sched_state *sched;
-
/* L1CTL specific */
- struct l1ctl_link *l1l;
const char *bind_socket;
/* TRX specific */
- struct trx_instance *trx;
const char *trx_bind_ip;
const char *trx_remote_ip;
uint16_t trx_base_port;
@@ -88,7 +83,6 @@
};
static void *tall_trxcon_ctx = NULL;
-struct osmo_fsm_inst *trxcon_fsm;
static void trxcon_gsmtap_send(const struct l1sched_lchan_desc *lchan_desc,
uint32_t fn, uint8_t tn, uint16_t band_arfcn,
@@ -112,13 +106,15 @@
int l1sched_handle_config_req(struct l1sched_state *sched,
const struct l1sched_config_req *cr)
{
+ struct trxcon_inst *trxcon = sched->priv;
+
switch (cr->type) {
case L1SCHED_CFG_PCHAN_COMB:
- return trx_if_cmd_setslot(app_data.trx,
+ return trx_if_cmd_setslot(trxcon->trx,
cr->pchan_comb.tn,
cr->pchan_comb.pchan);
default:
- LOGPFSML(trxcon_fsm, LOGL_ERROR,
+ LOGPFSML(trxcon->fi, LOGL_ERROR,
"Unhandled config request (type 0x%02x)\n", cr->type);
return -ENODEV;
}
@@ -127,7 +123,9 @@
int l1sched_handle_burst_req(struct l1sched_state *sched,
const struct l1sched_burst_req *br)
{
- return trx_if_tx_burst(app_data.trx, br);
+ struct trxcon_inst *trxcon = sched->priv;
+
+ return trx_if_tx_burst(trxcon->trx, br);
}
/* External L2 API for the scheduler */
@@ -138,6 +136,8 @@
{
const struct l1sched_meas_set *meas = &lchan->meas_avg;
const struct l1sched_lchan_desc *lchan_desc;
+ struct l1sched_state *sched = lchan->ts->sched;
+ struct trxcon_inst *trxcon = sched->priv;
struct l1ctl_info_dl dl_hdr;
int rc;
@@ -147,7 +147,7 @@
.chan_nr = lchan_desc->chan_nr | lchan->ts->index,
.link_id = lchan_desc->link_id,
.frame_nr = htonl(meas->fn),
- .band_arfcn = htons(app_data.trx->band_arfcn),
+ .band_arfcn = htons(trxcon->trx->band_arfcn),
.fire_crc = data_len > 0 ? 0 : 2,
.rx_level = dbm2rxlev(meas->rssi),
.num_biterr = n_errors,
@@ -157,29 +157,28 @@
switch (dt) {
case L1SCHED_DT_TRAFFIC:
case L1SCHED_DT_PACKET_DATA:
- rc = l1ctl_tx_dt_ind(app_data.l1l, &dl_hdr, data, data_len, true);
+ rc = l1ctl_tx_dt_ind(trxcon->l1l, &dl_hdr, data, data_len, true);
break;
case L1SCHED_DT_SIGNALING:
- rc = l1ctl_tx_dt_ind(app_data.l1l, &dl_hdr, data, data_len, false);
+ rc = l1ctl_tx_dt_ind(trxcon->l1l, &dl_hdr, data, data_len, false);
break;
case L1SCHED_DT_OTHER:
if (lchan->type == L1SCHED_SCH) {
- if (app_data.l1l->fbsb_conf_sent)
+ if (trxcon->l1l->fbsb_conf_sent)
return 0;
- rc = l1ctl_tx_fbsb_conf(app_data.l1l, 0, &dl_hdr,
- lchan->ts->sched->bsic);
+ rc = l1ctl_tx_fbsb_conf(trxcon->l1l, 0, &dl_hdr, sched->bsic);
break;
}
/* fall through */
default:
- LOGPFSML(trxcon_fsm, LOGL_ERROR,
+ LOGPFSML(trxcon->fi, LOGL_ERROR,
"Unhandled L2 DATA.ind (type 0x%02x)\n", dt);
return -ENODEV;
}
if (data != NULL && data_len > 0) {
trxcon_gsmtap_send(lchan_desc, meas->fn, lchan->ts->index,
- app_data.trx->band_arfcn, meas->rssi, 0,
+ trxcon->trx->band_arfcn, meas->rssi, 0,
data, data_len);
}
@@ -190,6 +189,8 @@
uint32_t fn, enum l1sched_data_type dt)
{
const struct l1sched_lchan_desc *lchan_desc;
+ struct l1sched_state *sched = lchan->ts->sched;
+ struct trxcon_inst *trxcon = sched->priv;
struct l1ctl_info_dl dl_hdr;
const uint8_t *data;
uint8_t ra_buf[2];
@@ -202,18 +203,18 @@
.chan_nr = lchan_desc->chan_nr | lchan->ts->index,
.link_id = lchan_desc->link_id,
.frame_nr = htonl(fn),
- .band_arfcn = htons(app_data.trx->band_arfcn),
+ .band_arfcn = htons(trxcon->trx->band_arfcn),
};
switch (dt) {
case L1SCHED_DT_TRAFFIC:
case L1SCHED_DT_PACKET_DATA:
- rc = l1ctl_tx_dt_conf(app_data.l1l, &dl_hdr, true);
+ rc = l1ctl_tx_dt_conf(trxcon->l1l, &dl_hdr, true);
data_len = lchan->prim->payload_len;
data = lchan->prim->payload;
break;
case L1SCHED_DT_SIGNALING:
- rc = l1ctl_tx_dt_conf(app_data.l1l, &dl_hdr, false);
+ rc = l1ctl_tx_dt_conf(trxcon->l1l, &dl_hdr, false);
data_len = lchan->prim->payload_len;
data = lchan->prim->payload;
break;
@@ -223,7 +224,7 @@
rach = (struct l1sched_ts_prim_rach *)lchan->prim->payload;
- rc = l1ctl_tx_rach_conf(app_data.l1l, app_data.trx->band_arfcn, fn);
+ rc = l1ctl_tx_rach_conf(trxcon->l1l, 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);
@@ -238,13 +239,13 @@
}
/* fall through */
default:
- LOGPFSML(trxcon_fsm, LOGL_ERROR,
+ LOGPFSML(trxcon->fi, LOGL_ERROR,
"Unhandled L2 DATA.cnf (type 0x%02x)\n", dt);
return -ENODEV;
}
trxcon_gsmtap_send(lchan_desc, fn, lchan->ts->index,
- app_data.trx->band_arfcn | ARFCN_UPLINK,
+ trxcon->trx->band_arfcn | ARFCN_UPLINK,
0, 0, data, data_len);
return rc;
@@ -255,23 +256,25 @@
uint32_t event, void *data)
{
if (event == L1CTL_EVENT_CONNECT)
- osmo_fsm_inst_state_chg(trxcon_fsm, TRXCON_STATE_MANAGED, 0, 0);
+ osmo_fsm_inst_state_chg(fi, TRXCON_STATE_MANAGED, 0, 0);
}
static void trxcon_fsm_managed_action(struct osmo_fsm_inst *fi,
uint32_t event, void *data)
{
+ struct trxcon_inst *trxcon = fi->priv;
+
switch (event) {
case L1CTL_EVENT_DISCONNECT:
- osmo_fsm_inst_state_chg(trxcon_fsm, TRXCON_STATE_IDLE, 0, 0);
+ osmo_fsm_inst_state_chg(fi, TRXCON_STATE_IDLE, 0, 0);
- if (app_data.trx->fsm->state != TRX_STATE_OFFLINE) {
+ if (trxcon->trx->fsm->state != TRX_STATE_OFFLINE) {
/* Reset scheduler and clock counter */
- l1sched_reset(app_data.sched, true);
+ l1sched_reset(trxcon->sched, true);
/* TODO: implement trx_if_reset() */
- trx_if_cmd_poweroff(app_data.trx);
- trx_if_cmd_echo(app_data.trx);
+ trx_if_cmd_poweroff(trxcon->trx);
+ trx_if_cmd_echo(trxcon->trx);
}
break;
case TRX_EVENT_RSP_ERROR:
@@ -310,13 +313,69 @@
};
static struct osmo_fsm trxcon_fsm_def = {
- .name = "trxcon_app_fsm",
+ .name = "trxcon",
.states = trxcon_fsm_states,
.num_states = ARRAY_SIZE(trxcon_fsm_states),
.log_subsys = DAPP,
.event_names = trxcon_fsm_event_names,
};
+struct trxcon_inst *trxcon_inst_alloc(void *ctx)
+{
+ struct trxcon_inst *trxcon;
+
+ trxcon = talloc_zero(ctx, struct trxcon_inst);
+ OSMO_ASSERT(trxcon != NULL);
+
+ trxcon->fi = osmo_fsm_inst_alloc(&trxcon_fsm_def, tall_trxcon_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,
+ app_data.trx_remote_ip,
+ app_data.trx_base_port);
+ if (trxcon->trx == NULL) {
+ trxcon_inst_free(trxcon);
+ return NULL;
+ }
+
+ trxcon->l1l->priv = trxcon;
+
+ /* Init scheduler */
+ trxcon->sched = l1sched_alloc(trxcon, app_data.trx_fn_advance, trxcon);
+ if (trxcon->sched == NULL) {
+ trxcon_inst_free(trxcon);
+ return NULL;
+ }
+
+ return trxcon;
+}
+
+void trxcon_inst_free(struct trxcon_inst *trxcon)
+{
+ /* Shutdown the scheduler */
+ if (trxcon->sched != NULL)
+ l1sched_free(trxcon->sched);
+ /* Close active connections */
+ if (trxcon->l1l != NULL)
+ l1ctl_link_shutdown(trxcon->l1l);
+ if (trxcon->trx != NULL)
+ trx_if_close(trxcon->trx);
+
+ if (trxcon->fi != NULL)
+ osmo_fsm_inst_free(trxcon->fi);
+ talloc_free(trxcon);
+}
+
static void print_usage(const char *app)
{
printf("Usage: %s\n", app);
@@ -427,6 +486,7 @@
int main(int argc, char **argv)
{
+ struct trxcon_inst *trxcon = NULL;
int rc = 0;
printf("%s", COPYRIGHT);
@@ -469,37 +529,14 @@
gsmtap_source_add_sink(app_data.gsmtap);
}
- /* Allocate the application state machine */
+ /* Register the trxcon state machine */
OSMO_ASSERT(osmo_fsm_register(&trxcon_fsm_def) == 0);
- trxcon_fsm = osmo_fsm_inst_alloc(&trxcon_fsm_def, tall_trxcon_ctx,
- NULL, LOGL_DEBUG, "main");
- /* Init L1CTL server */
- app_data.l1l = l1ctl_link_init(tall_trxcon_ctx,
- app_data.bind_socket);
- if (app_data.l1l == NULL)
+ /* Allocate the trxcon instance (only one for now) */
+ trxcon = trxcon_inst_alloc(tall_trxcon_ctx);
+ if (trxcon == NULL)
goto exit;
- /* Init transceiver interface */
- app_data.trx = trx_if_open(tall_trxcon_ctx,
- app_data.trx_bind_ip, app_data.trx_remote_ip,
- app_data.trx_base_port);
- if (!app_data.trx)
- goto exit;
-
- /* Bind L1CTL with TRX and vice versa */
- app_data.l1l->trx = app_data.trx;
- app_data.trx->l1l = app_data.l1l;
-
- /* Init scheduler */
- app_data.sched = l1sched_alloc(tall_trxcon_ctx, app_data.trx_fn_advance);
- if (app_data.sched == NULL)
- goto exit;
-
- /* Let both L1CTL and TRX interfaces access to the scheduler */
- app_data.l1l->sched = app_data.sched;
- app_data.trx->sched = app_data.sched;
-
LOGP(DAPP, LOGL_NOTICE, "Init complete\n");
if (app_data.daemonize) {
@@ -517,13 +554,9 @@
osmo_select_main(0);
exit:
- /* Close active connections */
- l1ctl_link_shutdown(app_data.l1l);
- l1sched_free(app_data.sched);
- trx_if_close(app_data.trx);
-
- /* Shutdown main state machine */
- osmo_fsm_inst_free(trxcon_fsm);
+ /* Release the trxcon instance */
+ if (trxcon != NULL)
+ trxcon_inst_free(trxcon);
/* Deinitialize logging */
log_fini();
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/28667
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I23319951c56577085e1092669b5534f9d6bda48d
Gerrit-Change-Number: 28667
Gerrit-PatchSet: 5
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged