fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/30103 )
Change subject: trxcon: move shim l1sched/phyif API to libtrxcon.la ......................................................................
trxcon: move shim l1sched/phyif API to libtrxcon.la
Change-Id: I56701b471a6f1c30ffd107037c2b1aed65621b2c Related: OS#5599 --- M src/host/trxcon/include/osmocom/bb/trxcon/phyif.h M src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h M src/host/trxcon/src/Makefile.am M src/host/trxcon/src/trx_if.c M src/host/trxcon/src/trxcon_main.c A src/host/trxcon/src/trxcon_shim.c 6 files changed, 273 insertions(+), 239 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/03/30103/1
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h b/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h index de6c3fd..132cd9b 100644 --- a/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h +++ b/src/host/trxcon/include/osmocom/bb/trxcon/phyif.h @@ -89,8 +89,8 @@ };
-int osmo_trxcon_phyif_handle_bi(void *phyif, const struct osmo_trxcon_phyif_bi *bi); +int osmo_trxcon_phyif_handle_bi(void *priv, const struct osmo_trxcon_phyif_bi *bi); int osmo_trxcon_phyif_handle_br(void *phyif, const struct osmo_trxcon_phyif_br *br); int osmo_trxcon_phyif_handle_cmd(void *phyif, const struct osmo_trxcon_phyif_cmd *cmd); -int osmo_trxcon_phyif_handle_rsp(void *phyif, const struct osmo_trxcon_phyif_rsp *rsp); +int osmo_trxcon_phyif_handle_rsp(void *priv, const struct osmo_trxcon_phyif_rsp *rsp); void osmo_trxcon_phyif_close(void *phyif); diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h index b3966bf..098609e 100644 --- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h +++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h @@ -13,6 +13,9 @@ /* Logging context for sched and l1c */ const char *log_prefix;
+ /* GSMTAP instance (optional) */ + struct gsmtap_inst *gsmtap; + /* The L1 scheduler */ struct l1sched_state *sched; /* PHY interface (e.g. TRXC/TRXD) */ diff --git a/src/host/trxcon/src/Makefile.am b/src/host/trxcon/src/Makefile.am index e0ce6a2..34b7a3c 100644 --- a/src/host/trxcon/src/Makefile.am +++ b/src/host/trxcon/src/Makefile.am @@ -40,6 +40,7 @@ libtrxcon_la_SOURCES = \ trxcon_inst.c \ trxcon_fsm.c \ + trxcon_shim.c \ l1ctl.c \ $(NULL)
diff --git a/src/host/trxcon/src/trx_if.c b/src/host/trxcon/src/trx_if.c index cc0599f..b00b34b 100644 --- a/src/host/trxcon/src/trx_if.c +++ b/src/host/trxcon/src/trx_if.c @@ -390,7 +390,7 @@ }, };
- osmo_trxcon_phyif_handle_rsp(trx, &rsp); + osmo_trxcon_phyif_handle_rsp(trx->priv, &rsp); }
/* @@ -676,7 +676,7 @@ "RX burst tn=%u fn=%u rssi=%d toa=%d\n", bi.tn, bi.fn, bi.rssi, bi.toa256);
- return osmo_trxcon_phyif_handle_bi(trx, &bi); + return osmo_trxcon_phyif_handle_bi(trx->priv, &bi); }
int trx_if_handle_phyif_br(struct trx_instance *trx, diff --git a/src/host/trxcon/src/trxcon_main.c b/src/host/trxcon/src/trxcon_main.c index ebdc3b2..440bc0f 100644 --- a/src/host/trxcon/src/trxcon_main.c +++ b/src/host/trxcon/src/trxcon_main.c @@ -48,7 +48,6 @@ #include <osmocom/bb/trxcon/logging.h> #include <osmocom/bb/trxcon/l1ctl.h> #include <osmocom/bb/trxcon/l1ctl_server.h> -#include <osmocom/bb/l1sched/l1sched.h>
#define COPYRIGHT \ "Copyright (C) 2016-2022 by Vadim Yanitskiy axilirator@gmail.com\n" \ @@ -87,87 +86,6 @@
static void *tall_trxcon_ctx = NULL;
-static void trxcon_gsmtap_send(const struct l1sched_lchan_desc *lchan_desc, - uint32_t fn, uint8_t tn, uint16_t band_arfcn, - int8_t signal_dbm, uint8_t snr, - const uint8_t *data, size_t data_len) -{ - /* GSMTAP logging may be not enabled */ - if (app_data.gsmtap == NULL) - return; - - /* Omit frames with unknown channel type */ - if (lchan_desc->gsmtap_chan_type == GSMTAP_CHANNEL_UNKNOWN) - return; - - /* TODO: distinguish GSMTAP_CHANNEL_PCH and GSMTAP_CHANNEL_AGCH */ - gsmtap_send(app_data.gsmtap, band_arfcn, tn, lchan_desc->gsmtap_chan_type, - lchan_desc->ss_nr, fn, signal_dbm, snr, data, data_len); -} - -/* External L1 API for the scheduler */ -int l1sched_handle_config_req(struct l1sched_state *sched, - const struct l1sched_config_req *cr) -{ - struct osmo_trxcon_inst *trxcon = sched->priv; - - switch (cr->type) { - case L1SCHED_CFG_PCHAN_COMB: - { - struct trxcon_param_set_phy_config_req req = { - .type = TRXCON_PHY_CFGT_PCHAN_COMB, - .pchan_comb = { - .tn = cr->pchan_comb.tn, - .pchan = cr->pchan_comb.pchan, - }, - }; - - return osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_SET_PHY_CONFIG_REQ, &req); - } - default: - LOGPFSML(trxcon->fi, LOGL_ERROR, - "Unhandled config request (type 0x%02x)\n", cr->type); - return -ENODEV; - } -} - -int l1sched_handle_burst_req(struct l1sched_state *sched, - const struct l1sched_burst_req *br) -{ - struct osmo_trxcon_inst *trxcon = sched->priv; - const struct osmo_trxcon_phyif_br phybr = { - .fn = br->fn, - .tn = br->tn, - .pwr = br->pwr, - .burst = &br->burst[0], - .burst_len = br->burst_len, - }; - - return osmo_trxcon_phyif_handle_br(trxcon->phyif, &phybr); -} - -/* External L1 API for the PHYIF */ -int osmo_trxcon_phyif_handle_bi(void *phyif, const struct osmo_trxcon_phyif_bi *bi) -{ - struct trx_instance *trx = phyif; - struct osmo_trxcon_inst *trxcon = trx->priv; - const struct l1sched_meas_set meas = { - .fn = bi->fn, - .toa256 = bi->toa256, - .rssi = bi->rssi, - }; - - /* Poke scheduler */ - l1sched_handle_rx_burst(trxcon->sched, bi->tn, bi->fn, - bi->burst, bi->burst_len, &meas); - - /* Correct local clock counter */ - if (bi->fn % 51 == 0) - l1sched_clck_handle(trxcon->sched, bi->fn); - - return 0; -} - int osmo_trxcon_phyif_handle_br(void *phyif, const struct osmo_trxcon_phyif_br *br) { return trx_if_handle_phyif_br(phyif, br); @@ -178,164 +96,11 @@ return trx_if_handle_phyif_cmd(phyif, cmd); }
-int osmo_trxcon_phyif_handle_rsp(void *phyif, const struct osmo_trxcon_phyif_rsp *rsp) -{ - struct trx_instance *trx = phyif; - struct osmo_trxcon_inst *trxcon = trx->priv; - - switch (rsp->type) { - case OSMO_TRXCON_PHYIF_CMDT_MEASURE: - { - const struct osmo_trxcon_phyif_rspp_measure *meas = &rsp->param.measure; - struct trxcon_param_full_power_scan_res res = { - .band_arfcn = meas->band_arfcn, - .dbm = meas->dbm, - }; - - return osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_FULL_POWER_SCAN_RES, &res); - } - default: - LOGPFSML(trxcon->fi, LOGL_ERROR, - "Unhandled PHYIF response (type 0x%02x)\n", rsp->type); - return -ENODEV; - } -} - void osmo_trxcon_phyif_close(void *phyif) { trx_if_close(phyif); }
-/* External L2 API for the scheduler */ -int l1sched_handle_data_ind(struct l1sched_lchan_state *lchan, - const uint8_t *data, size_t data_len, - int n_errors, int n_bits_total, - enum l1sched_data_type dt) -{ - const struct l1sched_meas_set *meas = &lchan->meas_avg; - const struct l1sched_lchan_desc *lchan_desc; - struct l1sched_state *sched = lchan->ts->sched; - struct osmo_trxcon_inst *trxcon = sched->priv; - int rc; - - lchan_desc = &l1sched_lchan_desc[lchan->type]; - - struct trxcon_param_rx_data_ind ind = { - /* .traffic is set below */ - .chan_nr = lchan_desc->chan_nr | lchan->ts->index, - .link_id = lchan_desc->link_id, - .band_arfcn = trxcon->l1p.band_arfcn, - .frame_nr = meas->fn, - .toa256 = meas->toa256, - .rssi = meas->rssi, - .n_errors = n_errors, - .n_bits_total = n_bits_total, - .data_len = data_len, - .data = data, - }; - - switch (dt) { - case L1SCHED_DT_PACKET_DATA: - case L1SCHED_DT_TRAFFIC: - ind.traffic = true; - /* fall-through */ - case L1SCHED_DT_SIGNALING: - rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_RX_DATA_IND, &ind); - break; - case L1SCHED_DT_OTHER: - if (lchan->type == L1SCHED_SCH) { - if (trxcon->fi->state != TRXCON_ST_FBSB_SEARCH) - return 0; - rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_FBSB_SEARCH_RES, NULL); - break; - } - /* fall through */ - default: - 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, - trxcon->l1p.band_arfcn, meas->rssi, 0, - data, data_len); - } - - return rc; -} - -int l1sched_handle_data_cnf(struct l1sched_lchan_state *lchan, - uint32_t fn, enum l1sched_data_type dt) -{ - const struct l1sched_lchan_desc *lchan_desc; - struct l1sched_state *sched = lchan->ts->sched; - struct osmo_trxcon_inst *trxcon = sched->priv; - bool is_traffic = false; - const uint8_t *data; - uint8_t ra_buf[2]; - size_t data_len; - int rc; - - lchan_desc = &l1sched_lchan_desc[lchan->type]; - - switch (dt) { - case L1SCHED_DT_TRAFFIC: - case L1SCHED_DT_PACKET_DATA: - is_traffic = true; - /* fall-through */ - case L1SCHED_DT_SIGNALING: - { - struct trxcon_param_tx_data_cnf cnf = { - .traffic = is_traffic, - .chan_nr = lchan_desc->chan_nr | lchan->ts->index, - .link_id = lchan_desc->link_id, - .band_arfcn = trxcon->l1p.band_arfcn, - .frame_nr = fn, - }; - - rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_DATA_CNF, &cnf); - data_len = lchan->prim->payload_len; - data = lchan->prim->payload; - break; - } - case L1SCHED_DT_OTHER: - if (L1SCHED_PRIM_IS_RACH(lchan->prim)) { - const struct l1sched_ts_prim_rach *rach; - struct trxcon_param_tx_access_burst_cnf cnf = { - .band_arfcn = trxcon->l1p.band_arfcn, - .frame_nr = fn, - }; - - rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_ACCESS_BURST_CNF, &cnf); - - rach = (struct l1sched_ts_prim_rach *)lchan->prim->payload; - if (lchan->prim->type == L1SCHED_PRIM_RACH11) { - ra_buf[0] = (uint8_t)(rach->ra >> 3); - ra_buf[1] = (uint8_t)(rach->ra & 0x07); - data = &ra_buf[0]; - data_len = 2; - } else { - ra_buf[0] = (uint8_t)(rach->ra); - data = &ra_buf[0]; - data_len = 1; - } - break; - } - /* fall through */ - default: - 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, - trxcon->l1p.band_arfcn | ARFCN_UPLINK, - 0, 0, data, data_len); - - return rc; -} - void osmo_trxcon_l1ctl_close(struct osmo_trxcon_inst *trxcon) { /* Avoid use-after-free: both *fi and *trxcon are children of @@ -391,6 +156,8 @@ osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_PHYIF_FAILURE, NULL); return; } + + trxcon->gsmtap = app_data.gsmtap; }
static void l1ctl_conn_close_cb(struct l1ctl_client *l1c) diff --git a/src/host/trxcon/src/trxcon_shim.c b/src/host/trxcon/src/trxcon_shim.c new file mode 100644 index 0000000..47e5cea --- /dev/null +++ b/src/host/trxcon/src/trxcon_shim.c @@ -0,0 +1,263 @@ +/* + * OsmocomBB <-> SDR connection bridge + * + * (C) 2022 by sysmocom - s.f.m.c. GmbH info@sysmocom.de + * Author: Vadim Yanitskiy vyanitskiy@sysmocom.de + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdint.h> +#include <errno.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/gsmtap_util.h> +#include <osmocom/core/gsmtap.h> + +#include <osmocom/bb/trxcon/trxcon.h> +#include <osmocom/bb/trxcon/trxcon_fsm.h> +#include <osmocom/bb/trxcon/phyif.h> +#include <osmocom/bb/l1sched/l1sched.h> + +static void trxcon_gsmtap_send(struct gsmtap_inst *gi, uint8_t chan_type, + uint32_t fn, uint8_t tn, uint8_t ss, + uint16_t band_arfcn, + int8_t signal_dbm, uint8_t snr, + const uint8_t *data, size_t data_len) +{ + /* Omit frames with unknown channel type */ + if (chan_type == GSMTAP_CHANNEL_UNKNOWN) + return; + + /* TODO: distinguish GSMTAP_CHANNEL_PCH and GSMTAP_CHANNEL_AGCH */ + gsmtap_send(gi, band_arfcn, tn, chan_type, ss, fn, signal_dbm, snr, data, data_len); +} + +/* External L1 API for the scheduler */ +int l1sched_handle_config_req(struct l1sched_state *sched, + const struct l1sched_config_req *cr) +{ + struct osmo_trxcon_inst *trxcon = sched->priv; + + switch (cr->type) { + case L1SCHED_CFG_PCHAN_COMB: + { + struct trxcon_param_set_phy_config_req req = { + .type = TRXCON_PHY_CFGT_PCHAN_COMB, + .pchan_comb = { + .tn = cr->pchan_comb.tn, + .pchan = cr->pchan_comb.pchan, + }, + }; + + return osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_SET_PHY_CONFIG_REQ, &req); + } + default: + LOGPFSML(trxcon->fi, LOGL_ERROR, + "Unhandled config request (type 0x%02x)\n", cr->type); + return -ENODEV; + } +} + +int l1sched_handle_burst_req(struct l1sched_state *sched, + const struct l1sched_burst_req *br) +{ + struct osmo_trxcon_inst *trxcon = sched->priv; + const struct osmo_trxcon_phyif_br phybr = { + .fn = br->fn, + .tn = br->tn, + .pwr = br->pwr, + .burst = &br->burst[0], + .burst_len = br->burst_len, + }; + + return osmo_trxcon_phyif_handle_br(trxcon->phyif, &phybr); +} + +/* External L2 API for the scheduler */ +int l1sched_handle_data_ind(struct l1sched_lchan_state *lchan, + const uint8_t *data, size_t data_len, + int n_errors, int n_bits_total, + enum l1sched_data_type dt) +{ + const struct l1sched_meas_set *meas = &lchan->meas_avg; + const struct l1sched_lchan_desc *lchan_desc; + struct l1sched_state *sched = lchan->ts->sched; + struct osmo_trxcon_inst *trxcon = sched->priv; + int rc; + + lchan_desc = &l1sched_lchan_desc[lchan->type]; + + struct trxcon_param_rx_data_ind ind = { + /* .traffic is set below */ + .chan_nr = lchan_desc->chan_nr | lchan->ts->index, + .link_id = lchan_desc->link_id, + .band_arfcn = trxcon->l1p.band_arfcn, + .frame_nr = meas->fn, + .toa256 = meas->toa256, + .rssi = meas->rssi, + .n_errors = n_errors, + .n_bits_total = n_bits_total, + .data_len = data_len, + .data = data, + }; + + switch (dt) { + case L1SCHED_DT_PACKET_DATA: + case L1SCHED_DT_TRAFFIC: + ind.traffic = true; + /* fall-through */ + case L1SCHED_DT_SIGNALING: + rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_RX_DATA_IND, &ind); + break; + case L1SCHED_DT_OTHER: + if (lchan->type == L1SCHED_SCH) { + if (trxcon->fi->state != TRXCON_ST_FBSB_SEARCH) + return 0; + rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_FBSB_SEARCH_RES, NULL); + break; + } + /* fall through */ + default: + LOGPFSML(trxcon->fi, LOGL_ERROR, + "Unhandled L2 DATA.ind (type 0x%02x)\n", dt); + return -ENODEV; + } + + if (trxcon->gsmtap != NULL && data != NULL && data_len > 0) { + trxcon_gsmtap_send(trxcon->gsmtap, lchan_desc->gsmtap_chan_type, + meas->fn, lchan->ts->index, lchan_desc->ss_nr, + trxcon->l1p.band_arfcn, meas->rssi, 0, + data, data_len); + } + + return rc; +} + +int l1sched_handle_data_cnf(struct l1sched_lchan_state *lchan, + uint32_t fn, enum l1sched_data_type dt) +{ + const struct l1sched_lchan_desc *lchan_desc; + struct l1sched_state *sched = lchan->ts->sched; + struct osmo_trxcon_inst *trxcon = sched->priv; + bool is_traffic = false; + const uint8_t *data; + uint8_t ra_buf[2]; + size_t data_len; + int rc; + + lchan_desc = &l1sched_lchan_desc[lchan->type]; + + switch (dt) { + case L1SCHED_DT_TRAFFIC: + case L1SCHED_DT_PACKET_DATA: + is_traffic = true; + /* fall-through */ + case L1SCHED_DT_SIGNALING: + { + struct trxcon_param_tx_data_cnf cnf = { + .traffic = is_traffic, + .chan_nr = lchan_desc->chan_nr | lchan->ts->index, + .link_id = lchan_desc->link_id, + .band_arfcn = trxcon->l1p.band_arfcn, + .frame_nr = fn, + }; + + rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_DATA_CNF, &cnf); + data_len = lchan->prim->payload_len; + data = lchan->prim->payload; + break; + } + case L1SCHED_DT_OTHER: + if (L1SCHED_PRIM_IS_RACH(lchan->prim)) { + const struct l1sched_ts_prim_rach *rach; + struct trxcon_param_tx_access_burst_cnf cnf = { + .band_arfcn = trxcon->l1p.band_arfcn, + .frame_nr = fn, + }; + + rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_ACCESS_BURST_CNF, &cnf); + + rach = (struct l1sched_ts_prim_rach *)lchan->prim->payload; + if (lchan->prim->type == L1SCHED_PRIM_RACH11) { + ra_buf[0] = (uint8_t)(rach->ra >> 3); + ra_buf[1] = (uint8_t)(rach->ra & 0x07); + data = &ra_buf[0]; + data_len = 2; + } else { + ra_buf[0] = (uint8_t)(rach->ra); + data = &ra_buf[0]; + data_len = 1; + } + break; + } + /* fall through */ + default: + LOGPFSML(trxcon->fi, LOGL_ERROR, + "Unhandled L2 DATA.cnf (type 0x%02x)\n", dt); + return -ENODEV; + } + + if (trxcon->gsmtap != NULL) { + trxcon_gsmtap_send(trxcon->gsmtap, lchan_desc->gsmtap_chan_type, + fn, lchan->ts->index, lchan_desc->ss_nr, + trxcon->l1p.band_arfcn | ARFCN_UPLINK, + 0, 0, data, data_len); + } + + return rc; +} + +/* External L1 API for the PHYIF */ +int osmo_trxcon_phyif_handle_bi(void *priv, const struct osmo_trxcon_phyif_bi *bi) +{ + struct osmo_trxcon_inst *trxcon = priv; + const struct l1sched_meas_set meas = { + .fn = bi->fn, + .toa256 = bi->toa256, + .rssi = bi->rssi, + }; + + /* Poke scheduler */ + l1sched_handle_rx_burst(trxcon->sched, bi->tn, bi->fn, + bi->burst, bi->burst_len, &meas); + + /* Correct local clock counter */ + if (bi->fn % 51 == 0) + l1sched_clck_handle(trxcon->sched, bi->fn); + + return 0; +} + +int osmo_trxcon_phyif_handle_rsp(void *priv, const struct osmo_trxcon_phyif_rsp *rsp) +{ + struct osmo_trxcon_inst *trxcon = priv; + + switch (rsp->type) { + case OSMO_TRXCON_PHYIF_CMDT_MEASURE: + { + const struct osmo_trxcon_phyif_rspp_measure *meas = &rsp->param.measure; + struct trxcon_param_full_power_scan_res res = { + .band_arfcn = meas->band_arfcn, + .dbm = meas->dbm, + }; + + return osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_FULL_POWER_SCAN_RES, &res); + } + default: + LOGPFSML(trxcon->fi, LOGL_ERROR, + "Unhandled PHYIF response (type 0x%02x)\n", rsp->type); + return -ENODEV; + } +}