2 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <sys/types.h>
28 #include <osmocom/vty.h>
29 #include <osmocom/vty/telnet_interface.h>
31 #include <osmocore/gsm48.h>
32 #include <osmocom/osmocom_data.h>
33 #include <osmocom/networks.h>
34 #include <osmocom/mncc.h>
35 #include <osmocom/transaction.h>
37 int mncc_call(struct osmocom_ms *ms, char *number);
38 int mncc_hangup(struct osmocom_ms *ms);
39 int mncc_answer(struct osmocom_ms *ms);
40 int mncc_hold(struct osmocom_ms *ms);
41 int mncc_retrieve(struct osmocom_ms *ms, int number);
43 extern struct llist_head ms_list;
44 extern struct llist_head active_connections;
46 struct cmd_node ms_node = {
52 struct cmd_node testsim_node = {
58 static void print_vty(void *priv, const char *fmt, ...)
61 struct vty *vty = priv;
65 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
66 buffer[sizeof(buffer) - 1] = '\0';
70 if (buffer[strlen(buffer) - 1] == '\n') {
71 buffer[strlen(buffer) - 1] = '\0';
72 vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
74 vty_out(vty, "%s", buffer);
78 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
80 struct osmocom_ms *ms;
82 llist_for_each_entry(ms, &ms_list, entity) {
83 if (!strcmp(ms->name, name))
86 vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
91 DEFUN(show_ms, show_ms_cmd, "show ms",
92 SHOW_STR "Display available MS entities\n")
94 struct osmocom_ms *ms;
96 llist_for_each_entry(ms, &ms_list, entity) {
97 struct gsm_settings *set = &ms->settings;
99 vty_out(vty, "MS NAME: %s%s", ms->name, VTY_NEWLINE);
100 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
101 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
102 if (set->imei_random)
103 vty_out(vty, " IMEI generation: random (%d trailing "
104 "digits)%s", set->imei_random, VTY_NEWLINE);
106 vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
107 vty_out(vty, " network selection mode: %s%s",
108 (set->plmn_mode == PLMN_MODE_AUTO)
109 ? "automatic" : "manual", VTY_NEWLINE);
115 DEFUN(show_support, show_support_cmd, "show support [ms_name]",
116 SHOW_STR "Display information about MS support\n"
117 "Name of MS (see \"show ms\")")
119 struct osmocom_ms *ms;
122 ms = get_ms(argv[0], vty);
125 gsm_support_dump(&ms->support, print_vty, vty);
127 llist_for_each_entry(ms, &ms_list, entity) {
128 gsm_support_dump(&ms->support, print_vty, vty);
129 vty_out(vty, "%s", VTY_NEWLINE);
136 static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
138 struct gsm_trans *trans;
140 vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
141 if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
142 vty_out(vty, " automatic network selection: %s%s",
143 plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
145 vty_out(vty, " manual network selection: %s%s",
146 plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
147 vty_out(vty, " cell selection: %s%s",
148 cs_state_names[ms->cellsel.state], VTY_NEWLINE);
149 vty_out(vty, " radio ressource layer: %s%s",
150 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
151 vty_out(vty, " mobility management layer: %s",
152 gsm48_mm_state_names[ms->mmlayer.state]);
153 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
155 gsm48_mm_substate_names[ms->mmlayer.substate]);
156 vty_out(vty, "%s", VTY_NEWLINE);
157 llist_for_each_entry(trans, &ms->trans_list, entry) {
158 vty_out(vty, " call control: %s%s",
159 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
163 DEFUN(show_states, show_states_cmd, "show states [ms_name]",
164 SHOW_STR "Display current states of given MS\n"
165 "Name of MS (see \"show ms\")")
167 struct osmocom_ms *ms;
170 ms = get_ms(argv[0], vty);
173 gsm_states_dump(ms, vty);
175 llist_for_each_entry(ms, &ms_list, entity) {
176 gsm_states_dump(ms, vty);
177 vty_out(vty, "%s", VTY_NEWLINE);
184 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
185 SHOW_STR "Display information about subscriber\n"
186 "Name of MS (see \"show ms\")")
188 struct osmocom_ms *ms;
191 ms = get_ms(argv[0], vty);
194 gsm_subscr_dump(&ms->subscr, print_vty, vty);
196 llist_for_each_entry(ms, &ms_list, entity) {
197 gsm_subscr_dump(&ms->subscr, print_vty, vty);
198 vty_out(vty, "%s", VTY_NEWLINE);
205 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
206 SHOW_STR "Display information about received cells\n"
207 "Name of MS (see \"show ms\")")
209 struct osmocom_ms *ms;
211 ms = get_ms(argv[0], vty);
215 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
221 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
222 SHOW_STR "Display information about received cell\n"
223 "Name of MS (see \"show ms\")\nRadio frequency number")
225 struct osmocom_ms *ms;
227 struct gsm48_sysinfo *s;
229 ms = get_ms(argv[0], vty);
234 if (i < 0 || i > 1023) {
235 vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
236 argv[1], VTY_NEWLINE);
239 s = ms->cellsel.list[i].sysinfo;
241 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
242 argv[1], VTY_NEWLINE);
246 gsm48_sysinfo_dump(s, i, print_vty, vty);
251 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [mcc] [mnc]",
252 SHOW_STR "Display information about band allocations\n"
253 "Name of MS (see \"show ms\")\nMobile Country Code\n"
254 "Mobile Network Code")
256 struct osmocom_ms *ms;
257 uint16_t mcc = 0, mnc = 0;
259 ms = get_ms(argv[0], vty);
264 mcc = gsm_input_mcc((char *)argv[1]);
265 mnc = gsm_input_mnc((char *)argv[2]);
267 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
271 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
276 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
281 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
282 SHOW_STR "Display information about forbidden cells / networks\n"
283 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
285 struct osmocom_ms *ms;
287 ms = get_ms(argv[0], vty);
291 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
296 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
297 SHOW_STR "Display information about forbidden cells / networks\n"
298 "Display forbidden location areas\nName of MS (see \"show ms\")")
300 struct osmocom_ms *ms;
302 ms = get_ms(argv[0], vty);
306 gsm322_dump_forbidden_la(ms, print_vty, vty);
311 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
312 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
314 struct osmocom_ms *ms;
316 ms = get_ms(argv[0], vty);
320 gsm48_rr_start_monitor(ms);
325 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
326 NO_STR "Monitor...\nDeactivate monitor of network information\n"
327 "Name of MS (see \"show ms\")")
329 struct osmocom_ms *ms;
331 ms = get_ms(argv[0], vty);
335 gsm48_rr_stop_monitor(ms);
340 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [mcc] [mnc]",
341 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
342 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN")
344 struct osmocom_ms *ms;
345 uint16_t mcc = 0x001, mnc = 0x01f;
347 ms = get_ms(argv[0], vty);
351 if (ms->subscr.sim_valid) {
352 vty_out(vty, "Sim already presend, remove first!%s",
358 mcc = gsm_input_mcc((char *)argv[1]);
359 mnc = gsm_input_mnc((char *)argv[2]);
361 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
365 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
370 gsm_subscr_testcard(ms, mcc, mnc);
375 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
376 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
378 struct osmocom_ms *ms;
380 ms = get_ms(argv[0], vty);
384 if (!ms->subscr.sim_valid) {
385 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
389 gsm_subscr_remove(ms);
394 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
395 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
396 "Mobile Country Code\nMobile Network Code")
398 struct osmocom_ms *ms;
399 struct gsm322_plmn *plmn;
401 struct gsm322_msg *ngm;
402 struct gsm322_plmn_list *temp;
403 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
404 mnc = gsm_input_mnc((char *)argv[2]);
407 ms = get_ms(argv[0], vty);
413 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
417 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
421 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
422 if (temp->mcc == mcc && temp->mnc == mnc)
425 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
429 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
432 ngm = (struct gsm322_msg *) nmsg->data;
435 gsm322_plmn_sendmsg(ms, nmsg);
440 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
441 "Make a call\nName of MS (see \"show ms\")\nPhone number to call\n"
442 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
443 "Hold current active call\n")
445 struct osmocom_ms *ms;
447 ms = get_ms(argv[0], vty);
451 switch (argv[1][0]) {
456 if (argv[1][1] == 'a')
462 mncc_call(ms, (char *)argv[1]);
468 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [number]",
469 "Make a call\nName of MS (see \"show ms\")\n"
470 "Retrieve call on hold\nNumber of call to retrieve")
472 struct osmocom_ms *ms;
474 ms = get_ms(argv[0], vty);
478 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
483 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
484 "Network ...\nShow results of network search (again)\n"
485 "Name of MS (see \"show ms\")")
487 struct osmocom_ms *ms;
488 struct gsm322_plmn *plmn;
489 struct gsm322_plmn_list *temp;
491 ms = get_ms(argv[0], vty);
496 if (ms->settings.plmn_mode != PLMN_MODE_AUTO
497 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
498 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
502 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
503 vty_out(vty, " Network %s, %s (%s, %s)%s",
504 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
505 gsm_get_mcc(temp->mcc),
506 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
511 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
512 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
514 struct osmocom_ms *ms;
517 ms = get_ms(argv[0], vty);
521 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
524 gsm322_plmn_sendmsg(ms, nmsg);
530 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
531 "Select a mobile station to configure\nName of MS (see \"show ms\")")
533 struct osmocom_ms *ms;
535 ms = get_ms(argv[0], vty);
545 static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
547 struct gsm_settings *set = &ms->settings;
549 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
550 switch(set->simtype) {
551 case GSM_SIM_TYPE_NONE:
552 vty_out(vty, " sim none%s", VTY_NEWLINE);
554 case GSM_SIM_TYPE_SLOT:
555 vty_out(vty, " sim slot%s", VTY_NEWLINE);
557 case GSM_SIM_TYPE_TEST:
558 vty_out(vty, " sim test%s", VTY_NEWLINE);
561 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
562 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
563 vty_out(vty, " imei %s %s%s", set->imei,
564 set->imeisv + strlen(set->imei), VTY_NEWLINE);
565 if (set->imei_random)
566 vty_out(vty, " imei-random %d%s", set->imei_random,
569 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
570 if (set->emergency_imsi[0])
571 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
574 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
575 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
576 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
577 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
578 vty_out(vty, " test-sim%s", VTY_NEWLINE);
579 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
580 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
582 if (set->test_rplmn_valid)
583 vty_out(vty, " rplmn %s %s%s",
584 gsm_print_mcc(set->test_rplmn_mcc),
585 gsm_print_mnc(set->test_rplmn_mnc),
588 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
589 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
590 : "foreign-country", VTY_NEWLINE);
591 vty_out(vty, " exit%s", VTY_NEWLINE);
592 if (set->alter_tx_power)
593 if (set->alter_tx_power_value)
594 vty_out(vty, " tx-power %d%s",
595 set->alter_tx_power_value, VTY_NEWLINE);
597 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
599 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
600 if (set->alter_delay)
601 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
604 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
606 vty_out(vty, " stick %d%s", set->stick_arfcn,
609 vty_out(vty, " no stick%s", VTY_NEWLINE);
611 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
613 vty_out(vty, " location-updating%s", VTY_NEWLINE);
614 vty_out(vty, "exit%s", VTY_NEWLINE);
615 vty_out(vty, "!%s", VTY_NEWLINE);
618 static int config_write_ms(struct vty *vty)
620 struct osmocom_ms *ms;
622 llist_for_each_entry(ms, &ms_list, entity)
623 config_write_ms_single(vty, ms);
628 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|test)",
629 "Set sim card type when powering on\nNo sim interted\n"
632 struct osmocom_ms *ms = vty->index;
634 switch (argv[0][0]) {
636 ms->settings.simtype = GSM_SIM_TYPE_NONE;
639 ms->settings.simtype = GSM_SIM_TYPE_SLOT;
642 ms->settings.simtype = GSM_SIM_TYPE_TEST;
649 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
650 "Set network selection mode\nAutomatic network selection\n"
651 "Manual network selection")
653 struct osmocom_ms *ms = vty->index;
656 if (!ms->plmn.state) {
657 if (argv[0][0] == 'a')
658 ms->settings.plmn_mode = PLMN_MODE_AUTO;
660 ms->settings.plmn_mode = PLMN_MODE_MANUAL;
664 if (argv[0][0] == 'a')
665 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
667 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
670 gsm322_plmn_sendmsg(ms, nmsg);
675 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
676 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
677 "Software version digit")
679 struct osmocom_ms *ms = vty->index;
680 char *error, *sv = "0";
683 sv = (char *)argv[1];
685 error = gsm_check_imei(argv[0], sv);
687 vty_out(vty, "%s%s", error, VTY_NEWLINE);
691 strcpy(ms->settings.imei, argv[0]);
692 strcpy(ms->settings.imeisv, argv[0]);
693 strcpy(ms->settings.imeisv + 15, sv);
698 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
699 "Use fixed IMEI on every power on")
701 struct osmocom_ms *ms = vty->index;
703 ms->settings.imei_random = 0;
708 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
709 "Use random IMEI on every power on\n"
710 "Number of trailing digits to randomize")
712 struct osmocom_ms *ms = vty->index;
714 ms->settings.imei_random = atoi(argv[0]);
719 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
720 "Use special IMSI for emergency calls\n15 digits IMSI")
722 struct osmocom_ms *ms = vty->index;
725 error = gsm_check_imsi(argv[0]);
727 vty_out(vty, "%s%s", error, VTY_NEWLINE);
730 strcpy(ms->settings.emergency_imsi, argv[0]);
735 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
736 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
738 struct osmocom_ms *ms = vty->index;
740 ms->settings.emergency_imsi[0] = '\0';
745 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
746 NO_STR "Disallow waiting calls")
748 struct osmocom_ms *ms = vty->index;
755 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
756 "Allow waiting calls")
758 struct osmocom_ms *ms = vty->index;
765 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
766 "Force caller ID presentation")
768 struct osmocom_ms *ms = vty->index;
770 ms->settings.clip = 1;
771 ms->settings.clir = 0;
776 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
777 "Force caller ID restriction")
779 struct osmocom_ms *ms = vty->index;
781 ms->settings.clip = 0;
782 ms->settings.clir = 1;
787 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
788 NO_STR "Disable forcing of caller ID presentation")
790 struct osmocom_ms *ms = vty->index;
792 ms->settings.clip = 0;
797 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
798 NO_STR "Disable forcing of caller ID restriction")
800 struct osmocom_ms *ms = vty->index;
802 ms->settings.clir = 0;
807 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
808 "Set the way to choose transmit power\nControlled by BTS\n"
809 "Always full power\nFixed GSM power value if supported")
811 struct osmocom_ms *ms = vty->index;
813 switch (argv[0][0]) {
815 ms->settings.alter_tx_power = 0;
818 ms->settings.alter_tx_power = 1;
819 ms->settings.alter_tx_power_value = 0;
826 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
827 "Set the way to choose transmit power\n"
828 "Fixed GSM power value if supported")
830 struct osmocom_ms *ms = vty->index;
832 ms->settings.alter_tx_power = 1;
833 ms->settings.alter_tx_power_value = atoi(argv[0]);
838 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
839 "Simulate a lower or higher distance from the BTS\n"
840 "Delay in half bits (distance in 553.85 meter steps)")
842 struct osmocom_ms *ms = vty->index;
844 ms->settings.alter_delay = atoi(argv[0]);
849 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
850 NO_STR "Do not simulate a lower or higher distance from the BTS")
852 struct osmocom_ms *ms = vty->index;
854 ms->settings.alter_delay = 0;
859 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
860 "Stick to the given cell\nARFCN of the cell to stick to")
862 struct osmocom_ms *ms = vty->index;
864 ms->settings.stick = 1;
865 ms->settings.stick_arfcn = atoi(argv[0]);
870 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
871 NO_STR "Do not stick to any cell")
873 struct osmocom_ms *ms = vty->index;
875 ms->settings.stick = 0;
880 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
881 "Allow location updating")
883 struct osmocom_ms *ms = vty->index;
885 ms->settings.no_lupd = 0;
890 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
891 NO_STR "Do not allow location updating")
893 struct osmocom_ms *ms = vty->index;
895 ms->settings.no_lupd = 1;
900 /* per testsim config */
901 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
902 "Configure test SIM emulation")
904 vty->node = TESTSIM_NODE;
909 static int config_write_dummy(struct vty *vty)
914 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
915 "Set IMSI on test card\n15 digits IMSI")
917 struct osmocom_ms *ms = vty->index;
918 char *error = gsm_check_imsi(argv[0]);
921 vty_out(vty, "%s%s", error, VTY_NEWLINE);
925 strcpy(ms->settings.test_imsi, argv[0]);
930 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
931 "Allow access to barred cells")
933 struct osmocom_ms *ms = vty->index;
935 ms->settings.test_barr = 1;
940 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
941 NO_STR "Deny access to barred cells")
943 struct osmocom_ms *ms = vty->index;
945 ms->settings.test_barr = 0;
950 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
951 NO_STR "Unset Registered PLMN")
953 struct osmocom_ms *ms = vty->index;
955 ms->settings.test_rplmn_valid = 0;
960 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
961 "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
963 struct osmocom_ms *ms = vty->index;
964 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
965 mnc = gsm_input_mnc((char *)argv[1]);
968 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
972 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
975 ms->settings.test_rplmn_valid = 1;
976 ms->settings.test_rplmn_mcc = mcc;
977 ms->settings.test_rplmn_mnc = mnc;
982 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
983 "Set Home PLMN search mode\n"
984 "Search for HPLMN when on any other network\n"
985 "Search for HPLMN when in a different country")
987 struct osmocom_ms *ms = vty->index;
989 switch (argv[0][0]) {
991 ms->settings.test_always = 1;
994 ms->settings.test_always = 0;
1001 enum node_type ms_vty_go_parent(struct vty *vty)
1003 switch (vty->node) {
1005 vty->node = CONFIG_NODE;
1009 vty->node = MS_NODE;
1012 vty->node = CONFIG_NODE;
1018 /* Down vty node level. */
1019 gDEFUN(ournode_exit,
1020 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
1022 switch (vty->node) {
1024 vty->node = CONFIG_NODE;
1028 vty->node = MS_NODE;
1036 /* End of configuration. */
1038 ournode_end_cmd, "end", "End current mode and change to enable mode.")
1040 switch (vty->node) {
1043 /* Nothing to do. */
1049 vty_config_unlock(vty);
1050 vty->node = ENABLE_NODE;
1052 vty->index_sub = NULL;
1060 int ms_vty_init(void)
1062 install_element_ve(&show_ms_cmd);
1063 install_element_ve(&show_subscr_cmd);
1064 install_element_ve(&show_support_cmd);
1065 install_element_ve(&show_states_cmd);
1066 install_element_ve(&show_cell_cmd);
1067 install_element_ve(&show_cell_si_cmd);
1068 install_element_ve(&show_ba_cmd);
1069 install_element_ve(&show_forb_la_cmd);
1070 install_element_ve(&show_forb_plmn_cmd);
1071 install_element_ve(&monitor_network_cmd);
1072 install_element_ve(&no_monitor_network_cmd);
1074 install_element(ENABLE_NODE, &sim_test_cmd);
1075 install_element(ENABLE_NODE, &sim_remove_cmd);
1076 install_element(ENABLE_NODE, &network_search_cmd);
1077 install_element(ENABLE_NODE, &network_show_cmd);
1078 install_element(ENABLE_NODE, &network_select_cmd);
1079 install_element(ENABLE_NODE, &call_cmd);
1080 install_element(ENABLE_NODE, &call_retr_cmd);
1082 install_element(CONFIG_NODE, &cfg_ms_cmd);
1083 install_element(CONFIG_NODE, &ournode_end_cmd);
1084 install_node(&ms_node, config_write_ms);
1085 install_default(MS_NODE);
1086 install_element(MS_NODE, &ournode_exit_cmd);
1087 install_element(MS_NODE, &ournode_end_cmd);
1088 install_element(MS_NODE, &cfg_ms_sim_cmd);
1089 install_element(MS_NODE, &cfg_ms_mode_cmd);
1090 install_element(MS_NODE, &cfg_ms_imei_cmd);
1091 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
1092 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
1093 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
1094 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
1095 install_element(MS_NODE, &cfg_ms_cw_cmd);
1096 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
1097 install_element(MS_NODE, &cfg_ms_clip_cmd);
1098 install_element(MS_NODE, &cfg_ms_clir_cmd);
1099 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
1100 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
1101 install_element(MS_NODE, &cfg_ms_testsim_cmd);
1102 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
1103 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
1104 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
1105 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
1106 install_element(MS_NODE, &cfg_ms_stick_cmd);
1107 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
1108 install_element(MS_NODE, &cfg_ms_lupd_cmd);
1109 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
1111 install_node(&testsim_node, config_write_dummy);
1112 install_default(TESTSIM_NODE);
1113 install_element(TESTSIM_NODE, &ournode_exit_cmd);
1114 install_element(TESTSIM_NODE, &ournode_end_cmd);
1115 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
1116 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
1117 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
1118 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
1119 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
1120 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
1125 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
1127 struct telnet_connection *connection;
1133 va_start(args, fmt);
1134 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
1135 buffer[sizeof(buffer) - 1] = '\0';
1142 llist_for_each_entry(connection, &active_connections, entry) {
1143 vty = connection->vty;
1147 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
1151 if (buffer[strlen(buffer) - 1] == '\n') {
1152 buffer[strlen(buffer) - 1] = '\0';
1153 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
1154 buffer[strlen(buffer)] = '\n';
1156 vty_out(vty, "%% %s", buffer);