aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinh-Quang Nguyen <minh-quang.nguyen@nutaq.com>2016-09-01 15:46:51 -0400
committerMinh-Quang Nguyen <minh-quang.nguyen@nutaq.com>2016-09-02 09:33:50 -0400
commitc37cbb45f509529fedfb19f4a146420d61d503d1 (patch)
treebf34ccdba19ba25b93faaa49f03841b2dbe3b87f
parentda30a797762a0113b75bcc6008d1b6699eb1278f (diff)
LC15: Implementation of major BTS alarms
-rw-r--r--include/osmo-bts/gsm_data.h1
-rw-r--r--include/osmo-bts/oml.h71
-rw-r--r--src/common/bts.c19
-rw-r--r--src/common/l1sap.c7
-rw-r--r--src/common/main.c13
-rw-r--r--src/common/oml.c299
-rw-r--r--src/common/pcu_sock.c44
-rw-r--r--src/common/rsl.c30
-rw-r--r--src/osmo-bts-litecell15/calib_file.c49
-rw-r--r--src/osmo-bts-litecell15/l1_if.c40
-rw-r--r--src/osmo-bts-litecell15/l1_if.h1
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;