aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2019-03-14 22:11:45 +0000
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2019-03-14 22:47:31 +0000
commit0848ff84b7655097a5aedae1b58cdcd2571c8af5 (patch)
tree206df5aed1f6628df4956fb13e7fbf80ba57ef03
parent85e2bc905130a1a18b914a40c526d3a9cfd17a7c (diff)
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: <INSERT REASONING HERE> Change-Id: I72aaa03539919e7e85b5b75b133326cec5e68bc9
-rw-r--r--include/osmocom/bsc/gsm_data.h17
-rw-r--r--include/osmocom/bsc/lchan_select.h2
-rw-r--r--src/osmo-bsc/assignment_fsm.c124
-rw-r--r--src/osmo-bsc/codec_pref.c10
-rw-r--r--src/osmo-bsc/handover_fsm.c5
-rw-r--r--src/osmo-bsc/lchan_select.c17
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c124
-rw-r--r--tests/codec_pref/codec_pref_test.c2
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");