mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-10-23 08:12:01 +00:00
Specify a release reason for the lchan
In case the put_lchan is making the refcount drop to zero use the release reason specified in the put_lchan call. This is used by the BSC MSC IP implementation for the assignment handling where the old channel is getting closed with a local end release (1).
This commit is contained in:
@@ -68,7 +68,7 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
|
||||
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
|
||||
u_int64_t str_to_imsi(const char *imsi_str);
|
||||
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t release_reason);
|
||||
|
||||
/* to be provided by external code */
|
||||
int abis_rsl_sendmsg(struct msgb *msg);
|
||||
|
@@ -34,13 +34,13 @@
|
||||
lchan->nr, lchan->use_count); \
|
||||
} while(0);
|
||||
|
||||
#define put_lchan(lchan) \
|
||||
#define put_lchan(lchan, reason) \
|
||||
do { lchan->use_count--; \
|
||||
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
if (lchan->use_count <= 0) \
|
||||
_lchan_release(lchan); \
|
||||
_lchan_release(lchan, reason); \
|
||||
} while(0);
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
|
||||
void lchan_free(struct gsm_lchan *lchan);
|
||||
|
||||
/* internal.. do not use */
|
||||
int _lchan_release(struct gsm_lchan *lchan);
|
||||
int _lchan_release(struct gsm_lchan *lchan, u_int8_t release_reason);
|
||||
|
||||
struct load_counter {
|
||||
unsigned int total;
|
||||
|
@@ -718,14 +718,15 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_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, u_int8_t link_id)
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason)
|
||||
{
|
||||
|
||||
struct msgb *msg;
|
||||
|
||||
msg = rsl_rll_simple(RSL_MT_REL_REQ, lchan2chan_nr(lchan),
|
||||
link_id, 0);
|
||||
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
|
||||
/* 0 is normal release, 1 is local end */
|
||||
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
|
||||
|
||||
lchan->state = LCHAN_S_REL_REQ;
|
||||
/* FIXME: start some timer in case we don't receive a REL ACK ? */
|
||||
|
@@ -160,7 +160,7 @@ void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
|
||||
DEBUGP(DMSC, "ERROR: The lchan is still associated\n.");
|
||||
|
||||
lchan->msc_data = NULL;
|
||||
put_lchan(lchan);
|
||||
put_lchan(lchan, 0);
|
||||
}
|
||||
|
||||
bss_sccp_free_data((struct bss_sccp_connection_data *)conn->data_ctx);
|
||||
@@ -306,20 +306,20 @@ static int handle_ass_compl(struct msgb *msg)
|
||||
|
||||
if (!msg->lchan->msc_data) {
|
||||
DEBUGP(DMSC, "No MSC data\n");
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
|
||||
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||
DEBUGP(DMSC, "assignment failure invalid: %d\n",
|
||||
msgb_l3len(msg) - sizeof(*gh));
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ static int handle_ass_compl(struct msgb *msg)
|
||||
/* give up the old channel to not do a SACCH deactivate */
|
||||
subscr_put(old_chan->subscr);
|
||||
old_chan->subscr = NULL;
|
||||
put_lchan(old_chan);
|
||||
put_lchan(old_chan, 1);
|
||||
|
||||
/* activate audio on it... */
|
||||
if (is_ipaccess_bts(msg->lchan->ts->trx->bts) && msg->lchan->tch_mode != GSM48_CMODE_SIGN)
|
||||
@@ -353,20 +353,20 @@ static int handle_ass_fail(struct msgb *msg)
|
||||
DEBUGP(DMSC, "ASSIGNMENT FAILURE from MS, forwarding to MSC\n");
|
||||
if (!msg->lchan->msc_data) {
|
||||
DEBUGP(DMSC, "No MSC data\n");
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
|
||||
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||
DEBUGP(DMSC, "assignment failure invalid: %d\n",
|
||||
msgb_l3len(msg) - sizeof(*gh));
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@@ -52,7 +52,7 @@ static LLIST_HEAD(bsc_rll_reqs);
|
||||
static void complete_rllr(struct bsc_rll_req *rllr, enum bsc_rllr_ind type)
|
||||
{
|
||||
llist_del(&rllr->list);
|
||||
put_lchan(rllr->lchan);
|
||||
put_lchan(rllr->lchan, 0);
|
||||
rllr->cb(rllr->lchan, rllr->link_id, rllr->data, type);
|
||||
talloc_free(rllr);
|
||||
}
|
||||
|
@@ -191,10 +191,10 @@ static int bssmap_handle_clear_command(struct sccp_connection *conn,
|
||||
|
||||
/* we might got killed during an assignment */
|
||||
if (msg->lchan->msc_data->secondary_lchan)
|
||||
put_lchan(msg->lchan->msc_data->secondary_lchan);
|
||||
put_lchan(msg->lchan->msc_data->secondary_lchan, 0);
|
||||
|
||||
msg->lchan->msc_data = NULL;
|
||||
put_lchan(msg->lchan);
|
||||
put_lchan(msg->lchan, 0);
|
||||
}
|
||||
|
||||
/* send the clear complete message */
|
||||
@@ -439,13 +439,13 @@ static void continue_new_assignment(struct gsm_lchan *new_lchan)
|
||||
{
|
||||
if (!new_lchan->msc_data) {
|
||||
LOGP(DMSC, LOGL_ERROR, "No BSS data found.\n");
|
||||
put_lchan(new_lchan);
|
||||
put_lchan(new_lchan, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_lchan->msc_data->secondary_lchan != new_lchan) {
|
||||
LOGP(DMSC, LOGL_ERROR, "This is not the secondary channel?\n");
|
||||
put_lchan(new_lchan);
|
||||
put_lchan(new_lchan, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -300,7 +300,7 @@ void lchan_free(struct gsm_lchan *lchan)
|
||||
}
|
||||
|
||||
/* Consider releasing the channel now */
|
||||
int _lchan_release(struct gsm_lchan *lchan)
|
||||
int _lchan_release(struct gsm_lchan *lchan, u_int8_t release_reason)
|
||||
{
|
||||
if (lchan->use_count > 0) {
|
||||
DEBUGP(DRLL, "BUG: _lchan_release called without zero use_count.\n");
|
||||
@@ -320,7 +320,7 @@ int _lchan_release(struct gsm_lchan *lchan)
|
||||
lchan->use_count);
|
||||
|
||||
DEBUGP(DRLL, "%s Recycling Channel\n", gsm_lchan_name(lchan));
|
||||
rsl_release_request(lchan, 0);
|
||||
rsl_release_request(lchan, 0, release_reason);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@@ -104,7 +104,7 @@ static void release_loc_updating_req(struct gsm_lchan *lchan)
|
||||
bsc_del_timer(&lchan->loc_operation->updating_timer);
|
||||
talloc_free(lchan->loc_operation);
|
||||
lchan->loc_operation = 0;
|
||||
put_lchan(lchan);
|
||||
put_lchan(lchan, 0);
|
||||
}
|
||||
|
||||
static void allocate_loc_updating_req(struct gsm_lchan *lchan)
|
||||
|
@@ -762,7 +762,7 @@ static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans,
|
||||
|
||||
/* release channel if done */
|
||||
if (!sms)
|
||||
rsl_release_request(msg->lchan, trans->sms.link_id);
|
||||
rsl_release_request(msg->lchan, trans->sms.link_id, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -837,7 +837,7 @@ static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans,
|
||||
if (sms)
|
||||
gsm411_send_sms_lchan(msg->lchan, sms);
|
||||
else
|
||||
rsl_release_request(msg->lchan, trans->sms.link_id);
|
||||
rsl_release_request(msg->lchan, trans->sms.link_id, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -207,7 +207,7 @@ void subscr_put_channel(struct gsm_lchan *lchan)
|
||||
* will listen to the paging requests before we timeout
|
||||
*/
|
||||
|
||||
put_lchan(lchan);
|
||||
put_lchan(lchan, 0);
|
||||
|
||||
if (lchan->subscr && !llist_empty(&lchan->subscr->requests))
|
||||
subscr_send_paging_request(lchan->subscr);
|
||||
|
@@ -255,7 +255,7 @@ static int ho_gsm48_ho_fail(struct gsm_lchan *old_lchan)
|
||||
|
||||
bsc_del_timer(&ho->T3103);
|
||||
llist_del(&ho->list);
|
||||
put_lchan(ho->new_lchan);
|
||||
put_lchan(ho->new_lchan, 0);
|
||||
talloc_free(ho);
|
||||
|
||||
return 0;
|
||||
|
@@ -135,7 +135,7 @@ int gsm_silent_call_stop(struct gsm_subscriber *subscr)
|
||||
if (!lchan->silent_call)
|
||||
return -EINVAL;
|
||||
|
||||
put_lchan(lchan);
|
||||
put_lchan(lchan, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -102,7 +102,7 @@ void trans_free(struct gsm_trans *trans)
|
||||
}
|
||||
|
||||
if (trans->lchan)
|
||||
put_lchan(trans->lchan);
|
||||
put_lchan(trans->lchan, 0);
|
||||
|
||||
if (trans->subscr)
|
||||
subscr_put(trans->subscr);
|
||||
@@ -159,7 +159,7 @@ int trans_lchan_change(struct gsm_lchan *lchan_old,
|
||||
llist_for_each_entry(trans, &net->trans_list, entry) {
|
||||
if (trans->lchan == lchan_old) {
|
||||
/* drop old channel use cound */
|
||||
put_lchan(trans->lchan);
|
||||
put_lchan(trans->lchan, 0);
|
||||
/* assign new channel */
|
||||
trans->lchan = lchan_new;
|
||||
/* bump new channel use count */
|
||||
|
Reference in New Issue
Block a user