diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bts.h | 7 | ||||
-rw-r--r-- | src/osmobts_sock.cpp | 2 | ||||
-rw-r--r-- | src/pcu_l1_if.cpp | 93 | ||||
-rw-r--r-- | src/pcu_l1_if.h | 8 | ||||
-rw-r--r-- | src/pcu_main.cpp | 3 | ||||
-rw-r--r-- | src/pcuif_proto.h | 60 |
6 files changed, 172 insertions, 1 deletions
@@ -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 */ |