summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/settings.h24
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/support.h12
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/vty.h1
-rw-r--r--src/host/layer23/src/mobile/gsm48_mm.c14
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c103
-rw-r--r--src/host/layer23/src/mobile/mnccms.c36
-rw-r--r--src/host/layer23/src/mobile/settings.c27
-rw-r--r--src/host/layer23/src/mobile/support.c83
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c505
9 files changed, 570 insertions, 235 deletions
diff --git a/src/host/layer23/include/osmocom/bb/mobile/settings.h b/src/host/layer23/include/osmocom/bb/mobile/settings.h
index 131e04f7..4c66f348 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/settings.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/settings.h
@@ -15,7 +15,6 @@ struct gsm_settings {
/* network search */
int plmn_mode; /* PLMN_MODE_* */
- int8_t min_rxlev_db; /* min DB to access */
/* SIM */
int sim_type; /* selects card on power on */
@@ -42,6 +41,29 @@ struct gsm_settings {
uint8_t stick;
uint16_t stick_arfcn;
uint8_t no_lupd;
+
+ /* supported by configuration */
+ uint8_t sms_ptp;
+ uint8_t a5_1;
+ uint8_t a5_2;
+ uint8_t a5_3;
+ uint8_t a5_4;
+ uint8_t a5_5;
+ uint8_t a5_6;
+ uint8_t a5_7;
+ uint8_t p_gsm;
+ uint8_t e_gsm;
+ uint8_t r_gsm;
+ uint8_t dcs;
+ uint8_t class_900;
+ uint8_t class_dcs;
+ uint8_t full_v1;
+ uint8_t full_v2;
+ uint8_t full_v3;
+ uint8_t half_v1;
+ uint8_t half_v3;
+ uint8_t ch_cap; /* channel capability */
+ int8_t min_rxlev_db; /* min DB to access */
};
int gsm_settings_init(struct osmocom_ms *ms);
diff --git a/src/host/layer23/include/osmocom/bb/mobile/support.h b/src/host/layer23/include/osmocom/bb/mobile/support.h
index e10888f3..b609b7da 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/support.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/support.h
@@ -17,9 +17,6 @@
struct gsm_support {
struct osmocom_ms *ms;
- /* rf power capability */
- uint8_t pwr_lev_900; /* and < 900 */
- uint8_t pwr_lev_1800; /* DCS and PCS */
/* controlled early classmark sending */
uint8_t es_ind;
/* revision level */
@@ -52,10 +49,9 @@ struct gsm_support {
uint8_t p_gsm;
uint8_t e_gsm;
uint8_t r_gsm;
- uint8_t r_capa;
- uint8_t low_capa;
- uint8_t dcs_1800;
- uint8_t dcs_capa;
+ uint8_t dcs;
+ uint8_t class_900;
+ uint8_t class_dcs;
uint8_t freq_map[128];
/* multi slot support */
uint8_t ms_sup;
@@ -98,7 +94,7 @@ struct gsm_support_scan_max {
extern struct gsm_support_scan_max gsm_sup_smax[];
void gsm_support_init(struct osmocom_ms *ms);
-void gsm_support_dump(struct gsm_support *sup,
+void gsm_support_dump(struct osmocom_ms *ms,
void (*print)(void *, const char *, ...), void *priv);
#endif /* _SUPPORT_H */
diff --git a/src/host/layer23/include/osmocom/bb/mobile/vty.h b/src/host/layer23/include/osmocom/bb/mobile/vty.h
index 70faef5b..1f1341bc 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/vty.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/vty.h
@@ -9,6 +9,7 @@
enum ms_vty_node {
MS_NODE = _LAST_OSMOVTY_NODE + 1,
TESTSIM_NODE,
+ SUPPORT_NODE,
};
enum node_type ms_vty_go_parent(struct vty *vty);
diff --git a/src/host/layer23/src/mobile/gsm48_mm.c b/src/host/layer23/src/mobile/gsm48_mm.c
index 3920d3f4..c955f897 100644
--- a/src/host/layer23/src/mobile/gsm48_mm.c
+++ b/src/host/layer23/src/mobile/gsm48_mm.c
@@ -1683,6 +1683,7 @@ static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim)
struct gsm_subscriber *subscr = &ms->subscr;
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct msgb *nmsg;
struct gsm48_hdr *ngh;
@@ -1703,10 +1704,10 @@ static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim)
/* classmark 1 */
if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
- pwr_lev = sup->pwr_lev_1800;
+ pwr_lev = sup->class_dcs - 1;
else
- pwr_lev = sup->pwr_lev_900;
- gsm48_encode_classmark1(&cm, sup->rev_lev, sup->es_ind, sup->a5_1,
+ pwr_lev = sup->class_900 - 1;
+ gsm48_encode_classmark1(&cm, sup->rev_lev, sup->es_ind, set->a5_1,
pwr_lev);
msgb_v_put(nmsg, *((uint8_t *)&cm));
/* MI */
@@ -2174,6 +2175,7 @@ static int gsm48_mm_loc_upd_ignore(struct osmocom_ms *ms, struct msgb *msg)
static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
{
struct gsm48_mmlayer *mm = &ms->mmlayer;
+ struct gsm_settings *set = &ms->settings;
struct gsm_support *sup = &ms->support;
struct gsm_subscriber *subscr = &ms->subscr;
struct gsm48_rrlayer *rr = &ms->rrlayer;
@@ -2205,11 +2207,11 @@ static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
gsm48_encode_lai(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac);
/* classmark 1 */
if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
- pwr_lev = sup->pwr_lev_1800;
+ pwr_lev = sup->class_dcs - 1;
else
- pwr_lev = sup->pwr_lev_900;
+ pwr_lev = sup->class_900 - 1;
gsm48_encode_classmark1(&nlu->classmark1, sup->rev_lev, sup->es_ind,
- sup->a5_1, pwr_lev);
+ set->a5_1, pwr_lev);
/* MI */
if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index d1f09638..c141f673 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -284,7 +284,7 @@ static int gsm48_apply_v_sd(struct gsm48_rrlayer *rr, struct msgb *msg)
static uint8_t gsm48_rr_check_mode(struct osmocom_ms *ms, uint8_t chan_nr,
uint8_t mode)
{
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
uint8_t ch_type, ch_subch, ch_ts;
/* only complain if we use TCH/F or TCH/H */
@@ -299,14 +299,14 @@ static uint8_t gsm48_rr_check_mode(struct osmocom_ms *ms, uint8_t chan_nr,
break;
case GSM48_CMODE_SPEECH_V1:
if (ch_type == RSL_CHAN_Bm_ACCHs) {
- if (!sup->full_v1) {
+ if (!set->full_v1) {
LOGP(DRR, LOGL_NOTICE, "Not supporting "
"full-rate speech V1\n");
return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
}
LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V1\n");
} else {
- if (!sup->half_v1) {
+ if (!set->half_v1) {
LOGP(DRR, LOGL_NOTICE, "Not supporting "
"half-rate speech V1\n");
return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
@@ -316,7 +316,7 @@ static uint8_t gsm48_rr_check_mode(struct osmocom_ms *ms, uint8_t chan_nr,
break;
case GSM48_CMODE_SPEECH_EFR:
if (ch_type == RSL_CHAN_Bm_ACCHs) {
- if (!sup->full_v2) {
+ if (!set->full_v2) {
LOGP(DRR, LOGL_NOTICE, "Not supporting "
"full-rate speech V2\n");
return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
@@ -330,14 +330,14 @@ static uint8_t gsm48_rr_check_mode(struct osmocom_ms *ms, uint8_t chan_nr,
break;
case GSM48_CMODE_SPEECH_AMR:
if (ch_type == RSL_CHAN_Bm_ACCHs) {
- if (!sup->full_v3) {
+ if (!set->full_v3) {
LOGP(DRR, LOGL_NOTICE, "Not supporting "
"full-rate speech V3\n");
return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
}
LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V3\n");
} else {
- if (!sup->half_v3) {
+ if (!set->half_v3) {
LOGP(DRR, LOGL_NOTICE, "Not supporting "
"half-rate speech V3\n");
return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
@@ -930,7 +930,7 @@ static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_cip_mode_cmd *cm = (struct gsm48_cip_mode_cmd *)gh->data;
int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
@@ -964,13 +964,13 @@ static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg)
}
/* check if we actually support this cipher */
- if (sc && ((alg_id == GSM_CIPHER_A5_1 && !sup->a5_1)
- || (alg_id == GSM_CIPHER_A5_2 && !sup->a5_2)
- || (alg_id == GSM_CIPHER_A5_3 && !sup->a5_3)
- || (alg_id == GSM_CIPHER_A5_4 && !sup->a5_4)
- || (alg_id == GSM_CIPHER_A5_5 && !sup->a5_5)
- || (alg_id == GSM_CIPHER_A5_6 && !sup->a5_6)
- || (alg_id == GSM_CIPHER_A5_7 && !sup->a5_7))) {
+ if (sc && ((alg_id == GSM_CIPHER_A5_1 && !set->a5_1)
+ || (alg_id == GSM_CIPHER_A5_2 && !set->a5_2)
+ || (alg_id == GSM_CIPHER_A5_3 && !set->a5_3)
+ || (alg_id == GSM_CIPHER_A5_4 && !set->a5_4)
+ || (alg_id == GSM_CIPHER_A5_5 && !set->a5_5)
+ || (alg_id == GSM_CIPHER_A5_6 && !set->a5_6)
+ || (alg_id == GSM_CIPHER_A5_7 && !set->a5_7))) {
LOGP(DRR, LOGL_NOTICE, "algo not supported\n");
return gsm48_rr_tx_rr_status(ms,
GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
@@ -1003,6 +1003,7 @@ static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg)
static int gsm48_rr_enc_cm3(struct osmocom_ms *ms, uint8_t *buf, uint8_t *len)
{
struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
struct bitvec bv;
memset(&bv, 0, sizeof(bv));
@@ -1012,57 +1013,57 @@ static int gsm48_rr_enc_cm3(struct osmocom_ms *ms, uint8_t *buf, uint8_t *len)
/* spare bit */
bitvec_set_bit(&bv, 0);
/* band 3 supported */
- if (sup->dcs_1800)
+ if (set->dcs)
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
/* band 2 supported */
- if (sup->e_gsm || sup->r_gsm)
+ if (set->e_gsm || set->r_gsm)
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
/* band 1 supported */
- if (sup->p_gsm && !(sup->e_gsm || sup->r_gsm))
+ if (set->p_gsm && !(set->e_gsm || set->r_gsm))
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
/* a5 bits */
- if (sup->a5_7)
+ if (set->a5_7)
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
- if (sup->a5_6)
+ if (set->a5_6)
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
- if (sup->a5_5)
+ if (set->a5_5)
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
- if (sup->a5_4)
+ if (set->a5_4)
bitvec_set_bit(&bv, ONE);
else
bitvec_set_bit(&bv, ZERO);
/* radio capability */
- if (sup->dcs_1800 && !sup->p_gsm && !(sup->e_gsm || sup->r_gsm)) {
+ if (set->dcs && !set->p_gsm && !(set->e_gsm || set->r_gsm)) {
/* dcs only */
bitvec_set_uint(&bv, 0, 4);
- bitvec_set_uint(&bv, sup->dcs_capa, 4);
+ bitvec_set_uint(&bv, set->class_dcs, 4);
} else
- if (sup->dcs_1800 && (sup->p_gsm || (sup->e_gsm || sup->r_gsm))) {
+ if (set->dcs && (set->p_gsm || (set->e_gsm || set->r_gsm))) {
/* dcs */
- bitvec_set_uint(&bv, sup->dcs_capa, 4);
+ bitvec_set_uint(&bv, set->class_dcs, 4);
/* low band */
- bitvec_set_uint(&bv, sup->low_capa, 4);
+ bitvec_set_uint(&bv, set->class_900, 4);
} else {
/* low band only */
bitvec_set_uint(&bv, 0, 4);
- bitvec_set_uint(&bv, sup->low_capa, 4);
+ bitvec_set_uint(&bv, set->class_900, 4);
}
/* r support */
- if (sup->r_gsm) {
+ if (set->r_gsm) {
bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, sup->r_capa, 3);
+ bitvec_set_uint(&bv, set->class_900, 3);
} else {
bitvec_set_bit(&bv, ZERO);
}
@@ -1117,22 +1118,23 @@ int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
- cm->pwr_lev = sup->pwr_lev_1800;
+ cm->pwr_lev = set->class_dcs - 1;
else
- cm->pwr_lev = sup->pwr_lev_900;
- cm->a5_1 = !sup->a5_1;
+ cm->pwr_lev = set->class_900 - 1;
+ cm->a5_1 = !set->a5_1;
cm->es_ind = sup->es_ind;
cm->rev_lev = sup->rev_lev;
- cm->fc = (sup->r_gsm || sup->e_gsm);
+ cm->fc = (set->r_gsm || set->e_gsm);
cm->vgcs = sup->vgcs;
cm->vbs = sup->vbs;
- cm->sm_cap = sup->sms_ptp;
+ cm->sm_cap = set->sms_ptp;
cm->ss_scr = sup->ss_ind;
cm->ps_cap = sup->ps_cap;
- cm->a5_2 = sup->a5_2;
- cm->a5_3 = sup->a5_3;
+ cm->a5_2 = set->a5_2;
+ cm->a5_3 = set->a5_3;
cm->cmsp = sup->cmsp;
cm->solsa = sup->solsa;
cm->lcsva_cap = sup->lcsva;
@@ -1144,6 +1146,7 @@ int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm)
static int gsm48_rr_tx_cm_change(struct osmocom_ms *ms)
{
struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
struct msgb *nmsg;
struct gsm48_hdr *gh;
struct gsm48_cm_change *cc;
@@ -1165,8 +1168,8 @@ static int gsm48_rr_tx_cm_change(struct osmocom_ms *ms)
gsm48_rr_enc_cm2(ms, &cc->cm2);
/* classmark 3 */
- if (sup->dcs_1800 || sup->e_gsm || sup->r_gsm
- || sup->a5_7 || sup->a5_6 || sup->a5_5 || sup->a5_4
+ if (set->dcs || set->e_gsm || set->r_gsm
+ || set->a5_7 || set->a5_6 || set->a5_5 || set->a5_4
|| sup->ms_sup
|| sup->ucs2_treat
|| sup->ext_meas || sup->meas_cap
@@ -1195,7 +1198,7 @@ static int gsm48_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg)
/* start random access */
static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
{
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm322_cellsel *cs = &ms->cellsel;
struct gsm48_sysinfo *s = cs->si;
@@ -1297,7 +1300,7 @@ static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
chan_req_val);
break;
case RR_EST_CAUSE_ANS_PAG_TCH_F:
- switch (sup->ch_cap) {
+ switch (set->ch_cap) {
case GSM_CAP_SDCCH:
chan_req_mask = 0x0f;
chan_req_val = 0x10;
@@ -1315,7 +1318,7 @@ static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
chan_req_val);
break;
case RR_EST_CAUSE_ANS_PAG_TCH_ANY:
- switch (sup->ch_cap) {
+ switch (set->ch_cap) {
case GSM_CAP_SDCCH:
chan_req_mask = 0x0f;
chan_req_val = 0x10;
@@ -1584,13 +1587,13 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg)
*/
/* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
-static int decode_freq_list(struct gsm_support *sup,
+static int decode_freq_list(struct gsm_settings *set,
struct gsm_sysinfo_freq *f, uint8_t *cd, uint8_t len, uint8_t mask,
uint8_t frqt)
{
/* only Bit map 0 format for P-GSM */
if ((cd[0] & 0xc0 & mask) != 0x00 &&
- (sup->p_gsm && !sup->e_gsm && !sup->r_gsm && !sup->dcs_1800))
+ (set->p_gsm && !set->e_gsm && !set->r_gsm && !set->dcs))
return 0;
return gsm48_decode_freq_list(f, cd, len, mask, frqt);
@@ -1878,7 +1881,7 @@ static int gsm48_rr_rx_sysinfo1(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
/* Cell Channel Description */
- decode_freq_list(&ms->support, s->freq,
+ decode_freq_list(&ms->settings, s->freq,
si->cell_channel_description,
sizeof(si->cell_channel_description), 0xce, FREQ_TYPE_SERV);
/* RACH Control Parameter */
@@ -1920,7 +1923,7 @@ static int gsm48_rr_rx_sysinfo2(struct osmocom_ms *ms, struct msgb *msg)
/* Neighbor Cell Description */
s->nb_ext_ind_si2 = (si->bcch_frequency_list[0] >> 6) & 1;
s->nb_ba_ind_si2 = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list,
+ decode_freq_list(&ms->settings, s->freq, si->bcch_frequency_list,
sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL_2);
/* NCC Permitted */
s->nb_ncc_permitted_si2 = si->ncc_permitted;
@@ -1961,7 +1964,7 @@ static int gsm48_rr_rx_sysinfo2bis(struct osmocom_ms *ms, struct msgb *msg)
/* Neighbor Cell Description */
s->nb_ext_ind_si2bis = (si->bcch_frequency_list[0] >> 6) & 1;
s->nb_ba_ind_si2bis = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(&ms->support, s->freq,
+ decode_freq_list(&ms->settings, s->freq,
si->bcch_frequency_list,
sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL_2bis);
/* RACH Control Parameter */
@@ -2001,7 +2004,7 @@ static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg)
/* Neighbor Cell Description 2 */
s->nb_multi_rep_si2ter = (si->ext_bcch_frequency_list[0] >> 6) & 3;
s->nb_ba_ind_si2ter = (si->ext_bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(&ms->support, s->freq,
+ decode_freq_list(&ms->settings, s->freq,
si->ext_bcch_frequency_list,
sizeof(si->ext_bcch_frequency_list), 0x8e,
FREQ_TYPE_NCELL_2ter);
@@ -2173,7 +2176,7 @@ static int gsm48_rr_rx_sysinfo5(struct osmocom_ms *ms, struct msgb *msg)
/* Neighbor Cell Description */
s->nb_ext_ind_si5 = (si->bcch_frequency_list[0] >> 6) & 1;
s->nb_ba_ind_si5 = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list,
+ decode_freq_list(&ms->settings, s->freq, si->bcch_frequency_list,
sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_REP_5);
s->si5 = 1;
@@ -2211,7 +2214,7 @@ static int gsm48_rr_rx_sysinfo5bis(struct osmocom_ms *ms, struct msgb *msg)
/* Neighbor Cell Description */
s->nb_ext_ind_si5bis = (si->bcch_frequency_list[0] >> 6) & 1;
s->nb_ba_ind_si5bis = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list,
+ decode_freq_list(&ms->settings, s->freq, si->bcch_frequency_list,
sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_REP_5bis);
s->si5bis = 1;
@@ -2249,7 +2252,7 @@ static int gsm48_rr_rx_sysinfo5ter(struct osmocom_ms *ms, struct msgb *msg)
/* Neighbor Cell Description */
s->nb_multi_rep_si5ter = (si->bcch_frequency_list[0] >> 6) & 3;
s->nb_ba_ind_si5ter = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(&ms->support, s->freq, si->bcch_frequency_list,
+ decode_freq_list(&ms->settings, s->freq, si->bcch_frequency_list,
sizeof(si->bcch_frequency_list), 0x8e, FREQ_TYPE_REP_5ter);
s->si5ter = 1;
diff --git a/src/host/layer23/src/mobile/mnccms.c b/src/host/layer23/src/mobile/mnccms.c
index d709d250..62a7dbe4 100644
--- a/src/host/layer23/src/mobile/mnccms.c
+++ b/src/host/layer23/src/mobile/mnccms.c
@@ -61,11 +61,11 @@ struct gsm_call *get_call_ref(uint32_t callref)
return NULL;
}
-static int8_t mncc_get_bearer(struct gsm_support *sup, uint8_t speech_ver)
+static int8_t mncc_get_bearer(struct gsm_settings *set, uint8_t speech_ver)
{
switch (speech_ver) {
case 4:
- if (sup->full_v3)
+ if (set->full_v3)
LOGP(DMNCC, LOGL_INFO, " net suggests full rate v3\n");
else {
LOGP(DMNCC, LOGL_INFO, " full rate v3 not supported\n");
@@ -73,7 +73,7 @@ static int8_t mncc_get_bearer(struct gsm_support *sup, uint8_t speech_ver)
}
break;
case 2:
- if (sup->full_v2)
+ if (set->full_v2)
LOGP(DMNCC, LOGL_INFO, " net suggests full rate v2\n");
else {
LOGP(DMNCC, LOGL_INFO, " full rate v2 not supported\n");
@@ -81,7 +81,7 @@ static int8_t mncc_get_bearer(struct gsm_support *sup, uint8_t speech_ver)
}
break;
case 0: /* mandatory */
- if (sup->full_v1)
+ if (set->full_v1)
LOGP(DMNCC, LOGL_INFO, " net suggests full rate v1\n");
else {
LOGP(DMNCC, LOGL_INFO, " full rate v1 not supported\n");
@@ -89,7 +89,7 @@ static int8_t mncc_get_bearer(struct gsm_support *sup, uint8_t speech_ver)
}
break;
case 5:
- if (sup->half_v3)
+ if (set->half_v3)
LOGP(DMNCC, LOGL_INFO, " net suggests half rate v3\n");
else {
LOGP(DMNCC, LOGL_INFO, " half rate v3 not supported\n");
@@ -97,7 +97,7 @@ static int8_t mncc_get_bearer(struct gsm_support *sup, uint8_t speech_ver)
}
break;
case 1:
- if (sup->half_v1)
+ if (set->half_v1)
LOGP(DMNCC, LOGL_INFO, " net suggests half rate v1\n");
else {
LOGP(DMNCC, LOGL_INFO, " half rate v1 not supported\n");
@@ -116,14 +116,13 @@ static int8_t mncc_get_bearer(struct gsm_support *sup, uint8_t speech_ver)
static void mncc_set_bearer(struct osmocom_ms *ms, int8_t speech_ver,
struct gsm_mncc *mncc)
{
- struct gsm_support *sup = &ms->support;
struct gsm_settings *set = &ms->settings;
int i = 0;
mncc->fields |= MNCC_F_BEARER_CAP;
mncc->bearer_cap.coding = 0;
- if (sup->ch_cap == GSM_CAP_SDCCH_TCHF_TCHH
- && (sup->half_v1 || sup->half_v3)) {
+ if (set->ch_cap == GSM_CAP_SDCCH_TCHF_TCHH
+ && (set->half_v1 || set->half_v3)) {
mncc->bearer_cap.radio = 3;
LOGP(DMNCC, LOGL_INFO, " support TCH/H also\n");
} else {
@@ -134,33 +133,33 @@ static void mncc_set_bearer(struct osmocom_ms *ms, int8_t speech_ver,
/* if no specific speech_ver is given */
if (speech_ver < 0) {
/* if half rate is supported and prefered */
- if (sup->half_v3 && set->half && set->half_prefer) {
+ if (set->half_v3 && set->half && set->half_prefer) {
mncc->bearer_cap.speech_ver[i++] = 5;
LOGP(DMNCC, LOGL_INFO, " support half rate v3\n");
}
- if (sup->half_v1 && set->half && set->half_prefer) {
+ if (set->half_v1 && set->half && set->half_prefer) {
mncc->bearer_cap.speech_ver[i++] = 1;
LOGP(DMNCC, LOGL_INFO, " support half rate v1\n");
}
/* if full rate is supported */
- if (sup->full_v3) {
+ if (set->full_v3) {
mncc->bearer_cap.speech_ver[i++] = 4;
LOGP(DMNCC, LOGL_INFO, " support full rate v3\n");
}
- if (sup->full_v2) {
+ if (set->full_v2) {
mncc->bearer_cap.speech_ver[i++] = 2;
LOGP(DMNCC, LOGL_INFO, " support full rate v2\n");
}
- if (sup->full_v1) { /* mandatory, so it's always true */
+ if (set->full_v1) { /* mandatory, so it's always true */
mncc->bearer_cap.speech_ver[i++] = 0;
LOGP(DMNCC, LOGL_INFO, " support full rate v1\n");
}
/* if half rate is supported and not prefered */
- if (sup->half_v3 && set->half && !set->half_prefer) {
+ if (set->half_v3 && set->half && !set->half_prefer) {
mncc->bearer_cap.speech_ver[i++] = 5;
LOGP(DMNCC, LOGL_INFO, " support half rate v3\n");
}
- if (sup->half_v1 && set->half && !set->half_prefer) {
+ if (set->half_v1 && set->half && !set->half_prefer) {
mncc->bearer_cap.speech_ver[i++] = 1;
LOGP(DMNCC, LOGL_INFO, " support half rate v1\n");
}
@@ -204,7 +203,6 @@ int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg)
int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
{
struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
struct gsm_mncc *data = arg;
struct gsm_call *call = get_call_ref(data->callref);
struct gsm_mncc mncc;
@@ -319,7 +317,7 @@ int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
LOGP(DMNCC, LOGL_INFO, "Call is proceeding\n");
if ((data->fields & MNCC_F_BEARER_CAP)
&& data->bearer_cap.speech_ver[0] >= 0) {
- mncc_get_bearer(sup, data->bearer_cap.speech_ver[0]);
+ mncc_get_bearer(set, data->bearer_cap.speech_ver[0]);
}
break;
case MNCC_ALERT_IND:
@@ -346,7 +344,7 @@ int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
for (i = 0; data->bearer_cap.speech_ver[i] >= 0; i++) {
- temp = mncc_get_bearer(sup,
+ temp = mncc_get_bearer(set,
data->bearer_cap.speech_ver[i]);
if (temp < 0)
continue;
diff --git a/src/host/layer23/src/mobile/settings.c b/src/host/layer23/src/mobile/settings.c
index b1e17552..cbef280b 100644
--- a/src/host/layer23/src/mobile/settings.c
+++ b/src/host/layer23/src/mobile/settings.c
@@ -41,11 +41,32 @@ int gsm_settings_init(struct osmocom_ms *ms)
strcpy(set->test_imsi, "001010000000000");
set->test_rplmn_mcc = set->test_rplmn_mnc = 1;
+ /* set all supported features */
+ set->sms_ptp = sup->sms_ptp;
+ set->a5_1 = sup->a5_1;
+ set->a5_2 = sup->a5_2;
+ set->a5_3 = sup->a5_3;
+ set->a5_4 = sup->a5_4;
+ set->a5_5 = sup->a5_5;
+ set->a5_6 = sup->a5_6;
+ set->a5_7 = sup->a5_7;
+ set->p_gsm = sup->p_gsm;
+ set->e_gsm = sup->e_gsm;
+ set->r_gsm = sup->r_gsm;
+ set->dcs = sup->dcs;
+ set->class_900 = sup->class_900;
+ set->class_dcs = sup->class_dcs;
+ set->full_v1 = sup->full_v1;
+ set->full_v2 = sup->full_v2;
+ set->full_v3 = sup->full_v3;
+ set->half_v1 = sup->half_v1;
+ set->half_v3 = sup->half_v3;
+ set->ch_cap = sup->ch_cap;
+ set->min_rxlev_db = sup->min_rxlev_db;
+
if (sup->half_v1 || sup->half_v3)
set->half = 1;
- set->min_rxlev_db = sup->min_rxlev_db;
-
return 0;
}
@@ -89,5 +110,3 @@ int gsm_random_imei(struct gsm_settings *set)
return 0;
}
-
-
diff --git a/src/host/layer23/src/mobile/support.c b/src/host/layer23/src/mobile/support.c
index 631fd5bf..beadc783 100644
--- a/src/host/layer23/src/mobile/support.c
+++ b/src/host/layer23/src/mobile/support.c
@@ -34,8 +34,8 @@ void gsm_support_init(struct osmocom_ms *ms)
sup->ms = ms;
/* rf power capability */
- sup->pwr_lev_900 = 3; /* CLASS 4: Handheld 2W */
- sup->pwr_lev_1800 = 0; /* CLASS 1: Handheld 1W */
+ sup->class_900 = 4; /* CLASS 4: Handheld 2W */
+ sup->class_dcs = 1; /* CLASS 1: Handheld 1W */
/* controlled early classmark sending */
sup->es_ind = 0; /* no */
/* revision level */
@@ -69,14 +69,12 @@ void gsm_support_init(struct osmocom_ms *ms)
sup->p_gsm = 1; /* P-GSM */
sup->e_gsm = 1; /* E-GSM */
sup->r_gsm = 1; /* R-GSM */
- sup->r_capa = 0;
- sup->low_capa = 4; /* p,e,r power class */
- sup->dcs_1800 = 1;
+ sup->dcs = 1;
/* set supported frequencies */
if (sup->p_gsm)
for(i = 1; i <= 124; i++)
sup->freq_map[i >> 3] |= (1 << (i & 7));
- if (sup->dcs_1800)
+ if (sup->dcs)
for(i = 512; i <= 885; i++)
sup->freq_map[i >> 3] |= (1 << (i & 7));
if (sup->e_gsm) {
@@ -87,7 +85,6 @@ void gsm_support_init(struct osmocom_ms *ms)
if (sup->r_gsm)
for(i = 955; i <= 974; i++)
sup->freq_map[i >> 3] |= (1 << (i & 7));
- sup->dcs_capa = 1; /* dcs power class */
/* multi slot support */
sup->ms_sup = 0; /* no */
/* ucs2 treatment */
@@ -124,49 +121,57 @@ struct gsm_support_scan_max gsm_sup_smax[] = {
{ 0, 0, 0, 0 }
};
+#define SUP_SET(item) \
+ ((sup->item) ? ((set->item) ? "yes" : "disabled") : "no")
/* dump support */
-void gsm_support_dump(struct gsm_support *sup,
+void gsm_support_dump(struct osmocom_ms *ms,
void (*print)(void *, const char *, ...), void *priv)
{
+ struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
+
print(priv, "Supported features of MS '%s':\n", sup->ms->name);
- if (sup->r_gsm)
- print(priv, " R-GSM (Channels 955-974)\n");
- if (sup->e_gsm)
- print(priv, " E-GSM (Channels 975-1023,0)\n");
- if (sup->p_gsm)
- print(priv, " P-GSM (Channels 1-124)\n");
- if (sup->dcs_1800)
- print(priv, " DCS1800 (Channels 512-885)\n");
print(priv, " Phase %d mobile station\n", sup->rev_lev + 1);
- print(priv, " CECS : %s\n", (sup->es_ind) ? "yes" : "no");
- print(priv, " VGCS : %s\n", (sup->vgcs) ? "yes" : "no");
- print(priv, " VBS : %s\n", (sup->vbs) ? "yes" : "no");
- print(priv, " SMS : %s\n", (sup->sms_ptp) ? "yes" : "no");
- print(priv, " SS_IND : %s\n", (sup->ss_ind) ? "yes" : "no");
- print(priv, " PS_CAP : %s\n", (sup->ps_cap) ? "yes" : "no");
- print(priv, " CMSP : %s\n", (sup->cmsp) ? "yes" : "no");
- print(priv, " SoLSA : %s\n", (sup->solsa) ? "yes" : "no");
- print(priv, " LCSVA : %s\n", (sup->lcsva) ? "yes" : "no");
- print(priv, " LOC_SERV : %s\n", (sup->loc_serv) ? "yes" : "no");
- print(priv, " A5/1 : %s\n", (sup->a5_1) ? "yes" : "no");
- print(priv, " A5/2 : %s\n", (sup->a5_2) ? "yes" : "no");
- print(priv, " A5/3 : %s\n", (sup->a5_3) ? "yes" : "no");
- print(priv, " A5/4 : %s\n", (sup->a5_4) ? "yes" : "no");
- print(priv, " A5/5 : %s\n", (sup->a5_5) ? "yes" : "no");
- print(priv, " A5/6 : %s\n", (sup->a5_6) ? "yes" : "no");
- print(priv, " A5/7 : %s\n", (sup->a5_7) ? "yes" : "no");
- print(priv, " A5/1 : %s\n", (sup->a5_1) ? "yes" : "no");
- switch (sup->ch_cap) {
+ print(priv, " R-GSM : %s\n", SUP_SET(r_gsm));
+ print(priv, " E-GSM : %s\n", SUP_SET(e_gsm));
+ print(priv, " P-GSM : %s\n", SUP_SET(p_gsm));
+ print(priv, " GSM900 Class: %d\n", set->class_900);
+ print(priv, " DCS 1800 : %s\n", SUP_SET(dcs));
+ print(priv, " DCS Class : %d\n", set->class_dcs);
+ print(priv, " CECS : %s\n", (sup->es_ind) ? "yes" : "no");
+ print(priv, " VGCS : %s\n", (sup->vgcs) ? "yes" : "no");
+ print(priv, " VBS : %s\n", (sup->vbs) ? "yes" : "no");
+ print(priv, " SMS : %s\n", SUP_SET(sms_ptp));
+ print(priv, " SS_IND : %s\n", (sup->ss_ind) ? "yes" : "no");
+ print(priv, " PS_CAP : %s\n", (sup->ps_cap) ? "yes" : "no");
+ print(priv, " CMSP : %s\n", (sup->cmsp) ? "yes" : "no");
+ print(priv, " SoLSA : %s\n", (sup->solsa) ? "yes" : "no");
+ print(priv, " LCSVA : %s\n", (sup->lcsva) ? "yes" : "no");
+ print(priv, " LOC_SERV : %s\n", (sup->loc_serv) ? "yes" : "no");
+ print(priv, " A5/1 : %s\n", SUP_SET(a5_1));
+ print(priv, " A5/2 : %s\n", SUP_SET(a5_2));
+ print(priv, " A5/3 : %s\n", SUP_SET(a5_3));
+ print(priv, " A5/4 : %s\n", SUP_SET(a5_4));
+ print(priv, " A5/5 : %s\n", SUP_SET(a5_5));
+ print(priv, " A5/6 : %s\n", SUP_SET(a5_6));
+ print(priv, " A5/7 : %s\n", SUP_SET(a5_7));
+ print(priv, " A5/1 : %s\n", SUP_SET(a5_1));
+ switch (set->ch_cap) {
case GSM_CAP_SDCCH:
- print(priv, " Channels : SDCCH only\n");
+ print(priv, " Channels : SDCCH only\n");
break;
case GSM_CAP_SDCCH_TCHF:
- print(priv, " Channels : SDCCH + TCH/F\n");
+ print(priv, " Channels : SDCCH + TCH/F\n");
break;
case GSM_CAP_SDCCH_TCHF_TCHH:
- print(priv, " Channels : SDCCH + TCH/F + TCH/H\n");
+ print(priv, " Channels : SDCCH + TCH/F + TCH/H\n");
break;
}
- print(priv, " Min RXLEV: %d\n", sup->min_rxlev_db);
+ print(priv, " Full-Rate V1: %s\n", SUP_SET(full_v1));
+ print(priv, " Full-Rate V2: %s\n", SUP_SET(full_v2));
+ print(priv, " Full-Rate V3: %s\n", SUP_SET(full_v3));
+ print(priv, " Half-Rate V1: %s\n", SUP_SET(half_v1));
+ print(priv, " Half-Rate V3: %s\n", SUP_SET(half_v3));
+ print(priv, " Min RXLEV : %d\n", set->min_rxlev_db);
}
diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c
index 4eecb6ef..184194b1 100644
--- a/src/host/layer23/src/mobile/vty_interface.c
+++ b/src/host/layer23/src/mobile/vty_interface.c
@@ -57,6 +57,12 @@ struct cmd_node testsim_node = {
1
};
+struct cmd_node support_node = {
+ SUPPORT_NODE,
+ "%s(support)#",
+ 1
+};
+
static void print_vty(void *priv, const char *fmt, ...)
{
char buffer[1000];
@@ -83,7 +89,8 @@ static void vty_restart(struct vty *vty)
{
if (vty_reading)
return;
- vty_out(vty, "You must restart for change take effect!%s", VTY_NEWLINE);
+ vty_out(vty, "You must restart for change to take effect!%s",
+ VTY_NEWLINE);
}
static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
@@ -133,10 +140,10 @@ DEFUN(show_support, show_support_cmd, "show support [ms_name]",
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
- gsm_support_dump(&ms->support, print_vty, vty);
+ gsm_support_dump(ms, print_vty, vty);
} else {
llist_for_each_entry(ms, &ms_list, entity) {
- gsm_support_dump(&ms->support, print_vty, vty);
+ gsm_support_dump(ms, print_vty, vty);
vty_out(vty, "%s", VTY_NEWLINE);
}
}
@@ -146,10 +153,11 @@ DEFUN(show_support, show_support_cmd, "show support [ms_name]",
static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
{
+ struct gsm_settings *set = &ms->settings;
struct gsm_trans *trans;
vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
- if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
+ if (set->plmn_mode == PLMN_MODE_AUTO)
vty_out(vty, " automatic network selection: %s%s",
plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
else
@@ -677,15 +685,17 @@ DEFUN(network_show, network_show_cmd, "network show MS_NAME",
"Name of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
+ struct gsm_settings *set;
struct gsm322_plmn *plmn;
struct gsm322_plmn_list *temp;
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
+ set = &ms->settings;
plmn = &ms->plmn;
- if (ms->settings.plmn_mode != PLMN_MODE_AUTO
+ if (set->plmn_mode != PLMN_MODE_AUTO
&& plmn->state != GSM322_M3_NOT_ON_PLMN) {
vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -796,10 +806,15 @@ DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
return CMD_SUCCESS;
}
+#define SUP_WRITE(item, cmd) \
+ if (sup->item) \
+ vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
+ VTY_NEWLINE);
+
static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
{
- struct gsm_support *sup = &ms->support;
struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
switch(set->sim_type) {
@@ -830,31 +845,6 @@ static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " test-sim%s", VTY_NEWLINE);
- vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
- switch (set->test_ki_type) {
- case GSM_SIM_KEY_XOR:
- vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
- VTY_NEWLINE);
- break;
- case GSM_SIM_KEY_COMP128:
- vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
- VTY_NEWLINE);
- break;
- }
- vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
- VTY_NEWLINE);
- if (set->test_rplmn_valid)
- vty_out(vty, " rplmn %s %s%s",
- gsm_print_mcc(set->test_rplmn_mcc),
- gsm_print_mnc(set->test_rplmn_mnc),
- VTY_NEWLINE);
- else
- vty_out(vty, " no rplmn%s", VTY_NEWLINE);
- vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
- : "foreign-country", VTY_NEWLINE);
- vty_out(vty, " exit%s", VTY_NEWLINE);
- vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
if (set->alter_tx_power)
if (set->alter_tx_power_value)
vty_out(vty, " tx-power %d%s",
@@ -877,13 +867,13 @@ static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
vty_out(vty, " no location-updating%s", VTY_NEWLINE);
else
vty_out(vty, " location-updating%s", VTY_NEWLINE);
- if (sup->full_v1 || sup->full_v2 || sup->full_v3) {
+ if (set->full_v1 || set->full_v2 || set->full_v3) {
/* mandatory anyway */
vty_out(vty, " codec full-speed%s%s",
(!set->half_prefer) ? " prefer" : "",
VTY_NEWLINE);
}
- if (sup->half_v1 || sup->half_v3) {
+ if (set->half_v1 || set->half_v3) {
if (set->half)
vty_out(vty, " codec half-speed%s%s",
(set->half_prefer) ? " prefer" : "",
@@ -891,6 +881,64 @@ static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
else
vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
}
+ vty_out(vty, " support%s", VTY_NEWLINE);
+ SUP_WRITE(sms_ptp, "sms");
+ SUP_WRITE(a5_1, "a5/1");
+ SUP_WRITE(a5_2, "a5/2");
+ SUP_WRITE(a5_3, "a5/3");
+ SUP_WRITE(a5_4, "a5/4");
+ SUP_WRITE(a5_5, "a5/5");
+ SUP_WRITE(a5_6, "a5/6");
+ SUP_WRITE(a5_7, "a5/7");
+ SUP_WRITE(p_gsm, "p-gsm");
+ SUP_WRITE(e_gsm, "e-gsm");
+ SUP_WRITE(r_gsm, "r-gsm");
+ SUP_WRITE(dcs, "dcs");
+ vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
+ vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
+ switch (set->ch_cap) {
+ case GSM_CAP_SDCCH:
+ vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
+ break;
+ case GSM_CAP_SDCCH_TCHF:
+ vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
+ break;
+ case GSM_CAP_SDCCH_TCHF_TCHH:
+ vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
+ VTY_NEWLINE);
+ break;
+ }
+ SUP_WRITE(full_v1, "full-speech-v1");
+ SUP_WRITE(full_v2, "full-speech-v2");
+ SUP_WRITE(full_v3, "full-speech-v3");
+ SUP_WRITE(half_v1, "half-speech-v1");
+ SUP_WRITE(half_v3, "half-speech-v3");
+ vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
+ vty_out(vty, " exit%s", VTY_NEWLINE);
+ vty_out(vty, " test-sim%s", VTY_NEWLINE);
+ vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
+ switch (set->test_ki_type) {
+ case GSM_SIM_KEY_XOR:
+ vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
+ VTY_NEWLINE);
+ break;
+ case GSM_SIM_KEY_COMP128:
+ vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
+ VTY_NEWLINE);
+ break;
+ }
+ vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
+ VTY_NEWLINE);
+ if (set->test_rplmn_valid)
+ vty_out(vty, " rplmn %s %s%s",
+ gsm_print_mcc(set->test_rplmn_mcc),
+ gsm_print_mnc(set->test_rplmn_mnc),
+ VTY_NEWLINE);
+ else
+ vty_out(vty, " no rplmn%s", VTY_NEWLINE);
+ vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
+ : "foreign-country", VTY_NEWLINE);
+ vty_out(vty, " exit%s", VTY_NEWLINE);
vty_out(vty, "exit%s", VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
}
@@ -918,16 +966,17 @@ DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
"Use SIM from reader\nTest SIM inserted")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
switch (argv[0][0]) {
case 'n':
- ms->settings.sim_type = GSM_SIM_TYPE_NONE;
+ set->sim_type = GSM_SIM_TYPE_NONE;
break;
case 'r':
- ms->settings.sim_type = GSM_SIM_TYPE_READER;
+ set->sim_type = GSM_SIM_TYPE_READER;
break;
case 't':
- ms->settings.sim_type = GSM_SIM_TYPE_TEST;
+ set->sim_type = GSM_SIM_TYPE_TEST;
break;
default:
vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
@@ -943,13 +992,14 @@ DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
"Manual network selection")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
struct msgb *nmsg;
if (!ms->plmn.state) {
if (argv[0][0] == 'a')
- ms->settings.plmn_mode = PLMN_MODE_AUTO;
+ set->plmn_mode = PLMN_MODE_AUTO;
else
- ms->settings.plmn_mode = PLMN_MODE_MANUAL;
+ set->plmn_mode = PLMN_MODE_MANUAL;
return CMD_SUCCESS;
}
@@ -969,6 +1019,7 @@ DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
"Software version digit")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
char *error, *sv = "0";
if (argc >= 2)
@@ -980,9 +1031,9 @@ DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
return CMD_WARNING;
}
- strcpy(ms->settings.imei, argv[0]);
- strcpy(ms->settings.imeisv, argv[0]);
- strcpy(ms->settings.imeisv + 15, sv);
+ strcpy(set->imei, argv[0]);
+ strcpy(set->imeisv, argv[0]);
+ strcpy(set->imeisv + 15, sv);
return CMD_SUCCESS;
}
@@ -991,8 +1042,9 @@ DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
"Use fixed IMEI on every power on")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.imei_random = 0;
+ set->imei_random = 0;
vty_restart(vty);
return CMD_SUCCESS;
@@ -1003,8 +1055,9 @@ DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
"Number of trailing digits to randomize")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.imei_random = atoi(argv[0]);
+ set->imei_random = atoi(argv[0]);
vty_restart(vty);
return CMD_SUCCESS;
@@ -1014,6 +1067,7 @@ DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
"Use special IMSI for emergency calls\n15 digits IMSI")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
char *error;
error = gsm_check_imsi(argv[0]);
@@ -1021,7 +1075,7 @@ DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
vty_out(vty, "%s%s", error, VTY_NEWLINE);
return CMD_WARNING;
}
- strcpy(ms->settings.emergency_imsi, argv[0]);
+ strcpy(set->emergency_imsi, argv[0]);
return CMD_SUCCESS;
}
@@ -1030,8 +1084,9 @@ DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
NO_STR "Use IMSI of SIM or IMEI for emergency calls")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.emergency_imsi[0] = '\0';
+ set->emergency_imsi[0] = '\0';
return CMD_SUCCESS;
}
@@ -1040,8 +1095,9 @@ DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
NO_STR "Disallow waiting calls")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.cw = 0;
+ set->cw = 0;
return CMD_SUCCESS;
}
@@ -1050,8 +1106,9 @@ DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
"Allow waiting calls")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.cw = 1;
+ set->cw = 1;
return CMD_SUCCESS;
}
@@ -1060,9 +1117,10 @@ DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
"Force caller ID presentation")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clip = 1;
- ms->settings.clir = 0;
+ set->clip = 1;
+ set->clir = 0;
return CMD_SUCCESS;
}
@@ -1071,9 +1129,10 @@ DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
"Force caller ID restriction")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clip = 0;
- ms->settings.clir = 1;
+ set->clip = 0;
+ set->clir = 1;
return CMD_SUCCESS;
}
@@ -1082,8 +1141,9 @@ DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
NO_STR "Disable forcing of caller ID presentation")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clip = 0;
+ set->clip = 0;
return CMD_SUCCESS;
}
@@ -1092,19 +1152,9 @@ DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
NO_STR "Disable forcing of caller ID restriction")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clir = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_min_rxlev, cfg_ms_min_rxlev_cmd, "min-rxlev <-110--47>",
- "Set the minimum receive level to select a cell\n"
- "Minimum receive level from -110 dBm to -47 dBm")
-{
- struct osmocom_ms *ms = vty->index;
-
- ms->settings.min_rxlev_db = atoi(argv[0]);
+ set->clir = 0;
return CMD_SUCCESS;
}
@@ -1114,14 +1164,15 @@ DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
"Always full power\nFixed GSM power value if supported")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
switch (argv[0][0]) {
case 'a':
- ms->settings.alter_tx_power = 0;
+ set->alter_tx_power = 0;
break;
case 'f':
- ms->settings.alter_tx_power = 1;
- ms->settings.alter_tx_power_value = 0;
+ set->alter_tx_power = 1;
+ set->alter_tx_power_value = 0;
break;
}
@@ -1133,9 +1184,10 @@ DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
"Fixed GSM power value if supported")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.alter_tx_power = 1;
- ms->settings.alter_tx_power_value = atoi(argv[0]);
+ set->alter_tx_power = 1;
+ set->alter_tx_power_value = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -1145,8 +1197,9 @@ DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
"Delay in half bits (distance in 553.85 meter steps)")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.alter_delay = atoi(argv[0]);
+ set->alter_delay = atoi(argv[0]);
gsm48_rr_alter_delay(ms);
return CMD_SUCCESS;
@@ -1156,8 +1209,9 @@ DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
NO_STR "Do not simulate a lower or higher distance from the BTS")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.alter_delay = 0;
+ set->alter_delay = 0;
gsm48_rr_alter_delay(ms);
return CMD_SUCCESS;
@@ -1167,9 +1221,10 @@ DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
"Stick to the given cell\nARFCN of the cell to stick to")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.stick = 1;
- ms->settings.stick_arfcn = atoi(argv[0]);
+ set->stick = 1;
+ set->stick_arfcn = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -1178,8 +1233,9 @@ DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
NO_STR "Do not stick to any cell")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.stick = 0;
+ set->stick = 0;
return CMD_SUCCESS;
}
@@ -1188,8 +1244,9 @@ DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
"Allow location updating")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.no_lupd = 0;
+ set->no_lupd = 0;
return CMD_SUCCESS;
}
@@ -1198,8 +1255,9 @@ DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
NO_STR "Do not allow location updating")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.no_lupd = 1;
+ set->no_lupd = 1;
return CMD_SUCCESS;
}
@@ -1208,9 +1266,9 @@ DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
"Enable codec\nFull speed speech codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->full_v1 && !sup->full_v2 && !sup->full_v3) {
+ if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1223,14 +1281,14 @@ DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
"Enable codec\nFull speed speech codec\nPrefer this codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->full_v1 && !sup->full_v2 && !sup->full_v3) {
+ if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half_prefer = 0;
+ set->half_prefer = 0;
return CMD_SUCCESS;
}
@@ -1239,14 +1297,14 @@ DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
"Enable codec\nHalf speed speech codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->half_v1 && !sup->half_v3) {
+ if (!set->half_v1 && !set->half_v3) {
vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half = 1;
+ set->half = 1;
return CMD_SUCCESS;
}
@@ -1256,15 +1314,15 @@ DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
"Enable codec\nHalf speed speech codec\nPrefer this codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->half_v1 && !sup->half_v3) {
+ if (!set->half_v1 && !set->half_v3) {
vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half = 1;
- ms->settings.half_prefer = 1;
+ set->half = 1;
+ set->half_prefer = 1;
return CMD_SUCCESS;
}
@@ -1273,30 +1331,207 @@ DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
NO_STR "Disable codec\nHalf speed speech codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->half_v1 && !sup->half_v3) {
+ if (!set->half_v1 && !set->half_v3) {
vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half = 0;
- ms->settings.half_prefer = 0;
+ set->half = 0;
+ set->half_prefer = 0;
return CMD_SUCCESS;
}
-/* per testsim config */
-DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
- "Configure test SIM emulation")
+static int config_write_dummy(struct vty *vty)
{
- vty->node = TESTSIM_NODE;
+ return CMD_SUCCESS;
+}
+
+/* per support config */
+DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
+ "Define supported features")
+{
+ vty->node = SUPPORT_NODE;
+
+ return CMD_SUCCESS;
+}
+
+#define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ struct gsm_support *sup = &ms->support; \
+ if (!sup->item) { \
+ vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
+ if (vty_reading) \
+ return CMD_SUCCESS; \
+ return CMD_WARNING; \
+ } \
+ if (restart) \
+ vty_restart(vty); \
+ set->item = 1; \
+ return CMD_SUCCESS; \
+}
+
+#define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ struct gsm_support *sup = &ms->support; \
+ if (!sup->item) { \
+ vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
+ if (vty_reading) \
+ return CMD_SUCCESS; \
+ return CMD_WARNING; \
+ } \
+ if (restart) \
+ vty_restart(vty); \
+ set->item = 0; \
+ return CMD_SUCCESS; \
+}
+
+SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
+SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
+SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
+SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
+SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
+SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
+SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
+SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
+SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
+SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
+SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
+SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
+SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
+SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
+SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
+SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
+SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
+ 1);
+SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
+ "P-GSM (900)", 1);
+SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
+ 1);
+SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
+ "E-GSM (850)", 1);
+SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
+ 1);
+SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
+ "R-GSM (850)", 1);
+SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
+SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
+
+DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
+ "Select power class for GSM 850/900\n"
+ "20 Watts\n"
+ "8 Watts\n"
+ "5 Watts\n"
+ "2 Watts\n"
+ "0.8 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_900 = atoi(argv[0]);
+
+ if (set->class_900 < sup->class_900 && !vty_reading)
+ vty_out(vty, "You selected an higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
-static int config_write_dummy(struct vty *vty)
+DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
+ "Select power class for DCS 1800\n"
+ "1 Watt\n"
+ "0.25 Watts\n"
+ "4 Watts")
{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_dcs = atoi(argv[0]);
+
+ if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
+ && !vty_reading)
+ vty_out(vty, "You selected an higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
+ "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
+ "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+ uint8_t ch_cap;
+
+ if (!strcmp(argv[0], "sdcch+tchf+tchh"))
+ ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
+ else if (!strcmp(argv[0], "sdcch+tchf"))
+ ch_cap = GSM_CAP_SDCCH_TCHF;
+ else
+ ch_cap = GSM_CAP_SDCCH;
+
+ if (ch_cap > sup->ch_cap && !vty_reading) {
+ vty_out(vty, "You selected an higher capability than supported "
+ " by hardware!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ set->ch_cap = ch_cap;
+
+ return CMD_SUCCESS;
+}
+
+SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
+ "Full rate speech V1", 0);
+SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
+ "full-speech-v1", "Full rate speech V1", 0);
+SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
+ "Full rate speech V2 (EFR)", 0);
+SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
+ "full-speech-v2", "Full rate speech V2 (EFR)", 0);
+SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
+ "Full rate speech V3 (AMR)", 0);
+SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
+ "full-speech-v3", "Full rate speech V3 (AMR)", 0);
+SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
+ "Half rate speech V1 (AMR)", 0);
+SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
+ "half-speech-v1", "Half rate speech V1", 0);
+SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
+ "Half rate speech V3 (AMR)", 0);
+SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
+ "half-speech-v3", "Half rate speech V3", 0);
+
+DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
+ "Set the minimum receive level to select a cell\n"
+ "Minimum receive level from -110 dBm to -47 dBm")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->min_rxlev_db = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+/* per testsim config */
+DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
+ "Configure test SIM emulation")
+{
+ vty->node = TESTSIM_NODE;
+
return CMD_SUCCESS;
}
@@ -1304,6 +1539,7 @@ DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
"Set IMSI on test card\n15 digits IMSI")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
char *error = gsm_check_imsi(argv[0]);
if (error) {
@@ -1311,7 +1547,7 @@ DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
return CMD_WARNING;
}
- strcpy(ms->settings.test_imsi, argv[0]);
+ strcpy(set->test_imsi, argv[0]);
vty_restart(vty);
return CMD_SUCCESS;
@@ -1379,8 +1615,9 @@ DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
"Allow access to barred cells")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.test_barr = 1;
+ set->test_barr = 1;
return CMD_SUCCESS;
}
@@ -1389,8 +1626,9 @@ DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
NO_STR "Deny access to barred cells")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.test_barr = 0;
+ set->test_barr = 0;
return CMD_SUCCESS;
}
@@ -1399,8 +1637,9 @@ DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
NO_STR "Unset Registered PLMN")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.test_rplmn_valid = 0;
+ set->test_rplmn_valid = 0;
vty_restart(vty);
return CMD_SUCCESS;
@@ -1410,6 +1649,7 @@ DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
"Set Registered PLMN\nMobile Country Code\nMobile Network Code")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
uint16_t mcc = gsm_input_mcc((char *)argv[0]),
mnc = gsm_input_mnc((char *)argv[1]);
@@ -1421,9 +1661,9 @@ DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.test_rplmn_valid = 1;
- ms->settings.test_rplmn_mcc = mcc;
- ms->settings.test_rplmn_mnc = mnc;
+ set->test_rplmn_valid = 1;
+ set->test_rplmn_mcc = mcc;
+ set->test_rplmn_mnc = mnc;
vty_restart(vty);
return CMD_SUCCESS;
@@ -1435,13 +1675,14 @@ DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-coun
"Search for HPLMN when in a different country")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
switch (argv[0][0]) {
case 'e':
- ms->settings.test_always = 1;
+ set->test_always = 1;
break;
case 'f':
- ms->settings.test_always = 0;
+ set->test_always = 0;
break;
}
@@ -1457,6 +1698,7 @@ enum node_type ms_vty_go_parent(struct vty *vty)
vty->index = NULL;
break;
case TESTSIM_NODE:
+ case SUPPORT_NODE:
vty->node = MS_NODE;
break;
default:
@@ -1476,6 +1718,7 @@ gDEFUN(ournode_exit,
vty->index = NULL;
break;
case TESTSIM_NODE:
+ case SUPPORT_NODE:
vty->node = MS_NODE;
break;
default:
@@ -1497,6 +1740,7 @@ gDEFUN(ournode_end,
case VTY_NODE:
case MS_NODE:
case TESTSIM_NODE:
+ case SUPPORT_NODE:
vty_config_unlock(vty);
vty->node = ENABLE_NODE;
vty->index = NULL;
@@ -1508,6 +1752,9 @@ gDEFUN(ournode_end,
return CMD_SUCCESS;
}
+#define SUP_NODE(item) \
+ install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
+
int ms_vty_init(void)
{
install_element_ve(&show_ms_cmd);
@@ -1561,8 +1808,6 @@ int ms_vty_init(void)
install_element(MS_NODE, &cfg_ms_clir_cmd);
install_element(MS_NODE, &cfg_ms_no_clip_cmd);
install_element(MS_NODE, &cfg_ms_no_clir_cmd);
- install_element(MS_NODE, &cfg_ms_testsim_cmd);
- install_element(MS_NODE, &cfg_ms_min_rxlev_cmd);
install_element(MS_NODE, &cfg_ms_tx_power_cmd);
install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
@@ -1576,6 +1821,50 @@ int ms_vty_init(void)
install_element(MS_NODE, &cfg_ms_codec_half_cmd);
install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
+ install_element(MS_NODE, &cfg_ms_testsim_cmd);
+ install_element(MS_NODE, &cfg_ms_support_cmd);
+ install_node(&support_node, config_write_dummy);
+ install_default(SUPPORT_NODE);
+ install_element(SUPPORT_NODE, &ournode_exit_cmd);
+ install_element(SUPPORT_NODE, &ournode_end_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
install_node(&testsim_node, config_write_dummy);
install_default(TESTSIM_NODE);
install_element(TESTSIM_NODE, &ournode_exit_cmd);