mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr.git
synced 2025-10-24 16:53:48 +00:00
Compare commits
2 Commits
osmith/fix
...
fixeria/us
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6f695e0e6 | ||
|
|
35d2342850 |
@@ -30,6 +30,7 @@ noinst_HEADERS = \
|
||||
ctrl.h \
|
||||
hlr_vty.h \
|
||||
hlr_vty_subscr.h \
|
||||
hlr_ss_ussd.h \
|
||||
db_bootstrap.h \
|
||||
$(NULL)
|
||||
|
||||
@@ -53,6 +54,7 @@ osmo_hlr_SOURCES = \
|
||||
hlr_vty.c \
|
||||
hlr_vty_subscr.c \
|
||||
gsup_send.c \
|
||||
hlr_ss_ussd.c \
|
||||
$(NULL)
|
||||
|
||||
osmo_hlr_LDADD = \
|
||||
|
||||
14
src/hlr.c
14
src/hlr.c
@@ -42,6 +42,7 @@
|
||||
#include "rand.h"
|
||||
#include "luop.h"
|
||||
#include "hlr_vty.h"
|
||||
#include "hlr_ss_ussd.h"
|
||||
|
||||
static struct hlr *g_hlr;
|
||||
|
||||
@@ -296,10 +297,19 @@ static int rx_upd_loc_req(struct osmo_gsup_conn *conn,
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
int rc;
|
||||
uint8_t *addr;
|
||||
rc = osmo_gsup_conn_ccm_get(conn, &addr, IPAC_IDTAG_SERNR);
|
||||
if (rc <= 0) {
|
||||
osmo_strlcpy(luop->subscr.imsi, gsup->imsi, sizeof(luop->subscr.imsi));
|
||||
lu_op_tx_error(luop, GMM_CAUSE_NET_FAIL);
|
||||
return 0;
|
||||
}
|
||||
/* TODO: Subscriber allowed to roam in PLMN? */
|
||||
/* TODO: Update RoutingInfo */
|
||||
/* TODO: Reset Flag MS Purged (cs/ps) */
|
||||
/* TODO: Control_Tracing_HLR / Control_Tracing_HLR_with_SGSN */
|
||||
db_subscr_lu(g_hlr->dbc, luop->subscr.id, (char *)addr, luop->is_ps);
|
||||
lu_op_tx_insert_subscr_data(luop);
|
||||
}
|
||||
return 0;
|
||||
@@ -524,6 +534,7 @@ static void signal_hdlr(int signal)
|
||||
case SIGINT:
|
||||
LOGP(DMAIN, LOGL_NOTICE, "Terminating due to SIGINT\n");
|
||||
osmo_gsup_server_destroy(g_hlr->gs);
|
||||
hlr_usse_clean_up(g_hlr);
|
||||
db_close(g_hlr->dbc);
|
||||
log_fini();
|
||||
talloc_report_full(hlr_ctx, stderr);
|
||||
@@ -560,6 +571,9 @@ int main(int argc, char **argv)
|
||||
|
||||
g_hlr = talloc_zero(hlr_ctx, struct hlr);
|
||||
|
||||
INIT_LLIST_HEAD(&g_hlr->usse_list);
|
||||
g_hlr->usse_default = NULL;
|
||||
|
||||
rc = osmo_init_logging2(hlr_ctx, &hlr_log_info);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error initializing logging\n");
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
struct hlr_usse;
|
||||
|
||||
struct hlr {
|
||||
/* GSUP server pointer */
|
||||
@@ -37,6 +40,10 @@ struct hlr {
|
||||
|
||||
/* Local bind addr */
|
||||
char *gsup_bind_addr;
|
||||
|
||||
/* SS/USSD processing entities */
|
||||
struct llist_head usse_list;
|
||||
struct hlr_usse *usse_default;
|
||||
};
|
||||
|
||||
struct hlr_subscriber;
|
||||
|
||||
129
src/hlr_ss_ussd.c
Normal file
129
src/hlr_ss_ussd.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* Supplementary Services signalling implementation */
|
||||
|
||||
/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#include "hlr.h"
|
||||
#include "hlr_ss_ussd.h"
|
||||
|
||||
struct hlr_usse *hlr_usse_find(struct hlr *hlr, const char *name)
|
||||
{
|
||||
struct hlr_usse *usse;
|
||||
|
||||
llist_for_each_entry(usse, &hlr->usse_list, list) {
|
||||
if (!strcmp(usse->name, name))
|
||||
return usse;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hlr_usse *hlr_usse_alloc(struct hlr *hlr, const char *name)
|
||||
{
|
||||
struct hlr_usse *usse;
|
||||
|
||||
usse = hlr_usse_find(hlr, name);
|
||||
if (usse)
|
||||
return NULL;
|
||||
|
||||
usse = talloc(hlr, struct hlr_usse);
|
||||
usse->name = talloc_strdup(usse, name);
|
||||
usse->description = NULL;
|
||||
usse->hlr = hlr;
|
||||
|
||||
INIT_LLIST_HEAD(&usse->patterns);
|
||||
llist_add_tail(&usse->list, &hlr->usse_list);
|
||||
|
||||
return usse;
|
||||
}
|
||||
|
||||
void hlr_usse_del(struct hlr_usse *usse)
|
||||
{
|
||||
struct hlr_usse_pattern *pt, *_pt;
|
||||
|
||||
/* Release linked patterns */
|
||||
llist_for_each_entry_safe(pt, _pt, &usse->patterns, list)
|
||||
hlr_usse_pattern_del(pt);
|
||||
|
||||
/* Unlink from the HLR's USSE list */
|
||||
llist_del(&usse->list);
|
||||
|
||||
/* Release memory */
|
||||
talloc_free(usse);
|
||||
}
|
||||
|
||||
struct hlr_usse_pattern *hlr_usse_pattern_find(struct hlr_usse *usse,
|
||||
enum hlr_usse_pattern_type type, const char *pattern)
|
||||
{
|
||||
struct hlr_usse_pattern *pt;
|
||||
|
||||
llist_for_each_entry(pt, &usse->patterns, list) {
|
||||
if (pt->type != type)
|
||||
continue;
|
||||
if (strcmp(pt->pattern, pattern))
|
||||
continue;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hlr_usse_pattern *hlr_usse_pattern_add(struct hlr_usse *usse,
|
||||
enum hlr_usse_pattern_type type, const char *pattern)
|
||||
{
|
||||
struct hlr_usse_pattern *pt;
|
||||
|
||||
pt = hlr_usse_pattern_find(usse, type, pattern);
|
||||
if (pt)
|
||||
return NULL;
|
||||
|
||||
pt = talloc(usse, struct hlr_usse_pattern);
|
||||
pt->pattern = talloc_strdup(pt, pattern);
|
||||
pt->rsp_fmt = NULL;
|
||||
pt->type = type;
|
||||
pt->usse = usse;
|
||||
|
||||
llist_add_tail(&pt->list, &usse->patterns);
|
||||
return pt;
|
||||
}
|
||||
|
||||
void hlr_usse_pattern_del(struct hlr_usse_pattern *pt)
|
||||
{
|
||||
/* Unlink from the USSE's list */
|
||||
llist_del(&pt->list);
|
||||
|
||||
/* Release memory */
|
||||
talloc_free(pt);
|
||||
}
|
||||
|
||||
void hlr_usse_clean_up(struct hlr *hlr)
|
||||
{
|
||||
struct hlr_usse *usse, *_usse;
|
||||
|
||||
llist_for_each_entry_safe(usse, _usse, &hlr->usse_list, list)
|
||||
hlr_usse_del(usse);
|
||||
}
|
||||
51
src/hlr_ss_ussd.h
Normal file
51
src/hlr_ss_ussd.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/gsm0480.h>
|
||||
|
||||
/* Represents a single USSE (either the internal, or an external) */
|
||||
struct hlr_usse {
|
||||
/* list in the per-HLR list of USSEs */
|
||||
struct llist_head list;
|
||||
/* back-pointer to the HLR instance */
|
||||
struct hlr *hlr;
|
||||
/* human-readable description */
|
||||
const char *description;
|
||||
/* name (must match the IPA ID tag) */
|
||||
const char *name;
|
||||
/* list of USSD-code matching patterns */
|
||||
struct llist_head patterns;
|
||||
};
|
||||
|
||||
/* Matching pattern types sorted by priority */
|
||||
enum hlr_usse_pattern_type {
|
||||
HLR_USSE_PATTERN_CODE = 0, /* higher priority */
|
||||
HLR_USSE_PATTERN_REGEXP,
|
||||
HLR_USSE_PATTERN_PREFIX,
|
||||
};
|
||||
|
||||
/* Represents a USSD-code matching pattern */
|
||||
struct hlr_usse_pattern {
|
||||
/* link to the parent USSE */
|
||||
struct llist_head list;
|
||||
/* back-pointer to the parent USSE */
|
||||
struct hlr_usse *usse;
|
||||
/* Patter type, e.g. code, regexp or prefix */
|
||||
enum hlr_usse_pattern_type type;
|
||||
/* Mathing pattern, e.g. '*110*' for prefix */
|
||||
const char *pattern;
|
||||
/* Response format string, e.g. 'Your MSISDN is %m' */
|
||||
char *rsp_fmt;
|
||||
};
|
||||
|
||||
struct hlr_usse *hlr_usse_find(struct hlr *hlr, const char *name);
|
||||
struct hlr_usse *hlr_usse_alloc(struct hlr *hlr, const char *name);
|
||||
void hlr_usse_del(struct hlr_usse *usse);
|
||||
|
||||
struct hlr_usse_pattern *hlr_usse_pattern_find(struct hlr_usse *usse,
|
||||
enum hlr_usse_pattern_type type, const char *pattern);
|
||||
struct hlr_usse_pattern *hlr_usse_pattern_add(struct hlr_usse *usse,
|
||||
enum hlr_usse_pattern_type type, const char *pattern);
|
||||
void hlr_usse_pattern_del(struct hlr_usse_pattern *pt);
|
||||
|
||||
void hlr_usse_clean_up(struct hlr *hlr);
|
||||
293
src/hlr_vty.c
293
src/hlr_vty.c
@@ -3,6 +3,7 @@
|
||||
/* (C) 2016 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
* (C) 2018 Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -29,6 +30,7 @@
|
||||
#include <osmocom/abis/ipa.h>
|
||||
|
||||
#include "hlr_vty.h"
|
||||
#include "hlr_ss_ussd.h"
|
||||
#include "hlr_vty_subscr.h"
|
||||
#include "gsup_server.h"
|
||||
|
||||
@@ -94,7 +96,7 @@ static void show_one_conn(struct vty *vty, const struct osmo_gsup_conn *conn)
|
||||
|
||||
DEFUN(show_gsup_conn, show_gsup_conn_cmd,
|
||||
"show gsup-connections",
|
||||
SHOW_STR "GSUP Connections from VLRs, SGSNs, EUSEs\n")
|
||||
SHOW_STR "GSUP Connections from VLRs, SGSNs, EUSSEs\n")
|
||||
{
|
||||
struct osmo_gsup_server *gs = g_hlr->gs;
|
||||
struct osmo_gsup_conn *conn;
|
||||
@@ -119,12 +121,290 @@ DEFUN(cfg_hlr_gsup_bind_ip,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Unstructured Supplementary Services processing Entity configuration
|
||||
***********************************************************************/
|
||||
|
||||
static struct cmd_node iusse_node = {
|
||||
IUSSE_NODE,
|
||||
"%s(config-hlr-iusse)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
static struct cmd_node eusse_node = {
|
||||
EUSSE_NODE,
|
||||
"%s(config-hlr-eusse)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
#define VTY_USSE_NAME_DESC \
|
||||
"Internal USSD processing Entity\n" \
|
||||
"Alphanumeric name of an External USSE\n"
|
||||
|
||||
DEFUN(cfg_usse, cfg_usse_cmd,
|
||||
"usse (internal|NAME)",
|
||||
"Configure a particular USSE (USSD processing Entity)\n"
|
||||
VTY_USSE_NAME_DESC)
|
||||
{
|
||||
const char *name = argv[0];
|
||||
struct hlr_usse *usse;
|
||||
|
||||
usse = hlr_usse_find(g_hlr, name);
|
||||
if (!usse) {
|
||||
usse = hlr_usse_alloc(g_hlr, name);
|
||||
if (!usse)
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
vty->index_sub = &usse->description;
|
||||
vty->index = usse;
|
||||
|
||||
/* IUSSE or EUSSE? */
|
||||
if (!strcmp(usse->name, "internal"))
|
||||
vty->node = IUSSE_NODE;
|
||||
else
|
||||
vty->node = EUSSE_NODE;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_usse, cfg_no_usse_cmd,
|
||||
"no usse (internal|NAME)",
|
||||
NO_STR "Remove a particular USSE (USSD processing Entity)\n"
|
||||
VTY_USSE_NAME_DESC)
|
||||
{
|
||||
const char *name = argv[0];
|
||||
struct hlr_usse *usse;
|
||||
|
||||
usse = hlr_usse_find(g_hlr, name);
|
||||
if (!usse) {
|
||||
vty_out(vty, "%% Cannot remove non-existent "
|
||||
"USSE '%s'%s", name, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (g_hlr->usse_default == usse) {
|
||||
vty_out(vty, "%% Cannot remove USSE '%s', "
|
||||
"it is the default route%s", name, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
hlr_usse_del(usse);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_usse_default, cfg_usse_default_cmd,
|
||||
"usse-default (internal|NAME)",
|
||||
"Default USSD processing Entity\n"
|
||||
VTY_USSE_NAME_DESC)
|
||||
{
|
||||
const char *name = argv[0];
|
||||
struct hlr_usse *usse;
|
||||
|
||||
usse = hlr_usse_find(g_hlr, name);
|
||||
if (!usse) {
|
||||
vty_out(vty, "%% Cannot find USSE '%s'%s", name, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (g_hlr->usse_default == usse) {
|
||||
vty_out(vty, "%% USSE '%s' is already "
|
||||
"used by default%s", usse->name, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
g_hlr->usse_default = usse;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_usse_default, cfg_no_usse_default_cmd,
|
||||
"no usse-default",
|
||||
NO_STR "No default USSD processing Entity "
|
||||
"(drop all unmatched requests)\n")
|
||||
{
|
||||
g_hlr->usse_default = NULL;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define VTY_USSE_PATTERN_CMD \
|
||||
"pattern (code|regexp|prefix) PATTERN"
|
||||
|
||||
#define VTY_USSE_PATTERN_DESC \
|
||||
"Match USSD-request codes by exact value (e.g. '*#100#')\n" \
|
||||
"Match USSD-request codes by regular expression (e.g. '^\\*[5-7]+'\\*)\n" \
|
||||
"Match USSD-request codes by prefix (e.g. '*#' or '*110*')\n" \
|
||||
"Matching pattern\n"
|
||||
|
||||
static int _cfg_usse_pattern(struct vty *vty, int argc, const char **argv)
|
||||
{
|
||||
struct hlr_usse *usse = vty->index;
|
||||
enum hlr_usse_pattern_type type;
|
||||
struct hlr_usse_pattern *pt;
|
||||
bool is_iusse;
|
||||
|
||||
/* Determine which kind of matching pattern required */
|
||||
switch (argv[0][0]) {
|
||||
case 'c':
|
||||
type = HLR_USSE_PATTERN_CODE;
|
||||
break;
|
||||
case 'r':
|
||||
type = HLR_USSE_PATTERN_REGEXP;
|
||||
break;
|
||||
case 'p':
|
||||
type = HLR_USSE_PATTERN_PREFIX;
|
||||
break;
|
||||
default:
|
||||
/* Shouldn't happen, but let's make sure */
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* IUSSE or EUSSE? */
|
||||
is_iusse = !strcmp(usse->name, "internal");
|
||||
|
||||
/* Attempt to find pattern */
|
||||
pt = hlr_usse_pattern_find(usse, type, argv[1]);
|
||||
if (pt && !is_iusse) {
|
||||
/* Response modification is only actual for IUSSE */
|
||||
vty_out(vty, "%% Pattern already exists!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Allocate if required */
|
||||
if (!pt) {
|
||||
pt = hlr_usse_pattern_add(usse, type, argv[1]);
|
||||
if (!pt) {
|
||||
vty_out(vty, "%% Cannot add pattern '%s' of type '%s'%s",
|
||||
argv[1], argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Response string for IUSSE */
|
||||
if (is_iusse) {
|
||||
if (pt->rsp_fmt)
|
||||
talloc_free(pt->rsp_fmt);
|
||||
pt->rsp_fmt = talloc_strdup(pt, argv_concat(argv, argc, 2));
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_iusse_pattern, cfg_iusse_pattern_cmd,
|
||||
VTY_USSE_PATTERN_CMD " response .RESPONSE",
|
||||
"Add or modify a USSD-code matching pattern\n"
|
||||
VTY_USSE_PATTERN_DESC
|
||||
"Response format string (e.g. 'Your MSISDN is %m')\n")
|
||||
{
|
||||
return _cfg_usse_pattern(vty, argc, argv);
|
||||
}
|
||||
|
||||
DEFUN(cfg_eusse_pattern, cfg_eusse_pattern_cmd,
|
||||
VTY_USSE_PATTERN_CMD,
|
||||
"Add a new USSD-code matching pattern\n"
|
||||
VTY_USSE_PATTERN_DESC)
|
||||
{
|
||||
return _cfg_usse_pattern(vty, argc, argv);
|
||||
}
|
||||
|
||||
DEFUN(cfg_usse_no_pattern, cfg_usse_no_pattern_cmd,
|
||||
"no " VTY_USSE_PATTERN_CMD,
|
||||
NO_STR "Remove an existing USSD-code matching pattern\n"
|
||||
VTY_USSE_PATTERN_DESC)
|
||||
{
|
||||
struct hlr_usse *usse = vty->index;
|
||||
enum hlr_usse_pattern_type type;
|
||||
struct hlr_usse_pattern *pt;
|
||||
|
||||
/* Determine which kind of matching pattern required */
|
||||
switch (argv[0][0]) {
|
||||
case 'c':
|
||||
type = HLR_USSE_PATTERN_CODE;
|
||||
break;
|
||||
case 'r':
|
||||
type = HLR_USSE_PATTERN_REGEXP;
|
||||
break;
|
||||
case 'p':
|
||||
type = HLR_USSE_PATTERN_PREFIX;
|
||||
break;
|
||||
default:
|
||||
/* Shouldn't happen, but let's make sure */
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
pt = hlr_usse_pattern_find(usse, type, argv[1]);
|
||||
if (!pt) {
|
||||
vty_out(vty, "%% Cannot remove non-existent pattern '%s' "
|
||||
"of type '%s'%s", argv[1], argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
hlr_usse_pattern_del(pt);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void dump_one_usse(struct vty *vty, struct hlr_usse *usse)
|
||||
{
|
||||
struct hlr_usse_pattern *pt;
|
||||
const char *pt_type;
|
||||
|
||||
vty_out(vty, " usse %s%s", usse->name, VTY_NEWLINE);
|
||||
// FIXME: what about usse->description?
|
||||
|
||||
llist_for_each_entry(pt, &usse->patterns, list) {
|
||||
/* Stringify pattern type */
|
||||
switch (pt->type) {
|
||||
case HLR_USSE_PATTERN_CODE:
|
||||
pt_type = "code";
|
||||
break;
|
||||
case HLR_USSE_PATTERN_REGEXP:
|
||||
pt_type = "regexp";
|
||||
break;
|
||||
case HLR_USSE_PATTERN_PREFIX:
|
||||
pt_type = "prefix";
|
||||
break;
|
||||
default:
|
||||
/* Should not happen */
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
|
||||
if (pt->rsp_fmt != NULL)
|
||||
vty_out(vty, " pattern %s %s response %s%s", pt_type,
|
||||
pt->pattern, pt->rsp_fmt, VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " pattern %s %s%s", pt_type,
|
||||
pt->pattern, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
static int config_write_usse(struct vty *vty)
|
||||
{
|
||||
struct hlr_usse *usse;
|
||||
|
||||
if (g_hlr->usse_default == NULL)
|
||||
vty_out(vty, " no usse-default%s", VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " usse-default %s%s",
|
||||
g_hlr->usse_default->name, VTY_NEWLINE);
|
||||
|
||||
llist_for_each_entry(usse, &g_hlr->usse_list, list)
|
||||
dump_one_usse(vty, usse);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Common Code
|
||||
***********************************************************************/
|
||||
|
||||
int hlr_vty_go_parent(struct vty *vty)
|
||||
{
|
||||
switch (vty->node) {
|
||||
case GSUP_NODE:
|
||||
case IUSSE_NODE:
|
||||
case EUSSE_NODE:
|
||||
vty->node = HLR_NODE;
|
||||
vty->index = NULL;
|
||||
vty->index_sub = NULL;
|
||||
break;
|
||||
default:
|
||||
case HLR_NODE:
|
||||
@@ -169,5 +449,16 @@ void hlr_vty_init(struct hlr *hlr, const struct log_info *cat)
|
||||
|
||||
install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd);
|
||||
|
||||
install_element(HLR_NODE, &cfg_usse_cmd);
|
||||
install_element(HLR_NODE, &cfg_no_usse_cmd);
|
||||
install_element(HLR_NODE, &cfg_usse_default_cmd);
|
||||
install_element(HLR_NODE, &cfg_no_usse_default_cmd);
|
||||
install_node(&eusse_node, config_write_usse);
|
||||
install_element(EUSSE_NODE, &cfg_eusse_pattern_cmd);
|
||||
install_element(EUSSE_NODE, &cfg_usse_no_pattern_cmd);
|
||||
install_node(&iusse_node, NULL);
|
||||
install_element(IUSSE_NODE, &cfg_iusse_pattern_cmd);
|
||||
install_element(IUSSE_NODE, &cfg_usse_no_pattern_cmd);
|
||||
|
||||
hlr_vty_subscriber_init(hlr);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
enum hlr_vty_node {
|
||||
HLR_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
GSUP_NODE,
|
||||
IUSSE_NODE,
|
||||
EUSSE_NODE,
|
||||
};
|
||||
|
||||
int hlr_vty_is_config_node(struct vty *vty, int node);
|
||||
|
||||
@@ -31,6 +31,7 @@ EXTRA_DIST = \
|
||||
test_subscriber.vty \
|
||||
test_subscriber.sql \
|
||||
test_subscriber.ctrl \
|
||||
test_sse.vty \
|
||||
$(NULL)
|
||||
|
||||
TESTSUITE = $(srcdir)/testsuite
|
||||
|
||||
@@ -70,6 +70,10 @@ OsmoHLR(config-hlr)# list
|
||||
exit
|
||||
end
|
||||
gsup
|
||||
usse (internal|NAME)
|
||||
no usse (internal|NAME)
|
||||
usse-default (internal|NAME)
|
||||
no usse-default
|
||||
|
||||
OsmoHLR(config-hlr)# gsup
|
||||
OsmoHLR(config-hlr-gsup)# list
|
||||
@@ -85,6 +89,39 @@ OsmoHLR(config-hlr-gsup)# list
|
||||
bind ip A.B.C.D
|
||||
|
||||
OsmoHLR(config-hlr-gsup)# exit
|
||||
OsmoHLR(config-hlr)# usse test
|
||||
OsmoHLR(config-hlr-eusse)# list
|
||||
help
|
||||
list
|
||||
write terminal
|
||||
write file
|
||||
write memory
|
||||
write
|
||||
show running-config
|
||||
exit
|
||||
end
|
||||
pattern (code|regexp|prefix) PATTERN
|
||||
no pattern (code|regexp|prefix) PATTERN
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# exit
|
||||
OsmoHLR(config-hlr)# usse internal
|
||||
OsmoHLR(config-hlr-iusse)# list
|
||||
help
|
||||
list
|
||||
write terminal
|
||||
write file
|
||||
write memory
|
||||
write
|
||||
show running-config
|
||||
exit
|
||||
end
|
||||
pattern (code|regexp|prefix) PATTERN response .RESPONSE
|
||||
no pattern (code|regexp|prefix) PATTERN
|
||||
|
||||
OsmoHLR(config-hlr-iusse)# exit
|
||||
OsmoHLR(config-hlr)# no usse test
|
||||
OsmoHLR(config-hlr)# no usse internal
|
||||
|
||||
OsmoHLR(config-hlr)# exit
|
||||
OsmoHLR(config)# exit
|
||||
OsmoHLR# configure terminal
|
||||
@@ -119,4 +156,5 @@ ctrl
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
no usse-default
|
||||
end
|
||||
|
||||
246
tests/test_usse.vty
Normal file
246
tests/test_usse.vty
Normal file
@@ -0,0 +1,246 @@
|
||||
OsmoHLR> enable
|
||||
OsmoHLR# configure terminal
|
||||
OsmoHLR(config)# show running-config
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 1
|
||||
logging print extended-timestamp 1
|
||||
logging print file 1
|
||||
logging level all debug
|
||||
logging level main notice
|
||||
logging level db notice
|
||||
logging level auc notice
|
||||
...
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
no usse-default
|
||||
end
|
||||
|
||||
OsmoHLR(config)# hlr
|
||||
OsmoHLR(config-hlr)# no usse test
|
||||
% Cannot remove non-existent USSE 'test'
|
||||
|
||||
OsmoHLR(config-hlr)# usse gw1
|
||||
OsmoHLR(config-hlr-eusse)# no pattern prefix *111*
|
||||
% Cannot remove non-existent pattern '*111*' of type 'prefix'
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# pattern prefix *110*
|
||||
OsmoHLR(config-hlr-eusse)# pattern prefix *181*
|
||||
OsmoHLR(config-hlr-eusse)# pattern prefix *110*
|
||||
% Pattern already exists!
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# pattern code *110*
|
||||
OsmoHLR(config-hlr-eusse)# pattern code *888#
|
||||
OsmoHLR(config-hlr-eusse)# pattern code *110*
|
||||
% Pattern already exists!
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# pattern regexp ^*[1-3]{3}*[0-9]+#$
|
||||
OsmoHLR(config-hlr-eusse)# pattern regexp ^*[5-7]{3}*[0-9]+#$
|
||||
OsmoHLR(config-hlr-eusse)# pattern regexp ^*[1-3]{3}*[0-9]+#$
|
||||
% Pattern already exists!
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# show running-config
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 1
|
||||
logging print extended-timestamp 1
|
||||
logging print file 1
|
||||
logging level all debug
|
||||
logging level main notice
|
||||
logging level db notice
|
||||
logging level auc notice
|
||||
...
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
no usse-default
|
||||
usse gw1
|
||||
pattern prefix *110*
|
||||
pattern prefix *181*
|
||||
pattern code *110*
|
||||
pattern code *888#
|
||||
pattern regexp ^*[1-3]{3}*[0-9]+#$
|
||||
pattern regexp ^*[5-7]{3}*[0-9]+#$
|
||||
end
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# no pattern prefix *181*
|
||||
OsmoHLR(config-hlr-eusse)# no pattern code *110*
|
||||
OsmoHLR(config-hlr-eusse)# no pattern regexp ^*[1-3]{3}*[0-9]+#$
|
||||
OsmoHLR(config-hlr-eusse)# show running-config
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 1
|
||||
logging print extended-timestamp 1
|
||||
logging print file 1
|
||||
logging level all debug
|
||||
logging level main notice
|
||||
logging level db notice
|
||||
logging level auc notice
|
||||
...
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
no usse-default
|
||||
usse gw1
|
||||
pattern prefix *110*
|
||||
pattern code *888#
|
||||
pattern regexp ^*[5-7]{3}*[0-9]+#$
|
||||
end
|
||||
|
||||
OsmoHLR(config-hlr-eusse)# exit
|
||||
OsmoHLR(config-hlr)# usse internal
|
||||
|
||||
OsmoHLR(config-hlr-iusse)# pattern code *#100#
|
||||
% Command incomplete.
|
||||
|
||||
OsmoHLR(config-hlr-iusse)# pattern code *#100# response Your extension is %m
|
||||
OsmoHLR(config-hlr-iusse)# pattern regexp ^*999*[0-3]+#$ response Mahlzeit!
|
||||
|
||||
OsmoHLR(config-hlr-iusse)# no pattern code *888#
|
||||
% Cannot remove non-existent pattern '*888#' of type 'code'
|
||||
|
||||
OsmoHLR(config-hlr-iusse)# show running-config
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 1
|
||||
logging print extended-timestamp 1
|
||||
logging print file 1
|
||||
logging level all debug
|
||||
logging level main notice
|
||||
logging level db notice
|
||||
logging level auc notice
|
||||
...
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
no usse-default
|
||||
usse gw1
|
||||
pattern prefix *110*
|
||||
pattern code *888#
|
||||
pattern regexp ^*[5-7]{3}*[0-9]+#$
|
||||
usse internal
|
||||
pattern code *#100# response Your extension is %m
|
||||
pattern regexp ^*999*[0-3]+#$ response Mahlzeit!
|
||||
end
|
||||
|
||||
OsmoHLR(config-hlr-iusse)# exit
|
||||
OsmoHLR(config-hlr)# usse-default test
|
||||
% Cannot find USSE 'test'
|
||||
|
||||
OsmoHLR(config-hlr)# usse-default internal
|
||||
OsmoHLR(config-hlr)# usse-default gw1
|
||||
OsmoHLR(config-hlr)# show running-config
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 1
|
||||
logging print extended-timestamp 1
|
||||
logging print file 1
|
||||
logging level all debug
|
||||
logging level main notice
|
||||
logging level db notice
|
||||
logging level auc notice
|
||||
...
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
usse-default gw1
|
||||
usse gw1
|
||||
pattern prefix *110*
|
||||
pattern code *888#
|
||||
pattern regexp ^*[5-7]{3}*[0-9]+#$
|
||||
usse internal
|
||||
pattern code *#100# response Your extension is %m
|
||||
pattern regexp ^*999*[0-3]+#$ response Mahlzeit!
|
||||
end
|
||||
|
||||
OsmoHLR(config-hlr)# no usse gw1
|
||||
% Cannot remove USSE 'gw1', it is the default route
|
||||
|
||||
OsmoHLR(config-hlr)# no usse-default
|
||||
OsmoHLR(config-hlr)# no usse gw1
|
||||
OsmoHLR(config-hlr)# show running-config
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 1
|
||||
logging print extended-timestamp 1
|
||||
logging print file 1
|
||||
logging level all debug
|
||||
logging level main notice
|
||||
logging level db notice
|
||||
logging level auc notice
|
||||
...
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ctrl
|
||||
bind 127.0.0.1
|
||||
hlr
|
||||
gsup
|
||||
bind ip 127.0.0.1
|
||||
no usse-default
|
||||
usse internal
|
||||
pattern code *#100# response Your extension is %m
|
||||
pattern regexp ^*999*[0-3]+#$ response Mahlzeit!
|
||||
end
|
||||
Reference in New Issue
Block a user