lchan: Release the lchan more quickly, align with GSM 04.08
* Release all channels with SAPI > 0 with the "local end release" (as of NOTE 1 of GSM 04.08). * No need to wait for all SAPIs to be torn down and the normal REL_IND/REL_CONF will call rsl_handle_release and the channel should be released. * Update the documentation
This commit is contained in:
parent
960c4044e6
commit
8582535c82
|
@ -56,21 +56,20 @@ bsc_api.c:gsm0808_clear
|
|||
* Release the primary lchan with normal release, SACH deactivate
|
||||
|
||||
chan_alloc.c:lchan_release(chan, sacch_deactivate, reason)
|
||||
* Start release procedure. It is working in steps with callbacks
|
||||
coming from the abis_rsl.c code.
|
||||
* Release all SAPI's > 0, wait for them to be released
|
||||
* Send SACH Deactivate on SAPI=0
|
||||
* Finally Release the channel
|
||||
* Start the release procedure. It is working in steps with callbacks
|
||||
coming from the abis_rsl.c code.
|
||||
* Release all SAPI's > 0 as local end (The BTS should send a
|
||||
REL_CONF a message)
|
||||
* Send SACH Deactivate on SAPI=0 if required.
|
||||
* It should start T3109 but it does not.
|
||||
* abis_rsl.c schedules the RSL_MT_RF_CHAN_REL once all SAPI's are
|
||||
released and after T3111 has timed out or there is an error.
|
||||
|
||||
RX of RELease INDication:
|
||||
* Calls internal rsl_handle_release which might release the RF.
|
||||
* Informs chan_alloc.c about the release with
|
||||
rsl_lchan_rll_release.
|
||||
|
||||
RX of RELease CONFimem:
|
||||
RX of RELease CONFirmation:
|
||||
* Calls internal rsl_handle_release which might release the RF.
|
||||
* Informs chan_alloc.c about the release with
|
||||
rsl_lchan_rll_release.
|
||||
|
||||
* RX of RF_CHAN_REL_ACK
|
||||
* call lchan_free()
|
||||
|
|
|
@ -74,7 +74,6 @@ int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
|
|||
|
||||
/* to be provided by external code */
|
||||
int rsl_deact_sacch(struct gsm_lchan *lchan);
|
||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, uint8_t link_id);
|
||||
|
||||
/* BCCH related code */
|
||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
|
||||
|
@ -97,5 +96,9 @@ int rsl_nokia_si_end(struct gsm_bts_trx *trx);
|
|||
/* required for Nokia BTS power control */
|
||||
int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction);
|
||||
|
||||
|
||||
int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
|
||||
enum rsl_rel_mode release_mode);
|
||||
|
||||
#endif /* RSL_MT_H */
|
||||
|
||||
|
|
|
@ -196,9 +196,6 @@ struct gsm_lchan {
|
|||
uint8_t sapis[8];
|
||||
int sacch_deact;
|
||||
|
||||
/* Release handling */
|
||||
enum rsl_rel_mode release_mode;
|
||||
|
||||
struct {
|
||||
uint32_t bound_ip;
|
||||
uint32_t connect_ip;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
|
||||
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2012 by Holger Hans Peter Freyther
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
|
@ -1581,7 +1582,6 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
rll_indication(msg->lchan, rllh->link_id,
|
||||
BSC_RLLR_IND_REL_IND);
|
||||
rsl_handle_release(msg->lchan);
|
||||
rsl_lchan_rll_release(msg->lchan, rllh->link_id);
|
||||
break;
|
||||
case RSL_MT_REL_CONF:
|
||||
/* BTS informs us of having received UA from MS,
|
||||
|
@ -1589,7 +1589,6 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
|
||||
msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
|
||||
rsl_handle_release(msg->lchan);
|
||||
rsl_lchan_rll_release(msg->lchan, rllh->link_id);
|
||||
break;
|
||||
case RSL_MT_ERROR_IND:
|
||||
rc = rsl_rx_rll_err_ind(msg);
|
||||
|
@ -2058,3 +2057,30 @@ int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduc
|
|||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all allocated SAPIs starting from @param start and
|
||||
* release them with the given release mode. Once the release
|
||||
* confirmation arrives it will be attempted to release the
|
||||
* the RF channel.
|
||||
*/
|
||||
int rsl_release_sapis_from(struct gsm_lchan *lchan, int start,
|
||||
enum rsl_rel_mode release_mode)
|
||||
{
|
||||
int no_sapi = 1;
|
||||
int sapi;
|
||||
|
||||
for (sapi = start; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
|
||||
uint8_t link_id;
|
||||
if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
|
||||
continue;
|
||||
|
||||
link_id = sapi;
|
||||
if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
|
||||
link_id |= 0x40;
|
||||
rsl_release_request(lchan, link_id, release_mode);
|
||||
no_sapi = 0;
|
||||
}
|
||||
|
||||
return no_sapi;
|
||||
}
|
||||
|
|
|
@ -345,8 +345,6 @@ void lchan_free(struct gsm_lchan *lchan)
|
|||
}
|
||||
|
||||
lchan->sacch_deact = 0;
|
||||
lchan->release_mode = RSL_REL_NORMAL;
|
||||
|
||||
/* FIXME: ts_free() the timeslot, if we're the last logical
|
||||
* channel using it */
|
||||
}
|
||||
|
@ -376,51 +374,22 @@ void lchan_reset(struct gsm_lchan *lchan)
|
|||
}
|
||||
}
|
||||
|
||||
/* release the next allocated SAPI or return 0 */
|
||||
static int _lchan_release_next_sapi(struct gsm_lchan *lchan)
|
||||
{
|
||||
int sapi;
|
||||
|
||||
for (sapi = 1; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
|
||||
uint8_t link_id;
|
||||
if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
|
||||
continue;
|
||||
|
||||
link_id = sapi;
|
||||
if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)
|
||||
link_id |= 0x40;
|
||||
rsl_release_request(lchan, link_id, RSL_REL_LOCAL_END);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Drive the release process of the lchan */
|
||||
static void _lchan_handle_release(struct gsm_lchan *lchan)
|
||||
static void _lchan_handle_release(struct gsm_lchan *lchan,
|
||||
int sach_deact, int mode)
|
||||
{
|
||||
/* Ask for SAPI != 0 to be freed first and stop if we need to wait */
|
||||
if (_lchan_release_next_sapi(lchan) == 0)
|
||||
return;
|
||||
/* Release all SAPIs on the local end and continue */
|
||||
rsl_release_sapis_from(lchan, 1, RSL_REL_LOCAL_END);
|
||||
|
||||
if (lchan->sacch_deact) {
|
||||
/*
|
||||
* Shall we send a RR Release, start T3109 and wait for the
|
||||
* release indication from the BTS or just take it down (e.g.
|
||||
* on assignment requests)
|
||||
*/
|
||||
if (sach_deact)
|
||||
gsm48_send_rr_release(lchan);
|
||||
return;
|
||||
}
|
||||
|
||||
rsl_release_request(lchan, 0, lchan->release_mode);
|
||||
rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ);
|
||||
}
|
||||
|
||||
/* called from abis rsl */
|
||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, uint8_t link_id)
|
||||
{
|
||||
if (lchan->state != LCHAN_S_REL_REQ)
|
||||
return -1;
|
||||
|
||||
if ((link_id & 0x7) != 0)
|
||||
_lchan_handle_release(lchan);
|
||||
return 0;
|
||||
else
|
||||
rsl_release_request(lchan, 0, mode);
|
||||
}
|
||||
|
||||
/* Consider releasing the channel now */
|
||||
|
@ -430,9 +399,7 @@ int lchan_release(struct gsm_lchan *lchan, int sacch_deact, enum rsl_rel_mode mo
|
|||
rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ);
|
||||
|
||||
lchan->conn = NULL;
|
||||
lchan->release_mode = mode;
|
||||
lchan->sacch_deact = sacch_deact;
|
||||
_lchan_handle_release(lchan);
|
||||
_lchan_handle_release(lchan, sacch_deact, mode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue