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",
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")
858 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
859 "GPS receiver\nSelect serial device\n"
860 "Full path of serial device including /dev/")
862 strncpy(gps.device, argv[0], sizeof(gps.device));
863 gps.device[sizeof(gps.device) - 1] = '\0';
867 vty_out(vty, "Failed to open GPS device!%s",
876 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
877 "(default|4800|""9600|19200|38400|57600|115200)",
878 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
880 if (argv[0][0] == 'd')
883 gps.baud = atoi(argv[0]);
888 vty_out(vty, "Failed to open GPS device!%s",
898 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
899 "Select a mobile station to configure\nName of MS (see \"show ms\")")
901 struct osmocom_ms *ms;
904 llist_for_each_entry(ms, &ms_list, entity) {
905 if (!strcmp(ms->name, argv[0])) {
913 vty_out(vty, "MS name '%s' does not exits, try "
914 "'ms %s create'%s", argv[0], argv[0],
918 ms = mobile_new((char *)argv[0]);
920 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
932 DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
933 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
934 "Create if MS does not exists")
936 struct osmocom_ms *ms;
939 llist_for_each_entry(ms, &ms_list, entity) {
940 if (!strcmp(ms->name, argv[0])) {
947 ms = mobile_new((char *)argv[0]);
949 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
958 vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
959 argv[0], VTY_NEWLINE);
963 DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
964 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
965 "Rename MS\nNew name of MS")
967 struct osmocom_ms *ms;
970 llist_for_each_entry(ms, &ms_list, entity) {
971 if (!strcmp(ms->name, argv[0])) {
978 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
983 strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
988 DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
989 NO_STR "Select a mobile station to remove\n"
990 "Name of MS (see \"show ms\")")
992 struct osmocom_ms *ms;
995 llist_for_each_entry(ms, &ms_list, entity) {
996 if (!strcmp(ms->name, argv[0])) {
1003 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1008 mobile_delete(ms, 1);
1013 #define SUP_WRITE(item, cmd) \
1015 vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
1018 static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
1020 struct gsm_settings *set = &ms->settings;
1021 struct gsm_support *sup = &ms->support;
1022 struct gsm_settings_abbrev *abbrev;
1024 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
1025 vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
1027 vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
1028 switch(set->sim_type) {
1029 case GSM_SIM_TYPE_NONE:
1030 vty_out(vty, " sim none%s", VTY_NEWLINE);
1032 case GSM_SIM_TYPE_READER:
1033 vty_out(vty, " sim reader%s", VTY_NEWLINE);
1035 case GSM_SIM_TYPE_TEST:
1036 vty_out(vty, " sim test%s", VTY_NEWLINE);
1039 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
1040 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
1041 vty_out(vty, " imei %s %s%s", set->imei,
1042 set->imeisv + strlen(set->imei), VTY_NEWLINE);
1043 if (set->imei_random)
1044 vty_out(vty, " imei-random %d%s", set->imei_random,
1047 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
1048 if (set->emergency_imsi[0])
1049 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
1052 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
1053 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
1054 vty_out(vty, " %sauto-answer%s", (set->auto_answer) ? "" : "no ",
1056 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
1057 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
1058 if (set->alter_tx_power)
1059 if (set->alter_tx_power_value)
1060 vty_out(vty, " tx-power %d%s",
1061 set->alter_tx_power_value, VTY_NEWLINE);
1063 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
1065 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
1066 if (set->alter_delay)
1067 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
1070 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
1072 vty_out(vty, " stick %d%s", set->stick_arfcn,
1075 vty_out(vty, " no stick%s", VTY_NEWLINE);
1077 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
1079 vty_out(vty, " location-updating%s", VTY_NEWLINE);
1080 if (set->full_v1 || set->full_v2 || set->full_v3) {
1081 /* mandatory anyway */
1082 vty_out(vty, " codec full-speed%s%s",
1083 (!set->half_prefer) ? " prefer" : "",
1086 if (set->half_v1 || set->half_v3) {
1088 vty_out(vty, " codec half-speed%s%s",
1089 (set->half_prefer) ? " prefer" : "",
1092 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
1094 if (llist_empty(&set->abbrev))
1095 vty_out(vty, " no abbrev%s", VTY_NEWLINE);
1097 llist_for_each_entry(abbrev, &set->abbrev, list)
1098 vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
1099 abbrev->number, (abbrev->name[0]) ? " " : "",
1100 abbrev->name, VTY_NEWLINE);
1102 vty_out(vty, " support%s", VTY_NEWLINE);
1103 SUP_WRITE(sms_ptp, "sms");
1104 SUP_WRITE(a5_1, "a5/1");
1105 SUP_WRITE(a5_2, "a5/2");
1106 SUP_WRITE(a5_3, "a5/3");
1107 SUP_WRITE(a5_4, "a5/4");
1108 SUP_WRITE(a5_5, "a5/5");
1109 SUP_WRITE(a5_6, "a5/6");
1110 SUP_WRITE(a5_7, "a5/7");
1111 SUP_WRITE(p_gsm, "p-gsm");
1112 SUP_WRITE(e_gsm, "e-gsm");
1113 SUP_WRITE(r_gsm, "r-gsm");
1114 SUP_WRITE(dcs, "dcs");
1115 vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
1116 vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
1117 switch (set->ch_cap) {
1119 vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
1121 case GSM_CAP_SDCCH_TCHF:
1122 vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
1124 case GSM_CAP_SDCCH_TCHF_TCHH:
1125 vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
1129 SUP_WRITE(full_v1, "full-speech-v1");
1130 SUP_WRITE(full_v2, "full-speech-v2");
1131 SUP_WRITE(full_v3, "full-speech-v3");
1132 SUP_WRITE(half_v1, "half-speech-v1");
1133 SUP_WRITE(half_v3, "half-speech-v3");
1134 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
1135 vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
1136 vty_out(vty, " exit%s", VTY_NEWLINE);
1137 vty_out(vty, " test-sim%s", VTY_NEWLINE);
1138 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
1139 switch (set->test_ki_type) {
1140 case GSM_SIM_KEY_XOR:
1141 vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
1144 case GSM_SIM_KEY_COMP128:
1145 vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
1149 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
1151 if (set->test_rplmn_valid) {
1152 vty_out(vty, " rplmn %s %s",
1153 gsm_print_mcc(set->test_rplmn_mcc),
1154 gsm_print_mnc(set->test_rplmn_mnc));
1155 if (set->test_lac > 0x0000 && set->test_lac < 0xfffe)
1156 vty_out(vty, " 0x%04x", set->test_lac);
1157 if (set->test_tmsi != 0xffffffff)
1158 vty_out(vty, " 0x%08x", set->test_tmsi);
1159 vty_out(vty, "%s", VTY_NEWLINE);
1161 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
1162 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
1163 : "foreign-country", VTY_NEWLINE);
1164 vty_out(vty, " exit%s", VTY_NEWLINE);
1165 vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
1167 vty_out(vty, "exit%s", VTY_NEWLINE);
1168 vty_out(vty, "!%s", VTY_NEWLINE);
1171 static int config_write(struct vty *vty)
1173 struct osmocom_ms *ms;
1175 vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
1177 vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
1179 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
1180 vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
1181 vty_out(vty, "!%s", VTY_NEWLINE);
1183 llist_for_each_entry(ms, &ms_list, entity)
1184 config_write_ms(vty, ms);
1189 DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
1190 SHOW_STR "Show config of this MS")
1192 struct osmocom_ms *ms = vty->index;
1194 config_write_ms(vty, ms);
1199 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1200 "Define socket path to connect between layer 2 and layer 1\n"
1201 "Unix socket, default '/tmp/osmocom_l2'")
1203 struct osmocom_ms *ms = vty->index;
1204 struct gsm_settings *set = &ms->settings;
1206 strncpy(set->layer2_socket_path, argv[0],
1207 sizeof(set->layer2_socket_path) - 1);
1209 vty_restart(vty, ms);
1213 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1214 "Define socket path to connect to SIM reader\n"
1215 "Unix socket, default '/tmp/osmocom_sap'")
1217 struct osmocom_ms *ms = vty->index;
1218 struct gsm_settings *set = &ms->settings;
1220 strncpy(set->sap_socket_path, argv[0],
1221 sizeof(set->sap_socket_path) - 1);
1223 vty_restart(vty, ms);
1227 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1228 "Set SIM card type when powering on\nNo SIM interted\n"
1229 "Use SIM from reader\nTest SIM inserted")
1231 struct osmocom_ms *ms = vty->index;
1232 struct gsm_settings *set = &ms->settings;
1234 switch (argv[0][0]) {
1236 set->sim_type = GSM_SIM_TYPE_NONE;
1239 set->sim_type = GSM_SIM_TYPE_READER;
1242 set->sim_type = GSM_SIM_TYPE_TEST;
1245 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1249 vty_restart(vty, ms);
1253 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1254 "Set network selection mode\nAutomatic network selection\n"
1255 "Manual network selection")
1257 struct osmocom_ms *ms = vty->index;
1258 struct gsm_settings *set = &ms->settings;
1261 if (!ms->plmn.state) {
1262 if (argv[0][0] == 'a')
1263 set->plmn_mode = PLMN_MODE_AUTO;
1265 set->plmn_mode = PLMN_MODE_MANUAL;
1269 if (argv[0][0] == 'a')
1270 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1272 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1275 gsm322_plmn_sendmsg(ms, nmsg);
1280 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1281 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1282 "Software version digit")
1284 struct osmocom_ms *ms = vty->index;
1285 struct gsm_settings *set = &ms->settings;
1286 char *error, *sv = "0";
1289 sv = (char *)argv[1];
1291 error = gsm_check_imei(argv[0], sv);
1293 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1297 strcpy(set->imei, argv[0]);
1298 strcpy(set->imeisv, argv[0]);
1299 strcpy(set->imeisv + 15, sv);
1304 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1305 "Use fixed IMEI on every power on")
1307 struct osmocom_ms *ms = vty->index;
1308 struct gsm_settings *set = &ms->settings;
1310 set->imei_random = 0;
1312 vty_restart(vty, ms);
1316 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1317 "Use random IMEI on every power on\n"
1318 "Number of trailing digits to randomize")
1320 struct osmocom_ms *ms = vty->index;
1321 struct gsm_settings *set = &ms->settings;
1323 set->imei_random = atoi(argv[0]);
1325 vty_restart(vty, ms);
1329 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1330 "Use special IMSI for emergency calls\n15 digits IMSI")
1332 struct osmocom_ms *ms = vty->index;
1333 struct gsm_settings *set = &ms->settings;
1336 error = gsm_check_imsi(argv[0]);
1338 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1341 strcpy(set->emergency_imsi, argv[0]);
1346 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1347 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1349 struct osmocom_ms *ms = vty->index;
1350 struct gsm_settings *set = &ms->settings;
1352 set->emergency_imsi[0] = '\0';
1357 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1358 NO_STR "Disallow waiting calls")
1360 struct osmocom_ms *ms = vty->index;
1361 struct gsm_settings *set = &ms->settings;
1368 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1369 "Allow waiting calls")
1371 struct osmocom_ms *ms = vty->index;
1372 struct gsm_settings *set = &ms->settings;
1379 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1380 NO_STR "Disable auto-answering calls")
1382 struct osmocom_ms *ms = vty->index;
1383 struct gsm_settings *set = &ms->settings;
1385 set->auto_answer = 0;
1390 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1391 "Enable auto-answering calls")
1393 struct osmocom_ms *ms = vty->index;
1394 struct gsm_settings *set = &ms->settings;
1396 set->auto_answer = 1;
1401 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1402 "Force caller ID presentation")
1404 struct osmocom_ms *ms = vty->index;
1405 struct gsm_settings *set = &ms->settings;
1413 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1414 "Force caller ID restriction")
1416 struct osmocom_ms *ms = vty->index;
1417 struct gsm_settings *set = &ms->settings;
1425 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1426 NO_STR "Disable forcing of caller ID presentation")
1428 struct osmocom_ms *ms = vty->index;
1429 struct gsm_settings *set = &ms->settings;
1436 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1437 NO_STR "Disable forcing of caller ID restriction")
1439 struct osmocom_ms *ms = vty->index;
1440 struct gsm_settings *set = &ms->settings;
1447 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1448 "Set the way to choose transmit power\nControlled by BTS\n"
1449 "Always full power\nFixed GSM power value if supported")
1451 struct osmocom_ms *ms = vty->index;
1452 struct gsm_settings *set = &ms->settings;
1454 switch (argv[0][0]) {
1456 set->alter_tx_power = 0;
1459 set->alter_tx_power = 1;
1460 set->alter_tx_power_value = 0;
1467 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1468 "Set the way to choose transmit power\n"
1469 "Fixed GSM power value if supported")
1471 struct osmocom_ms *ms = vty->index;
1472 struct gsm_settings *set = &ms->settings;
1474 set->alter_tx_power = 1;
1475 set->alter_tx_power_value = atoi(argv[0]);
1480 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1481 "Simulate a lower or higher distance from the BTS\n"
1482 "Delay in half bits (distance in 553.85 meter steps)")
1484 struct osmocom_ms *ms = vty->index;
1485 struct gsm_settings *set = &ms->settings;
1487 set->alter_delay = atoi(argv[0]);
1488 gsm48_rr_alter_delay(ms);
1493 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1494 NO_STR "Do not simulate a lower or higher distance from the BTS")
1496 struct osmocom_ms *ms = vty->index;
1497 struct gsm_settings *set = &ms->settings;
1499 set->alter_delay = 0;
1500 gsm48_rr_alter_delay(ms);
1505 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1506 "Stick to the given cell\nARFCN of the cell to stick to")
1508 struct osmocom_ms *ms = vty->index;
1509 struct gsm_settings *set = &ms->settings;
1512 set->stick_arfcn = atoi(argv[0]);
1517 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1518 NO_STR "Do not stick to any cell")
1520 struct osmocom_ms *ms = vty->index;
1521 struct gsm_settings *set = &ms->settings;
1528 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1529 "Allow location updating")
1531 struct osmocom_ms *ms = vty->index;
1532 struct gsm_settings *set = &ms->settings;
1539 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1540 NO_STR "Do not allow location updating")
1542 struct osmocom_ms *ms = vty->index;
1543 struct gsm_settings *set = &ms->settings;
1550 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1551 "Enable codec\nFull speed speech codec")
1553 struct osmocom_ms *ms = vty->index;
1554 struct gsm_settings *set = &ms->settings;
1556 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1557 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1564 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1566 "Enable codec\nFull speed speech codec\nPrefer this codec")
1568 struct osmocom_ms *ms = vty->index;
1569 struct gsm_settings *set = &ms->settings;
1571 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1572 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1576 set->half_prefer = 0;
1581 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1582 "Enable codec\nHalf speed speech codec")
1584 struct osmocom_ms *ms = vty->index;
1585 struct gsm_settings *set = &ms->settings;
1587 if (!set->half_v1 && !set->half_v3) {
1588 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1597 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1599 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1601 struct osmocom_ms *ms = vty->index;
1602 struct gsm_settings *set = &ms->settings;
1604 if (!set->half_v1 && !set->half_v3) {
1605 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1610 set->half_prefer = 1;
1615 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1616 NO_STR "Disable codec\nHalf speed speech codec")
1618 struct osmocom_ms *ms = vty->index;
1619 struct gsm_settings *set = &ms->settings;
1621 if (!set->half_v1 && !set->half_v3) {
1622 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1627 set->half_prefer = 0;
1632 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
1633 "Store given abbreviation number\n1-3 digits abbreviation\n"
1634 "Number to store for the abbreviation "
1635 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1636 "Name of the abbreviation")
1638 struct osmocom_ms *ms = vty->index;
1639 struct gsm_settings *set = &ms->settings;
1640 struct gsm_settings_abbrev *abbrev;
1643 llist_for_each_entry(abbrev, &set->abbrev, list) {
1644 if (!strcmp(argv[0], abbrev->abbrev)) {
1645 vty_out(vty, "Given abbreviation '%s' already stored, "
1646 "delete first!%s", argv[0], VTY_NEWLINE);
1651 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1652 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1656 for (i = 0; i < strlen(argv[0]); i++) {
1657 if (argv[0][i] < '0' || argv[0][i] > '9') {
1658 vty_out(vty, "Given abbreviation must have digits "
1659 "0..9 only!%s", VTY_NEWLINE);
1664 if (vty_check_number(vty, argv[1]))
1667 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1669 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1672 llist_add_tail(&abbrev->list, &set->abbrev);
1673 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1674 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1676 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1681 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
1682 NO_STR "Remove given abbreviation number or all numbers\n"
1683 "Abbreviation number to remove")
1685 struct osmocom_ms *ms = vty->index;
1686 struct gsm_settings *set = &ms->settings;
1687 struct gsm_settings_abbrev *abbrev, *abbrev2;
1688 uint8_t deleted = 0;
1690 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1691 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1692 llist_del(&abbrev->list);
1697 if (argc >= 1 && !deleted) {
1698 vty_out(vty, "Given abbreviation '%s' not found!%s",
1699 argv[0], VTY_NEWLINE);
1706 static int config_write_dummy(struct vty *vty)
1711 /* per support config */
1712 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1713 "Define supported features")
1715 vty->node = SUPPORT_NODE;
1720 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1721 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1723 struct osmocom_ms *ms = vty->index; \
1724 struct gsm_settings *set = &ms->settings; \
1725 struct gsm_support *sup = &ms->support; \
1727 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1729 return CMD_SUCCESS; \
1730 return CMD_WARNING; \
1733 vty_restart(vty, ms); \
1735 return CMD_SUCCESS; \
1738 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1739 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1741 struct osmocom_ms *ms = vty->index; \
1742 struct gsm_settings *set = &ms->settings; \
1743 struct gsm_support *sup = &ms->support; \
1745 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1747 return CMD_SUCCESS; \
1748 return CMD_WARNING; \
1751 vty_restart(vty, ms); \
1753 return CMD_SUCCESS; \
1756 #define SET_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; \
1762 vty_restart(vty, ms); \
1764 return CMD_SUCCESS; \
1767 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1768 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1770 struct osmocom_ms *ms = vty->index; \
1771 struct gsm_settings *set = &ms->settings; \
1773 vty_restart(vty, ms); \
1775 return CMD_SUCCESS; \
1778 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1779 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1780 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1781 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1782 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1783 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1784 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1785 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1786 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1787 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1788 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1789 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1790 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1791 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1792 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1793 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1794 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1795 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1796 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1798 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1800 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1802 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1804 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1806 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1808 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1809 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1811 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1812 "Select power class for GSM 850/900\n"
1819 struct osmocom_ms *ms = vty->index;
1820 struct gsm_settings *set = &ms->settings;
1821 struct gsm_support *sup = &ms->support;
1823 set->class_900 = atoi(argv[0]);
1825 if (set->class_900 < sup->class_900 && !vty_reading)
1826 vty_out(vty, "You selected an higher class than supported "
1827 " by hardware!%s", VTY_NEWLINE);
1832 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1833 "Select power class for DCS 1800\n"
1838 struct osmocom_ms *ms = vty->index;
1839 struct gsm_settings *set = &ms->settings;
1840 struct gsm_support *sup = &ms->support;
1842 set->class_dcs = atoi(argv[0]);
1844 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1846 vty_out(vty, "You selected an higher class than supported "
1847 " by hardware!%s", VTY_NEWLINE);
1852 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1853 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1854 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1856 struct osmocom_ms *ms = vty->index;
1857 struct gsm_settings *set = &ms->settings;
1858 struct gsm_support *sup = &ms->support;
1861 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
1862 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
1863 else if (!strcmp(argv[0], "sdcch+tchf"))
1864 ch_cap = GSM_CAP_SDCCH_TCHF;
1866 ch_cap = GSM_CAP_SDCCH;
1868 if (ch_cap > sup->ch_cap && !vty_reading) {
1869 vty_out(vty, "You selected an higher capability than supported "
1870 " by hardware!%s", VTY_NEWLINE);
1874 if (ch_cap != set->ch_cap
1875 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
1876 vty_restart(vty, ms);
1878 set->ch_cap = ch_cap;
1883 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
1884 "Full rate speech V1", 0);
1885 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
1886 "full-speech-v1", "Full rate speech V1", 0);
1887 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
1888 "Full rate speech V2 (EFR)", 0);
1889 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
1890 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
1891 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
1892 "Full rate speech V3 (AMR)", 0);
1893 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
1894 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
1895 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
1896 "Half rate speech V1", 0);
1897 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
1898 "half-speech-v1", "Half rate speech V1", 0);
1899 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
1900 "Half rate speech V3 (AMR)", 0);
1901 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
1902 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
1904 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
1905 "Set the minimum receive level to select a cell\n"
1906 "Minimum receive level from -110 dBm to -47 dBm")
1908 struct osmocom_ms *ms = vty->index;
1909 struct gsm_settings *set = &ms->settings;
1911 set->min_rxlev_db = atoi(argv[0]);
1916 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
1917 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
1918 "more reliable against bad RX signal. This increase the propability "
1919 "of missing a paging requests\n"
1920 "DSC initial and maximum value (standard is 90)")
1922 struct osmocom_ms *ms = vty->index;
1923 struct gsm_settings *set = &ms->settings;
1925 set->dsc_max = atoi(argv[0]);
1930 /* per testsim config */
1931 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1932 "Configure test SIM emulation")
1934 vty->node = TESTSIM_NODE;
1939 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1940 "Set IMSI on test card\n15 digits IMSI")
1942 struct osmocom_ms *ms = vty->index;
1943 struct gsm_settings *set = &ms->settings;
1944 char *error = gsm_check_imsi(argv[0]);
1947 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1951 strcpy(set->test_imsi, argv[0]);
1953 vty_restart(vty, ms);
1957 #define HEX_STR "\nByte as two digits hexadecimal"
1958 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1959 "HEX HEX HEX HEX HEX HEX",
1960 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1961 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
1963 struct osmocom_ms *ms = vty->index;
1964 struct gsm_settings *set = &ms->settings;
1969 for (i = 0; i < 12; i++) {
1971 if (!strncmp(p, "0x", 2))
1973 if (strlen(p) != 2) {
1974 vty_out(vty, "Expecting two digits hex value (with or "
1975 "without 0x in front)%s", VTY_NEWLINE);
1978 ki[i] = strtoul(p, NULL, 16);
1981 set->test_ki_type = GSM_SIM_KEY_XOR;
1982 memcpy(set->test_ki, ki, 12);
1986 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
1987 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
1988 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1989 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
1990 HEX_STR HEX_STR HEX_STR HEX_STR)
1992 struct osmocom_ms *ms = vty->index;
1993 struct gsm_settings *set = &ms->settings;
1998 for (i = 0; i < 16; i++) {
2000 if (!strncmp(p, "0x", 2))
2002 if (strlen(p) != 2) {
2003 vty_out(vty, "Expecting two digits hex value (with or "
2004 "without 0x in front)%s", VTY_NEWLINE);
2007 ki[i] = strtoul(p, NULL, 16);
2010 set->test_ki_type = GSM_SIM_KEY_COMP128;
2011 memcpy(set->test_ki, ki, 16);
2015 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
2016 "Allow access to barred cells")
2018 struct osmocom_ms *ms = vty->index;
2019 struct gsm_settings *set = &ms->settings;
2026 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2027 NO_STR "Deny access to barred cells")
2029 struct osmocom_ms *ms = vty->index;
2030 struct gsm_settings *set = &ms->settings;
2037 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2038 NO_STR "Unset Registered PLMN")
2040 struct osmocom_ms *ms = vty->index;
2041 struct gsm_settings *set = &ms->settings;
2043 set->test_rplmn_valid = 0;
2045 vty_restart(vty, ms);
2049 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
2050 "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
2051 "Optionally set locatio area code\n"
2052 "Optionally set current assigned TMSI")
2054 struct osmocom_ms *ms = vty->index;
2055 struct gsm_settings *set = &ms->settings;
2056 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2057 mnc = gsm_input_mnc((char *)argv[1]);
2060 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2064 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2067 set->test_rplmn_valid = 1;
2068 set->test_rplmn_mcc = mcc;
2069 set->test_rplmn_mnc = mnc;
2072 set->test_lac = strtoul(argv[2], NULL, 16);
2074 set->test_lac = 0xfffe;
2077 set->test_tmsi = strtoul(argv[3], NULL, 16);
2079 set->test_tmsi = 0xffffffff;
2081 vty_restart(vty, ms);
2085 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2086 "Set Home PLMN search mode\n"
2087 "Search for HPLMN when on any other network\n"
2088 "Search for HPLMN when in a different country")
2090 struct osmocom_ms *ms = vty->index;
2091 struct gsm_settings *set = &ms->settings;
2093 switch (argv[0][0]) {
2095 set->test_always = 1;
2098 set->test_always = 0;
2102 vty_restart(vty, ms);
2106 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2107 NO_STR "Activate and run MS")
2109 struct osmocom_ms *ms = vty->index, *tmp;
2112 if (ms->shutdown != 2)
2115 llist_for_each_entry(tmp, &ms_list, entity) {
2116 if (tmp->shutdown == 2)
2118 if (!strcmp(ms->settings.layer2_socket_path,
2119 tmp->settings.layer2_socket_path)) {
2120 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2121 "use the same layer2-socket.%sPlease shutdown "
2122 "MS '%s' first.%s", ms->name, tmp->name,
2123 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2126 if (!strcmp(ms->settings.sap_socket_path,
2127 tmp->settings.sap_socket_path)) {
2128 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2129 "use the same sap-socket.%sPlease shutdown "
2130 "MS '%s' first.%s", ms->name, tmp->name,
2131 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2136 rc = mobile_init(ms);
2138 vty_out(vty, "Connection to layer 1 failed!%s",
2146 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2147 "Shut down and deactivate MS")
2149 struct osmocom_ms *ms = vty->index;
2151 if (ms->shutdown == 0)
2157 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2158 "Shut down and deactivate MS\nDo not perform IMSI detach")
2160 struct osmocom_ms *ms = vty->index;
2162 if (ms->shutdown <= 1)
2168 enum node_type ms_vty_go_parent(struct vty *vty)
2170 switch (vty->node) {
2172 vty->node = CONFIG_NODE;
2177 vty->node = MS_NODE;
2180 vty->node = CONFIG_NODE;
2186 /* Down vty node level. */
2187 gDEFUN(ournode_exit,
2188 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2190 switch (vty->node) {
2192 vty->node = CONFIG_NODE;
2197 vty->node = MS_NODE;
2205 /* End of configuration. */
2207 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2209 switch (vty->node) {
2212 /* Nothing to do. */
2219 vty_config_unlock(vty);
2220 vty->node = ENABLE_NODE;
2222 vty->index_sub = NULL;
2230 DEFUN(off, off_cmd, "off",
2231 "Turn mobiles off (shutdown) and exit")
2233 dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2238 #define SUP_NODE(item) \
2239 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2241 int ms_vty_init(void)
2243 install_element_ve(&show_ms_cmd);
2244 install_element_ve(&show_subscr_cmd);
2245 install_element_ve(&show_support_cmd);
2246 install_element_ve(&show_cell_cmd);
2247 install_element_ve(&show_cell_si_cmd);
2248 install_element_ve(&show_ba_cmd);
2249 install_element_ve(&show_forb_la_cmd);
2250 install_element_ve(&show_forb_plmn_cmd);
2251 install_element_ve(&monitor_network_cmd);
2252 install_element_ve(&no_monitor_network_cmd);
2253 install_element(ENABLE_NODE, &off_cmd);
2255 install_element(ENABLE_NODE, &sim_test_cmd);
2256 install_element(ENABLE_NODE, &sim_reader_cmd);
2257 install_element(ENABLE_NODE, &sim_remove_cmd);
2258 install_element(ENABLE_NODE, &sim_pin_cmd);
2259 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2260 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2261 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2262 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2263 install_element(ENABLE_NODE, &sim_lai_cmd);
2264 install_element(ENABLE_NODE, &network_search_cmd);
2265 install_element(ENABLE_NODE, &network_show_cmd);
2266 install_element(ENABLE_NODE, &network_select_cmd);
2267 install_element(ENABLE_NODE, &call_cmd);
2268 install_element(ENABLE_NODE, &call_retr_cmd);
2269 install_element(ENABLE_NODE, &call_dtmf_cmd);
2271 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2272 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2273 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2274 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2276 install_element(CONFIG_NODE, &cfg_ms_cmd);
2277 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2278 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2279 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2280 install_element(CONFIG_NODE, &ournode_end_cmd);
2281 install_node(&ms_node, config_write);
2282 install_default(MS_NODE);
2283 install_element(MS_NODE, &ournode_exit_cmd);
2284 install_element(MS_NODE, &ournode_end_cmd);
2285 install_element(MS_NODE, &cfg_ms_show_this_cmd);
2286 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2287 install_element(MS_NODE, &cfg_ms_sap_cmd);
2288 install_element(MS_NODE, &cfg_ms_sim_cmd);
2289 install_element(MS_NODE, &cfg_ms_mode_cmd);
2290 install_element(MS_NODE, &cfg_ms_imei_cmd);
2291 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2292 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2293 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2294 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2295 install_element(MS_NODE, &cfg_ms_cw_cmd);
2296 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2297 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2298 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2299 install_element(MS_NODE, &cfg_ms_clip_cmd);
2300 install_element(MS_NODE, &cfg_ms_clir_cmd);
2301 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2302 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2303 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2304 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2305 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2306 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2307 install_element(MS_NODE, &cfg_ms_stick_cmd);
2308 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2309 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2310 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2311 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2312 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2313 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2314 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2315 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2316 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2317 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2318 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2319 install_element(MS_NODE, &cfg_ms_support_cmd);
2320 install_node(&support_node, config_write_dummy);
2321 install_default(SUPPORT_NODE);
2322 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2323 install_element(SUPPORT_NODE, &ournode_end_cmd);
2324 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2325 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2326 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2327 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2328 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2329 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2330 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2331 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2332 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2333 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2334 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2335 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2336 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2337 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2338 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2339 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2340 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2341 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2342 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2343 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2344 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2345 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2346 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2347 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2348 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2349 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2350 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2351 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2352 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2353 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2354 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2355 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2356 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2357 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2358 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2359 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2360 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2361 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2362 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2363 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2364 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2365 install_node(&testsim_node, config_write_dummy);
2366 install_default(TESTSIM_NODE);
2367 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2368 install_element(TESTSIM_NODE, &ournode_end_cmd);
2369 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2370 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2371 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2372 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2373 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2374 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2375 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2376 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2377 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2378 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2379 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2384 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2386 struct telnet_connection *connection;
2392 va_start(args, fmt);
2393 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2394 buffer[sizeof(buffer) - 1] = '\0';
2401 llist_for_each_entry(connection, &active_connections, entry) {
2402 vty = connection->vty;
2406 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2410 if (buffer[strlen(buffer) - 1] == '\n') {
2411 buffer[strlen(buffer) - 1] = '\0';
2412 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2413 buffer[strlen(buffer)] = '\n';
2415 vty_out(vty, "%% %s", buffer);