aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/a_iface.c
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2017-06-02 17:48:37 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-06-18 17:50:08 +0200
commit926f84a2a33432091fffc22a6166fbb6df2920e5 (patch)
tree010e7638a876292f949cceebd59d7b23833fff44 /openbsc/src/libmsc/a_iface.c
parent9f15ac5ba06c91086626eff4855848ee80b56d44 (diff)
fixup for: aoip: signal channel type to BSC
The channel type and the speech codec element is now signalled to the BSC. The BSC checks both fields and select a codec by its preference. The choosen speech codec and the choosen channel (type) is returned to the MSC. Currently the MSC ignores the return values
Diffstat (limited to 'openbsc/src/libmsc/a_iface.c')
-rw-r--r--openbsc/src/libmsc/a_iface.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/openbsc/src/libmsc/a_iface.c b/openbsc/src/libmsc/a_iface.c
index 93dcf07ef..a8c040eb7 100644
--- a/openbsc/src/libmsc/a_iface.c
+++ b/openbsc/src/libmsc/a_iface.c
@@ -25,6 +25,7 @@
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm0808_utils.h>
#include <openbsc/debug.h>
#include <openbsc/msc_ifaces.h>
#include <openbsc/a_iface.h>
@@ -195,7 +196,7 @@ static uint8_t convert_Abis_prev_to_A_pref(int radio)
}
/* Assemble the channel type field */
-static void make_channel_type(struct gsm_mncc_bearer_cap *bc, struct gsm0808_channel_type *ct)
+static void enc_channel_type(struct gsm0808_channel_type *ct, const struct gsm_mncc_bearer_cap *bc)
{
unsigned int i;
uint8_t sv;
@@ -223,18 +224,39 @@ static void make_channel_type(struct gsm_mncc_bearer_cap *bc, struct gsm0808_cha
ct->perm_spch_len = count;
if (only_gsm_hr)
- /* Default to full rate, in case only GSM HR V1 is available */
+ /* Note: We must avoid the usage of GSM HR1 as this
+ * codec only offers very poor audio quality. If the
+ * MS only supports GSM HR1 (and full rate), and has
+ * a preference for half rate. Then we will ignore the
+ * preference and assume a preference for full rate. */
ct->ch_rate_type = GSM0808_SPEECH_FULL_BM;
else
ct->ch_rate_type = convert_Abis_prev_to_A_pref(bc->radio);
}
+/* Assemble the speech codec field */
+static int enc_speeach_codec_list(struct gsm0808_speech_codec_list *scl, const struct gsm0808_channel_type *ct)
+{
+ unsigned int i;
+ int rc;
+
+ memset(scl, 0, sizeof(*scl));
+ for (i = 0; i < ct->perm_spch_len; i++) {
+ rc = gsm0808_extrapolate_speech_codec(&scl->codec[i], ct->perm_spch[i]);
+ if (rc != 0)
+ return -EINVAL;
+ }
+ scl->len = i;
+
+ return 0;
+}
+
/* Send assignment request via A-interface */
int a_assign(struct gsm_trans *trans)
{
struct gsm_subscriber_connection *conn;
struct gsm0808_channel_type ct;
- struct gsm0808_speech_codec_list *scl = NULL;
+ struct gsm0808_speech_codec_list scl;
uint32_t *ci_ptr = NULL;
struct msgb *msg;
struct sockaddr_storage rtp_addr;
@@ -244,7 +266,10 @@ int a_assign(struct gsm_trans *trans)
OSMO_ASSERT(conn);
/* Channel type */
- make_channel_type(&trans->bearer_cap, &ct);
+ enc_channel_type(&ct, &trans->bearer_cap);
+
+ /* Speech codec list */
+ enc_speeach_codec_list(&scl, &ct);
/* Package RTP-Address data */
memset(&rtp_addr_in, 0, sizeof(rtp_addr_in));
@@ -255,7 +280,7 @@ int a_assign(struct gsm_trans *trans)
memset(&rtp_addr, 0, sizeof(rtp_addr));
memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in));
- msg = gsm0808_create_ass(&ct, NULL, &rtp_addr, scl, ci_ptr);
+ msg = gsm0808_create_ass(&ct, NULL, &rtp_addr, &scl, ci_ptr);
LOGP(DMSC, LOGL_DEBUG, "N-DATA.req(%u, %s)\n", conn->a.conn_id, osmo_hexdump(msg->data, msg->len));
return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg);