aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinh-Quang Nguyen <minh-quang.nguyen@nutaq.com>2016-09-06 16:20:43 -0400
committerMinh-Quang Nguyen <minh-quang.nguyen@nutaq.com>2016-09-07 08:39:55 -0400
commitd5415a22f15addf8937a12f37d4c212ec07561e9 (patch)
treec43a55e024f081cc9e781a8f68d38f36ce46f794
parent16ddc90eabad423d247753f7d89639659e049d35 (diff)
Implementation of wrong PCU interface version alarm.
When the PCU receives wrong PCU interface version in BTS information indication message. It will send a critical alarm to the BTS before stopping itself. The BTS will do remaining task by forwarding this alarm to core network using standard TS 12.21 failure event report message where the alarm cause ID is manufature-defined by NuRAN Wireless. Change-Id: I0e1131a53ff86ccfccca44d45cae4606240f3c68
-rw-r--r--src/bts.h7
-rw-r--r--src/osmobts_sock.cpp2
-rw-r--r--src/pcu_l1_if.cpp93
-rw-r--r--src/pcu_l1_if.h8
-rw-r--r--src/pcu_main.cpp3
-rw-r--r--src/pcuif_proto.h60
6 files changed, 172 insertions, 1 deletions
diff --git a/src/bts.h b/src/bts.h
index 801342d..010ed2a 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -36,6 +36,7 @@ extern "C" {
#include "tbf.h"
#include "gprs_ms_storage.h"
#include "gprs_coding_scheme.h"
+#include "pcuif_proto.h"
#endif
#include <stdint.h>
@@ -208,6 +209,12 @@ struct gprs_rlcmac_bts {
* period.
*/
struct BTS *bts;
+
+ /*
+ * PCU alarm list
+ */
+ struct llist_head alarm_list;
+
};
#ifdef __cplusplus
diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp
index 21a404f..f753555 100644
--- a/src/osmobts_sock.cpp
+++ b/src/osmobts_sock.cpp
@@ -284,6 +284,7 @@ int pcu_l1if_open(void)
LOGP(DL1IF, LOGL_NOTICE, "osmo-bts PCU socket has been connected\n");
+ pcu_failure_report_init(NULL);
pcu_sock_state = state;
return 0;
@@ -297,6 +298,7 @@ void pcu_l1if_close(void)
if (!state)
return;
+ pcu_failure_report_free(NULL);
osmo_timer_del(&state->timer);
bfd = &state->conn_bfd;
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index f1c73c9..2397d79 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -52,6 +52,7 @@ int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn,
}
extern void *tall_pcu_ctx;
+struct pcu_fail_evt_rep_sig_data alarm_sig_data;
/*
* PCU messages
@@ -124,6 +125,27 @@ static int pcu_tx_data_req(uint8_t trx, uint8_t ts, uint8_t sapi,
return pcu_sock_send(msg);
}
+int pcu_tx_nm_fail_evt(uint8_t event_type, uint8_t event_severity,
+ uint8_t cause_type, uint16_t event_cause, char *add_text)
+{
+ struct msgb *msg;
+ struct gsm_pcu_if *pcu_prim;
+
+ msg = pcu_msgb_alloc(PCU_IF_MSG_FAILURE_EVT_IND, 0);
+ if (!msg)
+ return -ENOMEM;
+
+ pcu_prim = (struct gsm_pcu_if *) msg->data;
+ pcu_prim->u.failure_evt_ind.event_type = event_type;
+ pcu_prim->u.failure_evt_ind.event_severity = event_severity;
+ pcu_prim->u.failure_evt_ind.event_cause = event_cause;
+ pcu_prim->u.failure_evt_ind.cause_type = cause_type;
+ strcpy(pcu_prim->u.failure_evt_ind.add_text, add_text);
+
+ LOGP(DL1IF, LOGL_DEBUG, "[PCU->BTS] Sending FAILure EVT REP dump %s (%d)\n", osmo_hexdump(msg->data , msg->data_len), msg->data_len);
+ return pcu_sock_send(msg);
+}
+
void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn,
uint32_t fn, uint8_t block_nr)
{
@@ -343,12 +365,26 @@ static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind)
int rc = 0, ts;
uint8_t trx;
int i;
+ struct pcu_alarm_list *alarm_list;
if (info_ind->version != PCU_IF_VERSION) {
fprintf(stderr, "PCU interface version number of BTS (%d) is "
"different (%d).\nPlease re-compile!\n",
info_ind->version, PCU_IF_VERSION);
- exit(-1);
+
+ memcpy(alarm_sig_data.spare, &info_ind->version, sizeof(unsigned int));
+ osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_WRONG_IF_VER_ALARM, &alarm_sig_data);
+
+ /* allocate new list of sent alarms */
+ alarm_list = talloc_zero(tall_pcu_ctx, struct pcu_alarm_list);
+ if (!alarm_list)
+ return -EIO;
+
+ alarm_list->alarm_signal = S_PCU_NM_WRONG_IF_VER_ALARM;
+ /* add alarm to sent list */
+ llist_add(&alarm_list->list, &bts->alarm_list);
+ LOGP(DL1IF, LOGL_DEBUG, "PCU alarm 0x%04x added to sent alarm list\n", alarm_list->alarm_signal);
+ return -EPERM;
}
LOGP(DL1IF, LOGL_DEBUG, "Info indication received:\n");
@@ -534,6 +570,16 @@ int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
{
int rc = 0;
struct gprs_rlcmac_bts *bts = bts_main_data();
+ struct pcu_alarm_list *alarm_list;
+
+ /* check for the PCU alarm has already sent or not */
+ llist_for_each_entry(alarm_list, &bts->alarm_list, list) {
+ if (alarm_list->alarm_signal != S_PCU_NM_WRONG_IF_VER_ALARM)
+ continue;
+ llist_del(&alarm_list->list);
+ LOGP(DL1IF, LOGL_DEBUG, "Alarm 0x%04x has removed from PCU sent alarm list\n", alarm_list->alarm_signal);
+ exit(-1);
+ }
switch (msg_type) {
case PCU_IF_MSG_DATA_IND:
@@ -565,3 +611,48 @@ int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
return rc;
}
+
+static int handle_pcu_fail_evt_rep_sig(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *_signal_data)
+{
+ struct pcu_fail_evt_rep_sig_data *sig_data = (struct pcu_fail_evt_rep_sig_data *)_signal_data;
+ int rc = 0;
+ unsigned int res;
+ char log_msg[100];
+
+ if (subsys != SS_L_GLOBAL)
+ return 0;
+
+ switch (signal) {
+ case S_PCU_NM_WRONG_IF_VER_ALARM:
+ memcpy(&res, sig_data->spare, sizeof(unsigned int));
+ snprintf(log_msg, 100, "PCU interface version number of BTS (%d) is different (%d)", res, PCU_IF_VERSION);
+ sig_data->add_text = &log_msg[0];
+
+ rc = pcu_tx_nm_fail_evt(NM_EVT_PROC_FAIL,
+ NM_SEVER_CRITICAL,
+ NM_PCAUSE_T_MANUF,
+ PCU_NM_EVT_CAUSE_CRIT_BAD_PCU_IF_VER,
+ sig_data->add_text);
+ break;
+ default:
+ break;
+ }
+
+ sig_data->rc = rc;
+ return rc;
+}
+
+/* Initialization of the PCU failure alarm event handler */
+void pcu_failure_report_init(void *handler)
+{
+ /* register for failure report events */
+ osmo_signal_register_handler(SS_L_GLOBAL, handle_pcu_fail_evt_rep_sig, handler);
+}
+
+/* Uninitizalization of the PCU failure alarm event handler */
+void pcu_failure_report_free(void *handler)
+{
+ /* unregister for failure report events */
+ osmo_signal_unregister_handler(SS_L_GLOBAL, handle_pcu_fail_evt_rep_sig, handler);
+}
diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h
index b2a9832..7b2c603 100644
--- a/src/pcu_l1_if.h
+++ b/src/pcu_l1_if.h
@@ -133,6 +133,14 @@ int pcu_rx_data_ind_pdtch(uint8_t trx, uint8_t ts, uint8_t *data,
void pcu_rx_block_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no);
void pcu_rx_ra_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no);
+/* PCU transmits alarm message to BTS so that BTS is able to conveys it to network */
+int pcu_tx_nm_fail_evt(uint8_t event_type, uint8_t event_severity,
+ uint8_t cause_type, uint16_t event_cause, char *add_text);
+/* Initialization of signal creation-consumption based PCU alarm */
+void pcu_failure_report_init(void *handler);
+/* Free signal creation-consumption based PCU alarm */
+void pcu_failure_report_free(void *handler);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index afdfdc7..0f09560 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -217,6 +217,9 @@ int main(int argc, char *argv[])
*/
bts->dl_arq_type = EGPRS_ARQ1;
+ /* Initialization PCU alarm list */
+ INIT_LLIST_HEAD(&bts->alarm_list);
+
msgb_set_talloc_ctx(tall_pcu_ctx);
osmo_init_logging(&gprs_log_info);
diff --git a/src/pcuif_proto.h b/src/pcuif_proto.h
index 944f364..19fcb94 100644
--- a/src/pcuif_proto.h
+++ b/src/pcuif_proto.h
@@ -2,6 +2,8 @@
#define _PCUIF_PROTO_H
#include <osmocom/gsm/l1sap.h>
+#include <osmocom/core/signal.h>
+#include <osmocom/gsm/protocol/gsm_12_21.h>
#define PCU_IF_VERSION 0x07
@@ -16,6 +18,9 @@
#define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */
#define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */
+/*PCU alarm indication */
+#define PCU_IF_MSG_FAILURE_EVT_IND 0x61 /* PCU failure event report indication */
+
/* sapi */
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
#define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */
@@ -42,6 +47,50 @@
#define PCU_IF_FLAG_MCS8 (1 << 27)
#define PCU_IF_FLAG_MCS9 (1 << 28)
+/* NuRAN Wireless manufacture-defined alarm causes */
+enum pcu_nm_event_causes {
+ /* Critical causes */
+ PCU_NM_EVT_CAUSE_CRIT_BAD_PCU_IF_VER = 0x3415,
+ /* Major causes */
+ PCU_NM_EVT_CAUSE_MAJ_UKWN_L1_MSG = 0x3012,
+ PCU_NM_EVT_CAUSE_MAJ_UKWN_BTS_MSG = 0x3013,
+ /* Warning causes */
+ PCU_NM_EVT_CAUSE_WARN_NO_PDCH_AVAIL = 0x3011,
+
+};
+
+/* NuRAN Wireless manufacture-defined alarm signals */
+enum pcu_fail_evt_rep_sig {
+ S_PCU_NM_NO_PDCH_ALARM = 0x0b1b,
+ S_PCU_NM_RX_UNKN_L1_SAP_ALARM,
+ S_PCU_NM_RX_UNKN_L1_PRIM_ALARM,
+ S_PCU_NM_RX_UNKN_MSG_ALARM,
+ S_PCU_NM_FAIL_NSVC_ALARM,
+ S_PCU_NM_FAIL_RST_NSVC_ALARM,
+ S_PCU_NM_FAIL_UNBLK_NSVC_ALARM,
+ S_PCU_NM_FAIL_PTP_BVC_ALARM,
+ S_PCU_NM_UNKN_NSEI_BVCI_ALARM,
+ S_PCU_NM_UNKN_NSVC_ALARM,
+ S_PCU_NM_PDTCH_QUEUE_FULL_ALARM,
+ S_PCU_NM_FAIL_OPEN_L1_ALARM,
+ S_PCU_NM_FAIL_OPEN_PDCH_ALARM,
+ S_PCU_NM_WRONG_IF_VER_ALARM,
+};
+
+/* NuRAN Wireless manufacture-defined alarm signal data structure */
+struct pcu_fail_evt_rep_sig_data {
+ char *add_text;
+ int rc;
+ uint8_t spare[4];
+};
+
+/* NuRAN Wireless manufacture-defined alarm signal list structure */
+struct pcu_alarm_list {
+ struct llist_head list; /* List of sent failure alarm report */
+ uint16_t alarm_signal; /* Failure alarm report signal cause */
+};
+
+
struct gsm_pcu_if_data {
uint8_t sapi;
uint8_t len;
@@ -138,6 +187,14 @@ struct gsm_pcu_if_pag_req {
uint8_t identity_lv[9];
} __attribute__ ((packed));
+struct gsm_pcu_if_fail_evt_ind {
+ uint8_t event_type;
+ uint8_t event_severity;
+ uint8_t cause_type;
+ uint16_t event_cause;
+ char add_text[100];
+}__attribute__ ((packed));
+
struct gsm_pcu_if {
/* context based information */
uint8_t msg_type; /* message type */
@@ -154,7 +211,10 @@ struct gsm_pcu_if {
struct gsm_pcu_if_act_req act_req;
struct gsm_pcu_if_time_ind time_ind;
struct gsm_pcu_if_pag_req pag_req;
+ struct gsm_pcu_if_fail_evt_ind failure_evt_ind;
} u;
} __attribute__ ((packed));
+extern struct pcu_fail_evt_rep_sig_data alarm_sig_data;
+
#endif /* _PCUIF_PROTO_H */