summaryrefslogtreecommitdiffstats
path: root/src/host/layer23
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2010-10-03 10:51:31 +0000
committerAndreas.Eversberg <jolly@eversberg.eu>2010-10-03 10:51:31 +0000
commitf0c807a6828e60236de21e39748bd4eb6034c3f7 (patch)
tree720b3729c0142e1ac644b8a2effdb0cdc55afee5 /src/host/layer23
parent813c098ebd6bf1187e64764f8ed4c2e2980909ba (diff)
[layer23] Rework of "support"-features, features can be disabled now
Supported features of hardware (support.c) can be disabled by config. This way the full featured mobile can be downgraded to indicate less features to the network, like disabling speech support or crypto support.
Diffstat (limited to 'src/host/layer23')
-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);