From 419f617a3c04a68cd3054bb7bab9d0ab488937e2 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 9 Mar 2020 19:34:39 +0100 Subject: virtphy: Fix GSMTAP ARFCN use with multi-TRX BTS In case we get assignments to secondary TRXs, the ARFCN of that TRX must be used, and not the serving cell BCCH ARFCN. Change-Id: Ief6cf5816969d819ff9506be70bec9b8d0d9d9be --- src/host/virt_phy/include/virtphy/virt_l1_model.h | 1 + src/host/virt_phy/src/gsmtapl1_if.c | 36 ++++++++++++++++------- src/host/virt_phy/src/l1ctl_sap.c | 6 ++-- src/host/virt_phy/src/virt_prim_data.c | 3 +- src/host/virt_phy/src/virt_prim_traffic.c | 3 +- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/host/virt_phy/include/virtphy/virt_l1_model.h b/src/host/virt_phy/include/virtphy/virt_l1_model.h index e2485fc8..99ad39f3 100644 --- a/src/host/virt_phy/include/virtphy/virt_l1_model.h +++ b/src/host/virt_phy/include/virtphy/virt_l1_model.h @@ -68,6 +68,7 @@ struct l1_state_ms { struct { uint8_t chan_type; // like rsl chantype 08.58 -> Chapter 9.3.1 */ + uint16_t band_arfcn; uint8_t tn; // timeslot number 1-7 uint8_t subslot; // subslot of the dedicated channel, SDCCH/4:[0-3], SDCCH/8:[0-7] diff --git a/src/host/virt_phy/src/gsmtapl1_if.c b/src/host/virt_phy/src/gsmtapl1_if.c index 3fa69c4f..83b01fec 100644 --- a/src/host/virt_phy/src/gsmtapl1_if.c +++ b/src/host/virt_phy/src/gsmtapl1_if.c @@ -81,7 +81,7 @@ void gsmtapl1_tx_to_virt_um_inst(struct l1_model_ms *ms, uint32_t fn, uint8_t tn struct l1ctl_info_ul *ul; struct gsmtap_hdr *gh; struct msgb *outmsg; /* msg to send with gsmtap header prepended */ - uint16_t arfcn = ms->state.serving_cell.arfcn; /* arfcn of the cell we currently camp on */ + uint16_t arfcn; uint8_t signal_dbm = 63; /* signal strength */ uint8_t snr = 63; /* signal noise ratio, 63 is best */ uint8_t *data = msgb_l2(msg); /* data to transmit (whole message without l1 header) */ @@ -92,6 +92,16 @@ void gsmtapl1_tx_to_virt_um_inst(struct l1_model_ms *ms, uint32_t fn, uint8_t tn uint8_t timeslot; /* tdma timeslot to send in (0-7) */ uint8_t gsmtap_chan; /* the gsmtap channel */ + switch (ms->state.state) { + case MS_STATE_DEDICATED: + case MS_STATE_TBF: + arfcn = ms->state.dedicated.band_arfcn; + break; + default: + arfcn = ms->state.serving_cell.arfcn; + break; + } + switch (l1h->msg_type) { case L1CTL_DATA_TBF_REQ: ul = NULL; @@ -235,18 +245,24 @@ static void l1ctl_from_virt_um(struct l1ctl_sock_client *lsc, struct msgb *msg, gsm_fn2gsmtime(&ms->state.downlink_time, fn); - /* we do not forward messages to l23 if we are in network search state */ - if (ms->state.state == MS_STATE_IDLE_SEARCHING) + switch (ms->state.state) { + case MS_STATE_IDLE_SEARCHING: + /* we do not forward messages to l23 if we are in network search state */ return; - - /* forward downlink msg to fbsb sync routine if we are in sync state */ - if (ms->state.state == MS_STATE_IDLE_SYNCING) { + case MS_STATE_IDLE_SYNCING: + /* forward downlink msg to fbsb sync routine if we are in sync state */ prim_fbsb_sync(ms, msg); return; - } - /* generally ignore all messages coming from another arfcn than the camped one */ - if (ms->state.serving_cell.arfcn != arfcn) { - return; + case MS_STATE_DEDICATED: + /* generally ignore all messages coming from another arfcn than the camped one */ + if (arfcn != ms->state.dedicated.band_arfcn) + return; + break; + default: + /* generally ignore all messages coming from another arfcn than the camped one */ + if (arfcn != ms->state.serving_cell.arfcn) + return; + break; } virt_l1_sched_sync_time(ms, ms->state.downlink_time, 0); diff --git a/src/host/virt_phy/src/l1ctl_sap.c b/src/host/virt_phy/src/l1ctl_sap.c index 7669c868..0ff54121 100644 --- a/src/host/virt_phy/src/l1ctl_sap.c +++ b/src/host/virt_phy/src/l1ctl_sap.c @@ -286,9 +286,11 @@ void l1ctl_rx_dm_est_req(struct l1_model_ms *ms, struct msgb *msg) rsl_dec_chan_nr(ul->chan_nr, &rsl_chantype, &subslot, ×lot); - LOGPMS(DL1C, LOGL_INFO, ms, "Rx L1CTL_DM_EST_REQ (chan_nr=0x%02x, tn=%u, ss=%u)\n", - ul->chan_nr, timeslot, subslot); + LOGPMS(DL1C, LOGL_INFO, ms, "Rx L1CTL_DM_EST_REQ (chan_nr=0x%02x, arfcn=%u, tn=%u, ss=%u)\n", + ul->chan_nr, ntohs(est_req->h0.band_arfcn), timeslot, subslot); + OSMO_ASSERT(est_req->h == 0); /* we don't do hopping */ + ms->state.dedicated.band_arfcn = ntohs(est_req->h0.band_arfcn); ms->state.dedicated.chan_type = rsl_chantype; ms->state.dedicated.tn = timeslot; ms->state.dedicated.subslot = subslot; diff --git a/src/host/virt_phy/src/virt_prim_data.c b/src/host/virt_phy/src/virt_prim_data.c index 96534aab..65368b80 100644 --- a/src/host/virt_phy/src/virt_prim_data.c +++ b/src/host/virt_phy/src/virt_prim_data.c @@ -47,7 +47,8 @@ static void virt_l1_sched_handler_cb(struct l1_model_ms *ms, uint32_t fn, uint8_t tn, struct msgb * msg) { gsmtapl1_tx_to_virt_um_inst(ms, fn, tn, msg); - l1ctl_tx_data_conf(ms, fn, 0, ms->state.serving_cell.arfcn); + /* FIXME: get ARFCN from msg payload */ + l1ctl_tx_data_conf(ms, fn, 0, ms->state.dedicated.band_arfcn); } /** diff --git a/src/host/virt_phy/src/virt_prim_traffic.c b/src/host/virt_phy/src/virt_prim_traffic.c index 3d2b2b15..0e08a126 100644 --- a/src/host/virt_phy/src/virt_prim_traffic.c +++ b/src/host/virt_phy/src/virt_prim_traffic.c @@ -47,7 +47,8 @@ static void virt_l1_sched_handler_cb(struct l1_model_ms *ms, uint32_t fn, uint8_t tn, struct msgb * msg) { gsmtapl1_tx_to_virt_um_inst(ms, fn, tn, msg); - l1ctl_tx_traffic_conf(ms, fn, 0, ms->state.serving_cell.arfcn); + /* FIXME: get ARFCN from msg payload */ + l1ctl_tx_traffic_conf(ms, fn, 0, ms->state.dedicated.band_arfcn); } /** -- cgit v1.2.3