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 <osmocore/gsm48.h>
30 #include <osmocom/bb/common/osmocom_data.h>
31 #include <osmocom/bb/common/networks.h>
32 #include <osmocom/bb/mobile/mncc.h>
33 #include <osmocom/bb/mobile/transaction.h>
34 #include <osmocom/bb/mobile/vty.h>
35 #include <osmocom/bb/mobile/gps.h>
36 #include <osmocom/vty/telnet_interface.h>
38 int mncc_call(struct osmocom_ms *ms, char *number);
39 int mncc_hangup(struct osmocom_ms *ms);
40 int mncc_answer(struct osmocom_ms *ms);
41 int mncc_hold(struct osmocom_ms *ms);
42 int mncc_retrieve(struct osmocom_ms *ms, int number);
44 extern struct llist_head ms_list;
45 extern struct llist_head active_connections;
47 struct cmd_node ms_node = {
53 struct cmd_node testsim_node = {
59 static void print_vty(void *priv, const char *fmt, ...)
62 struct vty *vty = priv;
66 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
67 buffer[sizeof(buffer) - 1] = '\0';
71 if (buffer[strlen(buffer) - 1] == '\n') {
72 buffer[strlen(buffer) - 1] = '\0';
73 vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
75 vty_out(vty, "%s", buffer);
79 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
81 struct osmocom_ms *ms;
83 llist_for_each_entry(ms, &ms_list, entity) {
84 if (!strcmp(ms->name, name))
87 vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
92 DEFUN(show_ms, show_ms_cmd, "show ms",
93 SHOW_STR "Display available MS entities\n")
95 struct osmocom_ms *ms;
97 llist_for_each_entry(ms, &ms_list, entity) {
98 struct gsm_settings *set = &ms->settings;
100 vty_out(vty, "MS NAME: %s%s", ms->name, VTY_NEWLINE);
101 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
102 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
103 if (set->imei_random)
104 vty_out(vty, " IMEI generation: random (%d trailing "
105 "digits)%s", set->imei_random, VTY_NEWLINE);
107 vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
108 vty_out(vty, " network selection mode: %s%s",
109 (set->plmn_mode == PLMN_MODE_AUTO)
110 ? "automatic" : "manual", VTY_NEWLINE);
116 DEFUN(show_support, show_support_cmd, "show support [ms_name]",
117 SHOW_STR "Display information about MS support\n"
118 "Name of MS (see \"show ms\")")
120 struct osmocom_ms *ms;
123 ms = get_ms(argv[0], vty);
126 gsm_support_dump(&ms->support, print_vty, vty);
128 llist_for_each_entry(ms, &ms_list, entity) {
129 gsm_support_dump(&ms->support, print_vty, vty);
130 vty_out(vty, "%s", VTY_NEWLINE);
137 static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
139 struct gsm_trans *trans;
141 vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
142 if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
143 vty_out(vty, " automatic network selection: %s%s",
144 plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
146 vty_out(vty, " manual network selection: %s%s",
147 plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
148 vty_out(vty, " cell selection: %s%s",
149 cs_state_names[ms->cellsel.state], VTY_NEWLINE);
150 vty_out(vty, " radio ressource layer: %s%s",
151 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
152 vty_out(vty, " mobility management layer: %s",
153 gsm48_mm_state_names[ms->mmlayer.state]);
154 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
156 gsm48_mm_substate_names[ms->mmlayer.substate]);
157 vty_out(vty, "%s", VTY_NEWLINE);
158 llist_for_each_entry(trans, &ms->trans_list, entry) {
159 vty_out(vty, " call control: %s%s",
160 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
164 DEFUN(show_states, show_states_cmd, "show states [ms_name]",
165 SHOW_STR "Display current states of given MS\n"
166 "Name of MS (see \"show ms\")")
168 struct osmocom_ms *ms;
171 ms = get_ms(argv[0], vty);
174 gsm_states_dump(ms, vty);
176 llist_for_each_entry(ms, &ms_list, entity) {
177 gsm_states_dump(ms, vty);
178 vty_out(vty, "%s", VTY_NEWLINE);
185 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
186 SHOW_STR "Display information about subscriber\n"
187 "Name of MS (see \"show ms\")")
189 struct osmocom_ms *ms;
192 ms = get_ms(argv[0], vty);
195 gsm_subscr_dump(&ms->subscr, print_vty, vty);
197 llist_for_each_entry(ms, &ms_list, entity) {
198 gsm_subscr_dump(&ms->subscr, print_vty, vty);
199 vty_out(vty, "%s", VTY_NEWLINE);
206 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
207 SHOW_STR "Display information about received cells\n"
208 "Name of MS (see \"show ms\")")
210 struct osmocom_ms *ms;
212 ms = get_ms(argv[0], vty);
216 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
222 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
223 SHOW_STR "Display information about received cell\n"
224 "Name of MS (see \"show ms\")\nRadio frequency number")
226 struct osmocom_ms *ms;
228 struct gsm48_sysinfo *s;
230 ms = get_ms(argv[0], vty);
235 if (i < 0 || i > 1023) {
236 vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
237 argv[1], VTY_NEWLINE);
240 s = ms->cellsel.list[i].sysinfo;
242 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
243 argv[1], VTY_NEWLINE);
247 gsm48_sysinfo_dump(s, i, print_vty, vty);
252 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [mcc] [mnc]",
253 SHOW_STR "Display information about band allocations\n"
254 "Name of MS (see \"show ms\")\nMobile Country Code\n"
255 "Mobile Network Code")
257 struct osmocom_ms *ms;
258 uint16_t mcc = 0, mnc = 0;
260 ms = get_ms(argv[0], vty);
265 mcc = gsm_input_mcc((char *)argv[1]);
266 mnc = gsm_input_mnc((char *)argv[2]);
268 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
272 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
277 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
282 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
283 SHOW_STR "Display information about forbidden cells / networks\n"
284 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
286 struct osmocom_ms *ms;
288 ms = get_ms(argv[0], vty);
292 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
297 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
298 SHOW_STR "Display information about forbidden cells / networks\n"
299 "Display forbidden location areas\nName of MS (see \"show ms\")")
301 struct osmocom_ms *ms;
303 ms = get_ms(argv[0], vty);
307 gsm322_dump_forbidden_la(ms, print_vty, vty);
312 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
313 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
315 struct osmocom_ms *ms;
317 ms = get_ms(argv[0], vty);
321 gsm48_rr_start_monitor(ms);
326 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
327 NO_STR "Monitor...\nDeactivate monitor of network information\n"
328 "Name of MS (see \"show ms\")")
330 struct osmocom_ms *ms;
332 ms = get_ms(argv[0], vty);
336 gsm48_rr_stop_monitor(ms);
341 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [mcc] [mnc]",
342 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
343 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN")
345 struct osmocom_ms *ms;
346 uint16_t mcc = 0x001, mnc = 0x01f;
348 ms = get_ms(argv[0], vty);
352 if (ms->subscr.sim_valid) {
353 vty_out(vty, "Sim already presend, remove first!%s",
359 mcc = gsm_input_mcc((char *)argv[1]);
360 mnc = gsm_input_mnc((char *)argv[2]);
362 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
366 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
371 gsm_subscr_testcard(ms, mcc, mnc);
376 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
377 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
379 struct osmocom_ms *ms;
381 ms = get_ms(argv[0], vty);
385 if (!ms->subscr.sim_valid) {
386 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
390 gsm_subscr_remove(ms);
395 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
396 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
397 "Mobile Country Code\nMobile Network Code")
399 struct osmocom_ms *ms;
400 struct gsm322_plmn *plmn;
402 struct gsm322_msg *ngm;
403 struct gsm322_plmn_list *temp;
404 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
405 mnc = gsm_input_mnc((char *)argv[2]);
408 ms = get_ms(argv[0], vty);
414 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
418 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
422 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
423 if (temp->mcc == mcc && temp->mnc == mnc)
426 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
430 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
433 ngm = (struct gsm322_msg *) nmsg->data;
436 gsm322_plmn_sendmsg(ms, nmsg);
441 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
442 "Make a call\nName of MS (see \"show ms\")\nPhone number to call\n"
443 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
444 "Hold current active call\n")
446 struct osmocom_ms *ms;
448 ms = get_ms(argv[0], vty);
452 switch (argv[1][0]) {
457 if (argv[1][1] == 'a')
463 mncc_call(ms, (char *)argv[1]);
469 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [number]",
470 "Make a call\nName of MS (see \"show ms\")\n"
471 "Retrieve call on hold\nNumber of call to retrieve")
473 struct osmocom_ms *ms;
475 ms = get_ms(argv[0], vty);
479 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
484 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
485 "Network ...\nShow results of network search (again)\n"
486 "Name of MS (see \"show ms\")")
488 struct osmocom_ms *ms;
489 struct gsm322_plmn *plmn;
490 struct gsm322_plmn_list *temp;
492 ms = get_ms(argv[0], vty);
497 if (ms->settings.plmn_mode != PLMN_MODE_AUTO
498 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
499 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
503 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
504 vty_out(vty, " Network %s, %s (%s, %s)%s",
505 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
506 gsm_get_mcc(temp->mcc),
507 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
512 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
513 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
515 struct osmocom_ms *ms;
518 ms = get_ms(argv[0], vty);
522 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
525 gsm322_plmn_sendmsg(ms, nmsg);
530 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
535 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
543 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
544 NO_STR "Disable GPS receiver")
553 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
554 "GPS receiver\nSelect serial device\n"
555 "Full path of serial device including /dev/")
557 strncpy(gps.device, argv[0], sizeof(gps.device));
558 gps.device[sizeof(gps.device) - 1] = '\0';
562 vty_out(vty, "Failed to open GPS device!%s",
571 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
572 "(default|4800|""9600|19200|38400|57600|115200)",
573 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
575 if (argv[0][0] == 'd')
578 gps.baud = atoi(argv[0]);
583 vty_out(vty, "Failed to open GPS device!%s",
593 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
594 "Select a mobile station to configure\nName of MS (see \"show ms\")")
596 struct osmocom_ms *ms;
598 ms = get_ms(argv[0], vty);
608 static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
610 struct gsm_settings *set = &ms->settings;
612 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
613 switch(set->simtype) {
614 case GSM_SIM_TYPE_NONE:
615 vty_out(vty, " sim none%s", VTY_NEWLINE);
617 case GSM_SIM_TYPE_SLOT:
618 vty_out(vty, " sim slot%s", VTY_NEWLINE);
620 case GSM_SIM_TYPE_TEST:
621 vty_out(vty, " sim test%s", VTY_NEWLINE);
624 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
625 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
626 vty_out(vty, " imei %s %s%s", set->imei,
627 set->imeisv + strlen(set->imei), VTY_NEWLINE);
628 if (set->imei_random)
629 vty_out(vty, " imei-random %d%s", set->imei_random,
632 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
633 if (set->emergency_imsi[0])
634 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
637 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
638 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
639 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
640 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
641 vty_out(vty, " test-sim%s", VTY_NEWLINE);
642 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
643 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
645 if (set->test_rplmn_valid)
646 vty_out(vty, " rplmn %s %s%s",
647 gsm_print_mcc(set->test_rplmn_mcc),
648 gsm_print_mnc(set->test_rplmn_mnc),
651 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
652 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
653 : "foreign-country", VTY_NEWLINE);
654 vty_out(vty, " exit%s", VTY_NEWLINE);
655 if (set->alter_tx_power)
656 if (set->alter_tx_power_value)
657 vty_out(vty, " tx-power %d%s",
658 set->alter_tx_power_value, VTY_NEWLINE);
660 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
662 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
663 if (set->alter_delay)
664 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
667 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
669 vty_out(vty, " stick %d%s", set->stick_arfcn,
672 vty_out(vty, " no stick%s", VTY_NEWLINE);
674 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
676 vty_out(vty, " location-updating%s", VTY_NEWLINE);
677 vty_out(vty, "exit%s", VTY_NEWLINE);
678 vty_out(vty, "!%s", VTY_NEWLINE);
681 static int config_write_ms(struct vty *vty)
683 struct osmocom_ms *ms;
685 vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
687 vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
689 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
690 vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
691 vty_out(vty, "!%s", VTY_NEWLINE);
693 llist_for_each_entry(ms, &ms_list, entity)
694 config_write_ms_single(vty, ms);
699 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|test)",
700 "Set sim card type when powering on\nNo sim interted\n"
703 struct osmocom_ms *ms = vty->index;
705 switch (argv[0][0]) {
707 ms->settings.simtype = GSM_SIM_TYPE_NONE;
710 ms->settings.simtype = GSM_SIM_TYPE_SLOT;
713 ms->settings.simtype = GSM_SIM_TYPE_TEST;
720 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
721 "Set network selection mode\nAutomatic network selection\n"
722 "Manual network selection")
724 struct osmocom_ms *ms = vty->index;
727 if (!ms->plmn.state) {
728 if (argv[0][0] == 'a')
729 ms->settings.plmn_mode = PLMN_MODE_AUTO;
731 ms->settings.plmn_mode = PLMN_MODE_MANUAL;
735 if (argv[0][0] == 'a')
736 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
738 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
741 gsm322_plmn_sendmsg(ms, nmsg);
746 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
747 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
748 "Software version digit")
750 struct osmocom_ms *ms = vty->index;
751 char *error, *sv = "0";
754 sv = (char *)argv[1];
756 error = gsm_check_imei(argv[0], sv);
758 vty_out(vty, "%s%s", error, VTY_NEWLINE);
762 strcpy(ms->settings.imei, argv[0]);
763 strcpy(ms->settings.imeisv, argv[0]);
764 strcpy(ms->settings.imeisv + 15, sv);
769 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
770 "Use fixed IMEI on every power on")
772 struct osmocom_ms *ms = vty->index;
774 ms->settings.imei_random = 0;
779 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
780 "Use random IMEI on every power on\n"
781 "Number of trailing digits to randomize")
783 struct osmocom_ms *ms = vty->index;
785 ms->settings.imei_random = atoi(argv[0]);
790 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
791 "Use special IMSI for emergency calls\n15 digits IMSI")
793 struct osmocom_ms *ms = vty->index;
796 error = gsm_check_imsi(argv[0]);
798 vty_out(vty, "%s%s", error, VTY_NEWLINE);
801 strcpy(ms->settings.emergency_imsi, argv[0]);
806 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
807 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
809 struct osmocom_ms *ms = vty->index;
811 ms->settings.emergency_imsi[0] = '\0';
816 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
817 NO_STR "Disallow waiting calls")
819 struct osmocom_ms *ms = vty->index;
826 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
827 "Allow waiting calls")
829 struct osmocom_ms *ms = vty->index;
836 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
837 "Force caller ID presentation")
839 struct osmocom_ms *ms = vty->index;
841 ms->settings.clip = 1;
842 ms->settings.clir = 0;
847 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
848 "Force caller ID restriction")
850 struct osmocom_ms *ms = vty->index;
852 ms->settings.clip = 0;
853 ms->settings.clir = 1;
858 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
859 NO_STR "Disable forcing of caller ID presentation")
861 struct osmocom_ms *ms = vty->index;
863 ms->settings.clip = 0;
868 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
869 NO_STR "Disable forcing of caller ID restriction")
871 struct osmocom_ms *ms = vty->index;
873 ms->settings.clir = 0;
878 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
879 "Set the way to choose transmit power\nControlled by BTS\n"
880 "Always full power\nFixed GSM power value if supported")
882 struct osmocom_ms *ms = vty->index;
884 switch (argv[0][0]) {
886 ms->settings.alter_tx_power = 0;
889 ms->settings.alter_tx_power = 1;
890 ms->settings.alter_tx_power_value = 0;
897 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
898 "Set the way to choose transmit power\n"
899 "Fixed GSM power value if supported")
901 struct osmocom_ms *ms = vty->index;
903 ms->settings.alter_tx_power = 1;
904 ms->settings.alter_tx_power_value = atoi(argv[0]);
909 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
910 "Simulate a lower or higher distance from the BTS\n"
911 "Delay in half bits (distance in 553.85 meter steps)")
913 struct osmocom_ms *ms = vty->index;
915 ms->settings.alter_delay = atoi(argv[0]);
920 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
921 NO_STR "Do not simulate a lower or higher distance from the BTS")
923 struct osmocom_ms *ms = vty->index;
925 ms->settings.alter_delay = 0;
930 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
931 "Stick to the given cell\nARFCN of the cell to stick to")
933 struct osmocom_ms *ms = vty->index;
935 ms->settings.stick = 1;
936 ms->settings.stick_arfcn = atoi(argv[0]);
941 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
942 NO_STR "Do not stick to any cell")
944 struct osmocom_ms *ms = vty->index;
946 ms->settings.stick = 0;
951 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
952 "Allow location updating")
954 struct osmocom_ms *ms = vty->index;
956 ms->settings.no_lupd = 0;
961 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
962 NO_STR "Do not allow location updating")
964 struct osmocom_ms *ms = vty->index;
966 ms->settings.no_lupd = 1;
971 /* per testsim config */
972 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
973 "Configure test SIM emulation")
975 vty->node = TESTSIM_NODE;
980 static int config_write_dummy(struct vty *vty)
985 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
986 "Set IMSI on test card\n15 digits IMSI")
988 struct osmocom_ms *ms = vty->index;
989 char *error = gsm_check_imsi(argv[0]);
992 vty_out(vty, "%s%s", error, VTY_NEWLINE);
996 strcpy(ms->settings.test_imsi, argv[0]);
1001 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
1002 "Allow access to barred cells")
1004 struct osmocom_ms *ms = vty->index;
1006 ms->settings.test_barr = 1;
1011 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
1012 NO_STR "Deny access to barred cells")
1014 struct osmocom_ms *ms = vty->index;
1016 ms->settings.test_barr = 0;
1021 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
1022 NO_STR "Unset Registered PLMN")
1024 struct osmocom_ms *ms = vty->index;
1026 ms->settings.test_rplmn_valid = 0;
1031 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
1032 "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
1034 struct osmocom_ms *ms = vty->index;
1035 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
1036 mnc = gsm_input_mnc((char *)argv[1]);
1039 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
1043 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
1046 ms->settings.test_rplmn_valid = 1;
1047 ms->settings.test_rplmn_mcc = mcc;
1048 ms->settings.test_rplmn_mnc = mnc;
1053 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
1054 "Set Home PLMN search mode\n"
1055 "Search for HPLMN when on any other network\n"
1056 "Search for HPLMN when in a different country")
1058 struct osmocom_ms *ms = vty->index;
1060 switch (argv[0][0]) {
1062 ms->settings.test_always = 1;
1065 ms->settings.test_always = 0;
1072 enum node_type ms_vty_go_parent(struct vty *vty)
1074 switch (vty->node) {
1076 vty->node = CONFIG_NODE;
1080 vty->node = MS_NODE;
1083 vty->node = CONFIG_NODE;
1089 /* Down vty node level. */
1090 gDEFUN(ournode_exit,
1091 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
1093 switch (vty->node) {
1095 vty->node = CONFIG_NODE;
1099 vty->node = MS_NODE;
1107 /* End of configuration. */
1109 ournode_end_cmd, "end", "End current mode and change to enable mode.")
1111 switch (vty->node) {
1114 /* Nothing to do. */
1120 vty_config_unlock(vty);
1121 vty->node = ENABLE_NODE;
1123 vty->index_sub = NULL;
1131 int ms_vty_init(void)
1133 install_element_ve(&show_ms_cmd);
1134 install_element_ve(&show_subscr_cmd);
1135 install_element_ve(&show_support_cmd);
1136 install_element_ve(&show_states_cmd);
1137 install_element_ve(&show_cell_cmd);
1138 install_element_ve(&show_cell_si_cmd);
1139 install_element_ve(&show_ba_cmd);
1140 install_element_ve(&show_forb_la_cmd);
1141 install_element_ve(&show_forb_plmn_cmd);
1142 install_element_ve(&monitor_network_cmd);
1143 install_element_ve(&no_monitor_network_cmd);
1145 install_element(ENABLE_NODE, &sim_test_cmd);
1146 install_element(ENABLE_NODE, &sim_remove_cmd);
1147 install_element(ENABLE_NODE, &network_search_cmd);
1148 install_element(ENABLE_NODE, &network_show_cmd);
1149 install_element(ENABLE_NODE, &network_select_cmd);
1150 install_element(ENABLE_NODE, &call_cmd);
1151 install_element(ENABLE_NODE, &call_retr_cmd);
1153 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
1154 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
1155 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
1156 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
1158 install_element(CONFIG_NODE, &cfg_ms_cmd);
1159 install_element(CONFIG_NODE, &ournode_end_cmd);
1160 install_node(&ms_node, config_write_ms);
1161 install_default(MS_NODE);
1162 install_element(MS_NODE, &ournode_exit_cmd);
1163 install_element(MS_NODE, &ournode_end_cmd);
1164 install_element(MS_NODE, &cfg_ms_sim_cmd);
1165 install_element(MS_NODE, &cfg_ms_mode_cmd);
1166 install_element(MS_NODE, &cfg_ms_imei_cmd);
1167 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
1168 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
1169 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
1170 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
1171 install_element(MS_NODE, &cfg_ms_cw_cmd);
1172 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
1173 install_element(MS_NODE, &cfg_ms_clip_cmd);
1174 install_element(MS_NODE, &cfg_ms_clir_cmd);
1175 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
1176 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
1177 install_element(MS_NODE, &cfg_ms_testsim_cmd);
1178 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
1179 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
1180 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
1181 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
1182 install_element(MS_NODE, &cfg_ms_stick_cmd);
1183 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
1184 install_element(MS_NODE, &cfg_ms_lupd_cmd);
1185 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
1187 install_node(&testsim_node, config_write_dummy);
1188 install_default(TESTSIM_NODE);
1189 install_element(TESTSIM_NODE, &ournode_exit_cmd);
1190 install_element(TESTSIM_NODE, &ournode_end_cmd);
1191 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
1192 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
1193 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
1194 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
1195 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
1196 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
1201 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
1203 struct telnet_connection *connection;
1209 va_start(args, fmt);
1210 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
1211 buffer[sizeof(buffer) - 1] = '\0';
1218 llist_for_each_entry(connection, &active_connections, entry) {
1219 vty = connection->vty;
1223 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
1227 if (buffer[strlen(buffer) - 1] == '\n') {
1228 buffer[strlen(buffer) - 1] = '\0';
1229 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
1230 buffer[strlen(buffer)] = '\n';
1232 vty_out(vty, "%% %s", buffer);