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>
31 #include <osmocom/bb/common/osmocom_data.h>
32 #include <osmocom/bb/common/networks.h>
33 #include <osmocom/bb/mobile/mncc.h>
34 #include <osmocom/bb/mobile/transaction.h>
35 #include <osmocom/bb/mobile/vty.h>
36 #include <osmocom/bb/mobile/gps.h>
37 #include <osmocom/vty/telnet_interface.h>
39 int mncc_call(struct osmocom_ms *ms, char *number);
40 int mncc_hangup(struct osmocom_ms *ms);
41 int mncc_answer(struct osmocom_ms *ms);
42 int mncc_hold(struct osmocom_ms *ms);
43 int mncc_retrieve(struct osmocom_ms *ms, int number);
45 extern struct llist_head ms_list;
46 extern struct llist_head active_connections;
48 struct cmd_node ms_node = {
54 struct cmd_node testsim_node = {
60 struct cmd_node support_node = {
66 static void print_vty(void *priv, const char *fmt, ...)
69 struct vty *vty = priv;
73 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
74 buffer[sizeof(buffer) - 1] = '\0';
78 if (buffer[strlen(buffer) - 1] == '\n') {
79 buffer[strlen(buffer) - 1] = '\0';
80 vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
82 vty_out(vty, "%s", buffer);
88 static void vty_restart(struct vty *vty)
92 vty_out(vty, "You must restart for change to take effect!%s",
96 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
98 struct osmocom_ms *ms;
100 llist_for_each_entry(ms, &ms_list, entity) {
101 if (!strcmp(ms->name, name))
104 vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
109 DEFUN(show_ms, show_ms_cmd, "show ms",
110 SHOW_STR "Display available MS entities\n")
112 struct osmocom_ms *ms;
114 llist_for_each_entry(ms, &ms_list, entity) {
115 struct gsm_settings *set = &ms->settings;
117 vty_out(vty, "MS NAME: %s%s", ms->name, VTY_NEWLINE);
118 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
119 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
120 if (set->imei_random)
121 vty_out(vty, " IMEI generation: random (%d trailing "
122 "digits)%s", set->imei_random, VTY_NEWLINE);
124 vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
125 vty_out(vty, " network selection mode: %s%s",
126 (set->plmn_mode == PLMN_MODE_AUTO)
127 ? "automatic" : "manual", VTY_NEWLINE);
133 DEFUN(show_support, show_support_cmd, "show support [ms_name]",
134 SHOW_STR "Display information about MS support\n"
135 "Name of MS (see \"show ms\")")
137 struct osmocom_ms *ms;
140 ms = get_ms(argv[0], vty);
143 gsm_support_dump(ms, print_vty, vty);
145 llist_for_each_entry(ms, &ms_list, entity) {
146 gsm_support_dump(ms, print_vty, vty);
147 vty_out(vty, "%s", VTY_NEWLINE);
154 static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
156 struct gsm_settings *set = &ms->settings;
157 struct gsm_trans *trans;
159 vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
160 if (set->plmn_mode == PLMN_MODE_AUTO)
161 vty_out(vty, " automatic network selection: %s%s",
162 plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
164 vty_out(vty, " manual network selection: %s%s",
165 plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
166 vty_out(vty, " cell selection: %s",
167 cs_state_names[ms->cellsel.state]);
168 if (ms->rrlayer.state == GSM48_RR_ST_IDLE && ms->cellsel.selected)
169 vty_out(vty, " (ARFCN %d)", ms->cellsel.sel_arfcn);
170 vty_out(vty, "%s", VTY_NEWLINE);
171 vty_out(vty, " radio ressource layer: %s%s",
172 gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
173 vty_out(vty, " mobility management layer: %s",
174 gsm48_mm_state_names[ms->mmlayer.state]);
175 if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
177 gsm48_mm_substate_names[ms->mmlayer.substate]);
178 vty_out(vty, "%s", VTY_NEWLINE);
179 llist_for_each_entry(trans, &ms->trans_list, entry) {
180 vty_out(vty, " call control: %s%s",
181 gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
185 DEFUN(show_states, show_states_cmd, "show states [ms_name]",
186 SHOW_STR "Display current states of given MS\n"
187 "Name of MS (see \"show ms\")")
189 struct osmocom_ms *ms;
192 ms = get_ms(argv[0], vty);
195 gsm_states_dump(ms, vty);
197 llist_for_each_entry(ms, &ms_list, entity) {
198 gsm_states_dump(ms, vty);
199 vty_out(vty, "%s", VTY_NEWLINE);
206 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
207 SHOW_STR "Display information about subscriber\n"
208 "Name of MS (see \"show ms\")")
210 struct osmocom_ms *ms;
213 ms = get_ms(argv[0], vty);
216 gsm_subscr_dump(&ms->subscr, print_vty, vty);
218 llist_for_each_entry(ms, &ms_list, entity) {
219 gsm_subscr_dump(&ms->subscr, print_vty, vty);
220 vty_out(vty, "%s", VTY_NEWLINE);
227 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
228 SHOW_STR "Display information about received cells\n"
229 "Name of MS (see \"show ms\")")
231 struct osmocom_ms *ms;
233 ms = get_ms(argv[0], vty);
237 gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
243 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
244 SHOW_STR "Display information about received cell\n"
245 "Name of MS (see \"show ms\")\nRadio frequency number")
247 struct osmocom_ms *ms;
249 struct gsm48_sysinfo *s;
251 ms = get_ms(argv[0], vty);
256 if (i < 0 || i > 1023) {
257 vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
258 argv[1], VTY_NEWLINE);
261 s = ms->cellsel.list[i].sysinfo;
263 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
264 argv[1], VTY_NEWLINE);
268 gsm48_sysinfo_dump(s, i, print_vty, vty);
273 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [mcc] [mnc]",
274 SHOW_STR "Display information about band allocations\n"
275 "Name of MS (see \"show ms\")\nMobile Country Code\n"
276 "Mobile Network Code")
278 struct osmocom_ms *ms;
279 uint16_t mcc = 0, mnc = 0;
281 ms = get_ms(argv[0], vty);
286 mcc = gsm_input_mcc((char *)argv[1]);
287 mnc = gsm_input_mnc((char *)argv[2]);
289 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
293 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
298 gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
303 DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
304 SHOW_STR "Display information about forbidden cells / networks\n"
305 "Display forbidden PLMNs\nName of MS (see \"show ms\")")
307 struct osmocom_ms *ms;
309 ms = get_ms(argv[0], vty);
313 gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
318 DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
319 SHOW_STR "Display information about forbidden cells / networks\n"
320 "Display forbidden location areas\nName of MS (see \"show ms\")")
322 struct osmocom_ms *ms;
324 ms = get_ms(argv[0], vty);
328 gsm322_dump_forbidden_la(ms, print_vty, vty);
333 DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
334 "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
336 struct osmocom_ms *ms;
338 ms = get_ms(argv[0], vty);
342 gsm48_rr_start_monitor(ms);
347 DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
348 NO_STR "Monitor...\nDeactivate monitor of network information\n"
349 "Name of MS (see \"show ms\")")
351 struct osmocom_ms *ms;
353 ms = get_ms(argv[0], vty);
357 gsm48_rr_stop_monitor(ms);
362 DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [mcc] [mnc]",
363 "SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
364 "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN")
366 struct osmocom_ms *ms;
367 uint16_t mcc = 0x001, mnc = 0x01f;
369 ms = get_ms(argv[0], vty);
373 if (ms->subscr.sim_valid) {
374 vty_out(vty, "SIM already presend, remove first!%s",
380 mcc = gsm_input_mcc((char *)argv[1]);
381 mnc = gsm_input_mnc((char *)argv[2]);
383 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
387 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
392 gsm_subscr_testcard(ms, mcc, mnc);
397 DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
398 "SIM actions\nSelect SIM from reader\nName of MS (see \"show ms\")")
400 struct osmocom_ms *ms;
402 ms = get_ms(argv[0], vty);
406 if (ms->subscr.sim_valid) {
407 vty_out(vty, "SIM already presend, remove first!%s",
412 gsm_subscr_simcard(ms);
417 DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
418 "SIM actions\nRemove SIM card\nName of MS (see \"show ms\")")
420 struct osmocom_ms *ms;
422 ms = get_ms(argv[0], vty);
426 if (!ms->subscr.sim_valid) {
427 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
431 gsm_subscr_remove(ms);
436 DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
437 "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
440 struct osmocom_ms *ms;
442 ms = get_ms(argv[0], vty);
446 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
447 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
451 if (!ms->subscr.sim_pin_required) {
452 vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
456 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
461 DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
462 "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
465 struct osmocom_ms *ms;
467 ms = get_ms(argv[0], vty);
471 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
472 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
476 gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
481 DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
482 "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
485 struct osmocom_ms *ms;
487 ms = get_ms(argv[0], vty);
491 if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
492 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
496 gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
501 DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
502 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
503 "Old PIN number\nNew PIN number")
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, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
515 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
516 vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
520 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
525 DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
526 "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
527 "Personal Unblock Key\nNew PIN number")
529 struct osmocom_ms *ms;
531 ms = get_ms(argv[0], vty);
535 if (strlen(argv[1]) != 8) {
536 vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
539 if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
540 vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
544 gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
549 DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
550 "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
551 "Mobile Country Code\nMobile Network Code\nLocation Area Code "
552 " (use 0000 to remove LAI)")
554 struct osmocom_ms *ms;
555 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
556 mnc = gsm_input_mnc((char *)argv[2]),
557 lac = strtoul(argv[3], NULL, 16);
559 ms = get_ms(argv[0], vty);
564 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
568 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
572 ms->subscr.mcc = mcc;
573 ms->subscr.mnc = mnc;
574 ms->subscr.lac = lac;
575 ms->subscr.tmsi = 0xffffffff;
577 gsm_subscr_write_loci(ms);
582 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
583 "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
584 "Mobile Country Code\nMobile Network Code")
586 struct osmocom_ms *ms;
587 struct gsm322_plmn *plmn;
589 struct gsm322_msg *ngm;
590 struct gsm322_plmn_list *temp;
591 uint16_t mcc = gsm_input_mcc((char *)argv[1]),
592 mnc = gsm_input_mnc((char *)argv[2]);
595 ms = get_ms(argv[0], vty);
601 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
605 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
609 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
610 if (temp->mcc == mcc && temp->mnc == mnc)
613 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
617 nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
620 ngm = (struct gsm322_msg *) nmsg->data;
623 gsm322_plmn_sendmsg(ms, nmsg);
628 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
629 "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
630 "(Use digits '0123456789*#abc', and '+' to dial international)\n"
631 "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
632 "Hold current active call\n")
634 struct osmocom_ms *ms;
635 struct gsm_settings *set;
638 ms = get_ms(argv[0], vty);
643 if (set->ch_cap == GSM_CAP_SDCCH) {
644 vty_out(vty, "Basic call is not supported for SDCCH only "
645 "mobile%s", VTY_NEWLINE);
649 if (!strcmp(argv[1], "emergency"))
650 mncc_call(ms, (char *)argv[1]);
651 else switch (argv[1][0]) {
656 if (argv[1][1] == 'a')
662 for (i = 0; i < strlen(argv[1]); i++) {
663 /* allow international notation with + */
664 if (i == 0 && argv[1][i] == '+')
666 if (!(argv[1][i] >= '0' && argv[1][i] <= '9')
669 && !(argv[1][i] >= 'a' && argv[1][i] <= 'c')) {
670 vty_out(vty, "Invalid digit '%c'%s", argv[1][i],
675 mncc_call(ms, (char *)argv[1]);
681 DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [number]",
682 "Make a call\nName of MS (see \"show ms\")\n"
683 "Retrieve call on hold\nNumber of call to retrieve")
685 struct osmocom_ms *ms;
687 ms = get_ms(argv[0], vty);
691 mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
696 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
697 "Network ...\nShow results of network search (again)\n"
698 "Name of MS (see \"show ms\")")
700 struct osmocom_ms *ms;
701 struct gsm_settings *set;
702 struct gsm322_plmn *plmn;
703 struct gsm322_plmn_list *temp;
705 ms = get_ms(argv[0], vty);
711 if (set->plmn_mode != PLMN_MODE_AUTO
712 && plmn->state != GSM322_M3_NOT_ON_PLMN) {
713 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
717 llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
718 vty_out(vty, " Network %s, %s (%s, %s)%s",
719 gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
720 gsm_get_mcc(temp->mcc),
721 gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
726 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
727 "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
729 struct osmocom_ms *ms;
732 ms = get_ms(argv[0], vty);
736 nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
739 gsm322_plmn_sendmsg(ms, nmsg);
744 DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
749 vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
757 DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
758 NO_STR "Disable GPS receiver")
767 DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
768 "GPS receiver\nSelect serial device\n"
769 "Full path of serial device including /dev/")
771 strncpy(gps.device, argv[0], sizeof(gps.device));
772 gps.device[sizeof(gps.device) - 1] = '\0';
776 vty_out(vty, "Failed to open GPS device!%s",
785 DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
786 "(default|4800|""9600|19200|38400|57600|115200)",
787 "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
789 if (argv[0][0] == 'd')
792 gps.baud = atoi(argv[0]);
797 vty_out(vty, "Failed to open GPS device!%s",
807 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
808 "Select a mobile station to configure\nName of MS (see \"show ms\")")
810 struct osmocom_ms *ms;
812 ms = get_ms(argv[0], vty);
822 #define SUP_WRITE(item, cmd) \
824 vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
827 static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
829 struct gsm_settings *set = &ms->settings;
830 struct gsm_support *sup = &ms->support;
832 vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
833 switch(set->sim_type) {
834 case GSM_SIM_TYPE_NONE:
835 vty_out(vty, " sim none%s", VTY_NEWLINE);
837 case GSM_SIM_TYPE_READER:
838 vty_out(vty, " sim reader%s", VTY_NEWLINE);
840 case GSM_SIM_TYPE_TEST:
841 vty_out(vty, " sim test%s", VTY_NEWLINE);
844 vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
845 == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
846 vty_out(vty, " imei %s %s%s", set->imei,
847 set->imeisv + strlen(set->imei), VTY_NEWLINE);
848 if (set->imei_random)
849 vty_out(vty, " imei-random %d%s", set->imei_random,
852 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
853 if (set->emergency_imsi[0])
854 vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
857 vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
858 vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
859 vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
860 vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
861 if (set->alter_tx_power)
862 if (set->alter_tx_power_value)
863 vty_out(vty, " tx-power %d%s",
864 set->alter_tx_power_value, VTY_NEWLINE);
866 vty_out(vty, " tx-power full%s", VTY_NEWLINE);
868 vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
869 if (set->alter_delay)
870 vty_out(vty, " simulated-delay %d%s", set->alter_delay,
873 vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
875 vty_out(vty, " stick %d%s", set->stick_arfcn,
878 vty_out(vty, " no stick%s", VTY_NEWLINE);
880 vty_out(vty, " no location-updating%s", VTY_NEWLINE);
882 vty_out(vty, " location-updating%s", VTY_NEWLINE);
883 if (set->full_v1 || set->full_v2 || set->full_v3) {
884 /* mandatory anyway */
885 vty_out(vty, " codec full-speed%s%s",
886 (!set->half_prefer) ? " prefer" : "",
889 if (set->half_v1 || set->half_v3) {
891 vty_out(vty, " codec half-speed%s%s",
892 (set->half_prefer) ? " prefer" : "",
895 vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
897 vty_out(vty, " support%s", VTY_NEWLINE);
898 SUP_WRITE(sms_ptp, "sms");
899 SUP_WRITE(a5_1, "a5/1");
900 SUP_WRITE(a5_2, "a5/2");
901 SUP_WRITE(a5_3, "a5/3");
902 SUP_WRITE(a5_4, "a5/4");
903 SUP_WRITE(a5_5, "a5/5");
904 SUP_WRITE(a5_6, "a5/6");
905 SUP_WRITE(a5_7, "a5/7");
906 SUP_WRITE(p_gsm, "p-gsm");
907 SUP_WRITE(e_gsm, "e-gsm");
908 SUP_WRITE(r_gsm, "r-gsm");
909 SUP_WRITE(dcs, "dcs");
910 vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
911 vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
912 switch (set->ch_cap) {
914 vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
916 case GSM_CAP_SDCCH_TCHF:
917 vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
919 case GSM_CAP_SDCCH_TCHF_TCHH:
920 vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
924 SUP_WRITE(full_v1, "full-speech-v1");
925 SUP_WRITE(full_v2, "full-speech-v2");
926 SUP_WRITE(full_v3, "full-speech-v3");
927 SUP_WRITE(half_v1, "half-speech-v1");
928 SUP_WRITE(half_v3, "half-speech-v3");
929 vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
930 vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
931 vty_out(vty, " exit%s", VTY_NEWLINE);
932 vty_out(vty, " test-sim%s", VTY_NEWLINE);
933 vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
934 switch (set->test_ki_type) {
935 case GSM_SIM_KEY_XOR:
936 vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
939 case GSM_SIM_KEY_COMP128:
940 vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
944 vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
946 if (set->test_rplmn_valid)
947 vty_out(vty, " rplmn %s %s%s",
948 gsm_print_mcc(set->test_rplmn_mcc),
949 gsm_print_mnc(set->test_rplmn_mnc),
952 vty_out(vty, " no rplmn%s", VTY_NEWLINE);
953 vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
954 : "foreign-country", VTY_NEWLINE);
955 vty_out(vty, " exit%s", VTY_NEWLINE);
956 vty_out(vty, "exit%s", VTY_NEWLINE);
957 vty_out(vty, "!%s", VTY_NEWLINE);
960 static int config_write_ms(struct vty *vty)
962 struct osmocom_ms *ms;
964 vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
966 vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
968 vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
969 vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
970 vty_out(vty, "!%s", VTY_NEWLINE);
972 llist_for_each_entry(ms, &ms_list, entity)
973 config_write_ms_single(vty, ms);
978 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
979 "Set SIM card type when powering on\nNo SIM interted\n"
980 "Use SIM from reader\nTest SIM inserted")
982 struct osmocom_ms *ms = vty->index;
983 struct gsm_settings *set = &ms->settings;
985 switch (argv[0][0]) {
987 set->sim_type = GSM_SIM_TYPE_NONE;
990 set->sim_type = GSM_SIM_TYPE_READER;
993 set->sim_type = GSM_SIM_TYPE_TEST;
996 vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
1004 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
1005 "Set network selection mode\nAutomatic network selection\n"
1006 "Manual network selection")
1008 struct osmocom_ms *ms = vty->index;
1009 struct gsm_settings *set = &ms->settings;
1012 if (!ms->plmn.state) {
1013 if (argv[0][0] == 'a')
1014 set->plmn_mode = PLMN_MODE_AUTO;
1016 set->plmn_mode = PLMN_MODE_MANUAL;
1020 if (argv[0][0] == 'a')
1021 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
1023 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
1026 gsm322_plmn_sendmsg(ms, nmsg);
1031 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
1032 "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
1033 "Software version digit")
1035 struct osmocom_ms *ms = vty->index;
1036 struct gsm_settings *set = &ms->settings;
1037 char *error, *sv = "0";
1040 sv = (char *)argv[1];
1042 error = gsm_check_imei(argv[0], sv);
1044 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1048 strcpy(set->imei, argv[0]);
1049 strcpy(set->imeisv, argv[0]);
1050 strcpy(set->imeisv + 15, sv);
1055 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
1056 "Use fixed IMEI on every power on")
1058 struct osmocom_ms *ms = vty->index;
1059 struct gsm_settings *set = &ms->settings;
1061 set->imei_random = 0;
1067 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
1068 "Use random IMEI on every power on\n"
1069 "Number of trailing digits to randomize")
1071 struct osmocom_ms *ms = vty->index;
1072 struct gsm_settings *set = &ms->settings;
1074 set->imei_random = atoi(argv[0]);
1080 DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
1081 "Use special IMSI for emergency calls\n15 digits IMSI")
1083 struct osmocom_ms *ms = vty->index;
1084 struct gsm_settings *set = &ms->settings;
1087 error = gsm_check_imsi(argv[0]);
1089 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1092 strcpy(set->emergency_imsi, argv[0]);
1097 DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
1098 NO_STR "Use IMSI of SIM or IMEI for emergency calls")
1100 struct osmocom_ms *ms = vty->index;
1101 struct gsm_settings *set = &ms->settings;
1103 set->emergency_imsi[0] = '\0';
1108 DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
1109 NO_STR "Disallow waiting calls")
1111 struct osmocom_ms *ms = vty->index;
1112 struct gsm_settings *set = &ms->settings;
1119 DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
1120 "Allow waiting calls")
1122 struct osmocom_ms *ms = vty->index;
1123 struct gsm_settings *set = &ms->settings;
1130 DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
1131 "Force caller ID presentation")
1133 struct osmocom_ms *ms = vty->index;
1134 struct gsm_settings *set = &ms->settings;
1142 DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
1143 "Force caller ID restriction")
1145 struct osmocom_ms *ms = vty->index;
1146 struct gsm_settings *set = &ms->settings;
1154 DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
1155 NO_STR "Disable forcing of caller ID presentation")
1157 struct osmocom_ms *ms = vty->index;
1158 struct gsm_settings *set = &ms->settings;
1165 DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
1166 NO_STR "Disable forcing of caller ID restriction")
1168 struct osmocom_ms *ms = vty->index;
1169 struct gsm_settings *set = &ms->settings;
1176 DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
1177 "Set the way to choose transmit power\nControlled by BTS\n"
1178 "Always full power\nFixed GSM power value if supported")
1180 struct osmocom_ms *ms = vty->index;
1181 struct gsm_settings *set = &ms->settings;
1183 switch (argv[0][0]) {
1185 set->alter_tx_power = 0;
1188 set->alter_tx_power = 1;
1189 set->alter_tx_power_value = 0;
1196 DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
1197 "Set the way to choose transmit power\n"
1198 "Fixed GSM power value if supported")
1200 struct osmocom_ms *ms = vty->index;
1201 struct gsm_settings *set = &ms->settings;
1203 set->alter_tx_power = 1;
1204 set->alter_tx_power_value = atoi(argv[0]);
1209 DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
1210 "Simulate a lower or higher distance from the BTS\n"
1211 "Delay in half bits (distance in 553.85 meter steps)")
1213 struct osmocom_ms *ms = vty->index;
1214 struct gsm_settings *set = &ms->settings;
1216 set->alter_delay = atoi(argv[0]);
1217 gsm48_rr_alter_delay(ms);
1222 DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
1223 NO_STR "Do not simulate a lower or higher distance from the BTS")
1225 struct osmocom_ms *ms = vty->index;
1226 struct gsm_settings *set = &ms->settings;
1228 set->alter_delay = 0;
1229 gsm48_rr_alter_delay(ms);
1234 DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
1235 "Stick to the given cell\nARFCN of the cell to stick to")
1237 struct osmocom_ms *ms = vty->index;
1238 struct gsm_settings *set = &ms->settings;
1241 set->stick_arfcn = atoi(argv[0]);
1246 DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
1247 NO_STR "Do not stick to any cell")
1249 struct osmocom_ms *ms = vty->index;
1250 struct gsm_settings *set = &ms->settings;
1257 DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
1258 "Allow location updating")
1260 struct osmocom_ms *ms = vty->index;
1261 struct gsm_settings *set = &ms->settings;
1268 DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
1269 NO_STR "Do not allow location updating")
1271 struct osmocom_ms *ms = vty->index;
1272 struct gsm_settings *set = &ms->settings;
1279 DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
1280 "Enable codec\nFull speed speech codec")
1282 struct osmocom_ms *ms = vty->index;
1283 struct gsm_settings *set = &ms->settings;
1285 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1286 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1293 DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
1295 "Enable codec\nFull speed speech codec\nPrefer this codec")
1297 struct osmocom_ms *ms = vty->index;
1298 struct gsm_settings *set = &ms->settings;
1300 if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
1301 vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
1305 set->half_prefer = 0;
1310 DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
1311 "Enable codec\nHalf speed speech codec")
1313 struct osmocom_ms *ms = vty->index;
1314 struct gsm_settings *set = &ms->settings;
1316 if (!set->half_v1 && !set->half_v3) {
1317 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1326 DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
1328 "Enable codec\nHalf speed speech codec\nPrefer this codec")
1330 struct osmocom_ms *ms = vty->index;
1331 struct gsm_settings *set = &ms->settings;
1333 if (!set->half_v1 && !set->half_v3) {
1334 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1339 set->half_prefer = 1;
1344 DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
1345 NO_STR "Disable codec\nHalf speed speech codec")
1347 struct osmocom_ms *ms = vty->index;
1348 struct gsm_settings *set = &ms->settings;
1350 if (!set->half_v1 && !set->half_v3) {
1351 vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
1356 set->half_prefer = 0;
1361 static int config_write_dummy(struct vty *vty)
1366 /* per support config */
1367 DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
1368 "Define supported features")
1370 vty->node = SUPPORT_NODE;
1375 #define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
1376 DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
1378 struct osmocom_ms *ms = vty->index; \
1379 struct gsm_settings *set = &ms->settings; \
1380 struct gsm_support *sup = &ms->support; \
1382 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1384 return CMD_SUCCESS; \
1385 return CMD_WARNING; \
1390 return CMD_SUCCESS; \
1393 #define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
1394 DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
1396 struct osmocom_ms *ms = vty->index; \
1397 struct gsm_settings *set = &ms->settings; \
1398 struct gsm_support *sup = &ms->support; \
1400 vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
1402 return CMD_SUCCESS; \
1403 return CMD_WARNING; \
1408 return CMD_SUCCESS; \
1411 SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
1412 SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
1413 SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1414 SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
1415 SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1416 SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
1417 SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1418 SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
1419 SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1420 SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
1421 SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1422 SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
1423 SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1424 SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
1425 SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
1426 SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
1427 SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
1429 SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
1431 SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
1433 SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
1435 SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
1437 SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
1439 SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1440 SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
1442 DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
1443 "Select power class for GSM 850/900\n"
1450 struct osmocom_ms *ms = vty->index;
1451 struct gsm_settings *set = &ms->settings;
1452 struct gsm_support *sup = &ms->support;
1454 set->class_900 = atoi(argv[0]);
1456 if (set->class_900 < sup->class_900 && !vty_reading)
1457 vty_out(vty, "You selected an higher class than supported "
1458 " by hardware!%s", VTY_NEWLINE);
1463 DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
1464 "Select power class for DCS 1800\n"
1469 struct osmocom_ms *ms = vty->index;
1470 struct gsm_settings *set = &ms->settings;
1471 struct gsm_support *sup = &ms->support;
1473 set->class_dcs = atoi(argv[0]);
1475 if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
1477 vty_out(vty, "You selected an higher class than supported "
1478 " by hardware!%s", VTY_NEWLINE);
1483 DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
1484 "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
1485 "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
1487 struct osmocom_ms *ms = vty->index;
1488 struct gsm_settings *set = &ms->settings;
1489 struct gsm_support *sup = &ms->support;
1492 if (!strcmp(argv[0], "sdcch+tchf+tchh"))
1493 ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
1494 else if (!strcmp(argv[0], "sdcch+tchf"))
1495 ch_cap = GSM_CAP_SDCCH_TCHF;
1497 ch_cap = GSM_CAP_SDCCH;
1499 if (ch_cap > sup->ch_cap && !vty_reading) {
1500 vty_out(vty, "You selected an higher capability than supported "
1501 " by hardware!%s", VTY_NEWLINE);
1505 if (ch_cap != set->ch_cap
1506 && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
1509 set->ch_cap = ch_cap;
1514 SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
1515 "Full rate speech V1", 0);
1516 SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
1517 "full-speech-v1", "Full rate speech V1", 0);
1518 SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
1519 "Full rate speech V2 (EFR)", 0);
1520 SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
1521 "full-speech-v2", "Full rate speech V2 (EFR)", 0);
1522 SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
1523 "Full rate speech V3 (AMR)", 0);
1524 SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
1525 "full-speech-v3", "Full rate speech V3 (AMR)", 0);
1526 SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
1527 "Half rate speech V1 (AMR)", 0);
1528 SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
1529 "half-speech-v1", "Half rate speech V1", 0);
1530 SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
1531 "Half rate speech V3 (AMR)", 0);
1532 SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
1533 "half-speech-v3", "Half rate speech V3", 0);
1535 DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
1536 "Set the minimum receive level to select a cell\n"
1537 "Minimum receive level from -110 dBm to -47 dBm")
1539 struct osmocom_ms *ms = vty->index;
1540 struct gsm_settings *set = &ms->settings;
1542 set->min_rxlev_db = atoi(argv[0]);
1547 DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
1548 "Set the maximum DSC value. Standard is 90. Increase to make mobile "
1549 "more reliable against bad RX signal. This increase the propability "
1550 "of missing a paging requests\n"
1551 "DSC initial and maximum value (standard is 90)")
1553 struct osmocom_ms *ms = vty->index;
1554 struct gsm_settings *set = &ms->settings;
1556 set->dsc_max = atoi(argv[0]);
1561 /* per testsim config */
1562 DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
1563 "Configure test SIM emulation")
1565 vty->node = TESTSIM_NODE;
1570 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
1571 "Set IMSI on test card\n15 digits IMSI")
1573 struct osmocom_ms *ms = vty->index;
1574 struct gsm_settings *set = &ms->settings;
1575 char *error = gsm_check_imsi(argv[0]);
1578 vty_out(vty, "%s%s", error, VTY_NEWLINE);
1582 strcpy(set->test_imsi, argv[0]);
1588 #define HEX_STR "\nByte as two digits hexadecimal"
1589 DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
1590 "HEX HEX HEX HEX HEX HEX",
1591 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1592 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
1594 struct osmocom_ms *ms = vty->index;
1595 struct gsm_settings *set = &ms->settings;
1600 for (i = 0; i < 12; i++) {
1602 if (!strncmp(p, "0x", 2))
1604 if (strlen(p) != 2) {
1605 vty_out(vty, "Expecting two digits hex value (with or "
1606 "without 0x in front)%s", VTY_NEWLINE);
1609 ki[i] = strtoul(p, NULL, 16);
1612 set->test_ki_type = GSM_SIM_KEY_XOR;
1613 memcpy(set->test_ki, ki, 12);
1617 DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
1618 "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
1619 "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
1620 HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
1621 HEX_STR HEX_STR HEX_STR HEX_STR)
1623 struct osmocom_ms *ms = vty->index;
1624 struct gsm_settings *set = &ms->settings;
1629 for (i = 0; i < 16; i++) {
1631 if (!strncmp(p, "0x", 2))
1633 if (strlen(p) != 2) {
1634 vty_out(vty, "Expecting two digits hex value (with or "
1635 "without 0x in front)%s", VTY_NEWLINE);
1638 ki[i] = strtoul(p, NULL, 16);
1641 set->test_ki_type = GSM_SIM_KEY_COMP128;
1642 memcpy(set->test_ki, ki, 16);
1646 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
1647 "Allow access to barred cells")
1649 struct osmocom_ms *ms = vty->index;
1650 struct gsm_settings *set = &ms->settings;
1657 DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
1658 NO_STR "Deny access to barred cells")
1660 struct osmocom_ms *ms = vty->index;
1661 struct gsm_settings *set = &ms->settings;
1668 DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
1669 NO_STR "Unset Registered PLMN")
1671 struct osmocom_ms *ms = vty->index;
1672 struct gsm_settings *set = &ms->settings;
1674 set->test_rplmn_valid = 0;
1680 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
1681 "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
1683 struct osmocom_ms *ms = vty->index;
1684 struct gsm_settings *set = &ms->settings;
1685 uint16_t mcc = gsm_input_mcc((char *)argv[0]),
1686 mnc = gsm_input_mnc((char *)argv[1]);
1689 vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
1693 vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
1696 set->test_rplmn_valid = 1;
1697 set->test_rplmn_mcc = mcc;
1698 set->test_rplmn_mnc = mnc;
1704 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
1705 "Set Home PLMN search mode\n"
1706 "Search for HPLMN when on any other network\n"
1707 "Search for HPLMN when in a different country")
1709 struct osmocom_ms *ms = vty->index;
1710 struct gsm_settings *set = &ms->settings;
1712 switch (argv[0][0]) {
1714 set->test_always = 1;
1717 set->test_always = 0;
1725 enum node_type ms_vty_go_parent(struct vty *vty)
1727 switch (vty->node) {
1729 vty->node = CONFIG_NODE;
1734 vty->node = MS_NODE;
1737 vty->node = CONFIG_NODE;
1743 /* Down vty node level. */
1744 gDEFUN(ournode_exit,
1745 ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
1747 switch (vty->node) {
1749 vty->node = CONFIG_NODE;
1754 vty->node = MS_NODE;
1762 /* End of configuration. */
1764 ournode_end_cmd, "end", "End current mode and change to enable mode.")
1766 switch (vty->node) {
1769 /* Nothing to do. */
1776 vty_config_unlock(vty);
1777 vty->node = ENABLE_NODE;
1779 vty->index_sub = NULL;
1787 #define SUP_NODE(item) \
1788 install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
1790 int ms_vty_init(void)
1792 install_element_ve(&show_ms_cmd);
1793 install_element_ve(&show_subscr_cmd);
1794 install_element_ve(&show_support_cmd);
1795 install_element_ve(&show_states_cmd);
1796 install_element_ve(&show_cell_cmd);
1797 install_element_ve(&show_cell_si_cmd);
1798 install_element_ve(&show_ba_cmd);
1799 install_element_ve(&show_forb_la_cmd);
1800 install_element_ve(&show_forb_plmn_cmd);
1801 install_element_ve(&monitor_network_cmd);
1802 install_element_ve(&no_monitor_network_cmd);
1804 install_element(ENABLE_NODE, &sim_test_cmd);
1805 install_element(ENABLE_NODE, &sim_reader_cmd);
1806 install_element(ENABLE_NODE, &sim_remove_cmd);
1807 install_element(ENABLE_NODE, &sim_pin_cmd);
1808 install_element(ENABLE_NODE, &sim_disable_pin_cmd);
1809 install_element(ENABLE_NODE, &sim_enable_pin_cmd);
1810 install_element(ENABLE_NODE, &sim_change_pin_cmd);
1811 install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
1812 install_element(ENABLE_NODE, &sim_lai_cmd);
1813 install_element(ENABLE_NODE, &network_search_cmd);
1814 install_element(ENABLE_NODE, &network_show_cmd);
1815 install_element(ENABLE_NODE, &network_select_cmd);
1816 install_element(ENABLE_NODE, &call_cmd);
1817 install_element(ENABLE_NODE, &call_retr_cmd);
1819 install_element(CONFIG_NODE, &cfg_gps_device_cmd);
1820 install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
1821 install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
1822 install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
1824 install_element(CONFIG_NODE, &cfg_ms_cmd);
1825 install_element(CONFIG_NODE, &ournode_end_cmd);
1826 install_node(&ms_node, config_write_ms);
1827 install_default(MS_NODE);
1828 install_element(MS_NODE, &ournode_exit_cmd);
1829 install_element(MS_NODE, &ournode_end_cmd);
1830 install_element(MS_NODE, &cfg_ms_sim_cmd);
1831 install_element(MS_NODE, &cfg_ms_mode_cmd);
1832 install_element(MS_NODE, &cfg_ms_imei_cmd);
1833 install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
1834 install_element(MS_NODE, &cfg_ms_imei_random_cmd);
1835 install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
1836 install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
1837 install_element(MS_NODE, &cfg_ms_cw_cmd);
1838 install_element(MS_NODE, &cfg_ms_no_cw_cmd);
1839 install_element(MS_NODE, &cfg_ms_clip_cmd);
1840 install_element(MS_NODE, &cfg_ms_clir_cmd);
1841 install_element(MS_NODE, &cfg_ms_no_clip_cmd);
1842 install_element(MS_NODE, &cfg_ms_no_clir_cmd);
1843 install_element(MS_NODE, &cfg_ms_tx_power_cmd);
1844 install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
1845 install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
1846 install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
1847 install_element(MS_NODE, &cfg_ms_stick_cmd);
1848 install_element(MS_NODE, &cfg_ms_no_stick_cmd);
1849 install_element(MS_NODE, &cfg_ms_lupd_cmd);
1850 install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
1851 install_element(MS_NODE, &cfg_ms_codec_full_cmd);
1852 install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
1853 install_element(MS_NODE, &cfg_ms_codec_half_cmd);
1854 install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
1855 install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
1856 install_element(MS_NODE, &cfg_ms_testsim_cmd);
1857 install_element(MS_NODE, &cfg_ms_support_cmd);
1858 install_node(&support_node, config_write_dummy);
1859 install_default(SUPPORT_NODE);
1860 install_element(SUPPORT_NODE, &ournode_exit_cmd);
1861 install_element(SUPPORT_NODE, &ournode_end_cmd);
1862 install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
1863 install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
1864 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
1865 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
1866 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
1867 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
1868 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
1869 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
1870 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
1871 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
1872 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
1873 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
1874 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
1875 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
1876 install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
1877 install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
1878 install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
1879 install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
1880 install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
1881 install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
1882 install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
1883 install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
1884 install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
1885 install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
1886 install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
1887 install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
1888 install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
1889 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
1890 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
1891 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
1892 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
1893 install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
1894 install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
1895 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
1896 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
1897 install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
1898 install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
1899 install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
1900 install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
1901 install_node(&testsim_node, config_write_dummy);
1902 install_default(TESTSIM_NODE);
1903 install_element(TESTSIM_NODE, &ournode_exit_cmd);
1904 install_element(TESTSIM_NODE, &ournode_end_cmd);
1905 install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
1906 install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
1907 install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
1908 install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
1909 install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
1910 install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
1911 install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
1912 install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
1917 void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
1919 struct telnet_connection *connection;
1925 va_start(args, fmt);
1926 vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
1927 buffer[sizeof(buffer) - 1] = '\0';
1934 llist_for_each_entry(connection, &active_connections, entry) {
1935 vty = connection->vty;
1939 vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
1943 if (buffer[strlen(buffer) - 1] == '\n') {
1944 buffer[strlen(buffer) - 1] = '\0';
1945 vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
1946 buffer[strlen(buffer)] = '\n';
1948 vty_out(vty, "%% %s", buffer);