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
This commit is contained in:
parent
e5d8a469d2
commit
771e9f2838
|
@ -11,11 +11,13 @@ enum {
|
||||||
|
|
||||||
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn);
|
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_lchan_react(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
void vgcs_talker_frame(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);
|
void vgcs_listener_reset(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
|
|
@ -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_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_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_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 {
|
enum l1sap_common_sapi {
|
||||||
L1SAP_COMMON_SAPI_UNKNOWN,
|
L1SAP_COMMON_SAPI_UNKNOWN,
|
||||||
|
|
|
@ -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 */
|
/* Stop RACH detection, wait for valid frame */
|
||||||
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
|
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
|
||||||
if (l1sap_chan_modify(lchan->ts->trx, gsm_lchan2chan_nr(lchan)) != 0) {
|
if (l1sap_uplink_access(lchan, false) != 0) {
|
||||||
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "failed to modify channel after TALKER DET\n");
|
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access after TALKER DET.\n");
|
||||||
rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL);
|
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
|
||||||
lchan->asci.talker_active = VGCS_TALKER_NONE;
|
lchan->asci.talker_active = VGCS_TALKER_NONE;
|
||||||
return;
|
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) */
|
/* Received channel reactivation. (for assignment) */
|
||||||
void vgcs_lchan_react(struct gsm_lchan *lchan)
|
void vgcs_lchan_react(struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n");
|
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n");
|
||||||
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
|
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);
|
radio_link_timeout_reset(lchan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +183,7 @@ void vgcs_talker_frame(struct gsm_lchan *lchan)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release VGCS Talker state. */
|
/* 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)
|
if (lchan->asci.talker_active == VGCS_TALKER_NONE)
|
||||||
return;
|
return;
|
||||||
|
@ -179,8 +193,15 @@ void vgcs_talker_reset(struct gsm_lchan *lchan)
|
||||||
/* Stop T3115 */
|
/* Stop T3115 */
|
||||||
osmo_timer_del(&lchan->asci.t3115);
|
osmo_timer_del(&lchan->asci.t3115);
|
||||||
|
|
||||||
/* Talker detection done */
|
/* Talker released. */
|
||||||
lchan->asci.talker_active = VGCS_TALKER_NONE;
|
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. */
|
/* Release VGCS Listener state. */
|
||||||
|
|
|
@ -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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
/* release handover, listener and talker states */
|
||||||
handover_reset(lchan);
|
handover_reset(lchan);
|
||||||
vgcs_talker_reset(lchan);
|
vgcs_talker_reset(lchan, false);
|
||||||
vgcs_listener_reset(lchan);
|
vgcs_listener_reset(lchan);
|
||||||
vgcs_uplink_free_reset(lchan);
|
vgcs_uplink_free_reset(lchan);
|
||||||
|
|
||||||
|
|
|
@ -2207,8 +2207,12 @@ static int rsl_rx_chan_activ(struct msgb *msg)
|
||||||
lchan->top_acch_active = false;
|
lchan->top_acch_active = false;
|
||||||
|
|
||||||
/* set ASCI channel into right state */
|
/* set ASCI channel into right state */
|
||||||
if (reactivation && rsl_chan_rt_is_asci(lchan->rsl_chan_rt))
|
if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) {
|
||||||
vgcs_lchan_react(lchan);
|
if (reactivation)
|
||||||
|
vgcs_lchan_react(lchan);
|
||||||
|
else
|
||||||
|
vgcs_lchan_activate(lchan);
|
||||||
|
}
|
||||||
|
|
||||||
/* on reactivation, the channel is already activated */
|
/* on reactivation, the channel is already activated */
|
||||||
if (reactivation) {
|
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. */
|
/* VGCS Uplink is released by MSC using REL-REQ. */
|
||||||
if (rh->c.msg_type == RSL_MT_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));
|
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 */
|
/* REL_IND handling */
|
||||||
if (rh->msg_type == RSL_MT_REL_IND && lchan_is_tch(lchan)) {
|
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,
|
LOGPLCHAN(lchan, DRSL, LOGL_INFO,
|
||||||
"Scheduling %s to L3 in next associated TCH-RTS.ind\n",
|
"Scheduling %s to L3 in next associated TCH-RTS.ind\n",
|
||||||
rsl_msg_name(rh->msg_type));
|
rsl_msg_name(rh->msg_type));
|
||||||
|
|
Loading…
Reference in New Issue