aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRafael Diniz <rafael@riseup.net>2020-04-01 15:21:45 -0300
committerRafael Diniz <rafael@riseup.net>2020-04-01 15:21:45 -0300
commit908d64a5720e7d995f55873f910dd8a67f557075 (patch)
tree7606896a0bace15ed4c34ebab5f4d5fe68b77174 /src
parentc4744ac24c686d53d8075f45ecbcc64bb46dc9fe (diff)
from nrw/litecell15 branch, with Keith improvements andrafael2k/lc15-adaptation
other code to be considered to merge. Change-Id: I2b86827ce468d34a08b0e9b38c76dfd47b64b44d
Diffstat (limited to 'src')
-rw-r--r--src/osmo-bts-litecell15/l1_if.c141
-rw-r--r--src/osmo-bts-litecell15/l1_if.h7
-rw-r--r--src/osmo-bts-litecell15/lc15bts.c15
-rw-r--r--src/osmo-bts-litecell15/lc15bts.h32
-rw-r--r--src/osmo-bts-litecell15/lc15bts_vty.c219
-rw-r--r--src/osmo-bts-litecell15/main.c4
6 files changed, 411 insertions, 7 deletions
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index abf48bcd..c6a50b37 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -1263,8 +1263,10 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n",
get_value_string(lc15bts_l1status_names, status));
bts_shutdown(trx->bts, "RF-ACT failure");
- } else
- bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
+ } else {
+ if(trx->bts->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS)
+ bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
+ }
/* signal availability */
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
@@ -1275,7 +1277,8 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
} else {
- bts_update_status(BTS_STATUS_RF_ACTIVE, 0);
+ if(trx->bts->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS)
+ bts_update_status(BTS_STATUS_RF_ACTIVE, 0);
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
}
@@ -1290,17 +1293,25 @@ int l1if_activate_rf(struct lc15l1_hdl *hdl, int on)
{
struct msgb *msg = sysp_msgb_alloc();
Litecell15_Prim_t *sysp = msgb_sysprim(msg);
+ struct phy_instance *pinst = hdl->phy_inst;
if (on) {
sysp->id = Litecell15_PrimId_ActivateRfReq;
sysp->u.activateRfReq.msgq.u8UseTchMsgq = 0;
sysp->u.activateRfReq.msgq.u8UsePdtchMsgq = pcu_direct;
- sysp->u.activateRfReq.u8UnusedTsMode = 0;
+ sysp->u.activateRfReq.u8UnusedTsMode = pinst->u.lc15.pedestal_mode;
sysp->u.activateRfReq.u8McCorrMode = 0;
- /* maximum cell size in quarter-bits, 90 == 12.456 km */
- sysp->u.activateRfReq.u8MaxCellSize = 90;
+ /* diversity mode: 0: SISO-A, 1: SISO-B, 2: MRC */
+ sysp->u.activateRfReq.u8DiversityMode = pinst->u.lc15.diversity_mode;
+
+ /* maximum cell size in quarter-bits, eg. 90 == 12.456 km */
+ sysp->u.activateRfReq.u8MaxCellSize = pinst->u.lc15.max_cell_size;
+
+ /* auto tx power adjustment mode 0:none, 1: automatic*/
+ sysp->u.activateRfReq.u8EnAutoPowerAdjust = pinst->u.lc15.tx_pwr_adj_mode;
+
} else {
sysp->id = Litecell15_PrimId_DeactivateRfReq;
}
@@ -1589,6 +1600,83 @@ 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++;
+ LOGP(DL1C, LOGL_DEBUG, "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;
+ struct oml_alarm_list *alarm_sent;
+
+ Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
+ sys_prim->id = Litecell15_PrimId_IsAliveReq;
+
+ if (fl1h->hw_alive.dsp_alive_cnt == 0) {
+#if 0
+ /* check for the alarm has already sent or not */
+ llist_for_each_entry(alarm_sent, &fl1h->alarm_list, list) {
+ llist_del(&alarm_sent->list);
+ if (alarm_sent->alarm_signal != S_NM_OML_BTS_DSP_ALIVE_ALARM)
+ continue;
+
+ LOGP(DL1C, LOGL_ERROR, "Alarm %d has removed from sent alarm list (%d)\n", alarm_sent->alarm_signal, trx->nr);
+ exit(23);
+ }
+#endif
+ LOGP(DL1C, LOGL_ERROR, "Timeout waiting for SYS prim %s primitive (%d)\n",
+ get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr);
+
+ if( fl1h->phy_inst->trx ){
+ fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
+
+#if 0
+ alarm_sig_data.mo = &fl1h->phy_inst->trx->mo;
+ memcpy(alarm_sig_data.spare, &sys_prim->id, sizeof(unsigned int));
+ osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_DSP_ALIVE_ALARM, &alarm_sig_data);
+ if (!alarm_sig_data.rc) {
+ /* allocate new list of sent alarms */
+ alarm_sent = talloc_zero(fl1h, struct oml_alarm_list);
+ if (!alarm_sent)
+ return -EIO;
+
+ alarm_sent->alarm_signal = S_NM_OML_BTS_DSP_ALIVE_ALARM;
+ /* add alarm to sent list */
+ llist_add(&alarm_sent->list, &fl1h->alarm_list);
+ LOGP(DL1C, LOGL_ERROR, "Alarm %d has added to sent alarm list (%d)\n", alarm_sent->alarm_signal, trx->nr);
+ }
+#endif
+ }
+ }
+
+ LOGP(DL1C, LOGL_DEBUG, "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);
@@ -1608,6 +1696,27 @@ int bts_model_phy_link_open(struct phy_link *plink)
return -EIO;
}
+ /* Set default PHY parameters */
+ if (!pinst->u.lc15.max_cell_size)
+ pinst->u.lc15.max_cell_size = LC15_BTS_MAX_CELL_SIZE_DEFAULT;
+
+ if (!pinst->u.lc15.diversity_mode)
+ pinst->u.lc15.diversity_mode = LC15_BTS_DIVERSITY_MODE_DEFAULT;
+
+ if (!pinst->u.lc15.pedestal_mode)
+ pinst->u.lc15.pedestal_mode = LC15_BTS_PEDESTAL_MODE_DEFAULT;
+
+ if (!pinst->u.lc15.dsp_alive_period)
+ pinst->u.lc15.dsp_alive_period = LC15_BTS_DSP_ALIVE_TMR_DEFAULT;
+
+ if (!pinst->u.lc15.tx_pwr_adj_mode)
+ pinst->u.lc15.tx_pwr_adj_mode = LC15_BTS_TX_PWR_ADJ_DEFAULT;
+
+ if (!pinst->u.lc15.tx_pwr_red_8psk)
+ pinst->u.lc15.tx_pwr_red_8psk = LC15_BTS_TX_RED_PWR_8PSK_DEFAULT;
+
+ if (!pinst->u.lc15.tx_c0_idle_pwr_red)
+ pinst->u.lc15.tx_c0_idle_pwr_red = LC15_BTS_TX_C0_IDLE_RED_PWR_DEFAULT;
struct lc15l1_hdl *fl1h = pinst->u.lc15.hdl;
fl1h->dsp_trace_f = dsp_trace;
@@ -1616,5 +1725,25 @@ 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 */
+ 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 = pinst->u.lc15.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 aac26075..f11c889a 100644
--- a/src/osmo-bts-litecell15/l1_if.h
+++ b/src/osmo-bts-litecell15/l1_if.h
@@ -41,6 +41,7 @@ struct lc15l1_hdl {
HANDLE hLayer1; /* handle to the L1 instance in the DSP */
uint32_t dsp_trace_f; /* currently operational DSP trace flags */
struct llist_head wlc_list;
+// struct llist_head alarm_list; /* list of sent alarms */
struct phy_instance *phy_inst;
@@ -62,6 +63,12 @@ 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;
};
#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..8ebc3a22 100644
--- a/src/osmo-bts-litecell15/lc15bts.c
+++ b/src/osmo-bts-litecell15/lc15bts.c
@@ -121,6 +121,12 @@ 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;
+ case Litecell15_PrimId_SetMaxCellSizeReq: return L1P_T_REQ;
+ case Litecell15_PrimId_SetMaxCellSizeCnf: return L1P_T_CONF;
+ case Litecell15_PrimId_SetC0IdleSlotPowerReductionReq: return L1P_T_REQ;
+ case Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf: return L1P_T_CONF;
default: return L1P_T_INVALID;
}
}
@@ -142,6 +148,12 @@ 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" },
+ { Litecell15_PrimId_SetMaxCellSizeReq, "SET-MAX-CELL-SIZE.req" },
+ { Litecell15_PrimId_SetMaxCellSizeCnf, "SET-MAX-CELL-SIZE.cnf" },
+ { Litecell15_PrimId_SetC0IdleSlotPowerReductionReq, "SET-C0-IDLE-PWR-RED.req" },
+ { Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf, "SET-C0-IDLE-PWR-RED.cnf" },
{ 0, NULL }
};
@@ -155,6 +167,9 @@ 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;
+ case Litecell15_PrimId_SetMaxCellSizeReq: return Litecell15_PrimId_SetMaxCellSizeCnf;
+ case Litecell15_PrimId_SetC0IdleSlotPowerReductionReq: return Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf;
default: return -1; // Weak
}
}
diff --git a/src/osmo-bts-litecell15/lc15bts.h b/src/osmo-bts-litecell15/lc15bts.h
index 4c40db0f..660dc6a1 100644
--- a/src/osmo-bts-litecell15/lc15bts.h
+++ b/src/osmo-bts-litecell15/lc15bts.h
@@ -22,6 +22,27 @@ enum l1prim_type {
L1P_T_IND,
};
+enum lc15_diversity_mode{
+ LC15_DIVERSITY_SISO_A = 0,
+ LC15_DIVERSITY_SISO_B,
+ LC15_DIVERSITY_MRC,
+};
+
+enum lc15_pedestal_mode{
+ LC15_PEDESTAL_OFF = 0,
+ LC15_PEDESTAL_ON,
+};
+
+enum lc15_led_control_mode{
+ LC15_LED_CONTROL_BTS = 0,
+ LC15_LED_CONTROL_EXT,
+};
+
+enum lc15_auto_pwr_adjust_mode{
+ LC15_TX_PWR_ADJ_NONE = 0,
+ LC15_TX_PWR_ADJ_AUTO,
+};
+
enum l1prim_type lc15bts_get_l1prim_type(GsmL1_PrimId_t id);
const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1];
GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id);
@@ -61,4 +82,15 @@ enum pdch_cs {
const uint8_t pdch_msu_size[_NUM_PDCH_CS];
+/* LC15 default parameters */
+#define LC15_BTS_MAX_CELL_SIZE_DEFAULT 166 /* 166 qbits is default value */
+#define LC15_BTS_DIVERSITY_MODE_DEFAULT 0 /* SISO-A is default mode */
+#define LC15_BTS_PEDESTAL_MODE_DEFAULT 0 /* Unused TS is off by default */
+#define LC15_BTS_LED_CTRL_MODE_DEFAULT 0 /* LED is controlled by BTS by default */
+#define LC15_BTS_DSP_ALIVE_TMR_DEFAULT 5 /* Default DSP alive timer is 5 seconds */
+#define LC15_BTS_TX_PWR_ADJ_DEFAULT 0 /* Default Tx power auto adjustment is none */
+#define LC15_BTS_TX_RED_PWR_8PSK_DEFAULT 0 /* Default 8-PSK maximum power level is 0 dB */
+#define LC15_BTS_RTP_DRIFT_THRES_DEFAULT 0 /* Default RTP drift threshold is 0 ms (disabled) */
+#define LC15_BTS_TX_C0_IDLE_RED_PWR_DEFAULT 0 /* Default C0 idle slot reduction power level is 0 dB */
+
#endif /* LC15BTS_H */
diff --git a/src/osmo-bts-litecell15/lc15bts_vty.c b/src/osmo-bts-litecell15/lc15bts_vty.c
index d27ec281..0a72d82f 100644
--- a/src/osmo-bts-litecell15/lc15bts_vty.c
+++ b/src/osmo-bts-litecell15/lc15bts_vty.c
@@ -65,6 +65,31 @@ extern int lchan_activate(struct gsm_lchan *lchan);
static struct gsm_bts *vty_bts;
+static const struct value_string lc15_diversity_mode_strs[] = {
+ { LC15_DIVERSITY_SISO_A, "siso-a" },
+ { LC15_DIVERSITY_SISO_B, "siso-b" },
+ { LC15_DIVERSITY_MRC, "mrc" },
+ { 0, NULL }
+};
+
+static const struct value_string lc15_pedestal_mode_strs[] = {
+ { LC15_PEDESTAL_OFF, "off" },
+ { LC15_PEDESTAL_ON, "on" },
+ { 0, NULL }
+};
+
+static const struct value_string lc15_led_mode_strs[] = {
+ { LC15_LED_CONTROL_BTS, "bts" },
+ { LC15_LED_CONTROL_EXT, "external" },
+ { 0, NULL }
+};
+
+static const struct value_string lc15_auto_adj_pwr_strs[] = {
+ { LC15_TX_PWR_ADJ_NONE, "none" },
+ { LC15_TX_PWR_ADJ_AUTO, "auto" },
+ { 0, NULL }
+};
+
/* configuration */
DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd,
@@ -321,8 +346,162 @@ DEFUN(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_phy_max_cell_size, cfg_phy_max_cell_size_cmd,
+ "max-cell-size <0-166>",
+ "Set the maximum cell size in qbits\n")
+{
+ struct phy_instance *pinst = vty->index;
+ int cell_size = (uint8_t)atoi(argv[0]);
+
+ if (( cell_size > 166 ) || ( cell_size < 0 )) {
+ vty_out(vty, "Max cell size must be between 0 and 166 qbits (%d) %s",
+ cell_size, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ pinst->u.lc15.max_cell_size = (uint8_t)cell_size;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_phy_diversity_mode, cfg_phy_diversity_mode_cmd,
+ "diversity-mode (siso-a|siso-b|mrc)",
+ "Set reception diversity mode \n"
+ "Reception diversity mode can be (siso-a, siso-b, mrc)\n")
+{
+ struct phy_instance *pinst = vty->index;
+ int val = get_string_value(lc15_diversity_mode_strs, argv[0]);
+
+ if((val < LC15_DIVERSITY_SISO_A) || (val > LC15_DIVERSITY_MRC)) {
+ vty_out(vty, "Invalid reception diversity mode %d%s", val, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ pinst->u.lc15.diversity_mode = (uint8_t)val;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_phy_pedestal_mode, cfg_phy_pedestal_mode_cmd,
+ "pedestal-mode (on|off)",
+ "Set unused time-slot transmission in pedestal mode\n"
+ "Transmission pedestal mode can be (off, on)\n")
+{
+ struct phy_instance *pinst = vty->index;
+ int val = get_string_value(lc15_pedestal_mode_strs, argv[0]);
+
+ if((val < LC15_PEDESTAL_OFF) || (val > LC15_PEDESTAL_ON)) {
+ vty_out(vty, "Invalid unused time-slot transmission mode %d%s", val, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ pinst->u.lc15.pedestal_mode = (uint8_t)val;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_led_mode, cfg_bts_led_mode_cmd,
+ "led-control-mode (bts|external)",
+ "Set LED controlled by BTS or external software\n"
+ "LED can be controlled by (bts, external)\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int val = get_string_value(lc15_led_mode_strs, argv[0]);
+
+ if((val < LC15_LED_CONTROL_BTS) || (val > LC15_LED_CONTROL_EXT)) {
+ vty_out(vty, "Invalid LED control mode %d%s", val, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bts->lc15.led_ctrl_mode = (uint8_t)val;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_phy_dsp_alive_timer, cfg_phy_dsp_alive_timer_cmd,
+ "dsp-alive-period <0-60>",
+ "Set DSP alive timer period in second\n")
+{
+ struct phy_instance *pinst = vty->index;
+ 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;
+ }
+
+ pinst->u.lc15.dsp_alive_period = period;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_phy_auto_tx_pwr_adj, cfg_phy_auto_tx_pwr_adj_cmd,
+ "pwr-adj-mode (none|auto)",
+ "Set output power adjustment mode\n")
+{
+ struct phy_instance *pinst = vty->index;
+ int val = get_string_value(lc15_auto_adj_pwr_strs, argv[0]);
+
+ if((val < LC15_TX_PWR_ADJ_NONE) || (val > LC15_TX_PWR_ADJ_AUTO)) {
+ vty_out(vty, "Invalid output power adjustment mode %d%s", val, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ pinst->u.lc15.tx_pwr_adj_mode = (uint8_t)val;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_phy_tx_red_pwr_8psk, cfg_phy_tx_red_pwr_8psk_cmd,
+ "tx-red-pwr-8psk <0-40>",
+ "Set reduction output power for 8-PSK scheme in dB unit\n")
+{
+ struct phy_instance *pinst = vty->index;
+ int val = atoi(argv[0]);
+
+ if ((val > 40) || (val < 0)) {
+ vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s",
+ val, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ pinst->u.lc15.tx_pwr_red_8psk = (uint8_t)val;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_phy_c0_idle_red_pwr, cfg_phy_c0_idle_red_pwr_cmd,
+ "c0-idle-red-pwr <0-40>",
+ "Set reduction output power for C0 idle slot in dB unit\n")
+{
+ struct phy_instance *pinst = vty->index;
+ int val = atoi(argv[0]);
+
+ if ((val > 40) || (val < 0)) {
+ vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s",
+ val, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ pinst->u.lc15.tx_c0_idle_pwr_red = (uint8_t)val;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_rtp_drift_threshold, cfg_bts_rtp_drift_threshold_cmd,
+ "rtp-drift-threshold <0-10000>",
+ "RTP parameters\n"
+ "RTP timestamp drift threshold in ms\n")
+{
+ struct gsm_bts *bts = vty->index;
+
+ bts->lc15.rtp_drift_thres_ms = (unsigned int) atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
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, bts->lc15.led_ctrl_mode), VTY_NEWLINE);
+
+ vty_out(vty, " rtp-drift-threshold %d%s",
+ bts->lc15.rtp_drift_thres_ms, VTY_NEWLINE);
+
}
void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
@@ -349,6 +528,28 @@ void bts_model_config_write_phy_inst(struct vty *vty, struct phy_instance *pinst
if (pinst->u.lc15.calib_path)
vty_out(vty, " trx-calibration-path %s%s",
pinst->u.lc15.calib_path, VTY_NEWLINE);
+
+ vty_out(vty, " max-cell-size %d%s",
+ pinst->u.lc15.max_cell_size, VTY_NEWLINE);
+
+ vty_out(vty, " diversity-mode %s%s",
+ get_value_string(lc15_diversity_mode_strs, pinst->u.lc15.diversity_mode), VTY_NEWLINE);
+
+ vty_out(vty, " pedestal-mode %s%s",
+ get_value_string(lc15_pedestal_mode_strs, pinst->u.lc15.pedestal_mode) , VTY_NEWLINE);
+
+ vty_out(vty, " dsp-alive-period %d%s",
+ pinst->u.lc15.dsp_alive_period, VTY_NEWLINE);
+
+ vty_out(vty, " pwr-adj-mode %s%s",
+ get_value_string(lc15_auto_adj_pwr_strs, pinst->u.lc15.tx_pwr_adj_mode), VTY_NEWLINE);
+
+ vty_out(vty, " tx-red-pwr-8psk %d%s",
+ pinst->u.lc15.tx_pwr_red_8psk, VTY_NEWLINE);
+
+ vty_out(vty, " c0-idle-red-pwr %d%s",
+ pinst->u.lc15.tx_c0_idle_pwr_red, VTY_NEWLINE);
+
}
int bts_model_vty_init(struct gsm_bts *bts)
@@ -401,6 +602,8 @@ int bts_model_vty_init(struct gsm_bts *bts)
install_element(BTS_NODE, &cfg_bts_auto_band_cmd);
install_element(BTS_NODE, &cfg_bts_no_auto_band_cmd);
+ install_element(BTS_NODE, &cfg_bts_led_mode_cmd);
+ install_element(BTS_NODE, &cfg_bts_rtp_drift_threshold_cmd);
install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
@@ -408,10 +611,24 @@ int bts_model_vty_init(struct gsm_bts *bts)
install_element(PHY_INST_NODE, &cfg_phy_no_dsp_trace_f_cmd);
install_element(PHY_INST_NODE, &cfg_phy_cal_path_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_diversity_mode_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_pedestal_mode_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_max_cell_size_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_dsp_alive_timer_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_auto_tx_pwr_adj_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_tx_red_pwr_8psk_cmd);
+ install_element(PHY_INST_NODE, &cfg_phy_c0_idle_red_pwr_cmd);
+
return 0;
}
int bts_model_ctrl_cmds_install(struct gsm_bts *bts)
{
- return 0;
+ int rc = 0;
+
+#if 0
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_lc15_oml_alert);
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_lc15_oml_ceased);
+#endif
+ return rc;
}
diff --git a/src/osmo-bts-litecell15/main.c b/src/osmo-bts-litecell15/main.c
index 6f3fc006..988a58b6 100644
--- a/src/osmo-bts-litecell15/main.c
+++ b/src/osmo-bts-litecell15/main.c
@@ -90,6 +90,10 @@ int bts_model_init(struct gsm_bts *bts)
bts->variant = BTS_OSMO_LITECELL15;
bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3);
+ /* specific default values for LC15 platform */
+ bts->lc15.led_ctrl_mode = LC15_BTS_LED_CTRL_MODE_DEFAULT;
+ /* RTP drift threshold default */
+ bts->lc15.rtp_drift_thres_ms = LC15_BTS_RTP_DRIFT_THRES_DEFAULT;
rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd);
if (rc < 0) {