summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2024-01-30 03:32:19 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2024-02-06 02:00:01 +0700
commit20107916e504f7238068df8088e785255fc17c81 (patch)
tree773f1f246b1565324e8ec6ea8eb30ee75466d997
parent1b79142f0f1d7aa0e3bd62faf72ba7de7c7ba745 (diff)
mobile: set TRAFFIC.{ind,req} mode during call establishmentpespin/master
Now that we support data (CSD) calls in addition to voice calls, we can no longer initialize the TRAFFIC.{ind,req} routing mode in gsm48_rr_init(). We need to apply the appropriate TCH routing mode *during call establishment* based on its type and the configured I/O handler type. After this patch, one can have the following configuration: tch-voice io-handler l1phy tch-data io-handler unix-sock io-tch-format ti so that the io-handler setting for voice would not affect data calls. Before this patch, the L1 PHY (specifically, Calypso firmware) would not route TRAFFIC.{ind,req} during data calls at all. Thanks to this patch, it's also no longer required to restart the mobile application after changing voice or data I/O handler. Change-Id: Iab68cb47c28380a9c1efc149c6196ea54f75fdb8 Related: OS#4396
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c18
-rw-r--r--src/host/layer23/src/mobile/tch.c12
-rw-r--r--src/host/layer23/src/mobile/tch_data.c7
-rw-r--r--src/host/layer23/src/mobile/tch_voice.c20
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c59
5 files changed, 51 insertions, 65 deletions
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index 4d879d6f..83287c14 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -6996,20 +6996,7 @@ int gsm48_rr_init(struct osmocom_ms *ms)
start_rr_t_meas(rr, 1, 0);
rr->tch_loop_mode = L1CTL_TCH_LOOP_OPEN;
-
- /* Configure audio handling in the L1PHY */
- switch (ms->settings.tch_voice.io_handler) {
- case TCH_VOICE_IOH_L1PHY:
- rr->audio_mode = AUDIO_RX_SPEAKER | AUDIO_TX_MICROPHONE;
- break;
- case TCH_VOICE_IOH_MNCC_SOCK:
- case TCH_VOICE_IOH_LOOPBACK:
- case TCH_VOICE_IOH_GAPK:
- rr->audio_mode = AUDIO_RX_TRAFFIC_IND | AUDIO_TX_TRAFFIC_REQ;
- break;
- case TCH_VOICE_IOH_NONE:
- rr->audio_mode = 0x00;
- }
+ rr->audio_mode = 0x00; /* set in tch_{voice,data}_state_init() */
/* List of notifications about ongoing ASCI calls */
INIT_LLIST_HEAD(&rr->vgcs.notif_list);
@@ -7126,9 +7113,6 @@ int gsm48_rr_audio_mode(struct osmocom_ms *ms, uint8_t mode)
struct gsm48_rrlayer *rr = &ms->rrlayer;
uint8_t ch_type, ch_subch, ch_ts;
- if (ms->settings.tch_voice.io_handler != TCH_VOICE_IOH_NONE)
- return 0;
-
LOGP(DRR, LOGL_INFO, "setting audio mode to %d\n", mode);
rr->audio_mode = mode;
diff --git a/src/host/layer23/src/mobile/tch.c b/src/host/layer23/src/mobile/tch.c
index f63f4878..5acdef2e 100644
--- a/src/host/layer23/src/mobile/tch.c
+++ b/src/host/layer23/src/mobile/tch.c
@@ -133,8 +133,9 @@ int tch_serve_ms(struct osmocom_ms *ms)
static void tch_trans_cstate_active_cb(struct gsm_trans *trans, bool rx_only)
{
struct osmocom_ms *ms = trans->ms;
+ const struct gsm48_rrlayer *rr = &ms->rrlayer;
+ const struct gsm48_rr_cd *cd = &rr->cd_now;
struct tch_state *state;
- enum gsm48_chan_mode ch_mode;
if (ms->tch_state != NULL) {
ms->tch_state->rx_only = rx_only;
@@ -146,8 +147,7 @@ static void tch_trans_cstate_active_cb(struct gsm_trans *trans, bool rx_only)
ms->tch_state = state;
ms->tch_state->rx_only = rx_only;
- ch_mode = ms->rrlayer.cd_now.mode;
- switch (ch_mode) {
+ switch (cd->mode) {
case GSM48_CMODE_SPEECH_V1:
case GSM48_CMODE_SPEECH_EFR:
case GSM48_CMODE_SPEECH_AMR:
@@ -168,12 +168,15 @@ static void tch_trans_cstate_active_cb(struct gsm_trans *trans, bool rx_only)
case GSM48_CMODE_SIGN:
default:
LOGP(DL1C, LOGL_ERROR, "Unhandled channel mode %s\n",
- get_value_string(gsm48_chan_mode_names, ch_mode));
+ get_value_string(gsm48_chan_mode_names, cd->mode));
exit_free:
talloc_free(state);
ms->tch_state = NULL;
return;
}
+
+ /* rr->audio_mode has been set by tch_{voice,data}_state_init(), apply it */
+ gsm48_rr_audio_mode(ms, rr->audio_mode);
}
static void tch_trans_free_cb(struct gsm_trans *trans)
@@ -187,6 +190,7 @@ static void tch_trans_free_cb(struct gsm_trans *trans)
tch_voice_state_free(&state->voice);
else
tch_data_state_free(&state->data);
+ ms->rrlayer.audio_mode = 0x00;
talloc_free(state);
ms->tch_state = NULL;
diff --git a/src/host/layer23/src/mobile/tch_data.c b/src/host/layer23/src/mobile/tch_data.c
index 7f0a330c..b6b3be6a 100644
--- a/src/host/layer23/src/mobile/tch_data.c
+++ b/src/host/layer23/src/mobile/tch_data.c
@@ -36,6 +36,8 @@
#include <osmocom/bb/mobile/transaction.h>
#include <osmocom/bb/mobile/tch.h>
+#include <l1ctl_proto.h>
+
struct csd_v110_frame_desc {
uint16_t num_blocks;
uint16_t num_bits;
@@ -503,6 +505,7 @@ int tch_data_state_init(struct gsm_trans *trans,
struct tch_data_state *state)
{
struct osmocom_ms *ms = trans->ms;
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
const struct gsm_mncc_bearer_cap *bcap = trans->cc.bcap;
int rc;
@@ -514,13 +517,13 @@ int tch_data_state_init(struct gsm_trans *trans,
state->sock = tch_csd_sock_init(ms);
if (state->sock == NULL)
return -ENOMEM;
+ rr->audio_mode = AUDIO_RX_TRAFFIC_IND | AUDIO_TX_TRAFFIC_REQ;
break;
case TCH_DATA_IOH_LOOPBACK:
case TCH_DATA_IOH_NONE:
+ rr->audio_mode = AUDIO_RX_TRAFFIC_IND | AUDIO_TX_TRAFFIC_REQ;
/* we don't need V.110 TA / soft-UART */
return 0;
- default:
- break;
}
if (bcap->data.async) {
diff --git a/src/host/layer23/src/mobile/tch_voice.c b/src/host/layer23/src/mobile/tch_voice.c
index f4bbcfad..a85d7dcb 100644
--- a/src/host/layer23/src/mobile/tch_voice.c
+++ b/src/host/layer23/src/mobile/tch_voice.c
@@ -34,6 +34,8 @@
#include <osmocom/bb/mobile/transaction.h>
#include <osmocom/bb/mobile/tch.h>
+#include <l1ctl_proto.h>
+
/* Forward a Downlink voice frame to the external MNCC handler */
static int tch_forward_mncc(struct osmocom_ms *ms, struct msgb *msg)
{
@@ -119,11 +121,19 @@ int tch_voice_serve_ms(struct osmocom_ms *ms)
int tch_voice_state_init(struct gsm_trans *trans, struct tch_voice_state *state)
{
-#ifdef WITH_GAPK_IO
struct osmocom_ms *ms = trans->ms;
- const struct gsm48_rr_cd *cd = &ms->rrlayer.cd_now;
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+ const struct gsm48_rr_cd *cd = &rr->cd_now;
switch (state->handler) {
+ case TCH_VOICE_IOH_L1PHY:
+ rr->audio_mode = AUDIO_RX_SPEAKER | AUDIO_TX_MICROPHONE;
+ break;
+ case TCH_VOICE_IOH_MNCC_SOCK:
+ case TCH_VOICE_IOH_LOOPBACK:
+ rr->audio_mode = AUDIO_RX_TRAFFIC_IND | AUDIO_TX_TRAFFIC_REQ;
+ break;
+#ifdef WITH_GAPK_IO
case TCH_VOICE_IOH_GAPK:
if ((cd->chan_nr & RSL_CHAN_NR_MASK) == RSL_CHAN_Bm_ACCHs)
state->gapk_io = gapk_io_state_alloc_mode_rate(ms, cd->mode, true);
@@ -131,11 +141,13 @@ int tch_voice_state_init(struct gsm_trans *trans, struct tch_voice_state *state)
state->gapk_io = gapk_io_state_alloc_mode_rate(ms, cd->mode, false);
if (state->gapk_io == NULL)
return -1;
+ rr->audio_mode = AUDIO_RX_TRAFFIC_IND | AUDIO_TX_TRAFFIC_REQ;
break;
- default:
+#endif
+ case TCH_VOICE_IOH_NONE:
+ rr->audio_mode = 0x00;
break;
}
-#endif
return 0;
}
diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c
index 87c80458..eb582d35 100644
--- a/src/host/layer23/src/mobile/vty_interface.c
+++ b/src/host/layer23/src/mobile/vty_interface.c
@@ -2692,23 +2692,6 @@ ALIAS_DEPRECATED(cfg_ms_tch_voice, /* alias to 'tch-voice' */
cfg_ms_audio_cmd,
"audio", "(deprecated alias for 'tch-voice')\n");
-
-static int set_tch_voice_io_handler(struct vty *vty, enum tch_voice_io_handler val)
-{
- struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
- struct gsm_settings *set = &ms->settings;
-
- /* Don't restart on unchanged value */
- if (val == set->tch_voice.io_handler)
- return CMD_SUCCESS;
- set->tch_voice.io_handler = val;
-
- /* Restart required */
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
DEFUN(cfg_ms_tch_voice_io_handler, cfg_ms_tch_voice_io_handler_cmd,
"io-handler (none|gapk|l1phy|mncc-sock|loopback)",
"Set TCH frame I/O handler for voice calls\n"
@@ -2718,8 +2701,9 @@ DEFUN(cfg_ms_tch_voice_io_handler, cfg_ms_tch_voice_io_handler_cmd,
"External MNCC application (e.g. LCR) via MNCC socket\n"
"Return TCH frame payload back to sender\n")
{
- struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
int val = get_string_value(tch_voice_io_handler_names, argv[0]);
+ struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
+ struct gsm_settings *set = &ms->settings;
OSMO_ASSERT(val >= 0);
@@ -2738,13 +2722,20 @@ DEFUN(cfg_ms_tch_voice_io_handler, cfg_ms_tch_voice_io_handler_cmd,
}
#endif
- return set_tch_voice_io_handler(vty, val);
+ set->tch_voice.io_handler = (enum tch_voice_io_handler)val;
+
+ return CMD_SUCCESS;
}
DEFUN(cfg_ms_tch_voice_no_io_handler, cfg_ms_tch_voice_no_io_handler_cmd,
"no io-handler", NO_STR "Disable TCH frame handling for voice calls\n")
{
- return set_tch_voice_io_handler(vty, TCH_VOICE_IOH_NONE);
+ struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->tch_voice.io_handler = TCH_VOICE_IOH_NONE;
+
+ return CMD_SUCCESS;
}
DEFUN(cfg_ms_tch_voice_io_tch_format, cfg_ms_tch_voice_io_tch_format_cmd,
@@ -2805,22 +2796,6 @@ DEFUN(cfg_ms_tch_data,
return CMD_SUCCESS;
}
-static int set_tch_data_io_handler(struct vty *vty, enum tch_data_io_handler val)
-{
- struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
- struct gsm_settings *set = &ms->settings;
-
- /* Don't restart on unchanged value */
- if (val == set->tch_data.io_handler)
- return CMD_SUCCESS;
- set->tch_data.io_handler = val;
-
- /* Restart required */
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
DEFUN(cfg_ms_tch_data_io_handler,
cfg_ms_tch_data_io_handler_cmd,
"io-handler (none|unix-sock|loopback)",
@@ -2830,17 +2805,25 @@ DEFUN(cfg_ms_tch_data_io_handler,
"Return TCH frame payload back to sender\n")
{
int val = get_string_value(tch_data_io_handler_names, argv[0]);
+ struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
+ struct gsm_settings *set = &ms->settings;
OSMO_ASSERT(val >= 0);
+ set->tch_data.io_handler = (enum tch_data_io_handler)val;
- return set_tch_data_io_handler(vty, val);
+ return CMD_SUCCESS;
}
DEFUN(cfg_ms_tch_data_no_io_handler,
cfg_ms_tch_data_no_io_handler_cmd,
"no io-handler", NO_STR "Disable TCH frame handling for data calls\n")
{
- return set_tch_data_io_handler(vty, TCH_DATA_IOH_NONE);
+ struct osmocom_ms *ms = (struct osmocom_ms *)vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->tch_data.io_handler = TCH_DATA_IOH_NONE;
+
+ return CMD_SUCCESS;
}
DEFUN(cfg_ms_tch_data_io_tch_format,