codec_pref: move match_codec_pref() to separate c-file and add unit-test
At the moment there are three sources that may advertise a list of supported audio codec/rate settings. There is the MS that advertises advertises a speech codec list and the MSC that sends a channel type information element over A and there are also settings in the bsc configuration file that may restrict the codec/rate types that are allowed to use. The function match_codec_pref() looks at all of the three buckets and selects a codec that satisfies all three. This is already a somewhat complicated process, overit is very isolated, so lets give it its own c-file. Due to the lack of unit-tests it is very hard to make changes here so lets add also unit-test to make sure that regressions are catched early. - Put match_codec_pref() and all its helper functions into a separate c-file. - Add a unit test. Change-Id: Iabedfdcec8b99a319f2d57cbea45c5e36c7b6e29 Related: OS#3361
This commit is contained in:
parent
16dd64a078
commit
844876f8d5
|
@ -176,6 +176,7 @@ AC_OUTPUT(
|
|||
tests/atlocal
|
||||
tests/gsm0408/Makefile
|
||||
tests/bsc/Makefile
|
||||
tests/codec_pref/Makefile
|
||||
tests/abis/Makefile
|
||||
tests/subscr/Makefile
|
||||
tests/nanobts_omlattr/Makefile
|
||||
|
|
|
@ -12,6 +12,7 @@ noinst_HEADERS = \
|
|||
bss.h \
|
||||
bts_ipaccess_nanobts_omlattr.h \
|
||||
chan_alloc.h \
|
||||
codec_pref.h \
|
||||
ctrl.h \
|
||||
debug.h \
|
||||
e1_config.h \
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
int match_codec_pref(int *full_rate, enum gsm48_chan_mode *chan_mode,
|
||||
const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl,
|
||||
const struct bsc_msc_data *msc);
|
|
@ -53,6 +53,7 @@ osmo_bsc_SOURCES = \
|
|||
bts_sysmobts.c \
|
||||
bts_unknown.c \
|
||||
chan_alloc.c \
|
||||
codec_pref.c \
|
||||
e1_config.c \
|
||||
gsm_04_08_utils.c \
|
||||
gsm_04_80_utils.c \
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* (C) 2017-2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/gsm0808_utils.h>
|
||||
#include <osmocom/bsc/bsc_msc_data.h>
|
||||
#include <osmocom/bsc/codec_pref.h>
|
||||
|
||||
/* Helper function for match_codec_pref(), looks up a matching chan mode for
|
||||
* a given permitted speech value */
|
||||
enum gsm48_chan_mode gsm88_to_chan_mode(enum gsm0808_permitted_speech speech)
|
||||
{
|
||||
switch (speech) {
|
||||
case GSM0808_PERM_HR1:
|
||||
case GSM0808_PERM_FR1:
|
||||
return GSM48_CMODE_SPEECH_V1;
|
||||
break;
|
||||
case GSM0808_PERM_HR2:
|
||||
case GSM0808_PERM_FR2:
|
||||
return GSM48_CMODE_SPEECH_EFR;
|
||||
break;
|
||||
case GSM0808_PERM_HR3:
|
||||
case GSM0808_PERM_FR3:
|
||||
return GSM48_CMODE_SPEECH_AMR;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMSC, LOGL_FATAL, "Unsupported permitted speech selected, assuming AMR as channel mode...\n");
|
||||
return GSM48_CMODE_SPEECH_AMR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for match_codec_pref(), looks up a matching permitted speech
|
||||
* value for a given msc audio codec pref */
|
||||
enum gsm0808_permitted_speech audio_support_to_gsm88(struct gsm_audio_support *audio)
|
||||
{
|
||||
if (audio->hr) {
|
||||
switch (audio->ver) {
|
||||
case 1:
|
||||
return GSM0808_PERM_HR1;
|
||||
break;
|
||||
case 2:
|
||||
return GSM0808_PERM_HR2;
|
||||
break;
|
||||
case 3:
|
||||
return GSM0808_PERM_HR3;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMSC, LOGL_ERROR, "Wrong speech mode: hr%d, using hr1 instead\n", audio->ver);
|
||||
return GSM0808_PERM_HR1;
|
||||
}
|
||||
} else {
|
||||
switch (audio->ver) {
|
||||
case 1:
|
||||
return GSM0808_PERM_FR1;
|
||||
break;
|
||||
case 2:
|
||||
return GSM0808_PERM_FR2;
|
||||
break;
|
||||
case 3:
|
||||
return GSM0808_PERM_FR3;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMSC, LOGL_ERROR, "Wrong speech mode: fr%d, using fr1 instead\n", audio->ver);
|
||||
return GSM0808_PERM_FR1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for match_codec_pref(), tests if a given audio support
|
||||
* matches one of the permitted speech settings of the channel type element.
|
||||
* The matched permitted speech value is then also compared against the
|
||||
* speech codec list. (optional, only relevant for AoIP) */
|
||||
static bool test_codec_pref(const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl, uint8_t perm_spch)
|
||||
{
|
||||
unsigned int i;
|
||||
bool match = false;
|
||||
struct gsm0808_speech_codec sc;
|
||||
int rc;
|
||||
|
||||
/* Try to find the given permitted speech value in the
|
||||
* codec list of the channel type element */
|
||||
for (i = 0; i < ct->perm_spch_len; i++) {
|
||||
if (ct->perm_spch[i] == perm_spch) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we do not have a speech codec list to test against,
|
||||
* we just exit early (will be always the case in non-AoIP networks) */
|
||||
if (!scl)
|
||||
return match;
|
||||
|
||||
/* If we failed to match until here, there is no
|
||||
* point in testing further */
|
||||
if (match == false)
|
||||
return false;
|
||||
|
||||
/* Extrapolate speech codec data */
|
||||
rc = gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
|
||||
if (rc < 0)
|
||||
return false;
|
||||
|
||||
/* Try to find extrapolated speech codec data in
|
||||
* the speech codec list */
|
||||
for (i = 0; i < scl->len; i++) {
|
||||
if (sc.type == scl->codec[i].type)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Helper function for bssmap_handle_assignm_req(), matches the codec
|
||||
* preferences from the MSC with the codec preferences
|
||||
* \param[out] full_rate '1' if full-rate, '0' if half-rate, '-1' if no match
|
||||
* \param[out] chan_mode GSM 04.08 channel mode
|
||||
* \param[in] ct GSM 08.08 channel type
|
||||
* \param[in] scl GSM 08.08 speech codec list
|
||||
* \param[in] msc MSC data [for configuration]
|
||||
* \returns 0 on success, -1 in case no match was found */
|
||||
int match_codec_pref(int *full_rate, enum gsm48_chan_mode *chan_mode,
|
||||
const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl, const struct bsc_msc_data *msc)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t perm_spch;
|
||||
bool match = false;
|
||||
|
||||
for (i = 0; i < msc->audio_length; i++) {
|
||||
perm_spch = audio_support_to_gsm88(msc->audio_support[i]);
|
||||
if (test_codec_pref(ct, scl, perm_spch)) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit without result, in case no match can be deteched */
|
||||
if (!match) {
|
||||
*full_rate = -1;
|
||||
*chan_mode = GSM48_CMODE_SIGN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if the result is a half or full rate codec */
|
||||
if (perm_spch == GSM0808_PERM_HR1 || perm_spch == GSM0808_PERM_HR2 || perm_spch == GSM0808_PERM_HR3
|
||||
|| perm_spch == GSM0808_PERM_HR4 || perm_spch == GSM0808_PERM_HR6)
|
||||
*full_rate = 0;
|
||||
else
|
||||
*full_rate = 1;
|
||||
|
||||
/* Lookup a channel mode for the selected codec */
|
||||
*chan_mode = gsm88_to_chan_mode(perm_spch);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -22,17 +22,13 @@
|
|||
#include <osmocom/bsc/osmo_bsc.h>
|
||||
#include <osmocom/bsc/osmo_bsc_grace.h>
|
||||
#include <osmocom/bsc/osmo_bsc_rf.h>
|
||||
#include <osmocom/bsc/bsc_msc_data.h>
|
||||
#include <osmocom/bsc/debug.h>
|
||||
#include <osmocom/bsc/bsc_subscriber.h>
|
||||
#include <osmocom/bsc/paging.h>
|
||||
#include <osmocom/bsc/gsm_04_08_utils.h>
|
||||
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
|
||||
|
||||
#include <osmocom/gsm/protocol/gsm_08_08.h>
|
||||
#include <osmocom/bsc/codec_pref.h>
|
||||
#include <osmocom/gsm/gsm0808.h>
|
||||
#include <osmocom/gsm/gsm0808_utils.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
#include <osmocom/bsc/osmo_bsc_sigtran.h>
|
||||
#include <osmocom/bsc/osmo_bsc_lcls.h>
|
||||
#include <osmocom/bsc/a_reset.h>
|
||||
|
@ -45,161 +41,6 @@
|
|||
* helpers for the assignment command
|
||||
*/
|
||||
|
||||
/* Helper function for match_codec_pref(), looks up a matching permitted speech
|
||||
* value for a given msc audio codec pref */
|
||||
enum gsm0808_permitted_speech audio_support_to_gsm88(struct gsm_audio_support *audio)
|
||||
{
|
||||
if (audio->hr) {
|
||||
switch (audio->ver) {
|
||||
case 1:
|
||||
return GSM0808_PERM_HR1;
|
||||
break;
|
||||
case 2:
|
||||
return GSM0808_PERM_HR2;
|
||||
break;
|
||||
case 3:
|
||||
return GSM0808_PERM_HR3;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMSC, LOGL_ERROR, "Wrong speech mode: hr%d, using hr1 instead\n",
|
||||
audio->ver);
|
||||
return GSM0808_PERM_HR1;
|
||||
}
|
||||
} else {
|
||||
switch (audio->ver) {
|
||||
case 1:
|
||||
return GSM0808_PERM_FR1;
|
||||
break;
|
||||
case 2:
|
||||
return GSM0808_PERM_FR2;
|
||||
break;
|
||||
case 3:
|
||||
return GSM0808_PERM_FR3;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMSC, LOGL_ERROR, "Wrong speech mode: fr%d, using fr1 instead\n",
|
||||
audio->ver);
|
||||
return GSM0808_PERM_FR1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for match_codec_pref(), looks up a matching chan mode for
|
||||
* a given permitted speech value */
|
||||
enum gsm48_chan_mode gsm88_to_chan_mode(enum gsm0808_permitted_speech speech)
|
||||
{
|
||||
switch (speech) {
|
||||
case GSM0808_PERM_HR1:
|
||||
case GSM0808_PERM_FR1:
|
||||
return GSM48_CMODE_SPEECH_V1;
|
||||
break;
|
||||
case GSM0808_PERM_HR2:
|
||||
case GSM0808_PERM_FR2:
|
||||
return GSM48_CMODE_SPEECH_EFR;
|
||||
break;
|
||||
case GSM0808_PERM_HR3:
|
||||
case GSM0808_PERM_FR3:
|
||||
return GSM48_CMODE_SPEECH_AMR;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMSC, LOGL_FATAL,
|
||||
"Unsupported permitted speech selected, assuming AMR as channel mode...\n");
|
||||
return GSM48_CMODE_SPEECH_AMR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for match_codec_pref(), tests if a given audio support
|
||||
* matches one of the permitted speech settings of the channel type element.
|
||||
* The matched permitted speech value is then also compared against the
|
||||
* speech codec list. (optional, only relevant for AoIP) */
|
||||
static bool test_codec_pref(const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl,
|
||||
uint8_t perm_spch)
|
||||
{
|
||||
unsigned int i;
|
||||
bool match = false;
|
||||
struct gsm0808_speech_codec sc;
|
||||
int rc;
|
||||
|
||||
/* Try to finde the given permitted speech value in the
|
||||
* codec list of the channel type element */
|
||||
for (i = 0; i < ct->perm_spch_len; i++) {
|
||||
if (ct->perm_spch[i] == perm_spch) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we do not have a speech codec list to test against,
|
||||
* we just exit early (will be always the case in non-AoIP networks) */
|
||||
if (!scl)
|
||||
return match;
|
||||
|
||||
/* If we failed to match until here, there is no
|
||||
* point in testing further */
|
||||
if (match == false)
|
||||
return false;
|
||||
|
||||
/* Extrapolate speech codec data */
|
||||
rc = gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
|
||||
if (rc < 0)
|
||||
return false;
|
||||
|
||||
/* Try to find extrapolated speech codec data in
|
||||
* the speech codec list */
|
||||
for (i = 0; i < scl->len; i++) {
|
||||
if (sc.type == scl->codec[i].type)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Helper function for bssmap_handle_assignm_req(), matches the codec
|
||||
* preferences from the MSC with the codec preferences
|
||||
* \param[out] full_rate '1' if full-rate, '0' if half-rate, '-1' if no match
|
||||
* \param[out] chan_mode GSM 04.08 channel mode
|
||||
* \param[in] ct GSM 08.08 channel type
|
||||
* \param[in] scl GSM 08.08 speech codec list
|
||||
* \param[in] msc MSC data [for configuration]
|
||||
* \returns 0 on success, -1 in case no match was found */
|
||||
static int match_codec_pref(int *full_rate, enum gsm48_chan_mode *chan_mode,
|
||||
const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl,
|
||||
const struct bsc_msc_data *msc)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t perm_spch;
|
||||
bool match = false;
|
||||
|
||||
for (i = 0; i < msc->audio_length; i++) {
|
||||
perm_spch = audio_support_to_gsm88(msc->audio_support[i]);
|
||||
if (test_codec_pref(ct, scl, perm_spch)) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit without result, in case no match can be deteched */
|
||||
if (!match) {
|
||||
*full_rate = -1;
|
||||
*chan_mode = GSM48_CMODE_SIGN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if the result is a half or full rate codec */
|
||||
if (perm_spch == GSM0808_PERM_HR1 || perm_spch == GSM0808_PERM_HR2
|
||||
|| perm_spch == GSM0808_PERM_HR3 || perm_spch == GSM0808_PERM_HR4
|
||||
|| perm_spch == GSM0808_PERM_HR6)
|
||||
*full_rate = 0;
|
||||
else
|
||||
*full_rate = 1;
|
||||
|
||||
/* Lookup a channel mode for the selected codec */
|
||||
*chan_mode = gsm88_to_chan_mode(perm_spch);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bssmap_handle_reset_ack(struct bsc_msc_data *msc,
|
||||
struct msgb *msg, unsigned int length)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
SUBDIRS = \
|
||||
bsc \
|
||||
codec_pref \
|
||||
gsm0408 \
|
||||
abis \
|
||||
subscr \
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
AM_CPPFLAGS = \
|
||||
$(all_includes) \
|
||||
-I$(top_srcdir)/include \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = \
|
||||
-Wall \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOGSM_CFLAGS) \
|
||||
$(LIBOSMOABIS_CFLAGS) \
|
||||
$(LIBOSMOSIGTRAN_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
codec_pref_test.ok \
|
||||
$(NULL)
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
codec_pref_test \
|
||||
$(NULL)
|
||||
|
||||
codec_pref_test_SOURCES = \
|
||||
codec_pref_test.c \
|
||||
$(NULL)
|
||||
|
||||
codec_pref_test_LDADD = \
|
||||
$(top_builddir)/src/osmo-bsc/codec_pref.o \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
-lrt \
|
||||
$(NULL)
|
|
@ -0,0 +1,498 @@
|
|||
/*
|
||||
* (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osmocom/bsc/osmo_bsc.h>
|
||||
#include <osmocom/bsc/bsc_msc_data.h>
|
||||
#include <osmocom/bsc/gsm_04_80.h>
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/bsc/codec_pref.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void *ctx = NULL;
|
||||
|
||||
#define MSC_AUDIO_SUPPORT_MAX 5
|
||||
#define N_CONFIG_VARIANTS 9
|
||||
|
||||
/* Make sure that there is some memory to put our test configuration. */
|
||||
static void init_msc_config(struct bsc_msc_data *msc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
msc->audio_support = talloc_zero_array(ctx, struct gsm_audio_support *, MSC_AUDIO_SUPPORT_MAX);
|
||||
msc->audio_length = MSC_AUDIO_SUPPORT_MAX;
|
||||
for (i = 0; i < MSC_AUDIO_SUPPORT_MAX; i++) {
|
||||
msc->audio_support[i] = talloc_zero(msc->audio_support, struct gsm_audio_support);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory that we have used for the test configuration. */
|
||||
static void free_msc_config(struct bsc_msc_data *msc)
|
||||
{
|
||||
talloc_free(msc->audio_support);
|
||||
}
|
||||
|
||||
/* The speech codec list is sent by the MS and lists the voice codec settings
|
||||
* that the MS is able to support. The BSC must select one of this codecs
|
||||
* depending on what the MSC is able to support. The following function
|
||||
* generates some realistically made up speech codec lists. */
|
||||
static void make_scl_config(struct gsm0808_speech_codec_list *scl, uint8_t config_no)
|
||||
{
|
||||
OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
|
||||
|
||||
switch (config_no) {
|
||||
case 0:
|
||||
/* FR1 only */
|
||||
scl->codec[0].type = GSM0808_SCT_FR1;
|
||||
scl->len = 1;
|
||||
break;
|
||||
case 1:
|
||||
/* HR1 only */
|
||||
scl->codec[0].type = GSM0808_SCT_HR1;
|
||||
scl->len = 1;
|
||||
break;
|
||||
case 2:
|
||||
/* FR2 only */
|
||||
scl->codec[0].type = GSM0808_SCT_FR2;
|
||||
scl->len = 1;
|
||||
break;
|
||||
case 3:
|
||||
/* FR3 only */
|
||||
scl->codec[0].type = GSM0808_SCT_FR3;
|
||||
scl->len = 1;
|
||||
break;
|
||||
case 4:
|
||||
/* HR3 only */
|
||||
scl->codec[0].type = GSM0808_SCT_HR3;
|
||||
scl->len = 1;
|
||||
break;
|
||||
case 5:
|
||||
/* FR1 and HR1 */
|
||||
scl->codec[0].type = GSM0808_SCT_FR1;
|
||||
scl->codec[1].type = GSM0808_SCT_HR1;
|
||||
scl->len = 2;
|
||||
break;
|
||||
case 6:
|
||||
/* FR1, FR2 and HR1 */
|
||||
scl->codec[0].type = GSM0808_SCT_FR1;
|
||||
scl->codec[1].type = GSM0808_SCT_FR2;
|
||||
scl->codec[2].type = GSM0808_SCT_HR1;
|
||||
scl->len = 3;
|
||||
break;
|
||||
case 7:
|
||||
/* FR1, FR3 and HR3 */
|
||||
scl->codec[0].type = GSM0808_SCT_FR1;
|
||||
scl->codec[1].type = GSM0808_SCT_FR3;
|
||||
scl->codec[2].type = GSM0808_SCT_HR3;
|
||||
scl->len = 3;
|
||||
break;
|
||||
case 8:
|
||||
/* FR1, FR2, FR3, HR1 and HR3 */
|
||||
scl->codec[0].type = GSM0808_SCT_FR1;
|
||||
scl->codec[1].type = GSM0808_SCT_FR2;
|
||||
scl->codec[2].type = GSM0808_SCT_FR3;
|
||||
scl->codec[3].type = GSM0808_SCT_HR1;
|
||||
scl->codec[4].type = GSM0808_SCT_HR3;
|
||||
scl->len = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The channel type element which is sent to the BSC by the MSC lists all the
|
||||
* codecs that the MSC is able to support. The following function generates
|
||||
* a realistic permitted speech settings */
|
||||
static void make_ct_config(struct gsm0808_channel_type *ct, uint8_t config_no)
|
||||
{
|
||||
OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
|
||||
|
||||
switch (config_no) {
|
||||
case 0:
|
||||
/* FR1 only */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR1;
|
||||
ct->perm_spch_len = 1;
|
||||
break;
|
||||
case 1:
|
||||
/* HR1 only */
|
||||
ct->perm_spch[0] = GSM0808_PERM_HR1;
|
||||
ct->perm_spch_len = 1;
|
||||
break;
|
||||
case 2:
|
||||
/* FR2 only */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR2;
|
||||
ct->perm_spch_len = 1;
|
||||
break;
|
||||
case 3:
|
||||
/* FR3 only */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR3;
|
||||
ct->perm_spch_len = 1;
|
||||
break;
|
||||
case 4:
|
||||
/* HR3 only */
|
||||
ct->perm_spch[0] = GSM0808_PERM_HR3;
|
||||
ct->perm_spch_len = 1;
|
||||
break;
|
||||
case 5:
|
||||
/* FR1 and HR1 */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR1;
|
||||
ct->perm_spch[1] = GSM0808_PERM_HR1;
|
||||
ct->perm_spch_len = 2;
|
||||
break;
|
||||
case 6:
|
||||
/* FR1, FR2 and HR1 */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR1;
|
||||
ct->perm_spch[1] = GSM0808_PERM_FR2;
|
||||
ct->perm_spch[2] = GSM0808_PERM_HR1;
|
||||
ct->perm_spch_len = 3;
|
||||
break;
|
||||
case 7:
|
||||
/* FR1, FR3 and HR3 */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR1;
|
||||
ct->perm_spch[1] = GSM0808_PERM_FR3;
|
||||
ct->perm_spch[2] = GSM0808_PERM_HR3;
|
||||
ct->perm_spch_len = 3;
|
||||
break;
|
||||
case 8:
|
||||
/* FR1, FR2, FR3, HR1 and HR3 */
|
||||
ct->perm_spch[0] = GSM0808_PERM_FR1;
|
||||
ct->perm_spch[1] = GSM0808_PERM_FR2;
|
||||
ct->perm_spch[2] = GSM0808_PERM_FR3;
|
||||
ct->perm_spch[3] = GSM0808_PERM_HR1;
|
||||
ct->perm_spch[4] = GSM0808_PERM_HR3;
|
||||
ct->perm_spch_len = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate some realistic MSC configuration which one also could find in the
|
||||
* real world. This configuration acts as a filter. While the MSC could in
|
||||
* theory advertise codecs more codecs as we are able to support we have to
|
||||
* make sure that only the codecs we have support for are considered. */
|
||||
static void make_msc_config(struct bsc_msc_data *msc, uint8_t config_no)
|
||||
{
|
||||
/* 1 = FR1/HR1
|
||||
* 2 = FR2/HR2
|
||||
* 3 = FR2/HR3
|
||||
* Note: HR2 is deprecated */
|
||||
|
||||
OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
|
||||
|
||||
switch (config_no) {
|
||||
case 0:
|
||||
/* FR1 only */
|
||||
msc->audio_support[0]->ver = 1;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_length = 1;
|
||||
break;
|
||||
case 1:
|
||||
/* HR1 only */
|
||||
msc->audio_support[0]->ver = 1;
|
||||
msc->audio_support[0]->hr = 1;
|
||||
msc->audio_length = 1;
|
||||
break;
|
||||
case 2:
|
||||
/* FR2 only */
|
||||
msc->audio_support[0]->ver = 2;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_length = 1;
|
||||
break;
|
||||
case 3:
|
||||
/* FR3 only */
|
||||
msc->audio_support[0]->ver = 3;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_length = 1;
|
||||
break;
|
||||
case 4:
|
||||
/* HR3 only */
|
||||
msc->audio_support[0]->ver = 3;
|
||||
msc->audio_support[0]->hr = 1;
|
||||
msc->audio_length = 1;
|
||||
break;
|
||||
case 5:
|
||||
/* FR1 and HR1 */
|
||||
msc->audio_support[0]->ver = 1;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_support[1]->ver = 1;
|
||||
msc->audio_support[1]->hr = 1;
|
||||
msc->audio_length = 2;
|
||||
break;
|
||||
case 6:
|
||||
/* FR1, FR2 and HR1 */
|
||||
msc->audio_support[0]->ver = 1;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_support[1]->ver = 2;
|
||||
msc->audio_support[1]->hr = 0;
|
||||
msc->audio_support[2]->ver = 1;
|
||||
msc->audio_support[2]->hr = 1;
|
||||
msc->audio_length = 3;
|
||||
break;
|
||||
case 7:
|
||||
/* FR1, FR3 and HR3 */
|
||||
msc->audio_support[0]->ver = 1;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_support[1]->ver = 3;
|
||||
msc->audio_support[1]->hr = 0;
|
||||
msc->audio_support[2]->ver = 3;
|
||||
msc->audio_support[2]->hr = 1;
|
||||
msc->audio_length = 3;
|
||||
break;
|
||||
case 8:
|
||||
/* FR1, FR2, FR3, HR1 and HR3 */
|
||||
msc->audio_support[0]->ver = 1;
|
||||
msc->audio_support[0]->hr = 0;
|
||||
msc->audio_support[1]->ver = 2;
|
||||
msc->audio_support[1]->hr = 0;
|
||||
msc->audio_support[2]->ver = 3;
|
||||
msc->audio_support[2]->hr = 0;
|
||||
msc->audio_support[3]->ver = 1;
|
||||
msc->audio_support[3]->hr = 1;
|
||||
msc->audio_support[4]->ver = 3;
|
||||
msc->audio_support[4]->hr = 1;
|
||||
msc->audio_length = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try execute match_codec_pref(), display input and output parameters */
|
||||
static int test_match_codec_pref(const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl, const struct bsc_msc_data *msc)
|
||||
{
|
||||
int rc;
|
||||
unsigned int i;
|
||||
int full_rate;
|
||||
enum gsm48_chan_mode chan_mode;
|
||||
|
||||
printf("Determining channel mode and rate:\n");
|
||||
|
||||
printf(" * MS: speech codec list (%u items):\n", scl->len);
|
||||
for (i = 0; i < scl->len; i++)
|
||||
printf(" codec[%u]->type=%s\n", i, gsm0808_speech_codec_type_name(scl->codec[i].type));
|
||||
|
||||
printf(" * MSC: channel type permitted speech (%u items):\n", ct->perm_spch_len);
|
||||
for (i = 0; i < ct->perm_spch_len; i++)
|
||||
printf(" perm_spch[%u]=%s\n", i, gsm0808_permitted_speech_name(ct->perm_spch[i]));
|
||||
|
||||
printf(" * BSS: audio support settings (%u items):\n", msc->audio_length);
|
||||
for (i = 0; i < msc->audio_length; i++)
|
||||
if (msc->audio_support[i]->hr)
|
||||
printf(" audio_support[%u]=HR%u\n", i, msc->audio_support[i]->ver);
|
||||
else
|
||||
printf(" audio_support[%u]=FR%u\n", i, msc->audio_support[i]->ver);
|
||||
|
||||
rc = match_codec_pref(&full_rate, &chan_mode, ct, scl, msc);
|
||||
printf(" * result: rc=%i, full_rate=%i, chan_mode=%s\n", rc, full_rate, gsm48_chan_mode_name(chan_mode));
|
||||
|
||||
printf("\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* MS, MSC and local MSC settings are the same */
|
||||
static void test_one_to_one(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct gsm0808_channel_type ct_msc;
|
||||
struct gsm0808_speech_codec_list scl_ms;
|
||||
struct bsc_msc_data msc_local;
|
||||
int rc;
|
||||
|
||||
printf("============== test_one_to_one ==============\n\n");
|
||||
|
||||
init_msc_config(&msc_local);
|
||||
|
||||
for (i = 0; i < N_CONFIG_VARIANTS; i++) {
|
||||
make_msc_config(&msc_local, i);
|
||||
make_scl_config(&scl_ms, i);
|
||||
make_ct_config(&ct_msc, i);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
free_msc_config(&msc_local);
|
||||
}
|
||||
|
||||
/* Network supports all combinations, MS varies */
|
||||
static void test_ms(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct gsm0808_channel_type ct_msc;
|
||||
struct gsm0808_speech_codec_list scl_ms;
|
||||
struct bsc_msc_data msc_local;
|
||||
int rc;
|
||||
|
||||
printf("============== test_ms ==============\n\n");
|
||||
|
||||
init_msc_config(&msc_local);
|
||||
|
||||
make_msc_config(&msc_local, 8);
|
||||
make_ct_config(&ct_msc, 8);
|
||||
for (i = 0; i < N_CONFIG_VARIANTS; i++) {
|
||||
make_scl_config(&scl_ms, i);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
free_msc_config(&msc_local);
|
||||
}
|
||||
|
||||
/* BSS and MS support all combinations, MSC varies */
|
||||
static void test_ct(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct gsm0808_channel_type ct_msc;
|
||||
struct gsm0808_speech_codec_list scl_ms;
|
||||
struct bsc_msc_data msc_local;
|
||||
int rc;
|
||||
|
||||
printf("============== test_ct ==============\n\n");
|
||||
|
||||
init_msc_config(&msc_local);
|
||||
|
||||
make_msc_config(&msc_local, 8);
|
||||
make_scl_config(&scl_ms, 8);
|
||||
for (i = 0; i < N_CONFIG_VARIANTS; i++) {
|
||||
make_ct_config(&ct_msc, i);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
free_msc_config(&msc_local);
|
||||
}
|
||||
|
||||
/* MSC and MS support all combinations, BSS varies */
|
||||
static void test_msc(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct gsm0808_channel_type ct_msc;
|
||||
struct gsm0808_speech_codec_list scl_ms;
|
||||
struct bsc_msc_data msc_local;
|
||||
int rc;
|
||||
|
||||
printf("============== test_msc ==============\n\n");
|
||||
|
||||
init_msc_config(&msc_local);
|
||||
|
||||
make_ct_config(&ct_msc, 8);
|
||||
make_scl_config(&scl_ms, 8);
|
||||
for (i = 0; i < N_CONFIG_VARIANTS; i++) {
|
||||
make_msc_config(&msc_local, 8);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
free_msc_config(&msc_local);
|
||||
}
|
||||
|
||||
/* Some mixed configurations that are supposed to work */
|
||||
static void test_selected_working(void)
|
||||
{
|
||||
struct gsm0808_channel_type ct_msc;
|
||||
struct gsm0808_speech_codec_list scl_ms;
|
||||
struct bsc_msc_data msc_local;
|
||||
int rc;
|
||||
|
||||
printf("============== test_selected_working ==============\n\n");
|
||||
|
||||
init_msc_config(&msc_local);
|
||||
|
||||
make_scl_config(&scl_ms, 6);
|
||||
make_ct_config(&ct_msc, 5);
|
||||
make_msc_config(&msc_local, 7);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
make_scl_config(&scl_ms, 0);
|
||||
make_ct_config(&ct_msc, 5);
|
||||
make_msc_config(&msc_local, 7);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
make_scl_config(&scl_ms, 1);
|
||||
make_ct_config(&ct_msc, 5);
|
||||
make_msc_config(&msc_local, 6);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
free_msc_config(&msc_local);
|
||||
}
|
||||
|
||||
/* Some mixed configurations that can not work */
|
||||
static void test_selected_non_working(void)
|
||||
{
|
||||
struct gsm0808_channel_type ct_msc;
|
||||
struct gsm0808_speech_codec_list scl_ms;
|
||||
struct bsc_msc_data msc_local;
|
||||
int rc;
|
||||
|
||||
printf("============== test_selected_non_working ==============\n\n");
|
||||
|
||||
init_msc_config(&msc_local);
|
||||
|
||||
make_scl_config(&scl_ms, 1);
|
||||
make_ct_config(&ct_msc, 5);
|
||||
make_msc_config(&msc_local, 7);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == -1);
|
||||
|
||||
make_scl_config(&scl_ms, 1);
|
||||
make_ct_config(&ct_msc, 5);
|
||||
make_msc_config(&msc_local, 7);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == -1);
|
||||
|
||||
make_scl_config(&scl_ms, 1);
|
||||
make_ct_config(&ct_msc, 4);
|
||||
make_msc_config(&msc_local, 6);
|
||||
rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local);
|
||||
OSMO_ASSERT(rc == -1);
|
||||
|
||||
free_msc_config(&msc_local);
|
||||
}
|
||||
|
||||
static const struct log_info_cat log_categories[] = {
|
||||
[DMSC] = {
|
||||
.name = "DMSC",
|
||||
.description = "Mobile Switching Center",
|
||||
.enabled = 1,.loglevel = LOGL_NOTICE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct log_info log_info = {
|
||||
.cat = log_categories,
|
||||
.num_cat = ARRAY_SIZE(log_categories),
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ctx = talloc_named_const(NULL, 0, "codec_pref_test");
|
||||
msgb_talloc_ctx_init(ctx, 0);
|
||||
osmo_init_logging2(ctx, &log_info);
|
||||
|
||||
test_one_to_one();
|
||||
test_ms();
|
||||
test_ct();
|
||||
test_msc();
|
||||
test_selected_working();
|
||||
test_selected_non_working();
|
||||
|
||||
printf("Testing execution completed.\n");
|
||||
talloc_free(ctx);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,707 @@
|
|||
============== test_one_to_one ==============
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR1
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=FR1
|
||||
* BSS: audio support settings (1 items):
|
||||
audio_support[0]=FR1
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR1
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=HR1
|
||||
* BSS: audio support settings (1 items):
|
||||
audio_support[0]=HR1
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR2
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=FR2
|
||||
* BSS: audio support settings (1 items):
|
||||
audio_support[0]=FR2
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_EFR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=FR3
|
||||
* BSS: audio support settings (1 items):
|
||||
audio_support[0]=FR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_AMR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=HR3
|
||||
* BSS: audio support settings (1 items):
|
||||
audio_support[0]=HR3
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_AMR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (2 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=HR1
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (2 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=HR1
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (3 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=HR1
|
||||
* MSC: channel type permitted speech (3 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=HR1
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=HR1
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (3 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR3
|
||||
codec[2]->type=HR3
|
||||
* MSC: channel type permitted speech (3 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR3
|
||||
perm_spch[2]=HR3
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR3
|
||||
audio_support[2]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
============== test_ms ==============
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR1
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR1
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR2
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_EFR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_AMR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_AMR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (2 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=HR1
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (3 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=HR1
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (3 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR3
|
||||
codec[2]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
============== test_ct ==============
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=FR1
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=HR1
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=FR2
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_EFR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=FR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_AMR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_AMR
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (3 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=HR1
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (3 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR3
|
||||
perm_spch[2]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
============== test_msc ==============
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (5 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=FR3
|
||||
codec[3]->type=HR1
|
||||
codec[4]->type=HR3
|
||||
* MSC: channel type permitted speech (5 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=FR2
|
||||
perm_spch[2]=FR3
|
||||
perm_spch[3]=HR1
|
||||
perm_spch[4]=HR3
|
||||
* BSS: audio support settings (5 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=FR3
|
||||
audio_support[3]=HR1
|
||||
audio_support[4]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
============== test_selected_working ==============
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (3 items):
|
||||
codec[0]->type=FR1
|
||||
codec[1]->type=FR2
|
||||
codec[2]->type=HR1
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR3
|
||||
audio_support[2]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=FR1
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR3
|
||||
audio_support[2]=HR3
|
||||
* result: rc=0, full_rate=1, chan_mode=SPEECH_V1
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR1
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=HR1
|
||||
* result: rc=0, full_rate=0, chan_mode=SPEECH_V1
|
||||
|
||||
============== test_selected_non_working ==============
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR1
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR3
|
||||
audio_support[2]=HR3
|
||||
* result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR1
|
||||
* MSC: channel type permitted speech (2 items):
|
||||
perm_spch[0]=FR1
|
||||
perm_spch[1]=HR1
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR3
|
||||
audio_support[2]=HR3
|
||||
* result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
|
||||
|
||||
Determining channel mode and rate:
|
||||
* MS: speech codec list (1 items):
|
||||
codec[0]->type=HR1
|
||||
* MSC: channel type permitted speech (1 items):
|
||||
perm_spch[0]=HR3
|
||||
* BSS: audio support settings (3 items):
|
||||
audio_support[0]=FR1
|
||||
audio_support[1]=FR2
|
||||
audio_support[2]=HR1
|
||||
* result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
|
||||
|
||||
Testing execution completed.
|
|
@ -26,6 +26,12 @@ cat $abs_srcdir/bsc/bsc_test.ok > expout
|
|||
AT_CHECK([$abs_top_builddir/tests/bsc/bsc_test], [], [expout], [ignore])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([codec_pref])
|
||||
AT_KEYWORDS([codec_pref])
|
||||
cat $abs_srcdir/codec_pref/codec_pref_test.ok > expout
|
||||
AT_CHECK([$abs_top_builddir/tests/codec_pref/codec_pref_test], [], [expout], [ignore])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([nanobts_omlattr])
|
||||
AT_KEYWORDS([nanobts_omlattr])
|
||||
cat $abs_srcdir/nanobts_omlattr/nanobts_omlattr_test.ok > expout
|
||||
|
|
Loading…
Reference in New Issue