Merging parts of commit 653e974fec00414ba85baf258ccc46ea778a53bd
from branch nrw/litecell15
Original Author: Minh-Quang Nguyen <minh-quang.nguyen@nutaq.com>
LC15: Implementation of LC15 specific features
Made some modifications to this commit
based on d8cd756da4
Get rid of 'struct gsm_bts_role_bts'
Only compile tested.
This is just to get a start on this branch.
I have not yet looked at all other commits in the
nuran branch that may be related.
This one however, does seem to be important
as it implements a larger cell radius than
is currently possible with osmo master.
Change-Id: I79416faaa3ba328c9c2dabcd695a1b880fe666da
This commit is contained in:
parent
ae4d85d891
commit
9192c6c6c2
|
@ -783,6 +783,14 @@ struct gsm_bts {
|
||||||
} pcu;
|
} pcu;
|
||||||
|
|
||||||
void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
|
void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
|
||||||
|
#ifdef ENABLE_LC15BTS
|
||||||
|
/* specific to LC15 BTS */
|
||||||
|
struct {
|
||||||
|
uint8_t led_ctrl_mode; /* 0: control by BTS, 1: not control by BTS */
|
||||||
|
struct llist_head ceased_alarm_list; /* ceased alarm list*/
|
||||||
|
unsigned int rtp_drift_thres_ms; /* RTP timestamp drift detection threshold */
|
||||||
|
} lc15;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@ if ENABLE_LC15BTS
|
||||||
AM_CFLAGS += -DENABLE_LC15BTS
|
AM_CFLAGS += -DENABLE_LC15BTS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if ENABLE_LC15BTS
|
||||||
|
AM_CFLAGS += -DENABLE_LC15BTS
|
||||||
|
endif
|
||||||
|
|
||||||
noinst_LIBRARIES = libbts.a libl1sched.a
|
noinst_LIBRARIES = libbts.a libl1sched.a
|
||||||
libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \
|
libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \
|
||||||
rsl.c vty.c paging.c measurement.c amr.c lchan.c \
|
rsl.c vty.c paging.c measurement.c amr.c lchan.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",
|
LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n",
|
||||||
get_value_string(lc15bts_l1status_names, status));
|
get_value_string(lc15bts_l1status_names, status));
|
||||||
bts_shutdown(trx->bts, "RF-ACT failure");
|
bts_shutdown(trx->bts, "RF-ACT failure");
|
||||||
} else
|
} else {
|
||||||
bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
|
if(trx->bts->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS)
|
||||||
|
bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* signal availability */
|
/* signal availability */
|
||||||
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
|
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++)
|
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
|
||||||
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
||||||
} else {
|
} 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->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
|
||||||
oml_mo_state_chg(&trx->bb_transc.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,27 @@ int l1if_activate_rf(struct lc15l1_hdl *hdl, int on)
|
||||||
{
|
{
|
||||||
struct msgb *msg = sysp_msgb_alloc();
|
struct msgb *msg = sysp_msgb_alloc();
|
||||||
Litecell15_Prim_t *sysp = msgb_sysprim(msg);
|
Litecell15_Prim_t *sysp = msgb_sysprim(msg);
|
||||||
|
struct phy_instance *pinst = hdl->phy_inst;
|
||||||
|
|
||||||
if (on) {
|
if (on) {
|
||||||
sysp->id = Litecell15_PrimId_ActivateRfReq;
|
sysp->id = Litecell15_PrimId_ActivateRfReq;
|
||||||
sysp->u.activateRfReq.msgq.u8UseTchMsgq = 0;
|
sysp->u.activateRfReq.msgq.u8UseTchMsgq = 0;
|
||||||
sysp->u.activateRfReq.msgq.u8UsePdtchMsgq = pcu_direct;
|
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;
|
sysp->u.activateRfReq.u8McCorrMode = 0;
|
||||||
|
|
||||||
|
/* 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, 90 == 12.456 km */
|
/* maximum cell size in quarter-bits, 90 == 12.456 km */
|
||||||
sysp->u.activateRfReq.u8MaxCellSize = 90;
|
sysp->u.activateRfReq.u8MaxCellSize = pinst->u.lc15.max_cell_size;
|
||||||
|
|
||||||
|
/* auto tx power adjustment mode 0:none, 1: automatic*/
|
||||||
|
sysp->u.activateRfReq.autoPowerAdjust.u8EnAutoPowerAdjust = pinst->u.lc15.tx_pwr_adj_mode;
|
||||||
|
|
||||||
|
/* PSK modulation scheme maximum power level */
|
||||||
|
sysp->u.activateRfReq.autoPowerAdjust.u8PowerReduction8Psk = pinst->u.lc15.tx_pwr_red_8psk;
|
||||||
} else {
|
} else {
|
||||||
sysp->id = Litecell15_PrimId_DeactivateRfReq;
|
sysp->id = Litecell15_PrimId_DeactivateRfReq;
|
||||||
}
|
}
|
||||||
|
@ -1353,7 +1366,8 @@ static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
|
||||||
|
|
||||||
LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n",
|
LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n",
|
||||||
get_value_string(lc15bts_l1status_names, status));
|
get_value_string(lc15bts_l1status_names, status));
|
||||||
bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]);
|
if(trx->bts->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS)
|
||||||
|
bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]);
|
||||||
oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1);
|
oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1);
|
||||||
|
|
||||||
osmo_static_assert(
|
osmo_static_assert(
|
||||||
|
@ -1589,6 +1603,53 @@ int l1if_close(struct lc15l1_hdl *fl1h)
|
||||||
return 0;
|
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_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;
|
||||||
|
|
||||||
|
Litecell15_Prim_t *sys_prim = msgb_sysprim(msg);
|
||||||
|
sys_prim->id = Litecell15_PrimId_IsAliveReq;
|
||||||
|
|
||||||
|
if (fl1h->hw_alive.dsp_alive_cnt == 0) {
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
exit(23);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
int bts_model_phy_link_open(struct phy_link *plink)
|
||||||
{
|
{
|
||||||
struct phy_instance *pinst = phy_instance_by_num(plink, 0);
|
struct phy_instance *pinst = phy_instance_by_num(plink, 0);
|
||||||
|
@ -1608,6 +1669,24 @@ int bts_model_phy_link_open(struct phy_link *plink)
|
||||||
return -EIO;
|
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;
|
||||||
|
|
||||||
struct lc15l1_hdl *fl1h = pinst->u.lc15.hdl;
|
struct lc15l1_hdl *fl1h = pinst->u.lc15.hdl;
|
||||||
fl1h->dsp_trace_f = dsp_trace;
|
fl1h->dsp_trace_f = dsp_trace;
|
||||||
|
@ -1616,5 +1695,24 @@ int bts_model_phy_link_open(struct phy_link *plink)
|
||||||
|
|
||||||
phy_link_state_set(plink, PHY_LINK_CONNECTED);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,12 @@ struct lc15l1_hdl {
|
||||||
struct calib_send_state st;
|
struct calib_send_state st;
|
||||||
|
|
||||||
uint8_t last_rf_mute[8];
|
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)
|
#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h)
|
||||||
|
|
|
@ -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_MuteRfCnf: return L1P_T_CONF;
|
||||||
case Litecell15_PrimId_SetRxAttenReq: return L1P_T_REQ;
|
case Litecell15_PrimId_SetRxAttenReq: return L1P_T_REQ;
|
||||||
case Litecell15_PrimId_SetRxAttenCnf: return L1P_T_CONF;
|
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;
|
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_MuteRfCnf, "MUTE-RF.cnf" },
|
||||||
{ Litecell15_PrimId_SetRxAttenReq, "SET-RX-ATTEN.req" },
|
{ Litecell15_PrimId_SetRxAttenReq, "SET-RX-ATTEN.req" },
|
||||||
{ Litecell15_PrimId_SetRxAttenCnf, "SET-RX-ATTEN-CNF.cnf" },
|
{ Litecell15_PrimId_SetRxAttenCnf, "SET-RX-ATTEN-CNF.cnf" },
|
||||||
|
{ Litecell15_PrimId_IsAliveReq, "IS-ALIVE.req" },
|
||||||
|
{ Litecell15_PrimId_IsAliveCnf, "IS-ALIVE-CNF.cnf" },
|
||||||
{ 0, NULL }
|
{ 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_SetCalibTblReq: return Litecell15_PrimId_SetCalibTblCnf;
|
||||||
case Litecell15_PrimId_MuteRfReq: return Litecell15_PrimId_MuteRfCnf;
|
case Litecell15_PrimId_MuteRfReq: return Litecell15_PrimId_MuteRfCnf;
|
||||||
case Litecell15_PrimId_SetRxAttenReq: return Litecell15_PrimId_SetRxAttenCnf;
|
case Litecell15_PrimId_SetRxAttenReq: return Litecell15_PrimId_SetRxAttenCnf;
|
||||||
|
case Litecell15_PrimId_IsAliveReq: return Litecell15_PrimId_IsAliveCnf;
|
||||||
default: return -1; // Weak
|
default: return -1; // Weak
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,27 @@ enum l1prim_type {
|
||||||
L1P_T_IND,
|
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);
|
enum l1prim_type lc15bts_get_l1prim_type(GsmL1_PrimId_t id);
|
||||||
const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1];
|
const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1];
|
||||||
GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id);
|
GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id);
|
||||||
|
@ -61,4 +82,13 @@ enum pdch_cs {
|
||||||
|
|
||||||
const uint8_t pdch_msu_size[_NUM_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 */
|
||||||
|
|
||||||
#endif /* LC15BTS_H */
|
#endif /* LC15BTS_H */
|
||||||
|
|
|
@ -65,6 +65,31 @@ extern int lchan_activate(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
static struct gsm_bts *vty_bts;
|
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 */
|
/* configuration */
|
||||||
|
|
||||||
DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd,
|
DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd,
|
||||||
|
@ -321,8 +346,130 @@ DEFUN(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd,
|
||||||
return CMD_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts)
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
|
void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
|
||||||
|
@ -347,8 +494,27 @@ void bts_model_config_write_phy_inst(struct vty *vty, struct phy_instance *pinst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pinst->u.lc15.calib_path)
|
if (pinst->u.lc15.calib_path)
|
||||||
vty_out(vty, " trx-calibration-path %s%s",
|
vty_out(vty, " trx-calibration-path %s%s",
|
||||||
pinst->u.lc15.calib_path, VTY_NEWLINE);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int bts_model_vty_init(struct gsm_bts *bts)
|
int bts_model_vty_init(struct gsm_bts *bts)
|
||||||
|
@ -401,12 +567,20 @@ int bts_model_vty_init(struct gsm_bts *bts)
|
||||||
|
|
||||||
install_element(BTS_NODE, &cfg_bts_auto_band_cmd);
|
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_no_auto_band_cmd);
|
||||||
|
install_element(BTS_NODE, &cfg_bts_led_mode_cmd);
|
||||||
|
|
||||||
install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
|
install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
|
||||||
|
|
||||||
install_element(PHY_INST_NODE, &cfg_phy_dsp_trace_f_cmd);
|
install_element(PHY_INST_NODE, &cfg_phy_dsp_trace_f_cmd);
|
||||||
install_element(PHY_INST_NODE, &cfg_phy_no_dsp_trace_f_cmd);
|
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_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);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,8 @@ int bts_model_init(struct gsm_bts *bts)
|
||||||
|
|
||||||
bts->variant = BTS_OSMO_LITECELL15;
|
bts->variant = BTS_OSMO_LITECELL15;
|
||||||
bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3);
|
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;
|
||||||
rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd);
|
rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Error creating the OML router: %s rc=%d\n",
|
fprintf(stderr, "Error creating the OML router: %s rc=%d\n",
|
||||||
|
|
Loading…
Reference in New Issue