diff options
author | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2020-06-15 02:29:57 +0700 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2020-06-29 08:51:11 +0000 |
commit | 842e4fab44434ef60b12f56d175fe5a13d7cd4bc (patch) | |
tree | 907fe259d0bbc6850784e96770b62b645bebe6e0 | |
parent | f23d83583139f58b78ad4f57f2eab629e1dd3a1e (diff) |
A-bis/OML: handle hopping params in Set Channel Attributes
Change-Id: Ieac26c7aca118c16889cdde2565a514681dc137b
Related: OS#4546
-rw-r--r-- | include/osmo-bts/gsm_data.h | 12 | ||||
-rw-r--r-- | src/common/gsm_data.c | 5 | ||||
-rw-r--r-- | src/common/oml.c | 46 |
3 files changed, 42 insertions, 21 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 255c871d..7b4d4569 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -350,17 +350,13 @@ struct gsm_bts_trx_ts { uint8_t nm_chan_comb; int tsc; /* -1 == use BTS TSC */ + /* Frequency hopping parameters (configured via OML) */ struct { - /* Parameters below are configured by VTY */ - int enabled; + bool enabled; uint8_t maio; uint8_t hsn; - struct bitvec arfcns; - uint8_t arfcns_data[1024/8]; - /* This is the pre-computed MA for channel assignments */ - struct bitvec ma; - uint8_t ma_len; /* part of ma_data that is used */ - uint8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */ + uint16_t ma[64]; + uint8_t ma_len; } hopping; struct gsm_lchan lchan[TS_MAX_LCHAN]; diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c index ae604ec0..72394409 100644 --- a/src/common/gsm_data.c +++ b/src/common/gsm_data.c @@ -228,11 +228,6 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) gsm_mo_init(&ts->mo, bts, NM_OC_CHANNEL, bts->nr, trx->nr, ts->nr); - ts->hopping.arfcns.data_len = sizeof(ts->hopping.arfcns_data); - ts->hopping.arfcns.data = ts->hopping.arfcns_data; - ts->hopping.ma.data_len = sizeof(ts->hopping.ma_data); - ts->hopping.ma.data = ts->hopping.ma_data; - for (l = 0; l < TS_MAX_LCHAN; l++) { struct gsm_lchan *lchan; char *name; diff --git a/src/common/oml.c b/src/common/oml.c index 28fa066e..5f64d526 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -872,7 +872,7 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) struct abis_om_fom_hdr *foh = msgb_l3(msg); struct gsm_bts *bts = ts->trx->bts; struct tlv_parsed tp, *tp_merged; - int rc; + int rc, i; DEBUGPFOH(DOML, foh, "Rx SET CHAN ATTR\n"); @@ -883,11 +883,39 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); } - /* 9.4.21 HSN... */ - /* 9.4.27 MAIO */ + /* Check frequency hopping parameters (HSN, MAIO, ARFCN list) */ if (TLVP_PRESENT(&tp, NM_ATT_HSN) || TLVP_PRESENT(&tp, NM_ATT_MAIO)) { - LOGPFOH(DOML, LOGL_NOTICE, foh, "SET CHAN ATTR: Frequency hopping not supported.\n"); - return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); + if (!osmo_bts_has_feature(bts->features, BTS_FEAT_HOPPING)) { + LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: Frequency hopping not supported.\n"); + return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); + } + + if (!TLVP_PRES_LEN(&tp, NM_ATT_HSN, 1) || !TLVP_PRES_LEN(&tp, NM_ATT_MAIO, 1)) { + LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: HSN and/or MAIO is missing: " + "hsn=%u, maio=%u\n", TLVP_LEN(&tp, NM_ATT_HSN), TLVP_LEN(&tp, NM_ATT_MAIO)); + return oml_fom_ack_nack(msg, NM_NACK_ATTRLIST_INCONSISTENT); + } + + if (!TLVP_PRES_LEN(&tp, NM_ATT_ARFCN_LIST, 2)) { /* At least one ARFCN */ + LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: ARFCN list is missing\n"); + return oml_fom_ack_nack(msg, NM_NACK_ATTRLIST_INCONSISTENT); + } + + if (TLVP_LEN(&tp, NM_ATT_ARFCN_LIST) > sizeof(ts->hopping.ma)) { + LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: ARFCN list is too long\n"); + return oml_fom_ack_nack(msg, NM_NACK_ATTRLIST_INCONSISTENT); + } else if (TLVP_LEN(&tp, NM_ATT_ARFCN_LIST) % 2 != 0) { + LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: ARFCN list has odd length\n"); + return oml_fom_ack_nack(msg, NM_NACK_ATTRLIST_INCONSISTENT); + } + + ts->hopping.enabled = true; + ts->hopping.hsn = *TLVP_VAL(&tp, NM_ATT_HSN); + ts->hopping.maio = *TLVP_VAL(&tp, NM_ATT_MAIO); + + ts->hopping.ma_len = TLVP_LEN(&tp, NM_ATT_ARFCN_LIST) / sizeof(uint16_t); + for (i = 0; i < ts->hopping.ma_len; i++) + ts->hopping.ma[i] = osmo_load16be(TLVP_VAL(&tp, NM_ATT_ARFCN_LIST) + i * 2); } /* 9.4.52 Starting Time */ @@ -928,8 +956,6 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) } } - /* 9.4.5 ARFCN List */ - /* 9.4.60 TSC */ if (TLVP_PRES_LEN(&tp, NM_ATT_TSC, 1)) { ts->tsc = *TLVP_VAL(&tp, NM_ATT_TSC); @@ -937,8 +963,12 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) /* If there is no TSC specified, use the BCC */ ts->tsc = BSIC2BCC(bts->bsic); } - LOGPFOH(DOML, LOGL_INFO, foh, "SET CHAN ATTR (TSC=%u pchan=%s)\n", + LOGPFOH(DOML, LOGL_INFO, foh, "SET CHAN ATTR (TSC=%u pchan=%s", ts->tsc, gsm_pchan_name(ts->pchan)); + if (ts->hopping.enabled) + LOGPC(DOML, LOGL_INFO, " hsn=%u maio=%u ma_len=%u", + ts->hopping.hsn, ts->hopping.maio, ts->hopping.ma_len); + LOGPC(DOML, LOGL_INFO, ")\n"); /* call into BTS driver to apply new attributes to hardware */ return bts_model_apply_oml(bts, msg, tp_merged, NM_OC_CHANNEL, ts); |