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>
30 #include <osmocore/talloc.h>
31 #include <osmocore/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 %d)", ms->cellsel.sel_arfcn);
207 vty_out(vty, "%s", VTY_NEWLINE);
208 vty_out(vty, " radio ressource layer state: %s%s",
209 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
210 vty_out(vty, " mobility management layer state: %s",
211 gsm48_mm_state_names[ms->mmlayer.state]);
212 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
214 gsm48_mm_substate_names[ms->mmlayer.substate]);
215 vty_out(vty, "%s", VTY_NEWLINE);
216 llist_for_each_entry(trans, &ms->trans_list, entry) {
217 vty_out(vty, " call control state: %s%s",
218 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
223 DEFUN(show_ms, show_ms_cmd, "show ms [MS_NAME]",
224 SHOW_STR "Display available MS entities\n")
226 struct osmocom_ms *ms;
229 llist_for_each_entry(ms, &ms_list, entity) {
230 if (!strcmp(ms->name, argv[0])) {
231 gsm_ms_dump(ms, vty);
235 vty_out(vty, "MS name '%s' does not exits.%s", argv[0],
239 llist_for_each_entry(ms, &ms_list, entity) {
240 gsm_ms_dump(ms, vty);
241 vty_out(vty, "%s", VTY_NEWLINE);
248 DEFUN(show_support, show_support_cmd, "show support [MS_NAME]",
249 SHOW_STR "Display information about MS support\n"
250 "Name of MS (see \"show ms\")")
252 struct osmocom_ms *ms;
255 ms = get_ms(argv[0], vty);
258 gsm_support_dump(ms, print_vty, vty);
260 llist_for_each_entry(ms, &ms_list, entity) {
261 gsm_support_dump(ms, print_vty, vty);
262 vty_out(vty, "%s", VTY_NEWLINE);
269 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [MS_NAME]",
270 SHOW_STR "Display information about subscriber\n"
271 "Name of MS (see \"show ms\")")
273 struct osmocom_ms *ms;
276 ms = get_ms(argv[0], vty);
279 gsm_subscr_dump(&ms->subscr, print_vty, vty);
281 llist_for_each_entry(ms, &ms_list, entity) {
283 gsm_subscr_dump(&ms->subscr, print_vty, vty);
284 vty_out(vty, "%s", VTY_NEWLINE);
292 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
293 SHOW_STR "Display information about received cells\n"
294 "Name of MS (see \"show ms\")")
296 struct osmocom_ms *ms;
298 ms = get_ms(argv[0], vty);
302 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
308 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
309 SHOW_STR "Display information about received cell\n"
310 "Name of MS (see \"show ms\")\nRadio frequency number")
312 struct osmocom_ms *ms;
314 struct gsm48_sysinfo *s;
316 ms = get_ms(argv[0], vty);
321 if (i < 0 || i > 1023) {
322 vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
323 argv[1], VTY_NEWLINE);
326 s = ms->cellsel.list[i].sysinfo;
328 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
329 argv[1], VTY_NEWLINE);
333 gsm48_sysinfo_dump(s, i, print_vty, vty);
338 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [MCC] [MNC]",
339 SHOW_STR "Display information about band allocations\n"
340 "Name of MS (see \"show ms\")\nMobile Country Code\n"
341 "Mobile Network Code")
343 struct osmocom_ms *ms;
344 uint16_t mcc = 0, mnc = 0;
346 ms = get_ms(argv[0], vty);
351 mcc = gsm_input_mcc((char *)argv[1]);
352 mnc = gsm_input_mnc((char *)argv[2]);
354 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
358 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
363 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
368 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
369 SHOW_STR "Display information about forbidden cells / networks\n"
370 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
372 struct osmocom_ms *ms;
374 ms = get_ms(argv[0], vty);
378 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
383 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
384 SHOW_STR "Display information about forbidden cells / networks\n"
385 "Display forbidden location areas\nName of MS (see \"show ms\")")
387 struct osmocom_ms *ms;
389 ms = get_ms(argv[0], vty);
393 gsm322_dump_forbidden_la(ms, print_vty, vty);
398 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
399 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
401 struct osmocom_ms *ms;
403 ms = get_ms(argv[0], vty);
407 gsm48_rr_start_monitor(ms);
412 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
413 NO_STR "Monitor...\nDeactivate monitor of network information\n"
414 "Name of MS (see \"show ms\")")
416 struct osmocom_ms *ms;
418 ms = get_ms(argv[0], vty);
422 gsm48_rr_stop_monitor(ms);
427 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [MCC] [MNC] [LAC] [TMSI]",
428 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
429 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN\n"
430 "Optionally locatio area code\nOptionally current assigned TMSI")
432 struct osmocom_ms *ms;
433 uint16_t mcc = 0x001, mnc = 0x01f, lac = 0x0000;
434 uint32_t tmsi = 0xffffffff;
436 ms = get_ms(argv[0], vty);
440 if (ms->subscr.sim_valid) {
441 vty_out(vty, "SIM already presend, remove first!%s",
447 mcc = gsm_input_mcc((char *)argv[1]);
448 mnc = gsm_input_mnc((char *)argv[2]);
450 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
454 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
460 lac = strtoul(argv[3], NULL, 16);
463 tmsi = strtoul(argv[4], NULL, 16);
465 gsm_subscr_testcard(ms, mcc, mnc, lac, tmsi);
470 DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
471 "SIM actions\nSelect SIM from reader\nName of MS (see \"show ms\")")
473 struct osmocom_ms *ms;
475 ms = get_ms(argv[0], vty);
479 if (ms->subscr.sim_valid) {
480 vty_out(vty, "SIM already presend, remove first!%s",
485 gsm_subscr_simcard(ms);
490 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
491 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
493 struct osmocom_ms *ms;
495 ms = get_ms(argv[0], vty);
499 if (!ms->subscr.sim_valid) {
500 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
504 gsm_subscr_remove(ms);
509 DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
510 "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
513 struct osmocom_ms *ms;
515 ms = get_ms(argv[0], vty);
519 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
520 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
524 if (!ms->subscr.sim_pin_required) {
525 vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
529 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
534 DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
535 "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
538 struct osmocom_ms *ms;
540 ms = get_ms(argv[0], vty);
544 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
545 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
549 gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
554 DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
555 "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
558 struct osmocom_ms *ms;
560 ms = get_ms(argv[0], vty);
564 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
565 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
569 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
574 DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
575 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
576 "Old PIN number\nNew PIN number")
578 struct osmocom_ms *ms;
580 ms = get_ms(argv[0], vty);
584 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
585 vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
588 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
589 vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
593 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
598 DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
599 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
600 "Personal Unblock Key\nNew PIN number")
602 struct osmocom_ms *ms;
604 ms = get_ms(argv[0], vty);
608 if (strlen(argv[1]) != 8) {
609 vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
612 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
613 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
617 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
622 DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
623 "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
624 "Mobile Country Code\nMobile Network Code\nLocation Area Code "
625 " (use 0000 to remove LAI)")
627 struct osmocom_ms *ms;
628 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
629 mnc = gsm_input_mnc((char *)argv[2]),
630 lac = strtoul(argv[3], NULL, 16);
632 ms = get_ms(argv[0], vty);
637 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
641 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
645 ms->subscr.mcc = mcc;
646 ms->subscr.mnc = mnc;
647 ms->subscr.lac = lac;
648 ms->subscr.tmsi = 0xffffffff;
650 gsm_subscr_write_loci(ms);
655 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
656 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
657 "Mobile Country Code\nMobile Network Code")
659 struct osmocom_ms *ms;
660 struct gsm322_plmn *plmn;
662 struct gsm322_msg *ngm;
663 struct gsm322_plmn_list *temp;
664 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
665 mnc = gsm_input_mnc((char *)argv[2]);
668 ms = get_ms(argv[0], vty);
674 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
678 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
682 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
683 if (temp->mcc == mcc && temp->mnc == mnc)
686 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
690 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
693 ngm = (struct gsm322_msg *) nmsg->data;
696 gsm322_plmn_sendmsg(ms, nmsg);
701 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
702 "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
703 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
704 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
705 "Hold current active call\n")
707 struct osmocom_ms *ms;
708 struct gsm_settings *set;
709 struct gsm_settings_abbrev *abbrev;
712 ms = get_ms(argv[0], vty);
717 if (set->ch_cap == GSM_CAP_SDCCH) {
718 vty_out(vty, "Basic call is not supported for SDCCH only "
719 "mobile%s", VTY_NEWLINE);
723 number = (char *)argv[1];
724 if (!strcmp(number, "emergency"))
725 mncc_call(ms, number);
726 else if (!strcmp(number, "answer"))
728 else if (!strcmp(number, "hangup"))
730 else if (!strcmp(number, "hold"))
733 llist_for_each_entry(abbrev, &set->abbrev, list) {
734 if (!strcmp(number, abbrev->abbrev)) {
735 number = abbrev->number;
736 vty_out(vty, "Dialing number '%s'%s", number,
741 if (vty_check_number(vty, number))
743 mncc_call(ms, number);
749 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [NUMBER]",
750 "Make a call\nName of MS (see \"show ms\")\n"
751 "Retrieve call on hold\nNumber of call to retrieve")
753 struct osmocom_ms *ms;
755 ms = get_ms(argv[0], vty);
759 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
764 DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
765 "Make a call\nName of MS (see \"show ms\")\n"
766 "One or more DTMF digits to transmit")
768 struct osmocom_ms *ms;
769 struct gsm_settings *set;
771 ms = get_ms(argv[0], vty);
777 vty_out(vty, "DTMF not supported, please enable!%s",
782 mncc_dtmf(ms, (char *)argv[1]);
787 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
788 "Network ...\nShow results of network search (again)\n"
789 "Name of MS (see \"show ms\")")
791 struct osmocom_ms *ms;
792 struct gsm_settings *set;
793 struct gsm322_plmn *plmn;
794 struct gsm322_plmn_list *temp;
796 ms = get_ms(argv[0], vty);
802 if (set->plmn_mode != PLMN_MODE_AUTO
803 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
804 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
808 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
809 vty_out(vty, " Network %s, %s (%s, %s)%s",
810 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
811 gsm_get_mcc(temp->mcc),
812 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
817 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
818 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
820 struct osmocom_ms *ms;
823 ms = get_ms(argv[0], vty);
827 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
830 gsm322_plmn_sendmsg(ms, nmsg);
835 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
838 if (osmo_gps_open()) {
840 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
848 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
849 NO_STR "Disable GPS receiver")
859 DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",
860 "GPS receiver\nSelect gpsd host and port\n"
861 "IP and port (optional) of the host running gpsd")
863 char* colon = strstr(argv[0], ":");
865 memcpy(gps.gpsd_host, argv[0], colon - argv[0] - 1);
866 gps.gpsd_host[colon - argv[0]] = '\0';
867 memcpy(gps.gpsd_port, colon, strlen(colon));
868 gps.gpsd_port[strlen(colon)] = '\0';
870 snprintf(gps.gpsd_host, ARRAY_SIZE(gps.gpsd_host), "%s", argv[0]);
871 gps.gpsd_host[ARRAY_SIZE(gps.gpsd_host) - 1] = '\0';
872 snprintf(gps.gpsd_port, ARRAY_SIZE(gps.gpsd_port), "2947");
873 gps.gpsd_port[ARRAY_SIZE(gps.gpsd_port) - 1] = '\0';
877 if (osmo_gps_open()) {
878 vty_out(vty, "Failed to connect to gpsd host!%s",
887 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
888 "GPS receiver\nSelect serial device\n"
889 "Full path of serial device including /dev/")
891 strncpy(gps.device, argv[0], sizeof(gps.device));
892 gps.device[sizeof(gps.device) - 1] = '\0';
895 if (osmo_gps_open()) {
896 vty_out(vty, "Failed to open GPS device!%s",
907 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
908 "(default|4800|""9600|19200|38400|57600|115200)",
909 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
911 if (argv[0][0] == 'd')
914 gps.baud = atoi(argv[0]);
917 if (osmo_gps_open()) {
919 vty_out(vty, "Failed to open GPS device!%s",
930 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
931 "Select a mobile station to configure\nName of MS (see \"show ms\")")
933 struct osmocom_ms *ms;
936 llist_for_each_entry(ms, &ms_list, entity) {
937 if (!strcmp(ms->name, argv[0])) {
945 vty_out(vty, "MS name '%s' does not exits, try "
946 "'ms %s create'%s", argv[0], argv[0],
950 ms = mobile_new((char *)argv[0]);
952 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
964 DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
965 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
966 "Create if MS does not exists")
968 struct osmocom_ms *ms;
971 llist_for_each_entry(ms, &ms_list, entity) {
972 if (!strcmp(ms->name, argv[0])) {
979 ms = mobile_new((char *)argv[0]);
981 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
990 vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
991 argv[0], VTY_NEWLINE);
995 DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
996 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
997 "Rename MS\nNew name of MS")
999 struct osmocom_ms *ms;
1002 llist_for_each_entry(ms, &ms_list, entity) {
1003 if (!strcmp(ms->name, argv[0])) {
1010 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1015 strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
1020 DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
1021 NO_STR "Select a mobile station to remove\n"
1022 "Name of MS (see \"show ms\")")
1024 struct osmocom_ms *ms;
1027 llist_for_each_entry(ms, &ms_list, entity) {
1028 if (!strcmp(ms->name, argv[0])) {
1035 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1040 mobile_delete(ms, 1);
1045 #define SUP_WRITE(item, cmd) \
1047 vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
1050 static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
1052 struct gsm_settings *set = &ms->settings;
1053 struct gsm_support *sup = &ms->support;
1054 struct gsm_settings_abbrev *abbrev;
1056 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
1057 vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
1059 vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
1060 switch(set->sim_type) {
1061 case GSM_SIM_TYPE_NONE:
1062 vty_out(vty, " sim none%s", VTY_NEWLINE);
1064 case GSM_SIM_TYPE_READER:
1065 vty_out(vty, " sim reader%s", VTY_NEWLINE);
1067 case GSM_SIM_TYPE_TEST:
1068 vty_out(vty, " sim test%s", VTY_NEWLINE);
1071 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
1072 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
1073 vty_out(vty, " imei %s %s%s", set->imei,
1074 set->imeisv + strlen(set->imei), VTY_NEWLINE);
1075 if (set->imei_random)
1076 vty_out(vty, " imei-random %d%s", set->imei_random,
1079 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
1080 if (set->emergency_imsi[0])
1081 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
1084 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
1085 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
1086 vty_out(vty, " %sauto-answer%s", (set->auto_answer) ? "" : "no ",
1088 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
1089 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
1090 if (set->alter_tx_power)
1091 if (set->alter_tx_power_value)
1092 vty_out(vty, " tx-power %d%s",
1093 set->alter_tx_power_value, VTY_NEWLINE);
1095 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
1097 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
1098 if (set->alter_delay)
1099 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
1102 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
1104 vty_out(vty, " stick %d%s", set->stick_arfcn,
1107 vty_out(vty, " no stick%s", VTY_NEWLINE);
1109 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
1111 vty_out(vty, " location-updating%s", VTY_NEWLINE);
1112 if (set->full_v1 || set->full_v2 || set->full_v3) {
1113 /* mandatory anyway */
1114 vty_out(vty, " codec full-speed%s%s",
1115 (!set->half_prefer) ? " prefer" : "",
1118 if (set->half_v1 || set->half_v3) {
1120 vty_out(vty, " codec half-speed%s%s",
1121 (set->half_prefer) ? " prefer" : "",
1124 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
1126 if (llist_empty(&set->abbrev))
1127 vty_out(vty, " no abbrev%s", VTY_NEWLINE);
1129 llist_for_each_entry(abbrev, &set->abbrev, list)
1130 vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
1131 abbrev->number, (abbrev->name[0]) ? " " : "",
1132 abbrev->name, VTY_NEWLINE);
1134 vty_out(vty, " support%s", VTY_NEWLINE);
1135 SUP_WRITE(sms_ptp, "sms");
1136 SUP_WRITE(a5_1, "a5/1");
1137 SUP_WRITE(a5_2, "a5/2");
1138 SUP_WRITE(a5_3, "a5/3");
1139 SUP_WRITE(a5_4, "a5/4");
1140 SUP_WRITE(a5_5, "a5/5");
1141 SUP_WRITE(a5_6, "a5/6");
1142 SUP_WRITE(a5_7, "a5/7");
1143 SUP_WRITE(p_gsm, "p-gsm");
1144 SUP_WRITE(e_gsm, "e-gsm");
1145 SUP_WRITE(r_gsm, "r-gsm");
1146 SUP_WRITE(dcs, "dcs");
1147 vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
1148 vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
1149 switch (set->ch_cap) {
1151 vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
1153 case GSM_CAP_SDCCH_TCHF:
1154 vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
1156 case GSM_CAP_SDCCH_TCHF_TCHH:
1157 vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
1161 SUP_WRITE(full_v1, "full-speech-v1");
1162 SUP_WRITE(full_v2, "full-speech-v2");
1163 SUP_WRITE(full_v3, "full-speech-v3");
1164 SUP_WRITE(half_v1, "half-speech-v1");
1165 SUP_WRITE(half_v3, "half-speech-v3");
1166 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
1167 vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
1168 vty_out(vty, " exit%s", VTY_NEWLINE);
1169 vty_out(vty, " test-sim%s", VTY_NEWLINE);
1170 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
1171 switch (set->test_ki_type) {
1172 case GSM_SIM_KEY_XOR:
1173 vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
1176 case GSM_SIM_KEY_COMP128:
1177 vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
1181 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
1183 if (set->test_rplmn_valid) {
1184 vty_out(vty, " rplmn %s %s",
1185 gsm_print_mcc(set->test_rplmn_mcc),
1186 gsm_print_mnc(set->test_rplmn_mnc));
1187 if (set->test_lac > 0x0000 && set->test_lac < 0xfffe)
1188 vty_out(vty, " 0x%04x", set->test_lac);
1189 if (set->test_tmsi != 0xffffffff)
1190 vty_out(vty, " 0x%08x", set->test_tmsi);
1191 vty_out(vty, "%s", VTY_NEWLINE);
1193 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
1194 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
1195 : "foreign-country", VTY_NEWLINE);
1196 vty_out(vty, " exit%s", VTY_NEWLINE);
1197 vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
1199 vty_out(vty, "exit%s", VTY_NEWLINE);
1200 vty_out(vty, "!%s", VTY_NEWLINE);
1203 static int config_write(struct vty *vty)
1205 struct osmocom_ms *ms;
1208 vty_out(vty, "gpsd host %s%s", gps.gpsd_host, VTY_NEWLINE);
1209 vty_out(vty, "gpsd port %s%s", gps.gpsd_port, VTY_NEWLINE);
1211 vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
1213 vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
1215 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
1217 vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
1218 vty_out(vty, "!%s", VTY_NEWLINE);
1220 llist_for_each_entry(ms, &ms_list, entity)
1221 config_write_ms(vty, ms);
1226 DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
1227 SHOW_STR "Show config of this MS")
1229 struct osmocom_ms *ms = vty->index;
1231 config_write_ms(vty, ms);
1236 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1237 "Define socket path to connect between layer 2 and layer 1\n"
1238 "Unix socket, default '/tmp/osmocom_l2'")
1240 struct osmocom_ms *ms = vty->index;
1241 struct gsm_settings *set = &ms->settings;
1243 strncpy(set->layer2_socket_path, argv[0],
1244 sizeof(set->layer2_socket_path) - 1);
1246 vty_restart(vty, ms);
1250 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1251 "Define socket path to connect to SIM reader\n"
1252 "Unix socket, default '/tmp/osmocom_sap'")
1254 struct osmocom_ms *ms = vty->index;
1255 struct gsm_settings *set = &ms->settings;
1257 strncpy(set->sap_socket_path, argv[0],
1258 sizeof(set->sap_socket_path) - 1);
1260 vty_restart(vty, ms);
1264 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1265 "Set SIM card type when powering on\nNo SIM interted\n"
1266 "Use SIM from reader\nTest SIM inserted")
1268 struct osmocom_ms *ms = vty->index;
1269 struct gsm_settings *set = &ms->settings;
1271 switch (argv[0][0]) {
1273 set->sim_type = GSM_SIM_TYPE_NONE;
1276 set->sim_type = GSM_SIM_TYPE_READER;
1279 set->sim_type = GSM_SIM_TYPE_TEST;
1282 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1286 vty_restart(vty, ms);
1290 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1291 "Set network selection mode\nAutomatic network selection\n"
1292 "Manual network selection")
1294 struct osmocom_ms *ms = vty->index;
1295 struct gsm_settings *set = &ms->settings;
1298 if (!ms->plmn.state) {
1299 if (argv[0][0] == 'a')
1300 set->plmn_mode = PLMN_MODE_AUTO;
1302 set->plmn_mode = PLMN_MODE_MANUAL;
1306 if (argv[0][0] == 'a')
1307 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1309 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1312 gsm322_plmn_sendmsg(ms, nmsg);
1317 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1318 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1319 "Software version digit")
1321 struct osmocom_ms *ms = vty->index;
1322 struct gsm_settings *set = &ms->settings;
1323 char *error, *sv = "0";
1326 sv = (char *)argv[1];
1328 error = gsm_check_imei(argv[0], sv);
1330 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1334 strcpy(set->imei, argv[0]);
1335 strcpy(set->imeisv, argv[0]);
1336 strcpy(set->imeisv + 15, sv);
1341 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1342 "Use fixed IMEI on every power on")
1344 struct osmocom_ms *ms = vty->index;
1345 struct gsm_settings *set = &ms->settings;
1347 set->imei_random = 0;
1349 vty_restart(vty, ms);
1353 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1354 "Use random IMEI on every power on\n"
1355 "Number of trailing digits to randomize")
1357 struct osmocom_ms *ms = vty->index;
1358 struct gsm_settings *set = &ms->settings;
1360 set->imei_random = atoi(argv[0]);
1362 vty_restart(vty, ms);
1366 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1367 "Use special IMSI for emergency calls\n15 digits IMSI")
1369 struct osmocom_ms *ms = vty->index;
1370 struct gsm_settings *set = &ms->settings;
1373 error = gsm_check_imsi(argv[0]);
1375 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1378 strcpy(set->emergency_imsi, argv[0]);
1383 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1384 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1386 struct osmocom_ms *ms = vty->index;
1387 struct gsm_settings *set = &ms->settings;
1389 set->emergency_imsi[0] = '\0';
1394 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1395 NO_STR "Disallow waiting calls")
1397 struct osmocom_ms *ms = vty->index;
1398 struct gsm_settings *set = &ms->settings;
1405 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1406 "Allow waiting calls")
1408 struct osmocom_ms *ms = vty->index;
1409 struct gsm_settings *set = &ms->settings;
1416 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1417 NO_STR "Disable auto-answering calls")
1419 struct osmocom_ms *ms = vty->index;
1420 struct gsm_settings *set = &ms->settings;
1422 set->auto_answer = 0;
1427 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1428 "Enable auto-answering calls")
1430 struct osmocom_ms *ms = vty->index;
1431 struct gsm_settings *set = &ms->settings;
1433 set->auto_answer = 1;
1438 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1439 "Force caller ID presentation")
1441 struct osmocom_ms *ms = vty->index;
1442 struct gsm_settings *set = &ms->settings;
1450 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1451 "Force caller ID restriction")
1453 struct osmocom_ms *ms = vty->index;
1454 struct gsm_settings *set = &ms->settings;
1462 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1463 NO_STR "Disable forcing of caller ID presentation")
1465 struct osmocom_ms *ms = vty->index;
1466 struct gsm_settings *set = &ms->settings;
1473 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1474 NO_STR "Disable forcing of caller ID restriction")
1476 struct osmocom_ms *ms = vty->index;
1477 struct gsm_settings *set = &ms->settings;
1484 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1485 "Set the way to choose transmit power\nControlled by BTS\n"
1486 "Always full power\nFixed GSM power value if supported")
1488 struct osmocom_ms *ms = vty->index;
1489 struct gsm_settings *set = &ms->settings;
1491 switch (argv[0][0]) {
1493 set->alter_tx_power = 0;
1496 set->alter_tx_power = 1;
1497 set->alter_tx_power_value = 0;
1504 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1505 "Set the way to choose transmit power\n"
1506 "Fixed GSM power value if supported")
1508 struct osmocom_ms *ms = vty->index;
1509 struct gsm_settings *set = &ms->settings;
1511 set->alter_tx_power = 1;
1512 set->alter_tx_power_value = atoi(argv[0]);
1517 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1518 "Simulate a lower or higher distance from the BTS\n"
1519 "Delay in half bits (distance in 553.85 meter steps)")
1521 struct osmocom_ms *ms = vty->index;
1522 struct gsm_settings *set = &ms->settings;
1524 set->alter_delay = atoi(argv[0]);
1525 gsm48_rr_alter_delay(ms);
1530 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1531 NO_STR "Do not simulate a lower or higher distance from the BTS")
1533 struct osmocom_ms *ms = vty->index;
1534 struct gsm_settings *set = &ms->settings;
1536 set->alter_delay = 0;
1537 gsm48_rr_alter_delay(ms);
1542 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1543 "Stick to the given cell\nARFCN of the cell to stick to")
1545 struct osmocom_ms *ms = vty->index;
1546 struct gsm_settings *set = &ms->settings;
1549 set->stick_arfcn = atoi(argv[0]);
1554 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1555 NO_STR "Do not stick to any cell")
1557 struct osmocom_ms *ms = vty->index;
1558 struct gsm_settings *set = &ms->settings;
1565 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1566 "Allow location updating")
1568 struct osmocom_ms *ms = vty->index;
1569 struct gsm_settings *set = &ms->settings;
1576 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1577 NO_STR "Do not allow location updating")
1579 struct osmocom_ms *ms = vty->index;
1580 struct gsm_settings *set = &ms->settings;
1587 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1588 "Enable codec\nFull speed speech codec")
1590 struct osmocom_ms *ms = vty->index;
1591 struct gsm_settings *set = &ms->settings;
1593 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1594 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1601 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1603 "Enable codec\nFull speed speech codec\nPrefer this codec")
1605 struct osmocom_ms *ms = vty->index;
1606 struct gsm_settings *set = &ms->settings;
1608 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1609 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1613 set->half_prefer = 0;
1618 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1619 "Enable codec\nHalf speed speech codec")
1621 struct osmocom_ms *ms = vty->index;
1622 struct gsm_settings *set = &ms->settings;
1624 if (!set->half_v1 && !set->half_v3) {
1625 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1634 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1636 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1638 struct osmocom_ms *ms = vty->index;
1639 struct gsm_settings *set = &ms->settings;
1641 if (!set->half_v1 && !set->half_v3) {
1642 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1647 set->half_prefer = 1;
1652 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1653 NO_STR "Disable codec\nHalf speed speech codec")
1655 struct osmocom_ms *ms = vty->index;
1656 struct gsm_settings *set = &ms->settings;
1658 if (!set->half_v1 && !set->half_v3) {
1659 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1664 set->half_prefer = 0;
1669 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
1670 "Store given abbreviation number\n1-3 digits abbreviation\n"
1671 "Number to store for the abbreviation "
1672 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1673 "Name of the abbreviation")
1675 struct osmocom_ms *ms = vty->index;
1676 struct gsm_settings *set = &ms->settings;
1677 struct gsm_settings_abbrev *abbrev;
1680 llist_for_each_entry(abbrev, &set->abbrev, list) {
1681 if (!strcmp(argv[0], abbrev->abbrev)) {
1682 vty_out(vty, "Given abbreviation '%s' already stored, "
1683 "delete first!%s", argv[0], VTY_NEWLINE);
1688 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1689 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1693 for (i = 0; i < strlen(argv[0]); i++) {
1694 if (argv[0][i] < '0' || argv[0][i] > '9') {
1695 vty_out(vty, "Given abbreviation must have digits "
1696 "0..9 only!%s", VTY_NEWLINE);
1701 if (vty_check_number(vty, argv[1]))
1704 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1706 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1709 llist_add_tail(&abbrev->list, &set->abbrev);
1710 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1711 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1713 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1718 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
1719 NO_STR "Remove given abbreviation number or all numbers\n"
1720 "Abbreviation number to remove")
1722 struct osmocom_ms *ms = vty->index;
1723 struct gsm_settings *set = &ms->settings;
1724 struct gsm_settings_abbrev *abbrev, *abbrev2;
1725 uint8_t deleted = 0;
1727 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1728 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1729 llist_del(&abbrev->list);
1734 if (argc >= 1 && !deleted) {
1735 vty_out(vty, "Given abbreviation '%s' not found!%s",
1736 argv[0], VTY_NEWLINE);
1743 static int config_write_dummy(struct vty *vty)
1748 /* per support config */
1749 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1750 "Define supported features")
1752 vty->node = SUPPORT_NODE;
1757 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1758 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1760 struct osmocom_ms *ms = vty->index; \
1761 struct gsm_settings *set = &ms->settings; \
1762 struct gsm_support *sup = &ms->support; \
1764 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1766 return CMD_SUCCESS; \
1767 return CMD_WARNING; \
1770 vty_restart(vty, ms); \
1772 return CMD_SUCCESS; \
1775 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1776 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1778 struct osmocom_ms *ms = vty->index; \
1779 struct gsm_settings *set = &ms->settings; \
1780 struct gsm_support *sup = &ms->support; \
1782 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1784 return CMD_SUCCESS; \
1785 return CMD_WARNING; \
1788 vty_restart(vty, ms); \
1790 return CMD_SUCCESS; \
1793 #define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1794 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1796 struct osmocom_ms *ms = vty->index; \
1797 struct gsm_settings *set = &ms->settings; \
1799 vty_restart(vty, ms); \
1801 return CMD_SUCCESS; \
1804 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1805 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1807 struct osmocom_ms *ms = vty->index; \
1808 struct gsm_settings *set = &ms->settings; \
1810 vty_restart(vty, ms); \
1812 return CMD_SUCCESS; \
1815 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1816 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1817 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1818 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1819 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1820 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1821 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1822 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1823 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1824 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1825 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1826 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1827 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1828 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1829 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1830 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1831 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1832 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1833 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1835 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1837 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1839 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1841 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1843 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1845 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1846 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1848 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1849 "Select power class for GSM 850/900\n"
1856 struct osmocom_ms *ms = vty->index;
1857 struct gsm_settings *set = &ms->settings;
1858 struct gsm_support *sup = &ms->support;
1860 set->class_900 = atoi(argv[0]);
1862 if (set->class_900 < sup->class_900 && !vty_reading)
1863 vty_out(vty, "You selected an higher class than supported "
1864 " by hardware!%s", VTY_NEWLINE);
1869 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1870 "Select power class for DCS 1800\n"
1875 struct osmocom_ms *ms = vty->index;
1876 struct gsm_settings *set = &ms->settings;
1877 struct gsm_support *sup = &ms->support;
1879 set->class_dcs = atoi(argv[0]);
1881 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1883 vty_out(vty, "You selected an higher class than supported "
1884 " by hardware!%s", VTY_NEWLINE);
1889 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1890 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1891 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1893 struct osmocom_ms *ms = vty->index;
1894 struct gsm_settings *set = &ms->settings;
1895 struct gsm_support *sup = &ms->support;
1898 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
1899 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
1900 else if (!strcmp(argv[0], "sdcch+tchf"))
1901 ch_cap = GSM_CAP_SDCCH_TCHF;
1903 ch_cap = GSM_CAP_SDCCH;
1905 if (ch_cap > sup->ch_cap && !vty_reading) {
1906 vty_out(vty, "You selected an higher capability than supported "
1907 " by hardware!%s", VTY_NEWLINE);
1911 if (ch_cap != set->ch_cap
1912 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
1913 vty_restart(vty, ms);
1915 set->ch_cap = ch_cap;
1920 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
1921 "Full rate speech V1", 0);
1922 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
1923 "full-speech-v1", "Full rate speech V1", 0);
1924 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
1925 "Full rate speech V2 (EFR)", 0);
1926 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
1927 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
1928 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
1929 "Full rate speech V3 (AMR)", 0);
1930 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
1931 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
1932 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
1933 "Half rate speech V1", 0);
1934 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
1935 "half-speech-v1", "Half rate speech V1", 0);
1936 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
1937 "Half rate speech V3 (AMR)", 0);
1938 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
1939 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
1941 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
1942 "Set the minimum receive level to select a cell\n"
1943 "Minimum receive level from -110 dBm to -47 dBm")
1945 struct osmocom_ms *ms = vty->index;
1946 struct gsm_settings *set = &ms->settings;
1948 set->min_rxlev_db = atoi(argv[0]);
1953 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
1954 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
1955 "more reliable against bad RX signal. This increase the propability "
1956 "of missing a paging requests\n"
1957 "DSC initial and maximum value (standard is 90)")
1959 struct osmocom_ms *ms = vty->index;
1960 struct gsm_settings *set = &ms->settings;
1962 set->dsc_max = atoi(argv[0]);
1967 /* per testsim config */
1968 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1969 "Configure test SIM emulation")
1971 vty->node = TESTSIM_NODE;
1976 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1977 "Set IMSI on test card\n15 digits IMSI")
1979 struct osmocom_ms *ms = vty->index;
1980 struct gsm_settings *set = &ms->settings;
1981 char *error = gsm_check_imsi(argv[0]);
1984 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1988 strcpy(set->test_imsi, argv[0]);
1990 vty_restart(vty, ms);
1994 #define HEX_STR "\nByte as two digits hexadecimal"
1995 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1996 "HEX HEX HEX HEX HEX HEX",
1997 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1998 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
2000 struct osmocom_ms *ms = vty->index;
2001 struct gsm_settings *set = &ms->settings;
2006 for (i = 0; i < 12; i++) {
2008 if (!strncmp(p, "0x", 2))
2010 if (strlen(p) != 2) {
2011 vty_out(vty, "Expecting two digits hex value (with or "
2012 "without 0x in front)%s", VTY_NEWLINE);
2015 ki[i] = strtoul(p, NULL, 16);
2018 set->test_ki_type = GSM_SIM_KEY_XOR;
2019 memcpy(set->test_ki, ki, 12);
2023 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
2024 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
2025 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
2026 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
2027 HEX_STR HEX_STR HEX_STR HEX_STR)
2029 struct osmocom_ms *ms = vty->index;
2030 struct gsm_settings *set = &ms->settings;
2035 for (i = 0; i < 16; i++) {
2037 if (!strncmp(p, "0x", 2))
2039 if (strlen(p) != 2) {
2040 vty_out(vty, "Expecting two digits hex value (with or "
2041 "without 0x in front)%s", VTY_NEWLINE);
2044 ki[i] = strtoul(p, NULL, 16);
2047 set->test_ki_type = GSM_SIM_KEY_COMP128;
2048 memcpy(set->test_ki, ki, 16);
2052 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
2053 "Allow access to barred cells")
2055 struct osmocom_ms *ms = vty->index;
2056 struct gsm_settings *set = &ms->settings;
2063 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2064 NO_STR "Deny access to barred cells")
2066 struct osmocom_ms *ms = vty->index;
2067 struct gsm_settings *set = &ms->settings;
2074 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2075 NO_STR "Unset Registered PLMN")
2077 struct osmocom_ms *ms = vty->index;
2078 struct gsm_settings *set = &ms->settings;
2080 set->test_rplmn_valid = 0;
2082 vty_restart(vty, ms);
2086 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
2087 "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
2088 "Optionally set locatio area code\n"
2089 "Optionally set current assigned TMSI")
2091 struct osmocom_ms *ms = vty->index;
2092 struct gsm_settings *set = &ms->settings;
2093 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2094 mnc = gsm_input_mnc((char *)argv[1]);
2097 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2101 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2104 set->test_rplmn_valid = 1;
2105 set->test_rplmn_mcc = mcc;
2106 set->test_rplmn_mnc = mnc;
2109 set->test_lac = strtoul(argv[2], NULL, 16);
2111 set->test_lac = 0xfffe;
2114 set->test_tmsi = strtoul(argv[3], NULL, 16);
2116 set->test_tmsi = 0xffffffff;
2118 vty_restart(vty, ms);
2122 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2123 "Set Home PLMN search mode\n"
2124 "Search for HPLMN when on any other network\n"
2125 "Search for HPLMN when in a different country")
2127 struct osmocom_ms *ms = vty->index;
2128 struct gsm_settings *set = &ms->settings;
2130 switch (argv[0][0]) {
2132 set->test_always = 1;
2135 set->test_always = 0;
2139 vty_restart(vty, ms);
2143 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2144 NO_STR "Activate and run MS")
2146 struct osmocom_ms *ms = vty->index, *tmp;
2149 if (ms->shutdown != 2)
2152 llist_for_each_entry(tmp, &ms_list, entity) {
2153 if (tmp->shutdown == 2)
2155 if (!strcmp(ms->settings.layer2_socket_path,
2156 tmp->settings.layer2_socket_path)) {
2157 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2158 "use the same layer2-socket.%sPlease shutdown "
2159 "MS '%s' first.%s", ms->name, tmp->name,
2160 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2163 if (!strcmp(ms->settings.sap_socket_path,
2164 tmp->settings.sap_socket_path)) {
2165 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2166 "use the same sap-socket.%sPlease shutdown "
2167 "MS '%s' first.%s", ms->name, tmp->name,
2168 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2173 rc = mobile_init(ms);
2175 vty_out(vty, "Connection to layer 1 failed!%s",
2183 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2184 "Shut down and deactivate MS")
2186 struct osmocom_ms *ms = vty->index;
2188 if (ms->shutdown == 0)
2194 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2195 "Shut down and deactivate MS\nDo not perform IMSI detach")
2197 struct osmocom_ms *ms = vty->index;
2199 if (ms->shutdown <= 1)
2205 enum node_type ms_vty_go_parent(struct vty *vty)
2207 switch (vty->node) {
2209 vty->node = CONFIG_NODE;
2214 vty->node = MS_NODE;
2217 vty->node = CONFIG_NODE;
2223 /* Down vty node level. */
2224 gDEFUN(ournode_exit,
2225 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2227 switch (vty->node) {
2229 vty->node = CONFIG_NODE;
2234 vty->node = MS_NODE;
2242 /* End of configuration. */
2244 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2246 switch (vty->node) {
2249 /* Nothing to do. */
2256 vty_config_unlock(vty);
2257 vty->node = ENABLE_NODE;
2259 vty->index_sub = NULL;
2267 DEFUN(off, off_cmd, "off",
2268 "Turn mobiles off (shutdown) and exit")
2270 dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2275 #define SUP_NODE(item) \
2276 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2278 int ms_vty_init(void)
2280 install_element_ve(&show_ms_cmd);
2281 install_element_ve(&show_subscr_cmd);
2282 install_element_ve(&show_support_cmd);
2283 install_element_ve(&show_cell_cmd);
2284 install_element_ve(&show_cell_si_cmd);
2285 install_element_ve(&show_ba_cmd);
2286 install_element_ve(&show_forb_la_cmd);
2287 install_element_ve(&show_forb_plmn_cmd);
2288 install_element_ve(&monitor_network_cmd);
2289 install_element_ve(&no_monitor_network_cmd);
2290 install_element(ENABLE_NODE, &off_cmd);
2292 install_element(ENABLE_NODE, &sim_test_cmd);
2293 install_element(ENABLE_NODE, &sim_reader_cmd);
2294 install_element(ENABLE_NODE, &sim_remove_cmd);
2295 install_element(ENABLE_NODE, &sim_pin_cmd);
2296 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2297 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2298 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2299 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2300 install_element(ENABLE_NODE, &sim_lai_cmd);
2301 install_element(ENABLE_NODE, &network_search_cmd);
2302 install_element(ENABLE_NODE, &network_show_cmd);
2303 install_element(ENABLE_NODE, &network_select_cmd);
2304 install_element(ENABLE_NODE, &call_cmd);
2305 install_element(ENABLE_NODE, &call_retr_cmd);
2306 install_element(ENABLE_NODE, &call_dtmf_cmd);
2309 install_element(CONFIG_NODE, &cfg_gps_host_cmd);
2311 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2312 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2314 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2315 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2317 install_element(CONFIG_NODE, &cfg_ms_cmd);
2318 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2319 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2320 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2321 install_element(CONFIG_NODE, &ournode_end_cmd);
2322 install_node(&ms_node, config_write);
2323 install_default(MS_NODE);
2324 install_element(MS_NODE, &ournode_exit_cmd);
2325 install_element(MS_NODE, &ournode_end_cmd);
2326 install_element(MS_NODE, &cfg_ms_show_this_cmd);
2327 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2328 install_element(MS_NODE, &cfg_ms_sap_cmd);
2329 install_element(MS_NODE, &cfg_ms_sim_cmd);
2330 install_element(MS_NODE, &cfg_ms_mode_cmd);
2331 install_element(MS_NODE, &cfg_ms_imei_cmd);
2332 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2333 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2334 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2335 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2336 install_element(MS_NODE, &cfg_ms_cw_cmd);
2337 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2338 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2339 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2340 install_element(MS_NODE, &cfg_ms_clip_cmd);
2341 install_element(MS_NODE, &cfg_ms_clir_cmd);
2342 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2343 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2344 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2345 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2346 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2347 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2348 install_element(MS_NODE, &cfg_ms_stick_cmd);
2349 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2350 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2351 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2352 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2353 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2354 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2355 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2356 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2357 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2358 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2359 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2360 install_element(MS_NODE, &cfg_ms_support_cmd);
2361 install_node(&support_node, config_write_dummy);
2362 install_default(SUPPORT_NODE);
2363 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2364 install_element(SUPPORT_NODE, &ournode_end_cmd);
2365 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2366 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2367 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2368 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2369 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2370 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2371 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2372 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2373 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2374 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2375 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2376 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2377 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2378 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2379 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2380 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2381 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2382 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2383 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2384 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2385 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2386 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2387 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2388 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2389 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2390 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2391 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2392 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2393 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2394 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2395 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2396 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2397 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2398 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2399 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2400 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2401 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2402 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2403 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2404 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2405 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2406 install_node(&testsim_node, config_write_dummy);
2407 install_default(TESTSIM_NODE);
2408 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2409 install_element(TESTSIM_NODE, &ournode_end_cmd);
2410 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2411 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2412 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2413 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2414 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2415 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2416 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2417 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2418 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2419 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2420 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2425 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2427 struct telnet_connection *connection;
2433 va_start(args, fmt);
2434 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2435 buffer[sizeof(buffer) - 1] = '\0';
2442 llist_for_each_entry(connection, &active_connections, entry) {
2443 vty = connection->vty;
2447 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2451 if (buffer[strlen(buffer) - 1] == '\n') {
2452 buffer[strlen(buffer) - 1] = '\0';
2453 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2454 buffer[strlen(buffer)] = '\n';
2456 vty_out(vty, "%% %s", buffer);