diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2021-10-06 18:33:35 +0200 |
---|---|---|
committer | pespin <pespin@sysmocom.de> | 2021-10-07 12:11:52 +0000 |
commit | b1409015fa2109edea8645c135da962ad3abf104 (patch) | |
tree | 4ef4d02bc85afb13560c2b1c70a245fb39c32525 | |
parent | db5bf829cdd93d1730c27e17fba7be6a2fe91c88 (diff) |
Introduce gsm_lchan_release function helper
Change-Id: I0525beaba3c833f8d7adf9701fe373761a7720d3
-rw-r--r-- | include/osmo-bts/lchan.h | 1 | ||||
-rw-r--r-- | src/common/lchan.c | 75 | ||||
-rw-r--r-- | src/common/rsl.c | 61 |
3 files changed, 77 insertions, 60 deletions
diff --git a/include/osmo-bts/lchan.h b/include/osmo-bts/lchan.h index b9496b98..4cf957ab 100644 --- a/include/osmo-bts/lchan.h +++ b/include/osmo-bts/lchan.h @@ -325,6 +325,7 @@ static inline const char *lchan_ciph_state_name(uint8_t state) void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr); void gsm_lchan_name_update(struct gsm_lchan *lchan); +void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind); const char *gsm_lchans_name(enum gsm_lchan_state s); static inline char *gsm_lchan_name(const struct gsm_lchan *lchan) diff --git a/src/common/lchan.c b/src/common/lchan.c index afcb2c3e..10a375e7 100644 --- a/src/common/lchan.c +++ b/src/common/lchan.c @@ -20,10 +20,16 @@ */ #include <osmocom/core/logging.h> + +#include <osmocom/trau/osmo_ortp.h> + #include <osmo-bts/logging.h> #include <osmo-bts/lchan.h> #include <osmo-bts/bts.h> #include <osmo-bts/rsl.h> +#include <osmo-bts/pcu_if.h> +#include <osmo-bts/handover.h> +#include <osmo-bts/l1sap.h> #include <errno.h> static const struct value_string lchan_s_names[] = { @@ -70,6 +76,75 @@ void gsm_lchan_name_update(struct gsm_lchan *lchan) lchan->name = name; } +static int dyn_ts_pdch_release(struct gsm_lchan *lchan) +{ + struct gsm_bts_trx_ts *ts = lchan->ts; + + if (ts->dyn.pchan_is != ts->dyn.pchan_want) { + LOGP(DRSL, LOGL_ERROR, "%s: PDCH release requested but already" + " in switchover\n", gsm_ts_and_pchan_name(ts)); + return -EINVAL; + } + + /* + * Indicate PDCH Disconnect in dyn_pdch.want, let pcu_tx_info_ind() + * pick it up and wait for PCU to disable the channel. + */ + ts->dyn.pchan_want = GSM_PCHAN_NONE; + + if (!pcu_connected()) { + /* PCU not connected yet. Just record the new type and done, + * the PCU will pick it up once connected. */ + ts->dyn.pchan_is = GSM_PCHAN_NONE; + return 1; + } + + return pcu_tx_info_ind(); +} + +void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind) +{ + int rc; + + 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, + "Closing RTP socket on Channel Release "); + osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); + lchan->abis_ip.rtp_socket = NULL; + msgb_queue_flush(&lchan->dl_tch_queue); + } + + /* FIXME: right now we allow creating the rtp_socket even if chan is not + * activated... Once we check for that, we can move this check at the + * start of the function */ + if (lchan->state == LCHAN_S_NONE) + return; + + /* release handover state */ + handover_reset(lchan); + + lchan->rel_act_kind = rel_kind; + + /* Dynamic channel in PDCH mode is released via PCU */ + if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN + && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) { + rc = dyn_ts_pdch_release(lchan); + if (rc == 1) { + /* If the PCU is not connected, continue to rel ack right away. */ + lchan->rel_act_kind = LCHAN_REL_ACT_PCU; + rsl_tx_rf_rel_ack(lchan); + return; + } + /* Waiting for PDCH release */ + return; + } + + l1sap_chan_rel(lchan->ts->trx, gsm_lchan2chan_nr(lchan)); + + lapdm_channel_exit(&lchan->lapdm_ch); +} + const char *gsm_lchans_name(enum gsm_lchan_state s) { return get_value_string(lchan_s_names, s); diff --git a/src/common/rsl.c b/src/common/rsl.c index 89c3b962..f03d5102 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1934,37 +1934,9 @@ static int rsl_rx_chan_activ(struct msgb *msg) return 0; } -static int dyn_ts_pdch_release(struct gsm_lchan *lchan) -{ - struct gsm_bts_trx_ts *ts = lchan->ts; - - if (ts->dyn.pchan_is != ts->dyn.pchan_want) { - LOGP(DRSL, LOGL_ERROR, "%s: PDCH release requested but already" - " in switchover\n", gsm_ts_and_pchan_name(ts)); - return -EINVAL; - } - - /* - * Indicate PDCH Disconnect in dyn_pdch.want, let pcu_tx_info_ind() - * pick it up and wait for PCU to disable the channel. - */ - ts->dyn.pchan_want = GSM_PCHAN_NONE; - - if (!pcu_connected()) { - /* PCU not connected yet. Just record the new type and done, - * the PCU will pick it up once connected. */ - ts->dyn.pchan_is = GSM_PCHAN_NONE; - return 1; - } - - return pcu_tx_info_ind(); -} - /* 8.4.14 RF CHANnel RELease is received */ 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;" @@ -1975,38 +1947,7 @@ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr) * 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, - "Closing RTP socket on Channel Release "); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); - } - - /* release handover state */ - handover_reset(lchan); - - lchan->rel_act_kind = LCHAN_REL_ACT_RSL; - - /* Dynamic channel in PDCH mode is released via PCU */ - if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN - && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) { - rc = dyn_ts_pdch_release(lchan); - if (rc == 1) { - /* If the PCU is not connected, continue to rel ack right away. */ - lchan->rel_act_kind = LCHAN_REL_ACT_PCU; - return rsl_tx_rf_rel_ack(lchan); - } - /* Waiting for PDCH release */ - return rc; - } - - l1sap_chan_rel(lchan->ts->trx, chan_nr); - - lapdm_channel_exit(&lchan->lapdm_ch); - + gsm_lchan_release(lchan, LCHAN_REL_ACT_RSL); return 0; } |