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/core/utils.h>
29 #include <osmocom/gsm/gsm48.h>
30 #include <osmocom/core/talloc.h>
31 #include <osmocom/core/signal.h>
33 #include <osmocom/bb/common/osmocom_data.h>
34 #include <osmocom/bb/common/networks.h>
35 #include <osmocom/bb/common/gps.h>
36 #include <osmocom/bb/mobile/mncc.h>
37 #include <osmocom/bb/mobile/transaction.h>
38 #include <osmocom/bb/mobile/vty.h>
39 #include <osmocom/bb/mobile/app_mobile.h>
40 #include <osmocom/vty/telnet_interface.h>
44 int mncc_call(struct osmocom_ms *ms, char *number);
45 int mncc_hangup(struct osmocom_ms *ms);
46 int mncc_answer(struct osmocom_ms *ms);
47 int mncc_hold(struct osmocom_ms *ms);
48 int mncc_retrieve(struct osmocom_ms *ms, int number);
49 int mncc_dtmf(struct osmocom_ms *ms, char *dtmf);
51 extern struct llist_head ms_list;
52 extern struct llist_head active_connections;
54 struct cmd_node ms_node = {
60 struct cmd_node testsim_node = {
66 struct cmd_node support_node = {
72 static void print_vty(void *priv, const char *fmt, ...)
75 struct vty *vty = priv;
79 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
80 buffer[sizeof(buffer) - 1] = '\0';
84 if (buffer[strlen(buffer) - 1] == '\n') {
85 buffer[strlen(buffer) - 1] = '\0';
86 vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
88 vty_out(vty, "%s", buffer);
92 int vty_check_number(struct vty *vty, const char *number)
96 for (i = 0; i < strlen(number); i++) {
97 /* allow international notation with + */
98 if (i == 0 && number[i] == '+')
100 if (!(number[i] >= '0' && number[i] <= '9')
103 && !(number[i] >= 'a' && number[i] <= 'c')) {
104 vty_out(vty, "Invalid digit '%c' of number!%s",
105 number[i], VTY_NEWLINE);
109 if (number[0] == '\0' || (number[0] == '+' && number[1] == '\0')) {
110 vty_out(vty, "Given number has no digits!%s", VTY_NEWLINE);
119 static void vty_restart(struct vty *vty, struct osmocom_ms *ms)
123 if (ms->shutdown != 0)
125 vty_out(vty, "You must restart MS '%s' ('shutdown / no shutdown') for "
126 "change to take effect!%s", ms->name, VTY_NEWLINE);
129 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
131 struct osmocom_ms *ms;
133 llist_for_each_entry(ms, &ms_list, entity) {
134 if (!strcmp(ms->name, name)) {
136 vty_out(vty, "MS '%s' is admin down.%s", name,
143 vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
148 static void gsm_ms_dump(struct osmocom_ms *ms, struct vty *vty)
150 struct gsm_settings *set = &ms->settings;
151 struct gsm_trans *trans;
155 service = ", radio is not started";
156 else if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE) {
157 /* current MM idle state */
158 switch (ms->mmlayer.substate) {
159 case GSM48_MM_SST_NORMAL_SERVICE:
160 case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
161 service = ", service is normal";
163 case GSM48_MM_SST_LOC_UPD_NEEDED:
164 case GSM48_MM_SST_ATTEMPT_UPDATE:
165 service = ", service is limited (pending)";
167 case GSM48_MM_SST_NO_CELL_AVAIL:
168 service = ", service is unavailable";
171 if (ms->subscr.sim_valid)
172 service = ", service is limited";
174 service = ", service is limited "
179 service = ", MM connection active";
181 vty_out(vty, "MS '%s' is %s%s%s%s", ms->name,
182 (ms->shutdown) ? "administratively " : "",
183 (ms->shutdown || !ms->started) ? "down" : "up",
184 (!ms->shutdown) ? service : "",
186 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
187 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
188 if (set->imei_random)
189 vty_out(vty, " IMEI generation: random (%d trailing "
190 "digits)%s", set->imei_random, VTY_NEWLINE);
192 vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
197 if (set->plmn_mode == PLMN_MODE_AUTO)
198 vty_out(vty, " automatic network selection state: %s%s",
199 plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
201 vty_out(vty, " manual network selection state: %s%s",
202 plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
203 vty_out(vty, " cell selection state: %s",
204 cs_state_names[ms->cellsel.state]);
205 if (ms->rrlayer.state == GSM48_RR_ST_IDLE && ms->cellsel.selected)
206 vty_out(vty, " (ARFCN %s)",
207 gsm_print_arfcn(ms->cellsel.sel_arfcn));
208 vty_out(vty, "%s", VTY_NEWLINE);
209 vty_out(vty, " radio ressource layer state: %s%s",
210 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
211 vty_out(vty, " mobility management layer state: %s",
212 gsm48_mm_state_names[ms->mmlayer.state]);
213 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
215 gsm48_mm_substate_names[ms->mmlayer.substate]);
216 vty_out(vty, "%s", VTY_NEWLINE);
217 llist_for_each_entry(trans, &ms->trans_list, entry) {
218 vty_out(vty, " call control state: %s%s",
219 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
224 DEFUN(show_ms, show_ms_cmd, "show ms [MS_NAME]",
225 SHOW_STR "Display available MS entities\n")
227 struct osmocom_ms *ms;
230 llist_for_each_entry(ms, &ms_list, entity) {
231 if (!strcmp(ms->name, argv[0])) {
232 gsm_ms_dump(ms, vty);
236 vty_out(vty, "MS name '%s' does not exits.%s", argv[0],
240 llist_for_each_entry(ms, &ms_list, entity) {
241 gsm_ms_dump(ms, vty);
242 vty_out(vty, "%s", VTY_NEWLINE);
249 DEFUN(show_support, show_support_cmd, "show support [MS_NAME]",
250 SHOW_STR "Display information about MS support\n"
251 "Name of MS (see \"show ms\")")
253 struct osmocom_ms *ms;
256 ms = get_ms(argv[0], vty);
259 gsm_support_dump(ms, print_vty, vty);
261 llist_for_each_entry(ms, &ms_list, entity) {
262 gsm_support_dump(ms, print_vty, vty);
263 vty_out(vty, "%s", VTY_NEWLINE);
270 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [MS_NAME]",
271 SHOW_STR "Display information about subscriber\n"
272 "Name of MS (see \"show ms\")")
274 struct osmocom_ms *ms;
277 ms = get_ms(argv[0], vty);
280 gsm_subscr_dump(&ms->subscr, print_vty, vty);
282 llist_for_each_entry(ms, &ms_list, entity) {
284 gsm_subscr_dump(&ms->subscr, print_vty, vty);
285 vty_out(vty, "%s", VTY_NEWLINE);
293 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
294 SHOW_STR "Display information about received cells\n"
295 "Name of MS (see \"show ms\")")
297 struct osmocom_ms *ms;
299 ms = get_ms(argv[0], vty);
303 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
309 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
310 SHOW_STR "Display information about received cell\n"
311 "Name of MS (see \"show ms\")\nRadio frequency number\n"
312 "Given frequency is PCS band (1900) rather than DCS band.")
314 struct osmocom_ms *ms;
315 struct gsm48_sysinfo *s;
316 uint16_t arfcn = atoi(argv[1]);
318 ms = get_ms(argv[0], vty);
323 if (arfcn < 512 || arfcn > 810) {
324 vty_out(vty, "Given ARFCN not in PCS band%s",
331 s = ms->cellsel.list[arfcn2index(arfcn)].sysinfo;
333 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
334 argv[1], VTY_NEWLINE);
338 gsm48_sysinfo_dump(s, arfcn, print_vty, vty, ms->settings.freq_map);
343 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [MCC] [MNC]",
344 SHOW_STR "Display information about band allocations\n"
345 "Name of MS (see \"show ms\")\nMobile Country Code\n"
346 "Mobile Network Code")
348 struct osmocom_ms *ms;
349 uint16_t mcc = 0, mnc = 0;
351 ms = get_ms(argv[0], vty);
356 mcc = gsm_input_mcc((char *)argv[1]);
357 mnc = gsm_input_mnc((char *)argv[2]);
359 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
363 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
368 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
373 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
374 SHOW_STR "Display information about forbidden cells / networks\n"
375 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
377 struct osmocom_ms *ms;
379 ms = get_ms(argv[0], vty);
383 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
388 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
389 SHOW_STR "Display information about forbidden cells / networks\n"
390 "Display forbidden location areas\nName of MS (see \"show ms\")")
392 struct osmocom_ms *ms;
394 ms = get_ms(argv[0], vty);
398 gsm322_dump_forbidden_la(ms, print_vty, vty);
403 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
404 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
406 struct osmocom_ms *ms;
408 ms = get_ms(argv[0], vty);
412 gsm48_rr_start_monitor(ms);
417 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
418 NO_STR "Monitor...\nDeactivate monitor of network information\n"
419 "Name of MS (see \"show ms\")")
421 struct osmocom_ms *ms;
423 ms = get_ms(argv[0], vty);
427 gsm48_rr_stop_monitor(ms);
432 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [MCC] [MNC] [LAC] [TMSI]",
433 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
434 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN\n"
435 "Optionally locatio area code\nOptionally current assigned TMSI")
437 struct osmocom_ms *ms;
438 uint16_t mcc = 0x001, mnc = 0x01f, lac = 0x0000;
439 uint32_t tmsi = 0xffffffff;
441 ms = get_ms(argv[0], vty);
445 if (ms->subscr.sim_valid) {
446 vty_out(vty, "SIM already presend, remove first!%s",
452 mcc = gsm_input_mcc((char *)argv[1]);
453 mnc = gsm_input_mnc((char *)argv[2]);
455 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
459 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
465 lac = strtoul(argv[3], NULL, 16);
468 tmsi = strtoul(argv[4], NULL, 16);
470 gsm_subscr_testcard(ms, mcc, mnc, lac, tmsi);
475 DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
476 "SIM actions\nSelect SIM from reader\nName of MS (see \"show ms\")")
478 struct osmocom_ms *ms;
480 ms = get_ms(argv[0], vty);
484 if (ms->subscr.sim_valid) {
485 vty_out(vty, "SIM already presend, remove first!%s",
490 gsm_subscr_simcard(ms);
495 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
496 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
498 struct osmocom_ms *ms;
500 ms = get_ms(argv[0], vty);
504 if (!ms->subscr.sim_valid) {
505 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
509 gsm_subscr_remove(ms);
514 DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
515 "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
518 struct osmocom_ms *ms;
520 ms = get_ms(argv[0], vty);
524 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
525 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
529 if (!ms->subscr.sim_pin_required) {
530 vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
534 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
539 DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
540 "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
543 struct osmocom_ms *ms;
545 ms = get_ms(argv[0], vty);
549 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
550 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
554 gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
559 DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
560 "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
563 struct osmocom_ms *ms;
565 ms = get_ms(argv[0], vty);
569 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
570 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
574 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
579 DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
580 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
581 "Old PIN number\nNew PIN number")
583 struct osmocom_ms *ms;
585 ms = get_ms(argv[0], vty);
589 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
590 vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
593 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
594 vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
598 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
603 DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
604 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
605 "Personal Unblock Key\nNew PIN number")
607 struct osmocom_ms *ms;
609 ms = get_ms(argv[0], vty);
613 if (strlen(argv[1]) != 8) {
614 vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
617 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
618 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
622 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
627 DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
628 "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
629 "Mobile Country Code\nMobile Network Code\nLocation Area Code "
630 " (use 0000 to remove LAI)")
632 struct osmocom_ms *ms;
633 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
634 mnc = gsm_input_mnc((char *)argv[2]),
635 lac = strtoul(argv[3], NULL, 16);
637 ms = get_ms(argv[0], vty);
642 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
646 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
650 ms->subscr.mcc = mcc;
651 ms->subscr.mnc = mnc;
652 ms->subscr.lac = lac;
653 ms->subscr.tmsi = 0xffffffff;
655 gsm_subscr_write_loci(ms);
660 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
661 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
662 "Mobile Country Code\nMobile Network Code")
664 struct osmocom_ms *ms;
665 struct gsm322_plmn *plmn;
667 struct gsm322_msg *ngm;
668 struct gsm322_plmn_list *temp;
669 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
670 mnc = gsm_input_mnc((char *)argv[2]);
673 ms = get_ms(argv[0], vty);
679 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
683 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
687 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
688 if (temp->mcc == mcc && temp->mnc == mnc)
691 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
695 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
698 ngm = (struct gsm322_msg *) nmsg->data;
701 gsm322_plmn_sendmsg(ms, nmsg);
706 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
707 "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
708 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
709 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
710 "Hold current active call\n")
712 struct osmocom_ms *ms;
713 struct gsm_settings *set;
714 struct gsm_settings_abbrev *abbrev;
717 ms = get_ms(argv[0], vty);
722 if (set->ch_cap == GSM_CAP_SDCCH) {
723 vty_out(vty, "Basic call is not supported for SDCCH only "
724 "mobile%s", VTY_NEWLINE);
728 number = (char *)argv[1];
729 if (!strcmp(number, "emergency"))
730 mncc_call(ms, number);
731 else if (!strcmp(number, "answer"))
733 else if (!strcmp(number, "hangup"))
735 else if (!strcmp(number, "hold"))
738 llist_for_each_entry(abbrev, &set->abbrev, list) {
739 if (!strcmp(number, abbrev->abbrev)) {
740 number = abbrev->number;
741 vty_out(vty, "Dialing number '%s'%s", number,
746 if (vty_check_number(vty, number))
748 mncc_call(ms, number);
754 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [NUMBER]",
755 "Make a call\nName of MS (see \"show ms\")\n"
756 "Retrieve call on hold\nNumber of call to retrieve")
758 struct osmocom_ms *ms;
760 ms = get_ms(argv[0], vty);
764 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
769 DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
770 "Make a call\nName of MS (see \"show ms\")\n"
771 "One or more DTMF digits to transmit")
773 struct osmocom_ms *ms;
774 struct gsm_settings *set;
776 ms = get_ms(argv[0], vty);
782 vty_out(vty, "DTMF not supported, please enable!%s",
787 mncc_dtmf(ms, (char *)argv[1]);
792 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
793 "Network ...\nShow results of network search (again)\n"
794 "Name of MS (see \"show ms\")")
796 struct osmocom_ms *ms;
797 struct gsm_settings *set;
798 struct gsm322_plmn *plmn;
799 struct gsm322_plmn_list *temp;
801 ms = get_ms(argv[0], vty);
807 if (set->plmn_mode != PLMN_MODE_AUTO
808 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
809 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
813 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
814 vty_out(vty, " Network %s, %s (%s, %s)%s",
815 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
816 gsm_get_mcc(temp->mcc),
817 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
822 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
823 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
825 struct osmocom_ms *ms;
828 ms = get_ms(argv[0], vty);
832 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
835 gsm322_plmn_sendmsg(ms, nmsg);
840 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
843 if (osmo_gps_open()) {
845 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
853 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
854 NO_STR "Disable GPS receiver")
864 DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",
865 "GPS receiver\nSelect gpsd host and port\n"
866 "IP and port (optional) of the host running gpsd")
868 char* colon = strstr(argv[0], ":");
870 memcpy(g.gpsd_host, argv[0], colon - argv[0] - 1);
871 g.gpsd_host[colon - argv[0]] = '\0';
872 memcpy(g.gpsd_port, colon, strlen(colon));
873 g.gpsd_port[strlen(colon)] = '\0';
875 snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", argv[0]);
876 g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
877 snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "2947");
878 g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
880 g.gps_type = GPS_TYPE_GPSD;
883 if (osmo_gps_open()) {
884 vty_out(vty, "Failed to connect to gpsd host!%s",
894 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
895 "GPS receiver\nSelect serial device\n"
896 "Full path of serial device including /dev/")
898 strncpy(g.device, argv[0], sizeof(g.device));
899 g.device[sizeof(g.device) - 1] = '\0';
900 g.gps_type = GPS_TYPE_SERIAL;
903 if (osmo_gps_open()) {
904 vty_out(vty, "Failed to open GPS device!%s",
913 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
914 "(default|4800|""9600|19200|38400|57600|115200)",
915 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
917 if (argv[0][0] == 'd')
920 g.baud = atoi(argv[0]);
923 if (osmo_gps_open()) {
925 vty_out(vty, "Failed to open GPS device!%s",
935 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
936 "Select a mobile station to configure\nName of MS (see \"show ms\")")
938 struct osmocom_ms *ms;
941 llist_for_each_entry(ms, &ms_list, entity) {
942 if (!strcmp(ms->name, argv[0])) {
950 vty_out(vty, "MS name '%s' does not exits, try "
951 "'ms %s create'%s", argv[0], argv[0],
955 ms = mobile_new((char *)argv[0]);
957 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
969 DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
970 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
971 "Create if MS does not exists")
973 struct osmocom_ms *ms;
976 llist_for_each_entry(ms, &ms_list, entity) {
977 if (!strcmp(ms->name, argv[0])) {
984 ms = mobile_new((char *)argv[0]);
986 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
995 vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
996 argv[0], VTY_NEWLINE);
1000 DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
1001 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
1002 "Rename MS\nNew name of MS")
1004 struct osmocom_ms *ms;
1007 llist_for_each_entry(ms, &ms_list, entity) {
1008 if (!strcmp(ms->name, argv[0])) {
1015 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1020 strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
1025 DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
1026 NO_STR "Select a mobile station to remove\n"
1027 "Name of MS (see \"show ms\")")
1029 struct osmocom_ms *ms;
1032 llist_for_each_entry(ms, &ms_list, entity) {
1033 if (!strcmp(ms->name, argv[0])) {
1040 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1045 mobile_delete(ms, 1);
1050 #define SUP_WRITE(item, cmd) \
1052 vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
1055 static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
1057 struct gsm_settings *set = &ms->settings;
1058 struct gsm_support *sup = &ms->support;
1059 struct gsm_settings_abbrev *abbrev;
1061 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
1062 vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
1064 vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
1065 switch(set->sim_type) {
1066 case GSM_SIM_TYPE_NONE:
1067 vty_out(vty, " sim none%s", VTY_NEWLINE);
1069 case GSM_SIM_TYPE_READER:
1070 vty_out(vty, " sim reader%s", VTY_NEWLINE);
1072 case GSM_SIM_TYPE_TEST:
1073 vty_out(vty, " sim test%s", VTY_NEWLINE);
1076 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
1077 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
1078 vty_out(vty, " imei %s %s%s", set->imei,
1079 set->imeisv + strlen(set->imei), VTY_NEWLINE);
1080 if (set->imei_random)
1081 vty_out(vty, " imei-random %d%s", set->imei_random,
1084 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
1085 if (set->emergency_imsi[0])
1086 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
1089 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
1090 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
1091 vty_out(vty, " %sauto-answer%s", (set->auto_answer) ? "" : "no ",
1093 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
1094 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
1095 if (set->alter_tx_power)
1096 if (set->alter_tx_power_value)
1097 vty_out(vty, " tx-power %d%s",
1098 set->alter_tx_power_value, VTY_NEWLINE);
1100 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
1102 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
1103 if (set->alter_delay)
1104 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
1107 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
1109 vty_out(vty, " stick %d%s%s", set->stick_arfcn & 1023,
1110 (set->stick_arfcn & ARFCN_PCS) ? " pcs" : "",
1113 vty_out(vty, " no stick%s", VTY_NEWLINE);
1115 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
1117 vty_out(vty, " location-updating%s", VTY_NEWLINE);
1118 if (set->full_v1 || set->full_v2 || set->full_v3) {
1119 /* mandatory anyway */
1120 vty_out(vty, " codec full-speed%s%s",
1121 (!set->half_prefer) ? " prefer" : "",
1124 if (set->half_v1 || set->half_v3) {
1126 vty_out(vty, " codec half-speed%s%s",
1127 (set->half_prefer) ? " prefer" : "",
1130 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
1132 if (llist_empty(&set->abbrev))
1133 vty_out(vty, " no abbrev%s", VTY_NEWLINE);
1135 llist_for_each_entry(abbrev, &set->abbrev, list)
1136 vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
1137 abbrev->number, (abbrev->name[0]) ? " " : "",
1138 abbrev->name, VTY_NEWLINE);
1140 vty_out(vty, " support%s", VTY_NEWLINE);
1141 SUP_WRITE(sms_ptp, "sms");
1142 SUP_WRITE(a5_1, "a5/1");
1143 SUP_WRITE(a5_2, "a5/2");
1144 SUP_WRITE(a5_3, "a5/3");
1145 SUP_WRITE(a5_4, "a5/4");
1146 SUP_WRITE(a5_5, "a5/5");
1147 SUP_WRITE(a5_6, "a5/6");
1148 SUP_WRITE(a5_7, "a5/7");
1149 SUP_WRITE(p_gsm, "p-gsm");
1150 SUP_WRITE(e_gsm, "e-gsm");
1151 SUP_WRITE(r_gsm, "r-gsm");
1152 SUP_WRITE(pcs, "gsm-850");
1153 SUP_WRITE(gsm_480, "gsm-480");
1154 SUP_WRITE(gsm_450, "gsm-450");
1155 SUP_WRITE(dcs, "dcs");
1156 SUP_WRITE(pcs, "pcs");
1157 if (sup->r_gsm || sup->e_gsm || sup->p_gsm)
1158 vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
1160 vty_out(vty, " class-850 %d%s", set->class_850, VTY_NEWLINE);
1161 if (sup->gsm_480 || sup->gsm_450)
1162 vty_out(vty, " class-400 %d%s", set->class_400, VTY_NEWLINE);
1164 vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
1166 vty_out(vty, " class-pcs %d%s", set->class_pcs, VTY_NEWLINE);
1167 switch (set->ch_cap) {
1169 vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
1171 case GSM_CAP_SDCCH_TCHF:
1172 vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
1174 case GSM_CAP_SDCCH_TCHF_TCHH:
1175 vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
1179 SUP_WRITE(full_v1, "full-speech-v1");
1180 SUP_WRITE(full_v2, "full-speech-v2");
1181 SUP_WRITE(full_v3, "full-speech-v3");
1182 SUP_WRITE(half_v1, "half-speech-v1");
1183 SUP_WRITE(half_v3, "half-speech-v3");
1184 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
1185 vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
1186 vty_out(vty, " exit%s", VTY_NEWLINE);
1187 vty_out(vty, " test-sim%s", VTY_NEWLINE);
1188 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
1189 switch (set->test_ki_type) {
1190 case GSM_SIM_KEY_XOR:
1191 vty_out(vty, " ki xor %s%s", osmo_hexdump(set->test_ki, 12),
1194 case GSM_SIM_KEY_COMP128:
1195 vty_out(vty, " ki comp128 %s%s", osmo_hexdump(set->test_ki, 16),
1199 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
1201 if (set->test_rplmn_valid) {
1202 vty_out(vty, " rplmn %s %s",
1203 gsm_print_mcc(set->test_rplmn_mcc),
1204 gsm_print_mnc(set->test_rplmn_mnc));
1205 if (set->test_lac > 0x0000 && set->test_lac < 0xfffe)
1206 vty_out(vty, " 0x%04x", set->test_lac);
1207 if (set->test_tmsi != 0xffffffff)
1208 vty_out(vty, " 0x%08x", set->test_tmsi);
1209 vty_out(vty, "%s", VTY_NEWLINE);
1211 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
1212 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
1213 : "foreign-country", VTY_NEWLINE);
1214 vty_out(vty, " exit%s", VTY_NEWLINE);
1215 vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
1217 vty_out(vty, "exit%s", VTY_NEWLINE);
1218 vty_out(vty, "!%s", VTY_NEWLINE);
1221 static int config_write(struct vty *vty)
1223 struct osmocom_ms *ms;
1226 vty_out(vty, "gpsd host %s%s", g.gpsd_host, VTY_NEWLINE);
1227 vty_out(vty, "gpsd port %s%s", g.gpsd_port, VTY_NEWLINE);
1229 vty_out(vty, "gps device %s%s", g.device, VTY_NEWLINE);
1231 vty_out(vty, "gps baudrate %d%s", g.baud, VTY_NEWLINE);
1233 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
1234 vty_out(vty, "%sgps enable%s", (g.enable) ? "" : "no ", VTY_NEWLINE);
1235 vty_out(vty, "!%s", VTY_NEWLINE);
1237 llist_for_each_entry(ms, &ms_list, entity)
1238 config_write_ms(vty, ms);
1243 DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
1244 SHOW_STR "Show config of this MS")
1246 struct osmocom_ms *ms = vty->index;
1248 config_write_ms(vty, ms);
1253 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1254 "Define socket path to connect between layer 2 and layer 1\n"
1255 "Unix socket, default '/tmp/osmocom_l2'")
1257 struct osmocom_ms *ms = vty->index;
1258 struct gsm_settings *set = &ms->settings;
1260 strncpy(set->layer2_socket_path, argv[0],
1261 sizeof(set->layer2_socket_path) - 1);
1263 vty_restart(vty, ms);
1267 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1268 "Define socket path to connect to SIM reader\n"
1269 "Unix socket, default '/tmp/osmocom_sap'")
1271 struct osmocom_ms *ms = vty->index;
1272 struct gsm_settings *set = &ms->settings;
1274 strncpy(set->sap_socket_path, argv[0],
1275 sizeof(set->sap_socket_path) - 1);
1277 vty_restart(vty, ms);
1281 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1282 "Set SIM card type when powering on\nNo SIM interted\n"
1283 "Use SIM from reader\nTest SIM inserted")
1285 struct osmocom_ms *ms = vty->index;
1286 struct gsm_settings *set = &ms->settings;
1288 switch (argv[0][0]) {
1290 set->sim_type = GSM_SIM_TYPE_NONE;
1293 set->sim_type = GSM_SIM_TYPE_READER;
1296 set->sim_type = GSM_SIM_TYPE_TEST;
1299 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1303 vty_restart(vty, ms);
1307 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1308 "Set network selection mode\nAutomatic network selection\n"
1309 "Manual network selection")
1311 struct osmocom_ms *ms = vty->index;
1312 struct gsm_settings *set = &ms->settings;
1315 if (!ms->plmn.state) {
1316 if (argv[0][0] == 'a')
1317 set->plmn_mode = PLMN_MODE_AUTO;
1319 set->plmn_mode = PLMN_MODE_MANUAL;
1323 if (argv[0][0] == 'a')
1324 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1326 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1329 gsm322_plmn_sendmsg(ms, nmsg);
1334 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1335 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1336 "Software version digit")
1338 struct osmocom_ms *ms = vty->index;
1339 struct gsm_settings *set = &ms->settings;
1340 char *error, *sv = "0";
1343 sv = (char *)argv[1];
1345 error = gsm_check_imei(argv[0], sv);
1347 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1351 strcpy(set->imei, argv[0]);
1352 strcpy(set->imeisv, argv[0]);
1353 strcpy(set->imeisv + 15, sv);
1358 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1359 "Use fixed IMEI on every power on")
1361 struct osmocom_ms *ms = vty->index;
1362 struct gsm_settings *set = &ms->settings;
1364 set->imei_random = 0;
1366 vty_restart(vty, ms);
1370 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1371 "Use random IMEI on every power on\n"
1372 "Number of trailing digits to randomize")
1374 struct osmocom_ms *ms = vty->index;
1375 struct gsm_settings *set = &ms->settings;
1377 set->imei_random = atoi(argv[0]);
1379 vty_restart(vty, ms);
1383 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1384 "Use special IMSI for emergency calls\n15 digits IMSI")
1386 struct osmocom_ms *ms = vty->index;
1387 struct gsm_settings *set = &ms->settings;
1390 error = gsm_check_imsi(argv[0]);
1392 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1395 strcpy(set->emergency_imsi, argv[0]);
1400 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1401 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1403 struct osmocom_ms *ms = vty->index;
1404 struct gsm_settings *set = &ms->settings;
1406 set->emergency_imsi[0] = '\0';
1411 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1412 NO_STR "Disallow waiting calls")
1414 struct osmocom_ms *ms = vty->index;
1415 struct gsm_settings *set = &ms->settings;
1422 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1423 "Allow waiting calls")
1425 struct osmocom_ms *ms = vty->index;
1426 struct gsm_settings *set = &ms->settings;
1433 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1434 NO_STR "Disable auto-answering calls")
1436 struct osmocom_ms *ms = vty->index;
1437 struct gsm_settings *set = &ms->settings;
1439 set->auto_answer = 0;
1444 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1445 "Enable auto-answering calls")
1447 struct osmocom_ms *ms = vty->index;
1448 struct gsm_settings *set = &ms->settings;
1450 set->auto_answer = 1;
1455 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1456 "Force caller ID presentation")
1458 struct osmocom_ms *ms = vty->index;
1459 struct gsm_settings *set = &ms->settings;
1467 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1468 "Force caller ID restriction")
1470 struct osmocom_ms *ms = vty->index;
1471 struct gsm_settings *set = &ms->settings;
1479 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1480 NO_STR "Disable forcing of caller ID presentation")
1482 struct osmocom_ms *ms = vty->index;
1483 struct gsm_settings *set = &ms->settings;
1490 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1491 NO_STR "Disable forcing of caller ID restriction")
1493 struct osmocom_ms *ms = vty->index;
1494 struct gsm_settings *set = &ms->settings;
1501 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1502 "Set the way to choose transmit power\nControlled by BTS\n"
1503 "Always full power\nFixed GSM power value if supported")
1505 struct osmocom_ms *ms = vty->index;
1506 struct gsm_settings *set = &ms->settings;
1508 switch (argv[0][0]) {
1510 set->alter_tx_power = 0;
1513 set->alter_tx_power = 1;
1514 set->alter_tx_power_value = 0;
1521 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1522 "Set the way to choose transmit power\n"
1523 "Fixed GSM power value if supported")
1525 struct osmocom_ms *ms = vty->index;
1526 struct gsm_settings *set = &ms->settings;
1528 set->alter_tx_power = 1;
1529 set->alter_tx_power_value = atoi(argv[0]);
1534 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1535 "Simulate a lower or higher distance from the BTS\n"
1536 "Delay in half bits (distance in 553.85 meter steps)")
1538 struct osmocom_ms *ms = vty->index;
1539 struct gsm_settings *set = &ms->settings;
1541 set->alter_delay = atoi(argv[0]);
1542 gsm48_rr_alter_delay(ms);
1547 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1548 NO_STR "Do not simulate a lower or higher distance from the BTS")
1550 struct osmocom_ms *ms = vty->index;
1551 struct gsm_settings *set = &ms->settings;
1553 set->alter_delay = 0;
1554 gsm48_rr_alter_delay(ms);
1559 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023> [pcs]",
1560 "Stick to the given cell\nARFCN of the cell to stick to\n"
1561 "Given frequency is PCS band (1900) rather than DCS band.")
1563 struct osmocom_ms *ms = vty->index;
1564 struct gsm_settings *set = &ms->settings;
1565 uint16_t arfcn = atoi(argv[0]);
1568 if (arfcn < 512 || arfcn > 810) {
1569 vty_out(vty, "Given ARFCN not in PCS band%s",
1576 set->stick_arfcn = arfcn;
1581 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1582 NO_STR "Do not stick to any cell")
1584 struct osmocom_ms *ms = vty->index;
1585 struct gsm_settings *set = &ms->settings;
1592 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1593 "Allow location updating")
1595 struct osmocom_ms *ms = vty->index;
1596 struct gsm_settings *set = &ms->settings;
1603 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1604 NO_STR "Do not allow location updating")
1606 struct osmocom_ms *ms = vty->index;
1607 struct gsm_settings *set = &ms->settings;
1614 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1615 "Enable codec\nFull speed speech codec")
1617 struct osmocom_ms *ms = vty->index;
1618 struct gsm_settings *set = &ms->settings;
1620 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1621 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1628 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1630 "Enable codec\nFull speed speech codec\nPrefer this codec")
1632 struct osmocom_ms *ms = vty->index;
1633 struct gsm_settings *set = &ms->settings;
1635 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1636 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1640 set->half_prefer = 0;
1645 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1646 "Enable codec\nHalf speed speech codec")
1648 struct osmocom_ms *ms = vty->index;
1649 struct gsm_settings *set = &ms->settings;
1651 if (!set->half_v1 && !set->half_v3) {
1652 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1661 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1663 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1665 struct osmocom_ms *ms = vty->index;
1666 struct gsm_settings *set = &ms->settings;
1668 if (!set->half_v1 && !set->half_v3) {
1669 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1674 set->half_prefer = 1;
1679 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1680 NO_STR "Disable codec\nHalf speed speech codec")
1682 struct osmocom_ms *ms = vty->index;
1683 struct gsm_settings *set = &ms->settings;
1685 if (!set->half_v1 && !set->half_v3) {
1686 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1691 set->half_prefer = 0;
1696 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
1697 "Store given abbreviation number\n1-3 digits abbreviation\n"
1698 "Number to store for the abbreviation "
1699 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1700 "Name of the abbreviation")
1702 struct osmocom_ms *ms = vty->index;
1703 struct gsm_settings *set = &ms->settings;
1704 struct gsm_settings_abbrev *abbrev;
1707 llist_for_each_entry(abbrev, &set->abbrev, list) {
1708 if (!strcmp(argv[0], abbrev->abbrev)) {
1709 vty_out(vty, "Given abbreviation '%s' already stored, "
1710 "delete first!%s", argv[0], VTY_NEWLINE);
1715 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1716 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1720 for (i = 0; i < strlen(argv[0]); i++) {
1721 if (argv[0][i] < '0' || argv[0][i] > '9') {
1722 vty_out(vty, "Given abbreviation must have digits "
1723 "0..9 only!%s", VTY_NEWLINE);
1728 if (vty_check_number(vty, argv[1]))
1731 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1733 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1736 llist_add_tail(&abbrev->list, &set->abbrev);
1737 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1738 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1740 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1745 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
1746 NO_STR "Remove given abbreviation number or all numbers\n"
1747 "Abbreviation number to remove")
1749 struct osmocom_ms *ms = vty->index;
1750 struct gsm_settings *set = &ms->settings;
1751 struct gsm_settings_abbrev *abbrev, *abbrev2;
1752 uint8_t deleted = 0;
1754 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1755 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1756 llist_del(&abbrev->list);
1761 if (argc >= 1 && !deleted) {
1762 vty_out(vty, "Given abbreviation '%s' not found!%s",
1763 argv[0], VTY_NEWLINE);
1770 static int config_write_dummy(struct vty *vty)
1775 /* per support config */
1776 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1777 "Define supported features")
1779 vty->node = SUPPORT_NODE;
1784 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1785 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1787 struct osmocom_ms *ms = vty->index; \
1788 struct gsm_settings *set = &ms->settings; \
1789 struct gsm_support *sup = &ms->support; \
1791 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1793 return CMD_SUCCESS; \
1794 return CMD_WARNING; \
1797 vty_restart(vty, ms); \
1799 return CMD_SUCCESS; \
1802 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1803 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1805 struct osmocom_ms *ms = vty->index; \
1806 struct gsm_settings *set = &ms->settings; \
1807 struct gsm_support *sup = &ms->support; \
1809 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1811 return CMD_SUCCESS; \
1812 return CMD_WARNING; \
1815 vty_restart(vty, ms); \
1817 return CMD_SUCCESS; \
1820 #define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1821 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1823 struct osmocom_ms *ms = vty->index; \
1824 struct gsm_settings *set = &ms->settings; \
1826 vty_restart(vty, ms); \
1828 return CMD_SUCCESS; \
1831 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1832 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1834 struct osmocom_ms *ms = vty->index; \
1835 struct gsm_settings *set = &ms->settings; \
1837 vty_restart(vty, ms); \
1839 return CMD_SUCCESS; \
1842 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1843 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1844 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1845 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1846 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1847 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1848 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1849 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1850 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1851 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1852 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1853 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1854 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1855 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1856 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1857 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1858 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1859 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1860 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1862 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1864 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1866 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1868 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1870 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1872 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1873 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1874 SUP_EN(cfg_ms_sup_gsm_850, cfg_ms_sup_gsm_850_cmd, gsm_850, "gsm-850",
1876 SUP_DI(cfg_ms_sup_no_gsm_850, cfg_ms_sup_no_gsm_850_cmd, gsm_850, "gsm-850",
1878 SUP_EN(cfg_ms_sup_pcs, cfg_ms_sup_pcs_cmd, pcs, "pcs", "PCS (1900)", 0);
1879 SUP_DI(cfg_ms_sup_no_pcs, cfg_ms_sup_no_pcs_cmd, pcs, "pcs", "PCS (1900)", 0);
1880 SUP_EN(cfg_ms_sup_gsm_480, cfg_ms_sup_gsm_480_cmd, gsm_480, "gsm-480",
1882 SUP_DI(cfg_ms_sup_no_gsm_480, cfg_ms_sup_no_gsm_480_cmd, gsm_480, "gsm-480",
1884 SUP_EN(cfg_ms_sup_gsm_450, cfg_ms_sup_gsm_450_cmd, gsm_450, "gsm-450",
1886 SUP_DI(cfg_ms_sup_no_gsm_450, cfg_ms_sup_no_gsm_450_cmd, gsm_450, "gsm-450",
1889 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1890 "Select power class for GSM 900\n"
1897 struct osmocom_ms *ms = vty->index;
1898 struct gsm_settings *set = &ms->settings;
1899 struct gsm_support *sup = &ms->support;
1901 set->class_900 = atoi(argv[0]);
1903 if (set->class_900 < sup->class_900 && !vty_reading)
1904 vty_out(vty, "Note: You selected a higher class than supported "
1905 " by hardware!%s", VTY_NEWLINE);
1910 DEFUN(cfg_ms_sup_class_850, cfg_ms_sup_class_850_cmd, "class-850 (1|2|3|4|5)",
1911 "Select power class for GSM 850\n"
1918 struct osmocom_ms *ms = vty->index;
1919 struct gsm_settings *set = &ms->settings;
1920 struct gsm_support *sup = &ms->support;
1922 set->class_850 = atoi(argv[0]);
1924 if (set->class_850 < sup->class_850 && !vty_reading)
1925 vty_out(vty, "Note: You selected a higher class than supported "
1926 " by hardware!%s", VTY_NEWLINE);
1931 DEFUN(cfg_ms_sup_class_400, cfg_ms_sup_class_400_cmd, "class-400 (1|2|3|4|5)",
1932 "Select power class for GSM 400 (480 and 450)\n"
1939 struct osmocom_ms *ms = vty->index;
1940 struct gsm_settings *set = &ms->settings;
1941 struct gsm_support *sup = &ms->support;
1943 set->class_400 = atoi(argv[0]);
1945 if (set->class_400 < sup->class_400 && !vty_reading)
1946 vty_out(vty, "Note: You selected a higher class than supported "
1947 " by hardware!%s", VTY_NEWLINE);
1952 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1953 "Select power class for DCS 1800\n"
1958 struct osmocom_ms *ms = vty->index;
1959 struct gsm_settings *set = &ms->settings;
1960 struct gsm_support *sup = &ms->support;
1962 set->class_dcs = atoi(argv[0]);
1964 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1966 vty_out(vty, "Note: You selected a higher class than supported "
1967 " by hardware!%s", VTY_NEWLINE);
1972 DEFUN(cfg_ms_sup_class_pcs, cfg_ms_sup_class_pcs_cmd, "class-pcs (1|2|3)",
1973 "Select power class for PCS 1900\n"
1978 struct osmocom_ms *ms = vty->index;
1979 struct gsm_settings *set = &ms->settings;
1980 struct gsm_support *sup = &ms->support;
1982 set->class_pcs = atoi(argv[0]);
1984 if (((set->class_pcs + 1) & 3) < ((sup->class_pcs + 1) & 3)
1986 vty_out(vty, "Note: You selected a higher class than supported "
1987 " by hardware!%s", VTY_NEWLINE);
1992 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1993 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1994 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1996 struct osmocom_ms *ms = vty->index;
1997 struct gsm_settings *set = &ms->settings;
1998 struct gsm_support *sup = &ms->support;
2001 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
2002 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
2003 else if (!strcmp(argv[0], "sdcch+tchf"))
2004 ch_cap = GSM_CAP_SDCCH_TCHF;
2006 ch_cap = GSM_CAP_SDCCH;
2008 if (ch_cap > sup->ch_cap && !vty_reading) {
2009 vty_out(vty, "You selected an higher capability than supported "
2010 " by hardware!%s", VTY_NEWLINE);
2014 if (ch_cap != set->ch_cap
2015 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
2016 vty_restart(vty, ms);
2018 set->ch_cap = ch_cap;
2023 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
2024 "Full rate speech V1", 0);
2025 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
2026 "full-speech-v1", "Full rate speech V1", 0);
2027 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
2028 "Full rate speech V2 (EFR)", 0);
2029 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
2030 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
2031 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
2032 "Full rate speech V3 (AMR)", 0);
2033 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
2034 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
2035 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
2036 "Half rate speech V1", 0);
2037 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
2038 "half-speech-v1", "Half rate speech V1", 0);
2039 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
2040 "Half rate speech V3 (AMR)", 0);
2041 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
2042 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
2044 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
2045 "Set the minimum receive level to select a cell\n"
2046 "Minimum receive level from -110 dBm to -47 dBm")
2048 struct osmocom_ms *ms = vty->index;
2049 struct gsm_settings *set = &ms->settings;
2051 set->min_rxlev_db = atoi(argv[0]);
2056 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
2057 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
2058 "more reliable against bad RX signal. This increase the propability "
2059 "of missing a paging requests\n"
2060 "DSC initial and maximum value (standard is 90)")
2062 struct osmocom_ms *ms = vty->index;
2063 struct gsm_settings *set = &ms->settings;
2065 set->dsc_max = atoi(argv[0]);
2070 /* per testsim config */
2071 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
2072 "Configure test SIM emulation")
2074 vty->node = TESTSIM_NODE;
2079 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
2080 "Set IMSI on test card\n15 digits IMSI")
2082 struct osmocom_ms *ms = vty->index;
2083 struct gsm_settings *set = &ms->settings;
2084 char *error = gsm_check_imsi(argv[0]);
2087 vty_out(vty, "%s%s", error, VTY_NEWLINE);
2091 strcpy(set->test_imsi, argv[0]);
2093 vty_restart(vty, ms);
2097 #define HEX_STR "\nByte as two digits hexadecimal"
2098 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
2099 "HEX HEX HEX HEX HEX HEX",
2100 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
2101 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
2103 struct osmocom_ms *ms = vty->index;
2104 struct gsm_settings *set = &ms->settings;
2109 for (i = 0; i < 12; i++) {
2111 if (!strncmp(p, "0x", 2))
2113 if (strlen(p) != 2) {
2114 vty_out(vty, "Expecting two digits hex value (with or "
2115 "without 0x in front)%s", VTY_NEWLINE);
2118 ki[i] = strtoul(p, NULL, 16);
2121 set->test_ki_type = GSM_SIM_KEY_XOR;
2122 memcpy(set->test_ki, ki, 12);
2126 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
2127 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
2128 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
2129 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
2130 HEX_STR HEX_STR HEX_STR HEX_STR)
2132 struct osmocom_ms *ms = vty->index;
2133 struct gsm_settings *set = &ms->settings;
2138 for (i = 0; i < 16; i++) {
2140 if (!strncmp(p, "0x", 2))
2142 if (strlen(p) != 2) {
2143 vty_out(vty, "Expecting two digits hex value (with or "
2144 "without 0x in front)%s", VTY_NEWLINE);
2147 ki[i] = strtoul(p, NULL, 16);
2150 set->test_ki_type = GSM_SIM_KEY_COMP128;
2151 memcpy(set->test_ki, ki, 16);
2155 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
2156 "Allow access to barred cells")
2158 struct osmocom_ms *ms = vty->index;
2159 struct gsm_settings *set = &ms->settings;
2166 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2167 NO_STR "Deny access to barred cells")
2169 struct osmocom_ms *ms = vty->index;
2170 struct gsm_settings *set = &ms->settings;
2177 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2178 NO_STR "Unset Registered PLMN")
2180 struct osmocom_ms *ms = vty->index;
2181 struct gsm_settings *set = &ms->settings;
2183 set->test_rplmn_valid = 0;
2185 vty_restart(vty, ms);
2189 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
2190 "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
2191 "Optionally set locatio area code\n"
2192 "Optionally set current assigned TMSI")
2194 struct osmocom_ms *ms = vty->index;
2195 struct gsm_settings *set = &ms->settings;
2196 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2197 mnc = gsm_input_mnc((char *)argv[1]);
2200 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2204 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2207 set->test_rplmn_valid = 1;
2208 set->test_rplmn_mcc = mcc;
2209 set->test_rplmn_mnc = mnc;
2212 set->test_lac = strtoul(argv[2], NULL, 16);
2214 set->test_lac = 0xfffe;
2217 set->test_tmsi = strtoul(argv[3], NULL, 16);
2219 set->test_tmsi = 0xffffffff;
2221 vty_restart(vty, ms);
2225 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2226 "Set Home PLMN search mode\n"
2227 "Search for HPLMN when on any other network\n"
2228 "Search for HPLMN when in a different country")
2230 struct osmocom_ms *ms = vty->index;
2231 struct gsm_settings *set = &ms->settings;
2233 switch (argv[0][0]) {
2235 set->test_always = 1;
2238 set->test_always = 0;
2242 vty_restart(vty, ms);
2246 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2247 NO_STR "Activate and run MS")
2249 struct osmocom_ms *ms = vty->index, *tmp;
2252 if (ms->shutdown != 2)
2255 llist_for_each_entry(tmp, &ms_list, entity) {
2256 if (tmp->shutdown == 2)
2258 if (!strcmp(ms->settings.layer2_socket_path,
2259 tmp->settings.layer2_socket_path)) {
2260 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2261 "use the same layer2-socket.%sPlease shutdown "
2262 "MS '%s' first.%s", ms->name, tmp->name,
2263 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2266 if (!strcmp(ms->settings.sap_socket_path,
2267 tmp->settings.sap_socket_path)) {
2268 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2269 "use the same sap-socket.%sPlease shutdown "
2270 "MS '%s' first.%s", ms->name, tmp->name,
2271 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2276 rc = mobile_init(ms);
2278 vty_out(vty, "Connection to layer 1 failed!%s",
2286 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2287 "Shut down and deactivate MS")
2289 struct osmocom_ms *ms = vty->index;
2291 if (ms->shutdown == 0)
2297 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2298 "Shut down and deactivate MS\nDo not perform IMSI detach")
2300 struct osmocom_ms *ms = vty->index;
2302 if (ms->shutdown <= 1)
2308 enum node_type ms_vty_go_parent(struct vty *vty)
2310 switch (vty->node) {
2312 vty->node = CONFIG_NODE;
2317 vty->node = MS_NODE;
2320 vty->node = CONFIG_NODE;
2326 /* Down vty node level. */
2327 gDEFUN(ournode_exit,
2328 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2330 switch (vty->node) {
2332 vty->node = CONFIG_NODE;
2337 vty->node = MS_NODE;
2345 /* End of configuration. */
2347 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2349 switch (vty->node) {
2352 /* Nothing to do. */
2359 vty_config_unlock(vty);
2360 vty->node = ENABLE_NODE;
2362 vty->index_sub = NULL;
2370 DEFUN(off, off_cmd, "off",
2371 "Turn mobiles off (shutdown) and exit")
2373 osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2378 #define SUP_NODE(item) \
2379 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2381 int ms_vty_init(void)
2383 install_element_ve(&show_ms_cmd);
2384 install_element_ve(&show_subscr_cmd);
2385 install_element_ve(&show_support_cmd);
2386 install_element_ve(&show_cell_cmd);
2387 install_element_ve(&show_cell_si_cmd);
2388 install_element_ve(&show_ba_cmd);
2389 install_element_ve(&show_forb_la_cmd);
2390 install_element_ve(&show_forb_plmn_cmd);
2391 install_element_ve(&monitor_network_cmd);
2392 install_element_ve(&no_monitor_network_cmd);
2393 install_element(ENABLE_NODE, &off_cmd);
2395 install_element(ENABLE_NODE, &sim_test_cmd);
2396 install_element(ENABLE_NODE, &sim_reader_cmd);
2397 install_element(ENABLE_NODE, &sim_remove_cmd);
2398 install_element(ENABLE_NODE, &sim_pin_cmd);
2399 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2400 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2401 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2402 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2403 install_element(ENABLE_NODE, &sim_lai_cmd);
2404 install_element(ENABLE_NODE, &network_search_cmd);
2405 install_element(ENABLE_NODE, &network_show_cmd);
2406 install_element(ENABLE_NODE, &network_select_cmd);
2407 install_element(ENABLE_NODE, &call_cmd);
2408 install_element(ENABLE_NODE, &call_retr_cmd);
2409 install_element(ENABLE_NODE, &call_dtmf_cmd);
2412 install_element(CONFIG_NODE, &cfg_gps_host_cmd);
2414 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2415 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2416 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2417 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2419 install_element(CONFIG_NODE, &cfg_ms_cmd);
2420 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2421 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2422 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2423 install_element(CONFIG_NODE, &ournode_end_cmd);
2424 install_node(&ms_node, config_write);
2425 install_default(MS_NODE);
2426 install_element(MS_NODE, &ournode_exit_cmd);
2427 install_element(MS_NODE, &ournode_end_cmd);
2428 install_element(MS_NODE, &cfg_ms_show_this_cmd);
2429 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2430 install_element(MS_NODE, &cfg_ms_sap_cmd);
2431 install_element(MS_NODE, &cfg_ms_sim_cmd);
2432 install_element(MS_NODE, &cfg_ms_mode_cmd);
2433 install_element(MS_NODE, &cfg_ms_imei_cmd);
2434 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2435 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2436 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2437 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2438 install_element(MS_NODE, &cfg_ms_cw_cmd);
2439 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2440 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2441 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2442 install_element(MS_NODE, &cfg_ms_clip_cmd);
2443 install_element(MS_NODE, &cfg_ms_clir_cmd);
2444 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2445 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2446 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2447 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2448 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2449 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2450 install_element(MS_NODE, &cfg_ms_stick_cmd);
2451 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2452 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2453 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2454 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2455 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2456 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2457 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2458 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2459 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2460 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2461 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2462 install_element(MS_NODE, &cfg_ms_support_cmd);
2463 install_node(&support_node, config_write_dummy);
2464 install_default(SUPPORT_NODE);
2465 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2466 install_element(SUPPORT_NODE, &ournode_end_cmd);
2467 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2468 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2469 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2470 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2471 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2472 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2473 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2474 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2475 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2476 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2477 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2478 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2479 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2480 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2481 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2482 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2483 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2484 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2485 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2486 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2487 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2488 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2489 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2490 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2491 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2492 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2493 install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_850_cmd);
2494 install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_850_cmd);
2495 install_element(SUPPORT_NODE, &cfg_ms_sup_pcs_cmd);
2496 install_element(SUPPORT_NODE, &cfg_ms_sup_no_pcs_cmd);
2497 install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_480_cmd);
2498 install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_480_cmd);
2499 install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_450_cmd);
2500 install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_450_cmd);
2501 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2502 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2503 install_element(SUPPORT_NODE, &cfg_ms_sup_class_850_cmd);
2504 install_element(SUPPORT_NODE, &cfg_ms_sup_class_pcs_cmd);
2505 install_element(SUPPORT_NODE, &cfg_ms_sup_class_400_cmd);
2506 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2507 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2508 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2509 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2510 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2511 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2512 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2513 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2514 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2515 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2516 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2517 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2518 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2519 install_node(&testsim_node, config_write_dummy);
2520 install_default(TESTSIM_NODE);
2521 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2522 install_element(TESTSIM_NODE, &ournode_end_cmd);
2523 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2524 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2525 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2526 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2527 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2528 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2529 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2530 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2531 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2532 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2533 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2538 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2540 struct telnet_connection *connection;
2546 va_start(args, fmt);
2547 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2548 buffer[sizeof(buffer) - 1] = '\0';
2555 llist_for_each_entry(connection, &active_connections, entry) {
2556 vty = connection->vty;
2560 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2564 if (buffer[strlen(buffer) - 1] == '\n') {
2565 buffer[strlen(buffer) - 1] = '\0';
2566 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2567 buffer[strlen(buffer)] = '\n';
2569 vty_out(vty, "%% %s", buffer);