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(g.gpsd_host, argv[0], colon - argv[0] - 1);
866 g.gpsd_host[colon - argv[0]] = '\0';
867 memcpy(g.gpsd_port, colon, strlen(colon));
868 g.gpsd_port[strlen(colon)] = '\0';
870 snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", argv[0]);
871 g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
872 snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "2947");
873 g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
875 g.gps_type = GPS_TYPE_GPSD;
878 if (osmo_gps_open()) {
879 vty_out(vty, "Failed to connect to gpsd host!%s",
889 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
890 "GPS receiver\nSelect serial device\n"
891 "Full path of serial device including /dev/")
893 strncpy(g.device, argv[0], sizeof(g.device));
894 g.device[sizeof(g.device) - 1] = '\0';
895 g.gps_type = GPS_TYPE_SERIAL;
898 if (osmo_gps_open()) {
899 vty_out(vty, "Failed to open GPS device!%s",
908 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
909 "(default|4800|""9600|19200|38400|57600|115200)",
910 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
912 if (argv[0][0] == 'd')
915 g.baud = atoi(argv[0]);
918 if (osmo_gps_open()) {
920 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", g.gpsd_host, VTY_NEWLINE);
1209 vty_out(vty, "gpsd port %s%s", g.gpsd_port, VTY_NEWLINE);
1211 vty_out(vty, "gps device %s%s", g.device, VTY_NEWLINE);
1213 vty_out(vty, "gps baudrate %d%s", g.baud, VTY_NEWLINE);
1215 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
1216 vty_out(vty, "%sgps enable%s", (g.enable) ? "" : "no ", VTY_NEWLINE);
1217 vty_out(vty, "!%s", VTY_NEWLINE);
1219 llist_for_each_entry(ms, &ms_list, entity)
1220 config_write_ms(vty, ms);
1225 DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
1226 SHOW_STR "Show config of this MS")
1228 struct osmocom_ms *ms = vty->index;
1230 config_write_ms(vty, ms);
1235 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1236 "Define socket path to connect between layer 2 and layer 1\n"
1237 "Unix socket, default '/tmp/osmocom_l2'")
1239 struct osmocom_ms *ms = vty->index;
1240 struct gsm_settings *set = &ms->settings;
1242 strncpy(set->layer2_socket_path, argv[0],
1243 sizeof(set->layer2_socket_path) - 1);
1245 vty_restart(vty, ms);
1249 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1250 "Define socket path to connect to SIM reader\n"
1251 "Unix socket, default '/tmp/osmocom_sap'")
1253 struct osmocom_ms *ms = vty->index;
1254 struct gsm_settings *set = &ms->settings;
1256 strncpy(set->sap_socket_path, argv[0],
1257 sizeof(set->sap_socket_path) - 1);
1259 vty_restart(vty, ms);
1263 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1264 "Set SIM card type when powering on\nNo SIM interted\n"
1265 "Use SIM from reader\nTest SIM inserted")
1267 struct osmocom_ms *ms = vty->index;
1268 struct gsm_settings *set = &ms->settings;
1270 switch (argv[0][0]) {
1272 set->sim_type = GSM_SIM_TYPE_NONE;
1275 set->sim_type = GSM_SIM_TYPE_READER;
1278 set->sim_type = GSM_SIM_TYPE_TEST;
1281 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1285 vty_restart(vty, ms);
1289 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1290 "Set network selection mode\nAutomatic network selection\n"
1291 "Manual network selection")
1293 struct osmocom_ms *ms = vty->index;
1294 struct gsm_settings *set = &ms->settings;
1297 if (!ms->plmn.state) {
1298 if (argv[0][0] == 'a')
1299 set->plmn_mode = PLMN_MODE_AUTO;
1301 set->plmn_mode = PLMN_MODE_MANUAL;
1305 if (argv[0][0] == 'a')
1306 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1308 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1311 gsm322_plmn_sendmsg(ms, nmsg);
1316 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1317 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1318 "Software version digit")
1320 struct osmocom_ms *ms = vty->index;
1321 struct gsm_settings *set = &ms->settings;
1322 char *error, *sv = "0";
1325 sv = (char *)argv[1];
1327 error = gsm_check_imei(argv[0], sv);
1329 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1333 strcpy(set->imei, argv[0]);
1334 strcpy(set->imeisv, argv[0]);
1335 strcpy(set->imeisv + 15, sv);
1340 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1341 "Use fixed IMEI on every power on")
1343 struct osmocom_ms *ms = vty->index;
1344 struct gsm_settings *set = &ms->settings;
1346 set->imei_random = 0;
1348 vty_restart(vty, ms);
1352 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1353 "Use random IMEI on every power on\n"
1354 "Number of trailing digits to randomize")
1356 struct osmocom_ms *ms = vty->index;
1357 struct gsm_settings *set = &ms->settings;
1359 set->imei_random = atoi(argv[0]);
1361 vty_restart(vty, ms);
1365 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1366 "Use special IMSI for emergency calls\n15 digits IMSI")
1368 struct osmocom_ms *ms = vty->index;
1369 struct gsm_settings *set = &ms->settings;
1372 error = gsm_check_imsi(argv[0]);
1374 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1377 strcpy(set->emergency_imsi, argv[0]);
1382 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1383 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1385 struct osmocom_ms *ms = vty->index;
1386 struct gsm_settings *set = &ms->settings;
1388 set->emergency_imsi[0] = '\0';
1393 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1394 NO_STR "Disallow waiting calls")
1396 struct osmocom_ms *ms = vty->index;
1397 struct gsm_settings *set = &ms->settings;
1404 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1405 "Allow waiting calls")
1407 struct osmocom_ms *ms = vty->index;
1408 struct gsm_settings *set = &ms->settings;
1415 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1416 NO_STR "Disable auto-answering calls")
1418 struct osmocom_ms *ms = vty->index;
1419 struct gsm_settings *set = &ms->settings;
1421 set->auto_answer = 0;
1426 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1427 "Enable auto-answering calls")
1429 struct osmocom_ms *ms = vty->index;
1430 struct gsm_settings *set = &ms->settings;
1432 set->auto_answer = 1;
1437 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1438 "Force caller ID presentation")
1440 struct osmocom_ms *ms = vty->index;
1441 struct gsm_settings *set = &ms->settings;
1449 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1450 "Force caller ID restriction")
1452 struct osmocom_ms *ms = vty->index;
1453 struct gsm_settings *set = &ms->settings;
1461 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1462 NO_STR "Disable forcing of caller ID presentation")
1464 struct osmocom_ms *ms = vty->index;
1465 struct gsm_settings *set = &ms->settings;
1472 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1473 NO_STR "Disable forcing of caller ID restriction")
1475 struct osmocom_ms *ms = vty->index;
1476 struct gsm_settings *set = &ms->settings;
1483 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1484 "Set the way to choose transmit power\nControlled by BTS\n"
1485 "Always full power\nFixed GSM power value if supported")
1487 struct osmocom_ms *ms = vty->index;
1488 struct gsm_settings *set = &ms->settings;
1490 switch (argv[0][0]) {
1492 set->alter_tx_power = 0;
1495 set->alter_tx_power = 1;
1496 set->alter_tx_power_value = 0;
1503 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1504 "Set the way to choose transmit power\n"
1505 "Fixed GSM power value if supported")
1507 struct osmocom_ms *ms = vty->index;
1508 struct gsm_settings *set = &ms->settings;
1510 set->alter_tx_power = 1;
1511 set->alter_tx_power_value = atoi(argv[0]);
1516 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1517 "Simulate a lower or higher distance from the BTS\n"
1518 "Delay in half bits (distance in 553.85 meter steps)")
1520 struct osmocom_ms *ms = vty->index;
1521 struct gsm_settings *set = &ms->settings;
1523 set->alter_delay = atoi(argv[0]);
1524 gsm48_rr_alter_delay(ms);
1529 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1530 NO_STR "Do not simulate a lower or higher distance from the BTS")
1532 struct osmocom_ms *ms = vty->index;
1533 struct gsm_settings *set = &ms->settings;
1535 set->alter_delay = 0;
1536 gsm48_rr_alter_delay(ms);
1541 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1542 "Stick to the given cell\nARFCN of the cell to stick to")
1544 struct osmocom_ms *ms = vty->index;
1545 struct gsm_settings *set = &ms->settings;
1548 set->stick_arfcn = atoi(argv[0]);
1553 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1554 NO_STR "Do not stick to any cell")
1556 struct osmocom_ms *ms = vty->index;
1557 struct gsm_settings *set = &ms->settings;
1564 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1565 "Allow location updating")
1567 struct osmocom_ms *ms = vty->index;
1568 struct gsm_settings *set = &ms->settings;
1575 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1576 NO_STR "Do not allow location updating")
1578 struct osmocom_ms *ms = vty->index;
1579 struct gsm_settings *set = &ms->settings;
1586 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1587 "Enable codec\nFull speed speech codec")
1589 struct osmocom_ms *ms = vty->index;
1590 struct gsm_settings *set = &ms->settings;
1592 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1593 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1600 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1602 "Enable codec\nFull speed speech codec\nPrefer this codec")
1604 struct osmocom_ms *ms = vty->index;
1605 struct gsm_settings *set = &ms->settings;
1607 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1608 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1612 set->half_prefer = 0;
1617 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1618 "Enable codec\nHalf speed speech codec")
1620 struct osmocom_ms *ms = vty->index;
1621 struct gsm_settings *set = &ms->settings;
1623 if (!set->half_v1 && !set->half_v3) {
1624 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1633 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1635 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1637 struct osmocom_ms *ms = vty->index;
1638 struct gsm_settings *set = &ms->settings;
1640 if (!set->half_v1 && !set->half_v3) {
1641 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1646 set->half_prefer = 1;
1651 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1652 NO_STR "Disable codec\nHalf speed speech codec")
1654 struct osmocom_ms *ms = vty->index;
1655 struct gsm_settings *set = &ms->settings;
1657 if (!set->half_v1 && !set->half_v3) {
1658 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1663 set->half_prefer = 0;
1668 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
1669 "Store given abbreviation number\n1-3 digits abbreviation\n"
1670 "Number to store for the abbreviation "
1671 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1672 "Name of the abbreviation")
1674 struct osmocom_ms *ms = vty->index;
1675 struct gsm_settings *set = &ms->settings;
1676 struct gsm_settings_abbrev *abbrev;
1679 llist_for_each_entry(abbrev, &set->abbrev, list) {
1680 if (!strcmp(argv[0], abbrev->abbrev)) {
1681 vty_out(vty, "Given abbreviation '%s' already stored, "
1682 "delete first!%s", argv[0], VTY_NEWLINE);
1687 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1688 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1692 for (i = 0; i < strlen(argv[0]); i++) {
1693 if (argv[0][i] < '0' || argv[0][i] > '9') {
1694 vty_out(vty, "Given abbreviation must have digits "
1695 "0..9 only!%s", VTY_NEWLINE);
1700 if (vty_check_number(vty, argv[1]))
1703 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1705 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1708 llist_add_tail(&abbrev->list, &set->abbrev);
1709 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1710 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1712 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1717 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
1718 NO_STR "Remove given abbreviation number or all numbers\n"
1719 "Abbreviation number to remove")
1721 struct osmocom_ms *ms = vty->index;
1722 struct gsm_settings *set = &ms->settings;
1723 struct gsm_settings_abbrev *abbrev, *abbrev2;
1724 uint8_t deleted = 0;
1726 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1727 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1728 llist_del(&abbrev->list);
1733 if (argc >= 1 && !deleted) {
1734 vty_out(vty, "Given abbreviation '%s' not found!%s",
1735 argv[0], VTY_NEWLINE);
1742 static int config_write_dummy(struct vty *vty)
1747 /* per support config */
1748 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1749 "Define supported features")
1751 vty->node = SUPPORT_NODE;
1756 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1757 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1759 struct osmocom_ms *ms = vty->index; \
1760 struct gsm_settings *set = &ms->settings; \
1761 struct gsm_support *sup = &ms->support; \
1763 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1765 return CMD_SUCCESS; \
1766 return CMD_WARNING; \
1769 vty_restart(vty, ms); \
1771 return CMD_SUCCESS; \
1774 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1775 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1777 struct osmocom_ms *ms = vty->index; \
1778 struct gsm_settings *set = &ms->settings; \
1779 struct gsm_support *sup = &ms->support; \
1781 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1783 return CMD_SUCCESS; \
1784 return CMD_WARNING; \
1787 vty_restart(vty, ms); \
1789 return CMD_SUCCESS; \
1792 #define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1793 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1795 struct osmocom_ms *ms = vty->index; \
1796 struct gsm_settings *set = &ms->settings; \
1798 vty_restart(vty, ms); \
1800 return CMD_SUCCESS; \
1803 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1804 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1806 struct osmocom_ms *ms = vty->index; \
1807 struct gsm_settings *set = &ms->settings; \
1809 vty_restart(vty, ms); \
1811 return CMD_SUCCESS; \
1814 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1815 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1816 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1817 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1818 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1819 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1820 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1821 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1822 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1823 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1824 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1825 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1826 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1827 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1828 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1829 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1830 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1831 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1832 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1834 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1836 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1838 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1840 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1842 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1844 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1845 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1847 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1848 "Select power class for GSM 850/900\n"
1855 struct osmocom_ms *ms = vty->index;
1856 struct gsm_settings *set = &ms->settings;
1857 struct gsm_support *sup = &ms->support;
1859 set->class_900 = atoi(argv[0]);
1861 if (set->class_900 < sup->class_900 && !vty_reading)
1862 vty_out(vty, "You selected an higher class than supported "
1863 " by hardware!%s", VTY_NEWLINE);
1868 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1869 "Select power class for DCS 1800\n"
1874 struct osmocom_ms *ms = vty->index;
1875 struct gsm_settings *set = &ms->settings;
1876 struct gsm_support *sup = &ms->support;
1878 set->class_dcs = atoi(argv[0]);
1880 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1882 vty_out(vty, "You selected an higher class than supported "
1883 " by hardware!%s", VTY_NEWLINE);
1888 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1889 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1890 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1892 struct osmocom_ms *ms = vty->index;
1893 struct gsm_settings *set = &ms->settings;
1894 struct gsm_support *sup = &ms->support;
1897 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
1898 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
1899 else if (!strcmp(argv[0], "sdcch+tchf"))
1900 ch_cap = GSM_CAP_SDCCH_TCHF;
1902 ch_cap = GSM_CAP_SDCCH;
1904 if (ch_cap > sup->ch_cap && !vty_reading) {
1905 vty_out(vty, "You selected an higher capability than supported "
1906 " by hardware!%s", VTY_NEWLINE);
1910 if (ch_cap != set->ch_cap
1911 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
1912 vty_restart(vty, ms);
1914 set->ch_cap = ch_cap;
1919 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
1920 "Full rate speech V1", 0);
1921 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
1922 "full-speech-v1", "Full rate speech V1", 0);
1923 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
1924 "Full rate speech V2 (EFR)", 0);
1925 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
1926 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
1927 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
1928 "Full rate speech V3 (AMR)", 0);
1929 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
1930 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
1931 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
1932 "Half rate speech V1", 0);
1933 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
1934 "half-speech-v1", "Half rate speech V1", 0);
1935 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
1936 "Half rate speech V3 (AMR)", 0);
1937 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
1938 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
1940 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
1941 "Set the minimum receive level to select a cell\n"
1942 "Minimum receive level from -110 dBm to -47 dBm")
1944 struct osmocom_ms *ms = vty->index;
1945 struct gsm_settings *set = &ms->settings;
1947 set->min_rxlev_db = atoi(argv[0]);
1952 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
1953 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
1954 "more reliable against bad RX signal. This increase the propability "
1955 "of missing a paging requests\n"
1956 "DSC initial and maximum value (standard is 90)")
1958 struct osmocom_ms *ms = vty->index;
1959 struct gsm_settings *set = &ms->settings;
1961 set->dsc_max = atoi(argv[0]);
1966 /* per testsim config */
1967 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1968 "Configure test SIM emulation")
1970 vty->node = TESTSIM_NODE;
1975 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1976 "Set IMSI on test card\n15 digits IMSI")
1978 struct osmocom_ms *ms = vty->index;
1979 struct gsm_settings *set = &ms->settings;
1980 char *error = gsm_check_imsi(argv[0]);
1983 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1987 strcpy(set->test_imsi, argv[0]);
1989 vty_restart(vty, ms);
1993 #define HEX_STR "\nByte as two digits hexadecimal"
1994 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1995 "HEX HEX HEX HEX HEX HEX",
1996 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1997 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
1999 struct osmocom_ms *ms = vty->index;
2000 struct gsm_settings *set = &ms->settings;
2005 for (i = 0; i < 12; i++) {
2007 if (!strncmp(p, "0x", 2))
2009 if (strlen(p) != 2) {
2010 vty_out(vty, "Expecting two digits hex value (with or "
2011 "without 0x in front)%s", VTY_NEWLINE);
2014 ki[i] = strtoul(p, NULL, 16);
2017 set->test_ki_type = GSM_SIM_KEY_XOR;
2018 memcpy(set->test_ki, ki, 12);
2022 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
2023 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
2024 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
2025 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
2026 HEX_STR HEX_STR HEX_STR HEX_STR)
2028 struct osmocom_ms *ms = vty->index;
2029 struct gsm_settings *set = &ms->settings;
2034 for (i = 0; i < 16; i++) {
2036 if (!strncmp(p, "0x", 2))
2038 if (strlen(p) != 2) {
2039 vty_out(vty, "Expecting two digits hex value (with or "
2040 "without 0x in front)%s", VTY_NEWLINE);
2043 ki[i] = strtoul(p, NULL, 16);
2046 set->test_ki_type = GSM_SIM_KEY_COMP128;
2047 memcpy(set->test_ki, ki, 16);
2051 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
2052 "Allow access to barred cells")
2054 struct osmocom_ms *ms = vty->index;
2055 struct gsm_settings *set = &ms->settings;
2062 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2063 NO_STR "Deny access to barred cells")
2065 struct osmocom_ms *ms = vty->index;
2066 struct gsm_settings *set = &ms->settings;
2073 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2074 NO_STR "Unset Registered PLMN")
2076 struct osmocom_ms *ms = vty->index;
2077 struct gsm_settings *set = &ms->settings;
2079 set->test_rplmn_valid = 0;
2081 vty_restart(vty, ms);
2085 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
2086 "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
2087 "Optionally set locatio area code\n"
2088 "Optionally set current assigned TMSI")
2090 struct osmocom_ms *ms = vty->index;
2091 struct gsm_settings *set = &ms->settings;
2092 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2093 mnc = gsm_input_mnc((char *)argv[1]);
2096 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2100 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2103 set->test_rplmn_valid = 1;
2104 set->test_rplmn_mcc = mcc;
2105 set->test_rplmn_mnc = mnc;
2108 set->test_lac = strtoul(argv[2], NULL, 16);
2110 set->test_lac = 0xfffe;
2113 set->test_tmsi = strtoul(argv[3], NULL, 16);
2115 set->test_tmsi = 0xffffffff;
2117 vty_restart(vty, ms);
2121 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2122 "Set Home PLMN search mode\n"
2123 "Search for HPLMN when on any other network\n"
2124 "Search for HPLMN when in a different country")
2126 struct osmocom_ms *ms = vty->index;
2127 struct gsm_settings *set = &ms->settings;
2129 switch (argv[0][0]) {
2131 set->test_always = 1;
2134 set->test_always = 0;
2138 vty_restart(vty, ms);
2142 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2143 NO_STR "Activate and run MS")
2145 struct osmocom_ms *ms = vty->index, *tmp;
2148 if (ms->shutdown != 2)
2151 llist_for_each_entry(tmp, &ms_list, entity) {
2152 if (tmp->shutdown == 2)
2154 if (!strcmp(ms->settings.layer2_socket_path,
2155 tmp->settings.layer2_socket_path)) {
2156 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2157 "use the same layer2-socket.%sPlease shutdown "
2158 "MS '%s' first.%s", ms->name, tmp->name,
2159 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2162 if (!strcmp(ms->settings.sap_socket_path,
2163 tmp->settings.sap_socket_path)) {
2164 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2165 "use the same sap-socket.%sPlease shutdown "
2166 "MS '%s' first.%s", ms->name, tmp->name,
2167 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2172 rc = mobile_init(ms);
2174 vty_out(vty, "Connection to layer 1 failed!%s",
2182 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2183 "Shut down and deactivate MS")
2185 struct osmocom_ms *ms = vty->index;
2187 if (ms->shutdown == 0)
2193 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2194 "Shut down and deactivate MS\nDo not perform IMSI detach")
2196 struct osmocom_ms *ms = vty->index;
2198 if (ms->shutdown <= 1)
2204 enum node_type ms_vty_go_parent(struct vty *vty)
2206 switch (vty->node) {
2208 vty->node = CONFIG_NODE;
2213 vty->node = MS_NODE;
2216 vty->node = CONFIG_NODE;
2222 /* Down vty node level. */
2223 gDEFUN(ournode_exit,
2224 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2226 switch (vty->node) {
2228 vty->node = CONFIG_NODE;
2233 vty->node = MS_NODE;
2241 /* End of configuration. */
2243 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2245 switch (vty->node) {
2248 /* Nothing to do. */
2255 vty_config_unlock(vty);
2256 vty->node = ENABLE_NODE;
2258 vty->index_sub = NULL;
2266 DEFUN(off, off_cmd, "off",
2267 "Turn mobiles off (shutdown) and exit")
2269 dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2274 #define SUP_NODE(item) \
2275 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2277 int ms_vty_init(void)
2279 install_element_ve(&show_ms_cmd);
2280 install_element_ve(&show_subscr_cmd);
2281 install_element_ve(&show_support_cmd);
2282 install_element_ve(&show_cell_cmd);
2283 install_element_ve(&show_cell_si_cmd);
2284 install_element_ve(&show_ba_cmd);
2285 install_element_ve(&show_forb_la_cmd);
2286 install_element_ve(&show_forb_plmn_cmd);
2287 install_element_ve(&monitor_network_cmd);
2288 install_element_ve(&no_monitor_network_cmd);
2289 install_element(ENABLE_NODE, &off_cmd);
2291 install_element(ENABLE_NODE, &sim_test_cmd);
2292 install_element(ENABLE_NODE, &sim_reader_cmd);
2293 install_element(ENABLE_NODE, &sim_remove_cmd);
2294 install_element(ENABLE_NODE, &sim_pin_cmd);
2295 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2296 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2297 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2298 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2299 install_element(ENABLE_NODE, &sim_lai_cmd);
2300 install_element(ENABLE_NODE, &network_search_cmd);
2301 install_element(ENABLE_NODE, &network_show_cmd);
2302 install_element(ENABLE_NODE, &network_select_cmd);
2303 install_element(ENABLE_NODE, &call_cmd);
2304 install_element(ENABLE_NODE, &call_retr_cmd);
2305 install_element(ENABLE_NODE, &call_dtmf_cmd);
2308 install_element(CONFIG_NODE, &cfg_gps_host_cmd);
2310 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2311 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2312 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2313 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2315 install_element(CONFIG_NODE, &cfg_ms_cmd);
2316 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2317 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2318 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2319 install_element(CONFIG_NODE, &ournode_end_cmd);
2320 install_node(&ms_node, config_write);
2321 install_default(MS_NODE);
2322 install_element(MS_NODE, &ournode_exit_cmd);
2323 install_element(MS_NODE, &ournode_end_cmd);
2324 install_element(MS_NODE, &cfg_ms_show_this_cmd);
2325 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2326 install_element(MS_NODE, &cfg_ms_sap_cmd);
2327 install_element(MS_NODE, &cfg_ms_sim_cmd);
2328 install_element(MS_NODE, &cfg_ms_mode_cmd);
2329 install_element(MS_NODE, &cfg_ms_imei_cmd);
2330 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2331 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2332 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2333 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2334 install_element(MS_NODE, &cfg_ms_cw_cmd);
2335 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2336 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2337 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2338 install_element(MS_NODE, &cfg_ms_clip_cmd);
2339 install_element(MS_NODE, &cfg_ms_clir_cmd);
2340 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2341 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2342 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2343 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2344 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2345 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2346 install_element(MS_NODE, &cfg_ms_stick_cmd);
2347 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2348 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2349 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2350 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2351 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2352 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2353 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2354 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2355 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2356 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2357 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2358 install_element(MS_NODE, &cfg_ms_support_cmd);
2359 install_node(&support_node, config_write_dummy);
2360 install_default(SUPPORT_NODE);
2361 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2362 install_element(SUPPORT_NODE, &ournode_end_cmd);
2363 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2364 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2365 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2366 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2367 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2368 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2369 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2370 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2371 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2372 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2373 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2374 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2375 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2376 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2377 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2378 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2379 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2380 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2381 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2382 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2383 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2384 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2385 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2386 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2387 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2388 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2389 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2390 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2391 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2392 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2393 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2394 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2395 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2396 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2397 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2398 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2399 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2400 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2401 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2402 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2403 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2404 install_node(&testsim_node, config_write_dummy);
2405 install_default(TESTSIM_NODE);
2406 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2407 install_element(TESTSIM_NODE, &ournode_end_cmd);
2408 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2409 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2410 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2411 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2412 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2413 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2414 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2415 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2416 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2417 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2418 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2423 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2425 struct telnet_connection *connection;
2431 va_start(args, fmt);
2432 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2433 buffer[sizeof(buffer) - 1] = '\0';
2440 llist_for_each_entry(connection, &active_connections, entry) {
2441 vty = connection->vty;
2445 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2449 if (buffer[strlen(buffer) - 1] == '\n') {
2450 buffer[strlen(buffer) - 1] = '\0';
2451 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2452 buffer[strlen(buffer)] = '\n';
2454 vty_out(vty, "%% %s", buffer);