From 379649cfcdd8ff449cd97be895431ea45ed32383 Mon Sep 17 00:00:00 2001 From: Minh-Quang Nguyen Date: Wed, 7 Sep 2016 14:17:49 -0400 Subject: Implementation of NSVC failure related alarms: - Too many NS-ALIVE timer expired - Unable to perform unblocking procedure - Unable to perform reset prodecure Alarms ID are manufacture-defined by NuRAN Wireless Change-Id: Ida791c30a50c929975c2610c312fd844f9c7ccb5 --- src/gprs_bssgp_pcu.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/gprs_bssgp_pcu.h | 1 + src/pcu_l1_if.cpp | 35 +++++++++++++++++++++++++++++++++++ src/pcuif_proto.h | 3 +++ 4 files changed, 84 insertions(+) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index da1d26c1..a4f77b9f 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -24,9 +24,11 @@ #include #include #include +#include #define BSSGP_TIMER_T1 30 /* Guards the (un)blocking procedures */ #define BSSGP_TIMER_T2 30 /* Guards the reset procedure */ +#define BSSGP_TIMER_T3 5 /* Reset procedure status polling timer*/ /* Tuning parameters for BSSGP flow control */ #define FC_DEFAULT_LIFE_TIME_SECS 10 /* experimental value, 10s */ @@ -44,6 +46,7 @@ extern void *tall_pcu_ctx; extern uint16_t spoof_mcc, spoof_mnc; static void bvc_timeout(void *_priv); +static void bssgp_timeout_cb(void *_priv); static int parse_imsi(struct tlv_parsed *tp, char *imsi) { @@ -507,6 +510,9 @@ static int nsvc_signal_cb(unsigned int subsys, unsigned int signal, case S_NS_ALIVE_EXP: LOGP(DPCU, LOGL_NOTICE, "Tns alive expired too often, " "re-starting RESET procedure\n"); + memcpy(alarm_sig_data.spare, &the_pcu.nsvc->nsvci, sizeof(uint16_t)); + osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_FAIL_NSVC_ALARM, &alarm_sig_data); + gprs_ns_reconnect(nssd->nsvc); break; } @@ -780,6 +786,9 @@ static void bvc_timeout(void *_priv) return; } + /* Cancel any pending BSSGP timer on successful of BVCI reset */ + osmo_timer_del(&the_pcu.bssgp_timer); + if (!the_pcu.bvc_unblocked) { LOGP(DBSSGP, LOGL_INFO, "Sending unblock on BVCI %d\n", the_pcu.bctx->bvci); @@ -816,6 +825,13 @@ int gprs_ns_reconnect(struct gprs_nsvc *nsvc) return -EIO; } + /* Cancel any existing BSSGP timer */ + osmo_timer_del(&the_pcu.bssgp_timer); + + /* start BSSGP timer */ + the_pcu.bssgp_timer.cb = bssgp_timeout_cb; + osmo_timer_schedule(&the_pcu.bssgp_timer, BSSGP_TIMER_T3, 0); + return 0; } @@ -884,6 +900,12 @@ struct gprs_bssgp_pcu *gprs_bssgp_create_and_connect(struct gprs_rlcmac_bts *bts the_pcu.bvc_timer.cb = bvc_timeout; + /* Cancel any existing BSSGP timer */ + osmo_timer_del(&the_pcu.bssgp_timer); + + /* Start BSSGP timer */ + the_pcu.bssgp_timer.cb = bssgp_timeout_cb; + osmo_timer_schedule(&the_pcu.bssgp_timer, BSSGP_TIMER_T3, 0); return &the_pcu; } @@ -946,3 +968,26 @@ void gprs_bssgp_update_queue_delay(const struct timeval *tv_recv, the_pcu.queue_delay_count += 1; } + +static void bssgp_timeout_cb(void *_priv) { + + LOGP(DBSSGP, LOGL_DEBUG, "BSSGP timer expired, NSVC state=%x, restart BSSGP timer\n", the_pcu.nsvc->state); + + if (the_pcu.nsvc->state & NSE_S_BLOCKED) { + LOGP(DBSSGP, LOGL_DEBUG, "PCU: Tx NSVC BLOCKED failure alarm\n"); + memcpy(alarm_sig_data.spare, &the_pcu.nsvc->nsvci, sizeof(uint16_t)); + osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_FAIL_UNBLK_NSVC_ALARM, &alarm_sig_data); + } + + if (the_pcu.nsvc->state & NSE_S_RESET) { + LOGP(DBSSGP, LOGL_DEBUG, "PCU: Tx NSVC RESET failure alarm\n"); + memcpy(alarm_sig_data.spare, &the_pcu.nsvc->nsvci, sizeof(uint16_t)); + osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_FAIL_RST_NSVC_ALARM, &alarm_sig_data); + } + + /* Cancel any existing BSSGP timer */ + osmo_timer_del(&the_pcu.bssgp_timer); + + /* restart BSSGP timer */ + osmo_timer_schedule(&the_pcu.bssgp_timer, BSSGP_TIMER_T3, 0); +} diff --git a/src/gprs_bssgp_pcu.h b/src/gprs_bssgp_pcu.h index bb449034..4b956850 100644 --- a/src/gprs_bssgp_pcu.h +++ b/src/gprs_bssgp_pcu.h @@ -51,6 +51,7 @@ struct gprs_bssgp_pcu { struct gprs_rlcmac_bts *bts; struct osmo_timer_list bvc_timer; + struct osmo_timer_list bssgp_timer; int nsvc_unblocked; diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 7308fa1f..3fb00f34 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -624,6 +624,7 @@ static int handle_pcu_fail_evt_rep_sig(unsigned int subsys, unsigned int signal, int rc = 0; unsigned int res; char log_msg[100]; + uint16_t nscvi; if (subsys != SS_L_GLOBAL) return 0; @@ -715,6 +716,40 @@ static int handle_pcu_fail_evt_rep_sig(unsigned int subsys, unsigned int signal, sig_data->add_text); break; + case S_PCU_NM_FAIL_NSVC_ALARM: + memcpy(&nscvi, sig_data->spare, sizeof(uint16_t)); + snprintf(log_msg, 100, "PCU: NS-VC %d failure\n", nscvi); + sig_data->add_text = &log_msg[0]; + + rc = pcu_tx_nm_fail_evt(NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + PCU_NM_EVT_CAUSE_CRIT_NSVC_FAIL, + sig_data->add_text); + break; + + case S_PCU_NM_FAIL_RST_NSVC_ALARM: + memcpy(&nscvi, sig_data->spare, sizeof(uint16_t)); + snprintf(log_msg, 100, "PCU: NS-VC %d reset failure\n", nscvi); + sig_data->add_text = &log_msg[0]; + rc = pcu_tx_nm_fail_evt(NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + PCU_NM_EVT_CAUSE_CRIT_NSVC_RST_FAIL, + sig_data->add_text); + break; + + case S_PCU_NM_FAIL_UNBLK_NSVC_ALARM: + memcpy(&nscvi, sig_data->spare, sizeof(uint16_t)); + snprintf(log_msg, 100, "PCU: NS-VC %d unblock failure\n", nscvi); + sig_data->add_text = &log_msg[0]; + rc = pcu_tx_nm_fail_evt(NM_EVT_COMM_FAIL, + NM_SEVER_MAJOR, + NM_PCAUSE_T_MANUF, + PCU_NM_EVT_CAUSE_CRIT_NSVC_UNBLK_FAIL, + sig_data->add_text); + break; + default: break; } diff --git a/src/pcuif_proto.h b/src/pcuif_proto.h index e4604ba7..85a9040e 100644 --- a/src/pcuif_proto.h +++ b/src/pcuif_proto.h @@ -57,6 +57,9 @@ extern "C" { /* NuRAN Wireless manufacture-defined alarm causes */ enum pcu_nm_event_causes { /* Critical causes */ + PCU_NM_EVT_CAUSE_CRIT_NSVC_FAIL = 0x3310, + PCU_NM_EVT_CAUSE_CRIT_NSVC_RST_FAIL = 0x3311, + PCU_NM_EVT_CAUSE_CRIT_NSVC_UNBLK_FAIL = 0x3312, PCU_NM_EVT_CAUSE_CRIT_OPEN_L1_FAIL = 0x333b, PCU_NM_EVT_CAUSE_CRIT_OPEN_PDCH_FAIL = 0x3411, PCU_NM_EVT_CAUSE_CRIT_BAD_PCU_IF_VER = 0x3415, -- cgit v1.2.3