aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 801342dd..010ed2a2 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 21a404fd..f7535559 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 f1c73c93..2397d79e 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 b2a9832e..7b2c6030 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 afdfdc75..0f095605 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 944f3644..19fcb94f 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 */