diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2018-09-13 12:05:51 +0200 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2018-09-24 11:35:52 +0200 |
commit | 67e47c6076fea691345d594977e354538d50566b (patch) | |
tree | af72aeba4e5b5b0625069547d71b2ff12e7fdba1 /src/osmo-bsc | |
parent | 5a43b55a8e749ef020a35679ecc3d75e1d23a8fa (diff) |
codec_pref: Add Codec List to COMPLETE LAYER 3 INFORMATION
The COMPLETE LAYER 3 INFORMATION message lacks the Codec List (BSS Supported)
information element. This information element is mandatory for networks
that use an IP based user plane (AoIP).
- Add function to generate the speech codec list from the current codec
settings (Available codecs)
- Generate and embed information element in L3 Compl. message
Depends: libosmocore I4e656731b16621736c7a2f4e64d9ce63b1064e98
Change-Id: Id6f2af3fdab45bf05f06aec03e222734d7a4cf70
Related: OS#3548
Diffstat (limited to 'src/osmo-bsc')
-rw-r--r-- | src/osmo-bsc/codec_pref.c | 65 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_08_08.c | 9 |
2 files changed, 73 insertions, 1 deletions
diff --git a/src/osmo-bsc/codec_pref.c b/src/osmo-bsc/codec_pref.c index 924f77fe2..c998e6007 100644 --- a/src/osmo-bsc/codec_pref.c +++ b/src/osmo-bsc/codec_pref.c @@ -242,3 +242,68 @@ int match_codec_pref(enum gsm48_chan_mode *chan_mode, return 0; } + +/*! Determine the BSS supported speech codec list that is sent to the MSC with + * the COMPLETE LAYER 3 INFORMATION message. + * \param[out] scl GSM 08.08 speech codec list with BSS supported codecs. + * \param[in] msc associated msc (current codec settings). + * \param[in] bts associated bts (current codec settings). */ +void gen_bss_supported_codec_list(struct gsm0808_speech_codec_list *scl, + const struct bsc_msc_data *msc, const struct gsm_bts *bts) +{ + uint8_t perm_spch; + unsigned int i; + int rc; + uint16_t amr_s15_s0_bts; + uint16_t amr_s15_s0_msc; + uint16_t amr_s15_s0; + const struct gsm48_multi_rate_conf *amr_cfg_bts; + const struct gsm48_multi_rate_conf *amr_cfg_msc; + + memset(scl, 0, sizeof(*scl)); + + for (i = 0; i < msc->audio_length; i++) { + + /* Pick a permitted speech value from the global codec configuration list */ + perm_spch = audio_support_to_gsm88(msc->audio_support[i]); + + /* Check this permitted speech value against the BTS specific parameters. + * if the BTS does not support the codec, try the next one */ + if (!test_codec_support_bts(&bts->codec, perm_spch)) + continue; + + /* Write item into codec list */ + rc = gsm0808_speech_codec_from_chan_type(&scl->codec[scl->len], perm_spch); + if (rc != 0) + continue; + + /* AMR (HR/FR version 3) is the only codec that requires a codec + * configuration (S0-S15). Determine the current configuration and update + * the cfg flag. */ + if (msc->audio_support[i]->ver == 3) { + + /* First lookup the BTS specific AMR rate configuration. Thsi config + * is set via the VTY for each BTS individually. In cases where no + * configuration is set we will assume a safe default */ + if (msc->audio_support[i]->hr) { + amr_cfg_bts = (struct gsm48_multi_rate_conf *)&bts->mr_half.gsm48_ie; + amr_s15_s0_bts = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_bts, false); + } else { + amr_cfg_bts = (struct gsm48_multi_rate_conf *)&bts->mr_full.gsm48_ie; + amr_s15_s0_bts = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_bts, true); + } + + /* At next, lookup the AMR rate configuration that is set for the MSC */ + amr_cfg_msc = &msc->amr_conf; + amr_s15_s0_msc = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_msc, true); + + /* Calculate the intersection of the two configurations and update S0-S15 + * in the codec list. */ + amr_s15_s0 = amr_s15_s0_bts & amr_s15_s0_msc; + scl->codec[scl->len].cfg = amr_s15_s0; + } + + scl->len++; + } +} + diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c index 0d7cdf0d5..807eb8c44 100644 --- a/src/osmo-bsc/gsm_08_08.c +++ b/src/osmo-bsc/gsm_08_08.c @@ -24,6 +24,7 @@ #include <osmocom/bsc/debug.h> #include <osmocom/bsc/paging.h> #include <osmocom/bsc/gsm_08_08.h> +#include <osmocom/bsc/codec_pref.h> #include <osmocom/bsc/gsm_04_80.h> #include <osmocom/bsc/gsm_04_08_rr.h> @@ -446,6 +447,7 @@ static bool complete_layer3(struct gsm_subscriber_connection *conn, char *imsi = NULL; struct msgb *resp; enum bsc_con ret; + struct gsm0808_speech_codec_list scl; /* Check the filter */ rc = bsc_filter_initial(msc->network->bsc_data, msc, conn, msg, @@ -491,7 +493,12 @@ static bool complete_layer3(struct gsm_subscriber_connection *conn, bsc_scan_bts_msg(conn, msg); - resp = gsm0808_create_layer3_2(msg, cgi_for_msc(conn->sccp.msc, conn_get_bts(conn)), NULL); + if (gscon_is_aoip(conn)) { + gen_bss_supported_codec_list(&scl, msc, conn_get_bts(conn)); + resp = gsm0808_create_layer3_2(msg, cgi_for_msc(conn->sccp.msc, conn_get_bts(conn)), &scl); + } else + resp = gsm0808_create_layer3_2(msg, cgi_for_msc(conn->sccp.msc, conn_get_bts(conn)), NULL); + if (!resp) { LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n"); return false; |