Harald Welte has submitted this change and it was merged. Change subject: rsl: do not allow MODE MODIFY request with unsupp. codec/rate ......................................................................
rsl: do not allow MODE MODIFY request with unsupp. codec/rate When the BSC sends a MODE MODIFY request with an unsupported codec, the BTS must respond with a negative acknowledge. Currently the codec parameter is not checked at all, which may lead into malfunction or crash of the BTS. - Introduce a mechanism to check the codec/rate against a table that is set up in the phy specific code. - Add tables with supported codec/rate combinations for octphy, sysmobts, and trx. Change-Id: Id9b222b7ab19ece90591718bc562b3a8c5e02023 Related: SYS#3212 --- M include/osmo-bts/bts.h M include/osmo-bts/gsm_data.h M src/common/bts.c M src/common/rsl.c M src/osmo-bts-octphy/l1_if.c M src/osmo-bts-sysmo/main.c M src/osmo-bts-trx/main.c M tests/misc/misc_test.c 8 files changed, 106 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 9e16e05..2f63e37 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -45,5 +45,8 @@ int bts_main(int argc, char **argv); +int bts_supports_cm(struct gsm_bts_role_bts *bts, + enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm); + #endif /* _BTS_H */ diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index dcffcf6..853b445 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -33,6 +33,11 @@ struct pcu_sock_state *pcu_state; }; +struct bts_cm { + enum gsm_phys_chan_config pchan; + enum gsm48_chan_mode cm; +}; + /* data structure for BTS related data specific to the BTS role */ struct gsm_bts_role_bts { struct { @@ -89,6 +94,7 @@ bool rtp_jitter_adaptive; struct { uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */ + const struct bts_cm *cm; /* Table with supp. ch rate/mode combinations */ } support; struct { uint8_t tc4_ctr; @@ -146,4 +152,6 @@ bool ts_is_pdch(const struct gsm_bts_trx_ts *ts); +int bts_model_check_cm_mode(enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm); + #endif /* _GSM_DATA_H */ diff --git a/src/common/bts.c b/src/common/bts.c index 6747f50..31afba4 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -675,3 +675,33 @@ return &btsb->gsm_time; } + +int bts_supports_cm(struct gsm_bts_role_bts *bts, + enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm) +{ + const struct bts_cm *supported; + int i; + + supported = bts->support.cm; + + /* Check if we got a list with supported codec, if not, no list has + * been configured yet for that BTS. In that case we will just skip + * and accept any combination */ + if (supported == NULL) + return 1; + + for (i = 0;; i++) { + /* If we manage to find the given combination in the list, + * we know that the pchan/cm combination is supported */ + if (supported[i].pchan == pchan && supported[i].cm == cm) + return 1; + + /* When we hit the terminator, we know that the given + * pchan/cm combination is not supported because it + * is not in the list. */ + if (supported[i].pchan == _GSM_PCHAN_MAX) + return 0; + } + + return 0; +} diff --git a/src/common/rsl.c b/src/common/rsl.c index 3d0993c..2eb0db1 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1278,6 +1278,7 @@ struct gsm_lchan *lchan = msg->lchan; struct rsl_ie_chan_mode *cm; struct tlv_parsed tp; + struct gsm_bts_role_bts *btsb = bts_role_bts(lchan->ts->trx->bts); rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); @@ -1289,6 +1290,11 @@ cm = (struct rsl_ie_chan_mode *) TLVP_VAL(&tp, RSL_IE_CHAN_MODE); lchan_tchmode_from_cmode(lchan, cm); + if (bts_supports_cm(btsb, lchan->ts->pchan, lchan->tch_mode) != 1) { + LOGP(DRSL, LOGL_ERROR, "invalid mode/codec instructed by BSC, check BSC configuration.\n"); + return rsl_tx_mode_modif_nack(lchan, RSL_ERR_SERV_OPT_UNAVAIL); + } + /* 9.3.7 Encryption Information */ if (TLVP_PRESENT(&tp, RSL_IE_ENCR_INFO)) { uint8_t len = TLVP_LEN(&tp, RSL_IE_ENCR_INFO); diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index fce3484..dde993d 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -76,6 +76,14 @@ /* timeout until which we expect PHY to respond */ #define CMD_TIMEOUT 5 +/* Table with channel rate / and codec configuration that are supported + * by the hardware bts_supports_cm() */ +static const struct bts_cm bts_model_supported_cm[] = { + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_V1}, + { GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_V1}, + { _GSM_PCHAN_MAX, 0 } +}; + /* allocate a msgb for a Layer1 primitive */ struct msgb *l1p_msgb_alloc(void) { @@ -776,6 +784,7 @@ bts->variant = BTS_OSMO_OCTPHY; btsb = bts_role_bts(bts); btsb->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + btsb->support.cm = bts_model_supported_cm; /* FIXME: what is the nominal transmit power of the PHY/board? */ bts->c0->nominal_power = 15; diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index ce12d63..f52ecdd 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -55,6 +55,17 @@ #include "hw_misc.h" #include "oml_router.h" +/* Table with channel rate / and codec configuration that are supported + * by the hardware bts_supports_cm() */ +static const struct bts_cm bts_model_supported_cm[] = { + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_V1}, + { GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_V1}, + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_EFR}, + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_AMR}, + { GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_AMR}, + { _GSM_PCHAN_MAX, 0 } +}; + int bts_model_init(struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb; @@ -65,6 +76,7 @@ bts->variant = BTS_OSMO_SYSMO; btsb = bts_role_bts(bts); btsb->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + btsb->support.cm = bts_model_supported_cm; rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd); if (rc < 0) { diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c index a1eb686..973a611 100644 --- a/src/osmo-bts-trx/main.c +++ b/src/osmo-bts-trx/main.c @@ -59,6 +59,17 @@ #include "l1_if.h" #include "trx_if.h" +/* Table with channel rate / and codec configuration that are supported + * by the hardware bts_supports_cm() */ +static const struct bts_cm bts_model_supported_cm[] = { + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_V1}, + { GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_V1}, + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_EFR}, + { GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_AMR}, + { GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_AMR}, + { _GSM_PCHAN_MAX, 0 } +}; + /* dummy, since no direct dsp support */ uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx) { @@ -101,6 +112,7 @@ bts->variant = BTS_OSMO_TRX; btsb->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2); + btsb->support.cm = bts_model_supported_cm; /* FIXME: this needs to be overridden with the real hardrware * value */ diff --git a/tests/misc/misc_test.c b/tests/misc/misc_test.c index c2918fb..00744a6 100644 --- a/tests/misc/misc_test.c +++ b/tests/misc/misc_test.c @@ -157,6 +157,31 @@ } } +static const struct bts_cm bts_model_supported_cm[] = { + {GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_V1}, + {GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_V1}, + {GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_AMR}, + {GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_AMR}, + {_GSM_PCHAN_MAX, 0} +}; + +static void test_bts_supports_cm(void) +{ + struct gsm_bts_role_bts bts; + bts.support.cm = bts_model_supported_cm; + + OSMO_ASSERT(bts_supports_cm + (&bts, GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_V1) == 1); + OSMO_ASSERT(bts_supports_cm + (&bts, GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_V1) == 1); + OSMO_ASSERT(bts_supports_cm + (&bts, GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_EFR) == 0); + OSMO_ASSERT(bts_supports_cm + (&bts, GSM_PCHAN_TCH_F, GSM48_CMODE_SPEECH_AMR) == 1); + OSMO_ASSERT(bts_supports_cm + (&bts, GSM_PCHAN_TCH_H, GSM48_CMODE_SPEECH_AMR) == 1); +} + int main(int argc, char **argv) { bts_log_init(NULL); @@ -164,5 +189,6 @@ test_sacch_get(); test_msg_utils_ipa(); test_msg_utils_oml(); + test_bts_supports_cm(); return EXIT_SUCCESS; } -- To view, visit https://gerrit.osmocom.org/6097 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id9b222b7ab19ece90591718bc562b3a8c5e02023 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter <pma...@sysmocom.de> Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy <axilira...@gmail.com> Gerrit-Reviewer: dexter <pma...@sysmocom.de>