From 0848ff84b7655097a5aedae1b58cdcd2571c8af5 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Thu, 14 Mar 2019 22:11:45 +0000 Subject: Revert "assignment_fsm: Properly support assigning signalling mode TCH/x" This commit breaks voice channel assignment. It results in the Assignment Complete sent to the MSC for a voice lchan lacking AoIP Transport Layer Address, Speech Version and Speech Codec. Hence the MSC cannot complete the Assignment for a voice call. Let's revisit this patch, test thoroughly and re-merge later. This reverts commit 4d3a21269b25e7164a94fa8ce3ad67ff80904aee. Reason for revert: Change-Id: I72aaa03539919e7e85b5b75b133326cec5e68bc9 --- include/osmocom/bsc/gsm_data.h | 17 +++-- include/osmocom/bsc/lchan_select.h | 2 +- src/osmo-bsc/assignment_fsm.c | 124 ++++++++++++++++++++----------------- src/osmo-bsc/codec_pref.c | 10 ++- src/osmo-bsc/handover_fsm.c | 5 +- src/osmo-bsc/lchan_select.c | 17 ++--- src/osmo-bsc/osmo_bsc_bssap.c | 124 ++++++++++++++----------------------- tests/codec_pref/codec_pref_test.c | 2 +- 8 files changed, 133 insertions(+), 168 deletions(-) diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index aff73de36..47ca5e839 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -98,15 +98,9 @@ enum subscr_sccp_state { SUBSCR_SCCP_ST_CONNECTED }; -enum channel_rate { - CH_RATE_SDCCH, - CH_RATE_HALF, - CH_RATE_FULL, -}; - struct channel_mode_and_rate { enum gsm48_chan_mode chan_mode; - enum channel_rate chan_rate; + bool full_rate; uint16_t s15_s0; }; @@ -121,9 +115,12 @@ struct assignment_request { char msc_rtp_addr[INET_ADDRSTRLEN]; uint16_t msc_rtp_port; - /* Rate/codec setting in preference order (need at least 1 !) */ - int n_ch_mode_rate; - struct channel_mode_and_rate ch_mode_rate[3]; + /* Prefered rate/codec setting (mandatory) */ + struct channel_mode_and_rate ch_mode_rate_pref; + + /* Alternate rate/codec setting (optional) */ + bool ch_mode_rate_alt_present; + struct channel_mode_and_rate ch_mode_rate_alt; }; /* State of an ongoing Assignment, while the assignment_fsm is still busy. This serves as state separation to keep the diff --git a/include/osmocom/bsc/lchan_select.h b/include/osmocom/bsc/lchan_select.h index 865181bf5..4aecdf676 100644 --- a/include/osmocom/bsc/lchan_select.h +++ b/include/osmocom/bsc/lchan_select.h @@ -3,4 +3,4 @@ struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts, enum gsm_chan_t type); struct gsm_lchan *lchan_select_by_chan_mode(struct gsm_bts *bts, - enum gsm48_chan_mode chan_mode, enum channel_rate chan_rate); + enum gsm48_chan_mode chan_mode, bool full_rate); diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c index 218079159..aa696ac0a 100644 --- a/src/osmo-bsc/assignment_fsm.c +++ b/src/osmo-bsc/assignment_fsm.c @@ -251,15 +251,17 @@ static void assignment_fsm_update_id(struct gsm_subscriber_connection *conn) static bool lchan_type_compat_with_mode(enum gsm_chan_t type, const struct channel_mode_and_rate *ch_mode_rate) { enum gsm48_chan_mode chan_mode = ch_mode_rate->chan_mode; - enum channel_rate chan_rate = ch_mode_rate->chan_rate; + bool full_rate = ch_mode_rate->full_rate; switch (chan_mode) { case GSM48_CMODE_SIGN: switch (type) { - case GSM_LCHAN_TCH_F: return chan_rate == CH_RATE_FULL; - case GSM_LCHAN_TCH_H: return chan_rate == CH_RATE_HALF; - case GSM_LCHAN_SDCCH: return chan_rate == CH_RATE_SDCCH; - default: return false; + case GSM_LCHAN_TCH_F: + case GSM_LCHAN_TCH_H: + case GSM_LCHAN_SDCCH: + return true; + default: + return false; } case GSM48_CMODE_SPEECH_V1: @@ -267,12 +269,12 @@ static bool lchan_type_compat_with_mode(enum gsm_chan_t type, const struct chann case GSM48_CMODE_DATA_3k6: case GSM48_CMODE_DATA_6k0: /* these services can all run on TCH/H, but we may have - * an explicit override by the 'chan_rate' argument */ + * an explicit override by the 'full_rate' argument */ switch (type) { case GSM_LCHAN_TCH_F: - return chan_rate == CH_RATE_FULL; + return full_rate; case GSM_LCHAN_TCH_H: - return chan_rate == CH_RATE_HALF; + return !full_rate; default: return false; } @@ -318,34 +320,45 @@ static int check_requires_voice(bool *requires_voice, enum gsm48_chan_mode chan_ * sure that both are consistent. */ static int check_requires_voice_stream(struct gsm_subscriber_connection *conn) { - bool requires_voice_pref = false, requires_voice_alt; + bool result_requires_voice_alt; + bool result_requires_voice_pref; struct assignment_request *req = &conn->assignment.req; struct osmo_fsm_inst *fi = conn->fi; - int i, rc; + int rc; /* When the assignment request indicates that there is an alternate * rate available (e.g. "Full or Half rate channel, Half rate * preferred..."), then both must be either voice or either signalling, * a mismatch is not permitted */ - for (i = 0; i < req->n_ch_mode_rate; i++) { - rc = check_requires_voice(&requires_voice_alt, req->ch_mode_rate[i].chan_mode); - if (rc < 0) { - assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP, - "Channel mode not supported (prev level %d): %s", i, - gsm48_chan_mode_name(req->ch_mode_rate[i].chan_mode)); - return -EINVAL; - } + /* Check the prefered setting */ + rc = check_requires_voice(&result_requires_voice_pref, req->ch_mode_rate_pref.chan_mode); + if (rc < 0) { + assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP, + "Prefered channel mode not supported: %s", + gsm48_chan_mode_name(req->ch_mode_rate_pref.chan_mode)); + return -EINVAL; + } + conn->assignment.requires_voice_stream = result_requires_voice_pref; + + /* If there is an alternate setting, check that one as well */ + if (!req->ch_mode_rate_alt_present) + return 0; + rc = check_requires_voice(&result_requires_voice_alt, req->ch_mode_rate_alt.chan_mode); + if (rc < 0) { + assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP, + "Alternate channel mode not supported: %s", + gsm48_chan_mode_name(req->ch_mode_rate_alt.chan_mode)); + return -EINVAL; + } - if (i==0) - requires_voice_pref = requires_voice_alt; - else if (requires_voice_alt != requires_voice_pref) { - assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP, - "Inconsistent channel modes: %s != %s", - gsm48_chan_mode_name(req->ch_mode_rate[0].chan_mode), - gsm48_chan_mode_name(req->ch_mode_rate[i].chan_mode)); - return -EINVAL; - } + /* Make sure both settings match */ + if (result_requires_voice_pref != result_requires_voice_alt) { + assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP, + "Inconsistent channel modes: %s != %s", + gsm48_chan_mode_name(req->ch_mode_rate_pref.chan_mode), + gsm48_chan_mode_name(req->ch_mode_rate_alt.chan_mode)); + return -EINVAL; } return 0; @@ -357,20 +370,18 @@ static int check_requires_voice_stream(struct gsm_subscriber_connection *conn) static bool reuse_existing_lchan(struct gsm_subscriber_connection *conn) { struct assignment_request *req = &conn->assignment.req; - int i; if (!conn->lchan) return false; /* Check if the currently existing lchan is compatible with the * preferred rate/codec. */ - for (i = 0; i < req->n_ch_mode_rate; i++) - if (lchan_type_compat_with_mode(conn->lchan->type, &req->ch_mode_rate[i])) { - conn->lchan->ch_mode_rate = req->ch_mode_rate[i]; - break; - } - - if (i == req->n_ch_mode_rate) + if (lchan_type_compat_with_mode(conn->lchan->type, &req->ch_mode_rate_pref)) + conn->lchan->ch_mode_rate = req->ch_mode_rate_pref; + else if (req->ch_mode_rate_alt_present + && lchan_type_compat_with_mode(conn->lchan->type, &req->ch_mode_rate_alt)) + conn->lchan->ch_mode_rate = req->ch_mode_rate_alt; + else return false; if (conn->lchan->tch_mode != conn->lchan->ch_mode_rate.chan_mode) { @@ -388,14 +399,8 @@ static bool reuse_existing_lchan(struct gsm_subscriber_connection *conn) void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts, struct assignment_request *req) { - static const char *rate_names[] = { - [CH_RATE_SDCCH] = "SDCCH", - [CH_RATE_HALF] = "HR", - [CH_RATE_FULL] = "FR", - }; struct osmo_fsm_inst *fi; struct lchan_activate_info info; - int i; OSMO_ASSERT(conn); OSMO_ASSERT(conn->fi); @@ -438,13 +443,17 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts return; } - /* Try to allocate a new lchan in order of preference */ - for (i = 0; i < req->n_ch_mode_rate; i++) { - conn->assignment.new_lchan = lchan_select_by_chan_mode(bts, - req->ch_mode_rate[i].chan_mode, req->ch_mode_rate[i].chan_rate); - conn->lchan->ch_mode_rate = req->ch_mode_rate[i]; - if (conn->assignment.new_lchan) - break; + /* Try to allocate a new lchan with the preferred codec/rate choice */ + conn->assignment.new_lchan = + lchan_select_by_chan_mode(bts, req->ch_mode_rate_pref.chan_mode, req->ch_mode_rate_pref.full_rate); + conn->lchan->ch_mode_rate = req->ch_mode_rate_pref; + + /* In case the lchan allocation fails, we try with the alternat codec/ + * rate choice (if possible) */ + if (!conn->assignment.new_lchan && req->ch_mode_rate_alt_present) { + conn->assignment.new_lchan = + lchan_select_by_chan_mode(bts, req->ch_mode_rate_alt.chan_mode, req->ch_mode_rate_alt.full_rate); + conn->lchan->ch_mode_rate = req->ch_mode_rate_alt; } /* Check whether the lchan allocation was successful or not and tear @@ -453,22 +462,21 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts assignment_count_result(BSC_CTR_ASSIGNMENT_NO_CHANNEL); assignment_fail(GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, "BSSMAP Assignment Command:" - " No lchan available for: pref=%s:%s / alt1=%s:%s / alt2=%s:%s\n", - gsm48_chan_mode_name(req->ch_mode_rate[0].chan_mode), - rate_names[req->ch_mode_rate[0].chan_rate], - req->n_ch_mode_rate >= 1 ? gsm48_chan_mode_name(req->ch_mode_rate[0].chan_mode) : "", - req->n_ch_mode_rate >= 1 ? rate_names[req->ch_mode_rate[0].chan_rate] : "", - req->n_ch_mode_rate >= 2 ? gsm48_chan_mode_name(req->ch_mode_rate[0].chan_mode) : "", - req->n_ch_mode_rate >= 2 ? rate_names[req->ch_mode_rate[0].chan_rate] : "" - ); + " No lchan available for: preferred=%s%s / alternate=%s%s\n", + gsm48_chan_mode_name(req->ch_mode_rate_pref.chan_mode), + req->ch_mode_rate_pref.full_rate ? ",FR" : ",HR", + req->ch_mode_rate_alt_present ? + gsm48_chan_mode_name(req->ch_mode_rate_alt.chan_mode) : "none", + req->ch_mode_rate_alt_present ? + (req->ch_mode_rate_alt.full_rate ? ",FR" : ",HR") : ""); return; } assignment_fsm_update_id(conn); - LOG_ASSIGNMENT(conn, LOGL_INFO, "Starting Assignment: chan_mode=%s, chan_type=%s," + LOG_ASSIGNMENT(conn, LOGL_INFO, "Starting Assignment: chan_mode=%s, full_rate=%d," " aoip=%s MSC-rtp=%s:%u\n", gsm48_chan_mode_name(conn->lchan->ch_mode_rate.chan_mode), - rate_names[conn->lchan->ch_mode_rate.chan_rate], + conn->lchan->ch_mode_rate.full_rate, req->aoip ? "yes" : "no", req->msc_rtp_addr, req->msc_rtp_port); assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE); diff --git a/src/osmo-bsc/codec_pref.c b/src/osmo-bsc/codec_pref.c index 659853ce8..a94d6a834 100644 --- a/src/osmo-bsc/codec_pref.c +++ b/src/osmo-bsc/codec_pref.c @@ -281,7 +281,6 @@ int match_codec_pref(struct channel_mode_and_rate *ch_mode_rate, { unsigned int i; uint8_t perm_spch; - bool full_rate; bool match = false; const struct gsm0808_speech_codec *sc_match = NULL; uint16_t amr_s15_s0_supported; @@ -296,16 +295,15 @@ int match_codec_pref(struct channel_mode_and_rate *ch_mode_rate, perm_spch = audio_support_to_gsm88(msc->audio_support[i]); /* Determine if the result is a half or full rate codec */ - rc = full_rate_from_perm_spch(&full_rate, perm_spch); + rc = full_rate_from_perm_spch(&ch_mode_rate->full_rate, perm_spch); if (rc < 0) return -EINVAL; - ch_mode_rate->chan_rate = full_rate ? CH_RATE_FULL : CH_RATE_HALF; /* If we have a preference for FR or HR in our request, we * discard the potential match */ - if (rate_pref == RATE_PREF_HR && ch_mode_rate->chan_rate == CH_RATE_FULL) + if (rate_pref == RATE_PREF_HR && ch_mode_rate->full_rate) continue; - if (rate_pref == RATE_PREF_FR && ch_mode_rate->chan_rate == CH_RATE_HALF) + if (rate_pref == RATE_PREF_FR && !ch_mode_rate->full_rate) continue; /* Check this permitted speech value against the BTS specific parameters. @@ -323,8 +321,8 @@ int match_codec_pref(struct channel_mode_and_rate *ch_mode_rate, /* Exit without result, in case no match can be deteched */ if (!match) { + ch_mode_rate->full_rate = false; ch_mode_rate->chan_mode = GSM48_CMODE_SIGN; - ch_mode_rate->chan_rate = CH_RATE_SDCCH; ch_mode_rate->s15_s0 = 0; return -1; } diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c index 77f81387a..a3d25d629 100644 --- a/src/osmo-bsc/handover_fsm.c +++ b/src/osmo-bsc/handover_fsm.c @@ -569,11 +569,10 @@ void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn, } LOG_HO(conn, LOGL_DEBUG, "BTS %u: Found matching audio type: %s %s (for %s)\n", - bts->nr, gsm48_chan_mode_name(ch_mode_rate.chan_mode), - ch_mode_rate.chan_rate == CH_RATE_FULL ? "full-rate" : "half-rate", + bts->nr, gsm48_chan_mode_name(ch_mode_rate.chan_mode), ch_mode_rate.full_rate? "full-rate" : "half-rate", gsm0808_channel_type_name(&req->ct)); - lchan = lchan_select_by_chan_mode(bts, ch_mode_rate.chan_mode, ch_mode_rate.chan_rate); + lchan = lchan_select_by_chan_mode(bts, ch_mode_rate.chan_mode, ch_mode_rate.full_rate); if (!lchan) { LOG_HO(conn, LOGL_DEBUG, "BTS %u has no matching free channels\n", bts->nr); continue; diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c index 0a9752e44..0f4dd6527 100644 --- a/src/osmo-bsc/lchan_select.c +++ b/src/osmo-bsc/lchan_select.c @@ -128,31 +128,22 @@ _lc_find_bts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan) } struct gsm_lchan *lchan_select_by_chan_mode(struct gsm_bts *bts, - enum gsm48_chan_mode chan_mode, enum channel_rate chan_rate) + enum gsm48_chan_mode chan_mode, bool full_rate) { enum gsm_chan_t type; switch (chan_mode) { case GSM48_CMODE_SIGN: - switch (chan_rate) { - case CH_RATE_SDCCH: type = GSM_LCHAN_SDCCH; break; - case CH_RATE_HALF: type = GSM_LCHAN_TCH_H; break; - case CH_RATE_FULL: type = GSM_LCHAN_TCH_F; break; - default: return NULL; - } + type = GSM_LCHAN_SDCCH; break; case GSM48_CMODE_SPEECH_EFR: /* EFR works over FR channels only */ - if (chan_rate != CH_RATE_FULL) + if (!full_rate) return NULL; /* fall through */ case GSM48_CMODE_SPEECH_V1: case GSM48_CMODE_SPEECH_AMR: - switch (chan_rate) { - case CH_RATE_HALF: type = GSM_LCHAN_TCH_H; break; - case CH_RATE_FULL: type = GSM_LCHAN_TCH_F; break; - default: return NULL; - } + type = full_rate ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H; break; default: return NULL; diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 5c8ce972f..85aab22d2 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -626,48 +626,60 @@ static int bssmap_handle_lcls_connect_ctrl(struct gsm_subscriber_connection *con static int select_codecs(struct assignment_request *req, struct gsm0808_channel_type *ct, struct gsm_subscriber_connection *conn) { - int rc, i, nc = 0; + int rc; struct bsc_msc_data *msc; msc = conn->sccp.msc; + req->ch_mode_rate_alt_present = false; switch (ct->ch_rate_type) { case GSM0808_SPEECH_FULL_BM: - rc = match_codec_pref(&req->ch_mode_rate[nc], ct, &conn->codec_list, msc, conn_get_bts(conn), + rc = match_codec_pref(&req->ch_mode_rate_pref, ct, &conn->codec_list, msc, conn_get_bts(conn), RATE_PREF_FR); - nc += (rc == 0); break; case GSM0808_SPEECH_HALF_LM: - rc = match_codec_pref(&req->ch_mode_rate[nc], ct, &conn->codec_list, msc, conn_get_bts(conn), + rc = match_codec_pref(&req->ch_mode_rate_pref, ct, &conn->codec_list, msc, conn_get_bts(conn), RATE_PREF_HR); - nc += (rc == 0); break; case GSM0808_SPEECH_PERM: case GSM0808_SPEECH_PERM_NO_CHANGE: case GSM0808_SPEECH_FULL_PREF_NO_CHANGE: case GSM0808_SPEECH_FULL_PREF: - rc = match_codec_pref(&req->ch_mode_rate[nc], ct, &conn->codec_list, msc, conn_get_bts(conn), + rc = match_codec_pref(&req->ch_mode_rate_pref, ct, &conn->codec_list, msc, conn_get_bts(conn), RATE_PREF_FR); - nc += (rc == 0); - rc = match_codec_pref(&req->ch_mode_rate[nc], ct, &conn->codec_list, msc, conn_get_bts(conn), + if (rc < 0) { + rc = match_codec_pref(&req->ch_mode_rate_pref, ct, &conn->codec_list, msc, conn_get_bts(conn), + RATE_PREF_HR); + break; + } + rc = match_codec_pref(&req->ch_mode_rate_alt, ct, &conn->codec_list, msc, conn_get_bts(conn), RATE_PREF_HR); - nc += (rc == 0); + if (rc == 0) + req->ch_mode_rate_alt_present = true; + rc = 0; break; case GSM0808_SPEECH_HALF_PREF_NO_CHANGE: case GSM0808_SPEECH_HALF_PREF: - rc = match_codec_pref(&req->ch_mode_rate[nc], ct, &conn->codec_list, msc, conn_get_bts(conn), + rc = match_codec_pref(&req->ch_mode_rate_pref, ct, &conn->codec_list, msc, conn_get_bts(conn), RATE_PREF_HR); - nc += (rc == 0); - rc = match_codec_pref(&req->ch_mode_rate[nc], ct, &conn->codec_list, msc, conn_get_bts(conn), + + if (rc < 0) { + rc = match_codec_pref(&req->ch_mode_rate_pref, ct, &conn->codec_list, msc, conn_get_bts(conn), + RATE_PREF_FR); + break; + } + rc = match_codec_pref(&req->ch_mode_rate_alt, ct, &conn->codec_list, msc, conn_get_bts(conn), RATE_PREF_FR); - nc += (rc == 0); + if (rc == 0) + req->ch_mode_rate_alt_present = true; + rc = 0; break; default: rc = -EINVAL; break; } - if (!nc) { + if (rc < 0) { LOGP(DMSC, LOGL_ERROR, "No supported audio type found for channel_type =" " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[%s] }\n", ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len)); @@ -676,67 +688,27 @@ static int select_codecs(struct assignment_request *req, struct gsm0808_channel_ return -EINVAL; } - for (i = 0; i < nc; i++ ) { - DEBUGP(DMSC, "Found matching audio type (pref=%d): %s %s for channel_type =" + if (req->ch_mode_rate_alt_present) { + DEBUGP(DMSC, "Found matching audio type (preferred): %s %s for channel_type =" " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n", - i, - req->ch_mode_rate[i].chan_rate == CH_RATE_FULL ? "full rate" : "half rate", - get_value_string(gsm48_chan_mode_names, req->ch_mode_rate[i].chan_mode), + req->ch_mode_rate_pref.full_rate ? "full rate" : "half rate", + get_value_string(gsm48_chan_mode_names, req->ch_mode_rate_pref.chan_mode), + ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len)); + DEBUGP(DMSC, "Found matching audio type (alternative): %s %s for channel_type =" + " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n", + req->ch_mode_rate_alt.full_rate ? "full rate" : "half rate", + get_value_string(gsm48_chan_mode_names, req->ch_mode_rate_alt.chan_mode), + ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len)); + } else { + DEBUGP(DMSC, "Found matching audio type: %s %s for channel_type =" + " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n", + req->ch_mode_rate_pref.full_rate ? "full rate" : "half rate", + get_value_string(gsm48_chan_mode_names, req->ch_mode_rate_pref.chan_mode), ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len)); - } - - req->n_ch_mode_rate = nc; - - return 0; -} - -static int select_sign_chan(struct assignment_request *req, struct gsm0808_channel_type *ct) -{ - int i, nc = 0; - switch (ct->ch_rate_type) { - case GSM0808_SIGN_ANY: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_SDCCH; - req->ch_mode_rate[nc++].chan_rate = CH_RATE_HALF; - req->ch_mode_rate[nc++].chan_rate = CH_RATE_FULL; - break; - case GSM0808_SIGN_SDCCH: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_SDCCH; - break; - case GSM0808_SIGN_SDCCH_FULL_BM: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_SDCCH; - req->ch_mode_rate[nc++].chan_rate = CH_RATE_FULL; - break; - case GSM0808_SIGN_SDCCH_HALF_LM: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_SDCCH; - req->ch_mode_rate[nc++].chan_rate = CH_RATE_HALF; - break; - case GSM0808_SIGN_FULL_BM: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_FULL; - break; - case GSM0808_SIGN_HALF_LM: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_HALF; - break; - case GSM0808_SIGN_FULL_PREF: - case GSM0808_SIGN_FULL_PREF_NO_CHANGE: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_FULL; - req->ch_mode_rate[nc++].chan_rate = CH_RATE_HALF; - break; - case GSM0808_SIGN_HALF_PREF: - case GSM0808_SIGN_HALF_PREF_NO_CHANGE: - req->ch_mode_rate[nc++].chan_rate = CH_RATE_HALF; - req->ch_mode_rate[nc++].chan_rate = CH_RATE_FULL; - break; - default: - break; } - for (i = 0; i < nc; i++) - req->ch_mode_rate[i].chan_mode = GSM48_CMODE_SIGN; - - req->n_ch_mode_rate = nc; - - return nc > 0 ? 0 : -EINVAL; + return 0; } /* @@ -756,6 +728,7 @@ static int bssmap_handle_assignm_req(struct gsm_subscriber_connection *conn, uint8_t cause; int rc; struct assignment_request req = {}; + struct channel_mode_and_rate ch_mode_rate_pref = {}; if (!conn) { LOGP(DMSC, LOGL_ERROR, @@ -876,15 +849,14 @@ static int bssmap_handle_assignm_req(struct gsm_subscriber_connection *conn, } break; case GSM0808_CHAN_SIGN: + ch_mode_rate_pref = (struct channel_mode_and_rate) { + .chan_mode = GSM48_CMODE_SIGN, + }; + req = (struct assignment_request){ .aoip = aoip, + .ch_mode_rate_pref = ch_mode_rate_pref, }; - - rc = select_sign_chan(&req, &ct); - if (rc < 0) { - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } break; default: cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS; diff --git a/tests/codec_pref/codec_pref_test.c b/tests/codec_pref/codec_pref_test.c index ce82f3d93..bb5468a4c 100644 --- a/tests/codec_pref/codec_pref_test.c +++ b/tests/codec_pref/codec_pref_test.c @@ -407,7 +407,7 @@ static int test_match_codec_pref(const struct gsm0808_channel_type *ct, const st rc = match_codec_pref(&ch_mode_rate, ct, scl, msc, bts, RATE_PREF_NONE); printf(" * result: rc=%i, full_rate=%i, s15_s0=%04x, chan_mode=%s\n", - rc, ch_mode_rate.chan_rate == CH_RATE_FULL, ch_mode_rate.s15_s0, gsm48_chan_mode_name(ch_mode_rate.chan_mode)); + rc, ch_mode_rate.full_rate, ch_mode_rate.s15_s0, gsm48_chan_mode_name(ch_mode_rate.chan_mode)); printf("\n"); -- cgit v1.2.3