Added ARFCN to system information dump.
[osmocom-bb.git] / src / host / layer23 / src / vty_interface.c
1 /*
2  * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
3  *
4  * All Rights Reserved
5  *
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.
10  *
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.
15  *
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.
19  *
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27
28 #include <vty/command.h>
29 #include <vty/buffer.h>
30 #include <vty/vty.h>
31
32 #include <osmocom/osmocom_data.h>
33 #include <osmocom/networks.h>
34
35 int mncc_call(struct osmocom_ms *ms, char *number);
36 int mncc_hangup(struct osmocom_ms *ms);
37 int mncc_answer(struct osmocom_ms *ms);
38
39 extern struct llist_head ms_list;
40
41 struct cmd_node ms_node = {
42         MS_NODE,
43         "%s(ms)#",
44         1
45 };
46
47 struct cmd_node testsim_node = {
48         TESTSIM_NODE,
49         "%s(test-sim)#",
50         1
51 };
52
53 static void print_vty(void *priv, const char *fmt, ...)
54 {
55         char buffer[1000];
56         struct vty *vty = priv;
57         va_list args;
58
59         va_start(args, fmt);
60         vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
61         buffer[sizeof(buffer) - 1] = '\0';
62         va_end(args);
63
64         if (buffer[0]) {
65                 if (buffer[strlen(buffer) - 1] == '\n') {
66                         buffer[strlen(buffer) - 1] = '\0';
67                         vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
68                 } else
69                         vty_out(vty, "%s", buffer);
70         }
71 }
72
73 static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
74 {
75         struct osmocom_ms *ms;
76
77         llist_for_each_entry(ms, &ms_list, entity) {
78                 if (!strcmp(ms->name, name))
79                         return ms;
80         }
81         vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
82
83         return NULL;
84 }
85
86 DEFUN(show_ms, show_ms_cmd, "show ms",
87         SHOW_STR "Display available MS entities\n")
88 {
89         struct osmocom_ms *ms;
90
91         llist_for_each_entry(ms, &ms_list, entity) {
92                 struct gsm_settings *set = &ms->settings;
93
94                 vty_out(vty, "MS NAME: %s%s", ms->name, VTY_NEWLINE);
95                 vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
96                 vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
97                 if (set->imei_random)
98                         vty_out(vty, " IMEI generation: random (%d trailing "
99                                 "digits)%s", set->imei_random, VTY_NEWLINE);
100                 else
101                         vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
102                 vty_out(vty, " network selection mode: %s%s",
103                         (set->plmn_mode == PLMN_MODE_AUTO)
104                                 ? "automatic" : "manual", VTY_NEWLINE);
105         }
106
107         return CMD_SUCCESS;
108 }
109
110 DEFUN(show_support, show_support_cmd, "show support [ms_name]",
111         SHOW_STR "Display information about MS support\n"
112         "Name of MS (see \"show ms\")")
113 {
114         struct osmocom_ms *ms;
115
116         if (argc) {
117                 ms = get_ms(argv[0], vty);
118                 if (!ms)
119                         return CMD_WARNING;
120                 gsm_support_dump(&ms->support, print_vty, vty);
121         } else {
122                 llist_for_each_entry(ms, &ms_list, entity) {
123                         gsm_support_dump(&ms->support, print_vty, vty);
124                         vty_out(vty, "%s", VTY_NEWLINE);
125                 }
126         }
127
128         return CMD_SUCCESS;
129 }
130
131 DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
132         SHOW_STR "Display information about subscriber\n"
133         "Name of MS (see \"show ms\")")
134 {
135         struct osmocom_ms *ms;
136
137         if (argc) {
138                 ms = get_ms(argv[0], vty);
139                 if (!ms)
140                         return CMD_WARNING;
141                 gsm_subscr_dump(&ms->subscr, print_vty, vty);
142         } else {
143                 llist_for_each_entry(ms, &ms_list, entity) {
144                         gsm_subscr_dump(&ms->subscr, print_vty, vty);
145                         vty_out(vty, "%s", VTY_NEWLINE);
146                 }
147         }
148
149         return CMD_SUCCESS;
150 }
151
152 DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
153         SHOW_STR "Display information about received cells\n"
154         "Name of MS (see \"show ms\")")
155 {
156         struct osmocom_ms *ms;
157
158         ms = get_ms(argv[0], vty);
159         if (!ms)
160                 return CMD_WARNING;
161
162         gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SYSINFO, print_vty,
163                 vty);
164
165         return CMD_SUCCESS;
166 }
167
168 DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
169         SHOW_STR "Display information about received cell\n"
170         "Name of MS (see \"show ms\")\nRadio frequency number")
171 {
172         struct osmocom_ms *ms;
173         int i;
174         struct gsm48_sysinfo *s;
175
176         ms = get_ms(argv[0], vty);
177         if (!ms)
178                 return CMD_WARNING;
179
180         i = atoi(argv[1]);
181         if (i < 0 || i > 1023) {
182                 vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
183                         argv[1], VTY_NEWLINE);
184                 return CMD_WARNING;
185         }
186         s = ms->cellsel.list[i].sysinfo;
187         if (!s) {
188                 vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
189                         argv[1], VTY_NEWLINE);
190                 return CMD_SUCCESS;
191         }
192
193         gsm48_sysinfo_dump(s, i, print_vty, vty);
194
195         return CMD_SUCCESS;
196 }
197
198 DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [mcc] [mnc]",
199         SHOW_STR "Display information about band allocations\n"
200         "Name of MS (see \"show ms\")\nMobile Country Code\n"
201         "Mobile Network Code")
202 {
203         struct osmocom_ms *ms;
204         uint16_t mcc = 0, mnc = 0;
205
206         ms = get_ms(argv[0], vty);
207         if (!ms)
208                 return CMD_WARNING;
209
210         if (argc >= 3) {
211                 mcc = atoi(argv[1]);
212                 mnc = atoi(argv[2]);
213         }
214
215         gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
216
217         return CMD_SUCCESS;
218 }
219
220 DEFUN(insert_test, insert_test_cmd, "insert testcard MS_NAME [mcc] [mnc]",
221         "Insert ...\nInsert test card\nName of MS (see \"show ms\")\n"
222         "Mobile Country Code\nMobile Network Code")
223 {
224         struct osmocom_ms *ms;
225         uint16_t mcc = 1, mnc = 1;
226
227         ms = get_ms(argv[0], vty);
228         if (!ms)
229                 return CMD_WARNING;
230
231         if (ms->subscr.sim_valid) {
232                 vty_out(vty, "Sim already presend, remove first!%s",
233                         VTY_NEWLINE);
234                 return CMD_WARNING;
235         }
236
237         if (argc >= 3) {
238                 mcc = atoi(argv[1]);
239                 mnc = atoi(argv[2]);
240         }
241
242         gsm_subscr_testcard(ms);
243
244         return CMD_SUCCESS;
245 }
246
247 DEFUN(remove_sim, remove_sim_cmd, "remove sim MS_NAME",
248         "Remove ...\nRemove SIM card\nName of MS (see \"show ms\")")
249 {
250         struct osmocom_ms *ms;
251
252         ms = get_ms(argv[0], vty);
253         if (!ms)
254                 return CMD_WARNING;
255
256         if (!ms->subscr.sim_valid) {
257                 vty_out(vty, "No Sim inserted!%s", VTY_NEWLINE);
258                 return CMD_WARNING;
259         }
260
261         gsm_subscr_remove(ms);
262
263         return CMD_SUCCESS;
264 }
265
266 DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC",
267         "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
268         "Mobile Country Code\nMobile Network Code")
269 {
270         struct osmocom_ms *ms;
271         struct gsm322_plmn *plmn;
272         struct msgb *nmsg;
273         struct gsm322_msg *ngm;
274         struct gsm322_plmn_list *temp;
275         uint16_t mcc, mnc;
276         int found = 0;
277
278         ms = get_ms(argv[0], vty);
279         if (!ms)
280                 return CMD_WARNING;
281         plmn = &ms->plmn;
282
283         mcc = atoi(argv[1]);
284         mnc = atoi(argv[2]);
285
286         llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
287                 if (temp->mcc == mcc &&  temp->mnc == mnc)
288                         found = 1;
289         if (!found) {
290                 vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
291                 return CMD_WARNING;
292         }
293
294         nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOSE_PLMN);
295         if (!nmsg)
296                 return CMD_WARNING;
297         ngm = (struct gsm322_msg *) nmsg->data;
298         ngm->mcc = mcc;
299         ngm->mnc = mnc;
300         gsm322_plmn_sendmsg(ms, nmsg);
301
302         return CMD_SUCCESS;
303 }
304
305 DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup)",
306         "Make a call\nName of MS (see \"show ms\")\nPhone number to call\n"
307         "Make an emergency call\nAnswer an incomming call\nHangup a call")
308 {
309         struct osmocom_ms *ms;
310
311         ms = get_ms(argv[0], vty);
312         if (!ms)
313                 return CMD_WARNING;
314
315         switch (argv[1][0]) {
316         case 'a':
317                 mncc_answer(ms);
318                 break;
319         case 'h':
320                 mncc_hangup(ms);
321                 break;
322         default:
323                 mncc_call(ms, (char *)argv[1]);
324         }
325
326         return CMD_SUCCESS;
327 }
328
329 DEFUN(network_show, network_show_cmd, "network show MS_NAME",
330         "Network ...\nShow results of network search (again)\n"
331         "Name of MS (see \"show ms\")")
332 {
333         struct osmocom_ms *ms;
334         struct gsm322_plmn *plmn;
335         struct gsm322_plmn_list *temp;
336
337         ms = get_ms(argv[0], vty);
338         if (!ms)
339                 return CMD_WARNING;
340         plmn = &ms->plmn;
341
342         if (ms->settings.plmn_mode != PLMN_MODE_AUTO
343          && plmn->state != GSM322_M3_NOT_ON_PLMN) {
344                 vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
345                 return CMD_WARNING;
346         }
347
348         llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
349                 vty_out(vty, " Network %03d, %02d (%s, %s)%s", temp->mcc,
350                         temp->mnc, gsm_get_mcc(temp->mcc),
351                         gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
352
353         return CMD_SUCCESS;
354 }
355
356 DEFUN(network_search, network_search_cmd, "network search MS_NAME",
357         "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
358 {
359         struct osmocom_ms *ms;
360         struct msgb *nmsg;
361
362         ms = get_ms(argv[0], vty);
363         if (!ms)
364                 return CMD_WARNING;
365
366         nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
367         if (!nmsg)
368                 return CMD_WARNING;
369         gsm322_plmn_sendmsg(ms, nmsg);
370
371         return CMD_SUCCESS;
372 }
373
374 /* per MS config */
375 DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
376         "Select a mobile station to configure\nName of MS (see \"show ms\")")
377 {
378         struct osmocom_ms *ms;
379
380         ms = get_ms(argv[0], vty);
381         if (!ms)
382                 return CMD_WARNING;
383
384         vty->index = ms;
385         vty->node = MS_NODE;
386
387         return CMD_SUCCESS;
388 }
389
390 static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
391 {
392         struct gsm_settings *set = &ms->settings;
393
394         vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
395         switch(ms->settings.simtype) {
396                 case GSM_SIM_TYPE_NONE:
397                 vty_out(vty, " sim none%s", VTY_NEWLINE);
398                 break;
399                 case GSM_SIM_TYPE_SLOT:
400                 vty_out(vty, " sim slot%s", VTY_NEWLINE);
401                 break;
402                 case GSM_SIM_TYPE_TEST:
403                 vty_out(vty, " sim test%s", VTY_NEWLINE);
404                 break;
405         }
406         vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
407                         == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
408         vty_out(vty, " imei %s %s%s", set->imei,
409                 set->imeisv + strlen(set->imei), VTY_NEWLINE);
410         if (set->imei_random)
411                 vty_out(vty, " imei-random %d%s", set->imei_random,
412                         VTY_NEWLINE);
413         else
414                 vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
415         vty_out(vty, " test-sim%s", VTY_NEWLINE);
416         vty_out(vty, "  imsi %s%s", ms->settings.test_imsi, VTY_NEWLINE);
417         vty_out(vty, "  barred-access %s%s", (set->test_barr) ? "yes" : "no",
418                 VTY_NEWLINE);
419         if (ms->settings.test_rplmn_valid)
420                 vty_out(vty, "  rplmn-valid%s", VTY_NEWLINE);
421         else
422                 vty_out(vty, "  rplmn-invalid%s", VTY_NEWLINE);
423         vty_out(vty, "  rplmn %03d %02d%s", ms->settings.test_rplmn_mcc,
424                 ms->settings.test_rplmn_mnc, VTY_NEWLINE);
425         vty_out(vty, "  hplmn-search %s%s", (set->test_always) ? "everywhere"
426                         : "foreign-country", VTY_NEWLINE);
427         vty_out(vty, " exit%s", VTY_NEWLINE);
428         vty_out(vty, "exit%s", VTY_NEWLINE);
429         vty_out(vty, "!%s", VTY_NEWLINE);
430 }
431
432 static int config_write_ms(struct vty *vty)
433 {
434         struct osmocom_ms *ms;
435
436         llist_for_each_entry(ms, &ms_list, entity)
437                 config_write_ms_single(vty, ms);
438
439         return CMD_SUCCESS;
440 }
441
442 DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
443         "Set network selection mode\nAutomatic network selection\n"
444         "Manual network selection")
445 {
446         struct osmocom_ms *ms = vty->index;
447         struct msgb *nmsg;
448
449         if (!ms->plmn.state) {
450                 if (argv[0][0] == 'a')
451                         ms->settings.plmn_mode = PLMN_MODE_AUTO;
452                 else
453                         ms->settings.plmn_mode = PLMN_MODE_MANUAL;
454
455                 return CMD_SUCCESS;
456         }
457         if (argv[0][0] == 'a')
458                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
459         else
460                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
461         if (!nmsg)
462                 return CMD_WARNING;
463         gsm322_plmn_sendmsg(ms, nmsg);
464
465         return CMD_SUCCESS;
466 }
467
468 DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
469         "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
470         "Software version digit")
471 {
472         struct osmocom_ms *ms = vty->index;
473         char *error, *sv = "0";
474
475         if (argc >= 2)
476                 sv = (char *)argv[1];
477
478         error = gsm_check_imei(argv[0], sv);
479         if (error) {
480                 vty_out(vty, "%s%s", error, VTY_NEWLINE);
481                 return CMD_WARNING;
482         }
483
484         strcpy(ms->settings.imei, argv[0]);
485         strcpy(ms->settings.imeisv, argv[0]);
486         strcpy(ms->settings.imeisv + 15, sv);
487
488         return CMD_SUCCESS;
489 }
490
491 DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
492         "Use fixed IMEI on every power on")
493 {
494         struct osmocom_ms *ms = vty->index;
495
496         ms->settings.imei_random = 0;
497
498         return CMD_SUCCESS;
499 }
500
501 DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
502         "Use random IMEI on every power on\n"
503         "Number of trailing digits to randomize")
504 {
505         struct osmocom_ms *ms = vty->index;
506
507         ms->settings.imei_random = atoi(argv[0]);
508
509         return CMD_SUCCESS;
510 }
511
512 DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|test)",
513         "Set sim card type when powering on\nNo sim interted\n"
514         "Test sim inserted")
515 {
516         struct osmocom_ms *ms = vty->index;
517
518         switch (argv[0][0]) {
519         case 'n':
520                 ms->settings.simtype = GSM_SIM_TYPE_NONE;
521                 break;
522         case 's':
523                 ms->settings.simtype = GSM_SIM_TYPE_SLOT;
524                 break;
525         case 't':
526                 ms->settings.simtype = GSM_SIM_TYPE_TEST;
527                 break;
528         }
529
530         return CMD_SUCCESS;
531 }
532
533 /* per MS config */
534 DEFUN(cfg_testsim, cfg_testsim_cmd, "test-sim",
535         "Configure test SIM emulation")
536 {
537         vty->node = TESTSIM_NODE;
538
539         return CMD_SUCCESS;
540 }
541
542 static int config_write_dummy(struct vty *vty)
543 {
544         return CMD_SUCCESS;
545 }
546
547 DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
548         "Set IMSI on test card\n15 Digits IMSI")
549 {
550         struct osmocom_ms *ms = vty->index;
551         uint16_t mcc, mnc;
552         char *error = gsm_check_imsi(argv[0], &mcc, &mnc);
553
554         if (error) {
555                 vty_out(vty, "%s%s", error, VTY_NEWLINE);
556                 return CMD_WARNING;
557         }
558
559         strcpy(ms->settings.test_imsi, argv[0]);
560
561         return CMD_SUCCESS;
562 }
563
564 DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access (yes|no)",
565         "Allow access to barred cells\nAccess allowed\nAccess denied")
566 {
567         struct osmocom_ms *ms = vty->index;
568
569         switch (argv[0][0]) {
570         case 'y':
571                 ms->settings.test_barr = 1;
572                 break;
573         case 'n':
574                 ms->settings.test_barr = 0;
575                 break;
576         }
577
578         return CMD_SUCCESS;
579 }
580
581 DEFUN(cfg_test_rplmn_valid, cfg_test_rplmn_valid_cmd, "rplmn-valid",
582         "Mark Registered PLMN as valid")
583 {
584         struct osmocom_ms *ms = vty->index;
585
586         ms->settings.test_rplmn_valid = 1;
587
588         return CMD_SUCCESS;
589 }
590
591 DEFUN(cfg_test_rplmn_invalid, cfg_test_rplmn_invalid_cmd, "rplmn-invalid",
592         "Mark Registered PLMN as invalid")
593 {
594         struct osmocom_ms *ms = vty->index;
595
596         ms->settings.test_rplmn_valid = 0;
597
598         return CMD_SUCCESS;
599 }
600
601 DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
602         "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
603 {
604         struct osmocom_ms *ms = vty->index;
605
606         ms->settings.test_rplmn_mcc = atoi(argv[0]);
607         ms->settings.test_rplmn_mnc = atoi(argv[1]);
608
609         return CMD_SUCCESS;
610 }
611
612 DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
613         "Set Home PLMN search mode\n"
614         "Search for HPLMN when on any other network\n"
615         "Search for HPLMN when in a different country")
616 {
617         struct osmocom_ms *ms = vty->index;
618
619         switch (argv[0][0]) {
620         case 'e':
621                 ms->settings.test_always = 1;
622                 break;
623         case 'f':
624                 ms->settings.test_always = 0;
625                 break;
626         }
627
628         return CMD_SUCCESS;
629 }
630
631 int ms_vty_init(void)
632 {
633         cmd_init(1);
634         vty_init();
635
636         install_element(ENABLE_NODE, &show_ms_cmd);
637         install_element(VIEW_NODE, &show_ms_cmd);
638         install_element(ENABLE_NODE, &show_subscr_cmd);
639         install_element(VIEW_NODE, &show_subscr_cmd);
640         install_element(ENABLE_NODE, &show_support_cmd);
641         install_element(VIEW_NODE, &show_support_cmd);
642         install_element(ENABLE_NODE, &show_cell_cmd);
643         install_element(VIEW_NODE, &show_cell_cmd);
644         install_element(ENABLE_NODE, &show_cell_si_cmd);
645         install_element(VIEW_NODE, &show_cell_si_cmd);
646         install_element(ENABLE_NODE, &show_ba_cmd);
647         install_element(VIEW_NODE, &show_ba_cmd);
648
649         install_element(ENABLE_NODE, &insert_test_cmd);
650         install_element(ENABLE_NODE, &remove_sim_cmd);
651         install_element(ENABLE_NODE, &network_search_cmd);
652         install_element(ENABLE_NODE, &network_show_cmd);
653         install_element(ENABLE_NODE, &network_select_cmd);
654         install_element(ENABLE_NODE, &call_cmd);
655
656         install_element(CONFIG_NODE, &cfg_ms_cmd);
657         install_node(&ms_node, config_write_ms);
658         install_default(MS_NODE);
659         install_element(MS_NODE, &cfg_ms_mode_cmd);
660         install_element(MS_NODE, &cfg_ms_imei_cmd);
661         install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
662         install_element(MS_NODE, &cfg_ms_imei_random_cmd);
663         install_element(MS_NODE, &cfg_ms_sim_cmd);
664
665         install_element(MS_NODE, &cfg_testsim_cmd);
666         install_node(&testsim_node, config_write_dummy);
667         install_default(TESTSIM_NODE);
668         install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
669         install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
670         install_element(TESTSIM_NODE, &cfg_test_rplmn_valid_cmd);
671         install_element(TESTSIM_NODE, &cfg_test_rplmn_invalid_cmd);
672         install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
673         install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
674
675         return 0;
676 }
677