blob: 029f0c4abced6e64ab3a047729595fc55725f97a [file] [log] [blame]
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02001/* OpenBSC interface to quagga VTY */
2/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freythere33966c2009-10-27 12:47:06 +01003 * (C) 2009 by Holger Hans Peter Freyther
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02004 * 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 <stdlib.h>
23#include <unistd.h>
24#include <sys/types.h>
25
26#include <vty/command.h>
27#include <vty/buffer.h>
28#include <vty/vty.h>
29
30#include <arpa/inet.h>
31
Harald Weltedfe6c7d2010-02-20 16:24:02 +010032#include <osmocore/linuxlist.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020033#include <openbsc/gsm_data.h>
34#include <openbsc/gsm_subscriber.h>
Harald Welteb54d9502009-11-17 06:00:23 +010035#include <openbsc/silent_call.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020036#include <openbsc/gsm_04_11.h>
37#include <openbsc/e1_input.h>
38#include <openbsc/abis_nm.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010039#include <osmocore/gsm_utils.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020040#include <openbsc/db.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010041#include <osmocore/talloc.h>
Harald Weltea1482332009-11-14 10:08:40 +010042#include <openbsc/signal.h>
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +010043#include <openbsc/debug.h>
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +020044#include <openbsc/vty.h>
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020045
46static struct gsm_network *gsmnet;
47
48struct cmd_node subscr_node = {
49 SUBSCR_NODE,
50 "%s(subscriber)#",
51 1,
52};
53
54static int dummy_config_write(struct vty *v)
55{
56 return CMD_SUCCESS;
57}
58
Sylvain Munaut99792902009-12-27 19:30:46 +010059static int hexparse(const char *str, u_int8_t *b, int max_len)
60
61{
62 int i, l, v;
63
64 l = strlen(str);
65 if ((l&1) || ((l>>1) > max_len))
66 return -1;
67
68 memset(b, 0x00, max_len);
69
70 for (i=0; i<l; i++) {
71 char c = str[i];
72 if (c >= '0' && c <= '9')
73 v = c - '0';
74 else if (c >= 'a' && c <= 'f')
75 v = 10 + (c - 'a');
76 else if (c >= 'A' && c <= 'F')
77 v = 10 + (c - 'a');
78 else
79 return -1;
80 b[i>>1] |= v << (i&1 ? 0 : 4);
81 }
82
83 return i>>1;
84}
85
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +020086/* per-subscriber configuration */
87DEFUN(cfg_subscr,
88 cfg_subscr_cmd,
89 "subscriber IMSI",
90 "Select a Subscriber to configure\n")
91{
92 const char *imsi = argv[0];
93 struct gsm_subscriber *subscr;
94
95 subscr = subscr_get_by_imsi(gsmnet, imsi);
96 if (!subscr) {
97 vty_out(vty, "%% No subscriber for IMSI %s%s",
98 imsi, VTY_NEWLINE);
99 return CMD_WARNING;
100 }
101
Holger Hans Peter Freythere33966c2009-10-27 12:47:06 +0100102 /* vty_go_parent should put this subscriber */
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200103 vty->index = subscr;
104 vty->node = SUBSCR_NODE;
105
106 return CMD_SUCCESS;
107}
108
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100109static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr)
110{
111 int rc;
112 struct gsm_auth_info ainfo;
113 struct gsm_auth_tuple atuple;
114
115 vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
116 subscr->authorized, VTY_NEWLINE);
117 if (subscr->name)
118 vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
119 if (subscr->extension)
120 vty_out(vty, " Extension: %s%s", subscr->extension,
121 VTY_NEWLINE);
122 if (subscr->imsi)
123 vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
124 if (subscr->tmsi != GSM_RESERVED_TMSI)
125 vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
126 VTY_NEWLINE);
127
128 rc = get_authinfo_by_subscr(&ainfo, subscr);
129 if (!rc) {
130 vty_out(vty, " A3A8 algorithm id: %d%s",
131 ainfo.auth_algo, VTY_NEWLINE);
132 vty_out(vty, " A3A8 Ki: %s%s",
133 hexdump(ainfo.a3a8_ki, ainfo.a3a8_ki_len),
134 VTY_NEWLINE);
135 }
136
137 rc = get_authtuple_by_subscr(&atuple, subscr);
138 if (!rc) {
139 vty_out(vty, " A3A8 last tuple (used %d times):%s",
140 atuple.use_count, VTY_NEWLINE);
141 vty_out(vty, " seq # : %d%s",
142 atuple.key_seq, VTY_NEWLINE);
143 vty_out(vty, " RAND : %s%s",
144 hexdump(atuple.rand, sizeof(atuple.rand)),
145 VTY_NEWLINE);
146 vty_out(vty, " SRES : %s%s",
147 hexdump(atuple.sres, sizeof(atuple.sres)),
148 VTY_NEWLINE);
149 vty_out(vty, " Kc : %s%s",
150 hexdump(atuple.kc, sizeof(atuple.kc)),
151 VTY_NEWLINE);
152 }
153
154 vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
155}
156
157
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200158/* Subscriber */
159DEFUN(show_subscr,
160 show_subscr_cmd,
161 "show subscriber [IMSI]",
162 SHOW_STR "Display information about a subscriber\n")
163{
164 const char *imsi;
165 struct gsm_subscriber *subscr;
166
167 if (argc >= 1) {
168 imsi = argv[0];
169 subscr = subscr_get_by_imsi(gsmnet, imsi);
170 if (!subscr) {
171 vty_out(vty, "%% unknown subscriber%s",
172 VTY_NEWLINE);
173 return CMD_WARNING;
174 }
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100175 subscr_dump_full_vty(vty, subscr);
Holger Hans Peter Freythere33966c2009-10-27 12:47:06 +0100176 subscr_put(subscr);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200177
178 return CMD_SUCCESS;
179 }
180
181 /* FIXME: iterate over all subscribers ? */
182 return CMD_WARNING;
183
184 return CMD_SUCCESS;
185}
186
187DEFUN(show_subscr_cache,
188 show_subscr_cache_cmd,
189 "show subscriber cache",
190 SHOW_STR "Display contents of subscriber cache\n")
191{
192 struct gsm_subscriber *subscr;
193
194 llist_for_each_entry(subscr, &active_subscribers, entry) {
195 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100196 subscr_dump_full_vty(vty, subscr);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200197 }
198
199 return CMD_SUCCESS;
200}
201
202DEFUN(sms_send_pend,
203 sms_send_pend_cmd,
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100204 "sms send pending",
205 "Send all pending SMS")
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200206{
207 struct gsm_sms *sms;
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100208 int id = 0;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200209
210 while (1) {
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100211 sms = db_sms_get_unsent_by_subscr(gsmnet, id);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200212 if (!sms)
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100213 break;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200214
215 gsm411_send_sms_subscr(sms->receiver, sms);
Sylvain Munautff1f19e2009-12-22 13:22:29 +0100216
217 id = sms->receiver->id + 1;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200218 }
219
220 return CMD_SUCCESS;
221}
222
223struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, const char *text)
224{
225 struct gsm_sms *sms = sms_alloc();
226
227 if (!sms)
228 return NULL;
229
230 if (!receiver->lac) {
231 /* subscriber currently not attached, store in database? */
232 return NULL;
233 }
234
235 sms->receiver = subscr_get(receiver);
236 strncpy(sms->text, text, sizeof(sms->text)-1);
237
238 /* FIXME: don't use ID 1 static */
239 sms->sender = subscr_get_by_id(gsmnet, 1);
240 sms->reply_path_req = 0;
241 sms->status_rep_req = 0;
242 sms->ud_hdr_ind = 0;
243 sms->protocol_id = 0; /* implicit */
244 sms->data_coding_scheme = 0; /* default 7bit */
245 strncpy(sms->dest_addr, receiver->extension, sizeof(sms->dest_addr)-1);
246 /* Generate user_data */
247 sms->user_data_len = gsm_7bit_encode(sms->user_data, sms->text);
248
249 return sms;
250}
251
252static int _send_sms_buffer(struct gsm_subscriber *receiver,
Harald Welte793a1352009-11-05 15:51:17 +0900253 struct buffer *b, u_int8_t tp_pid)
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200254{
255 struct gsm_sms *sms;
256
257 sms = sms_from_text(receiver, buffer_getstr(b));
Harald Welte793a1352009-11-05 15:51:17 +0900258 sms->protocol_id = tp_pid;
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200259 gsm411_send_sms_subscr(receiver, sms);
260
261 return CMD_SUCCESS;
262}
263
Harald Welte98f9c752009-11-14 08:00:53 +0100264static struct gsm_subscriber *get_subscr_by_argv(const char *type,
265 const char *id)
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200266{
Harald Welte98f9c752009-11-14 08:00:53 +0100267 if (!strcmp(type, "extension"))
268 return subscr_get_by_extension(gsmnet, id);
269 else if (!strcmp(type, "imsi"))
270 return subscr_get_by_imsi(gsmnet, id);
271 else if (!strcmp(type, "tmsi"))
272 return subscr_get_by_tmsi(gsmnet, atoi(id));
273 else if (!strcmp(type, "id"))
274 return subscr_get_by_id(gsmnet, atoi(id));
275
276 return NULL;
277}
278#define SUBSCR_TYPES "(extension|imsi|tmsi|id)"
279
280DEFUN(subscriber_send_sms,
281 subscriber_send_sms_cmd,
282 "subscriber " SUBSCR_TYPES " EXTEN sms send .LINE",
283 "Select subscriber based on extension")
284{
285 struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200286 struct buffer *b;
287 int rc;
288
Harald Welte20f98312009-11-14 10:11:45 +0100289 if (!subscr) {
290 vty_out(vty, "%% No subscriber found for %s %s%s",
291 argv[0], argv[1], VTY_NEWLINE);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200292 return CMD_WARNING;
Harald Welte20f98312009-11-14 10:11:45 +0100293 }
Harald Welte197dea92010-05-14 17:59:53 +0200294 b = vty_argv_to_buffer(argc, argv, 2);
Harald Welte98f9c752009-11-14 08:00:53 +0100295 rc = _send_sms_buffer(subscr, b, 0);
Harald Welte793a1352009-11-05 15:51:17 +0900296 buffer_free(b);
297
Harald Welteaf8c7b42009-11-14 10:10:54 +0100298 subscr_put(subscr);
299
Harald Welte793a1352009-11-05 15:51:17 +0900300 return rc;
301}
302
Harald Welte98f9c752009-11-14 08:00:53 +0100303DEFUN(subscriber_silent_sms,
304 subscriber_silent_sms_cmd,
305 "subscriber " SUBSCR_TYPES " EXTEN silent sms send .LINE",
306 "Select subscriber based on extension")
Harald Welte793a1352009-11-05 15:51:17 +0900307{
Harald Welte98f9c752009-11-14 08:00:53 +0100308 struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
Harald Welte793a1352009-11-05 15:51:17 +0900309 struct buffer *b;
310 int rc;
311
Harald Welte20f98312009-11-14 10:11:45 +0100312 if (!subscr) {
313 vty_out(vty, "%% No subscriber found for %s %s%s",
314 argv[0], argv[1], VTY_NEWLINE);
Harald Welte793a1352009-11-05 15:51:17 +0900315 return CMD_WARNING;
Harald Welte20f98312009-11-14 10:11:45 +0100316 }
Harald Welte793a1352009-11-05 15:51:17 +0900317
Harald Welte197dea92010-05-14 17:59:53 +0200318 b = vty_argv_to_buffer(argc, argv, 2);
Harald Welteaf8c7b42009-11-14 10:10:54 +0100319 rc = _send_sms_buffer(subscr, b, 64);
Harald Welte793a1352009-11-05 15:51:17 +0900320 buffer_free(b);
321
Harald Welteaf8c7b42009-11-14 10:10:54 +0100322 subscr_put(subscr);
323
Harald Welte793a1352009-11-05 15:51:17 +0900324 return rc;
325}
326
Sylvain Munaut50480702010-01-02 14:29:43 +0100327DEFUN(subscriber_silent_call_start,
328 subscriber_silent_call_start_cmd,
329 "subscriber " SUBSCR_TYPES " EXTEN silent call start (any|tch/f|tch/any|sdcch)",
330 "Start a silent call to a subscriber")
331{
332 struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
333 int rc, type;
334
335 if (!subscr) {
336 vty_out(vty, "%% No subscriber found for %s %s%s",
337 argv[0], argv[1], VTY_NEWLINE);
338 return CMD_WARNING;
339 }
340
341 if (!strcmp(argv[2], "tch/f"))
342 type = RSL_CHANNEED_TCH_F;
343 else if (!strcmp(argv[2], "tch/any"))
344 type = RSL_CHANNEED_TCH_ForH;
345 else if (!strcmp(argv[2], "sdcch"))
346 type = RSL_CHANNEED_SDCCH;
347 else
348 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
349
350 rc = gsm_silent_call_start(subscr, vty, type);
351 if (rc <= 0) {
352 vty_out(vty, "%% Subscriber not attached%s",
353 VTY_NEWLINE);
354 subscr_put(subscr);
355 return CMD_WARNING;
356 }
357
358 subscr_put(subscr);
359
360 return CMD_SUCCESS;
361}
362
363DEFUN(subscriber_silent_call_stop,
364 subscriber_silent_call_stop_cmd,
365 "subscriber " SUBSCR_TYPES " EXTEN silent call stop",
366 "Stop a silent call to a subscriber")
Harald Weltea1482332009-11-14 10:08:40 +0100367{
368 struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
369 int rc;
370
371 if (!subscr) {
372 vty_out(vty, "%% No subscriber found for %s %s%s",
Harald Welte20f98312009-11-14 10:11:45 +0100373 argv[0], argv[1], VTY_NEWLINE);
Harald Weltea1482332009-11-14 10:08:40 +0100374 return CMD_WARNING;
375 }
376
Sylvain Munaut50480702010-01-02 14:29:43 +0100377 rc = gsm_silent_call_stop(subscr);
378 if (rc < 0) {
379 subscr_put(subscr);
380 return CMD_WARNING;
Harald Weltea1482332009-11-14 10:08:40 +0100381 }
382
383 subscr_put(subscr);
384
385 return CMD_SUCCESS;
386}
387
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200388DEFUN(cfg_subscr_name,
389 cfg_subscr_name_cmd,
390 "name NAME",
391 "Set the name of the subscriber")
392{
393 const char *name = argv[0];
394 struct gsm_subscriber *subscr = vty->index;
395
396 strncpy(subscr->name, name, sizeof(subscr->name));
397
398 db_sync_subscriber(subscr);
399
400 return CMD_SUCCESS;
401}
402
403DEFUN(cfg_subscr_extension,
404 cfg_subscr_extension_cmd,
405 "extension EXTENSION",
406 "Set the extension of the subscriber")
407{
408 const char *name = argv[0];
409 struct gsm_subscriber *subscr = vty->index;
410
411 strncpy(subscr->extension, name, sizeof(subscr->extension));
412
413 db_sync_subscriber(subscr);
414
415 return CMD_SUCCESS;
416}
417
418DEFUN(cfg_subscr_authorized,
419 cfg_subscr_authorized_cmd,
420 "auth <0-1>",
421 "Set the authorization status of the subscriber")
422{
423 int auth = atoi(argv[0]);
424 struct gsm_subscriber *subscr = vty->index;
425
426 if (auth)
427 subscr->authorized = 1;
428 else
429 subscr->authorized = 0;
430
431 db_sync_subscriber(subscr);
432
433 return CMD_SUCCESS;
434}
435
Sylvain Munaut99792902009-12-27 19:30:46 +0100436#define A3A8_ALG_TYPES "(none|comp128v1)"
437
438DEFUN(cfg_subscr_a3a8,
439 cfg_subscr_a3a8_cmd,
440 "a3a8 " A3A8_ALG_TYPES " [KI]",
441 "Set a3a8 parameters for the subscriber")
442{
443 struct gsm_subscriber *subscr = vty->index;
444 const char *alg_str = argv[0];
445 const char *ki_str = argv[1];
446 struct gsm_auth_info ainfo;
447 int rc;
448
449 if (!strcasecmp(alg_str, "none")) {
450 /* Just erase */
451 rc = set_authinfo_for_subscr(NULL, subscr);
452 } else if (!strcasecmp(alg_str, "comp128v1")) {
453 /* Parse hex string Ki */
454 rc = hexparse(ki_str, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki));
455 if (rc != 16)
456 return CMD_WARNING;
457
458 /* Set the infos */
459 ainfo.auth_algo = AUTH_ALGO_COMP128v1;
460 ainfo.a3a8_ki_len = rc;
461 rc = set_authinfo_for_subscr(&ainfo, subscr);
462 } else {
463 /* Unknown method */
464 return CMD_WARNING;
465 }
466
467 return rc ? CMD_WARNING : CMD_SUCCESS;
468}
469
Harald Weltea1482332009-11-14 10:08:40 +0100470static int scall_cbfn(unsigned int subsys, unsigned int signal,
471 void *handler_data, void *signal_data)
472{
473 struct scall_signal_data *sigdata = signal_data;
474 struct vty *vty = sigdata->data;
475
476 switch (signal) {
477 case S_SCALL_SUCCESS:
478 vty_out(vty, "%% silent call on ARFCN %u timeslot %u%s",
479 sigdata->lchan->ts->trx->arfcn, sigdata->lchan->ts->nr,
480 VTY_NEWLINE);
481 break;
482 case S_SCALL_EXPIRED:
483 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
484 break;
485 }
486 return 0;
487}
488
Holger Hans Peter Freythere0ec3262010-04-15 11:28:14 +0200489DEFUN(show_stats,
490 show_stats_cmd,
491 "show statistics",
492 SHOW_STR "Display network statistics\n")
493{
494 struct gsm_network *net = gsmnet;
495
496 openbsc_vty_print_statistics(vty, net);
497 vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
498 counter_get(net->stats.loc_upd_type.attach),
499 counter_get(net->stats.loc_upd_type.normal),
500 counter_get(net->stats.loc_upd_type.periodic), VTY_NEWLINE);
501 vty_out(vty, "IMSI Detach Indications : %lu%s",
502 counter_get(net->stats.loc_upd_type.detach), VTY_NEWLINE);
503 vty_out(vty, "Location Update Response: %lu accept, %lu reject%s",
504 counter_get(net->stats.loc_upd_resp.accept),
505 counter_get(net->stats.loc_upd_resp.reject), VTY_NEWLINE);
506 vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, "
507 "%lu completed, %lu failed%s",
508 counter_get(net->stats.handover.attempted),
509 counter_get(net->stats.handover.no_channel),
510 counter_get(net->stats.handover.timeout),
511 counter_get(net->stats.handover.completed),
512 counter_get(net->stats.handover.failed), VTY_NEWLINE);
513 vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s",
514 counter_get(net->stats.sms.submitted),
515 counter_get(net->stats.sms.no_receiver), VTY_NEWLINE);
516 vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s",
517 counter_get(net->stats.sms.delivered),
518 counter_get(net->stats.sms.rp_err_mem),
519 counter_get(net->stats.sms.rp_err_other), VTY_NEWLINE);
520 return CMD_SUCCESS;
521}
522
523
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200524int bsc_vty_init_extra(struct gsm_network *net)
525{
526 gsmnet = net;
527
Harald Weltea1482332009-11-14 10:08:40 +0100528 register_signal_handler(SS_SCALL, scall_cbfn, NULL);
529
Harald Welteb4d5b172010-05-12 16:10:35 +0000530 install_element_ve(&show_subscr_cmd);
531 install_element_ve(&show_subscr_cache_cmd);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200532
Harald Welteb4d5b172010-05-12 16:10:35 +0000533 install_element_ve(&sms_send_pend_cmd);
Harald Welte98f9c752009-11-14 08:00:53 +0100534
Harald Welteb4d5b172010-05-12 16:10:35 +0000535 install_element_ve(&subscriber_send_sms_cmd);
536 install_element_ve(&subscriber_silent_sms_cmd);
537 install_element_ve(&subscriber_silent_call_start_cmd);
538 install_element_ve(&subscriber_silent_call_stop_cmd);
539 install_element_ve(&show_stats_cmd);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200540
541 install_element(CONFIG_NODE, &cfg_subscr_cmd);
542 install_node(&subscr_node, dummy_config_write);
543
544 install_default(SUBSCR_NODE);
545 install_element(SUBSCR_NODE, &cfg_subscr_name_cmd);
546 install_element(SUBSCR_NODE, &cfg_subscr_extension_cmd);
547 install_element(SUBSCR_NODE, &cfg_subscr_authorized_cmd);
Sylvain Munaut99792902009-12-27 19:30:46 +0100548 install_element(SUBSCR_NODE, &cfg_subscr_a3a8_cmd);
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +0200549
550 return 0;
551}