diff options
author | Andreas Eversberg <andreas@eversberg.eu> | 2023-10-24 17:57:17 +0200 |
---|---|---|
committer | jolly <andreas@eversberg.eu> | 2023-10-27 10:35:21 +0000 |
commit | 771e9f28381714e1b8666f8f4687bb9096aa28b0 (patch) | |
tree | ddb04db4f0c4b415ed8ed5606f4bca8d43210496 | |
parent | e5d8a469d2311642ba031cff6b6a446199aaf3a4 (diff) |
ASCI: Control uplink access bursts detection of physical interface
An MPH-INFO message is used to turn detection of uplink access bursts on
or off. Whenever the uplink on a voice group channel is free, the uplink
access burst detection is turned on. When the uplink access is granted
to a talker or when the calling subscriber has been assigned to the
channel, the uplink access burst detection is turned off until the
uplink becomes free again.
Related: OS#4851
Depends: libosmocore.git Ibd6a1d468a70126a8f67e944fcb916969cc3c36b
Change-Id: I92d6773a3a463eb747143c85aa149e54c1fda122
-rw-r--r-- | include/osmo-bts/asci.h | 4 | ||||
-rw-r--r-- | include/osmo-bts/l1sap.h | 1 | ||||
-rw-r--r-- | src/common/asci.c | 31 | ||||
-rw-r--r-- | src/common/l1sap.c | 23 | ||||
-rw-r--r-- | src/common/lchan.c | 2 | ||||
-rw-r--r-- | src/common/rsl.c | 12 |
6 files changed, 62 insertions, 11 deletions
diff --git a/include/osmo-bts/asci.h b/include/osmo-bts/asci.h index 59b48b27..99802962 100644 --- a/include/osmo-bts/asci.h +++ b/include/osmo-bts/asci.h @@ -11,11 +11,13 @@ enum { void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn); +void vgcs_lchan_activate(struct gsm_lchan *lchan); + void vgcs_lchan_react(struct gsm_lchan *lchan); void vgcs_talker_frame(struct gsm_lchan *lchan); -void vgcs_talker_reset(struct gsm_lchan *lchan); +void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access); void vgcs_listener_reset(struct gsm_lchan *lchan); diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 353fc905..34259bd3 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -102,6 +102,7 @@ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr); +int l1sap_uplink_access(struct gsm_lchan *lchan, bool active); enum l1sap_common_sapi { L1SAP_COMMON_SAPI_UNKNOWN, diff --git a/src/common/asci.c b/src/common/asci.c index ccaacd8e..88d40e78 100644 --- a/src/common/asci.c +++ b/src/common/asci.c @@ -126,9 +126,9 @@ void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t /* Stop RACH detection, wait for valid frame */ lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME; - if (l1sap_chan_modify(lchan->ts->trx, gsm_lchan2chan_nr(lchan)) != 0) { - LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "failed to modify channel after TALKER DET\n"); - rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL); + if (l1sap_uplink_access(lchan, false) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access after TALKER DET.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); lchan->asci.talker_active = VGCS_TALKER_NONE; return; } @@ -151,11 +151,25 @@ void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t } } +/* Received channel activation. */ +void vgcs_lchan_activate(struct gsm_lchan *lchan) +{ + LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated.\n"); + if (l1sap_uplink_access(lchan, true) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to activate uplink access after channel activation.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + } +} + /* Received channel reactivation. (for assignment) */ void vgcs_lchan_react(struct gsm_lchan *lchan) { LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n"); lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME; + if (l1sap_uplink_access(lchan, false) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access for assignment.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + } radio_link_timeout_reset(lchan); } @@ -169,7 +183,7 @@ void vgcs_talker_frame(struct gsm_lchan *lchan) } /* Release VGCS Talker state. */ -void vgcs_talker_reset(struct gsm_lchan *lchan) +void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access) { if (lchan->asci.talker_active == VGCS_TALKER_NONE) return; @@ -179,8 +193,15 @@ void vgcs_talker_reset(struct gsm_lchan *lchan) /* Stop T3115 */ osmo_timer_del(&lchan->asci.t3115); - /* Talker detection done */ + /* Talker released. */ lchan->asci.talker_active = VGCS_TALKER_NONE; + if (ul_access) { + if (l1sap_uplink_access(lchan, true) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, + "Failed to activate uplink access after uplink became free.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + } + } } /* Release VGCS Listener state. */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 844fdada..c5997260 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -2444,3 +2444,26 @@ int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr) return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_MODIFY, 0); } + +int l1sap_uplink_access(struct gsm_lchan *lchan, bool active) +{ + uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + struct osmo_phsap_prim l1sap; + + if (lchan->state != LCHAN_S_ACTIVE && !rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Channel %s is not an active ASCI type channel.\n", + rsl_chan_nr_str(chan_nr)); + return -EINVAL; + } + + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s uplink access detection on channel %s\n", + (active) ? "Activating" : "Deactivating", rsl_chan_nr_str(chan_nr)); + + + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_REQUEST, NULL); + l1sap.u.info.type = (active) ? PRIM_INFO_ACT_UL_ACC : PRIM_INFO_DEACT_UL_ACC; + l1sap.u.info.u.ulacc_req.chan_nr = chan_nr; + + return l1sap_down(lchan->ts->trx, &l1sap); +} diff --git a/src/common/lchan.c b/src/common/lchan.c index bd503497..6178200f 100644 --- a/src/common/lchan.c +++ b/src/common/lchan.c @@ -219,7 +219,7 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind /* release handover, listener and talker states */ handover_reset(lchan); - vgcs_talker_reset(lchan); + vgcs_talker_reset(lchan, false); vgcs_listener_reset(lchan); vgcs_uplink_free_reset(lchan); diff --git a/src/common/rsl.c b/src/common/rsl.c index 09723bed..deeb255c 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2207,8 +2207,12 @@ static int rsl_rx_chan_activ(struct msgb *msg) lchan->top_acch_active = false; /* set ASCI channel into right state */ - if (reactivation && rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) - vgcs_lchan_react(lchan); + if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) { + if (reactivation) + vgcs_lchan_react(lchan); + else + vgcs_lchan_activate(lchan); + } /* on reactivation, the channel is already activated */ if (reactivation) { @@ -3618,7 +3622,7 @@ static int rsl_rx_rll(struct gsm_bts_trx *trx, struct msgb *msg) /* VGCS Uplink is released by MSC using REL-REQ. */ if (rh->c.msg_type == RSL_MT_REL_REQ) - vgcs_talker_reset(lchan); + vgcs_talker_reset(lchan, true); LOGPLCHAN(lchan, DRLL, LOGL_DEBUG, "Rx RLL %s Abis -> LAPDm\n", rsl_msg_name(rh->c.msg_type)); @@ -3840,7 +3844,7 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx) /* REL_IND handling */ if (rh->msg_type == RSL_MT_REL_IND && lchan_is_tch(lchan)) { - vgcs_talker_reset(lchan); + vgcs_talker_reset(lchan, true); LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Scheduling %s to L3 in next associated TCH-RTS.ind\n", rsl_msg_name(rh->msg_type)); |