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 <osmocom/core/utils.h>
29 #include <osmocom/gsm/gsm48.h>
30 #include <osmocom/core/talloc.h>
31 #include <osmocom/core/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);
118 static int hide_default = 0;
120 static void vty_restart(struct vty *vty, struct osmocom_ms *ms)
124 if (ms->shutdown != 0)
126 vty_out(vty, "You must restart MS '%s' ('shutdown / no shutdown') for "
127 "change to take effect!%s", ms->name, VTY_NEWLINE);
130 static void vty_restart_if_started(struct vty *vty, struct osmocom_ms *ms)
134 vty_restart(vty, ms);
137 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
139 struct osmocom_ms *ms;
141 llist_for_each_entry(ms, &ms_list, entity) {
142 if (!strcmp(ms->name, name)) {
144 vty_out(vty, "MS '%s' is admin down.%s", name,
151 vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
156 static void gsm_ms_dump(struct osmocom_ms *ms, struct vty *vty)
158 struct gsm_settings *set = &ms->settings;
159 struct gsm_trans *trans;
163 service = ", radio is not started";
164 else if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE) {
165 /* current MM idle state */
166 switch (ms->mmlayer.substate) {
167 case GSM48_MM_SST_NORMAL_SERVICE:
168 case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
169 service = ", service is normal";
171 case GSM48_MM_SST_LOC_UPD_NEEDED:
172 case GSM48_MM_SST_ATTEMPT_UPDATE:
173 service = ", service is limited (pending)";
175 case GSM48_MM_SST_NO_CELL_AVAIL:
176 service = ", service is unavailable";
179 if (ms->subscr.sim_valid)
180 service = ", service is limited";
182 service = ", service is limited "
187 service = ", MM connection active";
189 vty_out(vty, "MS '%s' is %s%s%s%s", ms->name,
190 (ms->shutdown) ? "administratively " : "",
191 (ms->shutdown || !ms->started) ? "down" : "up",
192 (!ms->shutdown) ? service : "",
194 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
195 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
196 if (set->imei_random)
197 vty_out(vty, " IMEI generation: random (%d trailing "
198 "digits)%s", set->imei_random, VTY_NEWLINE);
200 vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
205 if (set->plmn_mode == PLMN_MODE_AUTO)
206 vty_out(vty, " automatic network selection state: %s%s",
207 get_a_state_name(ms->plmn.state), VTY_NEWLINE);
209 vty_out(vty, " manual network selection state : %s%s",
210 get_m_state_name(ms->plmn.state), VTY_NEWLINE);
212 vty_out(vty, " MCC=%s "
213 "MNC=%s (%s, %s)%s", gsm_print_mcc(ms->plmn.mcc),
214 gsm_print_mnc(ms->plmn.mnc), gsm_get_mcc(ms->plmn.mcc),
215 gsm_get_mnc(ms->plmn.mcc, ms->plmn.mnc), VTY_NEWLINE);
216 vty_out(vty, " cell selection state: %s%s",
217 get_cs_state_name(ms->cellsel.state), VTY_NEWLINE);
218 if (ms->cellsel.sel_mcc) {
219 vty_out(vty, " ARFCN=%s MCC=%s MNC=%s "
220 "LAC=0x%04x CELLID=0x%04x%s",
221 gsm_print_arfcn(ms->cellsel.sel_arfcn),
222 gsm_print_mcc(ms->cellsel.sel_mcc),
223 gsm_print_mnc(ms->cellsel.sel_mnc),
224 ms->cellsel.sel_lac, ms->cellsel.sel_id, VTY_NEWLINE);
225 vty_out(vty, " (%s, %s)%s",
226 gsm_get_mcc(ms->cellsel.sel_mcc),
227 gsm_get_mnc(ms->cellsel.sel_mcc, ms->cellsel.sel_mnc),
230 vty_out(vty, " radio ressource layer state: %s%s",
231 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
232 vty_out(vty, " mobility management layer state: %s",
233 gsm48_mm_state_names[ms->mmlayer.state]);
234 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
236 gsm48_mm_substate_names[ms->mmlayer.substate]);
237 vty_out(vty, "%s", VTY_NEWLINE);
238 llist_for_each_entry(trans, &ms->trans_list, entry) {
239 vty_out(vty, " call control state: %s%s",
240 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
245 DEFUN(show_ms, show_ms_cmd, "show ms [MS_NAME]",
246 SHOW_STR "Display available MS entities\n")
248 struct osmocom_ms *ms;
251 llist_for_each_entry(ms, &ms_list, entity) {
252 if (!strcmp(ms->name, argv[0])) {
253 gsm_ms_dump(ms, vty);
257 vty_out(vty, "MS name '%s' does not exits.%s", argv[0],
261 llist_for_each_entry(ms, &ms_list, entity) {
262 gsm_ms_dump(ms, vty);
263 vty_out(vty, "%s", VTY_NEWLINE);
270 DEFUN(show_support, show_support_cmd, "show support [MS_NAME]",
271 SHOW_STR "Display information about MS support\n"
272 "Name of MS (see \"show ms\")")
274 struct osmocom_ms *ms;
277 ms = get_ms(argv[0], vty);
280 gsm_support_dump(ms, print_vty, vty);
282 llist_for_each_entry(ms, &ms_list, entity) {
283 gsm_support_dump(ms, print_vty, vty);
284 vty_out(vty, "%s", VTY_NEWLINE);
291 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [MS_NAME]",
292 SHOW_STR "Display information about subscriber\n"
293 "Name of MS (see \"show ms\")")
295 struct osmocom_ms *ms;
298 ms = get_ms(argv[0], vty);
301 gsm_subscr_dump(&ms->subscr, print_vty, vty);
303 llist_for_each_entry(ms, &ms_list, entity) {
305 gsm_subscr_dump(&ms->subscr, print_vty, vty);
306 vty_out(vty, "%s", VTY_NEWLINE);
314 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
315 SHOW_STR "Display information about received cells\n"
316 "Name of MS (see \"show ms\")")
318 struct osmocom_ms *ms;
320 ms = get_ms(argv[0], vty);
324 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SUPPORT, print_vty,
330 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
331 SHOW_STR "Display information about received cell\n"
332 "Name of MS (see \"show ms\")\nRadio frequency number\n"
333 "Given frequency is PCS band (1900) rather than DCS band.")
335 struct osmocom_ms *ms;
336 struct gsm48_sysinfo *s;
337 uint16_t arfcn = atoi(argv[1]);
339 ms = get_ms(argv[0], vty);
344 if (arfcn < 512 || arfcn > 810) {
345 vty_out(vty, "Given ARFCN not in PCS band%s",
352 s = ms->cellsel.list[arfcn2index(arfcn)].sysinfo;
354 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
355 argv[1], VTY_NEWLINE);
359 gsm48_sysinfo_dump(s, arfcn, print_vty, vty, ms->settings.freq_map);
364 DEFUN(show_nbcells, show_nbcells_cmd, "show neighbour-cells MS_NAME",
365 SHOW_STR "Display information about current neighbour cells\n"
366 "Name of MS (see \"show ms\")")
368 struct osmocom_ms *ms;
370 ms = get_ms(argv[0], vty);
374 gsm322_dump_nb_list(&ms->cellsel, print_vty, vty);
379 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [MCC] [MNC]",
380 SHOW_STR "Display information about band allocations\n"
381 "Name of MS (see \"show ms\")\nMobile Country Code\n"
382 "Mobile Network Code")
384 struct osmocom_ms *ms;
385 uint16_t mcc = 0, mnc = 0;
387 ms = get_ms(argv[0], vty);
392 mcc = gsm_input_mcc((char *)argv[1]);
393 mnc = gsm_input_mnc((char *)argv[2]);
395 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
399 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
404 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
409 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
410 SHOW_STR "Display information about forbidden cells / networks\n"
411 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
413 struct osmocom_ms *ms;
415 ms = get_ms(argv[0], vty);
419 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
424 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
425 SHOW_STR "Display information about forbidden cells / networks\n"
426 "Display forbidden location areas\nName of MS (see \"show ms\")")
428 struct osmocom_ms *ms;
430 ms = get_ms(argv[0], vty);
434 gsm322_dump_forbidden_la(ms, print_vty, vty);
439 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
440 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
442 struct osmocom_ms *ms;
444 ms = get_ms(argv[0], vty);
448 gsm48_rr_start_monitor(ms);
453 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
454 NO_STR "Monitor...\nDeactivate monitor of network information\n"
455 "Name of MS (see \"show ms\")")
457 struct osmocom_ms *ms;
459 ms = get_ms(argv[0], vty);
463 gsm48_rr_stop_monitor(ms);
468 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [MCC] [MNC] [LAC] [TMSI]",
469 "SIM actions\nAttach bulit in test SIM\nName of MS (see \"show ms\")\n"
470 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN\n"
471 "Optionally location area code\nOptionally current assigned TMSI")
473 struct osmocom_ms *ms;
474 uint16_t mcc = 0x001, mnc = 0x01f, lac = 0x0000;
475 uint32_t tmsi = 0xffffffff;
477 ms = get_ms(argv[0], vty);
481 if (ms->subscr.sim_valid) {
482 vty_out(vty, "SIM already attached, remove first!%s",
488 mcc = gsm_input_mcc((char *)argv[1]);
489 mnc = gsm_input_mnc((char *)argv[2]);
491 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
495 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
501 lac = strtoul(argv[3], NULL, 16);
504 tmsi = strtoul(argv[4], NULL, 16);
506 gsm_subscr_testcard(ms, mcc, mnc, lac, tmsi);
511 DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
512 "SIM actions\nAttach SIM from reader\nName of MS (see \"show ms\")")
514 struct osmocom_ms *ms;
516 ms = get_ms(argv[0], vty);
520 if (ms->subscr.sim_valid) {
521 vty_out(vty, "SIM already attached, remove first!%s",
526 gsm_subscr_simcard(ms);
531 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
532 "SIM actions\nDetach SIM card\nName of MS (see \"show ms\")")
534 struct osmocom_ms *ms;
536 ms = get_ms(argv[0], vty);
540 if (!ms->subscr.sim_valid) {
541 vty_out(vty, "No SIM attached!%s", VTY_NEWLINE);
545 gsm_subscr_remove(ms);
550 DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
551 "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
554 struct osmocom_ms *ms;
556 ms = get_ms(argv[0], vty);
560 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
561 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
565 if (!ms->subscr.sim_pin_required) {
566 vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
570 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
575 DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
576 "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
579 struct osmocom_ms *ms;
581 ms = get_ms(argv[0], vty);
585 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
586 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
590 gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
595 DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
596 "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
599 struct osmocom_ms *ms;
601 ms = get_ms(argv[0], vty);
605 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
606 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
610 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
615 DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
616 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
617 "Old PIN number\nNew PIN number")
619 struct osmocom_ms *ms;
621 ms = get_ms(argv[0], vty);
625 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
626 vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
629 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
630 vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
634 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
639 DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
640 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
641 "Personal Unblock Key\nNew PIN number")
643 struct osmocom_ms *ms;
645 ms = get_ms(argv[0], vty);
649 if (strlen(argv[1]) != 8) {
650 vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
653 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
654 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
658 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
663 DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
664 "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
665 "Mobile Country Code\nMobile Network Code\nLocation Area Code "
666 " (use 0000 to remove LAI)")
668 struct osmocom_ms *ms;
669 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
670 mnc = gsm_input_mnc((char *)argv[2]),
671 lac = strtoul(argv[3], NULL, 16);
673 ms = get_ms(argv[0], vty);
678 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
682 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
686 ms->subscr.mcc = mcc;
687 ms->subscr.mnc = mnc;
688 ms->subscr.lac = lac;
689 ms->subscr.tmsi = 0xffffffff;
691 gsm_subscr_write_loci(ms);
696 DEFUN(network_select, network_select_cmd,
697 "network select MS_NAME MCC MNC [force]",
698 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
699 "Mobile Country Code\nMobile Network Code\n"
700 "Force selecting a network that is not in the list")
702 struct osmocom_ms *ms;
703 struct gsm322_plmn *plmn;
705 struct gsm322_msg *ngm;
706 struct gsm322_plmn_list *temp;
707 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
708 mnc = gsm_input_mnc((char *)argv[2]);
711 ms = get_ms(argv[0], vty);
716 if (ms->settings.plmn_mode != PLMN_MODE_MANUAL) {
717 vty_out(vty, "Not in manual network selection mode%s",
723 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
727 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
732 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
733 if (temp->mcc == mcc && temp->mnc == mnc)
736 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
737 vty_out(vty, "To force selecting this network, use "
738 "'force' keyword%s", VTY_NEWLINE);
743 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
746 ngm = (struct gsm322_msg *) nmsg->data;
749 gsm322_plmn_sendmsg(ms, nmsg);
754 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
755 "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
756 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
757 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
758 "Hold current active call\n")
760 struct osmocom_ms *ms;
761 struct gsm_settings *set;
762 struct gsm_settings_abbrev *abbrev;
765 ms = get_ms(argv[0], vty);
770 if (set->ch_cap == GSM_CAP_SDCCH) {
771 vty_out(vty, "Basic call is not supported for SDCCH only "
772 "mobile%s", VTY_NEWLINE);
776 number = (char *)argv[1];
777 if (!strcmp(number, "emergency"))
778 mncc_call(ms, number);
779 else if (!strcmp(number, "answer"))
781 else if (!strcmp(number, "hangup"))
783 else if (!strcmp(number, "hold"))
786 llist_for_each_entry(abbrev, &set->abbrev, list) {
787 if (!strcmp(number, abbrev->abbrev)) {
788 number = abbrev->number;
789 vty_out(vty, "Dialing number '%s'%s", number,
794 if (vty_check_number(vty, number))
796 mncc_call(ms, number);
802 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [NUMBER]",
803 "Make a call\nName of MS (see \"show ms\")\n"
804 "Retrieve call on hold\nNumber of call to retrieve")
806 struct osmocom_ms *ms;
808 ms = get_ms(argv[0], vty);
812 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
817 DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
818 "Make a call\nName of MS (see \"show ms\")\n"
819 "One or more DTMF digits to transmit")
821 struct osmocom_ms *ms;
822 struct gsm_settings *set;
824 ms = get_ms(argv[0], vty);
830 vty_out(vty, "DTMF not supported, please enable!%s",
835 mncc_dtmf(ms, (char *)argv[1]);
840 DEFUN(test_reselection, test_reselection_cmd, "test re-selection NAME",
841 "Manually trigger cell re-selection\nName of MS (see \"show ms\")")
843 struct osmocom_ms *ms;
844 struct gsm_settings *set;
847 ms = get_ms(argv[0], vty);
853 vty_out(vty, "Cannot trigger cell re-selection, because we "
854 "stick to a cell!%s", VTY_NEWLINE);
858 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
861 gsm322_c_event(ms, nmsg);
867 DEFUN(delete_forbidden_plmn, delete_forbidden_plmn_cmd,
868 "delete forbidden plmn NAME MCC MNC",
869 "Delete\nForbidden\nplmn\nName of MS (see \"show ms\")\n"
870 "Mobile Country Code\nMobile Network Code")
872 struct osmocom_ms *ms;
873 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
874 mnc = gsm_input_mnc((char *)argv[2]);
876 ms = get_ms(argv[0], vty);
881 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
885 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
889 gsm_subscr_del_forbidden_plmn(&ms->subscr, mcc, mnc);
894 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
895 "Network ...\nShow results of network search (again)\n"
896 "Name of MS (see \"show ms\")")
898 struct osmocom_ms *ms;
899 struct gsm_settings *set;
900 struct gsm322_plmn *plmn;
901 struct gsm322_plmn_list *temp;
903 ms = get_ms(argv[0], vty);
909 if (set->plmn_mode != PLMN_MODE_AUTO
910 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
911 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
915 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
916 vty_out(vty, " Network %s, %s (%s, %s)%s",
917 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
918 gsm_get_mcc(temp->mcc),
919 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
924 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
925 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
927 struct osmocom_ms *ms;
930 ms = get_ms(argv[0], vty);
934 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
937 gsm322_plmn_sendmsg(ms, nmsg);
942 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
945 if (osmo_gps_open()) {
947 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
955 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
956 NO_STR "Disable GPS receiver")
966 DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",
967 "GPS receiver\nSelect gpsd host and port\n"
968 "IP and port (optional) of the host running gpsd")
970 char* colon = strstr(argv[0], ":");
972 memcpy(g.gpsd_host, argv[0], colon - argv[0] - 1);
973 g.gpsd_host[colon - argv[0]] = '\0';
974 memcpy(g.gpsd_port, colon, strlen(colon));
975 g.gpsd_port[strlen(colon)] = '\0';
977 snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", argv[0]);
978 g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
979 snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "2947");
980 g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
982 g.gps_type = GPS_TYPE_GPSD;
985 if (osmo_gps_open()) {
986 vty_out(vty, "Failed to connect to gpsd host!%s",
996 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
997 "GPS receiver\nSelect serial device\n"
998 "Full path of serial device including /dev/")
1000 strncpy(g.device, argv[0], sizeof(g.device));
1001 g.device[sizeof(g.device) - 1] = '\0';
1002 g.gps_type = GPS_TYPE_SERIAL;
1005 if (osmo_gps_open()) {
1006 vty_out(vty, "Failed to open GPS device!%s",
1015 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
1016 "(default|4800|""9600|19200|38400|57600|115200)",
1017 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
1019 if (argv[0][0] == 'd')
1022 g.baud = atoi(argv[0]);
1025 if (osmo_gps_open()) {
1027 vty_out(vty, "Failed to open GPS device!%s",
1036 DEFUN(cfg_hide_default, cfg_hide_default_cmd, "hide-default",
1037 "Hide most default values in config to make it more compact")
1044 DEFUN(cfg_no_hide_default, cfg_no_hide_default_cmd, "no hide-default",
1045 NO_STR "Show default values in config")
1053 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
1054 "Select a mobile station to configure\nName of MS (see \"show ms\")")
1056 struct osmocom_ms *ms;
1059 llist_for_each_entry(ms, &ms_list, entity) {
1060 if (!strcmp(ms->name, argv[0])) {
1068 vty_out(vty, "MS name '%s' does not exits, try "
1069 "'ms %s create'%s", argv[0], argv[0],
1073 ms = mobile_new((char *)argv[0]);
1075 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
1082 vty->node = MS_NODE;
1087 DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
1088 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
1089 "Create if MS does not exists")
1091 struct osmocom_ms *ms;
1094 llist_for_each_entry(ms, &ms_list, entity) {
1095 if (!strcmp(ms->name, argv[0])) {
1102 ms = mobile_new((char *)argv[0]);
1104 vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
1111 vty->node = MS_NODE;
1113 vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
1114 argv[0], VTY_NEWLINE);
1118 DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
1119 "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
1120 "Rename MS\nNew name of MS")
1122 struct osmocom_ms *ms;
1125 llist_for_each_entry(ms, &ms_list, entity) {
1126 if (!strcmp(ms->name, argv[0])) {
1133 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1138 strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
1143 DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
1144 NO_STR "Select a mobile station to remove\n"
1145 "Name of MS (see \"show ms\")")
1147 struct osmocom_ms *ms;
1150 llist_for_each_entry(ms, &ms_list, entity) {
1151 if (!strcmp(ms->name, argv[0])) {
1158 vty_out(vty, "MS name '%s' does not exist%s", argv[0],
1163 mobile_delete(ms, 1);
1168 #define SUP_WRITE(item, cmd) \
1170 if (!hide_default || !set->item) \
1171 vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", \
1174 static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
1176 struct gsm_settings *set = &ms->settings;
1177 struct gsm_support *sup = &ms->support;
1178 struct gsm_settings_abbrev *abbrev;
1180 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
1181 vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
1183 vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
1184 switch(set->sim_type) {
1185 case GSM_SIM_TYPE_NONE:
1186 vty_out(vty, " sim none%s", VTY_NEWLINE);
1188 case GSM_SIM_TYPE_READER:
1189 vty_out(vty, " sim reader%s", VTY_NEWLINE);
1191 case GSM_SIM_TYPE_TEST:
1192 vty_out(vty, " sim test%s", VTY_NEWLINE);
1195 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
1196 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
1197 vty_out(vty, " imei %s %s%s", set->imei,
1198 set->imeisv + strlen(set->imei), VTY_NEWLINE);
1199 if (set->imei_random)
1200 vty_out(vty, " imei-random %d%s", set->imei_random,
1204 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
1205 if (set->emergency_imsi[0])
1206 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
1210 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
1211 if (!hide_default || set->cw)
1212 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ",
1214 if (!hide_default || set->auto_answer)
1215 vty_out(vty, " %sauto-answer%s",
1216 (set->auto_answer) ? "" : "no ", VTY_NEWLINE);
1217 if (!hide_default || set->clip)
1218 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ",
1220 if (!hide_default || set->clir)
1221 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ",
1223 if (set->alter_tx_power)
1224 if (set->alter_tx_power_value)
1225 vty_out(vty, " tx-power %d%s",
1226 set->alter_tx_power_value, VTY_NEWLINE);
1228 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
1231 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
1232 if (set->alter_delay)
1233 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
1237 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
1239 vty_out(vty, " stick %d%s%s", set->stick_arfcn & 1023,
1240 (set->stick_arfcn & ARFCN_PCS) ? " pcs" : "",
1244 vty_out(vty, " no stick%s", VTY_NEWLINE);
1245 if (!hide_default || set->no_lupd)
1246 vty_out(vty, " %slocation-updating%s",
1247 (set->no_lupd) ? "no " : "", VTY_NEWLINE);
1248 if (!hide_default || set->no_neighbour)
1249 vty_out(vty, " %sneighbour-measurement%s",
1250 (set->no_neighbour) ? "no " : "", VTY_NEWLINE);
1251 if (set->full_v1 || set->full_v2 || set->full_v3) {
1252 /* mandatory anyway */
1253 vty_out(vty, " codec full-speed%s%s",
1254 (!set->half_prefer) ? " prefer" : "",
1257 if (set->half_v1 || set->half_v3) {
1259 vty_out(vty, " codec half-speed%s%s",
1260 (set->half_prefer) ? " prefer" : "",
1263 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
1265 if (llist_empty(&set->abbrev)) {
1267 vty_out(vty, " no abbrev%s", VTY_NEWLINE);
1269 llist_for_each_entry(abbrev, &set->abbrev, list)
1270 vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
1271 abbrev->number, (abbrev->name[0]) ? " " : "",
1272 abbrev->name, VTY_NEWLINE);
1274 vty_out(vty, " support%s", VTY_NEWLINE);
1275 SUP_WRITE(sms_ptp, "sms");
1276 SUP_WRITE(a5_1, "a5/1");
1277 SUP_WRITE(a5_2, "a5/2");
1278 SUP_WRITE(a5_3, "a5/3");
1279 SUP_WRITE(a5_4, "a5/4");
1280 SUP_WRITE(a5_5, "a5/5");
1281 SUP_WRITE(a5_6, "a5/6");
1282 SUP_WRITE(a5_7, "a5/7");
1283 SUP_WRITE(p_gsm, "p-gsm");
1284 SUP_WRITE(e_gsm, "e-gsm");
1285 SUP_WRITE(r_gsm, "r-gsm");
1286 SUP_WRITE(pcs, "gsm-850");
1287 SUP_WRITE(gsm_480, "gsm-480");
1288 SUP_WRITE(gsm_450, "gsm-450");
1289 SUP_WRITE(dcs, "dcs");
1290 SUP_WRITE(pcs, "pcs");
1291 if (sup->r_gsm || sup->e_gsm || sup->p_gsm)
1292 if (!hide_default || sup->class_900 != set->class_900)
1293 vty_out(vty, " class-900 %d%s", set->class_900,
1296 if (!hide_default || sup->class_850 != set->class_850)
1297 vty_out(vty, " class-850 %d%s", set->class_850,
1299 if (sup->gsm_480 || sup->gsm_450)
1300 if (!hide_default || sup->class_400 != set->class_400)
1301 vty_out(vty, " class-400 %d%s", set->class_400,
1304 if (!hide_default || sup->class_dcs != set->class_dcs)
1305 vty_out(vty, " class-dcs %d%s", set->class_dcs,
1308 if (!hide_default || sup->class_pcs != set->class_pcs)
1309 vty_out(vty, " class-pcs %d%s", set->class_pcs,
1311 if (!hide_default || sup->ch_cap != set->ch_cap) {
1312 switch (set->ch_cap) {
1314 vty_out(vty, " channel-capability sdcch%s",
1317 case GSM_CAP_SDCCH_TCHF:
1318 vty_out(vty, " channel-capability sdcch+tchf%s",
1321 case GSM_CAP_SDCCH_TCHF_TCHH:
1322 vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
1327 SUP_WRITE(full_v1, "full-speech-v1");
1328 SUP_WRITE(full_v2, "full-speech-v2");
1329 SUP_WRITE(full_v3, "full-speech-v3");
1330 SUP_WRITE(half_v1, "half-speech-v1");
1331 SUP_WRITE(half_v3, "half-speech-v3");
1332 if (!hide_default || sup->min_rxlev_db != set->min_rxlev_db)
1333 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db,
1335 if (!hide_default || sup->dsc_max != set->dsc_max)
1336 vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
1337 if (!hide_default || set->skip_max_per_band)
1338 vty_out(vty, " %skip-max-per-band%s",
1339 (set->skip_max_per_band) ? "" : "no ", VTY_NEWLINE);
1340 vty_out(vty, " exit%s", VTY_NEWLINE);
1341 vty_out(vty, " test-sim%s", VTY_NEWLINE);
1342 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
1343 switch (set->test_ki_type) {
1344 case GSM_SIM_KEY_XOR:
1345 vty_out(vty, " ki xor %s%s",
1346 osmo_hexdump(set->test_ki, 12), VTY_NEWLINE);
1348 case GSM_SIM_KEY_COMP128:
1349 vty_out(vty, " ki comp128 %s%s",
1350 osmo_hexdump(set->test_ki, 16), VTY_NEWLINE);
1353 if (!hide_default || set->test_barr)
1354 vty_out(vty, " %sbarred-access%s",
1355 (set->test_barr) ? "" : "no ", VTY_NEWLINE);
1356 if (set->test_rplmn_valid) {
1357 vty_out(vty, " rplmn %s %s",
1358 gsm_print_mcc(set->test_rplmn_mcc),
1359 gsm_print_mnc(set->test_rplmn_mnc));
1360 if (set->test_lac > 0x0000 && set->test_lac < 0xfffe)
1361 vty_out(vty, " 0x%04x", set->test_lac);
1362 if (set->test_tmsi != 0xffffffff)
1363 vty_out(vty, " 0x%08x", set->test_tmsi);
1364 vty_out(vty, "%s", VTY_NEWLINE);
1367 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
1368 if (!hide_default || set->test_always)
1369 vty_out(vty, " hplmn-search %s%s",
1370 (set->test_always) ? "everywhere" : "foreign-country",
1372 vty_out(vty, " exit%s", VTY_NEWLINE);
1373 /* no shutdown must be written to config, because shutdown is default */
1374 vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
1376 vty_out(vty, "exit%s", VTY_NEWLINE);
1377 vty_out(vty, "!%s", VTY_NEWLINE);
1380 static int config_write(struct vty *vty)
1382 struct osmocom_ms *ms;
1385 vty_out(vty, "gpsd host %s%s", g.gpsd_host, VTY_NEWLINE);
1386 vty_out(vty, "gpsd port %s%s", g.gpsd_port, VTY_NEWLINE);
1388 vty_out(vty, "gps device %s%s", g.device, VTY_NEWLINE);
1390 vty_out(vty, "gps baudrate %d%s", g.baud, VTY_NEWLINE);
1392 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
1393 vty_out(vty, "%sgps enable%s", (g.enable) ? "" : "no ", VTY_NEWLINE);
1394 vty_out(vty, "!%s", VTY_NEWLINE);
1396 vty_out(vty, "%shide-default%s", (hide_default) ? "": "no ",
1398 vty_out(vty, "!%s", VTY_NEWLINE);
1400 llist_for_each_entry(ms, &ms_list, entity)
1401 config_write_ms(vty, ms);
1406 DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
1407 SHOW_STR "Show config of this MS")
1409 struct osmocom_ms *ms = vty->index;
1411 config_write_ms(vty, ms);
1416 DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
1417 "Define socket path to connect between layer 2 and layer 1\n"
1418 "Unix socket, default '/tmp/osmocom_l2'")
1420 struct osmocom_ms *ms = vty->index;
1421 struct gsm_settings *set = &ms->settings;
1423 strncpy(set->layer2_socket_path, argv[0],
1424 sizeof(set->layer2_socket_path) - 1);
1426 vty_restart(vty, ms);
1430 DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
1431 "Define socket path to connect to SIM reader\n"
1432 "Unix socket, default '/tmp/osmocom_sap'")
1434 struct osmocom_ms *ms = vty->index;
1435 struct gsm_settings *set = &ms->settings;
1437 strncpy(set->sap_socket_path, argv[0],
1438 sizeof(set->sap_socket_path) - 1);
1440 vty_restart(vty, ms);
1444 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
1445 "Set SIM card to attach when powering on\nAttach no SIM\n"
1446 "Attach SIM from reader\nAttach bulit in test SIM")
1448 struct osmocom_ms *ms = vty->index;
1449 struct gsm_settings *set = &ms->settings;
1451 switch (argv[0][0]) {
1453 set->sim_type = GSM_SIM_TYPE_NONE;
1456 set->sim_type = GSM_SIM_TYPE_READER;
1459 set->sim_type = GSM_SIM_TYPE_TEST;
1462 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1466 vty_restart_if_started(vty, ms);
1471 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1472 "Set network selection mode\nAutomatic network selection\n"
1473 "Manual network selection")
1475 struct osmocom_ms *ms = vty->index;
1476 struct gsm_settings *set = &ms->settings;
1480 if (argv[0][0] == 'a')
1481 set->plmn_mode = PLMN_MODE_AUTO;
1483 set->plmn_mode = PLMN_MODE_MANUAL;
1485 if (argv[0][0] == 'a')
1486 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1488 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1491 gsm322_plmn_sendmsg(ms, nmsg);
1497 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1498 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1499 "Software version digit")
1501 struct osmocom_ms *ms = vty->index;
1502 struct gsm_settings *set = &ms->settings;
1503 char *error, *sv = "0";
1506 sv = (char *)argv[1];
1508 error = gsm_check_imei(argv[0], sv);
1510 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1514 strcpy(set->imei, argv[0]);
1515 strcpy(set->imeisv, argv[0]);
1516 strcpy(set->imeisv + 15, sv);
1521 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1522 "Use fixed IMEI on every power on")
1524 struct osmocom_ms *ms = vty->index;
1525 struct gsm_settings *set = &ms->settings;
1527 set->imei_random = 0;
1532 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1533 "Use random IMEI on every power on\n"
1534 "Number of trailing digits to randomize")
1536 struct osmocom_ms *ms = vty->index;
1537 struct gsm_settings *set = &ms->settings;
1539 set->imei_random = atoi(argv[0]);
1544 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1545 "Use special IMSI for emergency calls\n15 digits IMSI")
1547 struct osmocom_ms *ms = vty->index;
1548 struct gsm_settings *set = &ms->settings;
1551 error = gsm_check_imsi(argv[0]);
1553 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1556 strcpy(set->emergency_imsi, argv[0]);
1561 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1562 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1564 struct osmocom_ms *ms = vty->index;
1565 struct gsm_settings *set = &ms->settings;
1567 set->emergency_imsi[0] = '\0';
1572 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1573 NO_STR "Disallow waiting calls")
1575 struct osmocom_ms *ms = vty->index;
1576 struct gsm_settings *set = &ms->settings;
1583 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1584 "Allow waiting calls")
1586 struct osmocom_ms *ms = vty->index;
1587 struct gsm_settings *set = &ms->settings;
1594 DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
1595 NO_STR "Disable auto-answering calls")
1597 struct osmocom_ms *ms = vty->index;
1598 struct gsm_settings *set = &ms->settings;
1600 set->auto_answer = 0;
1605 DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
1606 "Enable auto-answering calls")
1608 struct osmocom_ms *ms = vty->index;
1609 struct gsm_settings *set = &ms->settings;
1611 set->auto_answer = 1;
1616 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1617 "Force caller ID presentation")
1619 struct osmocom_ms *ms = vty->index;
1620 struct gsm_settings *set = &ms->settings;
1628 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1629 "Force caller ID restriction")
1631 struct osmocom_ms *ms = vty->index;
1632 struct gsm_settings *set = &ms->settings;
1640 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1641 NO_STR "Disable forcing of caller ID presentation")
1643 struct osmocom_ms *ms = vty->index;
1644 struct gsm_settings *set = &ms->settings;
1651 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1652 NO_STR "Disable forcing of caller ID restriction")
1654 struct osmocom_ms *ms = vty->index;
1655 struct gsm_settings *set = &ms->settings;
1662 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1663 "Set the way to choose transmit power\nControlled by BTS\n"
1664 "Always full power\nFixed GSM power value if supported")
1666 struct osmocom_ms *ms = vty->index;
1667 struct gsm_settings *set = &ms->settings;
1669 switch (argv[0][0]) {
1671 set->alter_tx_power = 0;
1674 set->alter_tx_power = 1;
1675 set->alter_tx_power_value = 0;
1682 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1683 "Set the way to choose transmit power\n"
1684 "Fixed GSM power value if supported")
1686 struct osmocom_ms *ms = vty->index;
1687 struct gsm_settings *set = &ms->settings;
1689 set->alter_tx_power = 1;
1690 set->alter_tx_power_value = atoi(argv[0]);
1695 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1696 "Simulate a lower or higher distance from the BTS\n"
1697 "Delay in half bits (distance in 553.85 meter steps)")
1699 struct osmocom_ms *ms = vty->index;
1700 struct gsm_settings *set = &ms->settings;
1702 set->alter_delay = atoi(argv[0]);
1703 gsm48_rr_alter_delay(ms);
1708 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1709 NO_STR "Do not simulate a lower or higher distance from the BTS")
1711 struct osmocom_ms *ms = vty->index;
1712 struct gsm_settings *set = &ms->settings;
1714 set->alter_delay = 0;
1715 gsm48_rr_alter_delay(ms);
1720 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023> [pcs]",
1721 "Stick to the given cell\nARFCN of the cell to stick to\n"
1722 "Given frequency is PCS band (1900) rather than DCS band.")
1724 struct osmocom_ms *ms = vty->index;
1725 struct gsm_settings *set = &ms->settings;
1726 uint16_t arfcn = atoi(argv[0]);
1729 if (arfcn < 512 || arfcn > 810) {
1730 vty_out(vty, "Given ARFCN not in PCS band%s",
1737 set->stick_arfcn = arfcn;
1742 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1743 NO_STR "Do not stick to any cell")
1745 struct osmocom_ms *ms = vty->index;
1746 struct gsm_settings *set = &ms->settings;
1753 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1754 "Allow location updating")
1756 struct osmocom_ms *ms = vty->index;
1757 struct gsm_settings *set = &ms->settings;
1764 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1765 NO_STR "Do not allow location updating")
1767 struct osmocom_ms *ms = vty->index;
1768 struct gsm_settings *set = &ms->settings;
1775 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1776 "Enable codec\nFull speed speech codec")
1778 struct osmocom_ms *ms = vty->index;
1779 struct gsm_settings *set = &ms->settings;
1781 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1782 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1789 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1791 "Enable codec\nFull speed speech codec\nPrefer this codec")
1793 struct osmocom_ms *ms = vty->index;
1794 struct gsm_settings *set = &ms->settings;
1796 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1797 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1801 set->half_prefer = 0;
1806 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1807 "Enable codec\nHalf speed speech codec")
1809 struct osmocom_ms *ms = vty->index;
1810 struct gsm_settings *set = &ms->settings;
1812 if (!set->half_v1 && !set->half_v3) {
1813 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1822 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1824 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1826 struct osmocom_ms *ms = vty->index;
1827 struct gsm_settings *set = &ms->settings;
1829 if (!set->half_v1 && !set->half_v3) {
1830 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1835 set->half_prefer = 1;
1840 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1841 NO_STR "Disable codec\nHalf speed speech codec")
1843 struct osmocom_ms *ms = vty->index;
1844 struct gsm_settings *set = &ms->settings;
1846 if (!set->half_v1 && !set->half_v3) {
1847 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1852 set->half_prefer = 0;
1857 DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
1858 "Store given abbreviation number\n1-3 digits abbreviation\n"
1859 "Number to store for the abbreviation "
1860 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
1861 "Name of the abbreviation")
1863 struct osmocom_ms *ms = vty->index;
1864 struct gsm_settings *set = &ms->settings;
1865 struct gsm_settings_abbrev *abbrev;
1868 llist_for_each_entry(abbrev, &set->abbrev, list) {
1869 if (!strcmp(argv[0], abbrev->abbrev)) {
1870 vty_out(vty, "Given abbreviation '%s' already stored, "
1871 "delete first!%s", argv[0], VTY_NEWLINE);
1876 if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
1877 vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
1881 for (i = 0; i < strlen(argv[0]); i++) {
1882 if (argv[0][i] < '0' || argv[0][i] > '9') {
1883 vty_out(vty, "Given abbreviation must have digits "
1884 "0..9 only!%s", VTY_NEWLINE);
1889 if (vty_check_number(vty, argv[1]))
1892 abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
1894 vty_out(vty, "No Memory!%s", VTY_NEWLINE);
1897 llist_add_tail(&abbrev->list, &set->abbrev);
1898 strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
1899 strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
1901 strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
1906 DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
1907 NO_STR "Remove given abbreviation number or all numbers\n"
1908 "Abbreviation number to remove")
1910 struct osmocom_ms *ms = vty->index;
1911 struct gsm_settings *set = &ms->settings;
1912 struct gsm_settings_abbrev *abbrev, *abbrev2;
1913 uint8_t deleted = 0;
1915 llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
1916 if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
1917 llist_del(&abbrev->list);
1922 if (argc >= 1 && !deleted) {
1923 vty_out(vty, "Given abbreviation '%s' not found!%s",
1924 argv[0], VTY_NEWLINE);
1931 DEFUN(cfg_ms_neighbour, cfg_ms_neighbour_cmd, "neighbour-measurement",
1932 "Allow neighbour cell measurement in idle mode")
1934 struct osmocom_ms *ms = vty->index;
1935 struct gsm_settings *set = &ms->settings;
1937 set->no_neighbour = 0;
1939 vty_restart_if_started(vty, ms);
1945 DEFUN(cfg_ms_no_neighbour, cfg_ms_no_neighbour_cmd, "no neighbour-measurement",
1946 NO_STR "Do not allow neighbour cell measurement in idle mode")
1948 struct osmocom_ms *ms = vty->index;
1949 struct gsm_settings *set = &ms->settings;
1951 set->no_neighbour = 1;
1953 vty_restart_if_started(vty, ms);
1958 static int config_write_dummy(struct vty *vty)
1963 /* per support config */
1964 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1965 "Define supported features")
1967 vty->node = SUPPORT_NODE;
1972 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1973 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1975 struct osmocom_ms *ms = vty->index; \
1976 struct gsm_settings *set = &ms->settings; \
1977 struct gsm_support *sup = &ms->support; \
1979 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1981 return CMD_SUCCESS; \
1982 return CMD_WARNING; \
1985 vty_restart(vty, ms); \
1987 return CMD_SUCCESS; \
1990 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1991 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1993 struct osmocom_ms *ms = vty->index; \
1994 struct gsm_settings *set = &ms->settings; \
1995 struct gsm_support *sup = &ms->support; \
1997 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1999 return CMD_SUCCESS; \
2000 return CMD_WARNING; \
2003 vty_restart(vty, ms); \
2005 return CMD_SUCCESS; \
2008 #define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
2009 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
2011 struct osmocom_ms *ms = vty->index; \
2012 struct gsm_settings *set = &ms->settings; \
2014 vty_restart(vty, ms); \
2016 return CMD_SUCCESS; \
2019 #define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
2020 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
2022 struct osmocom_ms *ms = vty->index; \
2023 struct gsm_settings *set = &ms->settings; \
2025 vty_restart(vty, ms); \
2027 return CMD_SUCCESS; \
2030 SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
2031 SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
2032 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
2033 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
2034 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
2035 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
2036 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
2037 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
2038 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
2039 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
2040 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
2041 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
2042 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
2043 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
2044 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
2045 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
2046 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
2047 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
2048 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
2050 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
2052 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
2054 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
2056 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
2058 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
2060 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 1);
2061 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 1);
2062 SUP_EN(cfg_ms_sup_gsm_850, cfg_ms_sup_gsm_850_cmd, gsm_850, "gsm-850",
2064 SUP_DI(cfg_ms_sup_no_gsm_850, cfg_ms_sup_no_gsm_850_cmd, gsm_850, "gsm-850",
2066 SUP_EN(cfg_ms_sup_pcs, cfg_ms_sup_pcs_cmd, pcs, "pcs", "PCS (1900)", 1);
2067 SUP_DI(cfg_ms_sup_no_pcs, cfg_ms_sup_no_pcs_cmd, pcs, "pcs", "PCS (1900)", 1);
2068 SUP_EN(cfg_ms_sup_gsm_480, cfg_ms_sup_gsm_480_cmd, gsm_480, "gsm-480",
2070 SUP_DI(cfg_ms_sup_no_gsm_480, cfg_ms_sup_no_gsm_480_cmd, gsm_480, "gsm-480",
2072 SUP_EN(cfg_ms_sup_gsm_450, cfg_ms_sup_gsm_450_cmd, gsm_450, "gsm-450",
2074 SUP_DI(cfg_ms_sup_no_gsm_450, cfg_ms_sup_no_gsm_450_cmd, gsm_450, "gsm-450",
2077 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
2078 "Select power class for GSM 900\n"
2085 struct osmocom_ms *ms = vty->index;
2086 struct gsm_settings *set = &ms->settings;
2087 struct gsm_support *sup = &ms->support;
2089 set->class_900 = atoi(argv[0]);
2091 if (set->class_900 < sup->class_900 && !vty_reading)
2092 vty_out(vty, "Note: You selected a higher class than supported "
2093 " by hardware!%s", VTY_NEWLINE);
2098 DEFUN(cfg_ms_sup_class_850, cfg_ms_sup_class_850_cmd, "class-850 (1|2|3|4|5)",
2099 "Select power class for GSM 850\n"
2106 struct osmocom_ms *ms = vty->index;
2107 struct gsm_settings *set = &ms->settings;
2108 struct gsm_support *sup = &ms->support;
2110 set->class_850 = atoi(argv[0]);
2112 if (set->class_850 < sup->class_850 && !vty_reading)
2113 vty_out(vty, "Note: You selected a higher class than supported "
2114 " by hardware!%s", VTY_NEWLINE);
2119 DEFUN(cfg_ms_sup_class_400, cfg_ms_sup_class_400_cmd, "class-400 (1|2|3|4|5)",
2120 "Select power class for GSM 400 (480 and 450)\n"
2127 struct osmocom_ms *ms = vty->index;
2128 struct gsm_settings *set = &ms->settings;
2129 struct gsm_support *sup = &ms->support;
2131 set->class_400 = atoi(argv[0]);
2133 if (set->class_400 < sup->class_400 && !vty_reading)
2134 vty_out(vty, "Note: You selected a higher class than supported "
2135 " by hardware!%s", VTY_NEWLINE);
2140 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
2141 "Select power class for DCS 1800\n"
2146 struct osmocom_ms *ms = vty->index;
2147 struct gsm_settings *set = &ms->settings;
2148 struct gsm_support *sup = &ms->support;
2150 set->class_dcs = atoi(argv[0]);
2152 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
2154 vty_out(vty, "Note: You selected a higher class than supported "
2155 " by hardware!%s", VTY_NEWLINE);
2160 DEFUN(cfg_ms_sup_class_pcs, cfg_ms_sup_class_pcs_cmd, "class-pcs (1|2|3)",
2161 "Select power class for PCS 1900\n"
2166 struct osmocom_ms *ms = vty->index;
2167 struct gsm_settings *set = &ms->settings;
2168 struct gsm_support *sup = &ms->support;
2170 set->class_pcs = atoi(argv[0]);
2172 if (((set->class_pcs + 1) & 3) < ((sup->class_pcs + 1) & 3)
2174 vty_out(vty, "Note: You selected a higher class than supported "
2175 " by hardware!%s", VTY_NEWLINE);
2180 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
2181 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
2182 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
2184 struct osmocom_ms *ms = vty->index;
2185 struct gsm_settings *set = &ms->settings;
2186 struct gsm_support *sup = &ms->support;
2189 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
2190 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
2191 else if (!strcmp(argv[0], "sdcch+tchf"))
2192 ch_cap = GSM_CAP_SDCCH_TCHF;
2194 ch_cap = GSM_CAP_SDCCH;
2196 if (ch_cap > sup->ch_cap && !vty_reading) {
2197 vty_out(vty, "You selected an higher capability than supported "
2198 " by hardware!%s", VTY_NEWLINE);
2202 if (ms->started && ch_cap != set->ch_cap
2203 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
2204 vty_restart_if_started(vty, ms);
2206 set->ch_cap = ch_cap;
2211 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
2212 "Full rate speech V1", 0);
2213 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
2214 "full-speech-v1", "Full rate speech V1", 0);
2215 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
2216 "Full rate speech V2 (EFR)", 0);
2217 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
2218 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
2219 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
2220 "Full rate speech V3 (AMR)", 0);
2221 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
2222 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
2223 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
2224 "Half rate speech V1", 0);
2225 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
2226 "half-speech-v1", "Half rate speech V1", 0);
2227 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
2228 "Half rate speech V3 (AMR)", 0);
2229 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
2230 "half-speech-v3", "Half rate speech V3 (AMR)", 0);
2232 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
2233 "Set the minimum receive level to select a cell\n"
2234 "Minimum receive level from -110 dBm to -47 dBm")
2236 struct osmocom_ms *ms = vty->index;
2237 struct gsm_settings *set = &ms->settings;
2239 set->min_rxlev_db = atoi(argv[0]);
2244 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
2245 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
2246 "more reliable against bad RX signal. This increase the propability "
2247 "of missing a paging requests\n"
2248 "DSC initial and maximum value (standard is 90)")
2250 struct osmocom_ms *ms = vty->index;
2251 struct gsm_settings *set = &ms->settings;
2253 set->dsc_max = atoi(argv[0]);
2258 DEFUN(cfg_ms_sup_skip_max_per_band, cfg_ms_sup_skip_max_per_band_cmd,
2259 "skip-max-per-band",
2260 "Scan all frequencies per band, not only a maximum number")
2262 struct osmocom_ms *ms = vty->index;
2263 struct gsm_settings *set = &ms->settings;
2265 set->skip_max_per_band = 1;
2270 DEFUN(cfg_ms_sup_no_skip_max_per_band, cfg_ms_sup_no_skip_max_per_band_cmd,
2271 "no skip-max-per-band",
2272 NO_STR "Scan only a maximum number of frequencies per band")
2274 struct osmocom_ms *ms = vty->index;
2275 struct gsm_settings *set = &ms->settings;
2277 set->skip_max_per_band = 0;
2282 /* per testsim config */
2283 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
2284 "Configure test SIM emulation")
2286 vty->node = TESTSIM_NODE;
2291 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
2292 "Set IMSI on test card\n15 digits IMSI")
2294 struct osmocom_ms *ms = vty->index;
2295 struct gsm_settings *set = &ms->settings;
2296 char *error = gsm_check_imsi(argv[0]);
2299 vty_out(vty, "%s%s", error, VTY_NEWLINE);
2303 strcpy(set->test_imsi, argv[0]);
2305 vty_restart_if_started(vty, ms);
2310 #define HEX_STR "\nByte as two digits hexadecimal"
2311 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
2312 "HEX HEX HEX HEX HEX HEX",
2313 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
2314 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
2316 struct osmocom_ms *ms = vty->index;
2317 struct gsm_settings *set = &ms->settings;
2322 for (i = 0; i < 12; i++) {
2324 if (!strncmp(p, "0x", 2))
2326 if (strlen(p) != 2) {
2327 vty_out(vty, "Expecting two digits hex value (with or "
2328 "without 0x in front)%s", VTY_NEWLINE);
2331 ki[i] = strtoul(p, NULL, 16);
2334 set->test_ki_type = GSM_SIM_KEY_XOR;
2335 memcpy(set->test_ki, ki, 12);
2339 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
2340 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
2341 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
2342 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
2343 HEX_STR HEX_STR HEX_STR HEX_STR)
2345 struct osmocom_ms *ms = vty->index;
2346 struct gsm_settings *set = &ms->settings;
2351 for (i = 0; i < 16; i++) {
2353 if (!strncmp(p, "0x", 2))
2355 if (strlen(p) != 2) {
2356 vty_out(vty, "Expecting two digits hex value (with or "
2357 "without 0x in front)%s", VTY_NEWLINE);
2360 ki[i] = strtoul(p, NULL, 16);
2363 set->test_ki_type = GSM_SIM_KEY_COMP128;
2364 memcpy(set->test_ki, ki, 16);
2368 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
2369 "Allow access to barred cells")
2371 struct osmocom_ms *ms = vty->index;
2372 struct gsm_settings *set = &ms->settings;
2379 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
2380 NO_STR "Deny access to barred cells")
2382 struct osmocom_ms *ms = vty->index;
2383 struct gsm_settings *set = &ms->settings;
2390 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
2391 NO_STR "Unset Registered PLMN")
2393 struct osmocom_ms *ms = vty->index;
2394 struct gsm_settings *set = &ms->settings;
2396 set->test_rplmn_valid = 0;
2398 vty_restart_if_started(vty, ms);
2403 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
2404 "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
2405 "Optionally set locatio area code\n"
2406 "Optionally set current assigned TMSI")
2408 struct osmocom_ms *ms = vty->index;
2409 struct gsm_settings *set = &ms->settings;
2410 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
2411 mnc = gsm_input_mnc((char *)argv[1]);
2414 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
2418 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
2421 set->test_rplmn_valid = 1;
2422 set->test_rplmn_mcc = mcc;
2423 set->test_rplmn_mnc = mnc;
2426 set->test_lac = strtoul(argv[2], NULL, 16);
2428 set->test_lac = 0xfffe;
2431 set->test_tmsi = strtoul(argv[3], NULL, 16);
2433 set->test_tmsi = 0xffffffff;
2435 vty_restart_if_started(vty, ms);
2440 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
2441 "Set Home PLMN search mode\n"
2442 "Search for HPLMN when on any other network\n"
2443 "Search for HPLMN when in a different country")
2445 struct osmocom_ms *ms = vty->index;
2446 struct gsm_settings *set = &ms->settings;
2448 switch (argv[0][0]) {
2450 set->test_always = 1;
2453 set->test_always = 0;
2457 vty_restart_if_started(vty, ms);
2462 DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
2463 NO_STR "Activate and run MS")
2465 struct osmocom_ms *ms = vty->index, *tmp;
2468 if (ms->shutdown != 2)
2471 llist_for_each_entry(tmp, &ms_list, entity) {
2472 if (tmp->shutdown == 2)
2474 if (!strcmp(ms->settings.layer2_socket_path,
2475 tmp->settings.layer2_socket_path)) {
2476 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2477 "use the same layer2-socket.%sPlease shutdown "
2478 "MS '%s' first.%s", ms->name, tmp->name,
2479 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2482 if (!strcmp(ms->settings.sap_socket_path,
2483 tmp->settings.sap_socket_path)) {
2484 vty_out(vty, "Cannot start MS '%s', because MS '%s' "
2485 "use the same sap-socket.%sPlease shutdown "
2486 "MS '%s' first.%s", ms->name, tmp->name,
2487 VTY_NEWLINE, tmp->name, VTY_NEWLINE);
2492 rc = mobile_init(ms);
2494 vty_out(vty, "Connection to layer 1 failed!%s",
2502 DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
2503 "Shut down and deactivate MS")
2505 struct osmocom_ms *ms = vty->index;
2507 if (ms->shutdown == 0)
2513 DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
2514 "Shut down and deactivate MS\nDo not perform IMSI detach")
2516 struct osmocom_ms *ms = vty->index;
2518 if (ms->shutdown <= 1)
2524 enum node_type ms_vty_go_parent(struct vty *vty)
2526 switch (vty->node) {
2528 vty->node = CONFIG_NODE;
2533 vty->node = MS_NODE;
2536 vty->node = CONFIG_NODE;
2542 /* Down vty node level. */
2543 gDEFUN(ournode_exit,
2544 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
2546 switch (vty->node) {
2548 vty->node = CONFIG_NODE;
2553 vty->node = MS_NODE;
2561 /* End of configuration. */
2563 ournode_end_cmd, "end", "End current mode and change to enable mode.")
2565 switch (vty->node) {
2568 /* Nothing to do. */
2575 vty_config_unlock(vty);
2576 vty->node = ENABLE_NODE;
2578 vty->index_sub = NULL;
2586 DEFUN(off, off_cmd, "off",
2587 "Turn mobiles off (shutdown) and exit")
2589 osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
2594 #define SUP_NODE(item) \
2595 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
2597 int ms_vty_init(void)
2599 install_element_ve(&show_ms_cmd);
2600 install_element_ve(&show_subscr_cmd);
2601 install_element_ve(&show_support_cmd);
2602 install_element_ve(&show_cell_cmd);
2603 install_element_ve(&show_cell_si_cmd);
2604 install_element_ve(&show_nbcells_cmd);
2605 install_element_ve(&show_ba_cmd);
2606 install_element_ve(&show_forb_la_cmd);
2607 install_element_ve(&show_forb_plmn_cmd);
2608 install_element_ve(&monitor_network_cmd);
2609 install_element_ve(&no_monitor_network_cmd);
2610 install_element(ENABLE_NODE, &off_cmd);
2612 install_element(ENABLE_NODE, &sim_test_cmd);
2613 install_element(ENABLE_NODE, &sim_reader_cmd);
2614 install_element(ENABLE_NODE, &sim_remove_cmd);
2615 install_element(ENABLE_NODE, &sim_pin_cmd);
2616 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
2617 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
2618 install_element(ENABLE_NODE, &sim_change_pin_cmd);
2619 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
2620 install_element(ENABLE_NODE, &sim_lai_cmd);
2621 install_element(ENABLE_NODE, &network_search_cmd);
2622 install_element(ENABLE_NODE, &network_show_cmd);
2623 install_element(ENABLE_NODE, &network_select_cmd);
2624 install_element(ENABLE_NODE, &call_cmd);
2625 install_element(ENABLE_NODE, &call_retr_cmd);
2626 install_element(ENABLE_NODE, &call_dtmf_cmd);
2627 install_element(ENABLE_NODE, &test_reselection_cmd);
2628 install_element(ENABLE_NODE, &delete_forbidden_plmn_cmd);
2631 install_element(CONFIG_NODE, &cfg_gps_host_cmd);
2633 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
2634 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
2635 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
2636 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
2638 install_element(CONFIG_NODE, &cfg_hide_default_cmd);
2639 install_element(CONFIG_NODE, &cfg_no_hide_default_cmd);
2641 install_element(CONFIG_NODE, &cfg_ms_cmd);
2642 install_element(CONFIG_NODE, &cfg_ms_create_cmd);
2643 install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
2644 install_element(CONFIG_NODE, &cfg_no_ms_cmd);
2645 install_element(CONFIG_NODE, &ournode_end_cmd);
2646 install_node(&ms_node, config_write);
2647 install_default(MS_NODE);
2648 install_element(MS_NODE, &ournode_exit_cmd);
2649 install_element(MS_NODE, &ournode_end_cmd);
2650 install_element(MS_NODE, &cfg_ms_show_this_cmd);
2651 install_element(MS_NODE, &cfg_ms_layer2_cmd);
2652 install_element(MS_NODE, &cfg_ms_sap_cmd);
2653 install_element(MS_NODE, &cfg_ms_sim_cmd);
2654 install_element(MS_NODE, &cfg_ms_mode_cmd);
2655 install_element(MS_NODE, &cfg_ms_imei_cmd);
2656 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
2657 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
2658 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
2659 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
2660 install_element(MS_NODE, &cfg_ms_cw_cmd);
2661 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
2662 install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
2663 install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
2664 install_element(MS_NODE, &cfg_ms_clip_cmd);
2665 install_element(MS_NODE, &cfg_ms_clir_cmd);
2666 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
2667 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
2668 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
2669 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
2670 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
2671 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
2672 install_element(MS_NODE, &cfg_ms_stick_cmd);
2673 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
2674 install_element(MS_NODE, &cfg_ms_lupd_cmd);
2675 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
2676 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
2677 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
2678 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
2679 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
2680 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
2681 install_element(MS_NODE, &cfg_ms_abbrev_cmd);
2682 install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
2683 install_element(MS_NODE, &cfg_ms_testsim_cmd);
2684 install_element(MS_NODE, &cfg_ms_neighbour_cmd);
2685 install_element(MS_NODE, &cfg_ms_no_neighbour_cmd);
2686 install_element(MS_NODE, &cfg_ms_support_cmd);
2687 install_node(&support_node, config_write_dummy);
2688 install_default(SUPPORT_NODE);
2689 install_element(SUPPORT_NODE, &ournode_exit_cmd);
2690 install_element(SUPPORT_NODE, &ournode_end_cmd);
2691 install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
2692 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
2693 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
2694 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
2695 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
2696 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
2697 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
2698 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
2699 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
2700 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
2701 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
2702 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
2703 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
2704 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
2705 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
2706 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
2707 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
2708 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
2709 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
2710 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
2711 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
2712 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
2713 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
2714 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
2715 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
2716 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
2717 install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_850_cmd);
2718 install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_850_cmd);
2719 install_element(SUPPORT_NODE, &cfg_ms_sup_pcs_cmd);
2720 install_element(SUPPORT_NODE, &cfg_ms_sup_no_pcs_cmd);
2721 install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_480_cmd);
2722 install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_480_cmd);
2723 install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_450_cmd);
2724 install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_450_cmd);
2725 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
2726 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
2727 install_element(SUPPORT_NODE, &cfg_ms_sup_class_850_cmd);
2728 install_element(SUPPORT_NODE, &cfg_ms_sup_class_pcs_cmd);
2729 install_element(SUPPORT_NODE, &cfg_ms_sup_class_400_cmd);
2730 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
2731 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
2732 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
2733 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
2734 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
2735 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
2736 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
2737 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
2738 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
2739 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
2740 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
2741 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
2742 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
2743 install_element(SUPPORT_NODE, &cfg_ms_sup_skip_max_per_band_cmd);
2744 install_element(SUPPORT_NODE, &cfg_ms_sup_no_skip_max_per_band_cmd);
2745 install_node(&testsim_node, config_write_dummy);
2746 install_default(TESTSIM_NODE);
2747 install_element(TESTSIM_NODE, &ournode_exit_cmd);
2748 install_element(TESTSIM_NODE, &ournode_end_cmd);
2749 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
2750 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
2751 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
2752 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
2753 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
2754 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
2755 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
2756 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
2757 install_element(MS_NODE, &cfg_ms_shutdown_cmd);
2758 install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
2759 install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
2764 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
2766 struct telnet_connection *connection;
2772 va_start(args, fmt);
2773 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
2774 buffer[sizeof(buffer) - 1] = '\0';
2781 llist_for_each_entry(connection, &active_connections, entry) {
2782 vty = connection->vty;
2786 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
2790 if (buffer[strlen(buffer) - 1] == '\n') {
2791 buffer[strlen(buffer) - 1] = '\0';
2792 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
2793 buffer[strlen(buffer)] = '\n';
2795 vty_out(vty, "%% %s", buffer);