summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/src
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2024-01-30 03:20:07 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2024-02-06 01:59:39 +0700
commit1b79142f0f1d7aa0e3bd62faf72ba7de7c7ba745 (patch)
tree9a291a3437d9df6962dac0689173188394b3bce5 /src/host/layer23/src
parentb512a08a7cfbe6ec829da0c03f61fe3a0e2f0905 (diff)
mobile: init TCH state earlier (on receipt of CC ALERTING)
During a Mobile Originating voice call, we would normally start receiving traffic indications with ringback tone (or even some melody) before the call gets CONNECTed. So in order for the user to be able to hear that, we need to init the voice call handler earlier (on receipt of CC ALERTING message). We should not be transmitting voice/data frames before the call gets CONNECTed, so add 'rx_only' flag to the TCH state. In tch_send_msg() drop msgb if this flag is set. Rx only mode makes no sense for data calls, so in tch_recv_cb() we discard received DL frames and thus do not trigger sending UL frames. Change-Id: Idd32c823639cc1f9999d77fcefe7e260e31a85ec Related: OS#4396
Diffstat (limited to 'src/host/layer23/src')
-rw-r--r--src/host/layer23/src/mobile/tch.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/host/layer23/src/mobile/tch.c b/src/host/layer23/src/mobile/tch.c
index 70c9163c..f63f4878 100644
--- a/src/host/layer23/src/mobile/tch.c
+++ b/src/host/layer23/src/mobile/tch.c
@@ -51,24 +51,35 @@ int tch_voice_serve_ms(struct osmocom_ms *ms);
static int tch_recv_cb(struct osmocom_ms *ms, struct msgb *msg)
{
struct tch_state *state = ms->tch_state;
- int rc;
if (state == NULL) {
msgb_free(msg);
return 0;
}
- if (state->is_voice)
- rc = tch_voice_recv(ms, msg);
- else
- rc = tch_data_recv(ms, msg);
- return rc;
+ if (state->is_voice) {
+ return tch_voice_recv(ms, msg);
+ } else {
+ /* Rx only mode makes no sense for data calls, so we discard
+ * received DL frames and thus do not trigger sending UL frames. */
+ if (!state->rx_only)
+ return tch_data_recv(ms, msg);
+ msgb_free(msg);
+ return 0;
+ }
}
/* Send an Uplink voice frame to the lower layers */
int tch_send_msg(struct osmocom_ms *ms, struct msgb *msg)
{
- /* Forward to RR */
+ struct tch_state *state = ms->tch_state;
+
+ if (state == NULL || state->rx_only) {
+ /* TODO: fix callers and print a warning here */
+ msgb_free(msg);
+ return -EIO;
+ }
+
return gsm48_rr_tx_traffic(ms, msg);
}
@@ -119,18 +130,21 @@ int tch_serve_ms(struct osmocom_ms *ms)
return rc;
}
-static void tch_trans_cstate_active_cb(struct gsm_trans *trans)
+static void tch_trans_cstate_active_cb(struct gsm_trans *trans, bool rx_only)
{
struct osmocom_ms *ms = trans->ms;
struct tch_state *state;
enum gsm48_chan_mode ch_mode;
- if (ms->tch_state != NULL)
+ if (ms->tch_state != NULL) {
+ ms->tch_state->rx_only = rx_only;
return; /* TODO: handle modify? */
+ }
state = talloc_zero(ms, struct tch_state);
OSMO_ASSERT(state != NULL);
ms->tch_state = state;
+ ms->tch_state->rx_only = rx_only;
ch_mode = ms->rrlayer.cd_now.mode;
switch (ch_mode) {
@@ -181,8 +195,11 @@ static void tch_trans_free_cb(struct gsm_trans *trans)
static void tch_trans_state_chg_cb(struct gsm_trans *trans)
{
switch (trans->cc.state) {
- case GSM_CSTATE_ACTIVE:
- tch_trans_cstate_active_cb(trans);
+ case GSM_CSTATE_CALL_DELIVERED: /* MO call: Rx CC ALERTING */
+ tch_trans_cstate_active_cb(trans, true);
+ break;
+ case GSM_CSTATE_ACTIVE: /* MO/MT call: Rx CC CONNECT */
+ tch_trans_cstate_active_cb(trans, false);
break;
case GSM_CSTATE_NULL:
tch_trans_free_cb(trans);