diff options
author | Minh-Quang Nguyen <minh-quang.nguyen@nutaq.com> | 2016-09-01 15:46:51 -0400 |
---|---|---|
committer | Minh-Quang Nguyen <minh-quang.nguyen@nutaq.com> | 2016-09-02 09:33:50 -0400 |
commit | c37cbb45f509529fedfb19f4a146420d61d503d1 (patch) | |
tree | bf34ccdba19ba25b93faaa49f03841b2dbe3b87f | |
parent | da30a797762a0113b75bcc6008d1b6699eb1278f (diff) |
LC15: Implementation of major BTS alarms
Change-Id: Ic4e088a3af115d3d5a124b61c1e92eed277d3469
-rw-r--r-- | include/osmo-bts/gsm_data.h | 1 | ||||
-rw-r--r-- | include/osmo-bts/oml.h | 71 | ||||
-rw-r--r-- | src/common/bts.c | 19 | ||||
-rw-r--r-- | src/common/l1sap.c | 7 | ||||
-rw-r--r-- | src/common/main.c | 13 | ||||
-rw-r--r-- | src/common/oml.c | 299 | ||||
-rw-r--r-- | src/common/pcu_sock.c | 44 | ||||
-rw-r--r-- | src/common/rsl.c | 30 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/calib_file.c | 49 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/l1_if.c | 40 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/l1_if.h | 1 |
11 files changed, 553 insertions, 21 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 447d8d25..ed864d61 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -115,6 +115,7 @@ struct gsm_bts_role_bts { /* specific to LC15 BTS */ struct { uint8_t led_ctrl_mode; /* 0: control by BTS, 1: not control by BTS */ + struct llist_head ceased_alarm_list; /* ceased alarm list*/ } lc15; #endif }; diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index 9f494447..b3ccf9d7 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -1,11 +1,76 @@ #ifndef _OML_H #define _OML_H +#include "openbsc/signal.h" struct gsm_bts; struct gsm_abis_mo; struct msgb; struct gsm_lchan; +enum oml_fail_evt_rep_sig { + S_NM_OML_PCU_CONN_LOST_ALARM = 0x0a1a, + S_NM_OML_PCU_CONN_LOST_CEASED, + S_NM_OML_PCU_CONN_NOT_AVAIL_ALARM, + S_NM_OML_BTS_RX_UNKN_PCU_MSG_ALARM, + S_NM_OML_BTS_RSL_FAILED_ALARM, + S_NM_OML_BTS_RF_DEACT_FAILED_ALARM, + S_NM_OML_BTS_RX_SIGINT_MSG_ALARM, + S_NM_OML_BTS_RX_SIGX_MSG_ALARM, + S_NM_OML_BTS_DSP_ALIVE_ALARM, + S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM, + S_NM_OML_BTS_RX_UNKN_L1SAP_UP_MSG_ALARM, + S_NM_OML_BTS_RX_UNKN_L1SAP_DOWN_MSG_ALARM, + S_NM_OML_BTS_PAG_TBL_FULL_ALARM, + S_NM_OML_BTS_FAIL_RTP_SOCK_ALARM, + S_NM_OML_BTS_FAIL_RTP_BIND_ALARM, + S_NM_OML_BTS_NO_RTP_SOCK_ALARM, + S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM, + S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM, + S_NM_OML_BTS_NO_CALIB_PATH_ALARM, +}; + +struct oml_fail_evt_rep_sig_data { + struct gsm_abis_mo *mo; + uint8_t event_type; + uint8_t event_serverity; + uint8_t cause_type; + uint16_t event_cause; + char *add_text; + int rc; + uint8_t spare[4]; +}; + +struct oml_alarm_list { + struct llist_head list; /* List of sent failure alarm report */ + uint16_t alarm_signal; /* Failure alarm report signal cause */ +}; + +enum abis_nm_failure_event_causes { + /* Critical causes */ + NM_EVT_CAUSE_CRIT_SW_FATAL = 0x3000, + NM_EVT_CAUSE_CRIT_DSP_FATAL = 0x3001, + NM_EVT_CAUSE_CRIT_PROC_STOP = 0x3006, + NM_EVT_CAUSE_CRIT_RTP_CREATE_FAIL = 0x332a, + NM_EVT_CAUSE_CRIT_RTP_BIND_FAIL = 0x332b, + NM_EVT_CAUSE_CRIT_RTP_NO_SOCK = 0x332c, + NM_EVT_CAUSE_CRIT_BAD_CALIB_PATH = 0x3401, + NM_EVT_CAUSE_CRIT_OPEN_CALIB_FAIL = 0x3403, + NM_EVT_CAUSE_CRIT_VERIFY_CALIB_FAIL = 0x3404, + /* Major causes */ + NM_EVT_CAUSE_MAJ_UKWN_PCU_MSG = 0x3002, + NM_EVT_CAUSE_MAJ_UKWN_DL_MSG = 0x3003, + NM_EVT_CAUSE_MAJ_UKWN_UL_MSG = 0x3004, + NM_EVT_CAUSE_MAJ_UKWN_MPH_MSG = 0x3005, + NM_EVT_CAUSE_MAJ_RSL_FAIL = 0x3309, + NM_EVT_CAUSE_MAJ_DEACT_RF_FAIL = 0x330a, + /* Minor causes */ + NM_EVT_CAUSE_MIN_PAG_TAB_FULL = 0x3402, + /* Warning causes */ + NM_EVT_CAUSE_WARN_SW_WARN = 0x0001, + +}; + +extern struct oml_fail_evt_rep_sig_data alarm_sig_data; int oml_init(void); int down_oml(struct gsm_bts *bts, struct msgb *msg); @@ -42,4 +107,10 @@ int oml_mo_fom_ack_nack(struct gsm_abis_mo *mo, uint8_t orig_msg_type, int oml_set_lchan_t200(struct gsm_lchan *lchan); extern const unsigned int oml_default_t200_ms[7]; +/* Transmit failure event report */ +int oml_tx_nm_fail_evt_rep(struct gsm_abis_mo *mo, uint8_t event_type, uint8_t event_serverity, uint8_t cause_type, uint16_t event_cause, char *add_text); + +/* Initialize failure report signalling */ +int oml_failure_report_init(void *handler); + #endif // _OML_H */ diff --git a/src/common/bts.c b/src/common/bts.c index 6f621c4d..42ac0967 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -44,6 +44,7 @@ #include <osmo-bts/rsl.h> #include <osmo-bts/oml.h> #include <osmo-bts/signal.h> +#include "osmo-bts/oml.h" #define MIN_QUAL_RACH 5.0f /* at least 5 dB C/I */ #define MIN_QUAL_NORM -0.5f /* at least -1 dB C/I */ @@ -175,6 +176,9 @@ int bts_init(struct gsm_bts *bts) INIT_LLIST_HEAD(&btsb->smscb_state.queue); INIT_LLIST_HEAD(&btsb->oml_queue); +#ifdef ENABLE_LC15BTS + INIT_LLIST_HEAD(&btsb->lc15.ceased_alarm_list); +#endif return rc; } @@ -250,6 +254,7 @@ int bts_link_estab(struct gsm_bts *bts) int trx_link_estab(struct gsm_bts_trx *trx) { struct e1inp_sign_link *link = trx->rsl_link; + int rc; uint8_t radio_state = link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED; LOGP(DSUM, LOGL_INFO, "RSL link (TRX %02x) state changed to %s, sending Status'.\n", @@ -258,11 +263,19 @@ int trx_link_estab(struct gsm_bts_trx *trx) oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK); if (link) - rsl_tx_rf_res(trx); + rc = rsl_tx_rf_res(trx); else - bts_model_trx_deact_rf(trx); + rc = bts_model_trx_deact_rf(trx); + + if(rc < 0) { + alarm_sig_data.mo = &trx->mo; + if(link) + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RSL_FAILED_ALARM, &alarm_sig_data); + else + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RF_DEACT_FAILED_ALARM, &alarm_sig_data); + } - return 0; + return rc; } /* set the availability of the TRX (used by PHY driver) */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 7c30c9b9..b3253a83 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -46,6 +46,7 @@ #include <osmo-bts/bts_model.h> #include <osmo-bts/handover.h> #include <osmo-bts/power_control.h> +#include "osmo-bts/oml.h" struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx, unsigned int chan_nr) @@ -1003,7 +1004,11 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) break; default: LOGP(DL1P, LOGL_NOTICE, "unknown prim %d op %d\n", - l1sap->oph.primitive, l1sap->oph.operation); + l1sap->oph.primitive, l1sap->oph.operation); + + alarm_sig_data.mo = &trx->mo; + memcpy(alarm_sig_data.spare, &l1sap->oph.primitive, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_UNKN_L1SAP_UP_MSG_ALARM, &alarm_sig_data); break; } diff --git a/src/common/main.c b/src/common/main.c index 5e0f1a16..62d71507 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -50,6 +50,7 @@ #include <osmo-bts/bts_model.h> #include <osmo-bts/pcu_if.h> #include <osmo-bts/control_if.h> +#include <osmo-bts/oml.h> int quit = 0; static const char *config_file = "osmo-bts.cfg"; @@ -181,13 +182,21 @@ static void signal_handler(int signal) switch (signal) { case SIGINT: //osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); - if (!quit) + if (!quit) { + alarm_sig_data.mo = &bts->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_SIGINT_MSG_ALARM, &alarm_sig_data); + bts_shutdown(bts, "SIGINT"); + } quit++; break; case SIGABRT: case SIGUSR1: case SIGUSR2: + alarm_sig_data.mo = &bts->mo; + alarm_sig_data.spare[0] = signal; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_SIGX_MSG_ALARM, &alarm_sig_data); + talloc_report_full(tall_bts_ctx, stderr); break; default: @@ -248,6 +257,8 @@ int bts_main(int argc, char **argv) e1inp_vty_init(); bts_vty_init(bts, &bts_log_info); + oml_failure_report_init(NULL); + /* enable realtime priority for us */ if (rt_prio != -1) { struct sched_param param; diff --git a/src/common/oml.c b/src/common/oml.c index 690a81d9..924c4dcb 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -41,6 +41,12 @@ #include <osmo-bts/bts_model.h> #include <osmo-bts/bts.h> #include <osmo-bts/signal.h> +#include <osmo-bts/pcu_if.h> +#include <osmo-bts/pcuif_proto.h> +#ifdef ENABLE_LC15BTS +#include "../osmo-bts-litecell15/lc15bts.h" +struct oml_fail_evt_rep_sig_data alarm_sig_data; +#endif /* FIXME: move this to libosmocore */ static struct tlv_definition abis_nm_att_tlvdef_ipa = { @@ -369,6 +375,37 @@ int oml_mo_tx_sw_act_rep(struct gsm_abis_mo *mo) return oml_mo_send_msg(mo, nmsg, NM_MT_SW_ACTIVATED_REP); } +/* TS 12.21 8.8.2 */ +int oml_tx_nm_fail_evt_rep(struct gsm_abis_mo *mo, uint8_t event_type, uint8_t event_serverity, uint8_t cause_type, uint16_t event_cause, char *add_text) +{ + struct msgb *nmsg; + uint8_t cause[3]; + int i, len; + + LOGP(DOML, LOGL_INFO, "%s Tx FAILure EVT REP\n", gsm_abis_mo_name(mo)); + + nmsg = oml_msgb_alloc(); + if (!nmsg) + return -ENOMEM; + + msgb_tv_put(nmsg, NM_ATT_EVENT_TYPE, event_type); + msgb_tv_put(nmsg, NM_ATT_SEVERITY, event_serverity); + + cause[0] = cause_type; + for (i = 0; i < 2 ; i++) + cause[i + 1] = ((uint8_t*)&event_cause)[1 - i]; + + msgb_tv_fixed_put(nmsg, NM_ATT_PROB_CAUSE, 3, cause); + + len = strlen(add_text); + if(len){ + LOGP(DOML, LOGL_DEBUG, "%s Tx FAILure EVT REP Additional Text = %s (%d)\n", gsm_abis_mo_name(mo), add_text, len); + msgb_tl16v_put(nmsg, NM_ATT_ADD_TEXT, len, add_text); + } + + return oml_mo_send_msg(mo, nmsg, NM_MT_FAILURE_EVENT_REP); +} + /* TS 12.21 9.4.53 */ enum abis_nm_t200_idx { T200_SDCCH = 0, @@ -1268,3 +1305,265 @@ int oml_init(void) return 0; } + +static int handle_oml_fail_evt_rep_sig(unsigned int subsys, unsigned int signal, + void *handler_data, void *_signal_data) +{ + struct oml_fail_evt_rep_sig_data *sig_data = _signal_data; + int rc = 0; + unsigned int res; + char log_msg[100]; + + if (subsys != SS_NM) + return 0; + + switch (signal) { + case S_NM_OML_PCU_CONN_LOST_ALARM: + snprintf(log_msg, 100, "PCU socket has LOST connection\n"); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_SW_FATAL, + sig_data->add_text); + break; + + case S_NM_OML_PCU_CONN_LOST_CEASED: + snprintf(log_msg, 100, "PCU socket has LOST connection\n"); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CEASED, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_SW_FATAL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_UNKN_PCU_MSG_ALARM: + snprintf(log_msg, 100, "Received unknown PCU msg type 0x%02x\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_PCU_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RSL_FAILED_ALARM: + snprintf(log_msg, 100, "Failed to establish RSL link (%d)\n", sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_RSL_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RF_DEACT_FAILED_ALARM: + snprintf(log_msg, 100, "Failed to deactivate RF (%d)\n", sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_DEACT_RF_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_UNKN_L1SAP_UP_MSG_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "unknown prim %d L1SAP UP trx %d\n", sig_data->mo->obj_inst.trx_nr, res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_UL_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_UNKN_L1SAP_DOWN_MSG_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "unknown prim %d L1SAP DOWN trx %d\n", sig_data->mo->obj_inst.trx_nr, res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_DL_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_RX_SIGINT_MSG_ALARM: + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_PROC_STOP, + "BTS: signal SIGINT received -> shutdown\n"); + break; + + case S_NM_OML_BTS_RX_SIGX_MSG_ALARM: + snprintf(log_msg, 100, "BTS: signal %d received\n", sig_data->spare[0]); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_PROC_STOP, + sig_data->add_text); + break; + + case S_NM_OML_BTS_DSP_ALIVE_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "Timeout waiting for SYS primitive %s (%d)\n", + get_value_string(lc15bts_sysprim_names, res + 1), sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_DSP_FATAL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM: + memcpy(&res, sig_data->spare, sizeof(unsigned int)); + snprintf(log_msg, 100, "unknown MPH-INFO.req %d\n", res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MAJ_UKWN_MPH_MSG, + sig_data->add_text); + break; + + case S_NM_OML_BTS_PAG_TBL_FULL_ALARM: + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_ENV_FAIL, + NM_SEVER_MINOR, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_MIN_PAG_TAB_FULL, + "BTS page table is full\n"); + break; + + case S_NM_OML_BTS_FAIL_RTP_SOCK_ALARM: + snprintf(log_msg, 100, "IPAC Failed to create RTP/RTCP sockets, trx=%d, ts=%d, ss=%d\n", + sig_data->mo->obj_inst.trx_nr, + sig_data->spare[0], + sig_data->spare[1]); + + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_RTP_CREATE_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_FAIL_RTP_BIND_ALARM: + snprintf(log_msg, 100, "IPAC Failed to bind RTP/RTCP sockets, trx=%d, ts=%d, ss=%d\n", + sig_data->mo->obj_inst.trx_nr, + sig_data->spare[0], + sig_data->spare[1]); + + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_RTP_BIND_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_NO_RTP_SOCK_ALARM: + snprintf(log_msg, 100, "Rx RSL IPAC MDCX, but we have no RTP socket! trx=%d, ts=%d, ss=%d\n", + sig_data->mo->obj_inst.trx_nr, + sig_data->spare[0], + sig_data->spare[1]); + + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_COMM_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_RTP_NO_SOCK, + sig_data->add_text); + break; + + case S_NM_OML_BTS_NO_CALIB_PATH_ALARM: + snprintf(log_msg, 100, "Calibration file path for trx=%d not specified\n", sig_data->mo->obj_inst.trx_nr); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_BAD_CALIB_PATH, + sig_data->add_text); + break; + + + case S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM: + memcpy(&res, sig_data->spare, sizeof(int)); + snprintf(log_msg, 100, "Failed to open L1 calibration table %s -> failed (%d)\n", + sig_data->add_text, + res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_OPEN_CALIB_FAIL, + sig_data->add_text); + break; + + case S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM: + memcpy(&res, sig_data->spare, sizeof(int)); + snprintf(log_msg, 100, "Verify L1 calibration table %s -> failed (%d)\n", + sig_data->add_text, + res); + sig_data->add_text = (char*)&log_msg; + + rc = oml_tx_nm_fail_evt_rep(sig_data->mo, + NM_EVT_PROC_FAIL, + NM_SEVER_CRITICAL, + NM_PCAUSE_T_MANUF, + NM_EVT_CAUSE_CRIT_VERIFY_CALIB_FAIL, + sig_data->add_text); + break; + + default: + break; + } + + sig_data->rc = rc; + return 0; +} + +int oml_failure_report_init(void *handler) +{ + /* register for failure report events */ + osmo_signal_register_handler(SS_NM, handle_oml_fail_evt_rep_sig, handler); + + return 0; +} diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 62f18a78..bd50be15 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -41,6 +41,7 @@ #include <osmo-bts/rsl.h> #include <osmo-bts/signal.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/oml.h> uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); @@ -131,12 +132,14 @@ int pcu_tx_info_ind(void) struct gsm_bts_gprs_nsvc *nsvc; struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; - int i, j; + int i, j, rc; + struct gsm_bts_role_bts *btsb; LOGP(DPCU, LOGL_INFO, "Sending info\n"); /* FIXME: allow multiple BTS */ bts = llist_entry(net->bts_list.next, struct gsm_bts, list); + btsb = bts_role_bts(bts); rlcc = &bts->gprs.cell.rlc_cfg; msg = pcu_msgb_alloc(PCU_IF_MSG_INFO_IND, bts->nr); @@ -245,7 +248,25 @@ int pcu_tx_info_ind(void) } } - return pcu_sock_send(net, msg); + rc = pcu_sock_send(net, msg); + if (rc < 0) + return rc; + +#ifdef ENABLE_LC15BTS + struct oml_alarm_list *ceased_alarm; + /* check for pending ceased alarm */ + llist_for_each_entry(ceased_alarm, &btsb->lc15.ceased_alarm_list, list) { + llist_del(&ceased_alarm->list); + if (ceased_alarm->alarm_signal != S_NM_OML_PCU_CONN_LOST_ALARM) + continue; + + LOGP(DPCU, LOGL_ERROR, "Alarm %d has removed from pending ceased alarm list\n", ceased_alarm->alarm_signal); + alarm_sig_data.mo = &bts->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_LOST_CEASED, &alarm_sig_data); + break; + } +#endif + return 0; } static int pcu_if_signal_cb(unsigned int subsys, unsigned int signal, @@ -603,6 +624,9 @@ static int pcu_rx(struct gsm_network *net, uint8_t msg_type, default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); + alarm_sig_data.mo = &bts->mo; + alarm_sig_data.spare[0] = msg_type; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_UNKN_PCU_MSG_ALARM, &alarm_sig_data); rc = -EINVAL; } @@ -654,11 +678,27 @@ static void pcu_sock_close(struct pcu_sock_state *state) struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; int i, j; + struct gsm_bts_role_bts *btsb; /* FIXME: allow multiple BTS */ bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); + btsb = bts_role_bts(bts); LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); +#ifdef ENABLE_LC15BTS + struct oml_alarm_list *ceased_alarm; + /*dispatch alarm signal */ + alarm_sig_data.mo = &bts->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_PCU_CONN_LOST_ALARM, &alarm_sig_data); + /* allocate new list of pending ceased alarm */ + ceased_alarm = talloc_zero(NULL, struct oml_alarm_list); + if (ceased_alarm) { + ceased_alarm->alarm_signal = S_NM_OML_PCU_CONN_LOST_ALARM; + /* add ceased alarm to pending list */ + llist_add(&ceased_alarm->list, &btsb->lc15.ceased_alarm_list); + LOGP(DPCU, LOGL_ERROR, "Alarm %d has added to pending ceased alarm list\n", ceased_alarm->alarm_signal); + } +#endif close(bfd->fd); bfd->fd = -1; diff --git a/src/common/rsl.c b/src/common/rsl.c index 490ae284..a31261b4 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -50,6 +50,7 @@ #include <osmo-bts/cbch.h> #include <osmo-bts/l1sap.h> #include <osmo-bts/bts_model.h> +#include "osmo-bts/oml.h" //#define FAKE_CIPH_MODE_COMPL @@ -392,6 +393,19 @@ static int rsl_rx_paging_cmd(struct gsm_bts_trx *trx, struct msgb *msg) identity_lv, chan_needed); if (rc < 0) { /* FIXME: notfiy the BSC somehow ?*/ + switch (rc) { + /* Send Failure event report of BTS page table is full to BSC */ + case -ENOSPC: + if (trx) { + alarm_sig_data.mo = &trx->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_PAG_TBL_FULL_ALARM, &alarm_sig_data); + } + break; + + default: + break; + } + } pcu_tx_pag_req(identity_lv, chan_needed); @@ -1600,6 +1614,11 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) LOGP(DRSL, LOGL_ERROR, "%s IPAC Failed to create RTP/RTCP sockets\n", gsm_lchan_name(lchan)); + alarm_sig_data.mo = &lchan->ts->trx->mo; + alarm_sig_data.spare[0] = lchan->ts->nr; + alarm_sig_data.spare[1] = lchan->nr; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_RTP_SOCK_ALARM, &alarm_sig_data); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } @@ -1629,6 +1648,11 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) LOGP(DRSL, LOGL_ERROR, "%s IPAC Failed to bind RTP/RTCP sockets\n", gsm_lchan_name(lchan)); + alarm_sig_data.mo = &lchan->ts->trx->mo; + alarm_sig_data.spare[0] = lchan->ts->nr; + alarm_sig_data.spare[1] = lchan->nr; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_RTP_BIND_ALARM, &alarm_sig_data); + osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); lchan->abis_ip.rtp_socket = NULL; msgb_queue_flush(&lchan->dl_tch_queue); @@ -1642,6 +1666,12 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) LOGP(DRSL, LOGL_ERROR, "%s Rx RSL IPAC MDCX, " "but we have no RTP socket!\n", gsm_lchan_name(lchan)); + + alarm_sig_data.mo = &lchan->ts->trx->mo; + alarm_sig_data.spare[0] = lchan->ts->nr; + alarm_sig_data.spare[1] = lchan->nr; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_NO_RTP_SOCK_ALARM, &alarm_sig_data); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } diff --git a/src/osmo-bts-litecell15/calib_file.c b/src/osmo-bts-litecell15/calib_file.c index 0714bc9e..3aa5905c 100644 --- a/src/osmo-bts-litecell15/calib_file.c +++ b/src/osmo-bts-litecell15/calib_file.c @@ -41,6 +41,7 @@ #include "l1_if.h" #include "lc15bts.h" #include "utils.h" +#include "osmo-bts/oml.h" /* Maximum calibration data chunk size */ #define MAX_CALIB_TBL_SIZE 65536 @@ -148,12 +149,19 @@ static int calib_file_open(struct lc15l1_hdl *fl1h, snprintf(fname, sizeof(fname)-1, "%s/%s", calib_path, desc->fname); fname[sizeof(fname)-1] = '\0'; - st->fp = fopen(fname, "rb"); - if (!st->fp) { - LOGP(DL1C, LOGL_ERROR, - "Failed to open '%s' for calibration data.\n", fname); - return -1; - } + st->fp = fopen(fname, "rb"); + if (!st->fp) { + LOGP(DL1C, LOGL_NOTICE, "Failed to open '%s' for calibration data.\n", fname); + + if( fl1h->phy_inst->trx ){ + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + alarm_sig_data.add_text = (char*)&fname[0]; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_OPEN_CALIB_ALARM, &alarm_sig_data); + } + return -1; + } return 0; } @@ -235,8 +243,18 @@ static int calib_file_send(struct lc15l1_hdl *fl1h, } rc = calib_verify(fl1h, desc); - if ( rc < 0 ) { - LOGP(DL1C, LOGL_ERROR, "Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc); + if (rc < 0) { + LOGP(DL1C, LOGL_NOTICE,"Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc); + + if (fl1h->phy_inst->trx) { + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + alarm_sig_data.add_text = (char*)&desc->fname[0]; + memcpy(alarm_sig_data.spare, &rc, sizeof(int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_FAIL_VERIFY_CALIB_ALARM, &alarm_sig_data); + } + st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx); if (st->last_file_idx >= 0) @@ -289,10 +307,17 @@ int calib_load(struct lc15l1_hdl *fl1h) struct calib_send_state *st = &fl1h->st; char *calib_path = fl1h->phy_inst->u.lc15.calib_path; - if (!calib_path) { - LOGP(DL1C, LOGL_ERROR, "Calibration file path not specified\n"); - return -1; - } + if (!calib_path) { + LOGP(DL1C, LOGL_NOTICE, "Calibration file path not specified\n"); + + if( fl1h->phy_inst->trx ){ + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_NO_CALIB_PATH_ALARM, &alarm_sig_data); + } + return -1; + } rc = get_next_calib_file_idx(fl1h, -1); if (rc < 0) { diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index e0000a2b..4137032a 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -66,6 +66,7 @@ #include "misc/lc15bts_par.h" #include "misc/lc15bts_bid.h" #include "utils.h" +#include "osmo-bts/oml.h" extern unsigned int dsp_trace; @@ -548,7 +549,10 @@ static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg, break; default: LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n", - l1sap->u.info.type); + l1sap->u.info.type); + alarm_sig_data.mo = &trx->mo; + memcpy(alarm_sig_data.spare, &l1sap->u.info.type, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_UNKN_MPH_INFO_REQ_ALARM, &alarm_sig_data); rc = -EINVAL; } @@ -574,6 +578,10 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) default: LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d\n", l1sap->oph.primitive, l1sap->oph.operation); + + alarm_sig_data.mo = &trx->mo; + memcpy(alarm_sig_data.spare, &l1sap->oph.primitive, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_RX_UNKN_L1SAP_DOWN_MSG_ALARM, &alarm_sig_data); rc = -EINVAL; } @@ -1438,6 +1446,7 @@ struct lc15l1_hdl *l1if_open(struct phy_instance *pinst) if (!fl1h) return NULL; INIT_LLIST_HEAD(&fl1h->wlc_list); + INIT_LLIST_HEAD(&fl1h->alarm_list); fl1h->phy_inst = pinst; fl1h->dsp_trace_f = pinst->u.lc15.dsp_trace_f; @@ -1486,16 +1495,43 @@ static int dsp_alive_timer_cb(void *data) struct gsm_bts_trx *trx = fl1h->phy_inst->trx; struct msgb *msg = sysp_msgb_alloc(); int rc; + struct oml_alarm_list *alarm_sent; Litecell15_Prim_t *sys_prim = msgb_sysprim(msg); sys_prim->id = Litecell15_PrimId_IsAliveReq; if (fl1h->hw_alive.dsp_alive_cnt == 0) { + /* check for the alarm has already sent or not */ + llist_for_each_entry(alarm_sent, &fl1h->alarm_list, list) { + llist_del(&alarm_sent->list); + if (alarm_sent->alarm_signal != S_NM_OML_BTS_DSP_ALIVE_ALARM) + continue; + + LOGP(DL1C, LOGL_ERROR, "Alarm %d has removed from sent alarm list (%d)\n", alarm_sent->alarm_signal, trx->nr); + exit(23); + } LOGP(DL1C, LOGL_ERROR, "Timeout waiting for SYS prim %s primitive (%d)\n", get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr); - exit(23); + if( fl1h->phy_inst->trx ){ + fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr; + + alarm_sig_data.mo = &fl1h->phy_inst->trx->mo; + memcpy(alarm_sig_data.spare, &sys_prim->id, sizeof(unsigned int)); + osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_DSP_ALIVE_ALARM, &alarm_sig_data); + if (!alarm_sig_data.rc) { + /* allocate new list of sent alarms */ + alarm_sent = talloc_zero(fl1h, struct oml_alarm_list); + if (!alarm_sent) + return -EIO; + + alarm_sent->alarm_signal = S_NM_OML_BTS_DSP_ALIVE_ALARM; + /* add alarm to sent list */ + llist_add(&alarm_sent->list, &fl1h->alarm_list); + LOGP(DL1C, LOGL_ERROR, "Alarm %d has added to sent alarm list (%d)\n", alarm_sent->alarm_signal, trx->nr); + } + } } LOGP(DL1C, LOGL_NOTICE, "Tx SYS prim %s (%d)\n", diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h index 8a7b737c..f3ac3d34 100644 --- a/src/osmo-bts-litecell15/l1_if.h +++ b/src/osmo-bts-litecell15/l1_if.h @@ -38,6 +38,7 @@ struct lc15l1_hdl { uint32_t hLayer1; /* handle to the L1 instance in the DSP */ uint32_t dsp_trace_f; /* currently operational DSP trace flags */ struct llist_head wlc_list; + struct llist_head alarm_list; /* list of sent alarms */ struct phy_instance *phy_inst; |