This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Harald Welte gerrit-no-reply at lists.osmocom.org
Review at https://gerrit.osmocom.org/7434
bssmap: State correct speech codec in ASSIGNMENT COMPLETE
Correctly compute the TS 48.008 "speech mode" (codec) for AMR on TCH/F.
There are way too many different ways how to express a given voice
codec. There are two different schemes in TS 48.008 alone, plus one
on TS 48.058 and one in 04.08 / 44.018. Let's avoid unneeded
conversion (that we might get wrong) and avoid storing information in
a sub-struct of the lchan if we can simply derive it from the lchan
at the time we need it.
Also, move BSSAP related encoding/conversion functions closer to the
user (osmo_bsc_bssap), rather than in libbsc.
Without this patch, TCH/F with AMR was erroneously reported as TCH/H
with AMR in the BSSMAP ASSIGNMENT COMPLETE. After this patch, it's
reported correctly.
Change-Id: I6feebfae77fdc93a7ce333a25dd9b9267c5a4a2e
Related: OS#3094
---
M include/osmocom/bsc/bsc_api.h
M include/osmocom/bsc/gsm_data.h
M src/libbsc/bsc_api.c
M src/libbsc/bsc_subscr_conn_fsm.c
M src/osmo-bsc/osmo_bsc_api.c
5 files changed, 93 insertions(+), 110 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/34/7434/1
diff --git a/include/osmocom/bsc/bsc_api.h b/include/osmocom/bsc/bsc_api.h
index 01f90b1..06f8093 100644
--- a/include/osmocom/bsc/bsc_api.h
+++ b/include/osmocom/bsc/bsc_api.h
@@ -21,9 +21,7 @@
void (*dtap)(struct gsm_subscriber_connection *conn, uint8_t link_id,
struct msgb *msg);
/*! \brief BSC->MSC: Assignment of lchan successful */
- void (*assign_compl)(struct gsm_subscriber_connection *conn,
- uint8_t rr_cause, uint8_t chosen_channel,
- uint8_t encr_alg_id, uint8_t speech_mode);
+ void (*assign_compl)(struct gsm_subscriber_connection *conn, uint8_t rr_cause);
/*! \brief BSC->MSC: Assignment of lchan failed */
void (*assign_fail)(struct gsm_subscriber_connection *conn,
uint8_t cause, uint8_t *rr_cause);
@@ -45,9 +43,6 @@
/** Callback for additional actions during conn cleanup */
void (*conn_cleanup)(struct gsm_subscriber_connection *conn);
};
-
-uint8_t lchan_to_chosen_channel(struct gsm_lchan *lchan);
-uint8_t chan_mode_to_speech(struct gsm_lchan *lchan);
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id, int allow_sacch);
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 82a5a51..f743e9c 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -416,9 +416,6 @@
* assignment completed message */
struct {
uint8_t rr_cause;
- uint8_t chosen_channel;
- uint8_t encr_alg_id;
- uint8_t speech_mode;
bool valid;
} ass_compl;
} abis_ip;
diff --git a/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c
index 7482453..142efef 100644
--- a/src/libbsc/bsc_api.c
+++ b/src/libbsc/bsc_api.c
@@ -50,89 +50,6 @@
static void handle_chan_ack(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct gsm_lchan *lchan);
static void handle_chan_nack(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct gsm_lchan *lchan);
-/* GSM 08.08 3.2.2.33 */
-uint8_t lchan_to_chosen_channel(struct gsm_lchan *lchan)
-{
- uint8_t channel_mode = 0, channel = 0;
-
- switch (lchan->tch_mode) {
- case GSM48_CMODE_SPEECH_V1:
- case GSM48_CMODE_SPEECH_EFR:
- case GSM48_CMODE_SPEECH_AMR:
- channel_mode = 0x9;
- break;
- case GSM48_CMODE_SIGN:
- channel_mode = 0x8;
- break;
- case GSM48_CMODE_DATA_14k5:
- channel_mode = 0xe;
- break;
- case GSM48_CMODE_DATA_12k0:
- channel_mode = 0xb;
- break;
- case GSM48_CMODE_DATA_6k0:
- channel_mode = 0xc;
- break;
- case GSM48_CMODE_DATA_3k6:
- channel_mode = 0xd;
- break;
- }
-
- switch (lchan->type) {
- case GSM_LCHAN_NONE:
- channel = 0x0;
- break;
- case GSM_LCHAN_SDCCH:
- channel = 0x1;
- break;
- case GSM_LCHAN_TCH_F:
- channel = 0x8;
- break;
- case GSM_LCHAN_TCH_H:
- channel = 0x9;
- break;
- case GSM_LCHAN_UNKNOWN:
- default:
- LOGP(DMSC, LOGL_ERROR, "Unknown lchan type: %p\n", lchan);
- break;
- }
-
- return channel_mode << 4 | channel;
-}
-
-uint8_t chan_mode_to_speech(struct gsm_lchan *lchan)
-{
- int mode = 0;
-
- switch (lchan->tch_mode) {
- case GSM48_CMODE_SPEECH_V1:
- mode = 1;
- break;
- case GSM48_CMODE_SPEECH_EFR:
- mode = 0x11;
- break;
- case GSM48_CMODE_SPEECH_AMR:
- mode = 0x21;
- break;
- case GSM48_CMODE_SIGN:
- case GSM48_CMODE_DATA_14k5:
- case GSM48_CMODE_DATA_12k0:
- case GSM48_CMODE_DATA_6k0:
- case GSM48_CMODE_DATA_3k6:
- default:
- LOGP(DMSC, LOGL_ERROR, "Using non speech mode: %d\n", mode);
- return 0;
- break;
- }
-
- /* assume to always do AMR HR on any TCH type */
- if (lchan->type == GSM_LCHAN_TCH_H ||
- lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
- mode |= 0x4;
-
- return mode;
-}
-
/*! \brief Determine and apply AMR multi-rate configuration to lchan
* Determine which AMR multi-rate configuration to use and apply it to
* the lchan (so it can be communicated to BTS and MS during channel
@@ -470,10 +387,7 @@
if (is_ipaccess_bts(conn_get_bts(conn)) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
rsl_ipacc_crcx(conn->lchan);
- api->assign_compl(conn, gh->data[0],
- lchan_to_chosen_channel(conn->lchan),
- conn->lchan->encr.alg_id,
- chan_mode_to_speech(conn->lchan));
+ api->assign_compl(conn, gh->data[0]);
}
static void handle_ass_fail(struct gsm_subscriber_connection *conn,
@@ -673,10 +587,7 @@
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
NULL);
} else if (rc >= 0) {
- api->assign_compl(conn, 0,
- lchan_to_chosen_channel(conn->lchan),
- conn->lchan->encr.alg_id,
- chan_mode_to_speech(conn->lchan));
+ api->assign_compl(conn, 0);
}
break;
case GSM48_MT_RR_CLSM_CHG:
diff --git a/src/libbsc/bsc_subscr_conn_fsm.c b/src/libbsc/bsc_subscr_conn_fsm.c
index a2b818b..581395e 100644
--- a/src/libbsc/bsc_subscr_conn_fsm.c
+++ b/src/libbsc/bsc_subscr_conn_fsm.c
@@ -145,12 +145,97 @@
LOGPFSML(fi, LOGL_ERROR, "Unable to deliver SCCP message!\n");
}
+
+/* See TS 48.008 3.2.2.11 Channel Type Octet 5 */
+static int bssap_speech_from_lchan(const struct gsm_lchan *lchan)
+{
+ int mode = 0;
+
+ switch (lchan->type) {
+ case GSM_LCHAN_TCH_H:
+ switch (lchan->tch_mode) {
+ case GSM48_CMODE_SPEECH_V1:
+ return 0x05;
+ case GSM48_CMODE_SPEECH_AMR:
+ return 0x01;
+ default:
+ return -1;
+ }
+ break;
+ case GSM_LCHAN_TCH_F:
+ switch (lchan->tch_mode) {
+ case GSM48_CMODE_SPEECH_V1:
+ return 0x01;
+ case GSM48_CMODE_SPEECH_EFR:
+ return 0x11;
+ case GSM48_CMODE_SPEECH_AMR:
+ return 0x21;
+ default:
+ return -1;
+ }
+ break;
+ default:
+ return -1;
+ }
+}
+
+/* GSM 08.08 3.2.2.33 */
+static uint8_t lchan_to_chosen_channel(struct gsm_lchan *lchan)
+{
+ uint8_t channel_mode = 0, channel = 0;
+
+ switch (lchan->tch_mode) {
+ case GSM48_CMODE_SPEECH_V1:
+ case GSM48_CMODE_SPEECH_EFR:
+ case GSM48_CMODE_SPEECH_AMR:
+ channel_mode = 0x9;
+ break;
+ case GSM48_CMODE_SIGN:
+ channel_mode = 0x8;
+ break;
+ case GSM48_CMODE_DATA_14k5:
+ channel_mode = 0xe;
+ break;
+ case GSM48_CMODE_DATA_12k0:
+ channel_mode = 0xb;
+ break;
+ case GSM48_CMODE_DATA_6k0:
+ channel_mode = 0xc;
+ break;
+ case GSM48_CMODE_DATA_3k6:
+ channel_mode = 0xd;
+ break;
+ }
+
+ switch (lchan->type) {
+ case GSM_LCHAN_NONE:
+ channel = 0x0;
+ break;
+ case GSM_LCHAN_SDCCH:
+ channel = 0x1;
+ break;
+ case GSM_LCHAN_TCH_F:
+ channel = 0x8;
+ break;
+ case GSM_LCHAN_TCH_H:
+ channel = 0x9;
+ break;
+ case GSM_LCHAN_UNKNOWN:
+ default:
+ LOGP(DMSC, LOGL_ERROR, "Unknown lchan type: %p\n", lchan);
+ break;
+ }
+
+ return channel_mode << 4 | channel;
+}
+
/* Generate and send assignment complete message */
static void send_ass_compl(struct gsm_lchan *lchan, struct osmo_fsm_inst *fi)
{
struct msgb *resp;
struct gsm0808_speech_codec sc;
struct gsm_subscriber_connection *conn;
+ int perm_spch = bssap_speech_from_lchan(lchan);
conn = lchan->conn;
@@ -160,13 +245,13 @@
LOGPFSML(fi, LOGL_DEBUG, "Sending assignment complete message... (id=%i)\n", conn->sccp.conn_id);
/* Extrapolate speech codec from speech mode */
- gsm0808_speech_codec_from_chan_type(&sc, lchan->abis_ip.ass_compl.speech_mode);
+ gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
+ /* FIXME: AMR codec configuration must be derived from lchan1! */
/* Generate message */
resp = gsm0808_create_ass_compl(lchan->abis_ip.ass_compl.rr_cause,
- lchan->abis_ip.ass_compl.chosen_channel,
- lchan->abis_ip.ass_compl.encr_alg_id,
- lchan->abis_ip.ass_compl.speech_mode,
+ lchan_to_chosen_channel(lchan),
+ lchan->encr.alg_id, perm_spch,
&conn->user_plane.aoip_rtp_addr_local, &sc, NULL);
if (!resp) {
diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c
index 40c06dd..9c519a4 100644
--- a/src/osmo-bsc/osmo_bsc_api.c
+++ b/src/osmo-bsc/osmo_bsc_api.c
@@ -410,17 +410,12 @@
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MO_DTAP, msg);
}
-static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause,
- uint8_t chosen_channel, uint8_t encr_alg_id,
- uint8_t speech_model)
+static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause)
{
if (!msc_connected(conn))
return;
conn->lchan->abis_ip.ass_compl.rr_cause = rr_cause;
- conn->lchan->abis_ip.ass_compl.chosen_channel = chosen_channel;
- conn->lchan->abis_ip.ass_compl.encr_alg_id = encr_alg_id;
- conn->lchan->abis_ip.ass_compl.speech_mode = speech_model;
if (is_ipaccess_bts(conn_get_bts(conn)) && conn->user_plane.rtp_ip) {
/* NOTE: In a network that makes use of an IPA base station
--
To view, visit https://gerrit.osmocom.org/7434
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6feebfae77fdc93a7ce333a25dd9b9267c5a4a2e
Gerrit-PatchSet: 1
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>