2009-08-10 08:17:50 +00:00
|
|
|
/* OpenBSC interface to quagga VTY */
|
|
|
|
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
2011-04-18 15:15:53 +00:00
|
|
|
* (C) 2009-2011 by Holger Hans Peter Freyther
|
2009-08-10 08:17:50 +00:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
2011-01-01 14:25:50 +00:00
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2009-08-10 08:17:50 +00:00
|
|
|
* (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
|
2011-01-01 14:25:50 +00:00
|
|
|
* GNU Affero General Public License for more details.
|
2009-08-10 08:17:50 +00:00
|
|
|
*
|
2011-01-01 14:25:50 +00:00
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-08-10 08:17:50 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2010-12-24 23:33:40 +00:00
|
|
|
#include <limits.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
#include <unistd.h>
|
2016-06-07 13:32:16 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <inttypes.h>
|
2013-07-27 17:42:35 +00:00
|
|
|
#include <time.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-19 17:45:32 +00:00
|
|
|
#include <osmocom/vty/command.h>
|
|
|
|
#include <osmocom/vty/buffer.h>
|
|
|
|
#include <osmocom/vty/vty.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/linuxlist.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
#include <openbsc/gsm_data.h>
|
|
|
|
#include <openbsc/gsm_subscriber.h>
|
add struct bsc_subscr, separating libbsc from gsm_subscriber
In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will
not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC
subscriber: struct bsc_subscr.
Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no
longer have a backpointer to gsm_network (used to be via subscr->group).
Create a separate logging filter for the new BSC subscriber. The implementation
of adjusting the filter context is added in libbsc to not introduce
bsc_subscr_get/_put() dependencies to libcommon.
During Paging Response, fetch a bsc_subscr from the mobile identity, like we do
for the gsm_subscriber. It looks like a duplication now, but will make sense
for the VLR as well as for future MSC split patches.
Naming: it was requested to not name the new struct bsc_sub, because 'sub' is
too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function
prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to
match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast
to type, relatively short, unambiguous, and the naming is consistent.
Add bsc_subscr unit test.
Related: OS#1592, OS#1594
Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e
2017-02-18 21:20:46 +00:00
|
|
|
#include <openbsc/bsc_subscriber.h>
|
2009-11-17 05:00:23 +00:00
|
|
|
#include <openbsc/silent_call.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
#include <openbsc/gsm_04_11.h>
|
src: port openBSC over libosmo-abis
This is a big patch that ports openBSC over libosmo-abis.
Sorry, the changes that are included here are all dependent
of libosmo-abis, splitting them into smaller pieces would
leave the repository in some intermediate state, which is
not desired.
The main changes are:
- The directory libabis/ has been removed as it now lives in
libosmo-abis.
- new configuration file format for nanoBTS and HSL femto, we
need to define the virtual e1_line and attach it to the OML
link.
- all the existing BTS drivers (nanoBTS, hsl femto, Nokia site,
BS11 and rbs2000) now use the new libosmo-abis framework.
- use r232 input driver available in libosmo-abis for bs11_config.
- use ipa_msg_recv instead of old ipaccess_read_msg function.
- delete definition of gsm_e1_subslot and input_signal_data.
These structures now lives in libosmo-abis.
Most of this patch are deletions of libabis/ which has been
moved to libosmo-abis.
This patch also modifies openBSC to use all the new definitions
available in libosmocore and libosmo-abis. In order to do that,
we have replaced the following:
- DINP, DMI, DMIB and DMUX by their respective DL* correspondences.
- SS_GLOBAL by SS_L_GLOBAL
- SS_INPUT by SS_L_INPUT
- S_GLOBAL_SHUTDOWN by S_L_GLOBAL_SHUTDOWN
- SS_INPUT by SS_L_INPUT
- S_INP_* by S_L_INP_* sub-signals
- E1INP_NODE by L_E1INP_NODE vty node
This patch has been tested with:
- one nanoBTS
- the HSL femto with the examples available under libosmo-abis
- BS11 with both dahdi and misdn drivers.
2011-08-17 20:44:07 +00:00
|
|
|
#include <osmocom/abis/e1_input.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
#include <openbsc/abis_nm.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/gsm_utils.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
#include <openbsc/db.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/talloc.h>
|
2009-11-14 09:08:40 +00:00
|
|
|
#include <openbsc/signal.h>
|
2010-01-06 05:00:40 +00:00
|
|
|
#include <openbsc/debug.h>
|
2010-04-15 09:28:14 +00:00
|
|
|
#include <openbsc/vty.h>
|
2010-07-26 12:01:07 +00:00
|
|
|
#include <openbsc/gsm_04_80.h>
|
|
|
|
#include <openbsc/chan_alloc.h>
|
2010-12-25 13:08:00 +00:00
|
|
|
#include <openbsc/sms_queue.h>
|
2011-09-01 16:18:43 +00:00
|
|
|
#include <openbsc/mncc_int.h>
|
2012-12-25 07:37:36 +00:00
|
|
|
#include <openbsc/handover.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2014-12-28 17:54:32 +00:00
|
|
|
#include <osmocom/vty/logging.h>
|
|
|
|
|
2012-11-11 09:58:51 +00:00
|
|
|
#include "meas_feed.h"
|
|
|
|
|
2010-05-16 18:52:23 +00:00
|
|
|
extern struct gsm_network *gsmnet_from_vty(struct vty *v);
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2015-04-06 07:55:10 +00:00
|
|
|
static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr)
|
2010-01-06 05:00:40 +00:00
|
|
|
{
|
|
|
|
int rc;
|
2015-08-04 11:18:47 +00:00
|
|
|
int reqs;
|
2010-01-06 05:00:40 +00:00
|
|
|
struct gsm_auth_info ainfo;
|
|
|
|
struct gsm_auth_tuple atuple;
|
2015-08-04 11:18:47 +00:00
|
|
|
struct llist_head *entry;
|
2013-07-27 17:42:35 +00:00
|
|
|
char expire_time[200];
|
2010-01-06 05:00:40 +00:00
|
|
|
|
|
|
|
vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
|
|
|
|
subscr->authorized, VTY_NEWLINE);
|
2014-04-04 09:50:41 +00:00
|
|
|
if (strlen(subscr->name))
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
|
2014-04-04 09:53:18 +00:00
|
|
|
if (strlen(subscr->extension))
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " Extension: %s%s", subscr->extension,
|
|
|
|
VTY_NEWLINE);
|
2010-12-25 15:40:54 +00:00
|
|
|
vty_out(vty, " LAC: %d/0x%x%s",
|
|
|
|
subscr->lac, subscr->lac, VTY_NEWLINE);
|
2013-07-14 06:38:24 +00:00
|
|
|
vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
|
2010-01-06 05:00:40 +00:00
|
|
|
if (subscr->tmsi != GSM_RESERVED_TMSI)
|
|
|
|
vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
|
|
|
|
VTY_NEWLINE);
|
|
|
|
|
2010-06-09 09:32:51 +00:00
|
|
|
rc = db_get_authinfo_for_subscr(&ainfo, subscr);
|
2010-01-06 05:00:40 +00:00
|
|
|
if (!rc) {
|
|
|
|
vty_out(vty, " A3A8 algorithm id: %d%s",
|
|
|
|
ainfo.auth_algo, VTY_NEWLINE);
|
|
|
|
vty_out(vty, " A3A8 Ki: %s%s",
|
2011-05-07 10:12:48 +00:00
|
|
|
osmo_hexdump(ainfo.a3a8_ki, ainfo.a3a8_ki_len),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
2010-06-09 09:32:51 +00:00
|
|
|
rc = db_get_lastauthtuple_for_subscr(&atuple, subscr);
|
2010-01-06 05:00:40 +00:00
|
|
|
if (!rc) {
|
|
|
|
vty_out(vty, " A3A8 last tuple (used %d times):%s",
|
|
|
|
atuple.use_count, VTY_NEWLINE);
|
|
|
|
vty_out(vty, " seq # : %d%s",
|
|
|
|
atuple.key_seq, VTY_NEWLINE);
|
|
|
|
vty_out(vty, " RAND : %s%s",
|
2016-04-20 11:13:19 +00:00
|
|
|
osmo_hexdump(atuple.vec.rand, sizeof(atuple.vec.rand)),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
vty_out(vty, " SRES : %s%s",
|
2016-04-20 11:13:19 +00:00
|
|
|
osmo_hexdump(atuple.vec.sres, sizeof(atuple.vec.sres)),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
vty_out(vty, " Kc : %s%s",
|
2016-04-20 11:13:19 +00:00
|
|
|
osmo_hexdump(atuple.vec.kc, sizeof(atuple.vec.kc)),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
}
|
2013-07-27 17:42:35 +00:00
|
|
|
|
|
|
|
/* print the expiration time of a subscriber */
|
|
|
|
strftime(expire_time, sizeof(expire_time),
|
|
|
|
"%a, %d %b %Y %T %z", localtime(&subscr->expire_lu));
|
|
|
|
expire_time[sizeof(expire_time) - 1] = '\0';
|
|
|
|
vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE);
|
2015-08-04 11:18:47 +00:00
|
|
|
|
|
|
|
reqs = 0;
|
|
|
|
llist_for_each(entry, &subscr->requests)
|
|
|
|
reqs += 1;
|
|
|
|
vty_out(vty, " Paging: %s paging Requests: %d%s",
|
|
|
|
subscr->is_paging ? "is" : "not", reqs, VTY_NEWLINE);
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
/* Subscriber */
|
|
|
|
DEFUN(show_subscr_cache,
|
|
|
|
show_subscr_cache_cmd,
|
|
|
|
"show subscriber cache",
|
2012-08-16 21:23:50 +00:00
|
|
|
SHOW_STR "Show information about subscribers\n"
|
|
|
|
"Display contents of subscriber cache\n")
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
|
|
|
struct gsm_subscriber *subscr;
|
|
|
|
|
|
|
|
llist_for_each_entry(subscr, &active_subscribers, entry) {
|
|
|
|
vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
|
2015-04-06 07:55:10 +00:00
|
|
|
subscr_dump_full_vty(vty, subscr);
|
2009-08-10 08:17:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(sms_send_pend,
|
|
|
|
sms_send_pend_cmd,
|
2009-12-22 12:22:29 +00:00
|
|
|
"sms send pending",
|
2016-04-01 00:17:24 +00:00
|
|
|
"SMS related commands\n" "SMS Sending related commands\n"
|
2009-12-22 12:22:29 +00:00
|
|
|
"Send all pending SMS")
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2010-05-16 18:52:23 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
2009-08-10 08:17:50 +00:00
|
|
|
struct gsm_sms *sms;
|
2009-12-22 12:22:29 +00:00
|
|
|
int id = 0;
|
2009-08-10 08:17:50 +00:00
|
|
|
|
|
|
|
while (1) {
|
2010-12-24 23:33:40 +00:00
|
|
|
sms = db_sms_get_unsent_by_subscr(gsmnet, id, UINT_MAX);
|
2009-08-10 08:17:50 +00:00
|
|
|
if (!sms)
|
2009-12-22 12:22:29 +00:00
|
|
|
break;
|
2009-08-10 08:17:50 +00:00
|
|
|
|
|
|
|
gsm411_send_sms_subscr(sms->receiver, sms);
|
2009-12-22 12:22:29 +00:00
|
|
|
|
|
|
|
id = sms->receiver->id + 1;
|
2009-08-10 08:17:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-12-27 23:49:01 +00:00
|
|
|
static int _send_sms_str(struct gsm_subscriber *receiver,
|
|
|
|
struct gsm_subscriber *sender,
|
|
|
|
char *str, uint8_t tp_pid)
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
|
|
|
struct gsm_sms *sms;
|
|
|
|
|
2012-12-27 23:49:01 +00:00
|
|
|
sms = sms_from_text(receiver, sender, 0, str);
|
2009-11-05 06:51:17 +00:00
|
|
|
sms->protocol_id = tp_pid;
|
2010-06-29 18:13:06 +00:00
|
|
|
|
2010-12-25 14:57:34 +00:00
|
|
|
/* store in database for the queue */
|
|
|
|
if (db_sms_store(sms) != 0) {
|
2012-11-10 18:46:58 +00:00
|
|
|
LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
|
2010-12-25 14:57:34 +00:00
|
|
|
sms_free(sms);
|
|
|
|
return CMD_WARNING;
|
2010-06-29 18:13:06 +00:00
|
|
|
}
|
2016-05-09 19:48:53 +00:00
|
|
|
LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-12-25 14:57:34 +00:00
|
|
|
sms_free(sms);
|
2014-12-03 08:28:24 +00:00
|
|
|
sms_queue_trigger(receiver->group->net->sms_queue);
|
2009-08-10 08:17:50 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-05-16 18:52:23 +00:00
|
|
|
static struct gsm_subscriber *get_subscr_by_argv(struct gsm_network *gsmnet,
|
|
|
|
const char *type,
|
2009-11-14 07:00:53 +00:00
|
|
|
const char *id)
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2009-11-14 07:00:53 +00:00
|
|
|
if (!strcmp(type, "extension"))
|
2014-12-03 08:28:24 +00:00
|
|
|
return subscr_get_by_extension(gsmnet->subscr_group, id);
|
2009-11-14 07:00:53 +00:00
|
|
|
else if (!strcmp(type, "imsi"))
|
2014-12-03 08:28:24 +00:00
|
|
|
return subscr_get_by_imsi(gsmnet->subscr_group, id);
|
2009-11-14 07:00:53 +00:00
|
|
|
else if (!strcmp(type, "tmsi"))
|
2014-12-03 08:28:24 +00:00
|
|
|
return subscr_get_by_tmsi(gsmnet->subscr_group, atoi(id));
|
2009-11-14 07:00:53 +00:00
|
|
|
else if (!strcmp(type, "id"))
|
2014-12-03 08:28:24 +00:00
|
|
|
return subscr_get_by_id(gsmnet->subscr_group, atoi(id));
|
2009-11-14 07:00:53 +00:00
|
|
|
|
|
|
|
return NULL;
|
2009-08-10 08:17:50 +00:00
|
|
|
}
|
2009-11-14 07:00:53 +00:00
|
|
|
#define SUBSCR_TYPES "(extension|imsi|tmsi|id)"
|
2010-05-14 18:05:17 +00:00
|
|
|
#define SUBSCR_HELP "Operations on a Subscriber\n" \
|
2016-04-01 00:17:24 +00:00
|
|
|
"Identify subscriber by extension (phone number)\n" \
|
|
|
|
"Identify subscriber by IMSI\n" \
|
|
|
|
"Identify subscriber by TMSI\n" \
|
|
|
|
"Identify subscriber by database ID\n" \
|
2010-05-14 18:05:17 +00:00
|
|
|
"Identifier for the subscriber\n"
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
DEFUN(show_subscr,
|
|
|
|
show_subscr_cmd,
|
|
|
|
"show subscriber " SUBSCR_TYPES " ID",
|
|
|
|
SHOW_STR SUBSCR_HELP)
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-04-06 07:55:10 +00:00
|
|
|
subscr_dump_full_vty(vty, subscr);
|
2010-05-27 08:44:58 +00:00
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-10-04 21:54:17 +00:00
|
|
|
DEFUN(subscriber_create,
|
|
|
|
subscriber_create_cmd,
|
|
|
|
"subscriber create imsi ID",
|
|
|
|
"Operations on a Subscriber\n" \
|
|
|
|
"Create new subscriber\n" \
|
|
|
|
"Identify the subscriber by his IMSI\n" \
|
|
|
|
"Identifier for the subscriber\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr;
|
|
|
|
|
2016-04-01 18:21:03 +00:00
|
|
|
subscr = subscr_get_by_imsi(gsmnet->subscr_group, argv[0]);
|
|
|
|
if (subscr)
|
|
|
|
db_sync_subscriber(subscr);
|
|
|
|
else {
|
2016-06-30 08:25:49 +00:00
|
|
|
subscr = subscr_create_subscriber(gsmnet->subscr_group, argv[0]);
|
2016-04-01 18:21:03 +00:00
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber created for IMSI %s%s",
|
|
|
|
argv[0], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2013-10-04 21:54:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Show info about the created subscriber. */
|
2015-04-06 07:55:10 +00:00
|
|
|
subscr_dump_full_vty(vty, subscr);
|
2013-10-04 21:54:17 +00:00
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-02-22 16:54:47 +00:00
|
|
|
DEFUN(subscriber_send_pending_sms,
|
|
|
|
subscriber_send_pending_sms_cmd,
|
2012-07-20 21:55:08 +00:00
|
|
|
"subscriber " SUBSCR_TYPES " ID sms pending-send",
|
2011-02-22 16:54:47 +00:00
|
|
|
SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
2013-07-04 18:34:46 +00:00
|
|
|
struct gsm_subscriber *subscr;
|
2011-02-22 16:54:47 +00:00
|
|
|
struct gsm_sms *sms;
|
|
|
|
|
2013-07-04 18:34:46 +00:00
|
|
|
subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2011-02-22 16:54:47 +00:00
|
|
|
sms = db_sms_get_unsent_by_subscr(gsmnet, subscr->id, UINT_MAX);
|
|
|
|
if (sms)
|
|
|
|
gsm411_send_sms_subscr(sms->receiver, sms);
|
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2009-11-14 07:00:53 +00:00
|
|
|
DEFUN(subscriber_send_sms,
|
|
|
|
subscriber_send_sms_cmd,
|
2012-12-27 23:49:01 +00:00
|
|
|
"subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
|
2013-03-03 08:32:08 +00:00
|
|
|
SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2010-05-16 18:52:23 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2012-12-27 23:49:01 +00:00
|
|
|
struct gsm_subscriber *sender = get_subscr_by_argv(gsmnet, argv[2], argv[3]);
|
2010-05-16 17:28:32 +00:00
|
|
|
char *str;
|
2009-08-10 08:17:50 +00:00
|
|
|
int rc;
|
|
|
|
|
2009-11-14 09:11:45 +00:00
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
2012-12-27 23:49:01 +00:00
|
|
|
rc = CMD_WARNING;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sender) {
|
|
|
|
vty_out(vty, "%% No sender found for %s %s%s",
|
|
|
|
argv[2], argv[3], VTY_NEWLINE);
|
|
|
|
rc = CMD_WARNING;
|
|
|
|
goto err;
|
2009-11-14 09:11:45 +00:00
|
|
|
}
|
2012-12-27 23:49:01 +00:00
|
|
|
|
|
|
|
str = argv_concat(argv, argc, 4);
|
|
|
|
rc = _send_sms_str(subscr, sender, str, 0);
|
2010-05-16 17:28:32 +00:00
|
|
|
talloc_free(str);
|
2009-11-05 06:51:17 +00:00
|
|
|
|
2012-12-27 23:49:01 +00:00
|
|
|
err:
|
|
|
|
if (sender)
|
|
|
|
subscr_put(sender);
|
|
|
|
|
|
|
|
if (subscr)
|
|
|
|
subscr_put(subscr);
|
2009-11-14 09:10:54 +00:00
|
|
|
|
2009-11-05 06:51:17 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2009-11-14 07:00:53 +00:00
|
|
|
DEFUN(subscriber_silent_sms,
|
|
|
|
subscriber_silent_sms_cmd,
|
2014-07-10 18:19:00 +00:00
|
|
|
|
|
|
|
"subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
|
|
|
|
SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
|
2009-11-05 06:51:17 +00:00
|
|
|
{
|
2010-05-16 18:52:23 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2012-12-27 23:49:01 +00:00
|
|
|
struct gsm_subscriber *sender = get_subscr_by_argv(gsmnet, argv[2], argv[3]);
|
2010-05-16 17:28:32 +00:00
|
|
|
char *str;
|
2009-11-05 06:51:17 +00:00
|
|
|
int rc;
|
|
|
|
|
2009-11-14 09:11:45 +00:00
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
2012-12-27 23:49:01 +00:00
|
|
|
rc = CMD_WARNING;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sender) {
|
|
|
|
vty_out(vty, "%% No sender found for %s %s%s",
|
|
|
|
argv[2], argv[3], VTY_NEWLINE);
|
|
|
|
rc = CMD_WARNING;
|
|
|
|
goto err;
|
2009-11-14 09:11:45 +00:00
|
|
|
}
|
2009-11-05 06:51:17 +00:00
|
|
|
|
2012-12-27 23:49:01 +00:00
|
|
|
str = argv_concat(argv, argc, 4);
|
|
|
|
rc = _send_sms_str(subscr, sender, str, 64);
|
2010-05-16 17:28:32 +00:00
|
|
|
talloc_free(str);
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2012-12-27 23:49:01 +00:00
|
|
|
err:
|
|
|
|
if (sender)
|
|
|
|
subscr_put(sender);
|
|
|
|
|
|
|
|
if (subscr)
|
|
|
|
subscr_put(subscr);
|
2009-11-14 09:10:54 +00:00
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-05-14 18:05:17 +00:00
|
|
|
#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
|
|
|
|
#define CHAN_TYPE_HELP \
|
|
|
|
"Any channel\n" \
|
|
|
|
"TCH/F channel\n" \
|
|
|
|
"Any TCH channel\n" \
|
|
|
|
"SDCCH channel\n"
|
|
|
|
|
2010-01-02 13:29:43 +00:00
|
|
|
DEFUN(subscriber_silent_call_start,
|
|
|
|
subscriber_silent_call_start_cmd,
|
2010-05-27 08:44:58 +00:00
|
|
|
"subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
|
2010-05-14 18:05:17 +00:00
|
|
|
SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
|
|
|
|
CHAN_TYPE_HELP)
|
2010-01-02 13:29:43 +00:00
|
|
|
{
|
2010-05-16 18:52:23 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2010-01-02 13:29:43 +00:00
|
|
|
int rc, type;
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(argv[2], "tch/f"))
|
|
|
|
type = RSL_CHANNEED_TCH_F;
|
|
|
|
else if (!strcmp(argv[2], "tch/any"))
|
|
|
|
type = RSL_CHANNEED_TCH_ForH;
|
|
|
|
else if (!strcmp(argv[2], "sdcch"))
|
|
|
|
type = RSL_CHANNEED_SDCCH;
|
|
|
|
else
|
|
|
|
type = RSL_CHANNEED_ANY; /* Defaults to ANY */
|
|
|
|
|
|
|
|
rc = gsm_silent_call_start(subscr, vty, type);
|
|
|
|
if (rc <= 0) {
|
|
|
|
vty_out(vty, "%% Subscriber not attached%s",
|
|
|
|
VTY_NEWLINE);
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(subscriber_silent_call_stop,
|
|
|
|
subscriber_silent_call_stop_cmd,
|
2010-05-27 08:44:58 +00:00
|
|
|
"subscriber " SUBSCR_TYPES " ID silent-call stop",
|
2010-05-14 18:05:17 +00:00
|
|
|
SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
|
|
|
|
CHAN_TYPE_HELP)
|
2009-11-14 09:08:40 +00:00
|
|
|
{
|
2010-05-16 18:52:23 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2009-11-14 09:08:40 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
2009-11-14 09:11:45 +00:00
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
2009-11-14 09:08:40 +00:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2010-01-02 13:29:43 +00:00
|
|
|
rc = gsm_silent_call_stop(subscr);
|
|
|
|
if (rc < 0) {
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_WARNING;
|
2009-11-14 09:08:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-07-26 12:01:07 +00:00
|
|
|
DEFUN(subscriber_ussd_notify,
|
|
|
|
subscriber_ussd_notify_cmd,
|
2010-07-27 10:27:46 +00:00
|
|
|
"subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
|
2012-08-16 21:23:50 +00:00
|
|
|
SUBSCR_HELP "Send a USSD notify to the subscriber\n"
|
|
|
|
"Alerting Level 0\n"
|
|
|
|
"Alerting Level 1\n"
|
|
|
|
"Alerting Level 2\n"
|
|
|
|
"Text of USSD message to send\n")
|
2010-07-26 12:01:07 +00:00
|
|
|
{
|
|
|
|
char *text;
|
|
|
|
struct gsm_subscriber_connection *conn;
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2010-07-27 10:27:46 +00:00
|
|
|
int level;
|
2010-07-26 12:01:07 +00:00
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2010-07-27 10:27:46 +00:00
|
|
|
level = atoi(argv[2]);
|
|
|
|
text = argv_concat(argv, argc, 3);
|
2010-07-26 12:01:07 +00:00
|
|
|
if (!text) {
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
conn = connection_for_subscr(subscr);
|
|
|
|
if (!conn) {
|
|
|
|
vty_out(vty, "%% An active connection is required for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
subscr_put(subscr);
|
|
|
|
talloc_free(text);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-05-10 10:50:31 +00:00
|
|
|
msc_send_ussd_notify(conn, level, text);
|
|
|
|
msc_send_ussd_release_complete(conn);
|
2010-07-26 12:01:07 +00:00
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
talloc_free(text);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-09-25 01:50:13 +00:00
|
|
|
DEFUN(ena_subscr_delete,
|
|
|
|
ena_subscr_delete_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID delete",
|
|
|
|
SUBSCR_HELP "Delete subscriber in HLR\n")
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (subscr->use_count != 1) {
|
|
|
|
vty_out(vty, "Removing active subscriber%s", VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = db_subscriber_delete(subscr);
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
vty_out(vty, "Failed to remove subscriber%s", VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-01-18 16:09:33 +00:00
|
|
|
DEFUN(ena_subscr_expire,
|
|
|
|
ena_subscr_expire_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID expire",
|
|
|
|
SUBSCR_HELP "Expire the subscriber Now\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
subscr->expire_lu = time(0);
|
|
|
|
db_sync_subscriber(subscr);
|
|
|
|
subscr_put(subscr);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-09-25 01:50:13 +00:00
|
|
|
DEFUN(ena_subscr_authorized,
|
2010-05-27 08:44:58 +00:00
|
|
|
ena_subscr_authorized_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID authorized (0|1)",
|
|
|
|
SUBSCR_HELP "(De-)Authorize subscriber in HLR\n"
|
|
|
|
"Subscriber should NOT be authorized\n"
|
|
|
|
"Subscriber should be authorized\n")
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2010-05-27 08:44:58 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
subscr->authorized = atoi(argv[2]);
|
2009-08-10 08:17:50 +00:00
|
|
|
db_sync_subscriber(subscr);
|
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
subscr_put(subscr);
|
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
DEFUN(ena_subscr_name,
|
|
|
|
ena_subscr_name_cmd,
|
2010-06-24 06:06:38 +00:00
|
|
|
"subscriber " SUBSCR_TYPES " ID name .NAME",
|
2010-05-27 08:44:58 +00:00
|
|
|
SUBSCR_HELP "Set the name of the subscriber\n"
|
|
|
|
"Name of the Subscriber\n")
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2010-05-27 08:44:58 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2010-06-24 06:06:38 +00:00
|
|
|
char *name;
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-06-24 06:06:38 +00:00
|
|
|
name = argv_concat(argv, argc, 2);
|
2010-07-26 11:43:54 +00:00
|
|
|
if (!name) {
|
|
|
|
subscr_put(subscr);
|
2010-06-24 06:06:38 +00:00
|
|
|
return CMD_WARNING;
|
2010-07-26 11:43:54 +00:00
|
|
|
}
|
2010-06-24 06:06:38 +00:00
|
|
|
|
2015-04-07 15:49:49 +00:00
|
|
|
if (strlen(name) > sizeof(subscr->name)-1) {
|
|
|
|
vty_out(vty,
|
2015-08-03 07:28:41 +00:00
|
|
|
"%% NAME is too long, max. %zu characters are allowed%s",
|
2015-04-07 15:49:49 +00:00
|
|
|
sizeof(subscr->name)-1, VTY_NEWLINE);
|
2017-02-23 19:27:01 +00:00
|
|
|
subscr_put(subscr);
|
2015-04-07 15:49:49 +00:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-01-13 02:12:08 +00:00
|
|
|
osmo_strlcpy(subscr->name, name, sizeof(subscr->name));
|
2010-06-24 06:06:38 +00:00
|
|
|
talloc_free(name);
|
2009-08-10 08:17:50 +00:00
|
|
|
db_sync_subscriber(subscr);
|
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
subscr_put(subscr);
|
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
DEFUN(ena_subscr_extension,
|
|
|
|
ena_subscr_extension_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID extension EXTENSION",
|
|
|
|
SUBSCR_HELP "Set the extension (phone number) of the subscriber\n"
|
|
|
|
"Extension (phone number)\n")
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2010-05-27 08:44:58 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
2011-04-18 15:15:53 +00:00
|
|
|
const char *ext = argv[2];
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2015-04-07 15:49:49 +00:00
|
|
|
if (strlen(ext) > sizeof(subscr->extension)-1) {
|
|
|
|
vty_out(vty,
|
2015-08-03 07:28:41 +00:00
|
|
|
"%% EXTENSION is too long, max. %zu characters are allowed%s",
|
2015-04-07 15:49:49 +00:00
|
|
|
sizeof(subscr->extension)-1, VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-01-13 02:10:54 +00:00
|
|
|
osmo_strlcpy(subscr->extension, ext, sizeof(subscr->extension));
|
2009-08-10 08:17:50 +00:00
|
|
|
db_sync_subscriber(subscr);
|
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
subscr_put(subscr);
|
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-12-25 07:37:36 +00:00
|
|
|
DEFUN(ena_subscr_handover,
|
|
|
|
ena_subscr_handover_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID handover BTS_NR",
|
|
|
|
SUBSCR_HELP "Handover the active connection\n"
|
|
|
|
"Number of the BTS to handover to\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct gsm_subscriber_connection *conn;
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s.%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
conn = connection_for_subscr(subscr);
|
|
|
|
if (!conn) {
|
|
|
|
vty_out(vty, "%% No active connection for subscriber %s %s.%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
bts = gsm_bts_num(gsmnet, atoi(argv[2]));
|
|
|
|
if (!bts) {
|
|
|
|
vty_out(vty, "%% BTS with number(%d) could not be found.%s",
|
|
|
|
atoi(argv[2]), VTY_NEWLINE);
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now start the handover */
|
|
|
|
ret = bsc_handover_start(conn->lchan, bts);
|
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "%% Handover failed with errno %d.%s",
|
|
|
|
ret, VTY_NEWLINE);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%% Handover started from %s",
|
|
|
|
gsm_lchan_name(conn->lchan));
|
|
|
|
vty_out(vty, " to %s.%s", gsm_lchan_name(conn->ho_lchan),
|
|
|
|
VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-06-10 22:19:42 +00:00
|
|
|
#define A3A8_ALG_TYPES "(none|xor|comp128v1)"
|
2010-05-14 18:05:17 +00:00
|
|
|
#define A3A8_ALG_HELP \
|
|
|
|
"Use No A3A8 algorithm\n" \
|
2010-06-10 22:19:42 +00:00
|
|
|
"Use XOR algorithm\n" \
|
2010-05-14 18:05:17 +00:00
|
|
|
"Use COMP128v1 algorithm\n"
|
2009-12-27 18:30:46 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
DEFUN(ena_subscr_a3a8,
|
|
|
|
ena_subscr_a3a8_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID a3a8 " A3A8_ALG_TYPES " [KI]",
|
2010-05-27 08:48:11 +00:00
|
|
|
SUBSCR_HELP "Set a3a8 parameters for the subscriber\n"
|
|
|
|
A3A8_ALG_HELP "Encryption Key Ki\n")
|
2009-12-27 18:30:46 +00:00
|
|
|
{
|
2010-05-27 08:44:58 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr =
|
|
|
|
get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
const char *alg_str = argv[2];
|
2010-06-10 22:19:42 +00:00
|
|
|
const char *ki_str = argc == 4 ? argv[3] : NULL;
|
2009-12-27 18:30:46 +00:00
|
|
|
struct gsm_auth_info ainfo;
|
2010-06-10 22:19:42 +00:00
|
|
|
int rc, minlen, maxlen;
|
2009-12-27 18:30:46 +00:00
|
|
|
|
2010-05-27 08:44:58 +00:00
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2009-12-27 18:30:46 +00:00
|
|
|
if (!strcasecmp(alg_str, "none")) {
|
2010-06-10 22:19:42 +00:00
|
|
|
ainfo.auth_algo = AUTH_ALGO_NONE;
|
|
|
|
minlen = maxlen = 0;
|
|
|
|
} else if (!strcasecmp(alg_str, "xor")) {
|
|
|
|
ainfo.auth_algo = AUTH_ALGO_XOR;
|
|
|
|
minlen = A38_XOR_MIN_KEY_LEN;
|
|
|
|
maxlen = A38_XOR_MAX_KEY_LEN;
|
2009-12-27 18:30:46 +00:00
|
|
|
} else if (!strcasecmp(alg_str, "comp128v1")) {
|
|
|
|
ainfo.auth_algo = AUTH_ALGO_COMP128v1;
|
2010-06-10 22:19:42 +00:00
|
|
|
minlen = maxlen = A38_COMP128_KEY_LEN;
|
2009-12-27 18:30:46 +00:00
|
|
|
} else {
|
|
|
|
/* Unknown method */
|
2010-12-28 21:26:34 +00:00
|
|
|
subscr_put(subscr);
|
2011-05-03 20:44:39 +00:00
|
|
|
vty_out(vty, "%% Unknown auth method %s%s",
|
|
|
|
alg_str, VTY_NEWLINE);
|
2009-12-27 18:30:46 +00:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2010-06-10 22:19:42 +00:00
|
|
|
if (ki_str) {
|
2011-05-07 10:12:48 +00:00
|
|
|
rc = osmo_hexparse(ki_str, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki));
|
2010-12-28 21:26:34 +00:00
|
|
|
if ((rc > maxlen) || (rc < minlen)) {
|
|
|
|
subscr_put(subscr);
|
2011-05-03 20:44:39 +00:00
|
|
|
vty_out(vty, "%% Wrong Ki `%s'%s",
|
|
|
|
ki_str, VTY_NEWLINE);
|
2010-06-10 22:19:42 +00:00
|
|
|
return CMD_WARNING;
|
2010-12-28 21:26:34 +00:00
|
|
|
}
|
2010-06-10 22:19:42 +00:00
|
|
|
ainfo.a3a8_ki_len = rc;
|
|
|
|
} else {
|
|
|
|
ainfo.a3a8_ki_len = 0;
|
2010-12-28 21:26:34 +00:00
|
|
|
if (minlen) {
|
|
|
|
subscr_put(subscr);
|
2011-05-03 20:44:39 +00:00
|
|
|
vty_out(vty, "%% Missing Ki argument%s", VTY_NEWLINE);
|
2010-06-10 22:19:42 +00:00
|
|
|
return CMD_WARNING;
|
2010-12-28 21:26:34 +00:00
|
|
|
}
|
2010-06-10 22:19:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rc = db_sync_authinfo_for_subscr(
|
|
|
|
ainfo.auth_algo == AUTH_ALGO_NONE ? NULL : &ainfo,
|
|
|
|
subscr);
|
|
|
|
|
2010-06-10 20:00:48 +00:00
|
|
|
/* the last tuple probably invalid with the new auth settings */
|
|
|
|
db_sync_lastauthtuple_for_subscr(NULL, subscr);
|
2010-12-28 21:26:34 +00:00
|
|
|
subscr_put(subscr);
|
2010-06-10 20:00:48 +00:00
|
|
|
|
2011-05-03 20:44:39 +00:00
|
|
|
if (rc) {
|
|
|
|
vty_out(vty, "%% Operation has failed%s", VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
2009-12-27 18:30:46 +00:00
|
|
|
}
|
|
|
|
|
2010-12-22 15:33:23 +00:00
|
|
|
DEFUN(subscriber_purge,
|
|
|
|
subscriber_purge_cmd,
|
|
|
|
"subscriber purge-inactive",
|
|
|
|
"Operations on a Subscriber\n" "Purge subscribers with a zero use count.\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
|
|
|
int purged;
|
|
|
|
|
2014-12-03 08:28:24 +00:00
|
|
|
purged = subscr_purge_inactive(net->subscr_group);
|
2010-12-22 15:33:23 +00:00
|
|
|
vty_out(vty, "%d subscriber(s) were purged.%s", purged, VTY_NEWLINE);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-12-22 17:12:11 +00:00
|
|
|
DEFUN(subscriber_update,
|
|
|
|
subscriber_update_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID update",
|
|
|
|
SUBSCR_HELP "Update the subscriber data from the dabase.\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
|
|
|
|
if (!subscr) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
subscr_update_from_db(subscr);
|
|
|
|
subscr_put(subscr);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2009-11-14 09:08:40 +00:00
|
|
|
static int scall_cbfn(unsigned int subsys, unsigned int signal,
|
|
|
|
void *handler_data, void *signal_data)
|
|
|
|
{
|
|
|
|
struct scall_signal_data *sigdata = signal_data;
|
|
|
|
struct vty *vty = sigdata->data;
|
|
|
|
|
|
|
|
switch (signal) {
|
|
|
|
case S_SCALL_SUCCESS:
|
|
|
|
vty_out(vty, "%% silent call on ARFCN %u timeslot %u%s",
|
2010-06-17 07:05:57 +00:00
|
|
|
sigdata->conn->lchan->ts->trx->arfcn, sigdata->conn->lchan->ts->nr,
|
2009-11-14 09:08:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
case S_SCALL_EXPIRED:
|
|
|
|
vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-15 09:28:14 +00:00
|
|
|
DEFUN(show_stats,
|
|
|
|
show_stats_cmd,
|
|
|
|
"show statistics",
|
|
|
|
SHOW_STR "Display network statistics\n")
|
|
|
|
{
|
2010-05-16 18:52:23 +00:00
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
2010-04-15 09:28:14 +00:00
|
|
|
|
|
|
|
openbsc_vty_print_statistics(vty, net);
|
|
|
|
vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-04-15 09:28:14 +00:00
|
|
|
vty_out(vty, "IMSI Detach Indications : %lu%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
LU counters: count completion and failure, not messages sent
From a human admin viewpoint it doesn't make sense to count the messages sent:
When we use TMSIs, we first send a LU Accept with a new TMSI, and then expect
the MS to respond with a TMSI Realloc Complete message. When that fails to come
through, the LU actually ends in failure, even though a LU Accept was sent.
If a conn breaks/vanishes during LU, we cancel the LU without sending any reply
at all, so the failed LU would not be counted.
Instead, count Location Updating results, i.e. completion and failures.
(With the new VLR developments, LU counters need to be triggered in completely
different places, and this patch prepares for that by providing sensible
counters.)
Change-Id: I03f14c6a2f7ec5e1d3ba401e32082476fc7b0cc6
2016-05-09 11:18:03 +00:00
|
|
|
vty_out(vty, "Location Updating Results: %lu completed, %lu failed%s",
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-04-15 09:28:14 +00:00
|
|
|
vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, "
|
|
|
|
"%lu completed, %lu failed%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[BSC_CTR_HANDOVER_ATTEMPTED].current,
|
|
|
|
net->msc_ctrs->ctr[BSC_CTR_HANDOVER_NO_CHANNEL].current,
|
|
|
|
net->msc_ctrs->ctr[BSC_CTR_HANDOVER_TIMEOUT].current,
|
|
|
|
net->msc_ctrs->ctr[BSC_CTR_HANDOVER_COMPLETED].current,
|
|
|
|
net->msc_ctrs->ctr[BSC_CTR_HANDOVER_FAILED].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-04-15 09:28:14 +00:00
|
|
|
vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-04-15 09:28:14 +00:00
|
|
|
vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-12-24 15:06:33 +00:00
|
|
|
vty_out(vty, "MO Calls : %lu setup, %lu connect ack%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-12-24 15:06:33 +00:00
|
|
|
vty_out(vty, "MT Calls : %lu setup, %lu connect%s",
|
2016-08-02 09:34:11 +00:00
|
|
|
net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
|
|
|
|
net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
|
2016-07-12 13:42:02 +00:00
|
|
|
VTY_NEWLINE);
|
2010-04-15 09:28:14 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-12-25 13:08:00 +00:00
|
|
|
DEFUN(show_smsqueue,
|
|
|
|
show_smsqueue_cmd,
|
|
|
|
"show sms-queue",
|
|
|
|
SHOW_STR "Display SMSqueue statistics\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
sms_queue_stats(net->sms_queue, vty);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-12-25 13:15:32 +00:00
|
|
|
DEFUN(smsqueue_trigger,
|
|
|
|
smsqueue_trigger_cmd,
|
|
|
|
"sms-queue trigger",
|
|
|
|
"SMS Queue\n" "Trigger sending messages\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
sms_queue_trigger(net->sms_queue);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2010-04-15 09:28:14 +00:00
|
|
|
|
2010-12-25 13:25:12 +00:00
|
|
|
DEFUN(smsqueue_max,
|
|
|
|
smsqueue_max_cmd,
|
|
|
|
"sms-queue max-pending <1-500>",
|
2012-07-20 21:55:08 +00:00
|
|
|
"SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
|
2010-12-25 13:25:12 +00:00
|
|
|
{
|
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
sms_queue_set_max_pending(net->sms_queue, atoi(argv[0]));
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-12-25 13:38:30 +00:00
|
|
|
DEFUN(smsqueue_clear,
|
|
|
|
smsqueue_clear_cmd,
|
|
|
|
"sms-queue clear",
|
|
|
|
"SMS Queue\n" "Clear the queue of pending SMS\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
sms_queue_clear(net->sms_queue);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-12-25 13:50:50 +00:00
|
|
|
DEFUN(smsqueue_fail,
|
|
|
|
smsqueue_fail_cmd,
|
|
|
|
"sms-queue max-failure <1-500>",
|
2012-07-20 21:55:08 +00:00
|
|
|
"SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
|
2010-12-25 13:50:50 +00:00
|
|
|
{
|
|
|
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
sms_queue_set_max_failure(net->sms_queue, atoi(argv[0]));
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-09-01 16:18:43 +00:00
|
|
|
|
|
|
|
DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
|
|
|
|
"mncc-int", "Configure internal MNCC handler")
|
|
|
|
{
|
|
|
|
vty->node = MNCC_INT_NODE;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct cmd_node mncc_int_node = {
|
|
|
|
MNCC_INT_NODE,
|
2012-08-17 11:16:10 +00:00
|
|
|
"%s(config-mncc-int)# ",
|
2011-09-01 16:18:43 +00:00
|
|
|
1,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct value_string tchf_codec_names[] = {
|
|
|
|
{ GSM48_CMODE_SPEECH_V1, "fr" },
|
|
|
|
{ GSM48_CMODE_SPEECH_EFR, "efr" },
|
|
|
|
{ GSM48_CMODE_SPEECH_AMR, "amr" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct value_string tchh_codec_names[] = {
|
|
|
|
{ GSM48_CMODE_SPEECH_V1, "hr" },
|
|
|
|
{ GSM48_CMODE_SPEECH_AMR, "amr" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static int config_write_mncc_int(struct vty *vty)
|
|
|
|
{
|
2012-11-11 09:58:51 +00:00
|
|
|
uint16_t meas_port;
|
|
|
|
char *meas_host;
|
2015-01-31 08:47:37 +00:00
|
|
|
const char *meas_scenario;
|
2012-11-11 09:58:51 +00:00
|
|
|
|
|
|
|
meas_feed_cfg_get(&meas_host, &meas_port);
|
2015-01-31 08:47:37 +00:00
|
|
|
meas_scenario = meas_feed_scenario_get();
|
2012-11-11 09:58:51 +00:00
|
|
|
|
2011-09-01 16:18:43 +00:00
|
|
|
vty_out(vty, "mncc-int%s", VTY_NEWLINE);
|
|
|
|
vty_out(vty, " default-codec tch-f %s%s",
|
|
|
|
get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
|
|
|
|
VTY_NEWLINE);
|
|
|
|
vty_out(vty, " default-codec tch-h %s%s",
|
|
|
|
get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
|
|
|
|
VTY_NEWLINE);
|
2012-11-11 09:58:51 +00:00
|
|
|
if (meas_port)
|
|
|
|
vty_out(vty, " meas-feed destination %s %u%s",
|
|
|
|
meas_host, meas_port, VTY_NEWLINE);
|
2015-01-31 08:47:37 +00:00
|
|
|
if (strlen(meas_scenario) > 0)
|
|
|
|
vty_out(vty, " meas-feed scenario %s%s",
|
|
|
|
meas_scenario, VTY_NEWLINE);
|
2012-11-11 09:58:51 +00:00
|
|
|
|
2011-09-01 16:18:43 +00:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(mnccint_def_codec_f,
|
|
|
|
mnccint_def_codec_f_cmd,
|
|
|
|
"default-codec tch-f (fr|efr|amr)",
|
|
|
|
"Set default codec\n" "Codec for TCH/F\n"
|
|
|
|
"Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
|
|
|
|
{
|
|
|
|
mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(mnccint_def_codec_h,
|
|
|
|
mnccint_def_codec_h_cmd,
|
|
|
|
"default-codec tch-h (hr|amr)",
|
|
|
|
"Set default codec\n" "Codec for TCH/H\n"
|
|
|
|
"Half-Rate\n" "Adaptive Multi-Rate\n")
|
|
|
|
{
|
|
|
|
mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-03-03 08:32:08 +00:00
|
|
|
#define OBSOLETE_MSG "Obsolete\n"
|
2013-02-12 10:15:49 +00:00
|
|
|
/* this is just for backwards compatibility as the sms code moved into
|
|
|
|
* libosmocore and old config files no longer parse... */
|
|
|
|
DEFUN_DEPRECATED(log_level_sms, log_level_sms_cmd,
|
|
|
|
"logging level sms (everything|debug|info|notice|error|fatal)",
|
2013-03-03 08:32:08 +00:00
|
|
|
".HIDDEN\n" OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG
|
|
|
|
OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG)
|
2013-02-12 10:15:49 +00:00
|
|
|
{
|
|
|
|
vty_out(vty, "%% 'logging level sms' is now called 'logging level "
|
|
|
|
"lsms', please update your config %s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-01-31 08:26:20 +00:00
|
|
|
#define MEAS_STR "Measurement export related\n"
|
2012-11-11 09:58:51 +00:00
|
|
|
DEFUN(mnccint_meas_feed, mnccint_meas_feed_cmd,
|
|
|
|
"meas-feed destination ADDR <0-65535>",
|
2015-01-31 08:26:20 +00:00
|
|
|
MEAS_STR "destination\n" "address or hostname\n" "port number\n")
|
2012-11-11 09:58:51 +00:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = meas_feed_cfg_set(argv[0], atoi(argv[1]));
|
|
|
|
if (rc < 0)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(meas_feed_scenario, meas_feed_scenario_cmd,
|
|
|
|
"meas-feed scenario NAME",
|
2015-01-31 08:26:20 +00:00
|
|
|
MEAS_STR "scenario\n" "Name up to 31 characters included in report\n")
|
2012-11-11 09:58:51 +00:00
|
|
|
{
|
|
|
|
meas_feed_scenario_set(argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-12-28 17:54:32 +00:00
|
|
|
|
|
|
|
DEFUN(logging_fltr_imsi,
|
|
|
|
logging_fltr_imsi_cmd,
|
|
|
|
"logging filter imsi IMSI",
|
|
|
|
LOGGING_STR FILTER_STR
|
|
|
|
"Filter log messages by IMSI\n" "IMSI to be used as filter\n")
|
|
|
|
{
|
add struct bsc_subscr, separating libbsc from gsm_subscriber
In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will
not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC
subscriber: struct bsc_subscr.
Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no
longer have a backpointer to gsm_network (used to be via subscr->group).
Create a separate logging filter for the new BSC subscriber. The implementation
of adjusting the filter context is added in libbsc to not introduce
bsc_subscr_get/_put() dependencies to libcommon.
During Paging Response, fetch a bsc_subscr from the mobile identity, like we do
for the gsm_subscriber. It looks like a duplication now, but will make sense
for the VLR as well as for future MSC split patches.
Naming: it was requested to not name the new struct bsc_sub, because 'sub' is
too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function
prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to
match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast
to type, relatively short, unambiguous, and the naming is consistent.
Add bsc_subscr unit test.
Related: OS#1592, OS#1594
Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e
2017-02-18 21:20:46 +00:00
|
|
|
struct gsm_subscriber *vlr_subscr;
|
|
|
|
struct bsc_subscr *bsc_subscr;
|
2014-12-28 17:54:32 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct log_target *tgt = osmo_log_vty2tgt(vty);
|
add struct bsc_subscr, separating libbsc from gsm_subscriber
In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will
not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC
subscriber: struct bsc_subscr.
Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no
longer have a backpointer to gsm_network (used to be via subscr->group).
Create a separate logging filter for the new BSC subscriber. The implementation
of adjusting the filter context is added in libbsc to not introduce
bsc_subscr_get/_put() dependencies to libcommon.
During Paging Response, fetch a bsc_subscr from the mobile identity, like we do
for the gsm_subscriber. It looks like a duplication now, but will make sense
for the VLR as well as for future MSC split patches.
Naming: it was requested to not name the new struct bsc_sub, because 'sub' is
too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function
prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to
match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast
to type, relatively short, unambiguous, and the naming is consistent.
Add bsc_subscr unit test.
Related: OS#1592, OS#1594
Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e
2017-02-18 21:20:46 +00:00
|
|
|
const char *imsi = argv[0];
|
2014-12-28 17:54:32 +00:00
|
|
|
|
|
|
|
if (!tgt)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
add struct bsc_subscr, separating libbsc from gsm_subscriber
In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will
not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC
subscriber: struct bsc_subscr.
Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no
longer have a backpointer to gsm_network (used to be via subscr->group).
Create a separate logging filter for the new BSC subscriber. The implementation
of adjusting the filter context is added in libbsc to not introduce
bsc_subscr_get/_put() dependencies to libcommon.
During Paging Response, fetch a bsc_subscr from the mobile identity, like we do
for the gsm_subscriber. It looks like a duplication now, but will make sense
for the VLR as well as for future MSC split patches.
Naming: it was requested to not name the new struct bsc_sub, because 'sub' is
too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function
prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to
match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast
to type, relatively short, unambiguous, and the naming is consistent.
Add bsc_subscr unit test.
Related: OS#1592, OS#1594
Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e
2017-02-18 21:20:46 +00:00
|
|
|
vlr_subscr = subscr_get_by_imsi(gsmnet->subscr_group, imsi);
|
|
|
|
bsc_subscr = bsc_subscr_find_by_imsi(gsmnet->bsc_subscribers, imsi);
|
|
|
|
|
|
|
|
if (!vlr_subscr && !bsc_subscr) {
|
2014-12-28 17:54:32 +00:00
|
|
|
vty_out(vty, "%%no subscriber with IMSI(%s)%s",
|
|
|
|
argv[0], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
add struct bsc_subscr, separating libbsc from gsm_subscriber
In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will
not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC
subscriber: struct bsc_subscr.
Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no
longer have a backpointer to gsm_network (used to be via subscr->group).
Create a separate logging filter for the new BSC subscriber. The implementation
of adjusting the filter context is added in libbsc to not introduce
bsc_subscr_get/_put() dependencies to libcommon.
During Paging Response, fetch a bsc_subscr from the mobile identity, like we do
for the gsm_subscriber. It looks like a duplication now, but will make sense
for the VLR as well as for future MSC split patches.
Naming: it was requested to not name the new struct bsc_sub, because 'sub' is
too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function
prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to
match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast
to type, relatively short, unambiguous, and the naming is consistent.
Add bsc_subscr unit test.
Related: OS#1592, OS#1594
Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e
2017-02-18 21:20:46 +00:00
|
|
|
log_set_filter_vlr_subscr(tgt, vlr_subscr);
|
|
|
|
log_set_filter_bsc_subscr(tgt, bsc_subscr);
|
2014-12-28 17:54:32 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2015-01-27 09:58:29 +00:00
|
|
|
|
|
|
|
static struct cmd_node nitb_node = {
|
|
|
|
NITB_NODE,
|
|
|
|
"%s(config-nitb)# ",
|
|
|
|
1,
|
|
|
|
};
|
|
|
|
|
|
|
|
DEFUN(cfg_nitb, cfg_nitb_cmd,
|
|
|
|
"nitb", "Configure NITB options")
|
|
|
|
{
|
|
|
|
vty->node = NITB_NODE;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-06-07 13:32:16 +00:00
|
|
|
/* Note: limit on the parameter length is set by internal vty code limitations */
|
|
|
|
DEFUN(cfg_nitb_subscr_random, cfg_nitb_subscr_random_cmd,
|
|
|
|
"subscriber-create-on-demand random <1-9999999999> <2-9999999999>",
|
|
|
|
"Set random parameters for a new record when a subscriber is first seen.\n"
|
|
|
|
"Set random parameters for a new record when a subscriber is first seen.\n"
|
|
|
|
"Minimum for subscriber extension\n""Maximum for subscriber extension\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
2017-05-12 12:56:25 +00:00
|
|
|
uint64_t mi = atoll(argv[0]), ma = atoll(argv[1]);
|
2016-06-30 08:25:49 +00:00
|
|
|
gsmnet->auto_create_subscr = true;
|
|
|
|
gsmnet->auto_assign_exten = true;
|
2016-06-07 13:32:16 +00:00
|
|
|
if (mi >= ma) {
|
|
|
|
vty_out(vty, "Incorrect range: %s >= %s, expected MIN < MAX%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
gsmnet->ext_min = mi;
|
|
|
|
gsmnet->ext_max = ma;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-01-27 09:58:29 +00:00
|
|
|
DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd,
|
2016-06-30 08:25:49 +00:00
|
|
|
"subscriber-create-on-demand [no-extension]",
|
2016-05-24 12:23:27 +00:00
|
|
|
"Make a new record when a subscriber is first seen.\n"
|
2016-06-30 08:25:49 +00:00
|
|
|
"Do not automatically assign extension to created subscribers\n")
|
2015-01-27 09:58:29 +00:00
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
2016-06-30 08:25:49 +00:00
|
|
|
gsmnet->auto_create_subscr = true;
|
|
|
|
gsmnet->auto_assign_exten = argc ? false : true;
|
2015-01-27 09:58:29 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_nitb_no_subscr_create, cfg_nitb_no_subscr_create_cmd,
|
|
|
|
"no subscriber-create-on-demand",
|
|
|
|
NO_STR "Make a new record when a subscriber is first seen.\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
2016-06-30 08:25:49 +00:00
|
|
|
gsmnet->auto_create_subscr = false;
|
2015-01-27 09:58:29 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-07-13 18:33:08 +00:00
|
|
|
DEFUN(cfg_nitb_assign_tmsi, cfg_nitb_assign_tmsi_cmd,
|
|
|
|
"assign-tmsi",
|
|
|
|
"Assign TMSI during Location Updating.\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
gsmnet->avoid_tmsi = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_nitb_no_assign_tmsi, cfg_nitb_no_assign_tmsi_cmd,
|
|
|
|
"no assign-tmsi",
|
|
|
|
NO_STR "Assign TMSI during Location Updating.\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
gsmnet->avoid_tmsi = 1;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-01-27 09:58:29 +00:00
|
|
|
static int config_write_nitb(struct vty *vty)
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
2016-06-30 08:25:49 +00:00
|
|
|
|
2015-01-27 09:58:29 +00:00
|
|
|
vty_out(vty, "nitb%s", VTY_NEWLINE);
|
2016-06-30 08:25:49 +00:00
|
|
|
if (!gsmnet->auto_create_subscr)
|
|
|
|
vty_out(vty, " no subscriber-create-on-demand%s", VTY_NEWLINE);
|
|
|
|
else
|
|
|
|
vty_out(vty, " subscriber-create-on-demand%s%s",
|
|
|
|
gsmnet->auto_assign_exten ? "" : " no-extension",
|
|
|
|
VTY_NEWLINE);
|
|
|
|
|
2016-06-07 13:32:16 +00:00
|
|
|
if (gsmnet->ext_min != GSM_MIN_EXTEN || gsmnet->ext_max != GSM_MAX_EXTEN)
|
|
|
|
vty_out(vty, " subscriber-create-on-demand random %"PRIu64" %"
|
|
|
|
PRIu64"%s", gsmnet->ext_min, gsmnet->ext_max,
|
|
|
|
VTY_NEWLINE);
|
2015-07-13 18:33:08 +00:00
|
|
|
vty_out(vty, " %sassign-tmsi%s",
|
|
|
|
gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE);
|
2015-01-27 09:58:29 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-05-16 18:52:23 +00:00
|
|
|
int bsc_vty_init_extra(void)
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2011-05-06 10:12:31 +00:00
|
|
|
osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
|
2009-11-14 09:08:40 +00:00
|
|
|
|
2010-05-12 16:10:35 +00:00
|
|
|
install_element_ve(&show_subscr_cmd);
|
|
|
|
install_element_ve(&show_subscr_cache_cmd);
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2010-05-12 16:10:35 +00:00
|
|
|
install_element_ve(&sms_send_pend_cmd);
|
2009-11-14 07:00:53 +00:00
|
|
|
|
2013-10-04 21:54:17 +00:00
|
|
|
install_element_ve(&subscriber_create_cmd);
|
2010-05-12 16:10:35 +00:00
|
|
|
install_element_ve(&subscriber_send_sms_cmd);
|
|
|
|
install_element_ve(&subscriber_silent_sms_cmd);
|
|
|
|
install_element_ve(&subscriber_silent_call_start_cmd);
|
|
|
|
install_element_ve(&subscriber_silent_call_stop_cmd);
|
2010-07-26 12:01:07 +00:00
|
|
|
install_element_ve(&subscriber_ussd_notify_cmd);
|
2010-12-22 17:12:11 +00:00
|
|
|
install_element_ve(&subscriber_update_cmd);
|
2010-05-12 16:10:35 +00:00
|
|
|
install_element_ve(&show_stats_cmd);
|
2010-12-25 13:08:00 +00:00
|
|
|
install_element_ve(&show_smsqueue_cmd);
|
2014-12-28 17:54:32 +00:00
|
|
|
install_element_ve(&logging_fltr_imsi_cmd);
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2014-09-25 01:50:13 +00:00
|
|
|
install_element(ENABLE_NODE, &ena_subscr_delete_cmd);
|
2017-01-18 16:09:33 +00:00
|
|
|
install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
|
2010-05-27 08:44:58 +00:00
|
|
|
install_element(ENABLE_NODE, &ena_subscr_name_cmd);
|
|
|
|
install_element(ENABLE_NODE, &ena_subscr_extension_cmd);
|
|
|
|
install_element(ENABLE_NODE, &ena_subscr_authorized_cmd);
|
|
|
|
install_element(ENABLE_NODE, &ena_subscr_a3a8_cmd);
|
2012-12-25 07:37:36 +00:00
|
|
|
install_element(ENABLE_NODE, &ena_subscr_handover_cmd);
|
2010-12-22 15:33:23 +00:00
|
|
|
install_element(ENABLE_NODE, &subscriber_purge_cmd);
|
2010-12-25 13:15:32 +00:00
|
|
|
install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
|
2010-12-25 13:25:12 +00:00
|
|
|
install_element(ENABLE_NODE, &smsqueue_max_cmd);
|
2010-12-25 13:38:30 +00:00
|
|
|
install_element(ENABLE_NODE, &smsqueue_clear_cmd);
|
2010-12-25 13:50:50 +00:00
|
|
|
install_element(ENABLE_NODE, &smsqueue_fail_cmd);
|
2011-02-22 16:54:47 +00:00
|
|
|
install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
|
2012-11-11 09:58:51 +00:00
|
|
|
install_element(ENABLE_NODE, &meas_feed_scenario_cmd);
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2011-09-01 16:18:43 +00:00
|
|
|
install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
|
|
|
|
install_node(&mncc_int_node, config_write_mncc_int);
|
2013-10-29 08:30:30 +00:00
|
|
|
vty_install_default(MNCC_INT_NODE);
|
2011-09-01 16:18:43 +00:00
|
|
|
install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
|
|
|
|
install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
|
2012-11-11 09:58:51 +00:00
|
|
|
install_element(MNCC_INT_NODE, &mnccint_meas_feed_cmd);
|
2015-01-31 08:47:37 +00:00
|
|
|
install_element(MNCC_INT_NODE, &meas_feed_scenario_cmd);
|
2011-09-01 16:18:43 +00:00
|
|
|
|
2013-02-12 10:15:49 +00:00
|
|
|
install_element(CFG_LOG_NODE, &log_level_sms_cmd);
|
2014-12-28 17:54:32 +00:00
|
|
|
install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
|
2013-02-12 10:15:49 +00:00
|
|
|
|
2015-01-27 09:58:29 +00:00
|
|
|
|
|
|
|
install_element(CONFIG_NODE, &cfg_nitb_cmd);
|
|
|
|
install_node(&nitb_node, config_write_nitb);
|
|
|
|
install_element(NITB_NODE, &cfg_nitb_subscr_create_cmd);
|
2016-06-07 13:32:16 +00:00
|
|
|
install_element(NITB_NODE, &cfg_nitb_subscr_random_cmd);
|
2015-01-27 09:58:29 +00:00
|
|
|
install_element(NITB_NODE, &cfg_nitb_no_subscr_create_cmd);
|
2015-07-13 18:33:08 +00:00
|
|
|
install_element(NITB_NODE, &cfg_nitb_assign_tmsi_cmd);
|
|
|
|
install_element(NITB_NODE, &cfg_nitb_no_assign_tmsi_cmd);
|
2015-01-27 09:58:29 +00:00
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|