mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr.git
synced 2025-11-02 21:23:30 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65f51535d0 | ||
|
|
386381662c | ||
|
|
777860ddb5 | ||
|
|
1d0a030aa4 | ||
|
|
3ca9a1fd4f | ||
|
|
b74769f1b4 | ||
|
|
140dffd8f7 | ||
|
|
d63ec88dba | ||
|
|
e427bb299f | ||
|
|
d456fced21 | ||
|
|
c772e525ef | ||
|
|
83a41471da | ||
|
|
b4f25a0d1a | ||
|
|
b246580900 | ||
|
|
0c13953ed0 | ||
|
|
77a1bf66e6 | ||
|
|
37a5b70195 | ||
|
|
4d7cbfcc9a | ||
|
|
bfeea69cab | ||
|
|
3f9d1977df | ||
|
|
608e2e483f | ||
|
|
60673e7f77 | ||
|
|
ca8e6efca6 | ||
|
|
ed2e36316b | ||
|
|
649c335602 |
65
README.md
Normal file
65
README.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
osmo-hlr - Osmocom HLR Implementation
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
This repository contains a C-language implementation of a GSM Home
|
||||||
|
Location Register (HLR). It is part of the
|
||||||
|
[Osmocom](https://osmocom.org/) Open Source Mobile Communications
|
||||||
|
project.
|
||||||
|
|
||||||
|
Warning: While the HLR logical functionality is implemented, OsmoHLR
|
||||||
|
does not use the ETSI/3GPP TCAP/MAP protocol stack. Instead, a much
|
||||||
|
simpler custom protocol (GSUP) is used. This means, OsmoHLR is of
|
||||||
|
no use outside the context of an Osmocom core network. You can use
|
||||||
|
it with OsmoMSC, OsmoSGSN etc. - but not with third party components.
|
||||||
|
|
||||||
|
Homepage
|
||||||
|
--------
|
||||||
|
|
||||||
|
The official homepage of the project is
|
||||||
|
https://osmocom.org/projects/osmo-hlr/wiki
|
||||||
|
|
||||||
|
GIT Repository
|
||||||
|
--------------
|
||||||
|
|
||||||
|
You can clone from the official osmo-hlr.git repository using
|
||||||
|
|
||||||
|
git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr
|
||||||
|
|
||||||
|
There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr>
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
User Manuals and VTY reference manuals are [optionally] built in PDF form
|
||||||
|
as part of the build process.
|
||||||
|
|
||||||
|
Pre-rendered PDF version of the current "master" can be found at
|
||||||
|
[User Manual](https://ftp.osmocom.org/docs/latest/osmohlr-usermanual.pdf)
|
||||||
|
as well as the VTY reference manuals
|
||||||
|
* [VTY Reference Manual for osmo-hlr](https://ftp.osmocom.org/docs/latest/osmohlr-vty-reference.pdf)
|
||||||
|
|
||||||
|
Mailing List
|
||||||
|
------------
|
||||||
|
|
||||||
|
Discussions related to osmo-hlr are happening on the
|
||||||
|
openbsc@lists.osmocom.org mailing list, please see
|
||||||
|
https://lists.osmocom.org/mailman/listinfo/openbsc for subscription
|
||||||
|
options and the list archive.
|
||||||
|
|
||||||
|
Please observe the [Osmocom Mailing List
|
||||||
|
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
||||||
|
when posting.
|
||||||
|
|
||||||
|
Contributing
|
||||||
|
------------
|
||||||
|
|
||||||
|
Our coding standards are described at
|
||||||
|
https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards
|
||||||
|
|
||||||
|
We us a gerrit based patch submission/review process for managing
|
||||||
|
contributions. Please see
|
||||||
|
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
|
||||||
|
more details
|
||||||
|
|
||||||
|
The current patch queue for osmo-hlr can be seen at
|
||||||
|
https://gerrit.osmocom.org/#/q/project:osmo-hlr+status:open
|
||||||
13
configure.ac
13
configure.ac
@@ -41,11 +41,11 @@ PKG_PROG_PKG_CONFIG([0.20])
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(TALLOC, [talloc >= 2.0.1])
|
PKG_CHECK_MODULES(TALLOC, [talloc >= 2.0.1])
|
||||||
|
|
||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
|
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.5.0)
|
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0)
|
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0)
|
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.1.0)
|
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(SQLITE3, sqlite3)
|
PKG_CHECK_MODULES(SQLITE3, sqlite3)
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ if test "x$enable_ext_tests" = "xyes" ; then
|
|||||||
AM_PATH_PYTHON
|
AM_PATH_PYTHON
|
||||||
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
||||||
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
||||||
AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.])
|
AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
||||||
@@ -206,7 +206,6 @@ AC_OUTPUT(
|
|||||||
tests/Makefile
|
tests/Makefile
|
||||||
tests/auc/Makefile
|
tests/auc/Makefile
|
||||||
tests/auc/gen_ts_55_205_test_sets/Makefile
|
tests/auc/gen_ts_55_205_test_sets/Makefile
|
||||||
tests/gsup_server/Makefile
|
|
||||||
tests/gsup/Makefile
|
tests/gsup/Makefile
|
||||||
tests/db/Makefile
|
tests/db/Makefile
|
||||||
tests/db_upgrade/Makefile
|
tests/db_upgrade/Makefile
|
||||||
|
|||||||
@@ -2,3 +2,13 @@ SUBDIRS = \
|
|||||||
systemd \
|
systemd \
|
||||||
dgsm \
|
dgsm \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
EXTRA_DIST = osmo-hlr-post-upgrade.sh
|
||||||
|
|
||||||
|
install-data-hook:
|
||||||
|
install -Dm755 $(srcdir)/osmo-hlr-post-upgrade.sh \
|
||||||
|
-t $(DESTDIR)$(datadir)/osmocom/
|
||||||
|
|
||||||
|
uninstall-hook:
|
||||||
|
@$(PRE_UNINSTALL)
|
||||||
|
$(RM) $(DESTDIR)$(datadir)/osmocom/osmo-hlr-post-upgrade.sh
|
||||||
|
|||||||
95
contrib/osmo-hlr-post-upgrade.sh
Normal file
95
contrib/osmo-hlr-post-upgrade.sh
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
# Copyright 2021 sysmocom s.f.m.c GmbH <info@sysmocom.de>
|
||||||
|
#
|
||||||
|
# Packagers are supposed to call this script in post-upgrade, so it can safely
|
||||||
|
# upgrade the database scheme if required.
|
||||||
|
|
||||||
|
DB="/var/lib/osmocom/hlr.db"
|
||||||
|
IS_ACTIVE=0
|
||||||
|
|
||||||
|
msg() {
|
||||||
|
echo "osmo-hlr-post-upgrade: $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
err() {
|
||||||
|
msg "ERROR: $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
open_db() {
|
||||||
|
# Attempt to open the database with osmo-hlr-db-tool, it will fail if
|
||||||
|
# upgrading the schema is required
|
||||||
|
osmo-hlr-db-tool -s -l "$DB" create
|
||||||
|
}
|
||||||
|
|
||||||
|
check_upgrade_required() {
|
||||||
|
if ! [ -e "$DB" ]; then
|
||||||
|
msg "nothing to do (no existing database)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if open_db 2>/dev/null; then
|
||||||
|
msg "nothing to do (database version is up to date)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg "database upgrade is required"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
if systemctl is-active -q osmo-hlr; then
|
||||||
|
IS_ACTIVE=1
|
||||||
|
msg "stopping osmo-hlr service"
|
||||||
|
systemctl stop osmo-hlr
|
||||||
|
|
||||||
|
# Verify that it stopped
|
||||||
|
for i in $(seq 1 100); do
|
||||||
|
if ! systemctl is-active -q osmo-hlr; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
err "failed to stop osmo-hlr service"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
msg "osmo-hlr service is not running"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_backup() {
|
||||||
|
backup="$DB.$(date +%Y%m%d%H%M%S).bak"
|
||||||
|
msg "creating backup: $backup"
|
||||||
|
if [ -e "$backup" ]; then
|
||||||
|
err "backup already exists: $backup"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cp "$DB" "$backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
upgrade() {
|
||||||
|
msg "performing database upgrade"
|
||||||
|
osmo-hlr-db-tool -s -U -l "$DB" create
|
||||||
|
|
||||||
|
if ! open_db 2>/dev/null; then
|
||||||
|
err "failed to open the database after upgrade"
|
||||||
|
err "osmo-hlr-db-tool output:"
|
||||||
|
open_db
|
||||||
|
# exit because of "set -e"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg "database upgrade successful"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
if [ "$IS_ACTIVE" = "1" ]; then
|
||||||
|
msg "starting osmo-hlr service"
|
||||||
|
systemctl start osmo-hlr
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_upgrade_required
|
||||||
|
stop_service
|
||||||
|
create_backup
|
||||||
|
upgrade
|
||||||
|
start_service
|
||||||
@@ -29,11 +29,11 @@ BuildRequires: python3
|
|||||||
%if 0%{?suse_version}
|
%if 0%{?suse_version}
|
||||||
BuildRequires: systemd-rpm-macros
|
BuildRequires: systemd-rpm-macros
|
||||||
%endif
|
%endif
|
||||||
BuildRequires: pkgconfig(libosmoabis) >= 1.1.0
|
BuildRequires: pkgconfig(libosmoabis) >= 1.3.0
|
||||||
BuildRequires: pkgconfig(libosmocore) >= 1.5.0
|
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.5.0
|
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmogsm) >= 1.5.0
|
BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmovty) >= 1.5.0
|
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(sqlite3)
|
BuildRequires: pkgconfig(sqlite3)
|
||||||
BuildRequires: pkgconfig(talloc) >= 2.0.1
|
BuildRequires: pkgconfig(talloc) >= 2.0.1
|
||||||
# only needed for populate_hlr_db.pl
|
# only needed for populate_hlr_db.pl
|
||||||
@@ -136,10 +136,13 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
|||||||
|
|
||||||
%pre
|
%pre
|
||||||
%service_add_pre %{name}.service
|
%service_add_pre %{name}.service
|
||||||
|
%endif
|
||||||
|
|
||||||
%post
|
%post
|
||||||
|
%if 0%{?suse_version}
|
||||||
%service_add_post %{name}.service
|
%service_add_post %{name}.service
|
||||||
%endif
|
%endif
|
||||||
|
/usr/share/osmocom/osmo-hlr-post-upgrade.sh
|
||||||
|
|
||||||
%post -n libosmo-gsup-client0 -p /sbin/ldconfig
|
%post -n libosmo-gsup-client0 -p /sbin/ldconfig
|
||||||
%postun -n libosmo-gsup-client0 -p /sbin/ldconfig
|
%postun -n libosmo-gsup-client0 -p /sbin/ldconfig
|
||||||
@@ -162,6 +165,8 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
|||||||
%dir %{_sysconfdir}/osmocom
|
%dir %{_sysconfdir}/osmocom
|
||||||
%config %{_sysconfdir}/osmocom/osmo-hlr.cfg
|
%config %{_sysconfdir}/osmocom/osmo-hlr.cfg
|
||||||
%{_unitdir}/osmo-hlr.service
|
%{_unitdir}/osmo-hlr.service
|
||||||
|
%dir %{_datadir}/osmocom
|
||||||
|
%{_datadir}/osmocom/osmo-hlr-post-upgrade.sh
|
||||||
|
|
||||||
%files -n libosmo-gsup-client0
|
%files -n libosmo-gsup-client0
|
||||||
%{_libdir}/libosmo-gsup-client.so.0*
|
%{_libdir}/libosmo-gsup-client.so.0*
|
||||||
|
|||||||
49
debian/changelog
vendored
49
debian/changelog
vendored
@@ -1,3 +1,52 @@
|
|||||||
|
osmo-hlr (1.5.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* treewide: remove FSF address
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* fixup: debian: remove unneeded dependency libdbd-sqlite3
|
||||||
|
* debian: add new 'osmo-mslookup-utils' package
|
||||||
|
* tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* ctrl: Mark function as static
|
||||||
|
* tests: Allow specyfing specific ctrl test to run
|
||||||
|
* tests/ctrl: Move ERROR test scenario to proper file
|
||||||
|
* Fix db_subscr_create() not returning -EEXIST expected by VTY subscriber create cmd
|
||||||
|
* ctrl: Introduce cmd SET subscriber.create <imsi>
|
||||||
|
* ctrl: Introduce CTRL command subscriber.by-*.msisdn
|
||||||
|
* cosmetic: hlr_vty_subscr.c: Fix trailing whitespace
|
||||||
|
* ctrl: Introduce cmd SET subscriber.delete <imsi>
|
||||||
|
* ctrl: Introduce CTRL command subscriber.by-*.aud2g <algo[,ki]>
|
||||||
|
* ctrl: Introduce CTRL command subscriber.by-*.aud3g <algo[,KI,(op|opc),OP_C[,ind_bitlen]]>
|
||||||
|
* doc: Document new subscriber CTRL commands
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* update git URLs (git -> https; gitea)
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 28 Jun 2022 18:38:31 +0200
|
||||||
|
|
||||||
|
osmo-hlr (1.4.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Keith ]
|
||||||
|
* Correct configuration written from vty
|
||||||
|
* vty: enable show subscribers filtered by IMEI
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* add README.md file as customary for cgit, github, gitlab, etc.
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* Add post-upgrade script for automatic db upgrade
|
||||||
|
* debian/control: remove dh-systemd build-depend
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* db: Avoid use uninitialized rc if running 0 statements
|
||||||
|
|
||||||
|
[ Neels Hofmeyr ]
|
||||||
|
* db v6: determine 3G AUC IND from VLR name
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 14:56:41 +0100
|
||||||
|
|
||||||
osmo-hlr (1.3.0) unstable; urgency=medium
|
osmo-hlr (1.3.0) unstable; urgency=medium
|
||||||
|
|
||||||
[ Alexander Couzens ]
|
[ Alexander Couzens ]
|
||||||
|
|||||||
25
debian/control
vendored
25
debian/control
vendored
@@ -5,23 +5,22 @@ Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
|||||||
Build-Depends: debhelper (>= 9),
|
Build-Depends: debhelper (>= 9),
|
||||||
pkg-config,
|
pkg-config,
|
||||||
dh-autoreconf,
|
dh-autoreconf,
|
||||||
dh-systemd (>= 1.5),
|
|
||||||
autotools-dev,
|
autotools-dev,
|
||||||
python3-minimal,
|
python3-minimal,
|
||||||
libosmocore-dev (>= 1.5.0),
|
libosmocore-dev (>= 1.7.0),
|
||||||
libosmo-abis-dev (>= 1.1.0),
|
libosmo-abis-dev (>= 1.3.0),
|
||||||
libosmo-netif-dev (>= 1.1.0),
|
libosmo-netif-dev (>= 1.2.0),
|
||||||
libsqlite3-dev,
|
libsqlite3-dev,
|
||||||
sqlite3,
|
sqlite3,
|
||||||
osmo-gsm-manuals-dev (>= 1.1.0)
|
osmo-gsm-manuals-dev (>= 1.3.0)
|
||||||
Standards-Version: 3.9.6
|
Standards-Version: 3.9.6
|
||||||
Vcs-Browser: http://cgit.osmocom.org/osmo-hlr
|
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr
|
||||||
Vcs-Git: git://git.osmocom.org/osmo-hlr
|
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr
|
||||||
Homepage: https://projects.osmocom.org/projects/osmo-hlr
|
Homepage: https://projects.osmocom.org/projects/osmo-hlr
|
||||||
|
|
||||||
Package: osmo-hlr
|
Package: osmo-hlr
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
Description: Osmocom Home Location Register
|
Description: Osmocom Home Location Register
|
||||||
OsmoHLR is a Osmocom implementation of HLR (Home Location Registrar) which works over GSUP
|
OsmoHLR is a Osmocom implementation of HLR (Home Location Registrar) which works over GSUP
|
||||||
protocol. The subscribers are store in sqlite DB. It supports both 2G and 3G authentication.
|
protocol. The subscribers are store in sqlite DB. It supports both 2G and 3G authentication.
|
||||||
@@ -81,6 +80,16 @@ Description: Development headers of Osmocom MS lookup library
|
|||||||
.
|
.
|
||||||
This package contains the development headers.
|
This package contains the development headers.
|
||||||
|
|
||||||
|
Package: osmo-mslookup-utils
|
||||||
|
Architecture: any
|
||||||
|
Section: utils
|
||||||
|
Depends: ${shlibs:Depends},
|
||||||
|
libosmo-mslookup0 (= ${binary:Version}),
|
||||||
|
${misc:Depends}
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: Utilities for Osmocom MS lookup
|
||||||
|
This package contains a simple MS lookup client utility.
|
||||||
|
|
||||||
Package: osmo-hlr-doc
|
Package: osmo-hlr-doc
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Section: doc
|
Section: doc
|
||||||
|
|||||||
1
debian/osmo-hlr.install
vendored
1
debian/osmo-hlr.install
vendored
@@ -5,4 +5,5 @@
|
|||||||
/usr/share/doc/osmo-hlr/sql/hlr.sql
|
/usr/share/doc/osmo-hlr/sql/hlr.sql
|
||||||
/usr/share/doc/osmo-hlr/sql/hlr_data.sql
|
/usr/share/doc/osmo-hlr/sql/hlr_data.sql
|
||||||
/usr/share/doc/osmo-hlr/examples/osmo-hlr.cfg
|
/usr/share/doc/osmo-hlr/examples/osmo-hlr.cfg
|
||||||
|
/usr/share/osmocom/osmo-hlr-post-upgrade.sh
|
||||||
/var/lib/osmocom
|
/var/lib/osmocom
|
||||||
|
|||||||
1
debian/osmo-mslookup-utils.install
vendored
Normal file
1
debian/osmo-mslookup-utils.install
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
usr/bin/osmo-mslookup-client
|
||||||
5
debian/postinst
vendored
Executable file
5
debian/postinst
vendored
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
# Debian's postinst script is called on both installation and upgrade. Call the
|
||||||
|
# post-upgrade script in both cases, it won't do anything if there is nothing
|
||||||
|
# to do.
|
||||||
|
/usr/share/osmocom/osmo-hlr-post-upgrade.sh
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
EXTRA_DIST = example_subscriber_add_update_delete.vty \
|
EXTRA_DIST = \
|
||||||
|
example_subscriber_add_update_delete.vty \
|
||||||
|
example_subscriber_aud2g.ctrl \
|
||||||
|
example_subscriber_aud3g.ctrl \
|
||||||
example_subscriber_cs_ps_enabled.ctrl \
|
example_subscriber_cs_ps_enabled.ctrl \
|
||||||
example_subscriber_info.ctrl \
|
example_subscriber_info.ctrl \
|
||||||
|
example_subscriber_msisdn.ctrl \
|
||||||
osmohlr-usermanual.adoc \
|
osmohlr-usermanual.adoc \
|
||||||
osmohlr-usermanual-docinfo.xml \
|
osmohlr-usermanual-docinfo.xml \
|
||||||
osmohlr-vty-reference.xml \
|
osmohlr-vty-reference.xml \
|
||||||
|
|||||||
@@ -5,6 +5,16 @@ The actual protocol is described in <<common-control-if>>, the variables common
|
|||||||
to all programs using it are described in <<ctrl_common_vars>>. This section
|
to all programs using it are described in <<ctrl_common_vars>>. This section
|
||||||
describes the CTRL interface variables specific to OsmoHLR.
|
describes the CTRL interface variables specific to OsmoHLR.
|
||||||
|
|
||||||
|
Subscribers can be created and deleted using the following SET commands:
|
||||||
|
|
||||||
|
.Subscriber management commands available on OsmoHLR's Control interface
|
||||||
|
[options="header",width="100%",cols="35%,65%"]
|
||||||
|
|===
|
||||||
|
|Command|Comment
|
||||||
|
|subscriber.create '123456'|Create a new subscriber with IMSI "123456" to the database. Returns database ID of the subscriber being created.
|
||||||
|
|subscriber.delete '123456'|Delete subscriber with IMSI "123456" from database. Returns database ID of the subscriber being deleted.
|
||||||
|
|===
|
||||||
|
|
||||||
All subscriber variables are available by different selectors, which are freely
|
All subscriber variables are available by different selectors, which are freely
|
||||||
interchangeable:
|
interchangeable:
|
||||||
|
|
||||||
@@ -28,6 +38,9 @@ Each of the above selectors feature all of these control variables:
|
|||||||
|subscriber.by-\*.*info-all*|R|No||List both 'info' and 'info-aud' in one
|
|subscriber.by-\*.*info-all*|R|No||List both 'info' and 'info-aud' in one
|
||||||
|subscriber.by-\*.*cs-enabled*|RW|No|'1' or '0'|Enable/disable circuit-switched access
|
|subscriber.by-\*.*cs-enabled*|RW|No|'1' or '0'|Enable/disable circuit-switched access
|
||||||
|subscriber.by-\*.*ps-enabled*|RW|No|'1' or '0'|Enable/disable packet-switched access
|
|subscriber.by-\*.*ps-enabled*|RW|No|'1' or '0'|Enable/disable packet-switched access
|
||||||
|
|subscriber.by-\*.*msisdn*|RW|No|valid MSISDN string|Get/Set assigned MSISDN
|
||||||
|
|subscriber.by-\*.*aud2g*|RW|No|'algo[,KI]'|Get/Set 2g Authentication Data
|
||||||
|
|subscriber.by-\*.*aud2g*|RW|No|'algo[,KI,("op"|"opc"),OP_C[,ind_bitlen]]'|Get/Set 3g Authentication Data
|
||||||
|===
|
|===
|
||||||
|
|
||||||
=== subscriber.by-*.info, info-aud, info-all
|
=== subscriber.by-*.info, info-aud, info-all
|
||||||
@@ -104,3 +117,63 @@ commands:
|
|||||||
----
|
----
|
||||||
include::../example_subscriber_cs_ps_enabled.ctrl[]
|
include::../example_subscriber_cs_ps_enabled.ctrl[]
|
||||||
----
|
----
|
||||||
|
|
||||||
|
=== subscriber.by-*.msisdn
|
||||||
|
|
||||||
|
Get or set the MSISDN currently assigned to a subscriber.
|
||||||
|
|
||||||
|
|
||||||
|
This is an example transcript that illustrates use of this command:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::../example_subscriber_msisdn.ctrl[]
|
||||||
|
----
|
||||||
|
|
||||||
|
=== subscriber.by-*.aud2g
|
||||||
|
|
||||||
|
Get or set the 2G Authentication data of a subscriber.
|
||||||
|
|
||||||
|
The information is stored/retrieved as a comma separated list of fields:
|
||||||
|
|
||||||
|
----
|
||||||
|
algo[,KI]
|
||||||
|
----
|
||||||
|
|
||||||
|
Where::
|
||||||
|
* *KI* is the KI as a hexadecimal string.
|
||||||
|
* *algo* is one of the following algorithms: _none, xor, comp128v1, comp128v2,
|
||||||
|
comp128v3_.
|
||||||
|
|
||||||
|
All values are case insensitive.
|
||||||
|
|
||||||
|
This is an example transcript that illustrates use of this command:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::../example_subscriber_aud2g.ctrl[]
|
||||||
|
----
|
||||||
|
|
||||||
|
=== subscriber.by-*.aud3g
|
||||||
|
|
||||||
|
Get or set the 3G Authentication data of a subscriber.
|
||||||
|
|
||||||
|
The information is stored/retrieved as a comma separated list of fields:
|
||||||
|
|
||||||
|
----
|
||||||
|
algo[,KI,("op"|"opc"),OP_C[,ind_bitlen]]
|
||||||
|
----
|
||||||
|
|
||||||
|
Where:
|
||||||
|
* *KI* is the KI as a hexadecimal string.
|
||||||
|
* *algo* is one of the following algorithms: _none, xor, milenage_.
|
||||||
|
* "op" or "opc" indicates whether next field is an OP or OPC value.
|
||||||
|
* *OP_C* contains an OP or OPC values as hexadecimal string, based on what the
|
||||||
|
previous field specifies.
|
||||||
|
* *ind_bitlen* is set to 5 by default if not provided.
|
||||||
|
|
||||||
|
All values are case insensitive.
|
||||||
|
|
||||||
|
This is an example transcript that illustrates use of this command:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::../example_subscriber_aud3g.ctrl[]
|
||||||
|
----
|
||||||
|
|||||||
14
doc/manuals/example_subscriber_aud2g.ctrl
Normal file
14
doc/manuals/example_subscriber_aud2g.ctrl
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
GET 1 subscriber.by-imsi-901991234567891.aud2g
|
||||||
|
GET_REPLY 1 subscriber.by-imsi-901991234567891.aud2g none
|
||||||
|
|
||||||
|
SET 2 subscriber.by-imsi-901991234567891.aud2g xor,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||||
|
SET_REPLY 2 subscriber.by-imsi-901991234567891.aud2g OK
|
||||||
|
|
||||||
|
GET 3 subscriber.by-imsi-901991234567891.aud2g
|
||||||
|
GET_REPLY 3 subscriber.by-imsi-901991234567891.aud2g XOR,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||||
|
|
||||||
|
SET 4 subscriber.by-imsi-901991234567891.aud2g none
|
||||||
|
SET_REPLY 4 subscriber.by-imsi-901991234567891.aud2g OK
|
||||||
|
|
||||||
|
GET 5 subscriber.by-imsi-901991234567891.aud2g
|
||||||
|
GET_REPLY 5 subscriber.by-imsi-901991234567891.aud2g none
|
||||||
20
doc/manuals/example_subscriber_aud3g.ctrl
Normal file
20
doc/manuals/example_subscriber_aud3g.ctrl
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
GET 117 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 117 subscriber.by-imsi-901991234567891.aud3g none
|
||||||
|
|
||||||
|
SET 118 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,FB2A3D1B360F599ABAB99DB8669F8308
|
||||||
|
SET_REPLY 118 subscriber.by-imsi-901991234567891.aud3g OK
|
||||||
|
|
||||||
|
GET 119 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 119 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,fb2a3d1b360f599abab99db8669f8308,5
|
||||||
|
|
||||||
|
SET 120 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,FB2A3D1B360F599ABAB99DB8669F8308,7
|
||||||
|
SET_REPLY 120 subscriber.by-imsi-901991234567891.aud3g OK
|
||||||
|
|
||||||
|
GET 121 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 121 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,7
|
||||||
|
|
||||||
|
SET 122 subscriber.by-imsi-901991234567891.aud3g none
|
||||||
|
SET_REPLY 122 subscriber.by-imsi-901991234567891.aud3g OK
|
||||||
|
|
||||||
|
GET 123 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 123 subscriber.by-imsi-901991234567891.aud3g none
|
||||||
8
doc/manuals/example_subscriber_msisdn.ctrl
Normal file
8
doc/manuals/example_subscriber_msisdn.ctrl
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
GET 1 subscriber.by-imsi-901991234567891.msisdn
|
||||||
|
GET_REPLY 1 subscriber.by-imsi-901991234567891.msisdn none
|
||||||
|
|
||||||
|
SET 2 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||||
|
SET_REPLY 2 subscriber.by-imsi-901991234567891.msisdn OK
|
||||||
|
|
||||||
|
GET 3 subscriber.by-imsi-901991234567891.msisdn
|
||||||
|
GET_REPLY 3 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||||
@@ -30,5 +30,4 @@ enum hlr_ctrl_node {
|
|||||||
_LAST_CTRL_NODE_HLR
|
_LAST_CTRL_NODE_HLR
|
||||||
};
|
};
|
||||||
|
|
||||||
int hlr_ctrl_cmds_install();
|
|
||||||
struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr);
|
struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
#include <osmocom/gsupclient/cni_peer_id.h>
|
#include <osmocom/gsupclient/cni_peer_id.h>
|
||||||
|
#include <osmocom/gsm/gsup.h>
|
||||||
|
|
||||||
struct hlr;
|
struct hlr;
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ enum stmt_idx {
|
|||||||
DB_STMT_SEL_ALL_ORDER_LAST_SEEN,
|
DB_STMT_SEL_ALL_ORDER_LAST_SEEN,
|
||||||
DB_STMT_SEL_FILTER_MSISDN,
|
DB_STMT_SEL_FILTER_MSISDN,
|
||||||
DB_STMT_SEL_FILTER_IMSI,
|
DB_STMT_SEL_FILTER_IMSI,
|
||||||
|
DB_STMT_SEL_FILTER_IMEI,
|
||||||
DB_STMT_SEL_FILTER_CS,
|
DB_STMT_SEL_FILTER_CS,
|
||||||
DB_STMT_SEL_FILTER_PS,
|
DB_STMT_SEL_FILTER_PS,
|
||||||
DB_STMT_SEL_BY_IMSI,
|
DB_STMT_SEL_BY_IMSI,
|
||||||
@@ -39,6 +41,9 @@ enum stmt_idx {
|
|||||||
DB_STMT_SET_LAST_LU_SEEN_PS,
|
DB_STMT_SET_LAST_LU_SEEN_PS,
|
||||||
DB_STMT_EXISTS_BY_IMSI,
|
DB_STMT_EXISTS_BY_IMSI,
|
||||||
DB_STMT_EXISTS_BY_MSISDN,
|
DB_STMT_EXISTS_BY_MSISDN,
|
||||||
|
DB_STMT_IND_ADD,
|
||||||
|
DB_STMT_IND_SELECT,
|
||||||
|
DB_STMT_IND_DEL,
|
||||||
_NUM_DB_STMT
|
_NUM_DB_STMT
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -172,6 +177,9 @@ int db_subscr_lu(struct db_context *dbc, int64_t subscr_id,
|
|||||||
int db_subscr_purge(struct db_context *dbc, const char *by_imsi,
|
int db_subscr_purge(struct db_context *dbc, const char *by_imsi,
|
||||||
bool purge_val, bool is_ps);
|
bool purge_val, bool is_ps);
|
||||||
|
|
||||||
|
int db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr, unsigned int *ind);
|
||||||
|
int db_ind_del(struct db_context *dbc, const struct osmo_cni_peer_id *vlr);
|
||||||
|
|
||||||
/*! Call sqlite3_column_text() and copy result to a char[].
|
/*! Call sqlite3_column_text() and copy result to a char[].
|
||||||
* \param[out] buf A char[] used as sizeof() arg(!) and osmo_strlcpy() target.
|
* \param[out] buf A char[] used as sizeof() arg(!) and osmo_strlcpy() target.
|
||||||
* \param[in] stmt An sqlite3_stmt*.
|
* \param[in] stmt An sqlite3_stmt*.
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ struct osmo_gsup_conn {
|
|||||||
//struct oap_state oap_state;
|
//struct oap_state oap_state;
|
||||||
struct tlv_parsed ccm;
|
struct tlv_parsed ccm;
|
||||||
|
|
||||||
unsigned int auc_3g_ind; /*!< IND index used for UMTS AKA SQN */
|
|
||||||
|
|
||||||
/* Set when Location Update is received: */
|
/* Set when Location Update is received: */
|
||||||
bool supports_cs; /* client supports OSMO_GSUP_CN_DOMAIN_CS */
|
bool supports_cs; /* client supports OSMO_GSUP_CN_DOMAIN_CS */
|
||||||
bool supports_ps; /* client supports OSMO_GSUP_CN_DOMAIN_PS */
|
bool supports_ps; /* client supports OSMO_GSUP_CN_DOMAIN_PS */
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ enum hlr_vty_node {
|
|||||||
MSLOOKUP_CLIENT_NODE,
|
MSLOOKUP_CLIENT_NODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define A38_XOR_MIN_KEY_LEN 12
|
||||||
|
#define A38_XOR_MAX_KEY_LEN 16
|
||||||
|
#define A38_COMP128_KEY_LEN 16
|
||||||
|
#define MILENAGE_KEY_LEN 16
|
||||||
|
|
||||||
int hlr_vty_is_config_node(struct vty *vty, int node);
|
int hlr_vty_is_config_node(struct vty *vty, int node);
|
||||||
int hlr_vty_go_parent(struct vty *vty);
|
int hlr_vty_go_parent(struct vty *vty);
|
||||||
void hlr_vty_init(void);
|
void hlr_vty_init(void);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ enum {
|
|||||||
DMSLOOKUP,
|
DMSLOOKUP,
|
||||||
DLU,
|
DLU,
|
||||||
DDGSM,
|
DDGSM,
|
||||||
|
DCTRL,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct log_info hlr_log_info;
|
extern const struct log_info hlr_log_info;
|
||||||
|
|||||||
10
sql/hlr.sql
10
sql/hlr.sql
@@ -79,8 +79,16 @@ CREATE TABLE auc_3g (
|
|||||||
ind_bitlen INTEGER NOT NULL DEFAULT 5
|
ind_bitlen INTEGER NOT NULL DEFAULT 5
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE ind (
|
||||||
|
-- 3G auth IND pool to be used for this VLR
|
||||||
|
ind INTEGER PRIMARY KEY,
|
||||||
|
-- VLR identification, usually the GSUP source_name
|
||||||
|
vlr TEXT NOT NULL,
|
||||||
|
UNIQUE (vlr)
|
||||||
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX idx_subscr_imsi ON subscriber (imsi);
|
CREATE UNIQUE INDEX idx_subscr_imsi ON subscriber (imsi);
|
||||||
|
|
||||||
-- Set HLR database schema version number
|
-- Set HLR database schema version number
|
||||||
-- Note: This constant is currently duplicated in src/db.c and must be kept in sync!
|
-- Note: This constant is currently duplicated in src/db.c and must be kept in sync!
|
||||||
PRAGMA user_version = 5;
|
PRAGMA user_version = 6;
|
||||||
|
|||||||
395
src/ctrl.c
395
src/ctrl.c
@@ -31,12 +31,16 @@
|
|||||||
#include <osmocom/hlr/hlr.h>
|
#include <osmocom/hlr/hlr.h>
|
||||||
#include <osmocom/hlr/ctrl.h>
|
#include <osmocom/hlr/ctrl.h>
|
||||||
#include <osmocom/hlr/db.h>
|
#include <osmocom/hlr/db.h>
|
||||||
|
#include <osmocom/hlr/hlr_vty.h>
|
||||||
|
|
||||||
#define SEL_BY "by-"
|
#define SEL_BY "by-"
|
||||||
#define SEL_BY_IMSI SEL_BY "imsi-"
|
#define SEL_BY_IMSI SEL_BY "imsi-"
|
||||||
#define SEL_BY_MSISDN SEL_BY "msisdn-"
|
#define SEL_BY_MSISDN SEL_BY "msisdn-"
|
||||||
#define SEL_BY_ID SEL_BY "id-"
|
#define SEL_BY_ID SEL_BY "id-"
|
||||||
|
|
||||||
|
extern bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
||||||
|
int *minlen, int *maxlen);
|
||||||
|
|
||||||
#define hexdump_buf(buf) osmo_hexdump_nospc((void*)buf, sizeof(buf))
|
#define hexdump_buf(buf) osmo_hexdump_nospc((void*)buf, sizeof(buf))
|
||||||
|
|
||||||
static bool startswith(const char *str, const char *start)
|
static bool startswith(const char *str, const char *start)
|
||||||
@@ -197,6 +201,77 @@ static void print_subscr_info_aud3g(struct ctrl_cmd *cmd, struct osmo_sub_auth_d
|
|||||||
aud->u.umts.sqn);
|
aud->u.umts.sqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTRL_CMD_DEFINE_WO_NOVRF(subscr_create, "create");
|
||||||
|
static int set_subscr_create(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *imsi = cmd->value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!osmo_imsi_str_valid(imsi)) {
|
||||||
|
cmd->reply = "Invalid IMSI value.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the subscriber in the DB */
|
||||||
|
rc = db_subscr_create(g_hlr->dbc, imsi, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS);
|
||||||
|
if (rc) {
|
||||||
|
if (rc == -EEXIST)
|
||||||
|
cmd->reply = "Subscriber already exists.";
|
||||||
|
else
|
||||||
|
cmd->reply = "Cannot create subscriber.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGP(DCTRL, LOGL_INFO, "Created subscriber IMSI='%s'\n",
|
||||||
|
imsi);
|
||||||
|
|
||||||
|
/* Retrieve data of newly created subscriber: */
|
||||||
|
rc = db_subscr_get_by_imsi(hlr->dbc, imsi, &subscr);
|
||||||
|
if (rc < 0) {
|
||||||
|
cmd->reply = "Failed retrieving ID of newly created subscriber.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "%" PRIu64, subscr.id);
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTRL_CMD_DEFINE_WO_NOVRF(subscr_delete, "delete");
|
||||||
|
static int set_subscr_delete(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *imsi = cmd->value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!osmo_imsi_str_valid(imsi)) {
|
||||||
|
cmd->reply = "Invalid IMSI value.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve data of newly created subscriber: */
|
||||||
|
rc = db_subscr_get_by_imsi(hlr->dbc, imsi, &subscr);
|
||||||
|
if (rc < 0) {
|
||||||
|
cmd->reply = "Subscriber doesn't exist.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the subscriber in the DB */
|
||||||
|
rc = db_subscr_delete_by_id(g_hlr->dbc, subscr.id);
|
||||||
|
if (rc) {
|
||||||
|
cmd->reply = "Cannot delete subscriber.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGP(DCTRL, LOGL_INFO, "Deleted subscriber IMSI='%s'\n",
|
||||||
|
imsi);
|
||||||
|
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "%" PRIu64, subscr.id);
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
CTRL_CMD_DEFINE_RO(subscr_info, "info");
|
CTRL_CMD_DEFINE_RO(subscr_info, "info");
|
||||||
static int get_subscr_info(struct ctrl_cmd *cmd, void *data)
|
static int get_subscr_info(struct ctrl_cmd *cmd, void *data)
|
||||||
{
|
{
|
||||||
@@ -351,17 +426,302 @@ static int set_subscr_cs_enabled(struct ctrl_cmd *cmd, void *data)
|
|||||||
return set_subscr_cs_ps_enabled(cmd, data, false);
|
return set_subscr_cs_ps_enabled(cmd, data, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hlr_ctrl_cmds_install()
|
CTRL_CMD_DEFINE(subscr_msisdn, "msisdn");
|
||||||
|
static int verify_subscr_msisdn(struct ctrl_cmd *cmd, const char *value, void *data)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
struct hlr_subscriber subscr;
|
||||||
|
if (!value)
|
||||||
|
return 1;
|
||||||
|
if (strlen(value) > sizeof(subscr.msisdn) - 1)
|
||||||
|
return 1;
|
||||||
|
if (strcmp(value, "none") != 0 && !osmo_msisdn_str_valid(value))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int get_subscr_msisdn(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *by_selector = cmd->node;
|
||||||
|
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info);
|
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_aud);
|
return CTRL_CMD_ERROR;
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_all);
|
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_ps_enabled);
|
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_cs_enabled);
|
|
||||||
|
|
||||||
return rc;
|
if (strlen(subscr.msisdn) == 0)
|
||||||
|
snprintf(subscr.msisdn, sizeof(subscr.msisdn), "none");
|
||||||
|
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "%s", subscr.msisdn);
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
static int set_subscr_msisdn(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *by_selector = cmd->node;
|
||||||
|
const char *msisdn;
|
||||||
|
|
||||||
|
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
|
||||||
|
if (strcmp(cmd->value, "none") == 0)
|
||||||
|
msisdn = NULL;
|
||||||
|
else
|
||||||
|
msisdn = cmd->value;
|
||||||
|
|
||||||
|
if (db_subscr_update_msisdn_by_imsi(g_hlr->dbc, subscr.imsi, msisdn)) {
|
||||||
|
cmd->reply = "Update MSISDN failed";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->reply = "OK";
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value format: <algo[,KI]> */
|
||||||
|
CTRL_CMD_DEFINE(subscr_aud2g, "aud2g");
|
||||||
|
static int verify_subscr_aud2g(struct ctrl_cmd *cmd, const char *value, void *data)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
return 1;
|
||||||
|
if (strcasecmp(value, "none") != 0 && !strchr(value, ','))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int get_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *by_selector = cmd->node;
|
||||||
|
struct osmo_sub_auth_data aud2g;
|
||||||
|
struct osmo_sub_auth_data aud3g_unused;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
|
||||||
|
rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g, &aud3g_unused, NULL);
|
||||||
|
switch (rc) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case -ENOENT:
|
||||||
|
case -ENOKEY:
|
||||||
|
aud2g.algo = OSMO_AUTH_ALG_NONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd->reply = "Error retrieving data from database.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aud2g.algo == OSMO_AUTH_ALG_NONE) {
|
||||||
|
cmd->reply = "none";
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "%s,%s", osmo_auth_alg_name(aud2g.algo),
|
||||||
|
hexdump_buf(aud2g.u.gsm.ki));
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
static int set_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *by_selector = cmd->node;
|
||||||
|
char *tmp = NULL, *tok, *saveptr;
|
||||||
|
int minlen = 0;
|
||||||
|
int maxlen = 0;
|
||||||
|
struct sub_auth_data_str aud2g = {
|
||||||
|
.type = OSMO_AUTH_TYPE_GSM
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
|
||||||
|
tmp = talloc_strdup(cmd, cmd->value);
|
||||||
|
if (!tmp) {
|
||||||
|
cmd->reply = "OOM";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse alg_type: */
|
||||||
|
tok = strtok_r(tmp, ",", &saveptr);
|
||||||
|
if (!tok) {
|
||||||
|
cmd->reply = "Invalid format";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
if (strcmp(tok, "none") == 0) {
|
||||||
|
aud2g.algo = OSMO_AUTH_ALG_NONE;
|
||||||
|
} else if (!auth_algo_parse(tok, &aud2g.algo, &minlen, &maxlen)) {
|
||||||
|
cmd->reply = "Unknown auth algorithm.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aud2g.algo != OSMO_AUTH_ALG_NONE) {
|
||||||
|
tok = strtok_r(NULL, "\0", &saveptr);
|
||||||
|
if (!tok) {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
aud2g.u.gsm.ki = tok;
|
||||||
|
if (!osmo_is_hexstr(aud2g.u.gsm.ki, minlen * 2, maxlen * 2, true)) {
|
||||||
|
cmd->reply = "Invalid KI.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud2g)) {
|
||||||
|
cmd->reply = "Update aud2g failed.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->reply = "OK";
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value format: <algo[,KI,(op|opc),OP_C[,ind_bitlen]]> */
|
||||||
|
CTRL_CMD_DEFINE(subscr_aud3g, "aud3g");
|
||||||
|
static int verify_subscr_aud3g(struct ctrl_cmd *cmd, const char *value, void *data)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
return 1;
|
||||||
|
if (strcasecmp(value, "none") != 0 && !strchr(value, ','))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int get_subscr_aud3g(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *by_selector = cmd->node;
|
||||||
|
struct osmo_sub_auth_data aud2g_unused;
|
||||||
|
struct osmo_sub_auth_data aud3g;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
|
||||||
|
rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g_unused, &aud3g, NULL);
|
||||||
|
switch (rc) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case -ENOENT:
|
||||||
|
case -ENOKEY:
|
||||||
|
aud3g.algo = OSMO_AUTH_ALG_NONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd->reply = "Error retrieving data from database.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aud3g.algo == OSMO_AUTH_ALG_NONE) {
|
||||||
|
cmd->reply = "none";
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "%s,%s,%s,%s,%u", osmo_auth_alg_name(aud3g.algo),
|
||||||
|
osmo_hexdump_nospc_c(cmd, aud3g.u.umts.k, sizeof(aud3g.u.umts.k)),
|
||||||
|
aud3g.u.umts.opc_is_op ? "OP" : "OPC",
|
||||||
|
osmo_hexdump_nospc_c(cmd, aud3g.u.umts.opc, sizeof(aud3g.u.umts.opc)),
|
||||||
|
aud3g.u.umts.ind_bitlen);
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
static int set_subscr_aud3g(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hlr_subscriber subscr;
|
||||||
|
struct hlr *hlr = data;
|
||||||
|
const char *by_selector = cmd->node;
|
||||||
|
char *tmp = NULL, *tok, *saveptr;
|
||||||
|
int minlen = 0;
|
||||||
|
int maxlen = 0;
|
||||||
|
struct sub_auth_data_str aud3g = {
|
||||||
|
.type = OSMO_AUTH_TYPE_UMTS,
|
||||||
|
.u.umts = {
|
||||||
|
.ind_bitlen = 5,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
bool ind_bitlen_present;
|
||||||
|
|
||||||
|
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
|
||||||
|
tmp = talloc_strdup(cmd, cmd->value);
|
||||||
|
if (!tmp) {
|
||||||
|
cmd->reply = "OOM";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse alg_type: */
|
||||||
|
tok = strtok_r(tmp, ",", &saveptr);
|
||||||
|
if (!tok) {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
if (strcmp(tok, "none") == 0) {
|
||||||
|
aud3g.algo = OSMO_AUTH_ALG_NONE;
|
||||||
|
} else if (!auth_algo_parse(tok, &aud3g.algo, &minlen, &maxlen)) {
|
||||||
|
cmd->reply = "Unknown auth algorithm.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aud3g.algo != OSMO_AUTH_ALG_NONE) {
|
||||||
|
/* Parse K */
|
||||||
|
tok = strtok_r(NULL, ",", &saveptr);
|
||||||
|
if (!tok) {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
aud3g.u.umts.k = tok;
|
||||||
|
if (!osmo_is_hexstr(aud3g.u.umts.k, minlen * 2, maxlen * 2, true)) {
|
||||||
|
cmd->reply = "Invalid KI.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse OP/OPC choice */
|
||||||
|
tok = strtok_r(NULL, ",", &saveptr);
|
||||||
|
if (!tok) {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
if (strcasecmp(tok, "op") == 0) {
|
||||||
|
aud3g.u.umts.opc_is_op = true;
|
||||||
|
} else if (strcasecmp(tok, "opc") == 0) {
|
||||||
|
aud3g.u.umts.opc_is_op = false;
|
||||||
|
} else {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse OP/OPC value */
|
||||||
|
ind_bitlen_present = !!strchr(saveptr, ',');
|
||||||
|
tok = strtok_r(NULL, ind_bitlen_present ? "," : "\0", &saveptr);
|
||||||
|
if (!tok) {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
aud3g.u.umts.opc = tok;
|
||||||
|
if (!osmo_is_hexstr(aud3g.u.umts.opc, MILENAGE_KEY_LEN * 2, MILENAGE_KEY_LEN * 2, true)) {
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "Invalid OP/OPC.");
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ind_bitlen_present) {
|
||||||
|
/* Parse bitlen_ind */
|
||||||
|
tok = strtok_r(NULL, "\0", &saveptr);
|
||||||
|
if (!tok || tok[0] == '\0') {
|
||||||
|
cmd->reply = "Invalid format.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
aud3g.u.umts.ind_bitlen = atoi(tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud3g)) {
|
||||||
|
cmd->reply = "Update aud3g failed.";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->reply = "OK";
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
||||||
@@ -389,6 +749,25 @@ static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hlr_ctrl_cmds_install()
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR, &cmd_subscr_create);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR, &cmd_subscr_delete);
|
||||||
|
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_aud);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_all);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_ps_enabled);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_cs_enabled);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_msisdn);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_aud2g);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_aud3g);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr)
|
struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|||||||
32
src/db.c
32
src/db.c
@@ -28,7 +28,7 @@
|
|||||||
#include "db_bootstrap.h"
|
#include "db_bootstrap.h"
|
||||||
|
|
||||||
/* This constant is currently duplicated in sql/hlr.sql and must be kept in sync! */
|
/* This constant is currently duplicated in sql/hlr.sql and must be kept in sync! */
|
||||||
#define CURRENT_SCHEMA_VERSION 5
|
#define CURRENT_SCHEMA_VERSION 6
|
||||||
|
|
||||||
#define SEL_COLUMNS \
|
#define SEL_COLUMNS \
|
||||||
"id," \
|
"id," \
|
||||||
@@ -56,6 +56,7 @@ static const char *stmt_sql[] = {
|
|||||||
"WHERE last_lu_seen IS NOT NULL ORDER BY last_lu_seen;",
|
"WHERE last_lu_seen IS NOT NULL ORDER BY last_lu_seen;",
|
||||||
[DB_STMT_SEL_FILTER_MSISDN] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE msisdn LIKE $search ORDER BY msisdn",
|
[DB_STMT_SEL_FILTER_MSISDN] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE msisdn LIKE $search ORDER BY msisdn",
|
||||||
[DB_STMT_SEL_FILTER_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi LIKE $search ORDER BY imsi",
|
[DB_STMT_SEL_FILTER_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi LIKE $search ORDER BY imsi",
|
||||||
|
[DB_STMT_SEL_FILTER_IMEI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imei LIKE $search ORDER BY imei",
|
||||||
[DB_STMT_SEL_FILTER_CS] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE nam_cs = $search ORDER BY last_lu_seen",
|
[DB_STMT_SEL_FILTER_CS] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE nam_cs = $search ORDER BY last_lu_seen",
|
||||||
[DB_STMT_SEL_FILTER_PS] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE nam_ps = $search ORDER BY last_lu_seen",
|
[DB_STMT_SEL_FILTER_PS] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE nam_ps = $search ORDER BY last_lu_seen",
|
||||||
[DB_STMT_SEL_BY_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi = ?",
|
[DB_STMT_SEL_BY_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi = ?",
|
||||||
@@ -92,6 +93,9 @@ static const char *stmt_sql[] = {
|
|||||||
[DB_STMT_SET_LAST_LU_SEEN_PS] = "UPDATE subscriber SET last_lu_seen_ps = datetime($val, 'unixepoch') WHERE id = $subscriber_id",
|
[DB_STMT_SET_LAST_LU_SEEN_PS] = "UPDATE subscriber SET last_lu_seen_ps = datetime($val, 'unixepoch') WHERE id = $subscriber_id",
|
||||||
[DB_STMT_EXISTS_BY_IMSI] = "SELECT 1 FROM subscriber WHERE imsi = $imsi",
|
[DB_STMT_EXISTS_BY_IMSI] = "SELECT 1 FROM subscriber WHERE imsi = $imsi",
|
||||||
[DB_STMT_EXISTS_BY_MSISDN] = "SELECT 1 FROM subscriber WHERE msisdn = $msisdn",
|
[DB_STMT_EXISTS_BY_MSISDN] = "SELECT 1 FROM subscriber WHERE msisdn = $msisdn",
|
||||||
|
[DB_STMT_IND_ADD] = "INSERT INTO ind (vlr) VALUES ($vlr)",
|
||||||
|
[DB_STMT_IND_SELECT] = "SELECT ind FROM ind WHERE vlr = $vlr",
|
||||||
|
[DB_STMT_IND_DEL] = "DELETE FROM ind WHERE vlr = $vlr",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
|
static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
|
||||||
@@ -233,7 +237,7 @@ void db_close(struct db_context *dbc)
|
|||||||
|
|
||||||
static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count)
|
static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < statements_count; i++) {
|
for (i = 0; i < statements_count; i++) {
|
||||||
const char *stmt_str = statements[i];
|
const char *stmt_str = statements[i];
|
||||||
@@ -486,6 +490,29 @@ static int db_upgrade_v5(struct db_context *dbc)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int db_upgrade_v6(struct db_context *dbc)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
const char *statements[] = {
|
||||||
|
"CREATE TABLE ind (\n"
|
||||||
|
" -- 3G auth IND pool to be used for this VLR\n"
|
||||||
|
" ind INTEGER PRIMARY KEY,\n"
|
||||||
|
" -- VLR identification, usually the GSUP source_name\n"
|
||||||
|
" vlr TEXT NOT NULL,\n"
|
||||||
|
" UNIQUE (vlr)\n"
|
||||||
|
")"
|
||||||
|
,
|
||||||
|
"PRAGMA user_version = 6",
|
||||||
|
};
|
||||||
|
|
||||||
|
rc = db_run_statements(dbc, statements, ARRAY_SIZE(statements));
|
||||||
|
if (rc != SQLITE_DONE) {
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 6\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
typedef int (*db_upgrade_func_t)(struct db_context *dbc);
|
typedef int (*db_upgrade_func_t)(struct db_context *dbc);
|
||||||
static db_upgrade_func_t db_upgrade_path[] = {
|
static db_upgrade_func_t db_upgrade_path[] = {
|
||||||
db_upgrade_v1,
|
db_upgrade_v1,
|
||||||
@@ -493,6 +520,7 @@ static db_upgrade_func_t db_upgrade_path[] = {
|
|||||||
db_upgrade_v3,
|
db_upgrade_v3,
|
||||||
db_upgrade_v4,
|
db_upgrade_v4,
|
||||||
db_upgrade_v5,
|
db_upgrade_v5,
|
||||||
|
db_upgrade_v6,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int db_get_user_version(struct db_context *dbc)
|
static int db_get_user_version(struct db_context *dbc)
|
||||||
|
|||||||
110
src/db_hlr.c
110
src/db_hlr.c
@@ -45,7 +45,8 @@
|
|||||||
* \param[in,out] dbc database context.
|
* \param[in,out] dbc database context.
|
||||||
* \param[in] imsi ASCII string of IMSI digits, is validated.
|
* \param[in] imsi ASCII string of IMSI digits, is validated.
|
||||||
* \param[in] flags Bitmask of DB_SUBSCR_FLAG_*.
|
* \param[in] flags Bitmask of DB_SUBSCR_FLAG_*.
|
||||||
* \returns 0 on success, -EINVAL on invalid IMSI, -EIO on database error.
|
* \returns 0 on success, -EINVAL on invalid IMSI, -EEXIST if subscriber with
|
||||||
|
* provided imsi already exists, -EIO on other database errors.
|
||||||
*/
|
*/
|
||||||
int db_subscr_create(struct db_context *dbc, const char *imsi, uint8_t flags)
|
int db_subscr_create(struct db_context *dbc, const char *imsi, uint8_t flags)
|
||||||
{
|
{
|
||||||
@@ -73,6 +74,8 @@ int db_subscr_create(struct db_context *dbc, const char *imsi, uint8_t flags)
|
|||||||
if (rc != SQLITE_DONE) {
|
if (rc != SQLITE_DONE) {
|
||||||
LOGHLR(imsi, LOGL_ERROR, "Cannot create subscriber: SQL error: (%d) %s\n",
|
LOGHLR(imsi, LOGL_ERROR, "Cannot create subscriber: SQL error: (%d) %s\n",
|
||||||
rc, sqlite3_errmsg(dbc->db));
|
rc, sqlite3_errmsg(dbc->db));
|
||||||
|
if (rc == SQLITE_CONSTRAINT_UNIQUE)
|
||||||
|
return -EEXIST;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,6 +651,8 @@ int db_subscrs_get(struct db_context *dbc, const char *filter_type, const char *
|
|||||||
|
|
||||||
if (!filter_type) {
|
if (!filter_type) {
|
||||||
stmt = dbc->stmt[DB_STMT_SEL_ALL];
|
stmt = dbc->stmt[DB_STMT_SEL_ALL];
|
||||||
|
} else if (strcmp(filter_type, "imei") == 0) {
|
||||||
|
stmt = dbc->stmt[DB_STMT_SEL_FILTER_IMEI];
|
||||||
} else if (strcmp(filter_type, "imsi") == 0) {
|
} else if (strcmp(filter_type, "imsi") == 0) {
|
||||||
stmt = dbc->stmt[DB_STMT_SEL_FILTER_IMSI];
|
stmt = dbc->stmt[DB_STMT_SEL_FILTER_IMSI];
|
||||||
} else if (strcmp(filter_type, "msisdn") == 0) {
|
} else if (strcmp(filter_type, "msisdn") == 0) {
|
||||||
@@ -970,3 +975,106 @@ out:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _db_ind_run(struct db_context *dbc, sqlite3_stmt *stmt, const char *vlr, bool reset)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!db_bind_text(stmt, "$vlr", vlr))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
/* execute the statement */
|
||||||
|
rc = sqlite3_step(stmt);
|
||||||
|
if (reset)
|
||||||
|
db_remove_reset(stmt);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _db_ind_add(struct db_context *dbc, const char *vlr)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_ADD];
|
||||||
|
if (_db_ind_run(dbc, stmt, vlr, true) != SQLITE_DONE) {
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Cannot create IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr, -1));
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _db_ind_del(struct db_context *dbc, const char *vlr)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_DEL];
|
||||||
|
_db_ind_run(dbc, stmt, vlr, true);
|
||||||
|
/* We don't really care about the result. If it didn't exist, then that was the goal anyway. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _db_ind_get(struct db_context *dbc, const char *vlr, unsigned int *ind)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_SELECT];
|
||||||
|
int rc = _db_ind_run(dbc, stmt, vlr, false);
|
||||||
|
if (rc == SQLITE_DONE) {
|
||||||
|
/* Does not exist yet */
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
} else if (rc != SQLITE_ROW) {
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Error executing SQL: %d\n", rc);
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSMO_ASSERT(ind);
|
||||||
|
*ind = sqlite3_column_int64(stmt, 0);
|
||||||
|
out:
|
||||||
|
db_remove_reset(stmt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr,
|
||||||
|
unsigned int *ind, bool del)
|
||||||
|
{
|
||||||
|
const char *vlr_name = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
switch (vlr->type) {
|
||||||
|
case OSMO_CNI_PEER_ID_IPA_NAME:
|
||||||
|
if (vlr->ipa_name.len < 2 || vlr->ipa_name.val[vlr->ipa_name.len - 1] != '\0') {
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Expecting VLR ipa_name to be zero terminated; found %s\n",
|
||||||
|
osmo_ipa_name_to_str(&vlr->ipa_name));
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
vlr_name = (const char*)vlr->ipa_name.val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Unsupported osmo_cni_peer_id type: %s\n",
|
||||||
|
osmo_cni_peer_id_type_name(vlr->type));
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (del)
|
||||||
|
return _db_ind_del(dbc, vlr_name);
|
||||||
|
|
||||||
|
rc = _db_ind_get(dbc, vlr_name, ind);
|
||||||
|
if (!rc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Does not exist yet, create. */
|
||||||
|
rc = _db_ind_add(dbc, vlr_name);
|
||||||
|
if (rc) {
|
||||||
|
LOGP(DDB, LOGL_ERROR, "Error creating IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr_name, -1));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To be sure, query again from scratch. */
|
||||||
|
return _db_ind_get(dbc, vlr_name, ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr, unsigned int *ind)
|
||||||
|
{
|
||||||
|
return _db_ind(dbc, vlr, ind, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_ind_del(struct db_context *dbc, const struct osmo_cni_peer_id *vlr)
|
||||||
|
{
|
||||||
|
return _db_ind(dbc, vlr, NULL, true);
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,10 +18,6 @@
|
|||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* $Id: dbd_helper.c,v 1.44 2011/08/09 11:14:14 mhoenicka Exp $
|
* $Id: dbd_helper.c,v 1.44 2011/08/09 11:14:14 mhoenicka Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ int config_write_mslookup(struct vty *vty)
|
|||||||
|
|
||||||
msc = mslookup_server_msc_get(&mslookup_server_msc_wildcard, false);
|
msc = mslookup_server_msc_get(&mslookup_server_msc_wildcard, false);
|
||||||
if (msc)
|
if (msc)
|
||||||
config_write_msc_services(vty, " ", msc);
|
config_write_msc_services(vty, " ", msc);
|
||||||
|
|
||||||
llist_for_each_entry(msc, &g_hlr->mslookup.server.local_site_services, entry) {
|
llist_for_each_entry(msc, &g_hlr->mslookup.server.local_site_services, entry) {
|
||||||
if (!osmo_ipa_name_cmp(&mslookup_server_msc_wildcard, &msc->name))
|
if (!osmo_ipa_name_cmp(&mslookup_server_msc_wildcard, &msc->name))
|
||||||
|
|||||||
@@ -317,43 +317,6 @@ static int osmo_gsup_server_closed_cb(struct ipa_server_conn *conn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add conn to the clients list in a way that conn->auc_3g_ind takes the lowest
|
|
||||||
* unused integer and the list of clients remains sorted by auc_3g_ind.
|
|
||||||
* Keep this function non-static to allow linking in a unit test. */
|
|
||||||
void osmo_gsup_server_add_conn(struct llist_head *clients,
|
|
||||||
struct osmo_gsup_conn *conn)
|
|
||||||
{
|
|
||||||
struct osmo_gsup_conn *c;
|
|
||||||
struct osmo_gsup_conn *prev_conn;
|
|
||||||
|
|
||||||
c = llist_first_entry_or_null(clients, struct osmo_gsup_conn, list);
|
|
||||||
|
|
||||||
/* Is the first index, 0, unused? */
|
|
||||||
if (!c || c->auc_3g_ind > 0) {
|
|
||||||
conn->auc_3g_ind = 0;
|
|
||||||
llist_add(&conn->list, clients);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for a gap later on */
|
|
||||||
prev_conn = NULL;
|
|
||||||
llist_for_each_entry(c, clients, list) {
|
|
||||||
/* skip first item, we know it has auc_3g_ind == 0. */
|
|
||||||
if (!prev_conn) {
|
|
||||||
prev_conn = c;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c->auc_3g_ind > prev_conn->auc_3g_ind + 1)
|
|
||||||
break;
|
|
||||||
prev_conn = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSMO_ASSERT(prev_conn);
|
|
||||||
|
|
||||||
conn->auc_3g_ind = prev_conn->auc_3g_ind + 1;
|
|
||||||
llist_add(&conn->list, &prev_conn->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_fd_settings(int fd)
|
static void update_fd_settings(int fd)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -386,10 +349,9 @@ static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd)
|
|||||||
|
|
||||||
/* link data structure with server structure */
|
/* link data structure with server structure */
|
||||||
conn->server = gsups;
|
conn->server = gsups;
|
||||||
osmo_gsup_server_add_conn(&gsups->clients, conn);
|
llist_add_tail(&conn->list, &gsups->clients);
|
||||||
|
|
||||||
LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d (IND=%u)\n",
|
LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d\n", conn->conn->addr, conn->conn->port);
|
||||||
conn->conn->addr, conn->conn->port, conn->auc_3g_ind);
|
|
||||||
|
|
||||||
update_fd_settings(fd);
|
update_fd_settings(fd);
|
||||||
|
|
||||||
|
|||||||
13
src/hlr.c
13
src/hlr.c
@@ -281,13 +281,14 @@ int hlr_subscr_nam(struct hlr *hlr, struct hlr_subscriber *subscr, bool nam_val,
|
|||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
/* process an incoming SAI request */
|
/* process an incoming SAI request */
|
||||||
static int rx_send_auth_info(unsigned int auc_3g_ind, struct osmo_gsup_req *req)
|
static int rx_send_auth_info(struct osmo_gsup_req *req)
|
||||||
{
|
{
|
||||||
struct osmo_gsup_message gsup_out = {
|
struct osmo_gsup_message gsup_out = {
|
||||||
.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT,
|
.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT,
|
||||||
};
|
};
|
||||||
bool separation_bit = false;
|
bool separation_bit = false;
|
||||||
int num_auth_vectors = OSMO_GSUP_MAX_NUM_AUTH_INFO;
|
int num_auth_vectors = OSMO_GSUP_MAX_NUM_AUTH_INFO;
|
||||||
|
unsigned int auc_3g_ind;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
subscr_create_on_demand(req->gsup.imsi);
|
subscr_create_on_demand(req->gsup.imsi);
|
||||||
@@ -298,6 +299,14 @@ static int rx_send_auth_info(unsigned int auc_3g_ind, struct osmo_gsup_req *req)
|
|||||||
if (req->gsup.num_auth_vectors > 0 &&
|
if (req->gsup.num_auth_vectors > 0 &&
|
||||||
req->gsup.num_auth_vectors <= OSMO_GSUP_MAX_NUM_AUTH_INFO)
|
req->gsup.num_auth_vectors <= OSMO_GSUP_MAX_NUM_AUTH_INFO)
|
||||||
num_auth_vectors = req->gsup.num_auth_vectors;
|
num_auth_vectors = req->gsup.num_auth_vectors;
|
||||||
|
rc = db_ind(g_hlr->dbc, &req->source_name, &auc_3g_ind);
|
||||||
|
if (rc) {
|
||||||
|
LOG_GSUP_REQ(req, LOGL_ERROR,
|
||||||
|
"Unable to determine 3G auth IND for source %s (rc=%d),"
|
||||||
|
" generating tuples with IND = 0\n",
|
||||||
|
osmo_cni_peer_id_to_str(&req->source_name), rc);
|
||||||
|
auc_3g_ind = 0;
|
||||||
|
}
|
||||||
|
|
||||||
rc = db_get_auc(g_hlr->dbc, req->gsup.imsi, auc_3g_ind,
|
rc = db_get_auc(g_hlr->dbc, req->gsup.imsi, auc_3g_ind,
|
||||||
gsup_out.auth_vectors,
|
gsup_out.auth_vectors,
|
||||||
@@ -517,7 +526,7 @@ static int read_cb(struct osmo_gsup_conn *conn, struct msgb *msg)
|
|||||||
switch (req->gsup.message_type) {
|
switch (req->gsup.message_type) {
|
||||||
/* requests sent to us */
|
/* requests sent to us */
|
||||||
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
|
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
|
||||||
rx_send_auth_info(conn->auc_3g_ind, req);
|
rx_send_auth_info(req);
|
||||||
break;
|
break;
|
||||||
case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
|
case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
|
||||||
rx_upd_loc_req(conn, req);
|
rx_upd_loc_req(conn, req);
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ static int config_write_hlr_gsup(struct vty *vty)
|
|||||||
vty_out(vty, " gsup%s", VTY_NEWLINE);
|
vty_out(vty, " gsup%s", VTY_NEWLINE);
|
||||||
if (g_hlr->gsup_bind_addr)
|
if (g_hlr->gsup_bind_addr)
|
||||||
vty_out(vty, " bind ip %s%s", g_hlr->gsup_bind_addr, VTY_NEWLINE);
|
vty_out(vty, " bind ip %s%s", g_hlr->gsup_bind_addr, VTY_NEWLINE);
|
||||||
|
if (g_hlr->gsup_unit_name.serno)
|
||||||
|
vty_out(vty, " ipa-name %s%s", g_hlr->gsup_unit_name.serno, VTY_NEWLINE);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,8 +116,8 @@ static void show_one_conn(struct vty *vty, const struct osmo_gsup_conn *conn)
|
|||||||
rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &name, IPAC_IDTAG_SERNR);
|
rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &name, IPAC_IDTAG_SERNR);
|
||||||
OSMO_ASSERT(rc);
|
OSMO_ASSERT(rc);
|
||||||
|
|
||||||
vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u, 3G_IND=%u%s",
|
vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u%s",
|
||||||
name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps, conn->auc_3g_ind,
|
name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps,
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <osmocom/hlr/hlr.h>
|
#include <osmocom/hlr/hlr.h>
|
||||||
#include <osmocom/hlr/db.h>
|
#include <osmocom/hlr/db.h>
|
||||||
#include <osmocom/hlr/timestamp.h>
|
#include <osmocom/hlr/timestamp.h>
|
||||||
|
#include <osmocom/hlr/hlr_vty.h>
|
||||||
|
|
||||||
struct vty;
|
struct vty;
|
||||||
|
|
||||||
@@ -256,7 +257,7 @@ static int get_subscrs(struct vty *vty, const char *filter_type, const char *fil
|
|||||||
#define SUBSCRS_SHOW_HELP "Show all subscribers (with filter possibility)\n"
|
#define SUBSCRS_SHOW_HELP "Show all subscribers (with filter possibility)\n"
|
||||||
|
|
||||||
#define SUBSCR_ID "(imsi|msisdn|id|imei) IDENT"
|
#define SUBSCR_ID "(imsi|msisdn|id|imei) IDENT"
|
||||||
#define SUBSCR_FILTER "(imsi|msisdn) FILTER"
|
#define SUBSCR_FILTER "(imei|imsi|msisdn) FILTER"
|
||||||
|
|
||||||
#define SUBSCR_ID_HELP \
|
#define SUBSCR_ID_HELP \
|
||||||
"Identify subscriber by IMSI\n" \
|
"Identify subscriber by IMSI\n" \
|
||||||
@@ -307,7 +308,8 @@ DEFUN(show_subscriber_filtered,
|
|||||||
show_subscriber_filtered_cmd,
|
show_subscriber_filtered_cmd,
|
||||||
"show subscribers " SUBSCR_FILTER,
|
"show subscribers " SUBSCR_FILTER,
|
||||||
SHOW_STR SUBSCRS_SHOW_HELP
|
SHOW_STR SUBSCRS_SHOW_HELP
|
||||||
"Filter Subscribers by IMSI\n" "Filter Subscribers by MSISDN\n" "String to match in msisdn or imsi\n")
|
"Filter Subscribers by IMEI\n" "Filter Subscribers by IMSI\n" "Filter Subscribers by MSISDN\n"
|
||||||
|
"String to match in imei, imsi or msisdn\n")
|
||||||
{
|
{
|
||||||
const char *filter_type = argv[0];
|
const char *filter_type = argv[0];
|
||||||
const char *filter = argv[1];
|
const char *filter = argv[1];
|
||||||
@@ -345,7 +347,7 @@ DEFUN(subscriber_create,
|
|||||||
int rc;
|
int rc;
|
||||||
struct hlr_subscriber subscr;
|
struct hlr_subscriber subscr;
|
||||||
const char *imsi = argv[0];
|
const char *imsi = argv[0];
|
||||||
|
|
||||||
if (!osmo_imsi_str_valid(imsi)) {
|
if (!osmo_imsi_str_valid(imsi)) {
|
||||||
vty_out(vty, "%% Not a valid IMSI: %s%s", imsi, VTY_NEWLINE);
|
vty_out(vty, "%% Not a valid IMSI: %s%s", imsi, VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
@@ -469,14 +471,8 @@ static bool is_hexkey_valid(struct vty *vty, const char *label,
|
|||||||
#define AUTH_ALG_TYPES_3G_HELP \
|
#define AUTH_ALG_TYPES_3G_HELP \
|
||||||
"Use Milenage algorithm\n"
|
"Use Milenage algorithm\n"
|
||||||
|
|
||||||
#define A38_XOR_MIN_KEY_LEN 12
|
bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
||||||
#define A38_XOR_MAX_KEY_LEN 16
|
int *minlen, int *maxlen)
|
||||||
#define A38_COMP128_KEY_LEN 16
|
|
||||||
|
|
||||||
#define MILENAGE_KEY_LEN 16
|
|
||||||
|
|
||||||
static bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
|
||||||
int *minlen, int *maxlen)
|
|
||||||
{
|
{
|
||||||
if (!strcasecmp(alg_str, "none")) {
|
if (!strcasecmp(alg_str, "none")) {
|
||||||
*algo = OSMO_AUTH_ALG_NONE;
|
*algo = OSMO_AUTH_ALG_NONE;
|
||||||
@@ -635,7 +631,7 @@ DEFUN(subscriber_aud3g,
|
|||||||
.ind_bitlen = ind_bitlen,
|
.ind_bitlen = ind_bitlen,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!auth_algo_parse(alg_type, &aud3g.algo, &minlen, &maxlen)) {
|
if (!auth_algo_parse(alg_type, &aud3g.algo, &minlen, &maxlen)) {
|
||||||
vty_out(vty, "%% Unknown auth algorithm: '%s'%s", alg_type, VTY_NEWLINE);
|
vty_out(vty, "%% Unknown auth algorithm: '%s'%s", alg_type, VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ const struct log_info_cat hlr_log_info_cat[] = {
|
|||||||
.color = "\033[1;35m",
|
.color = "\033[1;35m",
|
||||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
},
|
},
|
||||||
|
[DCTRL] = {
|
||||||
|
.name = "DCTRL",
|
||||||
|
.description = "Osmocom CTRL interface",
|
||||||
|
.color = "\033[1;30m",
|
||||||
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct log_info hlr_log_info = {
|
const struct log_info hlr_log_info = {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
auc \
|
auc \
|
||||||
gsup_server \
|
|
||||||
db \
|
db \
|
||||||
gsup \
|
gsup \
|
||||||
db_upgrade \
|
db_upgrade \
|
||||||
@@ -70,6 +69,9 @@ vty-test:
|
|||||||
|
|
||||||
CTRL_TEST_DB = hlr_ctrl_test.db
|
CTRL_TEST_DB = hlr_ctrl_test.db
|
||||||
|
|
||||||
|
# Run a specific test with: 'make ctrl-test CTRL_TEST=test_subscriber.ctrl'
|
||||||
|
CTRL_TEST ?= *.ctrl
|
||||||
|
|
||||||
# To update the CTRL script from current application behavior,
|
# To update the CTRL script from current application behavior,
|
||||||
# pass -u to ctrl_script_runner.py by doing:
|
# pass -u to ctrl_script_runner.py by doing:
|
||||||
# make ctrl-test U=-u
|
# make ctrl-test U=-u
|
||||||
@@ -80,7 +82,7 @@ ctrl-test:
|
|||||||
osmo_verify_transcript_ctrl.py -v \
|
osmo_verify_transcript_ctrl.py -v \
|
||||||
-p 4259 \
|
-p 4259 \
|
||||||
-r "$(top_builddir)/src/osmo-hlr -c $(top_srcdir)/doc/examples/osmo-hlr.cfg -l $(CTRL_TEST_DB)" \
|
-r "$(top_builddir)/src/osmo-hlr -c $(top_srcdir)/doc/examples/osmo-hlr.cfg -l $(CTRL_TEST_DB)" \
|
||||||
$(U) $(srcdir)/*.ctrl
|
$(U) $(srcdir)/$(CTRL_TEST)
|
||||||
-rm -f $(CTRL_TEST_DB)
|
-rm -f $(CTRL_TEST_DB)
|
||||||
-rm $(CTRL_TEST_DB)-*
|
-rm $(CTRL_TEST_DB)-*
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ EXTRA_DIST = \
|
|||||||
auc_ts_55_205_test_sets.err \
|
auc_ts_55_205_test_sets.err \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
check_PROGRAMS = auc_ts_55_205_test_sets
|
check_PROGRAMS = auc_test auc_ts_55_205_test_sets
|
||||||
|
|
||||||
noinst_PROGRAMS = auc_test
|
|
||||||
|
|
||||||
auc_test_SOURCES = \
|
auc_test_SOURCES = \
|
||||||
auc_test.c \
|
auc_test.c \
|
||||||
|
|||||||
@@ -262,13 +262,13 @@ static void test_subscr_create_update_sel_delete()
|
|||||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
|
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
|
||||||
ASSERT_SEL(imsi, imsi2, 0);
|
ASSERT_SEL(imsi, imsi2, 0);
|
||||||
id2 = g_subscr.id;
|
id2 = g_subscr.id;
|
||||||
ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||||
ASSERT_SEL(imsi, imsi0, 0);
|
ASSERT_SEL(imsi, imsi0, 0);
|
||||||
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||||
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||||
ASSERT_SEL(imsi, imsi1, 0);
|
ASSERT_SEL(imsi, imsi1, 0);
|
||||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||||
ASSERT_SEL(imsi, imsi2, 0);
|
ASSERT_SEL(imsi, imsi2, 0);
|
||||||
|
|
||||||
ASSERT_RC(db_subscr_create(dbc, "123456789 000003", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EINVAL);
|
ASSERT_RC(db_subscr_create(dbc, "123456789 000003", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EINVAL);
|
||||||
@@ -918,6 +918,50 @@ static void test_subscr_sqn()
|
|||||||
comment_end();
|
comment_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_ind()
|
||||||
|
{
|
||||||
|
comment_start();
|
||||||
|
|
||||||
|
#define ASSERT_IND(VLR, IND) do { \
|
||||||
|
unsigned int ind; \
|
||||||
|
struct osmo_cni_peer_id vlr; \
|
||||||
|
OSMO_ASSERT(!osmo_cni_peer_id_set_str(&vlr, OSMO_CNI_PEER_ID_IPA_NAME, VLR)); \
|
||||||
|
ASSERT_RC(db_ind(dbc, &vlr, &ind), 0); \
|
||||||
|
fprintf(stderr, "%s ind = %u\n\n", osmo_quote_str((char*)vlr.ipa_name.val, vlr.ipa_name.len), ind); \
|
||||||
|
if (ind != (IND)) \
|
||||||
|
fprintf(stderr, " ERROR: expected " #IND "\n"); \
|
||||||
|
} while (0)
|
||||||
|
#define IND_DEL(VLR) do { \
|
||||||
|
struct osmo_cni_peer_id vlr; \
|
||||||
|
OSMO_ASSERT(!osmo_cni_peer_id_set_str(&vlr, OSMO_CNI_PEER_ID_IPA_NAME, VLR)); \
|
||||||
|
ASSERT_RC(db_ind_del(dbc, &vlr), 0); \
|
||||||
|
fprintf(stderr, "%s ind deleted\n\n", osmo_quote_str((char*)vlr.ipa_name.val, vlr.ipa_name.len)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
ASSERT_IND("msc-23", 1);
|
||||||
|
ASSERT_IND("sgsn-11", 2);
|
||||||
|
ASSERT_IND("msc-42", 3);
|
||||||
|
ASSERT_IND("sgsn-22", 4);
|
||||||
|
ASSERT_IND("msc-0x17", 5);
|
||||||
|
ASSERT_IND("sgsn-0xaa", 6);
|
||||||
|
ASSERT_IND("msc-42", 3);
|
||||||
|
ASSERT_IND("sgsn-22", 4);
|
||||||
|
ASSERT_IND("msc-0x17", 5);
|
||||||
|
ASSERT_IND("sgsn-0xaa", 6);
|
||||||
|
ASSERT_IND("sgsn-0xbb", 7);
|
||||||
|
ASSERT_IND("msc-0x2a", 8);
|
||||||
|
ASSERT_IND("msc-42", 3);
|
||||||
|
ASSERT_IND("sgsn-22", 4);
|
||||||
|
ASSERT_IND("msc-23", 1);
|
||||||
|
ASSERT_IND("sgsn-11", 2);
|
||||||
|
|
||||||
|
IND_DEL("msc-0x17"); /* dropped IND == 5 */
|
||||||
|
ASSERT_IND("msc-0x2a", 8); /* known CS remains where it is */
|
||||||
|
ASSERT_IND("any-unknown", 9); /* new VLR takes a new IND from the end */
|
||||||
|
|
||||||
|
comment_end();
|
||||||
|
}
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
} cmdline_opts = {
|
} cmdline_opts = {
|
||||||
@@ -1002,6 +1046,7 @@ int main(int argc, char **argv)
|
|||||||
test_subscr_aud();
|
test_subscr_aud();
|
||||||
test_subscr_aud_invalid_len();
|
test_subscr_aud_invalid_len();
|
||||||
test_subscr_sqn();
|
test_subscr_sqn();
|
||||||
|
test_ind();
|
||||||
|
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
db_close(dbc);
|
db_close(dbc);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ struct hlr_subscriber {
|
|||||||
.imsi = '123456789000002',
|
.imsi = '123456789000002',
|
||||||
}
|
}
|
||||||
|
|
||||||
db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||||
DAUC IMSI='123456789000000': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
DAUC IMSI='123456789000000': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||||
|
|
||||||
db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0
|
db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0
|
||||||
@@ -36,10 +36,10 @@ struct hlr_subscriber {
|
|||||||
.imsi = '123456789000000',
|
.imsi = '123456789000000',
|
||||||
}
|
}
|
||||||
|
|
||||||
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||||
DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||||
|
|
||||||
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||||
DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||||
|
|
||||||
db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0
|
db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0
|
||||||
@@ -48,10 +48,10 @@ struct hlr_subscriber {
|
|||||||
.imsi = '123456789000001',
|
.imsi = '123456789000001',
|
||||||
}
|
}
|
||||||
|
|
||||||
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||||
DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||||
|
|
||||||
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||||
DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||||
|
|
||||||
db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0
|
db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0
|
||||||
@@ -1613,3 +1613,83 @@ db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT
|
|||||||
|
|
||||||
===== test_subscr_sqn: SUCCESS
|
===== test_subscr_sqn: SUCCESS
|
||||||
|
|
||||||
|
|
||||||
|
===== test_ind
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-23\0" ind = 1
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-11\0" ind = 2
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-42\0" ind = 3
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-22\0" ind = 4
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-0x17\0" ind = 5
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-0xaa\0" ind = 6
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-42\0" ind = 3
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-22\0" ind = 4
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-0x17\0" ind = 5
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-0xaa\0" ind = 6
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-0xbb\0" ind = 7
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-0x2a\0" ind = 8
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-42\0" ind = 3
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-22\0" ind = 4
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-23\0" ind = 1
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"sgsn-11\0" ind = 2
|
||||||
|
|
||||||
|
db_ind_del(dbc, &vlr) --> 0
|
||||||
|
|
||||||
|
"msc-0x17\0" ind deleted
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"msc-0x2a\0" ind = 8
|
||||||
|
|
||||||
|
db_ind(dbc, &vlr, &ind) --> 0
|
||||||
|
|
||||||
|
"any-unknown\0" ind = 9
|
||||||
|
|
||||||
|
===== test_ind: SUCCESS
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 2
|
|||||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 3
|
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 3
|
||||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 4
|
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 4
|
||||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 5
|
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 5
|
||||||
|
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 6
|
||||||
DMAIN Cmdline option --db-check: Database was opened successfully, quitting.
|
DMAIN Cmdline option --db-check: Database was opened successfully, quitting.
|
||||||
|
|
||||||
Resulting db:
|
Resulting db:
|
||||||
@@ -117,6 +118,13 @@ algo_id_3g|ind_bitlen|k|op|opc|sqn|subscriber_id
|
|||||||
5|5|44444444444444444444444444444444|44444444444444444444444444444444||0|5
|
5|5|44444444444444444444444444444444|44444444444444444444444444444444||0|5
|
||||||
5|5|55555555555555555555555555555555||55555555555555555555555555555555|0|6
|
5|5|55555555555555555555555555555555||55555555555555555555555555555555|0|6
|
||||||
|
|
||||||
|
Table: ind
|
||||||
|
name|type|notnull|dflt_value|pk
|
||||||
|
ind|INTEGER|0||1
|
||||||
|
vlr|TEXT|1||0
|
||||||
|
|
||||||
|
Table ind contents:
|
||||||
|
|
||||||
Table: subscriber
|
Table: subscriber
|
||||||
name|type|notnull|dflt_value|pk
|
name|type|notnull|dflt_value|pk
|
||||||
ggsn_number|VARCHAR(15)|0||0
|
ggsn_number|VARCHAR(15)|0||0
|
||||||
@@ -171,5 +179,5 @@ osmo-hlr --database $db --db-check --config-file $srcdir/osmo-hlr.cfg
|
|||||||
rc = 0
|
rc = 0
|
||||||
DMAIN hlr starting
|
DMAIN hlr starting
|
||||||
DDB using database: <PATH>test.db
|
DDB using database: <PATH>test.db
|
||||||
DDB Database <PATH>test.db' has HLR DB schema version 5
|
DDB Database <PATH>test.db' has HLR DB schema version 6
|
||||||
DMAIN Cmdline option --db-check: Database was opened successfully, quitting.
|
DMAIN Cmdline option --db-check: Database was opened successfully, quitting.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ EXTRA_DIST = \
|
|||||||
gsup_test.err \
|
gsup_test.err \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
noinst_PROGRAMS = \
|
check_PROGRAMS = \
|
||||||
gsup_test \
|
gsup_test \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
AM_CPPFLAGS = \
|
|
||||||
$(all_includes) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
AM_CFLAGS = \
|
|
||||||
-Wall \
|
|
||||||
-ggdb3 \
|
|
||||||
-I$(top_srcdir)/include \
|
|
||||||
$(LIBOSMOCORE_CFLAGS) \
|
|
||||||
$(LIBOSMOGSM_CFLAGS) \
|
|
||||||
$(LIBOSMOABIS_CFLAGS) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
AM_LDFLAGS = \
|
|
||||||
-no-install \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
gsup_server_test.ok \
|
|
||||||
gsup_server_test.err \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
noinst_PROGRAMS = \
|
|
||||||
gsup_server_test \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
gsup_server_test_SOURCES = \
|
|
||||||
gsup_server_test.c \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
gsup_server_test_LDADD = \
|
|
||||||
$(top_srcdir)/src/gsup_server.c \
|
|
||||||
$(top_srcdir)/src/gsup_router.c \
|
|
||||||
$(top_srcdir)/src/gsup_send.c \
|
|
||||||
$(top_srcdir)/src/gsupclient/cni_peer_id.c \
|
|
||||||
$(top_srcdir)/src/gsupclient/gsup_req.c \
|
|
||||||
$(LIBOSMOCORE_LIBS) \
|
|
||||||
$(LIBOSMOGSM_LIBS) \
|
|
||||||
$(LIBOSMOABIS_LIBS) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
.PHONY: update_exp
|
|
||||||
update_exp:
|
|
||||||
$(builddir)/gsup_server_test >"$(srcdir)/gsup_server_test.ok" 2>"$(srcdir)/gsup_server_test.err"
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
|
||||||
*
|
|
||||||
* 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 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 <stdio.h>
|
|
||||||
#include <osmocom/core/utils.h>
|
|
||||||
#include <osmocom/hlr/gsup_server.h>
|
|
||||||
|
|
||||||
#define comment_start() printf("\n===== %s\n", __func__)
|
|
||||||
#define comment_end() printf("===== %s: SUCCESS\n\n", __func__)
|
|
||||||
#define btw(fmt, args...) printf("\n" fmt "\n", ## args)
|
|
||||||
|
|
||||||
#define VERBOSE_ASSERT(val, expect_op, fmt) \
|
|
||||||
do { \
|
|
||||||
printf(#val " == " fmt "\n", (val)); \
|
|
||||||
OSMO_ASSERT((val) expect_op); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
void osmo_gsup_server_add_conn(struct llist_head *clients,
|
|
||||||
struct osmo_gsup_conn *conn);
|
|
||||||
|
|
||||||
static void test_add_conn(void)
|
|
||||||
{
|
|
||||||
struct llist_head _list;
|
|
||||||
struct llist_head *clients = &_list;
|
|
||||||
struct osmo_gsup_conn conn_inst[23] = {};
|
|
||||||
struct osmo_gsup_conn *conn;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
comment_start();
|
|
||||||
|
|
||||||
INIT_LLIST_HEAD(clients);
|
|
||||||
|
|
||||||
btw("Add 10 items");
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[i]);
|
|
||||||
printf("conn_inst[%u].auc_3g_ind == %u\n", i, conn_inst[i].auc_3g_ind);
|
|
||||||
OSMO_ASSERT(clients->next == &conn_inst[0].list);
|
|
||||||
}
|
|
||||||
|
|
||||||
btw("Expecting a list of 0..9");
|
|
||||||
i = 0;
|
|
||||||
llist_for_each_entry(conn, clients, list) {
|
|
||||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
|
||||||
OSMO_ASSERT(conn->auc_3g_ind == i);
|
|
||||||
OSMO_ASSERT(conn == &conn_inst[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
btw("Punch two holes in the sequence in arbitrary order,"
|
|
||||||
" a larger one from 2..4 and a single one at 7.");
|
|
||||||
llist_del(&conn_inst[4].list);
|
|
||||||
llist_del(&conn_inst[2].list);
|
|
||||||
llist_del(&conn_inst[3].list);
|
|
||||||
llist_del(&conn_inst[7].list);
|
|
||||||
|
|
||||||
btw("Expecting a list of 0,1, 5,6, 8,9");
|
|
||||||
i = 0;
|
|
||||||
llist_for_each_entry(conn, clients, list) {
|
|
||||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
btw("Add conns, expecting them to take the open slots");
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[12]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[12].auc_3g_ind, == 2, "%u");
|
|
||||||
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[13]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[13].auc_3g_ind, == 3, "%u");
|
|
||||||
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[14]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[14].auc_3g_ind, == 4, "%u");
|
|
||||||
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[17]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[17].auc_3g_ind, == 7, "%u");
|
|
||||||
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[18]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[18].auc_3g_ind, == 10, "%u");
|
|
||||||
|
|
||||||
btw("Expecting a list of 0..10");
|
|
||||||
i = 0;
|
|
||||||
llist_for_each_entry(conn, clients, list) {
|
|
||||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
|
||||||
OSMO_ASSERT(conn->auc_3g_ind == i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
btw("Does it also work for the first item?");
|
|
||||||
llist_del(&conn_inst[0].list);
|
|
||||||
|
|
||||||
btw("Expecting a list of 1..10");
|
|
||||||
i = 0;
|
|
||||||
llist_for_each_entry(conn, clients, list) {
|
|
||||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
|
||||||
OSMO_ASSERT(conn->auc_3g_ind == i + 1);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
btw("Add another conn, should take auc_3g_ind == 0");
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[20]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[20].auc_3g_ind, == 0, "%u");
|
|
||||||
|
|
||||||
btw("Expecting a list of 0..10");
|
|
||||||
i = 0;
|
|
||||||
llist_for_each_entry(conn, clients, list) {
|
|
||||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
|
||||||
OSMO_ASSERT(conn->auc_3g_ind == i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
btw("If a client reconnects, it will (likely) get the same auc_3g_ind");
|
|
||||||
VERBOSE_ASSERT(conn_inst[5].auc_3g_ind, == 5, "%u");
|
|
||||||
llist_del(&conn_inst[5].list);
|
|
||||||
conn_inst[5].auc_3g_ind = 423;
|
|
||||||
osmo_gsup_server_add_conn(clients, &conn_inst[5]);
|
|
||||||
VERBOSE_ASSERT(conn_inst[5].auc_3g_ind, == 5, "%u");
|
|
||||||
|
|
||||||
comment_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
printf("test_gsup_server.c\n");
|
|
||||||
|
|
||||||
test_add_conn();
|
|
||||||
|
|
||||||
printf("Done\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
test_gsup_server.c
|
|
||||||
|
|
||||||
===== test_add_conn
|
|
||||||
|
|
||||||
Add 10 items
|
|
||||||
conn_inst[0].auc_3g_ind == 0
|
|
||||||
conn_inst[1].auc_3g_ind == 1
|
|
||||||
conn_inst[2].auc_3g_ind == 2
|
|
||||||
conn_inst[3].auc_3g_ind == 3
|
|
||||||
conn_inst[4].auc_3g_ind == 4
|
|
||||||
conn_inst[5].auc_3g_ind == 5
|
|
||||||
conn_inst[6].auc_3g_ind == 6
|
|
||||||
conn_inst[7].auc_3g_ind == 7
|
|
||||||
conn_inst[8].auc_3g_ind == 8
|
|
||||||
conn_inst[9].auc_3g_ind == 9
|
|
||||||
|
|
||||||
Expecting a list of 0..9
|
|
||||||
conn[0].auc_3g_ind == 0
|
|
||||||
conn[1].auc_3g_ind == 1
|
|
||||||
conn[2].auc_3g_ind == 2
|
|
||||||
conn[3].auc_3g_ind == 3
|
|
||||||
conn[4].auc_3g_ind == 4
|
|
||||||
conn[5].auc_3g_ind == 5
|
|
||||||
conn[6].auc_3g_ind == 6
|
|
||||||
conn[7].auc_3g_ind == 7
|
|
||||||
conn[8].auc_3g_ind == 8
|
|
||||||
conn[9].auc_3g_ind == 9
|
|
||||||
|
|
||||||
Punch two holes in the sequence in arbitrary order, a larger one from 2..4 and a single one at 7.
|
|
||||||
|
|
||||||
Expecting a list of 0,1, 5,6, 8,9
|
|
||||||
conn[0].auc_3g_ind == 0
|
|
||||||
conn[1].auc_3g_ind == 1
|
|
||||||
conn[2].auc_3g_ind == 5
|
|
||||||
conn[3].auc_3g_ind == 6
|
|
||||||
conn[4].auc_3g_ind == 8
|
|
||||||
conn[5].auc_3g_ind == 9
|
|
||||||
|
|
||||||
Add conns, expecting them to take the open slots
|
|
||||||
conn_inst[12].auc_3g_ind == 2
|
|
||||||
conn_inst[13].auc_3g_ind == 3
|
|
||||||
conn_inst[14].auc_3g_ind == 4
|
|
||||||
conn_inst[17].auc_3g_ind == 7
|
|
||||||
conn_inst[18].auc_3g_ind == 10
|
|
||||||
|
|
||||||
Expecting a list of 0..10
|
|
||||||
conn[0].auc_3g_ind == 0
|
|
||||||
conn[1].auc_3g_ind == 1
|
|
||||||
conn[2].auc_3g_ind == 2
|
|
||||||
conn[3].auc_3g_ind == 3
|
|
||||||
conn[4].auc_3g_ind == 4
|
|
||||||
conn[5].auc_3g_ind == 5
|
|
||||||
conn[6].auc_3g_ind == 6
|
|
||||||
conn[7].auc_3g_ind == 7
|
|
||||||
conn[8].auc_3g_ind == 8
|
|
||||||
conn[9].auc_3g_ind == 9
|
|
||||||
conn[10].auc_3g_ind == 10
|
|
||||||
|
|
||||||
Does it also work for the first item?
|
|
||||||
|
|
||||||
Expecting a list of 1..10
|
|
||||||
conn[0].auc_3g_ind == 1
|
|
||||||
conn[1].auc_3g_ind == 2
|
|
||||||
conn[2].auc_3g_ind == 3
|
|
||||||
conn[3].auc_3g_ind == 4
|
|
||||||
conn[4].auc_3g_ind == 5
|
|
||||||
conn[5].auc_3g_ind == 6
|
|
||||||
conn[6].auc_3g_ind == 7
|
|
||||||
conn[7].auc_3g_ind == 8
|
|
||||||
conn[8].auc_3g_ind == 9
|
|
||||||
conn[9].auc_3g_ind == 10
|
|
||||||
|
|
||||||
Add another conn, should take auc_3g_ind == 0
|
|
||||||
conn_inst[20].auc_3g_ind == 0
|
|
||||||
|
|
||||||
Expecting a list of 0..10
|
|
||||||
conn[0].auc_3g_ind == 0
|
|
||||||
conn[1].auc_3g_ind == 1
|
|
||||||
conn[2].auc_3g_ind == 2
|
|
||||||
conn[3].auc_3g_ind == 3
|
|
||||||
conn[4].auc_3g_ind == 4
|
|
||||||
conn[5].auc_3g_ind == 5
|
|
||||||
conn[6].auc_3g_ind == 6
|
|
||||||
conn[7].auc_3g_ind == 7
|
|
||||||
conn[8].auc_3g_ind == 8
|
|
||||||
conn[9].auc_3g_ind == 9
|
|
||||||
conn[10].auc_3g_ind == 10
|
|
||||||
|
|
||||||
If a client reconnects, it will (likely) get the same auc_3g_ind
|
|
||||||
conn_inst[5].auc_3g_ind == 5
|
|
||||||
conn_inst[5].auc_3g_ind == 5
|
|
||||||
===== test_add_conn: SUCCESS
|
|
||||||
|
|
||||||
Done
|
|
||||||
@@ -14,7 +14,7 @@ OsmoHLR> list
|
|||||||
...
|
...
|
||||||
show gsup-connections
|
show gsup-connections
|
||||||
show subscribers all
|
show subscribers all
|
||||||
show subscribers (imsi|msisdn) FILTER
|
show subscribers (imei|imsi|msisdn) FILTER
|
||||||
show subscribers (cs|ps) (on|off)
|
show subscribers (cs|ps) (on|off)
|
||||||
show subscribers last-seen
|
show subscribers last-seen
|
||||||
subscriber (imsi|msisdn|id|imei) IDENT show
|
subscriber (imsi|msisdn|id|imei) IDENT show
|
||||||
@@ -107,6 +107,7 @@ hlr
|
|||||||
database hlr_vty_test.db
|
database hlr_vty_test.db
|
||||||
gsup
|
gsup
|
||||||
bind ip 127.0.0.1
|
bind ip 127.0.0.1
|
||||||
|
ipa-name unnamed-HLR
|
||||||
ussd route prefix *#100# internal own-msisdn
|
ussd route prefix *#100# internal own-msisdn
|
||||||
ussd route prefix *#101# internal own-imsi
|
ussd route prefix *#101# internal own-imsi
|
||||||
end
|
end
|
||||||
@@ -345,9 +346,9 @@ OsmoHLR(config-mslookup-server-msc)# show running-config
|
|||||||
mslookup
|
mslookup
|
||||||
server
|
server
|
||||||
mdns bind 239.192.23.42 4266
|
mdns bind 239.192.23.42 4266
|
||||||
service foo.bar at 123.45.67.89 1011
|
service foo.bar at 123.45.67.89 1011
|
||||||
service baz.bar at 121.31.41.5 1617
|
service baz.bar at 121.31.41.5 1617
|
||||||
service baz.bar at a:b:c::d 1819
|
service baz.bar at a:b:c::d 1819
|
||||||
msc MSC-1
|
msc MSC-1
|
||||||
msc msc-901-70-23
|
msc msc-901-70-23
|
||||||
service foo.bar at 76.54.32.10 1234
|
service foo.bar at 76.54.32.10 1234
|
||||||
@@ -401,8 +402,8 @@ OsmoHLR(config-mslookup-client)# show running-config
|
|||||||
mslookup
|
mslookup
|
||||||
server
|
server
|
||||||
mdns bind 239.192.23.42 4266
|
mdns bind 239.192.23.42 4266
|
||||||
service foo.bar at 123.45.67.89 1011
|
service foo.bar at 123.45.67.89 1011
|
||||||
service baz.bar at 121.31.41.5 1617
|
service baz.bar at 121.31.41.5 1617
|
||||||
msc MSC-1
|
msc MSC-1
|
||||||
msc msc-901-70-23
|
msc msc-901-70-23
|
||||||
service foo.bar at 76.54.32.10 1234
|
service foo.bar at 76.54.32.10 1234
|
||||||
@@ -433,9 +434,9 @@ OsmoHLR(config-mslookup-server)# show running-config
|
|||||||
mslookup
|
mslookup
|
||||||
server
|
server
|
||||||
mdns bind 239.192.23.42 4266
|
mdns bind 239.192.23.42 4266
|
||||||
service foo.bar at 123.45.67.89 1011
|
service foo.bar at 123.45.67.89 1011
|
||||||
service baz.bar at 121.31.41.5 1617
|
service baz.bar at 121.31.41.5 1617
|
||||||
service gsup.hlr at 23.42.17.11 4223
|
service gsup.hlr at 23.42.17.11 4223
|
||||||
msc MSC-1
|
msc MSC-1
|
||||||
msc msc-901-70-23
|
msc msc-901-70-23
|
||||||
service foo.bar at 76.54.32.10 1234
|
service foo.bar at 76.54.32.10 1234
|
||||||
|
|||||||
@@ -610,5 +610,102 @@ periodic_lu_timer 0
|
|||||||
periodic_rau_tau_timer 0
|
periodic_rau_tau_timer 0
|
||||||
lmsi 00000000
|
lmsi 00000000
|
||||||
|
|
||||||
GET 101 subscriber.by-id-0x0123.info
|
SET 101 subscriber.create 901991234567891
|
||||||
ERROR 101 Invalid value part of 'by-xxx-value' selector.
|
SET_REPLY 101 subscriber.create 124
|
||||||
|
|
||||||
|
GET 102 subscriber.by-id-124.info
|
||||||
|
GET_REPLY 102 subscriber.by-id-124.info
|
||||||
|
id 124
|
||||||
|
imsi 901991234567891
|
||||||
|
nam_cs 1
|
||||||
|
nam_ps 1
|
||||||
|
ms_purged_cs 0
|
||||||
|
ms_purged_ps 0
|
||||||
|
periodic_lu_timer 0
|
||||||
|
periodic_rau_tau_timer 0
|
||||||
|
lmsi 00000000
|
||||||
|
|
||||||
|
GET 103 subscriber.by-imsi-901991234567891.msisdn
|
||||||
|
GET_REPLY 103 subscriber.by-imsi-901991234567891.msisdn none
|
||||||
|
|
||||||
|
SET 104 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||||
|
SET_REPLY 104 subscriber.by-imsi-901991234567891.msisdn OK
|
||||||
|
|
||||||
|
GET 105 subscriber.by-imsi-901991234567891.msisdn
|
||||||
|
GET_REPLY 105 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||||
|
|
||||||
|
SET 106 subscriber.by-imsi-901991234567891.msisdn 888000
|
||||||
|
SET_REPLY 106 subscriber.by-imsi-901991234567891.msisdn OK
|
||||||
|
|
||||||
|
GET 107 subscriber.by-imsi-901991234567891.msisdn
|
||||||
|
GET_REPLY 107 subscriber.by-imsi-901991234567891.msisdn 888000
|
||||||
|
|
||||||
|
GET 108 subscriber.by-imsi-901991234567891.info
|
||||||
|
GET_REPLY 108 subscriber.by-imsi-901991234567891.info
|
||||||
|
id 124
|
||||||
|
imsi 901991234567891
|
||||||
|
msisdn 888000
|
||||||
|
nam_cs 1
|
||||||
|
nam_ps 1
|
||||||
|
ms_purged_cs 0
|
||||||
|
ms_purged_ps 0
|
||||||
|
periodic_lu_timer 0
|
||||||
|
periodic_rau_tau_timer 0
|
||||||
|
lmsi 00000000
|
||||||
|
|
||||||
|
SET 109 subscriber.by-imsi-901991234567891.msisdn none
|
||||||
|
SET_REPLY 109 subscriber.by-imsi-901991234567891.msisdn OK
|
||||||
|
|
||||||
|
GET 110 subscriber.by-imsi-901991234567891.msisdn
|
||||||
|
GET_REPLY 110 subscriber.by-imsi-901991234567891.msisdn none
|
||||||
|
|
||||||
|
GET 111 subscriber.by-imsi-901991234567891.info
|
||||||
|
GET_REPLY 111 subscriber.by-imsi-901991234567891.info
|
||||||
|
id 124
|
||||||
|
imsi 901991234567891
|
||||||
|
nam_cs 1
|
||||||
|
nam_ps 1
|
||||||
|
ms_purged_cs 0
|
||||||
|
ms_purged_ps 0
|
||||||
|
periodic_lu_timer 0
|
||||||
|
periodic_rau_tau_timer 0
|
||||||
|
lmsi 00000000
|
||||||
|
|
||||||
|
GET 112 subscriber.by-imsi-901991234567891.aud2g
|
||||||
|
GET_REPLY 112 subscriber.by-imsi-901991234567891.aud2g none
|
||||||
|
|
||||||
|
SET 113 subscriber.by-imsi-901991234567891.aud2g xor,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||||
|
SET_REPLY 113 subscriber.by-imsi-901991234567891.aud2g OK
|
||||||
|
|
||||||
|
GET 114 subscriber.by-imsi-901991234567891.aud2g
|
||||||
|
GET_REPLY 114 subscriber.by-imsi-901991234567891.aud2g XOR,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||||
|
|
||||||
|
SET 115 subscriber.by-imsi-901991234567891.aud2g none
|
||||||
|
SET_REPLY 115 subscriber.by-imsi-901991234567891.aud2g OK
|
||||||
|
|
||||||
|
GET 116 subscriber.by-imsi-901991234567891.aud2g
|
||||||
|
GET_REPLY 116 subscriber.by-imsi-901991234567891.aud2g none
|
||||||
|
|
||||||
|
GET 117 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 117 subscriber.by-imsi-901991234567891.aud3g none
|
||||||
|
|
||||||
|
SET 118 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,FB2A3D1B360F599ABAB99DB8669F8308
|
||||||
|
SET_REPLY 118 subscriber.by-imsi-901991234567891.aud3g OK
|
||||||
|
|
||||||
|
GET 119 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 119 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,fb2a3d1b360f599abab99db8669f8308,5
|
||||||
|
|
||||||
|
SET 120 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,FB2A3D1B360F599ABAB99DB8669F8308,7
|
||||||
|
SET_REPLY 120 subscriber.by-imsi-901991234567891.aud3g OK
|
||||||
|
|
||||||
|
GET 121 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 121 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,7
|
||||||
|
|
||||||
|
SET 122 subscriber.by-imsi-901991234567891.aud3g none
|
||||||
|
SET_REPLY 122 subscriber.by-imsi-901991234567891.aud3g OK
|
||||||
|
|
||||||
|
GET 123 subscriber.by-imsi-901991234567891.aud3g
|
||||||
|
GET_REPLY 123 subscriber.by-imsi-901991234567891.aud3g none
|
||||||
|
|
||||||
|
SET 124 subscriber.delete 901991234567891
|
||||||
|
SET_REPLY 124 subscriber.delete 124
|
||||||
|
|||||||
@@ -105,3 +105,51 @@ GET 46 subscriber.by-imsi-1234567890123456.ps-enabled
|
|||||||
ERROR 46 Invalid value part of 'by-xxx-value' selector.
|
ERROR 46 Invalid value part of 'by-xxx-value' selector.
|
||||||
GET 47 subscriber.by-imsi-1234567890123456.cs-enabled
|
GET 47 subscriber.by-imsi-1234567890123456.cs-enabled
|
||||||
ERROR 47 Invalid value part of 'by-xxx-value' selector.
|
ERROR 47 Invalid value part of 'by-xxx-value' selector.
|
||||||
|
|
||||||
|
GET 48 subscriber.by-id-0x0123.info
|
||||||
|
ERROR 48 Invalid value part of 'by-xxx-value' selector.
|
||||||
|
|
||||||
|
SET 49 subscriber.create zzz
|
||||||
|
ERROR 49 Invalid IMSI value.
|
||||||
|
|
||||||
|
SET 50 subscriber.create 901990000000001
|
||||||
|
ERROR 50 Subscriber already exists.
|
||||||
|
|
||||||
|
SET 51 subscriber.by-imsi-1234567890123456.msisdn hellobadmsisdn
|
||||||
|
ERROR 51 Value failed verification.
|
||||||
|
|
||||||
|
SET 52 subscriber.delete 100000
|
||||||
|
ERROR 52 Subscriber doesn't exist.
|
||||||
|
|
||||||
|
SET 53 subscriber.delete zzz
|
||||||
|
ERROR 53 Invalid IMSI value.
|
||||||
|
|
||||||
|
SET 54 subscriber.by-imsi-901990000000003.aud2g foobar
|
||||||
|
ERROR 54 Value failed verification.
|
||||||
|
|
||||||
|
SET 55 subscriber.by-imsi-901990000000003.aud2g foobar,2134
|
||||||
|
ERROR 55 Unknown auth algorithm.
|
||||||
|
|
||||||
|
SET 56 subscriber.by-imsi-901990000000003.aud2g xor,2134
|
||||||
|
ERROR 56 Invalid KI.
|
||||||
|
|
||||||
|
SET 57 subscriber.by-imsi-901990000000003.aud3g foobar
|
||||||
|
ERROR 57 Value failed verification.
|
||||||
|
|
||||||
|
SET 58 subscriber.by-imsi-901990000000003.aud3g foobar,2134
|
||||||
|
ERROR 58 Unknown auth algorithm.
|
||||||
|
|
||||||
|
SET 60 subscriber.by-imsi-901990000000003.aud3g milenage,2134
|
||||||
|
ERROR 60 Invalid KI.
|
||||||
|
|
||||||
|
SET 61 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,AAA
|
||||||
|
ERROR 61 Invalid format.
|
||||||
|
|
||||||
|
SET 62 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC
|
||||||
|
ERROR 62 Invalid format.
|
||||||
|
|
||||||
|
SET 63 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,zzz
|
||||||
|
ERROR 63 Invalid OP/OPC.
|
||||||
|
|
||||||
|
SET 64 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,
|
||||||
|
ERROR 64 Invalid format.
|
||||||
|
|||||||
@@ -22,13 +22,6 @@ cat $abs_srcdir/gsup/gsup_test.err > experr
|
|||||||
AT_CHECK([$abs_top_builddir/tests/gsup/gsup_test], [], [expout], [experr])
|
AT_CHECK([$abs_top_builddir/tests/gsup/gsup_test], [], [expout], [experr])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
AT_SETUP([gsup_server])
|
|
||||||
AT_KEYWORDS([gsup_server])
|
|
||||||
cat $abs_srcdir/gsup_server/gsup_server_test.ok > expout
|
|
||||||
cat $abs_srcdir/gsup_server/gsup_server_test.err > experr
|
|
||||||
AT_CHECK([$abs_top_builddir/tests/gsup_server/gsup_server_test], [], [expout], [experr])
|
|
||||||
AT_CLEANUP
|
|
||||||
|
|
||||||
AT_SETUP([db])
|
AT_SETUP([db])
|
||||||
AT_KEYWORDS([db])
|
AT_KEYWORDS([db])
|
||||||
cat $abs_srcdir/db/db_test.ok > expout
|
cat $abs_srcdir/db/db_test.ok > expout
|
||||||
|
|||||||
Reference in New Issue
Block a user