Merge branch 'zecke/channel-release'

Merge the channel release re-work. The most notable change is that
SAPI > 0 will now be released on the local end and that the release
process should be both more fast and more standard conform. With SMS
spamming/mass sending the nanoBTS is crashing but this does not appear
to originate from any of these changes. I used git rebase to go through
each of the change to see where the nanoBTS is crashing but couldn't
reproduce it. It might be a general overload or something generated by
the modems of the sysmocom modem bank. Merge it before the 29C3 so we
can test this code some more.
This commit is contained in:
Holger Hans Peter Freyther 2012-12-23 20:21:15 +01:00
commit 7d0f60dce6
16 changed files with 180 additions and 117 deletions

View File

@ -56,21 +56,21 @@ 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.
* Start T3109 (stop it when the main signalling link is disconnected)
or when the channel released. On timeout start the error handling.
* 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()

View File

@ -30,7 +30,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0

View File

@ -31,7 +31,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0

View File

@ -30,7 +30,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0

View File

@ -30,7 +30,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0

View File

@ -29,7 +29,7 @@ network
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0

View File

@ -67,13 +67,13 @@ int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act);
int abis_rsl_rcvmsg(struct msgb *msg);
uint64_t str_to_imsi(const char *imsi_str);
int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason);
int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
enum rsl_rel_mode release_mode);
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);
@ -96,5 +96,10 @@ 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);
int rsl_start_t3109(struct gsm_lchan *lchan);
#endif /* RSL_MT_H */

View File

