From defb6c95c14e95133891312b65436eef5964e0a3 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 15 May 2017 10:29:54 +0200 Subject: Get basic BTS attributes Request BTS attributes via OML on connection and parse the response: request/parse incoming response as sw-config. Note: only basic BTS-wide KV attributes wrapped in sw-config are supported for now. Change-Id: I589be51daca0cb9e1f3473b93e910e46b06e23ae Related: OS#1614 --- openbsc/src/libbsc/abis_nm.c | 71 +++++++++++++++++++++++++++++++++++++++++++ openbsc/src/libbsc/bsc_init.c | 6 ++++ 2 files changed, 77 insertions(+) (limited to 'openbsc/src') diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 5212f6a40..ec1e47826 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -439,6 +439,74 @@ int abis_nm_select_newest_sw(const struct abis_nm_sw_desc *sw_descr, return res; } +static inline bool handle_attr(struct gsm_bts *bts, enum bts_attribute id, uint8_t *val, uint8_t len) +{ + switch (id) { + case BTS_TYPE_VARIANT: + LOGP(DNM, LOGL_ERROR, "BTS reported variant: %s\n", val); + break; + case BTS_SUB_MODEL: + LOGP(DNM, LOGL_ERROR, "BTS reported submodel: %s\n", val); + break; + default: + return false; + } + return true; +} + +/* Handle 3GPP TS 52.021 §9.4.64 Get Attribute Response Info */ +static int abis_nm_rx_get_attr_resp(struct msgb *mb, struct gsm_bts *bts) +{ + struct abis_om_hdr *oh = msgb_l2(mb); + struct abis_om_fom_hdr *foh = msgb_l3(mb); + struct e1inp_sign_link *sign_link = mb->dst; + struct tlv_parsed tp; + const uint8_t *ari; + uint8_t unreported, i; + uint16_t ari_len; + int rc; + struct abis_nm_sw_desc sw_descr[MAX_BTS_ATTR]; + + abis_nm_debugp_foh(DNM, foh); + + DEBUGPC(DNM, "Get Attributes Response\n"); + + abis_nm_tlv_parse(&tp, sign_link->trx->bts, foh->data, oh->length-sizeof(*foh)); + + if (!TLVP_PRESENT(&tp, NM_ATT_GET_ARI)) { + LOGP(DNM, LOGL_ERROR, "Get Attributes Response without Response Info?!\n"); + return -EINVAL; + } + + ari = TLVP_VAL(&tp, NM_ATT_GET_ARI); + ari_len = TLVP_LEN(&tp, NM_ATT_GET_ARI); + /* Attributes Response Info has peculiar structure - first the number of unreported attributes */ + unreported = ari[0]; + DEBUGP(DNM, "Found Get Attributes Response Info: %u bytes total with %u unreported attributes\n", + ari_len, unreported); + + /* than the list of unreported attributes */ + for (i = 0; i < unreported; i++) + LOGP(DNM, LOGL_ERROR, "Attribute %s is unreported\n", /* +1 because we have to account for number of */ + get_value_string(abis_nm_att_names, ari[i + 1])); /* unreported attributes, prefixing the list. */ + + /* after that there's finally list of replies in form of sw-conf structure: + it starts right after the list of unreported attributes + space for length of that list */ + rc = abis_nm_get_sw_conf(ari + unreported + 1, ari_len - (unreported + 2), &sw_descr[0], ARRAY_SIZE(sw_descr)); + if (rc > 0) { + for (i = 0; i < rc; i++) { + if (!handle_attr(bts, str2btsattr((const char *)sw_descr[i].file_id), sw_descr[i].file_version, + sw_descr[i].file_version_len)) + LOGP(DNM, LOGL_NOTICE, "ARI reported sw[%d/%d]: %s is %s\n", + i, rc, sw_descr[i].file_id, sw_descr[i].file_version); + } + } else + LOGP(DNM, LOGL_ERROR, "Failed to parse SW-Config part of Get Attribute Response Info: %s\n", + strerror(-rc)); + + return 0; +} + /* 3GPP TS 52.021 §6.2.5 */ static int abis_nm_rx_sw_act_req(struct msgb *mb) { @@ -651,6 +719,9 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb) break; case NM_MT_SET_BTS_ATTR_ACK: break; + case NM_MT_GET_ATTR_RESP: + ret = abis_nm_rx_get_attr_resp(mb, bts); + break; default: abis_nm_debugp_foh(DNM, foh); LOGPC(DNM, LOGL_ERROR, "Unhandled message %s\n", diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 521fc891f..cda435044 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -310,6 +310,10 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal, struct input_signal_data *isd = signal_data; struct gsm_bts_trx *trx = isd->trx; int ts_no, lchan_no; + const uint8_t attr[] = { NM_ATT_SW_CONFIG, }; + + /* we should not request more attributes than we're ready to handle */ + OSMO_ASSERT(sizeof(attr) < MAX_BTS_ATTR); if (subsys != SS_L_INPUT) return -EINVAL; @@ -333,6 +337,8 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal, for (i = 0; i < ARRAY_SIZE(cur_trx->ts); i++) generate_ma_for_ts(&cur_trx->ts[i]); } + + abis_nm_get_attr(trx->bts, NM_OC_BTS, trx->bts->nr, trx->nr, 0xFF, attr, sizeof(attr)); } if (isd->link_type == E1INP_SIGN_RSL) bootstrap_rsl(trx); -- cgit v1.2.3