aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-05-08 21:07:03 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-05-08 22:14:50 +0200
commit0958278fb9910f4d697aece07d9865ed1db41773 (patch)
tree8bd9f19cdc6a4550c495157550d8a7721bd251fa
parent8799619d27f499481f1bd4f008a7cecc463dc370 (diff)
ignore RSL RF CHAN REL for inactive lchans
When an RF CHANnel RELease request is received on an already released lchan, there is no "REL NACK" message or similar, we just ACK the release. When ACKing the release, make sure to reflect the same chan_nr that the release was asked for, since the lchan state may actually reflect a different chan_nr. Factor the actual Rel Ack message sending out of rsl_tx_rf_rel_ack(), which makes all sorts of decisions around normal Rel Ack: add static tx_rf_rel_ack(), with chan_nr argument instead of deriving chan_nr from the lchan. Use this to directly ACK an unusual Chan Rel with the chan_nr that came in with the request. Fixes: BTS_Tests.TC_dyn_osmo_pdch_unsol_deact (after I6b790e866ce4e66d9385b286b727ae41a83d3e67) Change-Id: Iceaa2e87874ced42d664a2a0b01a1c59e46a19b3
-rw-r--r--src/common/rsl.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 52eb5f48..a09d3a2c 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -613,10 +613,26 @@ static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg)
* dedicated channel related messages
*/
+/* Send an RF CHANnel RELease ACKnowledge with the given chan_nr. This chan_nr may mismatch the current
+ * lchan state, if we received a CHANnel RELease for an already released channel, and we're just acking
+ * what we got without taking any action. */
+static int tx_rf_rel_ack(struct gsm_lchan *lchan, uint8_t chan_nr)
+{
+ struct msgb *msg;
+
+ msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr));
+ if (!msg)
+ return -ENOMEM;
+
+ rsl_dch_push_hdr(msg, RSL_MT_RF_CHAN_REL_ACK, chan_nr);
+ msg->trx = lchan->ts->trx;
+
+ return abis_bts_rsl_sendmsg(msg);
+}
+
/* 8.4.19 sending RF CHANnel RELease ACKnowledge */
int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan)
{
- struct msgb *msg;
uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
bool send_rel_ack;
@@ -675,14 +691,7 @@ int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan)
*/
lapdm_channel_exit(&lchan->lapdm_ch);
- msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr));
- if (!msg)
- return -ENOMEM;
-
- rsl_dch_push_hdr(msg, RSL_MT_RF_CHAN_REL_ACK, chan_nr);
- msg->trx = lchan->ts->trx;
-
- return abis_bts_rsl_sendmsg(msg);
+ return tx_rf_rel_ack(lchan, chan_nr);
}
/* 8.4.2 sending CHANnel ACTIVation ACKnowledge */
@@ -1187,6 +1196,17 @@ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr)
{
int rc;
+ if (lchan->state == LCHAN_S_NONE) {
+ LOGP(DRSL, LOGL_ERROR,
+ "%s ss=%d state=%s Rx RSL RF Channel Release, but is already inactive;"
+ " just ACKing the release\n",
+ gsm_ts_and_pchan_name(lchan->ts), lchan->nr,
+ gsm_lchans_name(lchan->state));
+ /* Just ack the release and ignore. Make sure to reflect the same chan_nr we received,
+ * not necessarily reflecting the current lchan state. */
+ return tx_rf_rel_ack(lchan, chan_nr);
+ }
+
if (lchan->abis_ip.rtp_socket) {
rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC);
osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO,