Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/2545 to look at the new patch set (#3). Implement basic Get Attribute responder Add 3GPP TS 52.021 §8.11.2 Get Attribute Response handling: * report OsmoBTS version * report sysmoBTS sub-model * report OsmoBTS variant Change-Id: I09f95ed995fab5def9dc6e8cc201012fba4db28d Related: OS#1614 --- M src/common/oml.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/misc/sysmobts_mgr.c M src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c M src/osmo-bts-sysmo/misc/sysmobts_par.c M src/osmo-bts-sysmo/misc/sysmobts_par.h 6 files changed, 173 insertions(+), 25 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/45/2545/3 diff --git a/src/common/oml.c b/src/common/oml.c index 9d65d83..8f0719e 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -24,6 +24,8 @@ * Operation and Maintainance Messages */ +#include "btsconfig.h" + #include <errno.h> #include <stdarg.h> #include <string.h> @@ -31,6 +33,7 @@ #include <arpa/inet.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/msgb.h> #include <osmocom/gsm/protocol/gsm_12_21.h> #include <osmocom/gsm/abis_nm.h> #include <osmocom/abis/e1_input.h> @@ -148,6 +151,91 @@ get_value_string(abis_nm_obj_class_names, mo->obj_class), mo->obj_inst.bts_nr, mo->obj_inst.trx_nr, mo->obj_inst.ts_nr); return mo_buf; +} + +static inline struct msgb *add_bts_attr(const struct gsm_bts *bts) +{ + struct msgb *a = oml_msgb_alloc(); + + if (!a) + return NULL; + + abis_nm_put_sw_file(a, btstype2str(GSM_BTS_TYPE_OSMOBTS), PACKAGE_VERSION, true); + abis_nm_put_sw_file(a, btsatttr2str(BTS_TYPE_VARIANT), btsvariant2str(bts->variant), true); + + if (bts->sub_model) + abis_nm_put_sw_file(a, btsatttr2str(BTS_SUB_MODEL), bts->sub_model, true); + + return a; +} + +static inline int handle_attr(const struct gsm_abis_mo *mo, const uint8_t *attr, uint16_t attr_len, uint8_t *out) +{ + uint16_t i, r = 1; /* byte 0 is reserved for unsupported attributes counter */ + struct msgb *ba = NULL; + + for (i = 0; i < attr_len; i++) { + switch (attr[i]) { + case NM_ATT_SW_CONFIG: + switch (mo->obj_class) { + case NM_OC_BTS: + ba = add_bts_attr(mo->bts); + break; + default: + LOGP(DOML, LOGL_ERROR, "Unsupported MO class %s in Get Attribute Response\n", + get_value_string(abis_nm_obj_class_names, mo->obj_class)); + return -EINVAL; + } + break; + default: + LOGP(DOML, LOGL_ERROR, "O&M Get Attributes [%u], %s is unsupported.\n", i, + get_value_string(abis_nm_att_names, attr[i])); + out[r] = attr[i]; + r++; + } + } + + if (r - 1 > 255) { + /* The number of attributes in §9.4.26 List of Required Attributes is 2 bytes, but the Count of + not-reported attributes from §9.4.64 is 1 byte */ + LOGP(DOML, LOGL_ERROR, "O&M Get Attributes, Count of not-reported attributes is too big: %u\n", r - 1); + out[0] = 255; + } else + out[0] = r - 1; /* Count of not-reported attributes */ + + if (ba) { + memcpy(out + r, msgb_data(ba), ba->len); + i = r + 1 + ba->len; + msgb_free(ba); + } else + i = r + 1; + + return i; +} + +/* send 3GPP TS 52.021 §8.11.2 Get Attribute Response */ +static int oml_tx_attr_resp(struct gsm_abis_mo *mo, const uint8_t *attr, uint16_t attr_len) +{ + struct msgb *nmsg = oml_msgb_alloc(); + uint8_t resp[MAX_VERSION_LENGTH * attr_len * 2]; /* heuristic for ARI space requirements */ + int len; + + LOGP(DOML, LOGL_INFO, "%s Tx Get Attribute Response\n", gsm_abis_mo_name(mo)); + + if (!nmsg) + return -ENOMEM; + + len = handle_attr(mo, attr, attr_len, resp); + if (len < 0) { + LOGP(DOML, LOGL_ERROR, "Tx Get Attribute Response FAILED with %d\n", len); + msgb_free(nmsg); + return len; + } + + /* §9.4.64 Get Attribute Response Info */ + msgb_tl16v_put(nmsg, NM_ATT_GET_ARI, len, resp); + + return oml_mo_send_msg(mo, nmsg, NM_MT_GET_ATTR_RESP); } /* 8.8.1 sending State Changed Event Report */ @@ -368,6 +456,45 @@ dl_set_t200(&lc->lapdm_dcch.datalink[DL_SAPI3], t200_dcch_sapi3); dl_set_t200(&lc->lapdm_acch.datalink[DL_SAPI0], t200_acch); dl_set_t200(&lc->lapdm_acch.datalink[DL_SAPI3], t200_acch_sapi3); + + return 0; +} + +/* 3GPP TS 52.021 §8.11.1 Get Attributes has been received */ +static int oml_rx_get_attr(struct gsm_bts *bts, struct msgb *msg) +{ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct tlv_parsed tp; + struct gsm_abis_mo *mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); + int rc; + + abis_nm_debugp_foh(DOML, foh); + DEBUGPC(DOML, "Rx GET ATTR\n"); + + rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); + if (rc < 0) { + oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UNSUP_ATTR, "Get Attribute parsing failure"); + return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); + } + + if (!TLVP_PRESENT(&tp, NM_ATT_LIST_REQ_ATTR)) { + LOGP(DOML, LOGL_ERROR, "O&M Get Attributes message without Attribute List?!\n"); + oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UNSUP_ATTR, "Get Attribute without Attribute List"); + return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); + } + + rc = oml_tx_attr_resp(mo, TLVP_VAL(&tp, NM_ATT_LIST_REQ_ATTR), TLVP_LEN(&tp, NM_ATT_LIST_REQ_ATTR)); + if (rc < 0) { + LOGP(DOML, LOGL_ERROR, "Failed to respond to O&M Get Attributes message: %s\n", strerror(-rc)); + switch (-rc) { + case ENOMEM: + return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); + case ENOTSUP: + return oml_fom_ack_nack(msg, NM_NACK_OBJCLASS_NOTSUPP); + default: + return oml_fom_ack_nack(msg, NM_NACK_RES_NOTIMPL); + } + } return 0; } @@ -908,6 +1035,9 @@ case NM_MT_IPACC_SET_ATTR: ret = oml_ipa_set_attr(bts, msg); break; + case NM_MT_GET_ATTR: + ret = oml_rx_get_attr(bts, msg); + break; default: LOGP(DOML, LOGL_INFO, "unknown Formatted O&M msg_type 0x%02x\n", foh->msg_type); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 8eb6fcc..ea7fc93 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1553,7 +1553,7 @@ eeprom_SysInfo_t sysinfo; int val, rc; - rc = sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val); + rc = sysmobts_get_type(&val); if (rc < 0) return rc; fl1h->hw_info.model_nr = val; @@ -1563,7 +1563,7 @@ return rc; fl1h->hw_info.model_flags = val; - rc = sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val); + rc = sysmobts_get_trx(&val); if (rc < 0) return rc; fl1h->hw_info.trx_nr = val; @@ -1839,6 +1839,7 @@ int bts_model_phy_link_open(struct phy_link *plink) { struct phy_instance *pinst = phy_instance_by_num(plink, 0); + struct femtol1_hdl *hdl; struct gsm_bts *bts; OSMO_ASSERT(pinst); @@ -1864,6 +1865,9 @@ bts->c0->nominal_power = rc; } + hdl = pinst->u.sysmobts.hdl; + osmo_strlcpy(bts->sub_model, sysmobts_model(hdl->hw_info.model_nr, hdl->hw_info.trx_nr), sizeof(bts->sub_model)); + phy_link_state_set(plink, PHY_LINK_CONNECTED); return 0; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index e9c59bc..6fadf0f 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -90,13 +90,13 @@ { int rc; - rc = sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &bts_type); + rc = sysmobts_get_type(&bts_type); if (rc < 0) { fprintf(stderr, "Failed to get model number.\n"); return -1; } - rc = sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &trx_number); + rc = sysmobts_get_trx(&trx_number); if (rc < 0) { fprintf(stderr, "Failed to get the trx number.\n"); return -1; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c index f41bec2..48a0312 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c @@ -108,26 +108,7 @@ snprintf(ser_str, sizeof(ser_str), "%d", serno); /* fetch the model and trx number */ - switch(sysmobts_bts_type()) { - case 0: - case 0xffff: - case 1002: - model_name = "sysmoBTS 1002"; - break; - case 2050: - if (sysmobts_trx_number() == 0) - model_name = "sysmoBTS 2050 (master)"; - else if (sysmobts_trx_number() == 1) - model_name = "sysmoBTS 2050 (slave)"; - else - model_name = "sysmoBTS 2050 (unknown)"; - break; - default: - model_name = "Unknown"; - break; - } - - + model_name = sysmobts_model(sysmobts_bts_type(), sysmobts_trx_number()); fetched_info = 1; } diff --git a/src/osmo-bts-sysmo/misc/sysmobts_par.c b/src/osmo-bts-sysmo/misc/sysmobts_par.c index 98fe02b..de81fff 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_par.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_par.c @@ -324,6 +324,37 @@ return 0; } +int sysmobts_get_type(int *bts_type) +{ + return sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, bts_type); +} + +int sysmobts_get_trx(int *trx_number) +{ + return sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, trx_number); +} + +char *sysmobts_model(int bts_type, int trx_num) +{ + switch(bts_type) { + case 0: + case 0xffff: + case 1002: + return "sysmoBTS 1002"; + case 2050: + switch(trx_num) { + case 0: + return "sysmoBTS 2050 (master)"; + case 1: + return "sysmoBTS 2050 (slave)"; + default: + return "sysmoBTS 2050 (unknown)"; + } + default: + return "Unknown"; + } +} + int sysmobts_par_set_net(struct sysmobts_net_cfg *cfg) { struct sysmobts_eeprom *ee = get_eeprom(1); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_par.h b/src/osmo-bts-sysmo/misc/sysmobts_par.h index 5a603cc..52bf67d 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_par.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_par.h @@ -30,7 +30,9 @@ unsigned int size); int sysmobts_par_get_net(struct sysmobts_net_cfg *cfg); int sysmobts_par_set_net(struct sysmobts_net_cfg *cfg); - +int sysmobts_get_type(int *bts_type); +int sysmobts_get_trx(int *trx_number); +char *sysmobts_model(int bts_type, int trx_num); int sysmobts_par_is_int(enum sysmobts_par par); #endif -- To view, visit https://gerrit.osmocom.org/2545 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I09f95ed995fab5def9dc6e8cc201012fba4db28d Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max <msur...@sysmocom.de> Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max <msur...@sysmocom.de>