diff --git a/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h b/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h index dd97a0a76..9f51efd8b 100644 --- a/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h +++ b/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h @@ -23,12 +23,19 @@ #include #include +#include struct gsm_bts_sm; struct gsm_bts; struct gsm_bts_trx; struct gsm_gprs_nsvc; +extern const struct tlv_definition ipacc_eie_tlv_def; + +int ipacc_parse_supp_features(const struct gsm_bts *bts, + const struct abis_om_fom_hdr *foh, + const uint8_t *data, uint16_t data_len); + struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts); struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm); struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts); diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c index aa6a3a54e..1b544feb5 100644 --- a/src/osmo-bsc/abis_nm.c +++ b/src/osmo-bsc/abis_nm.c @@ -52,6 +52,7 @@ #include #include #include +#include #define OM_ALLOC_SIZE 1024 #define OM_HEADROOM_SIZE 128 @@ -560,7 +561,6 @@ static inline const uint8_t *parse_attr_resp_info_unreported(const struct abis_o return ari + num_unreported + 1; /* we have to account for 1st byte with number of unreported attributes */ } - /* Parse Attribute Response Info content for 3GPP TS 52.021 ยง9.4.30 Manufacturer Id */ static void parse_osmo_bts_features(struct gsm_bts *bts, const uint8_t *data, uint16_t data_len) @@ -618,6 +618,12 @@ static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_t parse_osmo_bts_features(bts, TLVP_VAL(tp, NM_ATT_MANUF_ID), TLVP_LEN(tp, NM_ATT_MANUF_ID)); } + /* fall-through */ + case GSM_BTS_TYPE_NANOBTS: + if (TLVP_PRESENT(tp, NM_ATT_IPACC_SUPP_FEATURES)) { + ipacc_parse_supp_features(bts, foh, TLVP_VAL(tp, NM_ATT_IPACC_SUPP_FEATURES), + TLVP_LEN(tp, NM_ATT_IPACC_SUPP_FEATURES)); + } break; default: break; diff --git a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c index d78f23baa..c65b701e6 100644 --- a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c +++ b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c @@ -26,6 +26,73 @@ #include #include +const struct tlv_definition ipacc_eie_tlv_def = { + .def = { + /* TODO: add more values from enum ipac_eie */ + [NM_IPAC_EIE_FREQ_BANDS] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_MAX_TA] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_CIPH_ALGOS] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_CHAN_TYPES] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_CHAN_MODES] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_GPRS_CODING] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_RTP_FEATURES] = { TLV_TYPE_TL16V }, + [NM_IPAC_EIE_RSL_FEATURES] = { TLV_TYPE_TL16V }, + } +}; + +static inline uint32_t ipacc_parse_supp_flags(const struct abis_om_fom_hdr *foh, + const struct value_string *flags, + const struct tlv_p_entry *e, + const char *text) +{ + uint32_t u32 = 0; + + for (unsigned int i = 0; i < OSMO_MAX(e->len, 4); i++) + u32 |= e->val[i] << (i * 8); + for (const struct value_string *vs = flags; vs->value && vs->str; vs++) { + if (u32 & vs->value) + LOGPFOH(DNM, LOGL_DEBUG, foh, "%s '%s' is supported\n", text, vs->str); + } + + return u32; +} + +/* Parse ip.access Supported Features IE */ +int ipacc_parse_supp_features(const struct gsm_bts *bts, + const struct abis_om_fom_hdr *foh, + const uint8_t *data, uint16_t data_len) +{ + const struct tlv_p_entry *e; + struct tlv_parsed tp; + + if (tlv_parse(&tp, &ipacc_eie_tlv_def, data, data_len, 0, 0) < 0) { + LOGPFOH(DNM, LOGL_ERROR, foh, "%s(): tlv_parse failed\n", __func__); + return -EINVAL; + } + + /* TODO: store the flags in the respective MO state */ + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_FREQ_BANDS)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_freq_band_desc, e, "Freq. band"); + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CIPH_ALGOS)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_ciph_algo_desc, e, "Ciphering algorithm"); + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CHAN_TYPES)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_chant_desc, e, "Channel type"); + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CHAN_MODES)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_chanm_desc, e, "Channel mode"); + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_GPRS_CODING)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_gprs_coding_desc, e, "GPRS Coding Scheme"); + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_RTP_FEATURES)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_rtp_feat_desc, e, "RTP Feature"); + if ((e = TLVP_GET(&tp, NM_IPAC_EIE_RSL_FEATURES)) != NULL) + ipacc_parse_supp_flags(foh, abis_nm_ipacc_rsl_feat_desc, e, "RSL Feature"); + if (TLVP_PRES_LEN(&tp, NM_IPAC_EIE_MAX_TA, 1)) { + uint8_t u8 = *TLVP_VAL(&tp, NM_IPAC_EIE_MAX_TA); + LOGPFOH(DNM, LOGL_DEBUG, foh, "Max Timing Advance %u\n", u8); + } + + return 0; +} + /* 3GPP TS 52.021 section 8.6.1 Set BTS Attributes */ struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts) {