mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-pcu.git
synced 2025-11-03 13:43:32 +00:00
Compare commits
12 Commits
1.0.0
...
nrw/litece
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61755b9398 | ||
|
|
dd37758689 | ||
|
|
b85ae72f0c | ||
|
|
379649cfcd | ||
|
|
bfc6cec8a5 | ||
|
|
64d1cc25d0 | ||
|
|
7b883fffdc | ||
|
|
1c80421ddc | ||
|
|
66a1786fcd | ||
|
|
17c1f04e85 | ||
|
|
e781319708 | ||
|
|
d5415a22f1 |
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user