summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-05-11 05:11:44 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2018-10-03 18:43:07 +0700
commit33c61fb11bd9fd6341365e1c355db445bd626fb3 (patch)
treee7eb2d7b65cb7e7fb3f94d54087d25e9f876b98c
parentff38b29d2ef1a7a48be6541b4053e36e7fd2fdf5 (diff)
mobile/gsm48_rr.c: properly handle CHANNEL MODE MODIFY
According to 3GPP TS 04.08, section 3.4.6.1.3 "Abnormal cases" of "channel mode modify procedure", if the MS doesn't support the indicated channel mode, it shall retain the old mode and return the associated channel mode information in the ACKNOWLEDGE message. Previously, if an indicated mode is not supported, we used to indicate the 'CHAN_MODE_UNACCT' RR case without sending the ACKNOWLEDGE message. Also, the result of gsm48_rr_set_mode() was ignored. Let's fix this! Change-Id: I952436ec796273e56341f9d3492b4a3b3a5dc410
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index c8fb057c..b00674d4 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -3569,7 +3569,7 @@ static int gsm48_rr_rx_chan_modify(struct osmocom_ms *ms, struct msgb *msg)
int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
struct gsm48_rr_cd *cd = &rr->cd_now;
uint8_t ch_type, ch_subch, ch_ts;
- uint8_t cause;
+ int rc;
LOGP(DRR, LOGL_INFO, "CHANNEL MODE MODIFY\n");
@@ -3601,14 +3601,30 @@ static int gsm48_rr_rx_chan_modify(struct osmocom_ms *ms, struct msgb *msg)
gsm_print_arfcn(cd->arfcn), ch_ts, ch_subch, cd->tsc,
cm->mode);
}
- /* mode */
- cause = gsm48_rr_check_mode(ms, cd->chan_nr, cm->mode);
- if (cause)
- return gsm48_rr_tx_rr_status(ms, cause);
+
+ /**
+ * According to 3GPP TS 04.08, section 3.4.6.1.3
+ * "Abnormal cases" of "channel mode modify procedure",
+ * if the MS doesn't support the indicated channel mode,
+ * it shall retain the old mode and return the associated
+ * channel mode information in the ACKNOWLEDGE message.
+ */
+
+ /* Check if we support this channel mode */
+ rc = gsm48_rr_check_mode(ms, cd->chan_nr, cm->mode);
+ if (rc)
+ goto ack;
+
+ /* Attempt to apply this mode */
+ rc = gsm48_rr_set_mode(ms, cd->chan_nr, cm->mode);
+ if (rc)
+ goto ack;
+
+ /* Finally set (a new) mode */
cd->mode = cm->mode;
- gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode);
- return gsm48_rr_tx_chan_modify_ack(ms, &cm->chan_desc, cm->mode);
+ack:
+ return gsm48_rr_tx_chan_modify_ack(ms, &cm->chan_desc, cd->mode);
}
/* 9.1.3 sending ASSIGNMENT COMPLETE */