mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-cbc.git
synced 2025-11-02 21:23:37 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
493845d8e4 | ||
|
|
d6a3728bce | ||
|
|
e8ab2f3148 | ||
|
|
e74594b247 | ||
|
|
fa4826bfa6 | ||
|
|
287a6aaeb0 | ||
|
|
557fcbc110 | ||
|
|
bc80894f0e | ||
|
|
2b158c3b2d | ||
|
|
071a60e465 | ||
|
|
24507ffd0d | ||
|
|
6467dfdb9c | ||
|
|
f80d53068a | ||
|
|
367cdb3697 | ||
|
|
8e1093e244 | ||
|
|
78fd4efa81 | ||
|
|
5180d5ffae | ||
|
|
51977c72f3 | ||
|
|
b8b77e77e4 | ||
|
|
51657edefd | ||
|
|
7e00b941b8 | ||
|
|
8b596fecb1 | ||
|
|
f1afe95754 | ||
|
|
f97cd9672d | ||
|
|
1d78b2e73d | ||
|
|
e88eceb790 | ||
|
|
d1c50f54cd | ||
|
|
5bf735efc9 | ||
|
|
eaee3e30b1 | ||
|
|
55956f4512 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -58,3 +58,5 @@ doc/manuals/osmobsc-usermanual.xml
|
||||
doc/manuals/common
|
||||
doc/manuals/build
|
||||
doc/manuals/vty/cbc_vty_reference.xml
|
||||
|
||||
contrib/osmo-cbc.spec
|
||||
|
||||
@@ -3,7 +3,13 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = src doc contrib tests
|
||||
|
||||
EXTRA_DIST = .version git-version-gen
|
||||
EXTRA_DIST = .version \
|
||||
README.md \
|
||||
git-version-gen \
|
||||
contrib/osmo-cbc.spec.in \
|
||||
cbc.schema.json \
|
||||
smscb.schema.json \
|
||||
$(NULL)
|
||||
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = \
|
||||
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
|
||||
|
||||
69
README.md
Normal file
69
README.md
Normal file
@@ -0,0 +1,69 @@
|
||||
osmo-cbc - Osmocom Cell Broadcast Centre
|
||||
========================================
|
||||
|
||||
This repository contains a C-language implementation of a minimal
|
||||
3GPP Cell Broadcast Centre (CBC). It is part of the
|
||||
[Osmocom](https://osmocom.org/) Open Source Mobile Communications
|
||||
project.
|
||||
|
||||
A Cell Broadcast Centre is the central network element of a cellular network
|
||||
for distribution of Cell Broadcast and Emergency messages.
|
||||
|
||||
This code implements
|
||||
* the CBSP protocol on the CBC-BSC interface
|
||||
* a custom HTTP/REST based interface for external users to create/delete CBS messages
|
||||
|
||||
We plan to add support for the following features in the future:
|
||||
* the SABP protocol on the CBC-RNC (or CBC-HNBGW) interface for UMTS support
|
||||
* the SBcAP protocol on the CBC-MME interface for LTE support
|
||||
|
||||
Homepage
|
||||
--------
|
||||
|
||||
The official homepage of the project is
|
||||
https://osmocom.org/projects/osmo-cbc/wiki
|
||||
|
||||
GIT Repository
|
||||
--------------
|
||||
|
||||
You can clone from the official osmo-cbc.git repository using
|
||||
|
||||
git clone https://git.osmocom.org/osmo-cbc.git
|
||||
|
||||
There is a cgit interface at https://git.osmocom.org/osmo-cbc/
|
||||
|
||||
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/osmocbc-usermanual.pdf)
|
||||
as well as the [VTY Reference Manual for osmo-cbc](https://ftp.osmocom.org/docs/latest/osmocbc-vty-reference.pdf)
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
Discussions related to osmo-cbc 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-cbc can be seen at
|
||||
https://gerrit.osmocom.org/#/q/project:osmo-cbc+status:open
|
||||
@@ -9,6 +9,8 @@ AC_CONFIG_AUX_DIR([.])
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
|
||||
CFLAGS="$CFLAGS -std=gnu11"
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
@@ -168,6 +170,7 @@ AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
|
||||
AC_OUTPUT(
|
||||
src/Makefile
|
||||
contrib/Makefile
|
||||
contrib/osmo-cbc.spec
|
||||
tests/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
SUBDIRS = systemd
|
||||
|
||||
EXTRA_DIST = cbc-apitool.py \
|
||||
$(NULL)
|
||||
|
||||
157
contrib/cbc-apitool.py
Executable file
157
contrib/cbc-apitool.py
Executable file
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# (C) 2020-2021 by Harald Welte <laforge@osmocom.org>
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# This is a simplistic program to show how the REST API of osmo-cbc can be used to
|
||||
# create and delete Cell Broadcast Messages
|
||||
#
|
||||
# A lot of the parameters are currently hard-coded, see the 'js' variable definitions
|
||||
# below.
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import requests
|
||||
|
||||
|
||||
def build_url(suffix):
|
||||
BASE_PATH= "/api/ecbe/v1"
|
||||
return "http://%s:%u%s%s" % (server_host, server_port, BASE_PATH, suffix)
|
||||
|
||||
|
||||
def rest_post(suffix, js = None):
|
||||
url = build_url(suffix)
|
||||
if verbose:
|
||||
print("POST %s (%s)" % (url, str(js)))
|
||||
resp = requests.post(url, json=js)
|
||||
if verbose:
|
||||
print("-> %s" % (resp))
|
||||
if not resp.ok:
|
||||
print("POST failed")
|
||||
return resp
|
||||
|
||||
def rest_delete(suffix, js = None):
|
||||
url = build_url(suffix)
|
||||
if verbose:
|
||||
print("DELETE %s (%s)" % (url, str(js)))
|
||||
resp = requests.delete(url, json=js)
|
||||
if verbose:
|
||||
print("-> %s" % (resp))
|
||||
if not resp.ok:
|
||||
print("DELETE failed " + str(resp))
|
||||
return resp
|
||||
|
||||
|
||||
def do_create_cbs(args):
|
||||
js = {
|
||||
'cbe_name': "cbc_apitool",
|
||||
'category': "normal",
|
||||
'repetition_period': args.repetition_period,
|
||||
'num_of_bcast': args.num_of_bcast,
|
||||
'scope': {
|
||||
'scope_plmn': { }
|
||||
},
|
||||
'smscb_message': {
|
||||
'message_id': args.msg_id,
|
||||
'serial_nr': {
|
||||
'serial_nr_decoded': {
|
||||
'geo_scope': "plmn_wide",
|
||||
'msg_code': args.msg_code,
|
||||
'update_nr': args.update_nr
|
||||
}
|
||||
},
|
||||
'payload': {
|
||||
'payload_decoded': {
|
||||
'character_set': "gsm",
|
||||
#'language': 'en',
|
||||
'data_utf8': args.payload_data_utf8,
|
||||
#'data_utf8': "Mahlzeit1 Mahlzeit2 Mahlzeit3 Mahlzeit4 Mahlzeit5 Mahlzeit6 Mahlzeit7 Mahlzeit8"
|
||||
#'data_utf8': "Mahlzeit1 Mahlzeit2 Mahlzeit3 Mahlzeit4 Mahlzeit5 Mahlzeit6 Mahlzeit7 Mahlzeit8 Mahlzeit9 Mahlzeit10 Mahlzeti11 Mahlzeit12 Mahlzeit13 Mahlzeit14 Mahlzeit15 Mahlzeit16 Mahlzeit17 Mahlzeit18 Mahlzeit19 Mahlzeit20 Mahlzeit21 Mahlzeit22 Mahlzeit23 Mahlzeit24 Mahlzeit25 Mahlzeit26 Mahlzeit27 Mahlzeit28"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rest_post("/message", js);
|
||||
|
||||
def do_create_etws(args):
|
||||
js = {
|
||||
'cbe_name': "cbc_apitool",
|
||||
'category': "normal",
|
||||
'repetition_period': args.repetition_period,
|
||||
'num_of_bcast': args.num_of_bcast,
|
||||
'scope': {
|
||||
'scope_plmn': { }
|
||||
},
|
||||
'smscb_message': {
|
||||
'message_id': args.msg_id,
|
||||
'serial_nr': {
|
||||
'serial_nr_decoded': {
|
||||
'geo_scope': "plmn_wide",
|
||||
'msg_code': args.msg_code,
|
||||
'update_nr': args.update_nr
|
||||
}
|
||||
},
|
||||
'payload': {
|
||||
'payload_etws': {
|
||||
'warning_type': {
|
||||
'warning_type_decoded': 'earthquake'
|
||||
},
|
||||
'emergency_user_alert': True,
|
||||
'popup_on_display': True
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rest_post("/message", js);
|
||||
|
||||
|
||||
def do_delete(args):
|
||||
rest_delete("/message/%u" % (args.msg_id))
|
||||
|
||||
def main(argv):
|
||||
global server_port, server_host, verbose
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-H", "--host", help="Host to connect to", default="localhost")
|
||||
parser.add_argument("-p", "--port", help="TCP port to connect to", default=12345)
|
||||
parser.add_argument("-v", "--verbose", help="increase output verbosity", action='count', default=0)
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
parser_c_cbs = subparsers.add_parser('create-cbs', help='Create a new CBS message')
|
||||
parser_c_cbs.add_argument("--msg-id", type=int, help='Message Identifier', required=True)
|
||||
parser_c_cbs.add_argument("--msg-code", type=int, help='Message Code', default=768)
|
||||
parser_c_cbs.add_argument("--update-nr", type=int, help='Update Number', default=0)
|
||||
parser_c_cbs.add_argument("--repetition-period", type=int, help='Repetition Period', default=5)
|
||||
parser_c_cbs.add_argument("--num-of-bcast", type=int, help='Number of Broadcasts', default=999)
|
||||
parser_c_cbs.add_argument("--payload-data-utf8", type=str, help='Payload Data in UTF8', required=True)
|
||||
parser_c_cbs.set_defaults(func=do_create_cbs)
|
||||
|
||||
parser_c_etws = subparsers.add_parser('create-etws', help='Create a new ETWS message')
|
||||
parser_c_etws.add_argument("--msg-id", type=int, help='Message Identifier', required=True)
|
||||
parser_c_etws.add_argument("--msg-code", type=int, help='Message Code', default=768)
|
||||
parser_c_etws.add_argument("--update-nr", type=int, help='Update Number', default=0)
|
||||
parser_c_etws.add_argument("--repetition-period", type=int, help='Repetition Period', default=5)
|
||||
parser_c_etws.add_argument("--num-of-bcast", type=int, help='Number of Broadcasts', default=999)
|
||||
parser_c_etws.set_defaults(func=do_create_etws)
|
||||
|
||||
parser_delete = subparsers.add_parser('delete', help='Delete a message')
|
||||
parser_delete.add_argument("--msg-id", type=int, help='Message Identifier', required=True)
|
||||
parser_delete.set_defaults(func=do_delete)
|
||||
|
||||
argv = sys.argv
|
||||
if len(sys.argv) == 1:
|
||||
args = parser.parse_args(['-h'])
|
||||
else:
|
||||
args = parser.parse_args()
|
||||
|
||||
server_host = args.host
|
||||
server_port = args.port
|
||||
verbose = args.verbose
|
||||
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
@@ -36,7 +36,6 @@ osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
# Additional configure options and depends
|
||||
CONFIG=""
|
||||
if [ "$WITH_MANUALS" = "1" ]; then
|
||||
osmo-build-dep.sh osmo-gsm-manuals
|
||||
CONFIG="--enable-manuals"
|
||||
fi
|
||||
|
||||
|
||||
104
contrib/osmo-cbc.spec.in
Normal file
104
contrib/osmo-cbc.spec.in
Normal file
@@ -0,0 +1,104 @@
|
||||
#
|
||||
# spec file for package osmo-cbc
|
||||
#
|
||||
# Copyright (c) 2021, Harald Welte <laforge@gnumonks.org>
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
## Disable LTO for now since it breaks compilation of the tests
|
||||
## https://osmocom.org/issues/4113
|
||||
%define _lto_cflags %{nil}
|
||||
|
||||
Name: osmo-cbc
|
||||
Version: @VERSION@
|
||||
Release: 0
|
||||
Summary: OsmoCBC: Osmocom's Cell Broadcast Centre for 3GPP mobile networks
|
||||
License: AGPL-3.0-or-later
|
||||
Group: Hardware/Mobile
|
||||
URL: https://osmocom.org/projects/osmo-cbc
|
||||
Source: %{name}-%{version}.tar.xz
|
||||
BuildRequires: automake >= 1.9
|
||||
BuildRequires: libtool >= 2
|
||||
BuildRequires: pkgconfig >= 0.20
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libcrypto) >= 0.9.5
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 0.6.0
|
||||
BuildRequires: pkgconfig(libosmo-sccp) >= 0.10.0
|
||||
BuildRequires: pkgconfig(libosmo-sigtran) >= 0.10.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 0.6.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.2.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.2.0
|
||||
BuildRequires: pkgconfig(libosmogb)
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.2.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.2.0
|
||||
BuildRequires: pkgconfig(talloc)
|
||||
BuildRequires: pkgconfig(libulfius)
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
OsmoCBC: Osmocom's Cell Broadcast Centre for 3GPP mobile networks.
|
||||
|
||||
%package utils
|
||||
Summary: CLI utility to interface osmo-cbc REST interface
|
||||
License: MIT
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description utils
|
||||
CLI utility to interface with the osmo-cbc REST interface (ECBE).
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
echo "%{version}" >.tarball-version
|
||||
autoreconf -fi
|
||||
%configure \
|
||||
--docdir=%{_docdir}/%{name} \
|
||||
--with-systemdsystemunitdir=%{_unitdir}
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
%make_install
|
||||
install -m 755 contrib/cbc-apitool.py %{buildroot}/usr/bin/cbc-apitool.py
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%preun
|
||||
%service_del_preun %{name}.service
|
||||
|
||||
%postun
|
||||
%service_del_postun %{name}.service
|
||||
|
||||
%pre
|
||||
%service_add_pre %{name}.service
|
||||
|
||||
%post
|
||||
%service_add_post %{name}.service
|
||||
%endif
|
||||
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc README.md
|
||||
%{_bindir}/osmo-cbc
|
||||
%dir %{_docdir}/%{name}/examples
|
||||
%dir %{_docdir}/%{name}/examples/osmo-cbc
|
||||
%{_docdir}/%{name}/examples/osmo-cbc/osmo-cbc*.cfg
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-cbc.cfg
|
||||
%{_unitdir}/%{name}.service
|
||||
|
||||
%files utils
|
||||
%{_bindir}/cbc-apitool.py
|
||||
|
||||
%changelog
|
||||
43
debian/changelog
vendored
43
debian/changelog
vendored
@@ -1,5 +1,44 @@
|
||||
osmo-cbc (0.1) UNRELEASED; urgency=medium
|
||||
osmo-cbc (0.2.1) unstable; urgency=medium
|
||||
|
||||
[ Harald Welte ]
|
||||
* VTY: don't save dynamically-allocated "unknown" peers
|
||||
* cbc-apitool: compatibility with python < 3.7
|
||||
|
||||
[ Oliver Smith ]
|
||||
* configure.ac: set -std=gnu11
|
||||
|
||||
-- Harald Welte <laforge@osmocom.org> Tue, 16 Feb 2021 22:39:23 +0100
|
||||
|
||||
osmo-cbc (0.2.0) unstable; urgency=medium
|
||||
|
||||
[ Harald Welte ]
|
||||
* Initial release.
|
||||
* add link to upstream bug related to custom malloc/free
|
||||
* Add simplistic cbc-apitool.py as example on how to use the REST API
|
||||
* Add RPM spec file
|
||||
* Add README.md file
|
||||
* debian/osmo-cbc.install: Fix typo (extra apostrophe at EOL)
|
||||
* charset: Fix padding of USSD messages in 7bit GSM alphabet
|
||||
* spec file: Add missing libulfius dependency
|
||||
* cbc-apitool.py: Generalize, make parameters configurable
|
||||
* osmo-cbc.spec: Don't depend on libosmo-mgcp-client
|
||||
* osmo-cbc.spec: No AUTHORS file; correct name of README.md
|
||||
* manual: Chapters on configuration + vty introspection
|
||||
* vty: Allow IPv6 address for peer remote-ip
|
||||
* Make CBSP local bind IP+port VTY-configurable
|
||||
* Make ECBE (REST interface) local bind IP + port VTY-configurable
|
||||
* terminate if CBSP or ECBE ports cannot be bound
|
||||
* cbc-apitool: Fix parsing if no argument is goven
|
||||
* Makefile.am: cosmetic changes
|
||||
* Makefile.am: add *.json to EXTRA_DIST
|
||||
* manual: Document ECBE; include JSON schema; cross-references
|
||||
* manual: Add dotty graph on position of CBC in network
|
||||
* manual: Document cbc-apitool.py
|
||||
* debian: Package cbc-apitool.py as a sub-package
|
||||
* contrib/osmo-cbc.spec: Add sub-package osmo-cbc-utils
|
||||
* osmo-cbc.spec: License is AGPLv3-or-later + MIT
|
||||
|
||||
-- Harald Welte <lafore@gnumonks.org> Wed, 06 Jan 2021 12:13:12 +0100
|
||||
[ Oliver Smith ]
|
||||
* contrib/jenkins: don't build osmo-gsm-manuals
|
||||
|
||||
-- Harald Welte <laforge@osmocom.org> Sun, 24 Jan 2021 16:15:49 +0100
|
||||
|
||||
6
debian/control
vendored
6
debian/control
vendored
@@ -27,6 +27,12 @@ Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: OsmoCBC: Osmocom's Cell Broadcast Center
|
||||
|
||||
Package: osmo-cbc-utils
|
||||
Architecture: any
|
||||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, python3
|
||||
Description: Utilities for OsmoCBC: Osmocom's Cell Broadcast Center
|
||||
|
||||
Package: osmo-cbc-dbg
|
||||
Section: debug
|
||||
Architecture: any
|
||||
|
||||
1
debian/osmo-cbc-utils.install
vendored
Normal file
1
debian/osmo-cbc-utils.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
usr/bin/cbc-apitool.py
|
||||
2
debian/osmo-cbc.install
vendored
2
debian/osmo-cbc.install
vendored
@@ -1,4 +1,4 @@
|
||||
/etc/osmocom/osmo-cbc.cfg
|
||||
lib/systemd/system/osmo-cbc.service
|
||||
usr/bin/osmo-cbc
|
||||
usr/share/doc/osmo-cbc/examples/osmo-cbc/*.cfg usr/share/doc/osmo-bsc/examples`
|
||||
usr/share/doc/osmo-cbc/examples/osmo-cbc/*.cfg usr/share/doc/osmo-bsc/examples
|
||||
|
||||
5
debian/rules
vendored
5
debian/rules
vendored
@@ -50,8 +50,9 @@ override_dh_auto_configure:
|
||||
dh_auto_configure -- $(CONFIGURE_FLAGS)
|
||||
#
|
||||
# Do not install libtool archive, python .pyc .pyo
|
||||
#override_dh_install:
|
||||
# dh_install --list-missing -X.la -X.pyc -X.pyo
|
||||
override_dh_install:
|
||||
install -m 755 contrib/cbc-apitool.py debian/tmp/usr/bin/cbc-apitool.py
|
||||
dh_install
|
||||
|
||||
# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
|
||||
override_dh_strip:
|
||||
|
||||
@@ -3,6 +3,7 @@ EXTRA_DIST = osmocbc-usermanual.adoc \
|
||||
osmocbc-vty-reference.xml \
|
||||
regen_doc.sh \
|
||||
chapters \
|
||||
images \
|
||||
vty
|
||||
|
||||
if BUILD_MANUALS
|
||||
|
||||
79
doc/manuals/chapters/cbc-apitool.adoc
Normal file
79
doc/manuals/chapters/cbc-apitool.adoc
Normal file
@@ -0,0 +1,79 @@
|
||||
[[apitool]]
|
||||
== `cbc-apitool.py`
|
||||
|
||||
`cbc-apitool.py` is a very simple/basic python3 script that can be used
|
||||
to demonstrate the use of the ECBE REST interface (<<ecbe>>) from the
|
||||
command line.
|
||||
|
||||
It uses the python3 standard librariy `requests` in order to issue ECBE
|
||||
API request over HTTP towards osmo-cbc.
|
||||
|
||||
`cbc-apitool.py` has a couple of sub-commands, each of which offer
|
||||
|
||||
=== Common options
|
||||
|
||||
*-h, --help*::
|
||||
Print a short help message about the supported common options.
|
||||
*-H, --host HOST*::
|
||||
Remote host name/IP to which to connect (typically your ECBE
|
||||
bind address of osmo-cbc). Default: 127.0.0.1.
|
||||
*-p, --port PORT*::
|
||||
Remote TCP port number to which to connect (typically your ECBE
|
||||
bind address of osmo-cbc). Default: 12345
|
||||
*-v, --verbose*::
|
||||
Print some more verbose information like the HTTP requests
|
||||
and responses during execution.
|
||||
|
||||
|
||||
=== `create-cbs`: Creating a new CBS message
|
||||
|
||||
You can create a new CBS message using `cbc-apitool create-cbs`.
|
||||
|
||||
==== `create-cbs` Options
|
||||
|
||||
*-h, --help*::
|
||||
Print a short help message about the supported create-cbs options.
|
||||
*--msg-id MSG_ID*::
|
||||
Specify the message ID of the to-be-created CBS
|
||||
message. Range: 0..65535
|
||||
*--msg-code MSG_CODE*::
|
||||
Specify the message code (part of the serial number). Range:
|
||||
0..1023. Default: 768
|
||||
*--update-nr UPDATE_NR*::
|
||||
Specify the update number (part of the serial number). Range:
|
||||
0..15. Default: 0
|
||||
*--repetition-period REPETITION_PERIOD*::
|
||||
How frequently this message shall be repeated (in number of CBCH
|
||||
slots). Default: 5
|
||||
*--num-of-bcast NUM_OF_BCAST*::
|
||||
Number of times this message shall be broadcast (Default: 999).
|
||||
*--payload-data-utf8 PAYLOAD_DATA_UTF8*::
|
||||
Payload data (typically text message) in UTF8 encoding. Will be
|
||||
transcoded to 7bit GSM alphabet internally.
|
||||
|
||||
|
||||
==== `create-etws` Options
|
||||
|
||||
*-h, --help*::
|
||||
Print a short help message about the supported create-cbs options.
|
||||
*--msg-id MSG_ID*::
|
||||
Specify the message ID of the to-be-created CBS
|
||||
message. Range: 0..65535
|
||||
*--msg-code MSG_CODE*::
|
||||
Specify the message code (part of the serial number). Range:
|
||||
0..1023. Default: 768
|
||||
*--update-nr UPDATE_NR*::
|
||||
Specify the update number (part of the serial number). Range:
|
||||
0..15. Default: 0
|
||||
*--repetition-period REPETITION_PERIOD*::
|
||||
How frequently this message shall be repeated (in number of CBCH
|
||||
slots). Default: 5
|
||||
*--num-of-bcast NUM_OF_BCAST*::
|
||||
Number of times this message shall be broadcast (Default: 999).
|
||||
|
||||
|
||||
==== `delete` Options
|
||||
|
||||
*--msg-id MSG_ID*::
|
||||
Specify the message ID of the to-be-created CBS
|
||||
message. Range: 0..65535
|
||||
83
doc/manuals/chapters/configuration.adoc
Normal file
83
doc/manuals/chapters/configuration.adoc
Normal file
@@ -0,0 +1,83 @@
|
||||
[[configuration]]
|
||||
== Configuration
|
||||
|
||||
=== CBSP / Peer Configuration
|
||||
|
||||
CBSP is the BSC-CBC interface within the 3GPP architecture. It serves
|
||||
to communicate CSB and ETWS messages from the CBC to the BSC, who then
|
||||
subsequently distributes it among the (matching) cells within the BSC
|
||||
coverage area.
|
||||
|
||||
[[config-cbsp]]
|
||||
==== Configuring the CBSP connections
|
||||
|
||||
According to 3GPP TS 48.049, a BSC typically operates as a TCP server,
|
||||
and the CBC connects as TCP client. This would require the CBC to have
|
||||
out-of-band knowledge of all the BSCs in the network (and their IP
|
||||
addresses).
|
||||
|
||||
In order to comply with the specifications, OsmoCBC supports this mode
|
||||
of operation as CBSP TCP client. However, to make network operation and
|
||||
configuration more simple, it also can operate in TCP server mode,
|
||||
accepting incoming connections from the BSCs. This way the BSCs need to
|
||||
know the CBC IP address, but not vice-versa.
|
||||
|
||||
The CBC related configuration of OsmoBSC can be found in the `cbc` configuration
|
||||
node of the VTY interface.
|
||||
|
||||
The default port number for the CBSP server is 48049, according to the CBSP
|
||||
specification.
|
||||
|
||||
.Example: Configure TCP server mode and allow arbitrary BSCs to connect
|
||||
----
|
||||
cbc
|
||||
unknown-peers accept
|
||||
----
|
||||
|
||||
|
||||
.Example: Configure TCP client mode and define each BSC
|
||||
----
|
||||
cbc
|
||||
peer my-bsc-1
|
||||
protocol cbsp
|
||||
remote-port 46133
|
||||
remote-ip 1.2.3.4
|
||||
peer my-bsc-2
|
||||
remote-port 46133
|
||||
remote-ip 1.2.3.4
|
||||
----
|
||||
|
||||
For more details on the available configuration commands, please check the OsmoCBC VTY Reference.
|
||||
|
||||
==== Configuring the IP/Port for CBSP to bind to
|
||||
|
||||
It can be configure to which IP and TCP port the CBSP protocol binds to.
|
||||
|
||||
The default is to bind to the 3GPP standard port number 48049 for CBSP at the
|
||||
loopback IP address 127.0.0.1.
|
||||
|
||||
.Example: Configure CBSP to bind to 127.0.0.1:48049
|
||||
----
|
||||
cbc
|
||||
cbsp
|
||||
local-ip 127.0.0.1
|
||||
local-port 48049
|
||||
----
|
||||
|
||||
[[config-ecbe]]
|
||||
=== ECBE (REST Interface) Configuration
|
||||
|
||||
==== Configuring the IP/Port for ECBE to bind to
|
||||
|
||||
It can be configure to which IP and TCP port the ECBE REST Interface binds to.
|
||||
|
||||
The default is to bind to is the non-standard port number 12349 at the
|
||||
loopback IP address 127.0.0.1.
|
||||
|
||||
.Example: Configure ECBE REST interface to bind to 127.0.0.1:8080
|
||||
----
|
||||
cbc
|
||||
ecbe
|
||||
local-ip 127.0.0.1
|
||||
local-port 8080
|
||||
----
|
||||
49
doc/manuals/chapters/ecbe-rest-interface.adoc
Normal file
49
doc/manuals/chapters/ecbe-rest-interface.adoc
Normal file
@@ -0,0 +1,49 @@
|
||||
[[ecbe]]
|
||||
== ECBE REST interface
|
||||
|
||||
The ECBE (External Cell Broadcast Entity) REST interface is specified in
|
||||
the JSON schema files `cbc.schema.json` and `smscb.schema.json`, which
|
||||
are part of the OsmoCBC distribution.
|
||||
|
||||
The REST interface binds to the IP and TCP port as configured and
|
||||
can be reached at `http://IP:PORT/api/ecbe/v1`
|
||||
|
||||
NOTE:: It is your responsibility to properly secure access to the REST
|
||||
interface endpoint to ensure only legitimate users can access it. This
|
||||
may be achieved via packet filtering and a reverse HTTP proxy.
|
||||
|
||||
=== API endpoints
|
||||
|
||||
==== `POST /api/ecbe/v1/message`
|
||||
|
||||
This command is used to create a new SMSCB or ETWS message inside the CBC.
|
||||
The `cbc_messsage` type as specified in the JSON schema (<<ecbe-json>>).
|
||||
|
||||
==== `DELETE /api/ecbe/v1/message/:message_id`
|
||||
|
||||
This command is used to delete an existing SMSCB or ETWS message from the CBC.
|
||||
|
||||
The `:message_id` parameter is the decimal integer representation of the
|
||||
cbc_message.smscb.message_id that was specified when creating the
|
||||
message via the POST command stated above.
|
||||
|
||||
[[ecbe-json]]
|
||||
=== JSON Schema
|
||||
|
||||
==== `cbc.schema.json`
|
||||
|
||||
This is the main JSOM schema for osmo-cbc. In many places, it
|
||||
references `smscb.schema.json` described further below.
|
||||
|
||||
----
|
||||
include::{srcdir}/../../cbc.schema.json[]
|
||||
----
|
||||
|
||||
==== `smscb.schema.json`
|
||||
|
||||
This JSON schema describes a lot of the basic data types relevant for
|
||||
SMSCB. It is used heavily by `cbc.schema.json` described above.
|
||||
|
||||
----
|
||||
include::{srcdir}/../../smscb.schema.json[]
|
||||
----
|
||||
91
doc/manuals/chapters/introspection.adoc
Normal file
91
doc/manuals/chapters/introspection.adoc
Normal file
@@ -0,0 +1,91 @@
|
||||
== Introspection using the VTY
|
||||
|
||||
OsmoCBC offers a VTY interface on TCP port 4264. Like all Osmocom VTY interfaces,
|
||||
it is normally bound only to the loopback address 127.0.0.1. You can change this
|
||||
via the configuration.
|
||||
|
||||
The actual IP/Port is printed to the log at startup time:
|
||||
|
||||
----
|
||||
20210124110559489 DLGLOBAL NOTICE Available via telnet 127.0.0.1 4264 (telnet_interface.c:104)
|
||||
----
|
||||
|
||||
=== Peer State
|
||||
|
||||
Using the `show peers` command, you can check on the state of all configured and/or connected
|
||||
peers:
|
||||
|
||||
.Example: Showing a list of all peers
|
||||
----
|
||||
OsmoCBC> show peers
|
||||
|Name | IP | Port | Proto | State |
|
||||
|--------------------|----------------|------|-------|---------------------|
|
||||
|ttcn3 | 127.0.0.1 | 9999 | CBSP | <disconnected> |
|
||||
|local-bsc | 127.0.0.1 | 46133| CBSP | IDLE |
|
||||
----
|
||||
|
||||
=== CBS Messages
|
||||
|
||||
Using `show messages cbs`, a list of all current CBS messages can be obtained.
|
||||
|
||||
.Example: Showing a list of all CBS messages
|
||||
----
|
||||
OsmoCBC> show messages cbs
|
||||
|MsgId|SerNo| CBE Name | Category |Period|E|DCS|
|
||||
|-----|-----|--------------------|-------------|------|-|---|
|
||||
| 04D2| 7000|cbc_apitool |Normal | 5 |N| 0f|
|
||||
----
|
||||
|
||||
Using `show message 1234`, details about a specific CBS message can be obtained:
|
||||
|
||||
.Example: Showing details about a single CBS message
|
||||
----
|
||||
OsmoCBC> show message id 1234
|
||||
Message ID 04D2, Serial Number 7000, State: ACTIVE
|
||||
Created by CBE 'cbc_apitool' at Sun Jan 24 11:10:31 2021
|
||||
Repetition Period: 5 ( 9.41s), Number of broadcasts: 999
|
||||
Warning Period: 4294967295s
|
||||
DCS: 0x0f, Number of pages: 1, User Data Bytes: 7
|
||||
Page 0: cd309aad2fa7e98d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168
|
||||
Peer: 'ttcn3', State: ACTIVE
|
||||
Cells Installed:
|
||||
Cells Failed:
|
||||
Number of Broadcasts Completed:
|
||||
Peer: 'local-bsc', State: ACTIVE
|
||||
Cells Installed:
|
||||
CGI 901-70-1-1234
|
||||
Cells Failed:
|
||||
Number of Broadcasts Completed:
|
||||
----
|
||||
|
||||
|
||||
=== ETWS Messages
|
||||
|
||||
Using `show messages etws` a list of all current ETWS messages can be obtained.
|
||||
|
||||
.Example: Showing a list of all ETWS messages
|
||||
----
|
||||
OsmoCBC> show messages etws
|
||||
|MsgId|SerNo| CBE Name | Category |Period|E|Warning Type|
|
||||
|-----|-----|--------------------|-------------|------|-|------------|
|
||||
| 03E8| 7000|cbc_apitool |Normal | 5 |N| 0000|
|
||||
----
|
||||
|
||||
.Example: Showing details of one single ETWS message
|
||||
----
|
||||
OsmoCBC> show message id 1000
|
||||
Message ID 03E8, Serial Number 7000, State: ACTIVE
|
||||
Created by CBE 'cbc_apitool' at Sun Jan 24 11:14:42 2021
|
||||
Repetition Period: 5 ( 9.41s), Number of broadcasts: 999
|
||||
ETWS Warning Type Value: 0x00, User Alert: On, Popup: On
|
||||
Security: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
Peer: 'ttcn3', State: ACTIVE
|
||||
Cells Installed:
|
||||
Cells Failed:
|
||||
Number of Broadcasts Completed:
|
||||
Peer: 'local-bsc', State: ACTIVE
|
||||
Cells Installed:
|
||||
CGI 901-70-1-1234
|
||||
Cells Failed:
|
||||
Number of Broadcasts Completed:
|
||||
----
|
||||
@@ -10,6 +10,12 @@ It acts as a gateway between external applications / users, such as government
|
||||
authorities for civil protection, and the various components within the 3GPP
|
||||
network to actually deliver those broadcast and/or emergency messages.
|
||||
|
||||
.Role of the CBC inside the 3GPP network architecture
|
||||
[graphviz]
|
||||
----
|
||||
include::../images/cbc-in-network.dot[]
|
||||
----
|
||||
|
||||
[[about]]
|
||||
=== About OsmoCBC
|
||||
|
||||
@@ -49,29 +55,16 @@ that all BSCs need to know the IP address of the CBC. In this situation,
|
||||
the CBC doesn't need to know each and every BSC in the network. It
|
||||
simply only accepts incoming CBSP connections.
|
||||
|
||||
For more information, see <<config-cbsp>> on how CBSP is configured.
|
||||
|
||||
=== REST interface
|
||||
=== ECBE REST interface
|
||||
|
||||
The REST interface is specified in the JSON schema files
|
||||
`cbc.schema.json` and `smscb.schema.json`, which are part of the OsmoCBC
|
||||
distribution.
|
||||
3GPP does not specify the external interface by which competent
|
||||
authorities can submit SMSCB and/or ETWS messages to a CBC.
|
||||
|
||||
The REST interface currently binds to TCP port 12345 (on INADRR_ANY) and
|
||||
can be reached at http://localhost:1234/api/ecbe/v1"
|
||||
Hence, a non-standard, Osmocom specific HTTP/REST/JSON based interface
|
||||
is offered for external entities to create and delete SMSCB and ETWS
|
||||
messages within the CBC. This interface is called ECBE.
|
||||
|
||||
NOTE:: It is your responsibility to properly secure access to the REST
|
||||
interface endpoint to ensure only legitimate users can access it. This
|
||||
may be achieved via packet filtering and a reverse HTTP proxy.
|
||||
|
||||
==== POST /api/ecbe/v1/message
|
||||
|
||||
This command is used to create a new SMSCB or ETWS message inside the CBC.
|
||||
The `cbc_messsage` type as specified in the JSON schema.
|
||||
|
||||
==== DELETE /api/ecbe/v1/message/:message_id
|
||||
|
||||
This command is used to delete an existing SMSCB or ETWS message from the CBC.
|
||||
|
||||
The `:message_id` parameter is the decimal integer representation of the
|
||||
cbc_message.smscb.message_id that was specified when creating the
|
||||
message via the POST command stated above.
|
||||
For more information, see <<ecbe>> on the ECBE API definition and <<config-ecbe>>
|
||||
on how it is configured.
|
||||
|
||||
17
doc/manuals/images/cbc-in-network.dot
Normal file
17
doc/manuals/images/cbc-in-network.dot
Normal file
@@ -0,0 +1,17 @@
|
||||
digraph G {
|
||||
rankdir = RL;
|
||||
CBC [color=red];
|
||||
CBE -> CBC [label="REST/JSON"];
|
||||
CBC -> BSC [label="CBSP"];
|
||||
CBC -> RNC [label="SABP"];
|
||||
CBC -> MME [label="SBc-AP"];
|
||||
|
||||
BSC -> BTS [label="A-bis RSL"];
|
||||
RNC -> NodeB [label="Iub"];
|
||||
MME -> eNodeB [label="S1-AP"];
|
||||
|
||||
BTS -> UE [label="CBCH"];
|
||||
NodeB -> UE [label="BMC/CTCH"];
|
||||
eNodeB -> UE [label="SIB10/11/12"];
|
||||
|
||||
}
|
||||
@@ -12,6 +12,14 @@ include::{srcdir}/chapters/overview.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/running.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/configuration.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/introspection.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/ecbe-rest-interface.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/cbc-apitool.adoc[]
|
||||
|
||||
include::./common/chapters/counters-overview.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/counters.adoc[]
|
||||
|
||||
@@ -26,6 +26,7 @@ struct cbc_peer {
|
||||
|
||||
char *remote_host; /* remote IP address in string format */
|
||||
int remote_port; /* remote port number or -1 for random */
|
||||
bool unknown_dynamic_peer; /* dynamic/unknown peer; not saved in VTY */
|
||||
|
||||
enum cbc_peer_protocol proto;
|
||||
union {
|
||||
@@ -165,6 +166,14 @@ struct cbc_message {
|
||||
struct cbc {
|
||||
struct {
|
||||
bool permit_unknown_peers;
|
||||
struct {
|
||||
char *local_host;
|
||||
int local_port;
|
||||
} cbsp;
|
||||
struct {
|
||||
char *local_host;
|
||||
int local_port;
|
||||
} ecbe;
|
||||
} config;
|
||||
|
||||
struct llist_head messages; /* cbc_message.list */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Osmocom CBC (Cell Broacast Centre) */
|
||||
|
||||
/* (C) 2019 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2019-2021 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0+
|
||||
@@ -219,6 +219,10 @@ int main(int argc, char **argv)
|
||||
INIT_LLIST_HEAD(&g_cbc->peers);
|
||||
INIT_LLIST_HEAD(&g_cbc->messages);
|
||||
INIT_LLIST_HEAD(&g_cbc->expired_messages);
|
||||
g_cbc->config.cbsp.local_host = talloc_strdup(g_cbc, "127.0.0.1");
|
||||
g_cbc->config.cbsp.local_port = CBSP_TCP_PORT;
|
||||
g_cbc->config.ecbe.local_host = talloc_strdup(g_cbc, "127.0.0.1");
|
||||
g_cbc->config.ecbe.local_port = 12345;
|
||||
|
||||
cbc_vty_init();
|
||||
|
||||
@@ -240,9 +244,17 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cbsp_cbc_create(tall_cbc_ctx, NULL, -1, &cbc_client_rx_cb);
|
||||
if (cbsp_cbc_create(tall_cbc_ctx, g_cbc->config.cbsp.local_host, g_cbc->config.cbsp.local_port,
|
||||
&cbc_client_rx_cb) == NULL) {
|
||||
perror("Error binidng CBSP port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rest_api_init(tall_rest_ctx, 12345);
|
||||
rc = rest_api_init(tall_rest_ctx, g_cbc->config.ecbe.local_host, g_cbc->config.ecbe.local_port);
|
||||
if (rc < 0) {
|
||||
perror("Error binidng ECBE port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LOGP(DREST, LOGL_INFO, "Main thread tid: %lu\n", pthread_self());
|
||||
g_cbc->it_q.rest2main = osmo_it_q_alloc(g_cbc, "rest2main", 10, rest2main_read_cb, NULL);
|
||||
|
||||
112
src/cbc_vty.c
112
src/cbc_vty.c
@@ -1,6 +1,6 @@
|
||||
/* Osmocom CBC (Cell Broacast Centre) */
|
||||
|
||||
/* (C) 2019 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2019-2021 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0+
|
||||
@@ -267,6 +267,8 @@ DEFUN(show_messages_etws, show_messages_etws_cmd,
|
||||
enum cbc_vty_node {
|
||||
CBC_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
PEER_NODE,
|
||||
CBSP_NODE,
|
||||
ECBE_NODE,
|
||||
};
|
||||
|
||||
static struct cmd_node cbc_node = {
|
||||
@@ -310,6 +312,96 @@ static int config_write_cbc(struct vty *vty)
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_cbsp, cfg_cbsp_cmd,
|
||||
"cbsp",
|
||||
"Cell Broadcast Service Protocol\n")
|
||||
{
|
||||
vty->node = CBSP_NODE;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_ecbe, cfg_ecbe_cmd,
|
||||
"ecbe",
|
||||
"External CBS Entity (REST Interface)\n")
|
||||
{
|
||||
vty->node = ECBE_NODE;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* CBSP */
|
||||
|
||||
static struct cmd_node cbsp_node = {
|
||||
CBSP_NODE,
|
||||
"%s(config-cbsp)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
static int config_write_cbsp(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, " cbsp%s", VTY_NEWLINE);
|
||||
vty_out(vty, " local-ip %s%s", g_cbc->config.cbsp.local_host, VTY_NEWLINE);
|
||||
vty_out(vty, " local-port %u%s", g_cbc->config.cbsp.local_port, VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_cbsp_local_ip, cfg_cbsp_local_ip_cmd,
|
||||
"local-ip (A.B.C.D|X:X::X:X)",
|
||||
"Local IP address for CBSP\n"
|
||||
"Local IPv4 address for CBSP\n" "Local IPv6 address for CBSP\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cbc, &g_cbc->config.cbsp.local_host, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_cbsp_local_port, cfg_cbsp_local_port_cmd,
|
||||
"local-port <0-65535>",
|
||||
"Local TCP port for CBSP\n"
|
||||
"Local TCP port for CBSP\n")
|
||||
{
|
||||
g_cbc->config.cbsp.local_port = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* ECBE */
|
||||
|
||||
static struct cmd_node ecbe_node = {
|
||||
ECBE_NODE,
|
||||
"%s(config-ecbe)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
static int config_write_ecbe(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, " ecbe%s", VTY_NEWLINE);
|
||||
vty_out(vty, " local-ip %s%s", g_cbc->config.ecbe.local_host, VTY_NEWLINE);
|
||||
vty_out(vty, " local-port %u%s", g_cbc->config.ecbe.local_port, VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_ecbe_local_ip, cfg_ecbe_local_ip_cmd,
|
||||
"local-ip (A.B.C.D|X:X::X:X)",
|
||||
"Local IP address for CBSP\n"
|
||||
"Local IPv4 address for ECBE REST Interface\n"
|
||||
"Local IPv6 address for ECBE REST Interface\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cbc, &g_cbc->config.ecbe.local_host, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_ecbe_local_port, cfg_ecbe_local_port_cmd,
|
||||
"local-port <0-65535>",
|
||||
"Local TCP port for ECBE RESET Interface\n"
|
||||
"Local TCP port for ECBE RESET Interface\n")
|
||||
{
|
||||
g_cbc->config.ecbe.local_port = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* PEER */
|
||||
|
||||
DEFUN(cfg_cbc_peer, cfg_cbc_peer_cmd,
|
||||
@@ -377,7 +469,7 @@ DEFUN(cfg_peer_no_remote_port, cfg_peer_no_remote_port_cmd,
|
||||
|
||||
|
||||
DEFUN(cfg_peer_remote_ip, cfg_peer_remote_ip_cmd,
|
||||
"remote-ip A.B.C.D",
|
||||
"remote-ip (A.B.C.D|X:X::X:X)",
|
||||
"Configure remote IP of peer\n"
|
||||
"Remote IP address of peer\n")
|
||||
{
|
||||
@@ -402,8 +494,12 @@ static void write_one_peer(struct vty *vty, struct cbc_peer *peer)
|
||||
static int config_write_peer(struct vty *vty)
|
||||
{
|
||||
struct cbc_peer *peer;
|
||||
llist_for_each_entry(peer, &g_cbc->peers, list)
|
||||
llist_for_each_entry(peer, &g_cbc->peers, list) {
|
||||
/* only save those configured via the VTY, not the "unknown" peers */
|
||||
if (peer->unknown_dynamic_peer)
|
||||
continue;
|
||||
write_one_peer(vty, peer);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -418,6 +514,16 @@ void cbc_vty_init(void)
|
||||
install_node(&cbc_node, config_write_cbc);
|
||||
install_lib_element(CBC_NODE, &cfg_permit_unknown_peers_cmd);
|
||||
|
||||
install_lib_element(CBC_NODE, &cfg_cbsp_cmd);
|
||||
install_node(&cbsp_node, config_write_cbsp);
|
||||
install_lib_element(CBSP_NODE, &cfg_cbsp_local_ip_cmd);
|
||||
install_lib_element(CBSP_NODE, &cfg_cbsp_local_port_cmd);
|
||||
|
||||
install_lib_element(CBC_NODE, &cfg_ecbe_cmd);
|
||||
install_node(&ecbe_node, config_write_ecbe);
|
||||
install_lib_element(ECBE_NODE, &cfg_ecbe_local_ip_cmd);
|
||||
install_lib_element(ECBE_NODE, &cfg_ecbe_local_port_cmd);
|
||||
|
||||
install_lib_element(CBC_NODE, &cfg_cbc_peer_cmd);
|
||||
install_lib_element(CBC_NODE, &cfg_cbc_no_peer_cmd);
|
||||
install_node(&peer_node, config_write_peer);
|
||||
|
||||
@@ -150,6 +150,7 @@ static int cbsp_cbc_accept_cb(struct osmo_stream_srv_link *link, int fd)
|
||||
remote_ip, remote_port);
|
||||
client->peer = cbc_peer_create(NULL, CBC_PEER_PROTO_CBSP);
|
||||
OSMO_ASSERT(client->peer);
|
||||
client->peer->unknown_dynamic_peer = true;
|
||||
} else {
|
||||
LOGPCC(client, LOGL_NOTICE, "Rejecting unknown CBSP peer %s:%d (not permitted)\n",
|
||||
remote_ip, remote_port);
|
||||
|
||||
@@ -26,13 +26,40 @@
|
||||
|
||||
#include "charset.h"
|
||||
|
||||
/* pad the entire "remainder" of a buffer with repeated instances of the given pad character */
|
||||
static void pad_with_septets(uint8_t *buf, size_t buf_len, int num_septets, char pad_char)
|
||||
{
|
||||
unsigned int bit_offset;
|
||||
|
||||
for (bit_offset = num_septets * 7; bit_offset + 7 <= buf_len * 8; bit_offset += 7) {
|
||||
unsigned int byte_offset = bit_offset / 8;
|
||||
unsigned int bits = bit_offset % 8;
|
||||
|
||||
/* put one more septet */
|
||||
buf[byte_offset] |= ((pad_char << bits) & 0xff);
|
||||
if (bits > 1)
|
||||
buf[byte_offset+1] = (pad_char) >> (8-bits);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* return number of output bytes written */
|
||||
int charset_utf8_to_gsm7(uint8_t *out, size_t out_len, const char *in, size_t in_len)
|
||||
{
|
||||
int octets;
|
||||
int octets, num_septets, num_bits, num_bytes_used;
|
||||
|
||||
/* FIXME: implement this for 'escape' characters outside 7bit alphabet */
|
||||
gsm_7bit_encode_n_ussd(out, out_len, in, &octets);
|
||||
return octets;
|
||||
num_septets = gsm_7bit_encode_n(out, out_len, in, &octets);
|
||||
num_bits = num_septets * 7;
|
||||
|
||||
/* we need to pad the entire remainder of the message with <CR> */
|
||||
pad_with_septets(out, out_len, num_septets, '\r');
|
||||
|
||||
/* return actual number of output octets used, excluding any padding */
|
||||
num_bytes_used = num_bits/8;
|
||||
if (num_bits % 8)
|
||||
num_bytes_used++;
|
||||
return num_bytes_used;
|
||||
}
|
||||
|
||||
/* return number of output bytes written */
|
||||
|
||||
@@ -25,7 +25,7 @@ enum cbsp_server_event {
|
||||
|
||||
|
||||
/* rest_api.c */
|
||||
int rest_api_init(void *ctx, uint16_t port);
|
||||
int rest_api_init(void *ctx, const char *bind_addr, uint16_t port);
|
||||
void rest_api_fin(void);
|
||||
|
||||
/* cbc_vty.c */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Osmocom CBC (Cell Broacast Centre) */
|
||||
|
||||
/* (C) 2019-2020 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2019-2021 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0+
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
|
||||
#include <osmocom/gsm/protocol/gsm_48_049.h>
|
||||
|
||||
@@ -677,27 +678,48 @@ static void my_o_free(void *obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
int rest_api_init(void *ctx, uint16_t port)
|
||||
int rest_api_init(void *ctx, const char *bind_addr, uint16_t port)
|
||||
{
|
||||
struct osmo_sockaddr_str sastr;
|
||||
int i;
|
||||
|
||||
#ifdef ULFIUS_MALLOC_NOT_BROKEN
|
||||
/* See https://github.com/babelouest/ulfius/issues/63 */
|
||||
g_tall_rest = ctx;
|
||||
o_set_alloc_funcs(my_o_malloc, my_o_realloc, my_o_free);
|
||||
#endif
|
||||
|
||||
if (ulfius_init_instance(&g_instance, port, NULL, NULL) != U_OK)
|
||||
return -1;
|
||||
OSMO_STRLCPY_ARRAY(sastr.ip, bind_addr);
|
||||
sastr.port = port;
|
||||
|
||||
if (strchr(bind_addr, ':')) {
|
||||
#if (ULFIUS_VERSION_MAJOR > 2) || (ULFIUS_VERSION_MAJOR == 2) && (ULFIUS_VERSION_MINOR >= 6)
|
||||
struct sockaddr_in6 sin6;
|
||||
sastr.af = AF_INET6;
|
||||
osmo_sockaddr_str_to_sockaddr_in6(&sastr, &sin6);
|
||||
if (ulfius_init_instance_ipv6(&g_instance, port, &sin6, U_USE_IPV6, NULL) != U_OK)
|
||||
return -1;
|
||||
#else
|
||||
LOGP(DREST, LOGL_FATAL, "IPv6 requires ulfius version >= 2.6\n");
|
||||
return -2;
|
||||
#endif
|
||||
} else {
|
||||
struct sockaddr_in sin;
|
||||
sastr.af = AF_INET;
|
||||
osmo_sockaddr_str_to_sockaddr_in(&sastr, &sin);
|
||||
if (ulfius_init_instance(&g_instance, port, &sin, NULL) != U_OK)
|
||||
return -1;
|
||||
}
|
||||
g_instance.mhd_response_copy_data = 1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(api_endpoints); i++)
|
||||
ulfius_add_endpoint(&g_instance, &api_endpoints[i]);
|
||||
|
||||
if (ulfius_start_framework(&g_instance) != U_OK) {
|
||||
LOGP(DREST, LOGL_FATAL, "Cannot start REST API on port %u\n", port);
|
||||
LOGP(DREST, LOGL_FATAL, "Cannot start ECBE REST API at %s:%u\n", bind_addr, port);
|
||||
return -1;
|
||||
}
|
||||
LOGP(DREST, LOGL_NOTICE, "Started REST API on port %u\n", port);
|
||||
LOGP(DREST, LOGL_NOTICE, "Started ECBE REST API at %s:%u\n", bind_addr, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user