Compare commits

...

12 Commits

Author SHA1 Message Date
Minh-Quang Nguyen
61755b9398 Implementation of unknown NSVC alarm.
The alarm cause ID is defined by NuRAN Wireless.

Change-Id: I48ee1c23cd299b5208487472d802d339c55c99e6
2016-09-08 11:34:54 -04:00
Minh-Quang Nguyen
dd37758689 Implementation of unknown BVCI alarm.
The alarms ID is manufacture-defined by NuRAN Wireless

Change-Id: Iab6d4938f5ab2bc1cc637da54e92931519f95cbb
2016-09-08 11:11:28 -04:00
Minh-Quang Nguyen
b85ae72f0c Implementation of PTP BVC failure alarm
The alarm cause ID is manufacture-defined by NuRAN Wireless

Change-Id: I29b8aa4f247d5676a26e7e7f3fb862276136fad3
2016-09-08 09:59:05 -04:00
Minh-Quang Nguyen
379649cfcd 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
2016-09-07 14:21:48 -04:00
Minh-Quang Nguyen
bfc6cec8a5 LC15: Implementation of PDTCH queue is full alarm.
The alarm cause ID is manufacture-defined by NuRAN Wireless.

Change-Id: I9ea5146f9940177e08c9f0b3087b0ab4b0c170d9
2016-09-07 14:21:38 -04:00
Minh-Quang Nguyen
64d1cc25d0 LC15: Implementation of receiving unknown BTS message alarm.
The alarm cause ID is manufacture-defined by NuRAN Wireless.

Change-Id: I0c86d987d9e36779ac5ffba184038b906effbc16
2016-09-07 10:21:54 -04:00
Minh-Quang Nguyen
7b883fffdc LC15: Implementation of receiving unknown L1 primitive message alarm.
The alarm cause ID is manufacture-defined by NuRAN Wireless.

Change-Id: I22bb10b795bdc403af259e68f652b7b5b11dcb57
2016-09-07 10:01:20 -04:00
Minh-Quang Nguyen
1c80421ddc LC15: Implementation of receiving unknown L1 SAP message alarm.
The alarm cause ID is manufacture-defined by NuRAN Wireless.

Change-Id: Ieab57aff503f86cbcf7a91e088cb1a8ea790557f
2016-09-07 09:54:36 -04:00
Minh-Quang Nguyen
66a1786fcd Implementation of no PDCH available alarm.
The alarm cause ID is defined by NuRAN Wireless.

Change-Id: I382c14b57a062ec7eb4c8421767896df581de634
2016-09-07 09:50:28 -04:00
Minh-Quang Nguyen
17c1f04e85 LC15: Implementation of L1 transport open failure alarm.
The alarm cause ID is manufacture-defined by NuRAN Wireless

Change-Id: I401d81b9bf6af82c9ea08329d89f9f720bae7003
2016-09-07 09:15:35 -04:00
Minh-Quang Nguyen
e781319708 Implementation of direct DSP access failure alarm.
The alarm cause ID is manufacture-defined by NuRAN Wireless

Change-Id: I14a8d15b9a0f9b823d850ba2582e62bb39fc9734
2016-09-07 09:00:46 -04:00
Minh-Quang Nguyen
d5415a22f1 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
2016-09-07 08:39:55 -04:00
10 changed files with 401 additions and 1 deletions

View File

@@ -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

View File

@@ -24,9 +24,11 @@
#include <bts.h>
#include <tbf.h>
#include <decoding.h>
#include <pcuif_proto.h>
#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)
{
@@ -360,6 +363,8 @@ static int gprs_bssgp_pcu_rcvmsg(struct msgb *msg)
LOGP(DBSSGP, LOGL_NOTICE, "NSEI=%u/BVCI=%u Rejecting PDU "
"type %u for unknown BVCI\n", msgb_nsei(msg), ns_bvci,
pdu_type);
memcpy(alarm_sig_data.spare, &ns_bvci, sizeof(uint16_t));
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_UNKN_NSEI_BVCI_ALARM, &alarm_sig_data);
return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, NULL, msg);
}
@@ -384,6 +389,10 @@ static int gprs_bssgp_pcu_rcvmsg(struct msgb *msg)
{
LOGP(DBSSGP, LOGL_DEBUG, "rx BVCI_PTP gprs_bssgp_rx_ptp\n");
rc = gprs_bssgp_pcu_rx_ptp(msg, &tp, bctx);
if (rc < 0) {
memcpy(alarm_sig_data.spare, &ns_bvci, sizeof(uint16_t));
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_FAIL_PTP_BVC_ALARM, &alarm_sig_data);
}
}
return rc;
}
@@ -479,6 +488,8 @@ static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
nssd = (struct ns_signal_data *)signal_data;
if (nssd->nsvc != the_pcu.nsvc) {
LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");
memcpy(alarm_sig_data.spare, &nssd->nsvc->nsvci, sizeof(uint16_t));
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_UNKN_NSVC_ALARM, &alarm_sig_data);
return -EINVAL;
}
@@ -507,6 +518,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 +794,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 +833,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 +908,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 +976,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);
}

