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]",
428 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
429 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN")
431 struct osmocom_ms *ms;
432 uint16_t mcc = 0x001, mnc = 0x01f;
434 ms = get_ms(argv[0], vty);
438 if (ms->subscr.sim_valid) {
439 vty_out(vty, "SIM already presend, remove first!%s",
445 mcc = gsm_input_mcc((char *)argv[1]);
446 mnc = gsm_input_mnc((char *)argv[2]);
448 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
452 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
457 gsm_subscr_testcard(ms, mcc, mnc);
462 DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
463 "SIM actions\nSelect SIM from reader\nName of MS (see \"show ms\")")
465 struct osmocom_ms *ms;
467 ms = get_ms(argv[0], vty);
471 if (ms->subscr.sim_valid) {
472 vty_out(vty, "SIM already presend, remove first!%s",
477 gsm_subscr_simcard(ms);
482 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
483 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
485 struct osmocom_ms *ms;
487 ms = get_ms(argv[0], vty);
491 if (!ms->subscr.sim_valid) {
492 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
496 gsm_subscr_remove(ms);
501 DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
502 "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
505 struct osmocom_ms *ms;
507 ms = get_ms(argv[0], vty);
511 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
512 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
516 if (!ms->subscr.sim_pin_required) {
517 vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
521 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
526 DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
527 "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
530 struct osmocom_ms *ms;
532 ms = get_ms(argv[0], vty);
536 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
537 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
541 gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
546 DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
547 "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
550 struct osmocom_ms *ms;
552 ms = get_ms(argv[0], vty);
556 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
557 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
561 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
566 DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
567 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
568 "Old PIN number\nNew PIN number")
570 struct osmocom_ms *ms;
572 ms = get_ms(argv[0], vty);
576 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
577 vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
580 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
581 vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
585 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
590 DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
591 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
592 "Personal Unblock Key\nNew PIN number")
594 struct osmocom_ms *ms;
596 ms = get_ms(argv[0], vty);
600 if (strlen(argv[1]) != 8) {
601 vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
604 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
605 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
609 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
614 DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
615 "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
616 "Mobile Country Code\nMobile Network Code\nLocation Area Code "
617 " (use 0000 to remove LAI)")
619 struct osmocom_ms *ms;
620 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
621 mnc = gsm_input_mnc((char *)argv[2]),
622 lac = strtoul(argv[3], NULL, 16);
624 ms = get_ms(argv[0], vty);
629 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
633 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
637 ms->subscr.mcc = mcc;
638 ms->subscr.mnc = mnc;
639 ms->subscr.lac = lac;
640 ms->subscr.tmsi = 0xffffffff;
642 gsm_subscr_write_loci(ms);
647 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
648 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
649 "Mobile Country Code\nMobile Network Code")
651 struct osmocom_ms *ms;
652 struct gsm322_plmn *plmn;
654 struct gsm322_msg *ngm;
655 struct gsm322_plmn_list *temp;
656 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
657 mnc = gsm_input_mnc((char *)argv[2]);
660 ms = get_ms(argv[0], vty);
666 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
670 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
674 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
675 if (temp->mcc == mcc && temp->mnc == mnc)
678 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
682 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
685 ngm = (struct gsm322_msg *) nmsg->data;
688 gsm322_plmn_sendmsg(ms, nmsg);
693 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
694 "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
695 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
696 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
697 "Hold current active call\n")
699 struct osmocom_ms *ms;
700 struct gsm_settings *set;
701 struct gsm_settings_abbrev *abbrev;
704 ms = get_ms(argv[0], vty);
709 if (set->ch_cap == GSM_CAP_SDCCH) {
710 vty_out(vty, "Basic call is not supported for SDCCH only "
711 "mobile%s", VTY_NEWLINE);
715 number = (char *)argv[1];
716 if (!strcmp(number, "emergency"))
717 mncc_call(ms, number);
718 else if (!strcmp(number, "answer"))
720 else if (!strcmp(number, "hangup"))
722 else if (!strcmp(number, "hold"))
725 llist_for_each_entry(abbrev, &set->abbrev, list) {
726 if (!strcmp(number, abbrev->abbrev)) {
727 number = abbrev->number;
728 vty_out(vty, "Dialing number '%s'%s", number,
733 if (vty_check_number(vty, number))
735 mncc_call(ms, number);
741 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [number]",
742 "Make a call\nName of MS (see \"show ms\")\n"
743 "Retrieve call on hold\nNumber of call to retrieve")
745 struct osmocom_ms *ms;
747 ms = get_ms(argv[0], vty);
751 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
756 DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
757 "Make a call\nName of MS (see \"show ms\")\n"
758 "One or more DTMF digits to transmit")
760 struct osmocom_ms *ms;
761 struct gsm_settings *set;
763 ms = get_ms(argv[0], vty);
769 vty_out(vty, "DTMF not supported, please enable!%s",
774 mncc_dtmf(ms, (char *)argv[1]);
779 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
780 "Network ...\nShow results of network search (again)\n"
781 "Name of MS (see \"show ms\")")
783 struct osmocom_ms *ms;
784 struct gsm_settings *set;
785 struct gsm322_plmn *plmn;
786 struct gsm322_plmn_list *temp;
788 ms = get_ms(argv[0], vty);
794 if (set->plmn_mode != PLMN_MODE_AUTO
795 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
796 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
800 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
801 vty_out(vty, " Network %s, %s (%s, %s)%s",
802 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
803 gsm_get_mcc(temp->mcc),
804 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
809 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
810 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
812 struct osmocom_ms *ms;
815 ms = get_ms(argv[0], vty);
819 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
822 gsm322_plmn_sendmsg(ms, nmsg);
827 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
832 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
840 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
841 NO_STR "Disable GPS receiver")
850 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
851 "GPS receiver\nSelect serial device\n"
852 "Full path of serial device including /dev/")
854 strncpy(gps.device, argv[0], sizeof(gps.device));
855 gps.device[sizeof(gps.device) - 1] = '\0';
859 vty_out(vty, "Failed to open GPS device!%s",
868 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
869 "(default|4800|""9600|19200|38400|57600|115200)",
870 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
872 if (argv[0][0] == 'd')
875 gps.baud = atoi(argv[0]);
880 vty_out(vty, "Failed to open GPS device!%s",
890 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
891 "Select a mobile station to configure\nName of MS (see \"show ms\")")
893 struct osmocom_ms *ms;
896 llist_for_each_entry(ms, &ms_list, entity) {
897 if (!strcmp(ms->name, argv[0])) {
905 vty_out(vty, "MS name '%s' does not exits, try "
906 "'ms %s create'%s", argv[0], argv[0],
910 ms = mobile_new((char *)argv[0]);
912 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
924 DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
925 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
926 "Create if MS does not exists")
928 struct osmocom_ms *ms;
931 llist_for_each_entry(ms, &ms_list, entity) {
932 if (!strcmp(ms->name, argv[0])) {
939 ms = mobile_new((char *)argv[0]);
941 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
950 vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
951 argv[0], VTY_NEWLINE);
955 DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
956 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
957 "Rename MS\nNew name of MS")
959 struct osmocom_ms *ms;
962 llist_for_each_entry(ms, &ms_list, entity) {
963 if (!strcmp(ms->name, argv[0])) {
970 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
975 strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
980 DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
981 NO_STR "Select a mobile station to remove\n"
982 "Name of MS (see \"show ms\")")
984 struct osmocom_ms *ms;
987 llist_for_each_entry(ms, &ms_list, entity) {
988 if (!strcmp(ms->name, argv[0])) {
995 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1000 mobile_delete(ms, 1);
1005 #define SUP_WRITE(item, cmd) \
1007 vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
1010 static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
1012 struct gsm_settings *set = &ms->settings;
1013 struct gsm_support *sup = &ms->support;
1014 struct gsm_settings_abbrev *abbrev;
1016 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
1017 vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
1019 vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
1020 switch(set->sim_type) {
1021 case GSM_SIM_TYPE_NONE:
1022 vty_out(vty, " sim none%s", VTY_NEWLINE);
1024 case GSM_SIM_TYPE_READER:
1025 vty_out(vty, " sim reader%s", VTY_NEWLINE);
1027 case GSM_SIM_TYPE_TEST:
1028 vty_out(vty, " sim test%s", VTY_NEWLINE);
1031 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
1032 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
1033 vty_out(vty, " imei %s %s%s", set->imei,
1034 set->imeisv + strlen(set->imei), VTY_NEWLINE);
1035 if (set->imei_random)
1036 vty_out(vty, " imei-random %d%s", set->imei_random,
1039 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
1040 if (set->emergency_imsi[0])
1041 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
1044 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
1045 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
1046 vty_out(vty, " %sauto-answer%s", (set->auto_answer) ? "" : "no ",
1048 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
1049 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
1050 if (set->alter_tx_power)
1051 if (set->alter_tx_power_value)
1052 vty_out(vty, " tx-power %d%s",
1053 set->alter_tx_power_value, VTY_NEWLINE);
1055 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
1057 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
1058 if (set->alter_delay)
1059 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
1062 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
1064 vty_out(vty, " stick %d%s", set->stick_arfcn,
1067 vty_out(vty, " no stick%s", VTY_NEWLINE);
1069 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
1071 vty_out(vty, " location-updating%s", VTY_NEWLINE);
1072 if (set->full_v1 || set->full_v2 || set->full_v3) {
1073 /* mandatory anyway */
1074 vty_out(vty, " codec full-speed%s%s",
1075 (!set->half_prefer) ? " prefer" : "",
1078 if (set->half_v1 || set->half_v3) {
1080 vty_out(vty, " codec half-speed%s%s",
1081 (set->half_prefer) ? " prefer" : "",
1084 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
1086 if (llist_empty(&set->abbrev))
1087 vty_out(vty, " no abbrev%s", VTY_NEWLINE);
1089 llist_for_each_entry(abbrev, &set->abbrev, list)
1090 vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
1091 abbrev->number, (abbrev->name[0]) ? " " : "",
1092 abbrev->name, VTY_NEWLINE);
1094 vty_out(vty, " support%s", VTY_NEWLINE);
1095 SUP_WRITE(sms_ptp, "sms");
1096 SUP_WRITE(a5_1, "a5/1");
1097 SUP_WRITE(a5_2, "a5/2");
1098 SUP_WRITE(a5_3, "a5/3");
1099 SUP_WRITE(a5_4, "a5/4");
1100 SUP_WRITE(a5_5, "a5/5");
1101 SUP_WRITE(a5_6, "a5/6");
1102 SUP_WRITE(a5_7, "a5/7");
1103 SUP_WRITE(p_gsm, "p-gsm");
1104 SUP_WRITE(e_gsm, "e-gsm");
1105 SUP_WRITE(r_gsm, "r-gsm");
1106 SUP_WRITE(dcs, "dcs");
1107 vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
1108 vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
1109 switch (set->ch_cap) {
1111 vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
1113 case GSM_CAP_SDCCH_TCHF:
1114 vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
1116 case GSM_CAP_SDCCH_TCHF_TCHH:
1117 vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
1121 SUP_WRITE(full_v1, "full-speech-v1");
1122 SUP_WRITE(full_v2, "full-speech-v2");
1123 SUP_WRITE(full_v3, "full-speech-v3");
1124 SUP_WRITE(half_v1, "half-speech-v1");
1125 SUP_WRITE(half_v3, "half-speech-v3");
1126 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
1127 vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
1128 vty_out(vty, " exit%s", VTY_NEWLINE);
1129 vty_out(vty, " test-sim%s", VTY_NEWLINE);
1130 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
1131 switch (set->test_ki_type) {
1132 case GSM_SIM_KEY_XOR:
1133 vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
1136 case GSM_SIM_KEY_COMP128:
1137 vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
1141 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
1143 if (set->test_rplmn_valid)
1144 vty_out(vty, " rplmn %s %s%s",
1145 gsm_print_mcc(set->test_rplmn_mcc),
1146 gsm_print_mnc(set->test_rplmn_mnc),
1149 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
1150 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
1151 : "foreign-country", VTY_NEWLINE);
1152 vty_out(vty, " exit%s", VTY_NEWLINE);
1153 vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
1155 vty_out(vty, "exit%s", VTY_NEWLINE);
1156 vty_out(vty, "!%s", VTY_NEWLINE);
1159 static int config_write_ms(struct vty *vty)
1161 struct osmocom_ms *ms;
1163 vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
1165 vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
1167 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
1168 vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
1169 vty_out(vty, "!%s", VTY_NEWLINE);
1171 llist_for_each_entry(ms, &ms_list, entity)
1172 config_write_ms_single(vty, ms);
1177 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1178 "Define socket path to connect between layer 2 and layer 1\n"
1179 "Unix socket, default '/tmp/osmocom_l2'")
1181 struct osmocom_ms *ms = vty->index;
1182 struct gsm_settings *set = &ms->settings;
1184 strncpy(set->layer2_socket_path, argv[0],
1185 sizeof(set->layer2_socket_path) - 1);
1187 vty_restart(vty, ms);
1191 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1192 "Define socket path to connect to SIM reader\n"
1193 "Unix socket, default '/tmp/osmocom_sap'")
1195 struct osmocom_ms *ms = vty->index;
1196 struct gsm_settings *set = &ms->settings;
1198 strncpy(set->sap_socket_path, argv[0],
1199 sizeof(set->sap_socket_path) - 1);
1201 vty_restart(vty, ms);
1205 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1206 "Set SIM card type when powering on\nNo SIM interted\n"
1207 "Use SIM from reader\nTest SIM inserted")
1209 struct osmocom_ms *ms = vty->index;
1210 struct gsm_settings *set = &ms->settings;
1212 switch (argv[0][0]) {
1214 set->sim_type = GSM_SIM_TYPE_NONE;
1217 set->sim_type = GSM_SIM_TYPE_READER;
1220 set->sim_type = GSM_SIM_TYPE_TEST;
1223 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1227 vty_restart(vty, ms);
1231 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1232 "Set network selection mode\nAutomatic network selection\n"
1233 "Manual network selection")
1235 struct osmocom_ms *ms = vty->index;
1236 struct gsm_settings *set = &ms->settings;
1239 if (!ms->plmn.state) {
1240 if (argv[0][0] == 'a')
1241 set->plmn_mode = PLMN_MODE_AUTO;
1243 set->plmn_mode = PLMN_MODE_MANUAL;
1247 if (argv[0][0] == 'a')
1248 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1250 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1253 gsm322_plmn_sendmsg(ms, nmsg);
1258 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1259 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1260 "Software version digit")
1262 struct osmocom_ms *ms = vty->index;
1263 struct gsm_settings *set = &ms->settings;
1264 char *error, *sv = "0";
1267 sv = (char *)argv[1];
1269 error = gsm_check_imei(argv[0], sv);
1271 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1275 strcpy(set->imei, argv[0]);
1276 strcpy(set->imeisv, argv[0]);
1277 strcpy(set->imeisv + 15, sv);
1282 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1283 "Use fixed IMEI on every power on")
1285 struct osmocom_ms *ms = vty->index;
1286 struct gsm_settings *set = &ms->settings;
1288 set->imei_random = 0;
1290 vty_restart(vty, ms);
1294 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1295 "Use random IMEI on every power on\n"
1296 "Number of trailing digits to randomize")
1298 struct osmocom_ms *ms = vty->index;
1299 struct gsm_settings *set = &ms->settings;
1301 set->imei_random = atoi(argv[0]);
1303 vty_restart(vty, ms);
1307 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1308 "Use special IMSI for emergency calls\n15 digits IMSI")
1310 struct osmocom_ms *ms = vty->index;
1311 struct gsm_settings *set = &ms->settings;
1314 error = gsm_check_imsi(argv[0]);
1316 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1319 strcpy(set->emergency_imsi, argv[0]);
1324 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1325 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1327 struct osmocom_ms *ms = vty->index;
1328 struct gsm_settings *set = &ms->settings;
1330 set->emergency_imsi[0] = '\0';
1335 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1336 NO_STR "Disallow waiting calls")
1338 struct osmocom_ms *ms = vty->index;
1339 struct gsm_settings *set = &ms->settings;
1346 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1347 "Allow waiting calls")
1349 struct osmocom_ms *ms = vty->index;
1350 struct gsm_settings *set = &ms->settings;
1357 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1358 NO_STR "Disable auto-answering calls")
1360 struct osmocom_ms *ms = vty->index;
1361 struct gsm_settings *set = &ms->settings;
1363 set->auto_answer = 0;
1368 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1369 "Enable auto-answering calls")
1371 struct osmocom_ms *ms = vty->index;
1372 struct gsm_settings *set = &ms->settings;
1374 set->auto_answer = 1;
1379 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1380 "Force caller ID presentation")
1382 struct osmocom_ms *ms = vty->index;
1383 struct gsm_settings *set = &ms->settings;
1391 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1392 "Force caller ID restriction")
1394 struct osmocom_ms *ms = vty->index;
1395 struct gsm_settings *set = &ms->settings;
1403 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1404 NO_STR "Disable forcing of caller ID presentation")
1406 struct osmocom_ms *ms = vty->index;
1407 struct gsm_settings *set = &ms->settings;
1414 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1415 NO_STR "Disable forcing of caller ID restriction")
1417 struct osmocom_ms *ms = vty->index;
1418 struct gsm_settings *set = &ms->settings;
1425 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1426 "Set the way to choose transmit power\nControlled by BTS\n"
1427 "Always full power\nFixed GSM power value if supported")
1429 struct osmocom_ms *ms = vty->index;
1430 struct gsm_settings *set = &ms->settings;
1432 switch (argv[0][0]) {
1434 set->alter_tx_power = 0;
1437 set->alter_tx_power = 1;
1438 set->alter_tx_power_value = 0;
1445 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1446 "Set the way to choose transmit power\n"
1447 "Fixed GSM power value if supported")
1449 struct osmocom_ms *ms = vty->index;
1450 struct gsm_settings *set = &ms->settings;
1452 set->alter_tx_power = 1;
1453 set->alter_tx_power_value = atoi(argv[0]);
1458 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1459 "Simulate a lower or higher distance from the BTS\n"
1460 "Delay in half bits (distance in 553.85 meter steps)")
1462 struct osmocom_ms *ms = vty->index;
1463 struct gsm_settings *set = &ms->settings;
1465 set->alter_delay = atoi(argv[0]);
1466 gsm48_rr_alter_delay(ms);
1471 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1472 NO_STR "Do not simulate a lower or higher distance from the BTS")
1474 struct osmocom_ms *ms = vty->index;
1475 struct gsm_settings *set = &ms->settings;
1477 set->alter_delay = 0;
1478 gsm48_rr_alter_delay(ms);
1483 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1484 "Stick to the given cell\nARFCN of the cell to stick to")
1486 struct osmocom_ms *ms = vty->index;
1487 struct gsm_settings *set = &ms->settings;
1490 set->stick_arfcn = atoi(argv[0]);
1495 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1496 NO_STR "Do not stick to any cell")
1498 struct osmocom_ms *ms = vty->index;
1499 struct gsm_settings *set = &ms->settings;
1506 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1507 "Allow location updating")
1509 struct osmocom_ms *ms = vty->index;
1510 struct gsm_settings *set = &ms->settings;
1517 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1518 NO_STR "Do not allow location updating")
1520 struct osmocom_ms *ms = vty->index;
1521 struct gsm_settings *set = &ms->settings;
1528 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1529 "Enable codec\nFull speed speech codec")
1531 struct osmocom_ms *ms = vty->index;
1532 struct gsm_settings *set = &ms->settings;
1534 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1535 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1542 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1544 "Enable codec\nFull speed speech codec\nPrefer this codec")
1546 struct osmocom_ms *ms = vty->index;
1547 struct gsm_settings *set = &ms->settings;
1549 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1550 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1554 set->half_prefer = 0;
1559 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1560 "Enable codec\nHalf speed speech codec")
1562 struct osmocom_ms *ms = vty->index;
1563 struct gsm_settings *set = &ms->settings;
1565 if (!set->half_v1 && !set->half_v3) {
1566 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1575 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1577 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1579 struct osmocom_ms *ms = vty->index;
1580 struct gsm_settings *set = &ms->settings;
1582 if (!set->half_v1 && !set->half_v3) {
1583 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1588 set->half_prefer = 1;
1593 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1594 NO_STR "Disable codec\nHalf speed speech codec")
1596 struct osmocom_ms *ms = vty->index;
1597 struct gsm_settings *set = &ms->settings;
1599 if (!set->half_v1 && !set->half_v3) {
1600 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1605 set->half_prefer = 0;
1610 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [name]",
1611 "Store given abbreviation number\n1-3 digits abbreviation\n"
1612 "Number to store for the abbreviation "
1613 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1614 "Name of the abbreviation")
1616 struct osmocom_ms *ms = vty->index;
1617 struct gsm_settings *set = &ms->settings;
1618 struct gsm_settings_abbrev *abbrev;
1621 llist_for_each_entry(abbrev, &set->abbrev, list) {
1622 if (!strcmp(argv[0], abbrev->abbrev)) {
1623 vty_out(vty, "Given abbreviation '%s' already stored, "
1624 "delete first!%s", argv[0], VTY_NEWLINE);
1629 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1630 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1634 for (i = 0; i < strlen(argv[0]); i++) {
1635 if (argv[0][i] < '0' || argv[0][i] > '9') {
1636 vty_out(vty, "Given abbreviation must have digits "
1637 "0..9 only!%s", VTY_NEWLINE);
1642 if (vty_check_number(vty, argv[1]))
1645 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1647 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1650 llist_add_tail(&abbrev->list, &set->abbrev);
1651 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1652 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1654 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1659 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [abbreviation]",
1660 NO_STR "Remove given abbreviation number or all numbers\n"
1661 "Abbreviation number to remove")
1663 struct osmocom_ms *ms = vty->index;
1664 struct gsm_settings *set = &ms->settings;
1665 struct gsm_settings_abbrev *abbrev, *abbrev2;
1666 uint8_t deleted = 0;
1668 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1669 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1670 llist_del(&abbrev->list);
1675 if (argc >= 1 && !deleted) {
1676 vty_out(vty, "Given abbreviation '%s' not found!%s",
1677 argv[0], VTY_NEWLINE);
1684 static int config_write_dummy(struct vty *vty)
1689 /* per support config */
1690 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1691 "Define supported features")
1693 vty->node = SUPPORT_NODE;
1698 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1699 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1701 struct osmocom_ms *ms = vty->index; \
1702 struct gsm_settings *set = &ms->settings; \
1703 struct gsm_support *sup = &ms->support; \
1705 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1707 return CMD_SUCCESS; \
1708 return CMD_WARNING; \
1711 vty_restart(vty, ms); \
1713 return CMD_SUCCESS; \
1716 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1717 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1719 struct osmocom_ms *ms = vty->index; \
1720 struct gsm_settings *set = &ms->settings; \
1721 struct gsm_support *sup = &ms->support; \
1723 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1725 return CMD_SUCCESS; \
1726 return CMD_WARNING; \
1729 vty_restart(vty, ms); \
1731 return CMD_SUCCESS; \
1734 #define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1735 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1737 struct osmocom_ms *ms = vty->index; \
1738 struct gsm_settings *set = &ms->settings; \
1740 vty_restart(vty, ms); \
1742 return CMD_SUCCESS; \
1745 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1746 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1748 struct osmocom_ms *ms = vty->index; \
1749 struct gsm_settings *set = &ms->settings; \
1751 vty_restart(vty, ms); \
1753 return CMD_SUCCESS; \
1756 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1757 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
1758 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1759 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1760 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1761 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1762 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1763 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1764 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1765 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1766 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1767 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1768 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1769 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1770 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1771 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1772 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1773 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1774 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1776 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1778 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1780 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1782 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1784 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1786 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1787 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1789 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1790 "Select power class for GSM 850/900\n"
1797 struct osmocom_ms *ms = vty->index;
1798 struct gsm_settings *set = &ms->settings;
1799 struct gsm_support *sup = &ms->support;
1801 set->class_900 = atoi(argv[0]);
1803 if (set->class_900 < sup->class_900 && !vty_reading)
1804 vty_out(vty, "You selected an higher class than supported "
1805 " by hardware!%s", VTY_NEWLINE);
1810 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1811 "Select power class for DCS 1800\n"
1816 struct osmocom_ms *ms = vty->index;
1817 struct gsm_settings *set = &ms->settings;
1818 struct gsm_support *sup = &ms->support;
1820 set->class_dcs = atoi(argv[0]);
1822 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1824 vty_out(vty, "You selected an higher class than supported "
1825 " by hardware!%s", VTY_NEWLINE);
1830 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1831 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1832 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1834 struct osmocom_ms *ms = vty->index;
1835 struct gsm_settings *set = &ms->settings;
1836 struct gsm_support *sup = &ms->support;
1839 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
1840 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
1841 else if (!strcmp(argv[0], "sdcch+tchf"))
1842 ch_cap = GSM_CAP_SDCCH_TCHF;
1844 ch_cap = GSM_CAP_SDCCH;
1846 if (ch_cap > sup->ch_cap && !vty_reading) {
1847 vty_out(vty, "You selected an higher capability than supported "
1848 " by hardware!%s", VTY_NEWLINE);
1852 if (ch_cap != set->ch_cap
1853 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
1854 vty_restart(vty, ms);
1856 set->ch_cap = ch_cap;
1861 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
1862 "Full rate speech V1", 0);
1863 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
1864 "full-speech-v1", "Full rate speech V1", 0);
1865 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
1866 "Full rate speech V2 (EFR)", 0);
1867 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
1868 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
1869 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
1870 "Full rate speech V3 (AMR)", 0);
1871 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
1872 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
1873 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
1874 "Half rate speech V1", 0);
1875 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
1876 "half-speech-v1", "Half rate speech V1", 0);
1877 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
1878 "Half rate speech V3 (AMR)", 0);
1879 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
1880 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
1882 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
1883 "Set the minimum receive level to select a cell\n"
1884 "Minimum receive level from -110 dBm to -47 dBm")
1886 struct osmocom_ms *ms = vty->index;
1887 struct gsm_settings *set = &ms->settings;
1889 set->min_rxlev_db = atoi(argv[0]);
1894 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
1895 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
1896 "more reliable against bad RX signal. This increase the propability "
1897 "of missing a paging requests\n"
1898 "DSC initial and maximum value (standard is 90)")
1900 struct osmocom_ms *ms = vty->index;
1901 struct gsm_settings *set = &ms->settings;
1903 set->dsc_max = atoi(argv[0]);
1908 /* per testsim config */
1909 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1910 "Configure test SIM emulation")
1912 vty->node = TESTSIM_NODE;
1917 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1918 "Set IMSI on test card\n15 digits IMSI")
1920 struct osmocom_ms *ms = vty->index;
1921 struct gsm_settings *set = &ms->settings;
1922 char *error = gsm_check_imsi(argv[0]);
1925 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1929 strcpy(set->test_imsi, argv[0]);
1931 vty_restart(vty, ms);
1935 #define HEX_STR "\nByte as two digits hexadecimal"
1936 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1937 "HEX HEX HEX HEX HEX HEX",
1938 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1939 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
1941 struct osmocom_ms *ms = vty->index;
1942 struct gsm_settings *set = &ms->settings;
1947 for (i = 0; i < 12; i++) {
1949 if (!strncmp(p, "0x", 2))
1951 if (strlen(p) != 2) {
1952 vty_out(vty, "Expecting two digits hex value (with or "
1953 "without 0x in front)%s", VTY_NEWLINE);
1956 ki[i] = strtoul(p, NULL, 16);
1959 set->test_ki_type = GSM_SIM_KEY_XOR;
1960 memcpy(set->test_ki, ki, 12);
1964 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
1965 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
1966 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1967 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
1968 HEX_STR HEX_STR HEX_STR HEX_STR)
1970 struct osmocom_ms *ms = vty->index;
1971 struct gsm_settings *set = &ms->settings;
1976 for (i = 0; i < 16; i++) {
1978 if (!strncmp(p, "0x", 2))
1980 if (strlen(p) != 2) {
1981 vty_out(vty, "Expecting two digits hex value (with or "
1982 "without 0x in front)%s", VTY_NEWLINE);
1985 ki[i] = strtoul(p, NULL, 16);
1988 set->test_ki_type = GSM_SIM_KEY_COMP128;
1989 memcpy(set->test_ki, ki, 16);
1993 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
1994 "Allow access to barred cells")
1996 struct osmocom_ms *ms = vty->index;
1997 struct gsm_settings *set = &ms->settings;
2004 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2005 NO_STR "Deny access to barred cells")
2007 struct osmocom_ms *ms = vty->index;
2008 struct gsm_settings *set = &ms->settings;
2015 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2016 NO_STR "Unset Registered PLMN")
2018 struct osmocom_ms *ms = vty->index;
2019 struct gsm_settings *set = &ms->settings;
2021 set->test_rplmn_valid = 0;
2023 vty_restart(vty, ms);
2027 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
2028 "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
2030 struct osmocom_ms *ms = vty->index;
2031 struct gsm_settings *set = &ms->settings;
2032 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2033 mnc = gsm_input_mnc((char *)argv[1]);
2036 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2040 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2043 set->test_rplmn_valid = 1;
2044 set->test_rplmn_mcc = mcc;
2045 set->test_rplmn_mnc = mnc;
2047 vty_restart(vty, ms);
2051 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2052 "Set Home PLMN search mode\n"
2053 "Search for HPLMN when on any other network\n"
2054 "Search for HPLMN when in a different country")
2056 struct osmocom_ms *ms = vty->index;
2057 struct gsm_settings *set = &ms->settings;
2059 switch (argv[0][0]) {
2061 set->test_always = 1;
2064 set->test_always = 0;
2068 vty_restart(vty, ms);
2072 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2073 NO_STR "Activate and run MS")
2075 struct osmocom_ms *ms = vty->index, *tmp;
2078 if (ms->shutdown != 2)
2081 llist_for_each_entry(tmp, &ms_list, entity) {
2082 if (tmp->shutdown == 2)
2084 if (!strcmp(ms->settings.layer2_socket_path,
2085 tmp->settings.layer2_socket_path)) {
2086 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2087 "use the same layer2-socket.%sPlease shutdown "
2088 "MS '%s' first.%s", ms->name, tmp->name,
2089 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2092 if (!strcmp(ms->settings.sap_socket_path,
2093 tmp->settings.sap_socket_path)) {
2094 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2095 "use the same sap-socket.%sPlease shutdown "
2096 "MS '%s' first.%s", ms->name, tmp->name,
2097 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2102 rc = mobile_init(ms);
2104 vty_out(vty, "Connection to layer 1 failed!%s",
2112 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2113 "Shut down and deactivate MS")
2115 struct osmocom_ms *ms = vty->index;
2117 if (ms->shutdown == 0)
2123 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2124 "Shut down and deactivate MS\nDo not perform IMSI detach")
2126 struct osmocom_ms *ms = vty->index;
2128 if (ms->shutdown <= 1)
2134 enum node_type ms_vty_go_parent(struct vty *vty)
2136 switch (vty->node) {
2138 vty->node = CONFIG_NODE;
2143 vty->node = MS_NODE;
2146 vty->node = CONFIG_NODE;
2152 /* Down vty node level. */
2153 gDEFUN(ournode_exit,
2154 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2156 switch (vty->node) {
2158 vty->node = CONFIG_NODE;
2163 vty->node = MS_NODE;
2171 /* End of configuration. */
2173 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2175 switch (vty->node) {
2178 /* Nothing to do. */
2185 vty_config_unlock(vty);
2186 vty->node = ENABLE_NODE;
2188 vty->index_sub = NULL;
2196 DEFUN(off, off_cmd, "off",
2197 "Turn mobiles off (shutdown) and exit")
2199 dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2204 #define SUP_NODE(item) \
2205 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2207 int ms_vty_init(void)
2209 install_element_ve(&show_ms_cmd);
2210 install_element_ve(&show_subscr_cmd);
2211 install_element_ve(&show_support_cmd);
2212 install_element_ve(&show_cell_cmd);
2213 install_element_ve(&show_cell_si_cmd);
2214 install_element_ve(&show_ba_cmd);
2215 install_element_ve(&show_forb_la_cmd);
2216 install_element_ve(&show_forb_plmn_cmd);
2217 install_element_ve(&monitor_network_cmd);
2218 install_element_ve(&no_monitor_network_cmd);
2219 install_element(ENABLE_NODE, &off_cmd);
2221 install_element(ENABLE_NODE, &sim_test_cmd);
2222 install_element(ENABLE_NODE, &sim_reader_cmd);
2223 install_element(ENABLE_NODE, &sim_remove_cmd);
2224 install_element(ENABLE_NODE, &sim_pin_cmd);
2225 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2226 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2227 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2228 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2229 install_element(ENABLE_NODE, &sim_lai_cmd);
2230 install_element(ENABLE_NODE, &network_search_cmd);
2231 install_element(ENABLE_NODE, &network_show_cmd);
2232 install_element(ENABLE_NODE, &network_select_cmd);
2233 install_element(ENABLE_NODE, &call_cmd);
2234 install_element(ENABLE_NODE, &call_retr_cmd);
2235 install_element(ENABLE_NODE, &call_dtmf_cmd);
2237 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2238 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2239 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2240 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2242 install_element(CONFIG_NODE, &cfg_ms_cmd);
2243 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2244 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2245 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2246 install_element(CONFIG_NODE, &ournode_end_cmd);
2247 install_node(&ms_node, config_write_ms);
2248 install_default(MS_NODE);
2249 install_element(MS_NODE, &ournode_exit_cmd);
2250 install_element(MS_NODE, &ournode_end_cmd);
2251 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2252 install_element(MS_NODE, &cfg_ms_sap_cmd);
2253 install_element(MS_NODE, &cfg_ms_sim_cmd);
2254 install_element(MS_NODE, &cfg_ms_mode_cmd);
2255 install_element(MS_NODE, &cfg_ms_imei_cmd);
2256 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2257 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2258 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2259 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2260 install_element(MS_NODE, &cfg_ms_cw_cmd);
2261 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2262 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2263 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2264 install_element(MS_NODE, &cfg_ms_clip_cmd);
2265 install_element(MS_NODE, &cfg_ms_clir_cmd);
2266 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2267 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2268 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2269 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2270 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2271 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2272 install_element(MS_NODE, &cfg_ms_stick_cmd);
2273 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2274 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2275 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2276 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2277 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2278 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2279 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2280 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2281 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2282 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2283 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2284 install_element(MS_NODE, &cfg_ms_support_cmd);
2285 install_node(&support_node, config_write_dummy);
2286 install_default(SUPPORT_NODE);
2287 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2288 install_element(SUPPORT_NODE, &ournode_end_cmd);
2289 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2290 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2291 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2292 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2293 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2294 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2295 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2296 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2297 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2298 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2299 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2300 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2301 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2302 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2303 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2304 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2305 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2306 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2307 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2308 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2309 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2310 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2311 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2312 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2313 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2314 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2315 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2316 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2317 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2318 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2319 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2320 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2321 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2322 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2323 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2324 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2325 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2326 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2327 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2328 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2329 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2330 install_node(&testsim_node, config_write_dummy);
2331 install_default(TESTSIM_NODE);
2332 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2333 install_element(TESTSIM_NODE, &ournode_end_cmd);
2334 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2335 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2336 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2337 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2338 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2339 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2340 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2341 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2342 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2343 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2344 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2349 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2351 struct telnet_connection *connection;
2357 va_start(args, fmt);
2358 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2359 buffer[sizeof(buffer) - 1] = '\0';
2366 llist_for_each_entry(connection, &active_connections, entry) {
2367 vty = connection->vty;
2371 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2375 if (buffer[strlen(buffer) - 1] == '\n') {
2376 buffer[strlen(buffer) - 1] = '\0';
2377 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2378 buffer[strlen(buffer)] = '\n';
2380 vty_out(vty, "%% %s", buffer);