/* OpenBSC interface to quagga VTY */ /* (C) 2009 by Harald Welte * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* forward declarations */ void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr); static struct gsm_network *gsmnet; struct cmd_node subscr_node = { SUBSCR_NODE, "%s(subscriber)#", 1, }; static int dummy_config_write(struct vty *v) { return CMD_SUCCESS; } static struct buffer *argv_to_buffer(int argc, const char *argv[], int base) { struct buffer *b = buffer_new(1024); int i; if (!b) return NULL; for (i = base; i < argc; i++) { buffer_putstr(b, argv[i]); buffer_putc(b, ' '); } buffer_putc(b, '\0'); return b; } /* per-subscriber configuration */ DEFUN(cfg_subscr, cfg_subscr_cmd, "subscriber IMSI", "Select a Subscriber to configure\n") { const char *imsi = argv[0]; struct gsm_subscriber *subscr; subscr = subscr_get_by_imsi(gsmnet, imsi); if (!subscr) { vty_out(vty, "%% No subscriber for IMSI %s%s", imsi, VTY_NEWLINE); return CMD_WARNING; } vty->index = subscr; vty->node = SUBSCR_NODE; return CMD_SUCCESS; } /* Subscriber */ DEFUN(show_subscr, show_subscr_cmd, "show subscriber [IMSI]", SHOW_STR "Display information about a subscriber\n") { const char *imsi; struct gsm_subscriber *subscr; if (argc >= 1) { imsi = argv[0]; subscr = subscr_get_by_imsi(gsmnet, imsi); if (!subscr) { vty_out(vty, "%% unknown subscriber%s", VTY_NEWLINE); return CMD_WARNING; } subscr_dump_vty(vty, subscr); return CMD_SUCCESS; } /* FIXME: iterate over all subscribers ? */ return CMD_WARNING; return CMD_SUCCESS; } DEFUN(show_subscr_cache, show_subscr_cache_cmd, "show subscriber cache", SHOW_STR "Display contents of subscriber cache\n") { struct gsm_subscriber *subscr; llist_for_each_entry(subscr, &active_subscribers, entry) { vty_out(vty, " Subscriber:%s", VTY_NEWLINE); subscr_dump_vty(vty, subscr); } return CMD_SUCCESS; } DEFUN(sms_send_pend, sms_send_pend_cmd, "sms send pending MIN_ID", "Send all pending SMS starting from MIN_ID") { struct gsm_sms *sms; int id = atoi(argv[0]); while (1) { sms = db_sms_get_unsent(gsmnet, id++); if (!sms) return CMD_WARNING; if (!sms->receiver) { sms_free(sms); continue; } gsm411_send_sms_subscr(sms->receiver, sms); } return CMD_SUCCESS; } struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, const char *text) { struct gsm_sms *sms = sms_alloc(); if (!sms) return NULL; if (!receiver->lac) { /* subscriber currently not attached, store in database? */ return NULL; } sms->receiver = subscr_get(receiver); strncpy(sms->text, text, sizeof(sms->text)-1); /* FIXME: don't use ID 1 static */ sms->sender = subscr_get_by_id(gsmnet, 1); sms->reply_path_req = 0; sms->status_rep_req = 0; sms->ud_hdr_ind = 0; sms->protocol_id = 0; /* implicit */ sms->data_coding_scheme = 0; /* default 7bit */ strncpy(sms->dest_addr, receiver->extension, sizeof(sms->dest_addr)-1); /* Generate user_data */ sms->user_data_len = gsm_7bit_encode(sms->user_data, sms->text); return sms; } static int _send_sms_buffer(struct gsm_subscriber *receiver, struct buffer *b) { struct gsm_sms *sms; sms = sms_from_text(receiver, buffer_getstr(b)); gsm411_send_sms_subscr(receiver, sms); return CMD_SUCCESS; } DEFUN(sms_send_ext, sms_send_ext_cmd, "sms send extension EXTEN .LINE", "Send a message to a subscriber identified by EXTEN") { struct gsm_subscriber *receiver; struct buffer *b; int rc; receiver = subscr_get_by_extension(gsmnet, argv[0]); if (!receiver) return CMD_WARNING; b = argv_to_buffer(argc, argv, 1); rc = _send_sms_buffer(receiver, b); buffer_free(b); return rc; } DEFUN(sms_send_imsi, sms_send_imsi_cmd, "sms send imsi IMSI .LINE", "Send a message to a subscriber identified by IMSI") { struct gsm_subscriber *receiver; struct buffer *b; int rc; receiver = subscr_get_by_imsi(gsmnet, argv[0]); if (!receiver) return CMD_WARNING; b = argv_to_buffer(argc, argv, 1); rc = _send_sms_buffer(receiver, b); buffer_free(b); return rc; } DEFUN(cfg_subscr_name, cfg_subscr_name_cmd, "name NAME", "Set the name of the subscriber") { const char *name = argv[0]; struct gsm_subscriber *subscr = vty->index; strncpy(subscr->name, name, sizeof(subscr->name)); db_sync_subscriber(subscr); return CMD_SUCCESS; } DEFUN(cfg_subscr_extension, cfg_subscr_extension_cmd, "extension EXTENSION", "Set the extension of the subscriber") { const char *name = argv[0]; struct gsm_subscriber *subscr = vty->index; strncpy(subscr->extension, name, sizeof(subscr->extension)); db_sync_subscriber(subscr); return CMD_SUCCESS; } DEFUN(cfg_subscr_authorized, cfg_subscr_authorized_cmd, "auth <0-1>", "Set the authorization status of the subscriber") { int auth = atoi(argv[0]); struct gsm_subscriber *subscr = vty->index; if (auth) subscr->authorized = 1; else subscr->authorized = 0; db_sync_subscriber(subscr); return CMD_SUCCESS; } int bsc_vty_init_extra(struct gsm_network *net) { gsmnet = net; install_element(VIEW_NODE, &show_subscr_cmd); install_element(VIEW_NODE, &show_subscr_cache_cmd); install_element(VIEW_NODE, &sms_send_pend_cmd); install_element(VIEW_NODE, &sms_send_ext_cmd); install_element(VIEW_NODE, &sms_send_imsi_cmd); install_element(CONFIG_NODE, &cfg_subscr_cmd); install_node(&subscr_node, dummy_config_write); install_default(SUBSCR_NODE); install_element(SUBSCR_NODE, &cfg_subscr_name_cmd); install_element(SUBSCR_NODE, &cfg_subscr_extension_cmd); install_element(SUBSCR_NODE, &cfg_subscr_authorized_cmd); return 0; }