@ -46,7 +46,7 @@ void lchan_free(struct gsm_lchan *lchan);
void lchan_reset(struct gsm_lchan *lchan);
/* Release the given lchan */
int lchan_release(struct gsm_lchan *lchan, int sacch_deact, int release_mode);
int lchan_release(struct gsm_lchan *lchan, int sacch_deact, enum rsl_rel_mode release_mode);
struct load_counter {
unsigned int total;

View File

@ -120,6 +120,7 @@ enum gsm_lchan_state {
LCHAN_S_ACTIVE, /* channel is active and operational */
LCHAN_S_REL_REQ, /* channel release has been requested */
LCHAN_S_REL_ERR, /* channel is in an error state */
LCHAN_S_BROKEN, /* channel is somehow unusable */
LCHAN_S_INACTIVE, /* channel is set inactive */
};
@ -196,9 +197,6 @@ struct gsm_lchan {
uint8_t sapis[8];
int sacch_deact;
/** GSM 08.58 9.3.20 */
int release_mode;
struct {
uint32_t bound_ip;
uint32_t connect_ip;
@ -219,9 +217,11 @@ struct gsm_lchan {
#ifdef ROLE_BSC
struct osmo_timer_list T3101;
struct osmo_timer_list T3109;
struct osmo_timer_list T3111;
struct osmo_timer_list error_timer;
struct osmo_timer_list act_timer;
uint8_t error_cause;
/* table of neighbor cell measurements */
struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS];

View File

@ -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
*
@ -45,6 +46,11 @@
#define RSL_ALLOC_SIZE 1024
#define RSL_ALLOC_HEADROOM 128
enum sacch_deact {
SACCH_NONE,
SACCH_DEACTIVATE,
};
static int rsl_send_imm_assignment(struct gsm_lchan *lchan);
static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
@ -56,6 +62,14 @@ static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
osmo_signal_dispatch(SS_LCHAN, sig_no, &sig);
}
static void do_lchan_free(struct gsm_lchan *lchan)
{
/* we have an error timer pending to release that */
if (lchan->state != LCHAN_S_REL_ERR)
rsl_lchan_set_state(lchan, LCHAN_S_NONE);
lchan_free(lchan);
}
static uint8_t mdisc_by_msgtype(uint8_t msg_type)
{
/* mask off the transparent bit ? */
@ -182,7 +196,7 @@ static void lchan_act_tmr_cb(void *data)
{
struct gsm_lchan *lchan = data;
LOGP(DRSL, LOGL_NOTICE, "%s Timeout during activation!\n",
LOGP(DRSL, LOGL_ERROR, "%s Timeout during activation!\n",
gsm_lchan_name(lchan));
rsl_lchan_set_state(lchan, LCHAN_S_NONE);
@ -193,12 +207,10 @@ static void lchan_deact_tmr_cb(void *data)
{
struct gsm_lchan *lchan = data;
LOGP(DRSL, LOGL_NOTICE, "%s Timeout during deactivation!\n",
LOGP(DRSL, LOGL_ERROR, "%s Timeout during deactivation!\n",
gsm_lchan_name(lchan));
if (lchan->state != LCHAN_S_REL_ERR)
rsl_lchan_set_state(lchan, LCHAN_S_NONE);
lchan_free(lchan);
do_lchan_free(lchan);
}
@ -637,12 +649,16 @@ static void error_timeout_cb(void *data)
static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan);
/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error,
enum sacch_deact deact_sacch)
{
struct abis_rsl_dchan_hdr *dh;
struct msgb *msg;
int rc;
/* Stop timers that should lead to a channel release */
osmo_timer_del(&lchan->T3109);
if (lchan->state == LCHAN_S_REL_ERR) {
LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
gsm_lchan_name(lchan));
@ -660,13 +676,34 @@ static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
if (error) {
/*
* the nanoBTS sends RLL release indications after the channel release. This can
* be a problem when we have reassigned the channel to someone else and then can
* not figure out who used this channel.
*/
struct e1inp_sign_link *sign_link = msg->dst;
/*
* FIXME: GSM 04.08 gives us two options for the abnormal
* chanel release. This can be either like in the non-existent
* sub-lcuase 3.5.1 or for the main signalling link deactivate
* the SACCH, start timer T3109 and consider the channel as
* released.
*
* This code is doing the later for all raido links and not
* only the main link. Right now all SAPIs are released on the
* local end, the SACCH will be de-activated and right now the
* T3111 will be started. First T3109 should be started and then
* the T3111.
*
* TODO: Move this out of the function.
*/
/*
* sacch de-activate and "local end release"
*/
if (deact_sacch == SACCH_DEACTIVATE)
rsl_deact_sacch(lchan);
rsl_release_sapis_from(lchan, 0, RSL_REL_LOCAL_END);
/*
* TODO: start T3109 now.
*/
rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
lchan->error_timer.data = lchan;
lchan->error_timer.cb = error_timeout_cb;
@ -696,17 +733,15 @@ static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
/* Stop all pending timers */
osmo_timer_del(&lchan->act_timer);
osmo_timer_del(&lchan->T3111);
if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
gsm_lchan_name(lchan),
gsm_lchans_name(lchan->state));
osmo_timer_del(&lchan->T3111);
/* we have an error timer pending to release that */
if (lchan->state != LCHAN_S_REL_ERR)
rsl_lchan_set_state(lchan, LCHAN_S_NONE);
lchan_free(lchan);
do_lchan_free(lchan);
return 0;
}
@ -833,7 +868,8 @@ int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
lchan_free() */
int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason)
int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id,
enum rsl_rel_mode release_mode)
{
struct msgb *msg;
@ -841,14 +877,14 @@ int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason
msg = rsl_rll_simple(RSL_MT_REL_REQ, gsm_lchan2chan_nr(lchan),
link_id, 0);
/* 0 is normal release, 1 is local end */
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, release_mode);
/* FIXME: start some timer in case we don't receive a REL ACK ? */
msg->dst = lchan->ts->trx->rsl_link;
DEBUGP(DRLL, "%s RSL RLL RELEASE REQ (link_id=0x%02x, reason=%u)\n",
gsm_lchan_name(lchan), link_id, reason);
gsm_lchan_name(lchan), link_id, release_mode);
return abis_rsl_sendmsg(msg);
}
@ -909,19 +945,18 @@ static int rsl_rx_chan_act_nack(struct msgb *msg)
const uint8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
print_rsl_cause(LOGL_ERROR, cause,
TLVP_LEN(&tp, RSL_IE_CAUSE));
msg->lchan->error_cause = *cause;
if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
else
rsl_rf_chan_release(msg->lchan, 1);
rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
} else
rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
LOGPC(DRSL, LOGL_ERROR, "\n");
send_lchan_signal(S_LCHAN_ACTIVATE_NACK, msg->lchan, NULL);
lchan_free(msg->lchan);
return 0;
}
@ -944,7 +979,7 @@ static int rsl_rx_conn_fail(struct msgb *msg)
LOGPC(DRSL, LOGL_NOTICE, "\n");
/* FIXME: only free it after channel release ACK */
osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
return rsl_rf_chan_release(msg->lchan, 1);
return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
}
static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
@ -1225,7 +1260,7 @@ static void t3101_expired(void *data)
{
struct gsm_lchan *lchan = data;
rsl_rf_chan_release(lchan, 1);
rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
}
/* If T3111 expires, we will send the RF Channel Request */
@ -1233,7 +1268,17 @@ static void t3111_expired(void *data)
{
struct gsm_lchan *lchan = data;
rsl_rf_chan_release(lchan, 0);
rsl_rf_chan_release(lchan, 0, SACCH_NONE);
}
/* If T3109 expires the MS has not send a UA/UM do the error release */
static void t3109_expired(void *data)
{
struct gsm_lchan *lchan = data;
LOGP(DRSL, LOGL_ERROR,
"%s SACCH deactivation timeout.\n", gsm_lchan_name(lchan));
rsl_rf_chan_release(lchan, 1, SACCH_NONE);
}
#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
@ -1491,7 +1536,7 @@ static int rsl_rx_rll_err_ind(struct msgb *msg)
if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
osmo_counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
return rsl_rf_chan_release(msg->lchan, 1);
return rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
}
return 0;
@ -1502,7 +1547,11 @@ static void rsl_handle_release(struct gsm_lchan *lchan)
int sapi;
struct gsm_bts *bts;
/* maybe we have only brought down one RLL */
/*
* Maybe only one link/SAPI was releasd or the error handling
* was activated. Just return now and let the other code handle
* it.
*/
if (lchan->state != LCHAN_S_REL_REQ)
return;
@ -1515,8 +1564,8 @@ static void rsl_handle_release(struct gsm_lchan *lchan)
}
/* wait a bit to send the RF Channel Release */
/* Stop T3109 and wait for T3111 before re-using the channel */
osmo_timer_del(&lchan->T3109);
lchan->T3111.cb = t3111_expired;
lchan->T3111.data = lchan;
bts = lchan->ts->trx->bts;
@ -1576,7 +1625,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,
@ -1584,7 +1632,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);
@ -2053,3 +2100,44 @@ 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;
}
int rsl_start_t3109(struct gsm_lchan *lchan)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
/* Disabled, mostly legacy code */
if (bts->network->T3109 == 0)
return -1;
lchan->T3109.cb = t3109_expired;
lchan->T3109.data = lchan;
osmo_timer_schedule(&lchan->T3109, bts->network->T3109, 0);
return 0;
}

View File

@ -141,7 +141,7 @@ static void assignment_t10_timeout(void *_conn)
* secondary_channel has not been released by the handle_chan_nack.
*/
if (conn->secondary_lchan)
lchan_release(conn->secondary_lchan, 0, 1);
lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
conn->secondary_lchan = NULL;
/* inform them about the failure */
@ -416,7 +416,7 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
/* swap channels */
osmo_timer_del(&conn->T10);
lchan_release(conn->lchan, 0, 1);
lchan_release(conn->lchan, 0, RSL_REL_LOCAL_END);
conn->lchan = conn->secondary_lchan;
conn->secondary_lchan = NULL;
@ -444,7 +444,7 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn,
/* stop the timer and release it */
osmo_timer_del(&conn->T10);
lchan_release(conn->secondary_lchan, 0, 1);
lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
conn->secondary_lchan = NULL;
gh = msgb_l3(msg);
@ -649,7 +649,7 @@ int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
rc = BSC_API_CONN_POL_REJECT;
lchan->conn = subscr_con_allocate(msg->lchan);
if (!lchan->conn) {
lchan_release(lchan, 1, 0);
lchan_release(lchan, 1, RSL_REL_NORMAL);
return -1;
}
@ -659,7 +659,7 @@ int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
if (rc != BSC_API_CONN_POL_ACCEPT) {
lchan->conn->lchan = NULL;
subscr_con_free(lchan->conn);
lchan_release(lchan, 1, 0);
lchan_release(lchan, 1, RSL_REL_NORMAL);
}
}
@ -698,10 +698,10 @@ int gsm0808_clear(struct gsm_subscriber_connection *conn)
bsc_clear_handover(conn, 1);
if (conn->secondary_lchan)
lchan_release(conn->secondary_lchan, 0, 1);
lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
if (conn->lchan)
lchan_release(conn->lchan, 1, 0);
lchan_release(conn->lchan, 1, RSL_REL_NORMAL);
conn->lchan = NULL;
conn->secondary_lchan = NULL;