View File

@@ -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;

View File

@@ -32,6 +32,7 @@
#include <lc15_l1_if.h>
#include <gprs_debug.h>
#include <pcu_l1_if.h>
#include <pcuif_proto.h>
extern void *tall_pcu_ctx;
@@ -225,6 +226,9 @@ static int handle_ph_data_ind(struct lc15l1_hdl *fl1h,
default:
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
get_value_string(lc15bts_l1sapi_names, data_ind->sapi));
memcpy(alarm_sig_data.spare, &data_ind->sapi, sizeof(unsigned int));
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_RX_UNKN_L1_SAP_ALARM, &alarm_sig_data);
break;
}
@@ -294,6 +298,7 @@ int l1if_handle_l1prim(int wq, struct lc15l1_hdl *fl1h, struct msgb *msg)
rc = handle_ph_ra_ind(fl1h, &l1p->u.phRaInd);
break;
default:
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_RX_UNKN_L1_PRIM_ALARM, &alarm_sig_data);
break;
}
@@ -347,6 +352,7 @@ int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn,
/* transmit */
if (osmo_wqueue_enqueue(&fl1h->write_q[MQ_PDTCH_WRITE], msg) != 0) {
LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n");
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_PDTCH_QUEUE_FULL_ALARM, &alarm_sig_data);
msgb_free(msg);
}
@@ -371,6 +377,8 @@ void *l1if_open_pdch(uint8_t trx_no, uint32_t hlayer1)
rc = l1if_transport_open(MQ_PDTCH_WRITE, fl1h);
if (rc < 0) {
alarm_sig_data.spare[0] = trx_no;
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_FAIL_OPEN_L1_ALARM, &alarm_sig_data);
talloc_free(fl1h);
return NULL;
}

View File

@@ -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;

View File

