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_single(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_ms(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_single(vty, ms);
1189 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1190 "Define socket path to connect between layer 2 and layer 1\n"
1191 "Unix socket, default '/tmp/osmocom_l2'")
1193 struct osmocom_ms *ms = vty->index;
1194 struct gsm_settings *set = &ms->settings;
1196 strncpy(set->layer2_socket_path, argv[0],
1197 sizeof(set->layer2_socket_path) - 1);
1199 vty_restart(vty, ms);
1203 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1204 "Define socket path to connect to SIM reader\n"
1205 "Unix socket, default '/tmp/osmocom_sap'")
1207 struct osmocom_ms *ms = vty->index;
1208 struct gsm_settings *set = &ms->settings;
1210 strncpy(set->sap_socket_path, argv[0],
1211 sizeof(set->sap_socket_path) - 1);
1213 vty_restart(vty, ms);
1217 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1218 "Set SIM card type when powering on\nNo SIM interted\n"
1219 "Use SIM from reader\nTest SIM inserted")
1221 struct osmocom_ms *ms = vty->index;
1222 struct gsm_settings *set = &ms->settings;
1224 switch (argv[0][0]) {
1226 set->sim_type = GSM_SIM_TYPE_NONE;
1229 set->sim_type = GSM_SIM_TYPE_READER;
1232 set->sim_type = GSM_SIM_TYPE_TEST;
1235 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1239 vty_restart(vty, ms);
1243 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1244 "Set network selection mode\nAutomatic network selection\n"
1245 "Manual network selection")
1247 struct osmocom_ms *ms = vty->index;
1248 struct gsm_settings *set = &ms->settings;
1251 if (!ms->plmn.state) {
1252 if (argv[0][0] == 'a')
1253 set->plmn_mode = PLMN_MODE_AUTO;
1255 set->plmn_mode = PLMN_MODE_MANUAL;
1259 if (argv[0][0] == 'a')
1260 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1262 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1265 gsm322_plmn_sendmsg(ms, nmsg);
1270 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1271 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1272 "Software version digit")
1274 struct osmocom_ms *ms = vty->index;
1275 struct gsm_settings *set = &ms->settings;
1276 char *error, *sv = "0";
1279 sv = (char *)argv[1];
1281 error = gsm_check_imei(argv[0], sv);
1283 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1287 strcpy(set->imei, argv[0]);
1288 strcpy(set->imeisv, argv[0]);
1289 strcpy(set->imeisv + 15, sv);
1294 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1295 "Use fixed IMEI on every power on")
1297 struct osmocom_ms *ms = vty->index;
1298 struct gsm_settings *set = &ms->settings;
1300 set->imei_random = 0;
1302 vty_restart(vty, ms);
1306 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1307 "Use random IMEI on every power on\n"
1308 "Number of trailing digits to randomize")
1310 struct osmocom_ms *ms = vty->index;
1311 struct gsm_settings *set = &ms->settings;
1313 set->imei_random = atoi(argv[0]);
1315 vty_restart(vty, ms);
1319 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1320 "Use special IMSI for emergency calls\n15 digits IMSI")
1322 struct osmocom_ms *ms = vty->index;
1323 struct gsm_settings *set = &ms->settings;
1326 error = gsm_check_imsi(argv[0]);
1328 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1331 strcpy(set->emergency_imsi, argv[0]);
1336 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1337 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1339 struct osmocom_ms *ms = vty->index;
1340 struct gsm_settings *set = &ms->settings;
1342 set->emergency_imsi[0] = '\0';
1347 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1348 NO_STR "Disallow waiting calls")
1350 struct osmocom_ms *ms = vty->index;
1351 struct gsm_settings *set = &ms->settings;
1358 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1359 "Allow waiting calls")
1361 struct osmocom_ms *ms = vty->index;
1362 struct gsm_settings *set = &ms->settings;
1369 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1370 NO_STR "Disable auto-answering calls")
1372 struct osmocom_ms *ms = vty->index;
1373 struct gsm_settings *set = &ms->settings;
1375 set->auto_answer = 0;
1380 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1381 "Enable auto-answering calls")
1383 struct osmocom_ms *ms = vty->index;
1384 struct gsm_settings *set = &ms->settings;
1386 set->auto_answer = 1;
1391 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1392 "Force caller ID presentation")
1394 struct osmocom_ms *ms = vty->index;
1395 struct gsm_settings *set = &ms->settings;
1403 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1404 "Force caller ID restriction")
1406 struct osmocom_ms *ms = vty->index;
1407 struct gsm_settings *set = &ms->settings;
1415 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1416 NO_STR "Disable forcing of caller ID presentation")
1418 struct osmocom_ms *ms = vty->index;
1419 struct gsm_settings *set = &ms->settings;
1426 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1427 NO_STR "Disable forcing of caller ID restriction")
1429 struct osmocom_ms *ms = vty->index;
1430 struct gsm_settings *set = &ms->settings;
1437 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1438 "Set the way to choose transmit power\nControlled by BTS\n"
1439 "Always full power\nFixed GSM power value if supported")
1441 struct osmocom_ms *ms = vty->index;
1442 struct gsm_settings *set = &ms->settings;
1444 switch (argv[0][0]) {
1446 set->alter_tx_power = 0;
1449 set->alter_tx_power = 1;
1450 set->alter_tx_power_value = 0;
1457 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1458 "Set the way to choose transmit power\n"
1459 "Fixed GSM power value if supported")
1461 struct osmocom_ms *ms = vty->index;
1462 struct gsm_settings *set = &ms->settings;
1464 set->alter_tx_power = 1;
1465 set->alter_tx_power_value = atoi(argv[0]);
1470 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1471 "Simulate a lower or higher distance from the BTS\n"
1472 "Delay in half bits (distance in 553.85 meter steps)")
1474 struct osmocom_ms *ms = vty->index;
1475 struct gsm_settings *set = &ms->settings;
1477 set->alter_delay = atoi(argv[0]);
1478 gsm48_rr_alter_delay(ms);
1483 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1484 NO_STR "Do not simulate a lower or higher distance from the BTS")
1486 struct osmocom_ms *ms = vty->index;
1487 struct gsm_settings *set = &ms->settings;
1489 set->alter_delay = 0;
1490 gsm48_rr_alter_delay(ms);
1495 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1496 "Stick to the given cell\nARFCN of the cell to stick to")
1498 struct osmocom_ms *ms = vty->index;
1499 struct gsm_settings *set = &ms->settings;
1502 set->stick_arfcn = atoi(argv[0]);
1507 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1508 NO_STR "Do not stick to any cell")
1510 struct osmocom_ms *ms = vty->index;
1511 struct gsm_settings *set = &ms->settings;
1518 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1519 "Allow location updating")
1521 struct osmocom_ms *ms = vty->index;
1522 struct gsm_settings *set = &ms->settings;
1529 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1530 NO_STR "Do not allow location updating")
1532 struct osmocom_ms *ms = vty->index;
1533 struct gsm_settings *set = &ms->settings;
1540 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1541 "Enable codec\nFull speed speech codec")
1543 struct osmocom_ms *ms = vty->index;
1544 struct gsm_settings *set = &ms->settings;
1546 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1547 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1554 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1556 "Enable codec\nFull speed speech codec\nPrefer this codec")
1558 struct osmocom_ms *ms = vty->index;
1559 struct gsm_settings *set = &ms->settings;
1561 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1562 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1566 set->half_prefer = 0;
1571 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1572 "Enable codec\nHalf speed speech codec")
1574 struct osmocom_ms *ms = vty->index;
1575 struct gsm_settings *set = &ms->settings;
1577 if (!set->half_v1 && !set->half_v3) {
1578 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1587 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1589 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1591 struct osmocom_ms *ms = vty->index;
1592 struct gsm_settings *set = &ms->settings;
1594 if (!set->half_v1 && !set->half_v3) {
1595 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1600 set->half_prefer = 1;
1605 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1606 NO_STR "Disable codec\nHalf speed speech codec")
1608 struct osmocom_ms *ms = vty->index;
1609 struct gsm_settings *set = &ms->settings;
1611 if (!set->half_v1 && !set->half_v3) {
1612 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1617 set->half_prefer = 0;
1622 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [name]",
1623 "Store given abbreviation number\n1-3 digits abbreviation\n"
1624 "Number to store for the abbreviation "
1625 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1626 "Name of the abbreviation")
1628 struct osmocom_ms *ms = vty->index;
1629 struct gsm_settings *set = &ms->settings;
1630 struct gsm_settings_abbrev *abbrev;
1633 llist_for_each_entry(abbrev, &set->abbrev, list) {
1634 if (!strcmp(argv[0], abbrev->abbrev)) {
1635 vty_out(vty, "Given abbreviation '%s' already stored, "
1636 "delete first!%s", argv[0], VTY_NEWLINE);
1641 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1642 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1646 for (i = 0; i < strlen(argv[0]); i++) {
1647 if (argv[0][i] < '0' || argv[0][i] > '9') {
1648 vty_out(vty, "Given abbreviation must have digits "
1649 "0..9 only!%s", VTY_NEWLINE);
1654 if (vty_check_number(vty, argv[1]))
1657 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1659 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1662 llist_add_tail(&abbrev->list, &set->abbrev);
1663 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1664 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1666 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1671 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [abbreviation]",
1672 NO_STR "Remove given abbreviation number or all numbers\n"
1673 "Abbreviation number to remove")
1675 struct osmocom_ms *ms = vty->index;
1676 struct gsm_settings *set = &ms->settings;
1677 struct gsm_settings_abbrev *abbrev, *abbrev2;
1678 uint8_t deleted = 0;
1680 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1681 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1682 llist_del(&abbrev->list);
1687 if (argc >= 1 && !deleted) {
1688 vty_out(vty, "Given abbreviation '%s' not found!%s",
1689 argv[0], VTY_NEWLINE);
1696 static int config_write_dummy(struct vty *vty)
1701 /* per support config */
1702 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1703 "Define supported features")
1705 vty->node = SUPPORT_NODE;
1710 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1711 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1713 struct osmocom_ms *ms = vty->index; \
1714 struct gsm_settings *set = &ms->settings; \
1715 struct gsm_support *sup = &ms->support; \
1717 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1719 return CMD_SUCCESS; \
1720 return CMD_WARNING; \
1723 vty_restart(vty, ms); \
1725 return CMD_SUCCESS; \
1728 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1729 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1731 struct osmocom_ms *ms = vty->index; \
1732 struct gsm_settings *set = &ms->settings; \
1733 struct gsm_support *sup = &ms->support; \
1735 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1737 return CMD_SUCCESS; \
1738 return CMD_WARNING; \
1741 vty_restart(vty, ms); \
1743 return CMD_SUCCESS; \
1746 #define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1747 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1749 struct osmocom_ms *ms = vty->index; \
1750 struct gsm_settings *set = &ms->settings; \
1752 vty_restart(vty, ms); \
1754 return CMD_SUCCESS; \
1757 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1758 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1760 struct osmocom_ms *ms = vty->index; \
1761 struct gsm_settings *set = &ms->settings; \
1763 vty_restart(vty, ms); \
1765 return CMD_SUCCESS; \
1768 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1769 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1770 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1771 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1772 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1773 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1774 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1775 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1776 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1777 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1778 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1779 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1780 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1781 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1782 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1783 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1784 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1785 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1786 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1788 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1790 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1792 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1794 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1796 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1798 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1799 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1801 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1802 "Select power class for GSM 850/900\n"
1809 struct osmocom_ms *ms = vty->index;
1810 struct gsm_settings *set = &ms->settings;
1811 struct gsm_support *sup = &ms->support;
1813 set->class_900 = atoi(argv[0]);
1815 if (set->class_900 < sup->class_900 && !vty_reading)
1816 vty_out(vty, "You selected an higher class than supported "
1817 " by hardware!%s", VTY_NEWLINE);
1822 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1823 "Select power class for DCS 1800\n"
1828 struct osmocom_ms *ms = vty->index;
1829 struct gsm_settings *set = &ms->settings;
1830 struct gsm_support *sup = &ms->support;
1832 set->class_dcs = atoi(argv[0]);
1834 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1836 vty_out(vty, "You selected an higher class than supported "
1837 " by hardware!%s", VTY_NEWLINE);
1842 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1843 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1844 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1846 struct osmocom_ms *ms = vty->index;
1847 struct gsm_settings *set = &ms->settings;
1848 struct gsm_support *sup = &ms->support;
1851 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
1852 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
1853 else if (!strcmp(argv[0], "sdcch+tchf"))
1854 ch_cap = GSM_CAP_SDCCH_TCHF;
1856 ch_cap = GSM_CAP_SDCCH;
1858 if (ch_cap > sup->ch_cap && !vty_reading) {
1859 vty_out(vty, "You selected an higher capability than supported "
1860 " by hardware!%s", VTY_NEWLINE);
1864 if (ch_cap != set->ch_cap
1865 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
1866 vty_restart(vty, ms);
1868 set->ch_cap = ch_cap;
1873 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
1874 "Full rate speech V1", 0);
1875 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
1876 "full-speech-v1", "Full rate speech V1", 0);
1877 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
1878 "Full rate speech V2 (EFR)", 0);
1879 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
1880 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
1881 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
1882 "Full rate speech V3 (AMR)", 0);
1883 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
1884 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
1885 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
1886 "Half rate speech V1", 0);
1887 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
1888 "half-speech-v1", "Half rate speech V1", 0);
1889 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
1890 "Half rate speech V3 (AMR)", 0);
1891 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
1892 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
1894 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
1895 "Set the minimum receive level to select a cell\n"
1896 "Minimum receive level from -110 dBm to -47 dBm")
1898 struct osmocom_ms *ms = vty->index;
1899 struct gsm_settings *set = &ms->settings;
1901 set->min_rxlev_db = atoi(argv[0]);
1906 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
1907 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
1908 "more reliable against bad RX signal. This increase the propability "
1909 "of missing a paging requests\n"
1910 "DSC initial and maximum value (standard is 90)")
1912 struct osmocom_ms *ms = vty->index;
1913 struct gsm_settings *set = &ms->settings;
1915 set->dsc_max = atoi(argv[0]);
1920 /* per testsim config */
1921 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1922 "Configure test SIM emulation")
1924 vty->node = TESTSIM_NODE;
1929 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1930 "Set IMSI on test card\n15 digits IMSI")
1932 struct osmocom_ms *ms = vty->index;
1933 struct gsm_settings *set = &ms->settings;
1934 char *error = gsm_check_imsi(argv[0]);
1937 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1941 strcpy(set->test_imsi, argv[0]);
1943 vty_restart(vty, ms);
1947 #define HEX_STR "\nByte as two digits hexadecimal"
1948 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1949 "HEX HEX HEX HEX HEX HEX",
1950 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1951 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
1953 struct osmocom_ms *ms = vty->index;
1954 struct gsm_settings *set = &ms->settings;
1959 for (i = 0; i < 12; i++) {
1961 if (!strncmp(p, "0x", 2))
1963 if (strlen(p) != 2) {
1964 vty_out(vty, "Expecting two digits hex value (with or "
1965 "without 0x in front)%s", VTY_NEWLINE);
1968 ki[i] = strtoul(p, NULL, 16);
1971 set->test_ki_type = GSM_SIM_KEY_XOR;
1972 memcpy(set->test_ki, ki, 12);
1976 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
1977 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
1978 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1979 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
1980 HEX_STR HEX_STR HEX_STR HEX_STR)
1982 struct osmocom_ms *ms = vty->index;
1983 struct gsm_settings *set = &ms->settings;
1988 for (i = 0; i < 16; i++) {
1990 if (!strncmp(p, "0x", 2))
1992 if (strlen(p) != 2) {
1993 vty_out(vty, "Expecting two digits hex value (with or "
1994 "without 0x in front)%s", VTY_NEWLINE);
1997 ki[i] = strtoul(p, NULL, 16);
2000 set->test_ki_type = GSM_SIM_KEY_COMP128;
2001 memcpy(set->test_ki, ki, 16);
2005 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
2006 "Allow access to barred cells")
2008 struct osmocom_ms *ms = vty->index;
2009 struct gsm_settings *set = &ms->settings;
2016 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2017 NO_STR "Deny access to barred cells")
2019 struct osmocom_ms *ms = vty->index;
2020 struct gsm_settings *set = &ms->settings;
2027 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2028 NO_STR "Unset Registered PLMN")
2030 struct osmocom_ms *ms = vty->index;
2031 struct gsm_settings *set = &ms->settings;
2033 set->test_rplmn_valid = 0;
2035 vty_restart(vty, ms);
2039 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [lac] [tmsi]",
2040 "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
2041 "Optionally set locatio area code\n"
2042 "Optionally set current assigned TMSI")
2044 struct osmocom_ms *ms = vty->index;
2045 struct gsm_settings *set = &ms->settings;
2046 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2047 mnc = gsm_input_mnc((char *)argv[1]);
2050 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2054 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2057 set->test_rplmn_valid = 1;
2058 set->test_rplmn_mcc = mcc;
2059 set->test_rplmn_mnc = mnc;
2062 set->test_lac = strtoul(argv[2], NULL, 16);
2064 set->test_lac = 0xfffe;
2067 set->test_tmsi = strtoul(argv[3], NULL, 16);
2069 set->test_tmsi = 0xffffffff;
2071 vty_restart(vty, ms);
2075 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2076 "Set Home PLMN search mode\n"
2077 "Search for HPLMN when on any other network\n"
2078 "Search for HPLMN when in a different country")
2080 struct osmocom_ms *ms = vty->index;
2081 struct gsm_settings *set = &ms->settings;
2083 switch (argv[0][0]) {
2085 set->test_always = 1;
2088 set->test_always = 0;
2092 vty_restart(vty, ms);
2096 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2097 NO_STR "Activate and run MS")
2099 struct osmocom_ms *ms = vty->index, *tmp;
2102 if (ms->shutdown != 2)
2105 llist_for_each_entry(tmp, &ms_list, entity) {
2106 if (tmp->shutdown == 2)
2108 if (!strcmp(ms->settings.layer2_socket_path,
2109 tmp->settings.layer2_socket_path)) {
2110 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2111 "use the same layer2-socket.%sPlease shutdown "
2112 "MS '%s' first.%s", ms->name, tmp->name,
2113 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2116 if (!strcmp(ms->settings.sap_socket_path,
2117 tmp->settings.sap_socket_path)) {
2118 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2119 "use the same sap-socket.%sPlease shutdown "
2120 "MS '%s' first.%s", ms->name, tmp->name,
2121 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2126 rc = mobile_init(ms);
2128 vty_out(vty, "Connection to layer 1 failed!%s",
2136 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2137 "Shut down and deactivate MS")
2139 struct osmocom_ms *ms = vty->index;
2141 if (ms->shutdown == 0)
2147 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2148 "Shut down and deactivate MS\nDo not perform IMSI detach")
2150 struct osmocom_ms *ms = vty->index;
2152 if (ms->shutdown <= 1)
2158 enum node_type ms_vty_go_parent(struct vty *vty)
2160 switch (vty->node) {
2162 vty->node = CONFIG_NODE;
2167 vty->node = MS_NODE;
2170 vty->node = CONFIG_NODE;
2176 /* Down vty node level. */
2177 gDEFUN(ournode_exit,
2178 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2180 switch (vty->node) {
2182 vty->node = CONFIG_NODE;
2187 vty->node = MS_NODE;
2195 /* End of configuration. */
2197 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2199 switch (vty->node) {
2202 /* Nothing to do. */
2209 vty_config_unlock(vty);
2210 vty->node = ENABLE_NODE;
2212 vty->index_sub = NULL;
2220 DEFUN(off, off_cmd, "off",
2221 "Turn mobiles off (shutdown) and exit")
2223 dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2228 #define SUP_NODE(item) \
2229 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2231 int ms_vty_init(void)
2233 install_element_ve(&show_ms_cmd);
2234 install_element_ve(&show_subscr_cmd);
2235 install_element_ve(&show_support_cmd);
2236 install_element_ve(&show_cell_cmd);
2237 install_element_ve(&show_cell_si_cmd);
2238 install_element_ve(&show_ba_cmd);
2239 install_element_ve(&show_forb_la_cmd);
2240 install_element_ve(&show_forb_plmn_cmd);
2241 install_element_ve(&monitor_network_cmd);
2242 install_element_ve(&no_monitor_network_cmd);
2243 install_element(ENABLE_NODE, &off_cmd);
2245 install_element(ENABLE_NODE, &sim_test_cmd);
2246 install_element(ENABLE_NODE, &sim_reader_cmd);
2247 install_element(ENABLE_NODE, &sim_remove_cmd);
2248 install_element(ENABLE_NODE, &sim_pin_cmd);
2249 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2250 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2251 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2252 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2253 install_element(ENABLE_NODE, &sim_lai_cmd);
2254 install_element(ENABLE_NODE, &network_search_cmd);
2255 install_element(ENABLE_NODE, &network_show_cmd);
2256 install_element(ENABLE_NODE, &network_select_cmd);
2257 install_element(ENABLE_NODE, &call_cmd);
2258 install_element(ENABLE_NODE, &call_retr_cmd);
2259 install_element(ENABLE_NODE, &call_dtmf_cmd);
2261 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2262 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2263 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2264 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2266 install_element(CONFIG_NODE, &cfg_ms_cmd);
2267 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2268 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2269 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2270 install_element(CONFIG_NODE, &ournode_end_cmd);
2271 install_node(&ms_node, config_write_ms);
2272 install_default(MS_NODE);
2273 install_element(MS_NODE, &ournode_exit_cmd);
2274 install_element(MS_NODE, &ournode_end_cmd);
2275 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2276 install_element(MS_NODE, &cfg_ms_sap_cmd);
2277 install_element(MS_NODE, &cfg_ms_sim_cmd);
2278 install_element(MS_NODE, &cfg_ms_mode_cmd);
2279 install_element(MS_NODE, &cfg_ms_imei_cmd);
2280 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2281 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2282 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2283 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2284 install_element(MS_NODE, &cfg_ms_cw_cmd);
2285 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2286 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2287 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2288 install_element(MS_NODE, &cfg_ms_clip_cmd);
2289 install_element(MS_NODE, &cfg_ms_clir_cmd);
2290 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2291 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2292 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2293 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2294 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2295 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2296 install_element(MS_NODE, &cfg_ms_stick_cmd);
2297 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2298 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2299 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2300 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2301 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2302 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2303 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2304 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2305 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2306 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2307 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2308 install_element(MS_NODE, &cfg_ms_support_cmd);
2309 install_node(&support_node, config_write_dummy);
2310 install_default(SUPPORT_NODE);
2311 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2312 install_element(SUPPORT_NODE, &ournode_end_cmd);
2313 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2314 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2315 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2316 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2317 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2318 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2319 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2320 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2321 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2322 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2323 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2324 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2325 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2326 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2327 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2328 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2329 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2330 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2331 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2332 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2333 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2334 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2335 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2336 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2337 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2338 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2339 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2340 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2341 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2342 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2343 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2344 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2345 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2346 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2347 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2348 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2349 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2350 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2351 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2352 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2353 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2354 install_node(&testsim_node, config_write_dummy);
2355 install_default(TESTSIM_NODE);
2356 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2357 install_element(TESTSIM_NODE, &ournode_end_cmd);
2358 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2359 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2360 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2361 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2362 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2363 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2364 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2365 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2366 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2367 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2368 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2373 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2375 struct telnet_connection *connection;
2381 va_start(args, fmt);
2382 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2383 buffer[sizeof(buffer) - 1] = '\0';
2390 llist_for_each_entry(connection, &active_connections, entry) {
2391 vty = connection->vty;
2395 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2399 if (buffer[strlen(buffer) - 1] == '\n') {
2400 buffer[strlen(buffer) - 1] = '\0';
2401 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2402 buffer[strlen(buffer)] = '\n';
2404 vty_out(vty, "%% %s", buffer);