diff options
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/settings.h | 24 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/support.h | 12 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/vty.h | 1 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_mm.c | 14 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_rr.c | 103 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/mnccms.c | 36 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/settings.c | 27 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/support.c | 83 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 505 |
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); |