bsc_api/GSCON: prevent unnecessary channel mode modifications

gsm0808_assign_req() checks if the new channel mode is compatible
with the new mode. If it is, it does a gsm48_lchan_modify(), but
it does not actually check if the new mode is equal to the current
mode.

- skip when the channel is compatible and the new mode is equal to
  the old mode.

- send the ASSIGNMENT COMPLETE directly from ST_ACTIVE when no
  mode modify was necessary.

Change-Id: I86a2d52836c54d2dbd77441b182f757327ec7262
Related: OS#2936
This commit is contained in:
Philipp Maier 2018-05-03 19:03:03 +02:00 committed by Harald Welte
parent 1b11bc808f
commit ad7277073c
2 changed files with 19 additions and 9 deletions

View File

@ -296,16 +296,17 @@ static int chan_compat_with_mode(struct gsm_lchan *lchan, int chan_mode, int ful
}
}
/**
* Send a GSM08.08 Assignment Request. Right now this does not contain the
* audio codec type or the allowed rates for the config. It is assumed that
* this is for audio handling only. In case the current channel does not allow
* the selected mode a new one will be allocated.
*
* TODO: Add multirate configuration, make it work for more than audio.
*/
/*! Send a GSM08.08 Assignment Request. Right now this does not contain the
* audio codec type or the allowed rates for the config. In case the current
* channel does not allow the selected mode a new one will be allocated.
* \param[out] conn related subscriber connection
* \param[in] chan_mode mode of the channel (see enum gsm48_chan_mode)
* \param[in] full_rate select full rate or half rate channel
* \returns 0 on success, 1 when no operation is neccessary, -1 on failure */
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
{
/* TODO: Add multirate configuration, make it work for more than audio. */
struct bsc_api *api;
api = conn->network->bsc_api;
@ -313,6 +314,11 @@ int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, in
if (handle_new_assignment(conn, chan_mode, full_rate) != 0)
goto error;
} else {
/* Check if the channel is already in the requested mode, if
* yes, we skip unnecessary channel mode modify operations. */
if (conn->lchan->tch_mode == chan_mode)
return 1;
if (chan_mode == GSM48_CMODE_SPEECH_AMR)
handle_mr_config(conn, conn->lchan, full_rate);

View File

@ -438,7 +438,11 @@ static void gscon_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *dat
* change back to ST_ACTIVE (here) immediately. */
rc = gsm0808_assign_req(conn, conn->user_plane.chan_mode,
conn->user_plane.full_rate);
if (rc != 0) {
if (rc == 1) {
send_ass_compl(conn->lchan, fi, false);
return;
} else if (rc != 0) {
resp = gsm0808_create_assignment_failure(GSM0808_CAUSE_EQUIPMENT_FAILURE, NULL);
sigtran_send(conn, resp, fi);
return;