}
int vty_reading = 0;
+static int hide_default = 0;
static void vty_restart(struct vty *vty, struct osmocom_ms *ms)
{
"change to take effect!%s", ms->name, VTY_NEWLINE);
}
+static void vty_restart_if_started(struct vty *vty, struct osmocom_ms *ms)
+{
+ if (!ms->started)
+ return;
+ vty_restart(vty, ms);
+}
+
static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
{
struct osmocom_ms *ms;
return;
if (set->plmn_mode == PLMN_MODE_AUTO)
- vty_out(vty, " automatic network selection state: %s%s",
- plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
+ vty_out(vty, " automatic network selection state: %s%s",
+ get_a_state_name(ms->plmn.state), VTY_NEWLINE);
else
- vty_out(vty, " manual network selection state: %s%s",
- plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
- vty_out(vty, " cell selection state: %s",
- cs_state_names[ms->cellsel.state]);
- if (ms->rrlayer.state == GSM48_RR_ST_IDLE && ms->cellsel.selected)
- vty_out(vty, " (ARFCN %d)", ms->cellsel.sel_arfcn);
- vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, " radio ressource layer state: %s%s",
+ vty_out(vty, " manual network selection state : %s%s",
+ get_m_state_name(ms->plmn.state), VTY_NEWLINE);
+ if (ms->plmn.mcc)
+ vty_out(vty, " MCC=%s "
+ "MNC=%s (%s, %s)%s", gsm_print_mcc(ms->plmn.mcc),
+ gsm_print_mnc(ms->plmn.mnc), gsm_get_mcc(ms->plmn.mcc),
+ gsm_get_mnc(ms->plmn.mcc, ms->plmn.mnc), VTY_NEWLINE);
+ vty_out(vty, " cell selection state: %s%s",
+ get_cs_state_name(ms->cellsel.state), VTY_NEWLINE);
+ if (ms->cellsel.sel_mcc) {
+ vty_out(vty, " ARFCN=%s MCC=%s MNC=%s "
+ "LAC=0x%04x CELLID=0x%04x%s",
+ gsm_print_arfcn(ms->cellsel.sel_arfcn),
+ gsm_print_mcc(ms->cellsel.sel_mcc),
+ gsm_print_mnc(ms->cellsel.sel_mnc),
+ ms->cellsel.sel_lac, ms->cellsel.sel_id, VTY_NEWLINE);
+ vty_out(vty, " (%s, %s)%s",
+ gsm_get_mcc(ms->cellsel.sel_mcc),
+ gsm_get_mnc(ms->cellsel.sel_mcc, ms->cellsel.sel_mnc),
+ VTY_NEWLINE);
+ }
+ vty_out(vty, " radio ressource layer state: %s%s",
gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
- vty_out(vty, " mobility management layer state: %s",
+ vty_out(vty, " mobility management layer state: %s",
gsm48_mm_state_names[ms->mmlayer.state]);
if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
- vty_out(vty, ", %s",
+ vty_out(vty, ", %s",
gsm48_mm_substate_names[ms->mmlayer.substate]);
vty_out(vty, "%s", VTY_NEWLINE);
llist_for_each_entry(trans, &ms->trans_list, entry) {
- vty_out(vty, " call control state: %s%s",
+ vty_out(vty, " call control state: %s%s",
gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
}
}
if (!ms)
return CMD_WARNING;
- gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
+ gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SUPPORT, print_vty,
vty);
return CMD_SUCCESS;
}
-DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
+DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
SHOW_STR "Display information about received cell\n"
- "Name of MS (see \"show ms\")\nRadio frequency number")
+ "Name of MS (see \"show ms\")\nRadio frequency number\n"
+ "Given frequency is PCS band (1900) rather than DCS band.")
{
struct osmocom_ms *ms;
- int i;
struct gsm48_sysinfo *s;
+ uint16_t arfcn = atoi(argv[1]);
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
- i = atoi(argv[1]);
- if (i < 0 || i > 1023) {
- vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
- argv[1], VTY_NEWLINE);
- return CMD_WARNING;
+ if (argc > 2) {
+ if (arfcn < 512 || arfcn > 810) {
+ vty_out(vty, "Given ARFCN not in PCS band%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ arfcn |= ARFCN_PCS;
}
- s = ms->cellsel.list[i].sysinfo;
+
+ s = ms->cellsel.list[arfcn2index(arfcn)].sysinfo;
if (!s) {
vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
argv[1], VTY_NEWLINE);
return CMD_SUCCESS;
}
- gsm48_sysinfo_dump(s, i, print_vty, vty);
+ gsm48_sysinfo_dump(s, arfcn, print_vty, vty, ms->settings.freq_map);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_nbcells, show_nbcells_cmd, "show neighbour-cells MS_NAME",
+ SHOW_STR "Display information about current neighbour cells\n"
+ "Name of MS (see \"show ms\")")
+{
+ struct osmocom_ms *ms;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+
+ gsm322_dump_nb_list(&ms->cellsel, print_vty, vty);
return CMD_SUCCESS;
}
if (argc >= 3) {
mcc = gsm_input_mcc((char *)argv[1]);
mnc = gsm_input_mnc((char *)argv[2]);
- if (!mcc) {
+ if (mcc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!mnc) {
+ if (mnc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [MCC] [MNC] [LAC] [TMSI]",
- "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
+ "SIM actions\nAttach bulit in test SIM\nName of MS (see \"show ms\")\n"
"Mobile Country Code of RPLMN\nMobile Network Code of RPLMN\n"
- "Optionally locatio area code\nOptionally current assigned TMSI")
+ "Optionally location area code\nOptionally current assigned TMSI")
{
struct osmocom_ms *ms;
uint16_t mcc = 0x001, mnc = 0x01f, lac = 0x0000;
return CMD_WARNING;
if (ms->subscr.sim_valid) {
- vty_out(vty, "SIM already presend, remove first!%s",
+ vty_out(vty, "SIM already attached, remove first!%s",
VTY_NEWLINE);
return CMD_WARNING;
}
if (argc >= 3) {
mcc = gsm_input_mcc((char *)argv[1]);
mnc = gsm_input_mnc((char *)argv[2]);
- if (!mcc) {
+ if (mcc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!mnc) {
+ if (mnc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
- "SIM actions\nSelect SIM from reader\nName of MS (see \"show ms\")")
+ "SIM actions\nAttach SIM from reader\nName of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
return CMD_WARNING;
if (ms->subscr.sim_valid) {
- vty_out(vty, "SIM already presend, remove first!%s",
+ vty_out(vty, "SIM already attached, remove first!%s",
VTY_NEWLINE);
return CMD_WARNING;
}
}
DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
- "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
+ "SIM actions\nDetach SIM card\nName of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
return CMD_WARNING;
if (!ms->subscr.sim_valid) {
- vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
+ vty_out(vty, "No SIM attached!%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (!ms)
return CMD_WARNING;
- if (!mcc) {
+ if (mcc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!mnc) {
+ if (mnc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
-DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
+DEFUN(network_select, network_select_cmd,
+ "network select MS_NAME MCC MNC [force]",
"Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
- "Mobile Country Code\nMobile Network Code")
+ "Mobile Country Code\nMobile Network Code\n"
+ "Force selecting a network that is not in the list")
{
struct osmocom_ms *ms;
struct gsm322_plmn *plmn;
return CMD_WARNING;
plmn = &ms->plmn;
- if (!mcc) {
+ if (ms->settings.plmn_mode != PLMN_MODE_MANUAL) {
+ vty_out(vty, "Not in manual network selection mode%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (mcc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!mnc) {
+ if (mnc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
- if (temp->mcc == mcc && temp->mnc == mnc)
- found = 1;
- if (!found) {
- vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
- return CMD_WARNING;
+ if (argc < 4) {
+ llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
+ if (temp->mcc == mcc && temp->mnc == mnc)
+ found = 1;
+ if (!found) {
+ vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
+ vty_out(vty, "To force selecting this network, use "
+ "'force' keyword%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
}
nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
return CMD_SUCCESS;
}
+DEFUN(test_reselection, test_reselection_cmd, "test re-selection NAME",
+ "Manually trigger cell re-selection\nName of MS (see \"show ms\")")
+{
+ struct osmocom_ms *ms;
+ struct gsm_settings *set;
+ struct msgb *nmsg;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+ set = &ms->settings;
+
+ if (set->stick) {
+ vty_out(vty, "Cannot trigger cell re-selection, because we "
+ "stick to a cell!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
+ if (!nmsg)
+ return CMD_WARNING;
+ gsm322_c_event(ms, nmsg);
+
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(delete_forbidden_plmn, delete_forbidden_plmn_cmd,
+ "delete forbidden plmn NAME MCC MNC",
+ "Delete\nForbidden\nplmn\nName of MS (see \"show ms\")\n"
+ "Mobile Country Code\nMobile Network Code")
+{
+ struct osmocom_ms *ms;
+ uint16_t mcc = gsm_input_mcc((char *)argv[1]),
+ mnc = gsm_input_mnc((char *)argv[2]);
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+
+ if (mcc == GSM_INPUT_INVALID) {
+ vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (mnc == GSM_INPUT_INVALID) {
+ vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ gsm_subscr_del_forbidden_plmn(&ms->subscr, mcc, mnc);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(network_show, network_show_cmd, "network show MS_NAME",
"Network ...\nShow results of network search (again)\n"
"Name of MS (see \"show ms\")")
return CMD_SUCCESS;
}
+DEFUN(cfg_hide_default, cfg_hide_default_cmd, "hide-default",
+ "Hide most default values in config to make it more compact")
+{
+ hide_default = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_hide_default, cfg_no_hide_default_cmd, "no hide-default",
+ NO_STR "Show default values in config")
+{
+ hide_default = 0;
+
+ return CMD_SUCCESS;
+}
+
/* per MS config */
DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
"Select a mobile station to configure\nName of MS (see \"show ms\")")
#define SUP_WRITE(item, cmd) \
if (sup->item) \
- vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
- VTY_NEWLINE);
+ if (!hide_default || !set->item) \
+ vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", \
+ cmd, VTY_NEWLINE);
static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
{
vty_out(vty, " imei-random %d%s", set->imei_random,
VTY_NEWLINE);
else
- vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
if (set->emergency_imsi[0])
vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
VTY_NEWLINE);
else
- vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
- vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %sauto-answer%s", (set->auto_answer) ? "" : "no ",
- VTY_NEWLINE);
- vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
+ if (!hide_default || set->cw)
+ vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ",
+ VTY_NEWLINE);
+ if (!hide_default || set->auto_answer)
+ vty_out(vty, " %sauto-answer%s",
+ (set->auto_answer) ? "" : "no ", VTY_NEWLINE);
+ if (!hide_default || set->clip)
+ vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ",
+ VTY_NEWLINE);
+ if (!hide_default || set->clir)
+ vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ",
+ VTY_NEWLINE);
if (set->alter_tx_power)
if (set->alter_tx_power_value)
vty_out(vty, " tx-power %d%s",
else
vty_out(vty, " tx-power full%s", VTY_NEWLINE);
else
- vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
if (set->alter_delay)
vty_out(vty, " simulated-delay %d%s", set->alter_delay,
VTY_NEWLINE);
else
- vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
if (set->stick)
- vty_out(vty, " stick %d%s", set->stick_arfcn,
+ vty_out(vty, " stick %d%s%s", set->stick_arfcn & 1023,
+ (set->stick_arfcn & ARFCN_PCS) ? " pcs" : "",
VTY_NEWLINE);
else
- vty_out(vty, " no stick%s", VTY_NEWLINE);
- if (set->no_lupd)
- vty_out(vty, " no location-updating%s", VTY_NEWLINE);
- else
- vty_out(vty, " location-updating%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " no stick%s", VTY_NEWLINE);
+ if (!hide_default || set->no_lupd)
+ vty_out(vty, " %slocation-updating%s",
+ (set->no_lupd) ? "no " : "", VTY_NEWLINE);
+ if (!hide_default || set->no_neighbour)
+ vty_out(vty, " %sneighbour-measurement%s",
+ (set->no_neighbour) ? "no " : "", VTY_NEWLINE);
if (set->full_v1 || set->full_v2 || set->full_v3) {
/* mandatory anyway */
vty_out(vty, " codec full-speed%s%s",
else
vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
}
- if (llist_empty(&set->abbrev))
- vty_out(vty, " no abbrev%s", VTY_NEWLINE);
- else {
+ if (llist_empty(&set->abbrev)) {
+ if (!hide_default)
+ vty_out(vty, " no abbrev%s", VTY_NEWLINE);
+ } else {
llist_for_each_entry(abbrev, &set->abbrev, list)
vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
abbrev->number, (abbrev->name[0]) ? " " : "",
SUP_WRITE(p_gsm, "p-gsm");
SUP_WRITE(e_gsm, "e-gsm");
SUP_WRITE(r_gsm, "r-gsm");
+ SUP_WRITE(pcs, "gsm-850");
+ SUP_WRITE(gsm_480, "gsm-480");
+ SUP_WRITE(gsm_450, "gsm-450");
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(pcs, "pcs");
+ if (sup->r_gsm || sup->e_gsm || sup->p_gsm)
+ if (!hide_default || sup->class_900 != set->class_900)
+ vty_out(vty, " class-900 %d%s", set->class_900,
+ VTY_NEWLINE);
+ if (sup->gsm_850)
+ if (!hide_default || sup->class_850 != set->class_850)
+ vty_out(vty, " class-850 %d%s", set->class_850,
+ VTY_NEWLINE);
+ if (sup->gsm_480 || sup->gsm_450)
+ if (!hide_default || sup->class_400 != set->class_400)
+ vty_out(vty, " class-400 %d%s", set->class_400,
+ VTY_NEWLINE);
+ if (sup->dcs)
+ if (!hide_default || sup->class_dcs != set->class_dcs)
+ vty_out(vty, " class-dcs %d%s", set->class_dcs,
+ VTY_NEWLINE);
+ if (sup->pcs)
+ if (!hide_default || sup->class_pcs != set->class_pcs)
+ vty_out(vty, " class-pcs %d%s", set->class_pcs,
+ VTY_NEWLINE);
+ if (!hide_default || sup->ch_cap != set->ch_cap) {
+ 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, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
+ if (!hide_default || sup->min_rxlev_db != set->min_rxlev_db)
+ vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db,
+ VTY_NEWLINE);
+ if (!hide_default || sup->dsc_max != set->dsc_max)
+ vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
+ if (!hide_default || set->skip_max_per_band)
+ vty_out(vty, " %skip-max-per-band%s",
+ (set->skip_max_per_band) ? "" : "no ", 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", osmo_hexdump(set->test_ki, 12),
- VTY_NEWLINE);
+ vty_out(vty, " ki xor %s%s",
+ osmo_hexdump(set->test_ki, 12), VTY_NEWLINE);
break;
case GSM_SIM_KEY_COMP128:
- vty_out(vty, " ki comp128 %s%s", osmo_hexdump(set->test_ki, 16),
- VTY_NEWLINE);
+ vty_out(vty, " ki comp128 %s%s",
+ osmo_hexdump(set->test_ki, 16), VTY_NEWLINE);
break;
}
- vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
- VTY_NEWLINE);
+ if (!hide_default || set->test_barr)
+ vty_out(vty, " %sbarred-access%s",
+ (set->test_barr) ? "" : "no ", VTY_NEWLINE);
if (set->test_rplmn_valid) {
vty_out(vty, " rplmn %s %s",
gsm_print_mcc(set->test_rplmn_mcc),
vty_out(vty, " 0x%08x", set->test_tmsi);
vty_out(vty, "%s", 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);
+ if (!hide_default)
+ vty_out(vty, " no rplmn%s", VTY_NEWLINE);
+ if (!hide_default || set->test_always)
+ vty_out(vty, " hplmn-search %s%s",
+ (set->test_always) ? "everywhere" : "foreign-country",
+ VTY_NEWLINE);
vty_out(vty, " exit%s", VTY_NEWLINE);
+ /* no shutdown must be written to config, because shutdown is default */
vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
VTY_NEWLINE);
vty_out(vty, "exit%s", VTY_NEWLINE);
vty_out(vty, "%sgps enable%s", (g.enable) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
+ vty_out(vty, "%shide-default%s", (hide_default) ? "": "no ",
+ VTY_NEWLINE);
+ vty_out(vty, "!%s", VTY_NEWLINE);
+
llist_for_each_entry(ms, &ms_list, entity)
config_write_ms(vty, ms);
}
DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
- "Set SIM card type when powering on\nNo SIM interted\n"
- "Use SIM from reader\nTest SIM inserted")
+ "Set SIM card to attach when powering on\nAttach no SIM\n"
+ "Attach SIM from reader\nAttach bulit in test SIM")
{
struct osmocom_ms *ms = vty->index;
struct gsm_settings *set = &ms->settings;
return CMD_WARNING;
}
- vty_restart(vty, ms);
+ vty_restart_if_started(vty, ms);
+
return CMD_SUCCESS;
}
struct gsm_settings *set = &ms->settings;
struct msgb *nmsg;
- if (!ms->plmn.state) {
+ if (!ms->started) {
if (argv[0][0] == 'a')
set->plmn_mode = PLMN_MODE_AUTO;
else
set->plmn_mode = PLMN_MODE_MANUAL;
-
- return CMD_SUCCESS;
+ } else {
+ if (argv[0][0] == 'a')
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
+ else
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
+ if (!nmsg)
+ return CMD_WARNING;
+ gsm322_plmn_sendmsg(ms, nmsg);
}
- if (argv[0][0] == 'a')
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
- else
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
- if (!nmsg)
- return CMD_WARNING;
- gsm322_plmn_sendmsg(ms, nmsg);
return CMD_SUCCESS;
}
set->imei_random = 0;
- vty_restart(vty, ms);
return CMD_SUCCESS;
}
set->imei_random = atoi(argv[0]);
- vty_restart(vty, ms);
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
-DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
- "Stick to the given cell\nARFCN of the cell to stick to")
+DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023> [pcs]",
+ "Stick to the given cell\nARFCN of the cell to stick to\n"
+ "Given frequency is PCS band (1900) rather than DCS band.")
{
struct osmocom_ms *ms = vty->index;
struct gsm_settings *set = &ms->settings;
+ uint16_t arfcn = atoi(argv[0]);
+ if (argc > 1) {
+ if (arfcn < 512 || arfcn > 810) {
+ vty_out(vty, "Given ARFCN not in PCS band%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ arfcn |= ARFCN_PCS;
+ }
set->stick = 1;
- set->stick_arfcn = atoi(argv[0]);
+ set->stick_arfcn = arfcn;
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
+DEFUN(cfg_ms_neighbour, cfg_ms_neighbour_cmd, "neighbour-measurement",
+ "Allow neighbour cell measurement in idle mode")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->no_neighbour = 0;
+
+ vty_restart_if_started(vty, ms);
+
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_no_neighbour, cfg_ms_no_neighbour_cmd, "no neighbour-measurement",
+ NO_STR "Do not allow neighbour cell measurement in idle mode")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->no_neighbour = 1;
+
+ vty_restart_if_started(vty, ms);
+
+ return CMD_SUCCESS;
+}
+
static int config_write_dummy(struct vty *vty)
{
return CMD_SUCCESS;
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_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
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",
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);
+SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 1);
+SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 1);
+SUP_EN(cfg_ms_sup_gsm_850, cfg_ms_sup_gsm_850_cmd, gsm_850, "gsm-850",
+ "GSM 850", 1);
+SUP_DI(cfg_ms_sup_no_gsm_850, cfg_ms_sup_no_gsm_850_cmd, gsm_850, "gsm-850",
+ "GSM 850", 1);
+SUP_EN(cfg_ms_sup_pcs, cfg_ms_sup_pcs_cmd, pcs, "pcs", "PCS (1900)", 1);
+SUP_DI(cfg_ms_sup_no_pcs, cfg_ms_sup_no_pcs_cmd, pcs, "pcs", "PCS (1900)", 1);
+SUP_EN(cfg_ms_sup_gsm_480, cfg_ms_sup_gsm_480_cmd, gsm_480, "gsm-480",
+ "GSM 480", 1);
+SUP_DI(cfg_ms_sup_no_gsm_480, cfg_ms_sup_no_gsm_480_cmd, gsm_480, "gsm-480",
+ "GSM 480", 1);
+SUP_EN(cfg_ms_sup_gsm_450, cfg_ms_sup_gsm_450_cmd, gsm_450, "gsm-450",
+ "GSM 450", 1);
+SUP_DI(cfg_ms_sup_no_gsm_450, cfg_ms_sup_no_gsm_450_cmd, gsm_450, "gsm-450",
+ "GSM 450", 1);
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"
+ "Select power class for GSM 900\n"
"20 Watts\n"
"8 Watts\n"
"5 Watts\n"
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 "
+ vty_out(vty, "Note: You selected a higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_850, cfg_ms_sup_class_850_cmd, "class-850 (1|2|3|4|5)",
+ "Select power class for GSM 850\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_850 = atoi(argv[0]);
+
+ if (set->class_850 < sup->class_850 && !vty_reading)
+ vty_out(vty, "Note: You selected a higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_400, cfg_ms_sup_class_400_cmd, "class-400 (1|2|3|4|5)",
+ "Select power class for GSM 400 (480 and 450)\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_400 = atoi(argv[0]);
+
+ if (set->class_400 < sup->class_400 && !vty_reading)
+ vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
return CMD_SUCCESS;
if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
&& !vty_reading)
- vty_out(vty, "You selected an higher class than supported "
+ vty_out(vty, "Note: You selected a higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_pcs, cfg_ms_sup_class_pcs_cmd, "class-pcs (1|2|3)",
+ "Select power class for PCS 1900\n"
+ "1 Watt\n"
+ "0.25 Watts\n"
+ "2 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_pcs = atoi(argv[0]);
+
+ if (((set->class_pcs + 1) & 3) < ((sup->class_pcs + 1) & 3)
+ && !vty_reading)
+ vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
return CMD_SUCCESS;
return CMD_WARNING;
}
- if (ch_cap != set->ch_cap
+ if (ms->started && ch_cap != set->ch_cap
&& (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
- vty_restart(vty, ms);
+ vty_restart_if_started(vty, ms);
set->ch_cap = ch_cap;
return CMD_SUCCESS;
}
+DEFUN(cfg_ms_sup_skip_max_per_band, cfg_ms_sup_skip_max_per_band_cmd,
+ "skip-max-per-band",
+ "Scan all frequencies per band, not only a maximum number")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->skip_max_per_band = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_no_skip_max_per_band, cfg_ms_sup_no_skip_max_per_band_cmd,
+ "no skip-max-per-band",
+ NO_STR "Scan only a maximum number of frequencies per band")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->skip_max_per_band = 0;
+
+ return CMD_SUCCESS;
+}
+
/* per testsim config */
DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
"Configure test SIM emulation")
strcpy(set->test_imsi, argv[0]);
- vty_restart(vty, ms);
+ vty_restart_if_started(vty, ms);
+
return CMD_SUCCESS;
}
set->test_rplmn_valid = 0;
- vty_restart(vty, ms);
+ vty_restart_if_started(vty, ms);
+
return CMD_SUCCESS;
}
uint16_t mcc = gsm_input_mcc((char *)argv[0]),
mnc = gsm_input_mnc((char *)argv[1]);
- if (!mcc) {
+ if (mcc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!mnc) {
+ if (mnc == GSM_INPUT_INVALID) {
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
else
set->test_tmsi = 0xffffffff;
- vty_restart(vty, ms);
+ vty_restart_if_started(vty, ms);
+
return CMD_SUCCESS;
}
break;
}
- vty_restart(vty, ms);
+ vty_restart_if_started(vty, ms);
+
return CMD_SUCCESS;
}
install_element_ve(&show_support_cmd);
install_element_ve(&show_cell_cmd);
install_element_ve(&show_cell_si_cmd);
+ install_element_ve(&show_nbcells_cmd);
install_element_ve(&show_ba_cmd);
install_element_ve(&show_forb_la_cmd);
install_element_ve(&show_forb_plmn_cmd);
install_element(ENABLE_NODE, &call_cmd);
install_element(ENABLE_NODE, &call_retr_cmd);
install_element(ENABLE_NODE, &call_dtmf_cmd);
+ install_element(ENABLE_NODE, &test_reselection_cmd);
+ install_element(ENABLE_NODE, &delete_forbidden_plmn_cmd);
#ifdef _HAVE_GPSD
install_element(CONFIG_NODE, &cfg_gps_host_cmd);
install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
+ install_element(CONFIG_NODE, &cfg_hide_default_cmd);
+ install_element(CONFIG_NODE, &cfg_no_hide_default_cmd);
+
install_element(CONFIG_NODE, &cfg_ms_cmd);
install_element(CONFIG_NODE, &cfg_ms_create_cmd);
install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
install_element(MS_NODE, &cfg_ms_abbrev_cmd);
install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
install_element(MS_NODE, &cfg_ms_testsim_cmd);
+ install_element(MS_NODE, &cfg_ms_neighbour_cmd);
+ install_element(MS_NODE, &cfg_ms_no_neighbour_cmd);
install_element(MS_NODE, &cfg_ms_support_cmd);
install_node(&support_node, config_write_dummy);
install_default(SUPPORT_NODE);
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_gsm_850_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_850_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_pcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_pcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_480_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_480_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_450_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_450_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_class_850_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_pcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_400_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_no_half_v3_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_skip_max_per_band_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_skip_max_per_band_cmd);
install_node(&testsim_node, config_write_dummy);
install_default(TESTSIM_NODE);
install_element(TESTSIM_NODE, &ournode_exit_cmd);