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/utils.h>
29 #include <osmocore/gsm48.h>
31 #include <osmocom/bb/common/osmocom_data.h>
32 #include <osmocom/bb/common/networks.h>
33 #include <osmocom/bb/mobile/mncc.h>
34 #include <osmocom/bb/mobile/transaction.h>
35 #include <osmocom/bb/mobile/vty.h>
36 #include <osmocom/bb/mobile/gps.h>
37 #include <osmocom/vty/telnet_interface.h>
39 int mncc_call(struct osmocom_ms *ms, char *number);
40 int mncc_hangup(struct osmocom_ms *ms);
41 int mncc_answer(struct osmocom_ms *ms);
42 int mncc_hold(struct osmocom_ms *ms);
43 int mncc_retrieve(struct osmocom_ms *ms, int number);
45 extern struct llist_head ms_list;
46 extern struct llist_head active_connections;
48 struct cmd_node ms_node = {
54 struct cmd_node testsim_node = {
60 static void print_vty(void *priv, const char *fmt, ...)
63 struct vty *vty = priv;
67 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
68 buffer[sizeof(buffer) - 1] = '\0';
72 if (buffer[strlen(buffer) - 1] == '\n') {
73 buffer[strlen(buffer) - 1] = '\0';
74 vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
76 vty_out(vty, "%s", buffer);
82 static void vty_restart(struct vty *vty)
86 vty_out(vty, "You must restart for change take effect!%s", VTY_NEWLINE);
89 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
91 struct osmocom_ms *ms;
93 llist_for_each_entry(ms, &ms_list, entity) {
94 if (!strcmp(ms->name, name))
97 vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
102 DEFUN(show_ms, show_ms_cmd, "show ms",
103 SHOW_STR "Display available MS entities\n")
105 struct osmocom_ms *ms;
107 llist_for_each_entry(ms, &ms_list, entity) {
108 struct gsm_settings *set = &ms->settings;
110 vty_out(vty, "MS NAME: %s%s", ms->name, VTY_NEWLINE);
111 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
112 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
113 if (set->imei_random)
114 vty_out(vty, " IMEI generation: random (%d trailing "
115 "digits)%s", set->imei_random, VTY_NEWLINE);
117 vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
118 vty_out(vty, " network selection mode: %s%s",
119 (set->plmn_mode == PLMN_MODE_AUTO)
120 ? "automatic" : "manual", VTY_NEWLINE);
126 DEFUN(show_support, show_support_cmd, "show support [ms_name]",
127 SHOW_STR "Display information about MS support\n"
128 "Name of MS (see \"show ms\")")
130 struct osmocom_ms *ms;
133 ms = get_ms(argv[0], vty);
136 gsm_support_dump(&ms->support, print_vty, vty);
138 llist_for_each_entry(ms, &ms_list, entity) {
139 gsm_support_dump(&ms->support, print_vty, vty);
140 vty_out(vty, "%s", VTY_NEWLINE);
147 static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
149 struct gsm_trans *trans;
151 vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
152 if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
153 vty_out(vty, " automatic network selection: %s%s",
154 plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
156 vty_out(vty, " manual network selection: %s%s",
157 plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
158 vty_out(vty, " cell selection: %s%s",
159 cs_state_names[ms->cellsel.state], VTY_NEWLINE);
160 vty_out(vty, " radio ressource layer: %s%s",
161 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
162 vty_out(vty, " mobility management layer: %s",
163 gsm48_mm_state_names[ms->mmlayer.state]);
164 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
166 gsm48_mm_substate_names[ms->mmlayer.substate]);
167 vty_out(vty, "%s", VTY_NEWLINE);
168 llist_for_each_entry(trans, &ms->trans_list, entry) {
169 vty_out(vty, " call control: %s%s",
170 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
174 DEFUN(show_states, show_states_cmd, "show states [ms_name]",
175 SHOW_STR "Display current states of given MS\n"
176 "Name of MS (see \"show ms\")")
178 struct osmocom_ms *ms;
181 ms = get_ms(argv[0], vty);
184 gsm_states_dump(ms, vty);
186 llist_for_each_entry(ms, &ms_list, entity) {
187 gsm_states_dump(ms, vty);
188 vty_out(vty, "%s", VTY_NEWLINE);
195 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
196 SHOW_STR "Display information about subscriber\n"
197 "Name of MS (see \"show ms\")")
199 struct osmocom_ms *ms;
202 ms = get_ms(argv[0], vty);
205 gsm_subscr_dump(&ms->subscr, print_vty, vty);
207 llist_for_each_entry(ms, &ms_list, entity) {
208 gsm_subscr_dump(&ms->subscr, print_vty, vty);
209 vty_out(vty, "%s", VTY_NEWLINE);
216 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
217 SHOW_STR "Display information about received cells\n"
218 "Name of MS (see \"show ms\")")
220 struct osmocom_ms *ms;
222 ms = get_ms(argv[0], vty);
226 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
232 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
233 SHOW_STR "Display information about received cell\n"
234 "Name of MS (see \"show ms\")\nRadio frequency number")
236 struct osmocom_ms *ms;
238 struct gsm48_sysinfo *s;
240 ms = get_ms(argv[0], vty);
245 if (i < 0 || i > 1023) {
246 vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
247 argv[1], VTY_NEWLINE);
250 s = ms->cellsel.list[i].sysinfo;
252 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
253 argv[1], VTY_NEWLINE);
257 gsm48_sysinfo_dump(s, i, print_vty, vty);
262 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [mcc] [mnc]",
263 SHOW_STR "Display information about band allocations\n"
264 "Name of MS (see \"show ms\")\nMobile Country Code\n"
265 "Mobile Network Code")
267 struct osmocom_ms *ms;
268 uint16_t mcc = 0, mnc = 0;
270 ms = get_ms(argv[0], vty);
275 mcc = gsm_input_mcc((char *)argv[1]);
276 mnc = gsm_input_mnc((char *)argv[2]);
278 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
282 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
287 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
292 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
293 SHOW_STR "Display information about forbidden cells / networks\n"
294 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
296 struct osmocom_ms *ms;
298 ms = get_ms(argv[0], vty);
302 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
307 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
308 SHOW_STR "Display information about forbidden cells / networks\n"
309 "Display forbidden location areas\nName of MS (see \"show ms\")")
311 struct osmocom_ms *ms;
313 ms = get_ms(argv[0], vty);
317 gsm322_dump_forbidden_la(ms, print_vty, vty);
322 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
323 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
325 struct osmocom_ms *ms;
327 ms = get_ms(argv[0], vty);
331 gsm48_rr_start_monitor(ms);
336 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
337 NO_STR "Monitor...\nDeactivate monitor of network information\n"
338 "Name of MS (see \"show ms\")")
340 struct osmocom_ms *ms;
342 ms = get_ms(argv[0], vty);
346 gsm48_rr_stop_monitor(ms);
351 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [mcc] [mnc]",
352 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
353 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN")
355 struct osmocom_ms *ms;
356 uint16_t mcc = 0x001, mnc = 0x01f;
358 ms = get_ms(argv[0], vty);
362 if (ms->subscr.sim_valid) {
363 vty_out(vty, "SIM already presend, remove first!%s",
369 mcc = gsm_input_mcc((char *)argv[1]);
370 mnc = gsm_input_mnc((char *)argv[2]);
372 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
376 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
381 gsm_subscr_testcard(ms, mcc, mnc);
386 DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
387 "SIM actions\nSelect SIM from reader\nName of MS (see \"show ms\")")
389 struct osmocom_ms *ms;
391 ms = get_ms(argv[0], vty);
395 if (ms->subscr.sim_valid) {
396 vty_out(vty, "SIM already presend, remove first!%s",
401 gsm_subscr_simcard(ms);
406 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
407 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
409 struct osmocom_ms *ms;
411 ms = get_ms(argv[0], vty);
415 if (!ms->subscr.sim_valid) {
416 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
420 gsm_subscr_remove(ms);
425 DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
426 "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
429 struct osmocom_ms *ms;
431 ms = get_ms(argv[0], vty);
435 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
436 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
440 if (!ms->subscr.sim_pin_required) {
441 vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
445 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
450 DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
451 "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
454 struct osmocom_ms *ms;
456 ms = get_ms(argv[0], vty);
460 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
461 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
465 gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
470 DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
471 "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
474 struct osmocom_ms *ms;
476 ms = get_ms(argv[0], vty);
480 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
481 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
485 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
490 DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
491 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
492 "Old PIN number\nNew PIN number")
494 struct osmocom_ms *ms;
496 ms = get_ms(argv[0], vty);
500 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
501 vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
504 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
505 vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
509 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
514 DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
515 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
516 "Personal Unblock Key\nNew PIN number")
518 struct osmocom_ms *ms;
520 ms = get_ms(argv[0], vty);
524 if (strlen(argv[1]) != 8) {
525 vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
528 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
529 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
533 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
538 DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
539 "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
540 "Mobile Country Code\nMobile Network Code\nLocation Area Code "
541 " (use 0000 to remove LAI)")
543 struct osmocom_ms *ms;
544 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
545 mnc = gsm_input_mnc((char *)argv[2]),
546 lac = strtoul(argv[3], NULL, 16);
548 ms = get_ms(argv[0], vty);
553 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
557 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
561 ms->subscr.mcc = mcc;
562 ms->subscr.mnc = mnc;
563 ms->subscr.lac = lac;
564 ms->subscr.tmsi = 0xffffffff;
566 gsm_subscr_write_loci(ms);
571 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
572 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
573 "Mobile Country Code\nMobile Network Code")
575 struct osmocom_ms *ms;
576 struct gsm322_plmn *plmn;
578 struct gsm322_msg *ngm;
579 struct gsm322_plmn_list *temp;
580 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
581 mnc = gsm_input_mnc((char *)argv[2]);
584 ms = get_ms(argv[0], vty);
590 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
594 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
598 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
599 if (temp->mcc == mcc && temp->mnc == mnc)
602 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
606 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
609 ngm = (struct gsm322_msg *) nmsg->data;
612 gsm322_plmn_sendmsg(ms, nmsg);
617 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
618 "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
619 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
620 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
621 "Hold current active call\n")
623 struct osmocom_ms *ms;
626 ms = get_ms(argv[0], vty);
630 switch (argv[1][0]) {
635 if (argv[1][1] == 'a')
641 for (i = 0; i < strlen(argv[1]); i++) {
642 /* allow international notation with + */
643 if (i == 0 && argv[1][i] == '+')
645 if (!(argv[1][i] >= '0' && argv[1][i] <= '9')
648 && !(argv[1][i] >= 'a' && argv[1][i] <= 'c')) {
649 vty_out(vty, "Invalid digit '%c'%s", argv[1][i],
654 mncc_call(ms, (char *)argv[1]);
660 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [number]",
661 "Make a call\nName of MS (see \"show ms\")\n"
662 "Retrieve call on hold\nNumber of call to retrieve")
664 struct osmocom_ms *ms;
666 ms = get_ms(argv[0], vty);
670 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
675 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
676 "Network ...\nShow results of network search (again)\n"
677 "Name of MS (see \"show ms\")")
679 struct osmocom_ms *ms;
680 struct gsm322_plmn *plmn;
681 struct gsm322_plmn_list *temp;
683 ms = get_ms(argv[0], vty);
688 if (ms->settings.plmn_mode != PLMN_MODE_AUTO
689 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
690 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
694 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
695 vty_out(vty, " Network %s, %s (%s, %s)%s",
696 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
697 gsm_get_mcc(temp->mcc),
698 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
703 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
704 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
706 struct osmocom_ms *ms;
709 ms = get_ms(argv[0], vty);
713 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
716 gsm322_plmn_sendmsg(ms, nmsg);
721 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
726 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
734 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
735 NO_STR "Disable GPS receiver")
744 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
745 "GPS receiver\nSelect serial device\n"
746 "Full path of serial device including /dev/")
748 strncpy(gps.device, argv[0], sizeof(gps.device));
749 gps.device[sizeof(gps.device) - 1] = '\0';
753 vty_out(vty, "Failed to open GPS device!%s",
762 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
763 "(default|4800|""9600|19200|38400|57600|115200)",
764 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
766 if (argv[0][0] == 'd')
769 gps.baud = atoi(argv[0]);
774 vty_out(vty, "Failed to open GPS device!%s",
784 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
785 "Select a mobile station to configure\nName of MS (see \"show ms\")")
787 struct osmocom_ms *ms;
789 ms = get_ms(argv[0], vty);
799 static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
801 struct gsm_support *sup = &ms->support;
802 struct gsm_settings *set = &ms->settings;
804 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
805 switch(set->sim_type) {
806 case GSM_SIM_TYPE_NONE:
807 vty_out(vty, " sim none%s", VTY_NEWLINE);
809 case GSM_SIM_TYPE_READER:
810 vty_out(vty, " sim reader%s", VTY_NEWLINE);
812 case GSM_SIM_TYPE_TEST:
813 vty_out(vty, " sim test%s", VTY_NEWLINE);
816 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
817 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
818 vty_out(vty, " imei %s %s%s", set->imei,
819 set->imeisv + strlen(set->imei), VTY_NEWLINE);
820 if (set->imei_random)
821 vty_out(vty, " imei-random %d%s", set->imei_random,
824 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
825 if (set->emergency_imsi[0])
826 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
829 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
830 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
831 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
832 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
833 vty_out(vty, " test-sim%s", VTY_NEWLINE);
834 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
835 switch (set->test_ki_type) {
836 case GSM_SIM_KEY_XOR:
837 vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
840 case GSM_SIM_KEY_COMP128:
841 vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
845 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
847 if (set->test_rplmn_valid)
848 vty_out(vty, " rplmn %s %s%s",
849 gsm_print_mcc(set->test_rplmn_mcc),
850 gsm_print_mnc(set->test_rplmn_mnc),
853 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
854 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
855 : "foreign-country", VTY_NEWLINE);
856 vty_out(vty, " exit%s", VTY_NEWLINE);
857 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
858 if (set->alter_tx_power)
859 if (set->alter_tx_power_value)
860 vty_out(vty, " tx-power %d%s",
861 set->alter_tx_power_value, VTY_NEWLINE);
863 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
865 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
866 if (set->alter_delay)
867 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
870 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
872 vty_out(vty, " stick %d%s", set->stick_arfcn,
875 vty_out(vty, " no stick%s", VTY_NEWLINE);
877 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
879 vty_out(vty, " location-updating%s", VTY_NEWLINE);
880 if (sup->full_v1 || sup->full_v2 || sup->full_v3) {
881 /* mandatory anyway */
882 vty_out(vty, " codec full-speed%s%s",
883 (!set->half_prefer) ? " prefer" : "",
886 if (sup->half_v1 || sup->half_v3) {
888 vty_out(vty, " codec half-speed%s%s",
889 (set->half_prefer) ? " prefer" : "",
892 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
894 vty_out(vty, "exit%s", VTY_NEWLINE);
895 vty_out(vty, "!%s", VTY_NEWLINE);
898 static int config_write_ms(struct vty *vty)
900 struct osmocom_ms *ms;
902 vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
904 vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
906 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
907 vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
908 vty_out(vty, "!%s", VTY_NEWLINE);
910 llist_for_each_entry(ms, &ms_list, entity)
911 config_write_ms_single(vty, ms);
916 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
917 "Set SIM card type when powering on\nNo SIM interted\n"
918 "Use SIM from reader\nTest SIM inserted")
920 struct osmocom_ms *ms = vty->index;
922 switch (argv[0][0]) {
924 ms->settings.sim_type = GSM_SIM_TYPE_NONE;
927 ms->settings.sim_type = GSM_SIM_TYPE_READER;
930 ms->settings.sim_type = GSM_SIM_TYPE_TEST;
933 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
941 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
942 "Set network selection mode\nAutomatic network selection\n"
943 "Manual network selection")
945 struct osmocom_ms *ms = vty->index;
948 if (!ms->plmn.state) {
949 if (argv[0][0] == 'a')
950 ms->settings.plmn_mode = PLMN_MODE_AUTO;
952 ms->settings.plmn_mode = PLMN_MODE_MANUAL;
956 if (argv[0][0] == 'a')
957 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
959 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
962 gsm322_plmn_sendmsg(ms, nmsg);
967 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
968 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
969 "Software version digit")
971 struct osmocom_ms *ms = vty->index;
972 char *error, *sv = "0";
975 sv = (char *)argv[1];
977 error = gsm_check_imei(argv[0], sv);
979 vty_out(vty, "%s%s", error, VTY_NEWLINE);
983 strcpy(ms->settings.imei, argv[0]);
984 strcpy(ms->settings.imeisv, argv[0]);
985 strcpy(ms->settings.imeisv + 15, sv);
990 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
991 "Use fixed IMEI on every power on")
993 struct osmocom_ms *ms = vty->index;
995 ms->settings.imei_random = 0;
1001 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1002 "Use random IMEI on every power on\n"
1003 "Number of trailing digits to randomize")
1005 struct osmocom_ms *ms = vty->index;
1007 ms->settings.imei_random = atoi(argv[0]);
1013 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1014 "Use special IMSI for emergency calls\n15 digits IMSI")
1016 struct osmocom_ms *ms = vty->index;
1019 error = gsm_check_imsi(argv[0]);
1021 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1024 strcpy(ms->settings.emergency_imsi, argv[0]);
1029 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1030 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1032 struct osmocom_ms *ms = vty->index;
1034 ms->settings.emergency_imsi[0] = '\0';
1039 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1040 NO_STR "Disallow waiting calls")
1042 struct osmocom_ms *ms = vty->index;
1044 ms->settings.cw = 0;
1049 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1050 "Allow waiting calls")
1052 struct osmocom_ms *ms = vty->index;
1054 ms->settings.cw = 1;
1059 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1060 "Force caller ID presentation")
1062 struct osmocom_ms *ms = vty->index;
1064 ms->settings.clip = 1;
1065 ms->settings.clir = 0;
1070 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1071 "Force caller ID restriction")
1073 struct osmocom_ms *ms = vty->index;
1075 ms->settings.clip = 0;
1076 ms->settings.clir = 1;
1081 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1082 NO_STR "Disable forcing of caller ID presentation")
1084 struct osmocom_ms *ms = vty->index;
1086 ms->settings.clip = 0;
1091 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1092 NO_STR "Disable forcing of caller ID restriction")
1094 struct osmocom_ms *ms = vty->index;
1096 ms->settings.clir = 0;
1101 DEFUN(cfg_ms_min_rxlev, cfg_ms_min_rxlev_cmd, "min-rxlev <-110--47>",
1102 "Set the minimum receive level to select a cell\n"
1103 "Minimum receive level from -110 dBm to -47 dBm")
1105 struct osmocom_ms *ms = vty->index;
1107 ms->settings.min_rxlev_db = atoi(argv[0]);
1112 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1113 "Set the way to choose transmit power\nControlled by BTS\n"
1114 "Always full power\nFixed GSM power value if supported")
1116 struct osmocom_ms *ms = vty->index;
1118 switch (argv[0][0]) {
1120 ms->settings.alter_tx_power = 0;
1123 ms->settings.alter_tx_power = 1;
1124 ms->settings.alter_tx_power_value = 0;
1131 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1132 "Set the way to choose transmit power\n"
1133 "Fixed GSM power value if supported")
1135 struct osmocom_ms *ms = vty->index;
1137 ms->settings.alter_tx_power = 1;
1138 ms->settings.alter_tx_power_value = atoi(argv[0]);
1143 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1144 "Simulate a lower or higher distance from the BTS\n"
1145 "Delay in half bits (distance in 553.85 meter steps)")
1147 struct osmocom_ms *ms = vty->index;
1149 ms->settings.alter_delay = atoi(argv[0]);
1150 gsm48_rr_alter_delay(ms);
1155 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1156 NO_STR "Do not simulate a lower or higher distance from the BTS")
1158 struct osmocom_ms *ms = vty->index;
1160 ms->settings.alter_delay = 0;
1161 gsm48_rr_alter_delay(ms);
1166 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1167 "Stick to the given cell\nARFCN of the cell to stick to")
1169 struct osmocom_ms *ms = vty->index;
1171 ms->settings.stick = 1;
1172 ms->settings.stick_arfcn = atoi(argv[0]);
1177 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1178 NO_STR "Do not stick to any cell")
1180 struct osmocom_ms *ms = vty->index;
1182 ms->settings.stick = 0;
1187 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1188 "Allow location updating")
1190 struct osmocom_ms *ms = vty->index;
1192 ms->settings.no_lupd = 0;
1197 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1198 NO_STR "Do not allow location updating")
1200 struct osmocom_ms *ms = vty->index;
1202 ms->settings.no_lupd = 1;
1207 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1208 "Enable codec\nFull speed speech codec")
1210 struct osmocom_ms *ms = vty->index;
1211 struct gsm_support *sup = &ms->support;
1213 if (!sup->full_v1 && !sup->full_v2 && !sup->full_v3) {
1214 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1221 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1223 "Enable codec\nFull speed speech codec\nPrefer this codec")
1225 struct osmocom_ms *ms = vty->index;
1226 struct gsm_support *sup = &ms->support;
1228 if (!sup->full_v1 && !sup->full_v2 && !sup->full_v3) {
1229 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1233 ms->settings.half_prefer = 0;
1238 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1239 "Enable codec\nHalf speed speech codec")
1241 struct osmocom_ms *ms = vty->index;
1242 struct gsm_support *sup = &ms->support;
1244 if (!sup->half_v1 && !sup->half_v3) {
1245 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1249 ms->settings.half = 1;
1254 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1256 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1258 struct osmocom_ms *ms = vty->index;
1259 struct gsm_support *sup = &ms->support;
1261 if (!sup->half_v1 && !sup->half_v3) {
1262 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1266 ms->settings.half = 1;
1267 ms->settings.half_prefer = 1;
1272 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1273 NO_STR "Disable codec\nHalf speed speech codec")
1275 struct osmocom_ms *ms = vty->index;
1276 struct gsm_support *sup = &ms->support;
1278 if (!sup->half_v1 && !sup->half_v3) {
1279 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1283 ms->settings.half = 0;
1284 ms->settings.half_prefer = 0;
1289 /* per testsim config */
1290 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1291 "Configure test SIM emulation")
1293 vty->node = TESTSIM_NODE;
1298 static int config_write_dummy(struct vty *vty)
1303 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1304 "Set IMSI on test card\n15 digits IMSI")
1306 struct osmocom_ms *ms = vty->index;
1307 char *error = gsm_check_imsi(argv[0]);
1310 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1314 strcpy(ms->settings.test_imsi, argv[0]);
1320 #define HEX_STR "\nByte as two digits hexadecimal"
1321 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1322 "HEX HEX HEX HEX HEX HEX",
1323 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1324 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
1326 struct osmocom_ms *ms = vty->index;
1327 struct gsm_settings *set = &ms->settings;
1332 for (i = 0; i < 12; i++) {
1334 if (!strncmp(p, "0x", 2))
1336 if (strlen(p) != 2) {
1337 vty_out(vty, "Expecting two digits hex value (with or "
1338 "without 0x in front)%s", VTY_NEWLINE);
1341 ki[i] = strtoul(p, NULL, 16);
1344 set->test_ki_type = GSM_SIM_KEY_XOR;
1345 memcpy(set->test_ki, ki, 12);
1349 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
1350 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
1351 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1352 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
1353 HEX_STR HEX_STR HEX_STR HEX_STR)
1355 struct osmocom_ms *ms = vty->index;
1356 struct gsm_settings *set = &ms->settings;
1361 for (i = 0; i < 16; i++) {
1363 if (!strncmp(p, "0x", 2))
1365 if (strlen(p) != 2) {
1366 vty_out(vty, "Expecting two digits hex value (with or "
1367 "without 0x in front)%s", VTY_NEWLINE);
1370 ki[i] = strtoul(p, NULL, 16);
1373 set->test_ki_type = GSM_SIM_KEY_COMP128;
1374 memcpy(set->test_ki, ki, 16);
1378 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
1379 "Allow access to barred cells")
1381 struct osmocom_ms *ms = vty->index;
1383 ms->settings.test_barr = 1;
1388 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
1389 NO_STR "Deny access to barred cells")
1391 struct osmocom_ms *ms = vty->index;
1393 ms->settings.test_barr = 0;
1398 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
1399 NO_STR "Unset Registered PLMN")
1401 struct osmocom_ms *ms = vty->index;
1403 ms->settings.test_rplmn_valid = 0;
1409 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
1410 "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
1412 struct osmocom_ms *ms = vty->index;
1413 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
1414 mnc = gsm_input_mnc((char *)argv[1]);
1417 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
1421 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
1424 ms->settings.test_rplmn_valid = 1;
1425 ms->settings.test_rplmn_mcc = mcc;
1426 ms->settings.test_rplmn_mnc = mnc;
1432 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
1433 "Set Home PLMN search mode\n"
1434 "Search for HPLMN when on any other network\n"
1435 "Search for HPLMN when in a different country")
1437 struct osmocom_ms *ms = vty->index;
1439 switch (argv[0][0]) {
1441 ms->settings.test_always = 1;
1444 ms->settings.test_always = 0;
1452 enum node_type ms_vty_go_parent(struct vty *vty)
1454 switch (vty->node) {
1456 vty->node = CONFIG_NODE;
1460 vty->node = MS_NODE;
1463 vty->node = CONFIG_NODE;
1469 /* Down vty node level. */
1470 gDEFUN(ournode_exit,
1471 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
1473 switch (vty->node) {
1475 vty->node = CONFIG_NODE;
1479 vty->node = MS_NODE;
1487 /* End of configuration. */
1489 ournode_end_cmd, "end", "End current mode and change to enable mode.")
1491 switch (vty->node) {
1494 /* Nothing to do. */
1500 vty_config_unlock(vty);
1501 vty->node = ENABLE_NODE;
1503 vty->index_sub = NULL;
1511 int ms_vty_init(void)
1513 install_element_ve(&show_ms_cmd);
1514 install_element_ve(&show_subscr_cmd);
1515 install_element_ve(&show_support_cmd);
1516 install_element_ve(&show_states_cmd);
1517 install_element_ve(&show_cell_cmd);
1518 install_element_ve(&show_cell_si_cmd);
1519 install_element_ve(&show_ba_cmd);
1520 install_element_ve(&show_forb_la_cmd);
1521 install_element_ve(&show_forb_plmn_cmd);
1522 install_element_ve(&monitor_network_cmd);
1523 install_element_ve(&no_monitor_network_cmd);
1525 install_element(ENABLE_NODE, &sim_test_cmd);
1526 install_element(ENABLE_NODE, &sim_reader_cmd);
1527 install_element(ENABLE_NODE, &sim_remove_cmd);
1528 install_element(ENABLE_NODE, &sim_pin_cmd);
1529 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
1530 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
1531 install_element(ENABLE_NODE, &sim_change_pin_cmd);
1532 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
1533 install_element(ENABLE_NODE, &sim_lai_cmd);
1534 install_element(ENABLE_NODE, &network_search_cmd);
1535 install_element(ENABLE_NODE, &network_show_cmd);
1536 install_element(ENABLE_NODE, &network_select_cmd);
1537 install_element(ENABLE_NODE, &call_cmd);
1538 install_element(ENABLE_NODE, &call_retr_cmd);
1540 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
1541 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
1542 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
1543 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
1545 install_element(CONFIG_NODE, &cfg_ms_cmd);
1546 install_element(CONFIG_NODE, &ournode_end_cmd);
1547 install_node(&ms_node, config_write_ms);
1548 install_default(MS_NODE);
1549 install_element(MS_NODE, &ournode_exit_cmd);
1550 install_element(MS_NODE, &ournode_end_cmd);
1551 install_element(MS_NODE, &cfg_ms_sim_cmd);
1552 install_element(MS_NODE, &cfg_ms_mode_cmd);
1553 install_element(MS_NODE, &cfg_ms_imei_cmd);
1554 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
1555 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
1556 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
1557 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
1558 install_element(MS_NODE, &cfg_ms_cw_cmd);
1559 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
1560 install_element(MS_NODE, &cfg_ms_clip_cmd);
1561 install_element(MS_NODE, &cfg_ms_clir_cmd);
1562 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
1563 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
1564 install_element(MS_NODE, &cfg_ms_testsim_cmd);
1565 install_element(MS_NODE, &cfg_ms_min_rxlev_cmd);
1566 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
1567 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
1568 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
1569 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
1570 install_element(MS_NODE, &cfg_ms_stick_cmd);
1571 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
1572 install_element(MS_NODE, &cfg_ms_lupd_cmd);
1573 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
1574 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
1575 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
1576 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
1577 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
1578 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
1579 install_node(&testsim_node, config_write_dummy);
1580 install_default(TESTSIM_NODE);
1581 install_element(TESTSIM_NODE, &ournode_exit_cmd);
1582 install_element(TESTSIM_NODE, &ournode_end_cmd);
1583 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
1584 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
1585 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
1586 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
1587 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
1588 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
1589 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
1590 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
1595 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
1597 struct telnet_connection *connection;
1603 va_start(args, fmt);
1604 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
1605 buffer[sizeof(buffer) - 1] = '\0';
1612 llist_for_each_entry(connection, &active_connections, entry) {
1613 vty = connection->vty;
1617 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
1621 if (buffer[strlen(buffer) - 1] == '\n') {
1622 buffer[strlen(buffer) - 1] = '\0';
1623 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
1624 buffer[strlen(buffer)] = '\n';
1626 vty_out(vty, "%% %s", buffer);