aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinh-Quang Nguyen <minh-quang.nguyen@nutaq.com>2016-06-10 11:27:18 -0400
committerMinh-Quang Nguyen <minh-quang.nguyen@nutaq.com>2016-06-10 11:27:18 -0400
commit67d5b2a058acce21e74843a94999da1221eb2b07 (patch)
tree85311dcfd8e8469a2835b27b4c17e406b9ad76b3
parent5ec217da048344f54c0aef911939e2356bec3fee (diff)
LC15: Introduce DSP alive timer per TRX
-rw-r--r--include/osmo-bts/gsm_data.h1
-rw-r--r--src/osmo-bts-litecell15/l1_if.c88
-rw-r--r--src/osmo-bts-litecell15/l1_if.h7
-rw-r--r--src/osmo-bts-litecell15/lc15bts.c5
-rw-r--r--src/osmo-bts-litecell15/lc15bts.h1
-rw-r--r--src/osmo-bts-litecell15/lc15bts_vty.c22
-rw-r--r--src/osmo-bts-litecell15/main.c1
7 files changed, 125 insertions, 0 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 001dacb7..ef569f83 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -118,6 +118,7 @@ struct gsm_bts_role_bts {
uint8_t pedestal_mode; /* 0: unused TS is OFF, 1: unused TS is in minimum Tx power */
uint8_t led_ctrl_mode; /* 0: control by BTS, 1: not control by BTS */
uint8_t pwr_red_step; /* Tx power reduction steps in 1 dB or 2 dB */
+ uint8_t dsp_alive_period; /* DSP alive timer period */
uint8_t tx_pwr_adj_mode; /* 0: no auto adjust power, 1: auto adjust power using RMS detector */
uint8_t tx_pwr_red_8psk; /* 8-PSK maximum Tx power reduction level in dB */
#endif
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 78be4edc..79558cf5 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -66,6 +66,7 @@
#include "misc/lc15bts_par.h"
#include "misc/lc15bts_bid.h"
#include "utils.h"
+#include "osmo-bts/oml.h"
extern unsigned int dsp_trace;
@@ -1396,6 +1397,73 @@ int l1if_close(struct lc15l1_hdl *fl1h)
return 0;
}
+static void dsp_alive_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data)
+{
+ Litecell15_Prim_t *sysp = msgb_sysprim(resp);
+ Litecell15_IsAliveCnf_t *sac = &sysp->u.IsAliveCnf;
+ struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
+
+ fl1h->hw_alive.dsp_alive_cnt++;
+ fl1h->failure_rep_sent = 0;
+ LOGP(DL1C, LOGL_NOTICE, "Rx SYS prim %s, status=%d (%d)\n",
+ get_value_string(lc15bts_sysprim_names, sysp->id), sac->status, trx->nr);
+
+ msgb_free(resp);
+}
+
+static int dsp_alive_timer_cb(void *data)
+{
+ struct lc15l1_hdl *fl1h = data;
+ struct gsm_bts_trx *trx = fl1h->phy_inst->trx;
+ struct msgb *msg = sysp_msgb_alloc();
+ int rc;
+ char log_msg[100];
+ struct gsm_failure_evt_rep failure_rep;
+
+ Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
+ sys_prim->id = Litecell15_PrimId_IsAliveReq;
+
+ if (fl1h->hw_alive.dsp_alive_cnt == 0) {
+
+ if(fl1h->failure_rep_sent)
+ exit(23);
+
+ snprintf(log_msg, 100, "Timeout waiting for SYS prim %s primitive (%d)\n",
+ get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr);
+
+ LOGP(DL1C, LOGL_ERROR,"%s", log_msg);
+
+ if( fl1h->phy_inst->trx ){
+ failure_rep.event_type = NM_EVT_PROC_FAIL;
+ failure_rep.event_serverity = NM_SEVER_CRITICAL;
+ failure_rep.cause_type = NM_PCAUSE_T_MANUF;
+ failure_rep.event_cause = NM_MM_EVT_CRIT_SW_FATAL;
+ failure_rep.add_text = (char *)&log_msg;
+
+ fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
+
+ rc = oml_tx_failure_event_rep(&fl1h->phy_inst->trx->mo, failure_rep);
+ if(!rc)
+ fl1h->failure_rep_sent = 1;
+ }
+ }
+
+ LOGP(DL1C, LOGL_NOTICE, "Tx SYS prim %s (%d)\n",
+ get_value_string(lc15bts_sysprim_names, sys_prim->id), trx->nr);
+
+ rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL);
+ if (rc < 0) {
+ LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id));
+ return -EIO;
+ }
+
+ /* restart timer */
+ fl1h->hw_alive.dsp_alive_cnt = 0;
+ osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0);
+
+ return 0;
+}
+
int bts_model_phy_link_open(struct phy_link *plink)
{
struct phy_instance *pinst = phy_instance_by_num(plink, 0);
@@ -1423,6 +1491,26 @@ int bts_model_phy_link_open(struct phy_link *plink)
phy_link_state_set(plink, PHY_LINK_CONNECTED);
+ /* Send first IS_ALIVE primitive */
+ struct msgb *msg = sysp_msgb_alloc();
+ int rc;
+
+ Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
+ sys_prim->id = Litecell15_PrimId_IsAliveReq;
+
+ rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL);
+ if (rc < 0) {
+ LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id));
+ return -EIO;
+ }
+
+ /* initialize DSP heart beat alive timer */
+ struct gsm_bts_role_bts *btsb = bts_role_bts(pinst->trx->bts);
+ fl1h->hw_alive.dsp_alive_timer.cb = dsp_alive_timer_cb;
+ fl1h->hw_alive.dsp_alive_timer.data = fl1h;
+ fl1h->hw_alive.dsp_alive_cnt = 0;
+ fl1h->hw_alive.dsp_alive_period = btsb->dsp_alive_period;
+ osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0);
return 0;
}
diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h
index 0c8843bd..ad75ea66 100644
--- a/src/osmo-bts-litecell15/l1_if.h
+++ b/src/osmo-bts-litecell15/l1_if.h
@@ -59,6 +59,13 @@ struct lc15l1_hdl {
struct calib_send_state st;
uint8_t last_rf_mute[8];
+
+ struct {
+ struct osmo_timer_list dsp_alive_timer;
+ unsigned int dsp_alive_cnt;
+ uint8_t dsp_alive_period;
+ } hw_alive;
+ uint8_t failure_rep_sent; /* Flag to indicate the failure report has already sent to network before stop BTS itself*/
};
#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h)
diff --git a/src/osmo-bts-litecell15/lc15bts.c b/src/osmo-bts-litecell15/lc15bts.c
index 172a7e45..6ce82e34 100644
--- a/src/osmo-bts-litecell15/lc15bts.c
+++ b/src/osmo-bts-litecell15/lc15bts.c
@@ -121,6 +121,8 @@ enum l1prim_type lc15bts_get_sysprim_type(Litecell15_PrimId_t id)
case Litecell15_PrimId_MuteRfCnf: return L1P_T_CONF;
case Litecell15_PrimId_SetRxAttenReq: return L1P_T_REQ;
case Litecell15_PrimId_SetRxAttenCnf: return L1P_T_CONF;
+ case Litecell15_PrimId_IsAliveReq: return L1P_T_REQ;
+ case Litecell15_PrimId_IsAliveCnf: return L1P_T_CONF;
default: return L1P_T_INVALID;
}
}
@@ -142,6 +144,8 @@ const struct value_string lc15bts_sysprim_names[Litecell15_PrimId_NUM+1] = {
{ Litecell15_PrimId_MuteRfCnf, "MUTE-RF.cnf" },
{ Litecell15_PrimId_SetRxAttenReq, "SET-RX-ATTEN.req" },
{ Litecell15_PrimId_SetRxAttenCnf, "SET-RX-ATTEN-CNF.cnf" },
+ { Litecell15_PrimId_IsAliveReq, "IS-ALIVE.req" },
+ { Litecell15_PrimId_IsAliveCnf, "IS-ALIVE-CNF.cnf" },
{ 0, NULL }
};
@@ -155,6 +159,7 @@ Litecell15_PrimId_t lc15bts_get_sysprim_conf(Litecell15_PrimId_t id)
case Litecell15_PrimId_SetCalibTblReq: return Litecell15_PrimId_SetCalibTblCnf;
case Litecell15_PrimId_MuteRfReq: return Litecell15_PrimId_MuteRfCnf;
case Litecell15_PrimId_SetRxAttenReq: return Litecell15_PrimId_SetRxAttenCnf;
+ case Litecell15_PrimId_IsAliveReq: return Litecell15_PrimId_IsAliveCnf;
default: return -1; // Weak
}
}
diff --git a/src/osmo-bts-litecell15/lc15bts.h b/src/osmo-bts-litecell15/lc15bts.h
index cada00d3..a00c48f5 100644
--- a/src/osmo-bts-litecell15/lc15bts.h
+++ b/src/osmo-bts-litecell15/lc15bts.h
@@ -88,6 +88,7 @@ const uint8_t pdch_msu_size[_NUM_PDCH_CS];
#define GSM_BTS_PEDESTAL_MODE_DEFAULT 0 /* Unused TS is off by default */
#define GSM_BTS_LED_CTRL_MODE_DEFAULT 0 /* LED is controlled by BTS by default */
#define GSM_BTS_PWR_RED_STEP_DEFAULT 2 /* Default Tx power reduction step is 2 dB */
+#define GSM_BTS_DSP_ALIVE_TMR_DEFAULT 5 /* Default DSP alive timer is 5 seconds */
#define GSM_BTS_TX_PWR_ADJ_DEFAULT 0 /* Default Tx power auto adjustment is none */
#define GSM_BTS_TX_RED_PWR_8PSK_DEFAULT 0 /* Default 8-PSK maximum power level is 0 dB */
diff --git a/src/osmo-bts-litecell15/lc15bts_vty.c b/src/osmo-bts-litecell15/lc15bts_vty.c
index 1b2ff616..41505049 100644
--- a/src/osmo-bts-litecell15/lc15bts_vty.c
+++ b/src/osmo-bts-litecell15/lc15bts_vty.c
@@ -448,6 +448,24 @@ DEFUN(cfg_bts_pwr_red_step, cfg_bts_pwr_red_step_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_dsp_alive_timer, cfg_bts_dsp_alive_timer_cmd,
+ "dsp-alive-period <0-60>",
+ "Set DSP alive timer period in second\n")
+{
+ struct gsm_bts *bts = vty->index;;
+ struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
+ uint8_t period = (uint8_t)atoi(argv[0]);
+
+ if (( period > 60 ) || ( period < 0 )) {
+ vty_out(vty, "DSP heart beat alive timer period must be between 0 and 60 seconds (%d) %s",
+ period, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ btsb->dsp_alive_period = period;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_bts_auto_tx_pwr_adj, cfg_bts_auto_tx_pwr_adj_cmd,
"pwr-adj-mode (none|auto)",
"Set output power adjustment mode\n")
@@ -499,6 +517,9 @@ void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " led-control-mode %s%s",
get_value_string(lc15_led_mode_strs, btsb->led_ctrl_mode), VTY_NEWLINE);
+ vty_out(vty, " dsp-alive-period %d%s",
+ btsb->dsp_alive_period, VTY_NEWLINE);
+
vty_out(vty, " pwr-adj-mode %s%s",
get_value_string(lc15_auto_adj_pwr_strs, btsb->tx_pwr_adj_mode), VTY_NEWLINE);
@@ -596,6 +617,7 @@ int bts_model_vty_init(struct gsm_bts *bts)
install_element(BTS_NODE, &cfg_bts_led_mode_cmd);
install_element(BTS_NODE, &cfg_bts_max_cell_size_cmd);
install_element(BTS_NODE, &cfg_bts_pwr_red_step_cmd);
+ install_element(BTS_NODE, &cfg_bts_dsp_alive_timer_cmd);
install_element(BTS_NODE, &cfg_bts_auto_tx_pwr_adj_cmd);
install_element(BTS_NODE, &cfg_bts_tx_red_pwr_8psk_cmd);
diff --git a/src/osmo-bts-litecell15/main.c b/src/osmo-bts-litecell15/main.c
index ce30021f..6a2509b6 100644
--- a/src/osmo-bts-litecell15/main.c
+++ b/src/osmo-bts-litecell15/main.c
@@ -78,6 +78,7 @@ int bts_model_init(struct gsm_bts *bts)
btsb->diversity_mode = GSM_BTS_DIVERSITY_MODE_DEFAULT;
btsb->pedestal_mode = GSM_BTS_PEDESTAL_MODE_DEFAULT;
btsb->pwr_red_step = GSM_BTS_PWR_RED_STEP_DEFAULT;
+ btsb->dsp_alive_period = GSM_BTS_DSP_ALIVE_TMR_DEFAULT;
btsb->tx_pwr_adj_mode = GSM_BTS_TX_PWR_ADJ_DEFAULT;
btsb->tx_pwr_red_8psk = GSM_BTS_TX_RED_PWR_8PSK_DEFAULT;