From ba0a12233fca0187864cd2af6a428e3f40fd85fa Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Wed, 18 Mar 2020 12:39:30 +0100 Subject: VTY: add show bts failure report Save OML failure reports from each BTS. Add a VTY command to display them conveniently and optionally clear the list. OsmoBSC> show bts 0 fail-rep [2020-03-23 14:51:22] Type=processing failure, Severity=minor failure, Probable cause=Manufacturer specific values: Software warning, Additional text=test message sent from VTY [2020-03-23 14:51:19] Type=processing failure, Severity=minor failure, Probable cause=Manufacturer specific values: Software warning, Additional text=test message sent from VTY Related: OS#1605 Change-Id: I18aa17a721cd5eb1c98926dc2367229c0a50bc78 --- include/osmocom/bsc/gsm_data.h | 8 ++++++ src/osmo-bsc/abis_nm.c | 15 ++++++++++ src/osmo-bsc/bsc_vty.c | 62 ++++++++++++++++++++++++++++++++++++++++++ src/osmo-bsc/gsm_data.c | 1 + 4 files changed, 86 insertions(+) diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index 5afc2cfce..259517485 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -1005,6 +1005,12 @@ struct bts_smscb_chan_state { uint8_t overflow; }; +struct bts_oml_fail_rep { + struct llist_head list; + time_t time; + struct msgb *mb; +}; + /* One BTS */ struct gsm_bts { /* list header in net->bts_list */ @@ -1267,6 +1273,8 @@ struct gsm_bts { struct bts_smscb_chan_state cbch_basic; struct bts_smscb_chan_state cbch_extended; struct osmo_timer_list etws_timer; /* when to stop ETWS PN */ + + struct llist_head oml_fail_rep; }; /* One rejected BTS */ diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c index 07effd38a..32e9a8faf 100644 --- a/src/osmo-bsc/abis_nm.c +++ b/src/osmo-bsc/abis_nm.c @@ -412,6 +412,21 @@ static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) int rc = 0; const uint8_t *p_val; const char *e_type, *severity, *p_text; + struct bts_oml_fail_rep *entry; + + /* Store copy in bts->oml_fail_rep */ + entry = talloc_zero(bts, struct bts_oml_fail_rep); + OSMO_ASSERT(entry); + entry->time = time(NULL); + entry->mb = msgb_copy_c(entry, mb, "OML failure report"); + llist_add(&entry->list, &bts->oml_fail_rep); + + /* Limit list size */ + if (llist_count(&bts->oml_fail_rep) > 50) { + struct bts_oml_fail_rep *old = llist_last_entry(&bts->oml_fail_rep, struct bts_oml_fail_rep, list); + llist_del(&old->list); + talloc_free(old); + } sd = abis_nm_fail_evt_rep_parse(mb, bts); if (!sd) { diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c index 39adb21ac..e9085b329 100644 --- a/src/osmo-bsc/bsc_vty.c +++ b/src/osmo-bsc/bsc_vty.c @@ -559,6 +559,67 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", return CMD_SUCCESS; } +DEFUN(show_bts_fail_rep, show_bts_fail_rep_cmd, "show bts <0-255> fail-rep [reset]", + SHOW_STR "Display information about a BTS\n" + "BTS number\n" "OML failure reports\n" + "Clear the list of failure reports after showing them\n") +{ + struct gsm_network *net = gsmnet_from_vty(vty); + struct bts_oml_fail_rep *entry; + struct gsm_bts *bts; + int bts_nr; + + bts_nr = atoi(argv[0]); + if (bts_nr >= net->num_bts) { + vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + bts = gsm_bts_num(net, bts_nr); + if (llist_empty(&bts->oml_fail_rep)) { + vty_out(vty, "No failure reports received.%s", VTY_NEWLINE); + return CMD_SUCCESS; + } + + llist_for_each_entry(entry, &bts->oml_fail_rep, list) { + struct nm_fail_rep_signal_data *sd; + char timestamp[20]; /* format like 2020-03-23 14:24:00 */ + enum abis_nm_pcause_type pcause; + enum abis_mm_event_causes cause; + + strftime(timestamp, sizeof(timestamp), "%F %T", localtime(&entry->time)); + sd = abis_nm_fail_evt_rep_parse(entry->mb, bts); + if (!sd) { + vty_out(vty, "[%s] (failed to parse report)%s", timestamp, VTY_NEWLINE); + continue; + } + pcause = sd->parsed.probable_cause[0]; + cause = osmo_load16be(sd->parsed.probable_cause + 1); + + vty_out(vty, "[%s] Type=%s, Severity=%s, ", timestamp, sd->parsed.event_type, sd->parsed.severity); + vty_out(vty, "Probable cause=%s: ", get_value_string(abis_nm_pcause_type_names, pcause)); + if (pcause == NM_PCAUSE_T_MANUF) + vty_out(vty, "%s, ", get_value_string(abis_mm_event_cause_names, cause)); + else + vty_out(vty, "%04X, ", cause); + vty_out(vty, "Additional text=%s%s", sd->parsed.additional_text, VTY_NEWLINE); + + talloc_free(sd); + } + + /* Optionally clear the list */ + if (argc > 1) { + while (!llist_empty(&bts->oml_fail_rep)) { + struct bts_oml_fail_rep *old = llist_last_entry(&bts->oml_fail_rep, struct bts_oml_fail_rep, + list); + llist_del(&old->list); + talloc_free(old); + } + } + + return CMD_SUCCESS; +} + DEFUN(show_rejected_bts, show_rejected_bts_cmd, "show rejected-bts", SHOW_STR "Display recently rejected BTS devices\n") { @@ -5272,6 +5333,7 @@ int bsc_vty_init(struct gsm_network *network) install_element_ve(&bsc_show_net_cmd); install_element_ve(&show_bts_cmd); + install_element_ve(&show_bts_fail_rep_cmd); install_element_ve(&show_rejected_bts_cmd); install_element_ve(&show_trx_cmd); install_element_ve(&show_trx_con_cmd); diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c index f12b0324d..fe421a4bf 100644 --- a/src/osmo-bsc/gsm_data.c +++ b/src/osmo-bsc/gsm_data.c @@ -881,6 +881,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num) INIT_LLIST_HEAD(&bts->abis_queue); INIT_LLIST_HEAD(&bts->loc_list); INIT_LLIST_HEAD(&bts->local_neighbors); + INIT_LLIST_HEAD(&bts->oml_fail_rep); /* Enable all codecs by default. These get reset to a more fine grained selection IF a * 'codec-support' config appears in the config file (see bsc_vty.c). */ -- cgit v1.2.3