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>
|
2013-07-27 17:42:35 +00:00
|
|
|
#include <time.h>
|
2016-05-20 19:59:55 +00:00
|
|
|
#include <inttypes.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>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/gsm_data.h>
|
|
|
|
#include <osmocom/msc/gsm_subscriber.h>
|
|
|
|
#include <osmocom/msc/silent_call.h>
|
|
|
|
#include <osmocom/msc/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>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/abis_nm.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/gsm_utils.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/db.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/talloc.h>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/signal.h>
|
|
|
|
#include <osmocom/msc/debug.h>
|
|
|
|
#include <osmocom/msc/vty.h>
|
|
|
|
#include <osmocom/msc/gsm_04_80.h>
|
|
|
|
#include <osmocom/msc/gsm_04_14.h>
|
|
|
|
#include <osmocom/msc/chan_alloc.h>
|
|
|
|
#include <osmocom/msc/sms_queue.h>
|
|
|
|
#include <osmocom/msc/mncc_int.h>
|
|
|
|
#include <osmocom/msc/handover.h>
|
|
|
|
#include <osmocom/msc/vlr.h>
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2014-12-28 17:54:32 +00:00
|
|
|
#include <osmocom/vty/logging.h>
|
|
|
|
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/osmo_msc.h>
|
2016-06-19 16:06:02 +00:00
|
|
|
|
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
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
|
2010-01-06 05:00:40 +00:00
|
|
|
{
|
2015-08-04 11:18:47 +00:00
|
|
|
int reqs;
|
|
|
|
struct llist_head *entry;
|
2010-01-06 05:00:40 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (strlen(vsub->name))
|
|
|
|
vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
|
|
|
|
if (strlen(vsub->msisdn))
|
|
|
|
vty_out(vty, " Extension: %s%s", vsub->msisdn,
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
2010-12-25 15:40:54 +00:00
|
|
|
vty_out(vty, " LAC: %d/0x%x%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
vsub->lac, vsub->lac, VTY_NEWLINE);
|
|
|
|
vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
|
|
|
|
if (vsub->tmsi != GSM_RESERVED_TMSI)
|
|
|
|
vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
|
|
|
|
VTY_NEWLINE);
|
|
|
|
if (vsub->tmsi_new != GSM_RESERVED_TMSI)
|
|
|
|
vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
#if 0
|
|
|
|
/* TODO: add this to vlr_subscr? */
|
|
|
|
if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
|
|
|
|
struct gsm_auth_info *i = &vsub->auth_info;
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " A3A8 algorithm id: %d%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
i->auth_algo, VTY_NEWLINE);
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " A3A8 Ki: %s%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
}
|
2016-06-19 16:06:02 +00:00
|
|
|
#endif
|
2010-01-06 05:00:40 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (vsub->last_tuple) {
|
|
|
|
struct gsm_auth_tuple *t = vsub->last_tuple;
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " A3A8 last tuple (used %d times):%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
t->use_count, VTY_NEWLINE);
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " seq # : %d%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
t->key_seq, VTY_NEWLINE);
|
2010-01-06 05:00:40 +00:00
|
|
|
vty_out(vty, " RAND : %s%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
vty_out(vty, " SRES : %s%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
vty_out(vty, " Kc : %s%s",
|
2016-06-19 16:06:02 +00:00
|
|
|
osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
|
2010-01-06 05:00:40 +00:00
|
|
|
VTY_NEWLINE);
|
|
|
|
}
|
2013-07-27 17:42:35 +00:00
|
|
|
|
2015-08-04 11:18:47 +00:00
|
|
|
reqs = 0;
|
2016-06-19 16:06:02 +00:00
|
|
|
llist_for_each(entry, &vsub->cs.requests)
|
2015-08-04 11:18:47 +00:00
|
|
|
reqs += 1;
|
2016-06-19 16:06:02 +00:00
|
|
|
vty_out(vty, " Paging: %s paging for %d requests%s",
|
|
|
|
vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
|
|
|
|
vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
|
2010-01-06 05:00:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct vlr_subscr *vsub;
|
|
|
|
int count = 0;
|
2009-08-10 08:17:50 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
|
|
|
|
if (++count > 100) {
|
|
|
|
vty_out(vty, "%% More than %d subscribers in cache,"
|
|
|
|
" stopping here.%s", count-1, VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
}
|
2009-08-10 08:17:50 +00:00
|
|
|
vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
|
2016-06-19 16:06:02 +00:00
|
|
|
subscr_dump_full_vty(vty, vsub);
|
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;
|
2016-06-19 16:06:02 +00:00
|
|
|
unsigned long long sms_id = 0;
|
2009-08-10 08:17:50 +00:00
|
|
|
|
|
|
|
while (1) {
|
2016-06-19 16:06:02 +00:00
|
|
|
sms = db_sms_get_next_unsent(gsmnet, sms_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
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (sms->receiver)
|
|
|
|
gsm411_send_sms_subscr(sms->receiver, sms);
|
2009-12-22 12:22:29 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
sms_id = sms->id + 1;
|
2009-08-10 08:17:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static int _send_sms_str(struct vlr_subscr *receiver,
|
|
|
|
struct vlr_subscr *sender,
|
|
|
|
char *str, uint8_t tp_pid)
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct gsm_network *net = receiver->vlr->user_ctx;
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
sms_queue_trigger(net->sms_queue);
|
2009-08-10 08:17:50 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
|
|
|
|
const char *type,
|
|
|
|
const char *id)
|
2009-08-10 08:17:50 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
|
|
|
|
return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
|
|
|
|
else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
|
|
|
|
return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
|
2009-11-14 07:00:53 +00:00
|
|
|
else if (!strcmp(type, "tmsi"))
|
2016-06-19 16:06:02 +00:00
|
|
|
return vlr_subscr_find_by_tmsi(gsmnet->vlr, 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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
|
|
|
|
argv[1]);
|
2010-05-27 08:44:58 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2010-05-27 08:44:58 +00:00
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
subscr_dump_full_vty(vty, vsub);
|
2010-05-27 08:44:58 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-05-27 08:44:58 +00:00
|
|
|
|
|
|
|
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")
|
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
|
|
|
|
VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
2013-10-04 21:54:17 +00:00
|
|
|
}
|
|
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub;
|
2011-02-22 16:54:47 +00:00
|
|
|
struct gsm_sms *sms;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
if (!vsub) {
|
2013-07-04 18:34:46 +00:00
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
|
2011-02-22 16:54:47 +00:00
|
|
|
if (sms)
|
|
|
|
gsm411_send_sms_subscr(sms->receiver, sms);
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2011-02-22 16:54:47 +00:00
|
|
|
|
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
struct vlr_subscr *sender = get_vsub_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;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2009-11-14 09:11:45 +00:00
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
rc = _send_sms_str(vsub, 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)
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(sender);
|
2012-12-27 23:49:01 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (vsub)
|
|
|
|
vlr_subscr_put(vsub);
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
struct vlr_subscr *sender = get_vsub_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;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2009-11-14 09:11:45 +00:00
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
rc = _send_sms_str(vsub, 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)
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(sender);
|
2012-12-27 23:49:01 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (vsub)
|
|
|
|
vlr_subscr_put(vsub);
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
2010-01-02 13:29:43 +00:00
|
|
|
int rc, type;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2010-01-02 13:29:43 +00:00
|
|
|
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 */
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
rc = gsm_silent_call_start(vsub, vty, type);
|
2010-01-02 13:29:43 +00:00
|
|
|
if (rc <= 0) {
|
|
|
|
vty_out(vty, "%% Subscriber not attached%s",
|
|
|
|
VTY_NEWLINE);
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-01-02 13:29:43 +00:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-01-02 13:29:43 +00:00
|
|
|
|
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
2009-11-14 09:08:40 +00:00
|
|
|
int rc;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2009-11-14 09:08:40 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
rc = gsm_silent_call_stop(vsub);
|
2010-01-02 13:29:43 +00:00
|
|
|
if (rc < 0) {
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-01-02 13:29:43 +00:00
|
|
|
return CMD_WARNING;
|
2009-11-14 09:08:40 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2009-11-14 09:08:40 +00:00
|
|
|
|
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_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
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2010-07-26 12:01:07 +00:00
|
|
|
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) {
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-07-26 12:01:07 +00:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
conn = connection_for_subscr(vsub);
|
2010-07-26 12:01:07 +00:00
|
|
|
if (!conn) {
|
|
|
|
vty_out(vty, "%% An active connection is required for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-07-26 12:01:07 +00:00
|
|
|
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
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2010-07-26 12:01:07 +00:00
|
|
|
talloc_free(text);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-06-11 23:52:27 +00:00
|
|
|
static int loop_by_char(uint8_t ch)
|
|
|
|
{
|
|
|
|
switch (ch) {
|
|
|
|
case 'a':
|
|
|
|
return GSM414_LOOP_A;
|
|
|
|
case 'b':
|
|
|
|
return GSM414_LOOP_B;
|
|
|
|
case 'c':
|
|
|
|
return GSM414_LOOP_C;
|
|
|
|
case 'd':
|
|
|
|
return GSM414_LOOP_D;
|
|
|
|
case 'e':
|
|
|
|
return GSM414_LOOP_E;
|
|
|
|
case 'f':
|
|
|
|
return GSM414_LOOP_F;
|
|
|
|
case 'i':
|
|
|
|
return GSM414_LOOP_I;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(subscriber_mstest_close,
|
|
|
|
subscriber_mstest_close_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
|
|
|
|
SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
|
|
|
|
"Close a TCH Loop inside the MS\n"
|
|
|
|
"Loop Type A\n"
|
|
|
|
"Loop Type B\n"
|
|
|
|
"Loop Type C\n"
|
|
|
|
"Loop Type D\n"
|
|
|
|
"Loop Type E\n"
|
|
|
|
"Loop Type F\n"
|
|
|
|
"Loop Type I\n")
|
|
|
|
{
|
|
|
|
struct gsm_subscriber_connection *conn;
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
const char *loop_str;
|
|
|
|
int loop_mode;
|
|
|
|
|
|
|
|
if (!vsub) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
loop_str = argv[2];
|
|
|
|
loop_mode = loop_by_char(loop_str[0]);
|
|
|
|
|
|
|
|
conn = connection_for_subscr(vsub);
|
|
|
|
if (!conn) {
|
|
|
|
vty_out(vty, "%% An active connection is required for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
vlr_subscr_put(vsub);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(subscriber_mstest_open,
|
|
|
|
subscriber_mstest_open_cmd,
|
|
|
|
"subscriber " SUBSCR_TYPES " ID ms-test open-loop",
|
|
|
|
SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
|
|
|
|
"Open a TCH Loop inside the MS\n")
|
|
|
|
{
|
|
|
|
struct gsm_subscriber_connection *conn;
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
|
|
|
|
|
|
|
|
if (!vsub) {
|
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
conn = connection_for_subscr(vsub);
|
|
|
|
if (!conn) {
|
|
|
|
vty_out(vty, "%% An active connection is required for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
vlr_subscr_put(vsub);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
gsm0414_tx_open_loop_cmd(conn);
|
|
|
|
|
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
|
|
|
|
argv[1]);
|
2017-01-18 16:09:33 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!vsub) {
|
2017-01-18 16:09:33 +00:00
|
|
|
vty_out(vty, "%% No subscriber found for %s %s%s",
|
|
|
|
argv[0], argv[1], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-12-27 18:34:15 +00:00
|
|
|
if (vlr_subscr_expire(vsub))
|
2016-06-19 16:06:02 +00:00
|
|
|
vty_out(vty, "%% VLR released subscriber %s%s",
|
|
|
|
vlr_subscr_name(vsub), VTY_NEWLINE);
|
|
|
|
|
|
|
|
if (vsub->use_count > 1)
|
|
|
|
vty_out(vty, "%% Subscriber %s is still in use,"
|
|
|
|
" should be released soon%s",
|
|
|
|
vlr_subscr_name(vsub), VTY_NEWLINE);
|
2017-01-18 16:09:33 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_put(vsub);
|
2017-01-18 16:09:33 +00:00
|
|
|
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
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
vty_out(vty, "%% 'subscriber a3a8' is no longer supported.%s"
|
|
|
|
"%% This is now up to osmo-hlr.%s",
|
|
|
|
VTY_NEWLINE, VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
2009-12-27 18:30:46 +00:00
|
|
|
}
|
|
|
|
|
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")
|
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
vty_out(vty, "%% 'subscriber update' is no longer supported.%s",
|
|
|
|
VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
2010-12-22 17:12:11 +00:00
|
|
|
}
|
|
|
|
|
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:
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
|
2009-11-14 09:08:40 +00:00
|
|
|
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
|
|
|
|
|
|
|
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, "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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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")
|
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vlr_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;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
|
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
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
if (!vlr_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;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
log_set_filter_vlr_subscr(tgt, vlr_subscr);
|
2014-12-28 17:54:32 +00:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2015-01-27 09:58:29 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static struct cmd_node hlr_node = {
|
|
|
|
HLR_NODE,
|
|
|
|
"%s(config-hlr)# ",
|
|
|
|
1,
|
|
|
|
};
|
|
|
|
|
|
|
|
DEFUN(cfg_hlr, cfg_hlr_cmd,
|
|
|
|
"hlr", "Configure connection to the HLR")
|
|
|
|
{
|
|
|
|
vty->node = HLR_NODE;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
|
|
|
|
"Remote GSUP address of the HLR\n"
|
|
|
|
"Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
talloc_free((void*)gsmnet->gsup_server_addr_str);
|
|
|
|
gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
|
|
|
|
"Remote GSUP port of the HLR\n"
|
|
|
|
"Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
gsmnet->gsup_server_port = atoi(argv[0]);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int config_write_hlr(struct vty *vty)
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
vty_out(vty, "hlr%s", VTY_NEWLINE);
|
|
|
|
vty_out(vty, " remote-ip %s%s",
|
|
|
|
gsmnet->gsup_server_addr_str, VTY_NEWLINE);
|
|
|
|
vty_out(vty, " remote-port %u%s",
|
|
|
|
gsmnet->gsup_server_port, VTY_NEWLINE);
|
|
|
|
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);
|
2017-06-11 23:52:27 +00:00
|
|
|
install_element_ve(&subscriber_mstest_close_cmd);
|
|
|
|
install_element_ve(&subscriber_mstest_open_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
|
|
|
|
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_a3a8_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);
|
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);
|
|
|
|
install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
|
|
|
|
install_element(MNCC_INT_NODE, &mnccint_def_codec_h_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
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
install_element(CONFIG_NODE, &cfg_hlr_cmd);
|
|
|
|
install_node(&hlr_node, config_write_hlr);
|
|
|
|
install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
|
|
|
|
install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
|
2015-01-27 09:58:29 +00:00
|
|
|
|
2009-08-10 08:17:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|