View File

@ -1379,7 +1379,7 @@ DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT.\n")
DECLARE_TIMER(3103, "Set the timeout value for HANDOVER.\n")
DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION.\n")
DECLARE_TIMER(3107, "Currently not used.\n")
DECLARE_TIMER(3109, "Currently not used.\n")
DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout.\n")
DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel.\n")
DECLARE_TIMER(3113, "Set the time to try paging a subscriber.\n")
DECLARE_TIMER(3115, "Currently not used.\n")

View File

@ -345,8 +345,6 @@ void lchan_free(struct gsm_lchan *lchan)
}
lchan->sacch_deact = 0;
lchan->release_mode = 0;
/* FIXME: ts_free() the timeslot, if we're the last logical
* channel using it */
}
@ -364,6 +362,7 @@ void lchan_free(struct gsm_lchan *lchan)
void lchan_reset(struct gsm_lchan *lchan)
{
osmo_timer_del(&lchan->T3101);
osmo_timer_del(&lchan->T3109);
osmo_timer_del(&lchan->T3111);
osmo_timer_del(&lchan->error_timer);
@ -376,63 +375,37 @@ 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, lchan->release_mode);
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 sacch_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 (sacch_deact) {
gsm48_send_rr_release(lchan);
return;
/* Deactivate the SACCH on the BTS side */
rsl_deact_sacch(lchan);
rsl_start_t3109(lchan);
} else {
rsl_release_request(lchan, 0, mode);
}
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;
}
/* Consider releasing the channel now */
int lchan_release(struct gsm_lchan *lchan, int sacch_deact, int mode)
int lchan_release(struct gsm_lchan *lchan, int sacch_deact, enum rsl_rel_mode mode)
{
DEBUGP(DRLL, "%s starting release sequence\n", gsm_lchan_name(lchan));
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;
}

View File

@ -231,11 +231,7 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan)
lchan->nr, lchan->type);
/* Send actual release request to MS */
gsm48_sendmsg(msg);
/* FIXME: Start Timer T3109 */
/* Deactivate the SACCH on the BTS side */
return rsl_deact_sacch(lchan);
return gsm48_sendmsg(msg);
}
int send_siemens_mrpci(struct gsm_lchan *lchan,

View File

@ -167,7 +167,7 @@ void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan)
conn->ho_lchan = NULL;
if (free_lchan)
lchan_release(ho->new_lchan, 0, 1);
lchan_release(ho->new_lchan, 0, RSL_REL_LOCAL_END);
osmo_timer_del(&ho->T3103);
llist_del(&ho->list);
@ -185,7 +185,7 @@ static void ho_T3103_cb(void *_ho)
ho->new_lchan->conn->ho_lchan = NULL;
ho->new_lchan->conn = NULL;
lchan_release(ho->new_lchan, 0, 1);
lchan_release(ho->new_lchan, 0, RSL_REL_LOCAL_END);
llist_del(&ho->list);
talloc_free(ho);
}
@ -276,7 +276,7 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
ho->old_lchan->conn = NULL;
rsl_lchan_set_state(ho->old_lchan, LCHAN_S_INACTIVE);
lchan_release(ho->old_lchan, 0, 1);
lchan_release(ho->old_lchan, 0, RSL_REL_LOCAL_END);
/* do something to re-route the actual speech frames ! */
@ -306,7 +306,7 @@ static int ho_gsm48_ho_fail(struct gsm_lchan *old_lchan)
/* release the channel and forget about it */
ho->new_lchan->conn->ho_lchan = NULL;
ho->new_lchan->conn = NULL;
lchan_release(ho->new_lchan, 0, 1);
lchan_release(ho->new_lchan, 0, RSL_REL_LOCAL_END);
talloc_free(ho);

View File

@ -109,6 +109,7 @@ static const struct value_string lchan_s_names[] = {
{ LCHAN_S_INACTIVE, "INACTIVE" },
{ LCHAN_S_REL_REQ, "RELEASE REQUESTED" },
{ LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },
{ LCHAN_S_BROKEN, "BROKEN UNUSABLE" },
{ 0, NULL }
};