@@ -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");
@@ -466,6 +502,9 @@ bssgp_failed:
if (!bts->trx[trx].fl1h) {
LOGP(DL1IF, LOGL_FATAL, "Failed to open direct "
"DSP access for PDCH.\n");
alarm_sig_data.spare[0] = trx;
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_FAIL_OPEN_PDCH_ALARM, &alarm_sig_data);
exit(0);
}
#else
@@ -534,6 +573,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:
@@ -560,8 +609,198 @@ int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
default:
LOGP(DL1IF, LOGL_ERROR, "Received unknwon PCU msg type %d\n",
msg_type);
alarm_sig_data.spare[0] = msg_type;
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_RX_UNKN_MSG_ALARM, &alarm_sig_data);
rc = -EINVAL;
}
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];
uint16_t val;
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;
#ifdef ENABLE_DIRECT_PHY
case S_PCU_NM_FAIL_OPEN_PDCH_ALARM:
snprintf(log_msg, 100, "PCU: Failed to open direct DSP (%d) access for PDCH.\n", sig_data->spare[0]);
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_OPEN_PDCH_FAIL,
sig_data->add_text);
break;
case S_PCU_NM_FAIL_OPEN_L1_ALARM:
snprintf(log_msg, 100, "PCU: Failed to open L1 transport for TRX %d", sig_data->spare[0]);
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_OPEN_L1_FAIL,
sig_data->add_text);
break;
case S_PCU_NM_RX_UNKN_L1_SAP_ALARM:
memcpy(&res, sig_data->spare, sizeof(unsigned int));
snprintf(log_msg, 100, "PCU: Rx PH-DATA.ind for unknown L1 SAPI 0x%x\n", res);
sig_data->add_text = &log_msg[0];
rc = pcu_tx_nm_fail_evt(NM_EVT_PROC_FAIL,
NM_SEVER_MAJOR,
NM_PCAUSE_T_MANUF,
PCU_NM_EVT_CAUSE_MAJ_UKWN_L1_MSG,
sig_data->add_text);
break;
case S_PCU_NM_RX_UNKN_L1_PRIM_ALARM:
memcpy(&res, sig_data->spare, sizeof(unsigned int));
snprintf(log_msg, 100, "PCU: Rx unknown L1 primitive type 0x%x\n", res);
sig_data->add_text = &log_msg[0];
rc = pcu_tx_nm_fail_evt(NM_EVT_PROC_FAIL,
NM_SEVER_MAJOR,
NM_PCAUSE_T_MANUF,
PCU_NM_EVT_CAUSE_MAJ_UKWN_L1_PRIM_MSG,
sig_data->add_text);
break;
case S_PCU_NM_PDTCH_QUEUE_FULL_ALARM:
rc = pcu_tx_nm_fail_evt(NM_EVT_PROC_FAIL,
NM_SEVER_MAJOR,
NM_PCAUSE_T_MANUF,
PCU_NM_EVT_CAUSE_MAJ_PDTCH_QUEUE_FULL,
"PCU: PDTCH queue full. PCU is dropping message.\n");
break;
#endif
case S_PCU_NM_NO_PDCH_ALARM:
rc = pcu_tx_nm_fail_evt(NM_EVT_PROC_FAIL,
NM_SEVER_WARNING,
NM_PCAUSE_T_MANUF,
PCU_NM_EVT_CAUSE_WARN_NO_PDCH_AVAIL,
"PCU no PDCH available\n");
break;
case S_PCU_NM_RX_UNKN_MSG_ALARM:
snprintf(log_msg, 100, "PCU: Rx unknown BTS message type 0x%x\n", sig_data->spare[0]);
sig_data->add_text = &log_msg[0];
rc = pcu_tx_nm_fail_evt(NM_EVT_PROC_FAIL,
NM_SEVER_MAJOR,
NM_PCAUSE_T_MANUF,
PCU_NM_EVT_CAUSE_MAJ_UKWN_BTS_MSG,
sig_data->add_text);
break;
case S_PCU_NM_FAIL_NSVC_ALARM:
memcpy(&val, sig_data->spare, sizeof(uint16_t));
snprintf(log_msg, 100, "PCU: NS-VC %d failure\n", val);
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(&val, sig_data->spare, sizeof(uint16_t));
snprintf(log_msg, 100, "PCU: NS-VC %d reset failure\n", val);
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(&val, sig_data->spare, sizeof(uint16_t));
snprintf(log_msg, 100, "PCU: NS-VC %d unblock failure\n", val);
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;
case S_PCU_NM_FAIL_PTP_BVC_ALARM:
memcpy(&val, sig_data->spare, sizeof(uint16_t));
snprintf(log_msg, 100, "PCU:BVCI %d PTP failure\n", val);
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_MAJ_PTP_BVC_FAIL,
sig_data->add_text);
break;
case S_PCU_NM_UNKN_NSEI_BVCI_ALARM:
memcpy(&val, sig_data->spare, sizeof(uint16_t));
snprintf(log_msg, 100, "PCU: Rx unknown BVCI %d\n", val);
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_MAJ_UNKN_NSEI_BVCI,
sig_data->add_text);
break;
case S_PCU_NM_UNKN_NSVC_ALARM:
memcpy(&val, sig_data->spare, sizeof(uint16_t));
snprintf(log_msg, 100, "PCU: Rx unknown NSVC %d\n", val);
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_MAJ_UNKN_NSVC,
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);
}

View File

@@ -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

View File

@@ -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);

View File

@@ -3,6 +3,15 @@
#include <osmocom/gsm/l1sap.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/core/signal.h>
#ifdef __cplusplus
}
#endif
#define PCU_IF_VERSION 0x07
/* msg_type */
@@ -16,6 +25,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 +54,60 @@
#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_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,
/* Major causes */
PCU_NM_EVT_CAUSE_MAJ_UKWN_L1_MSG = 0x3012,
PCU_NM_EVT_CAUSE_MAJ_UKWN_L1_PRIM_MSG = 0x3013,
PCU_NM_EVT_CAUSE_MAJ_UKWN_BTS_MSG = 0x3014,
PCU_NM_EVT_CAUSE_MAJ_PDTCH_QUEUE_FULL = 0x333a,
PCU_NM_EVT_CAUSE_MAJ_UNKN_NSVC = 0x3314,
PCU_NM_EVT_CAUSE_MAJ_UNKN_NSEI_BVCI = 0x3317,
PCU_NM_EVT_CAUSE_MAJ_PTP_BVC_FAIL = 0x3318,
/* 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 +204,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 +228,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 */

View File

@@ -29,6 +29,7 @@
#include <gprs_ms.h>
#include <decoding.h>
#include <pcu_utils.h>
#include <pcuif_proto.h>
extern "C" {
#include <osmocom/core/msgb.h>
@@ -282,6 +283,7 @@ gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
/* FIXME: send reject */
osmo_signal_dispatch(SS_L_GLOBAL, S_PCU_NM_NO_PDCH_ALARM, &alarm_sig_data);
return NULL;
}
tbf->m_contention_resolution_done = 1;