mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-cbc.git
synced 2025-11-04 14:13:48 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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/common
|
||||||
doc/manuals/build
|
doc/manuals/build
|
||||||
doc/manuals/vty/cbc_vty_reference.xml
|
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
|
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
|
||||||
SUBDIRS = src doc contrib tests
|
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 = \
|
AM_DISTCHECK_CONFIGURE_FLAGS = \
|
||||||
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
|
--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
|
||||||
@@ -168,6 +168,7 @@ AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
|
|||||||
AC_OUTPUT(
|
AC_OUTPUT(
|
||||||
src/Makefile
|
src/Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
|
contrib/osmo-cbc.spec
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
doc/examples/Makefile
|
doc/examples/Makefile
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
SUBDIRS = systemd
|
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(required=True)
|
||||||
|
|
||||||
|
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
|
# Additional configure options and depends
|
||||||
CONFIG=""
|
CONFIG=""
|
||||||
if [ "$WITH_MANUALS" = "1" ]; then
|
if [ "$WITH_MANUALS" = "1" ]; then
|
||||||
osmo-build-dep.sh osmo-gsm-manuals
|
|
||||||
CONFIG="--enable-manuals"
|
CONFIG="--enable-manuals"
|
||||||
fi
|
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
|
||||||
32
debian/changelog
vendored
32
debian/changelog
vendored
@@ -1,5 +1,33 @@
|
|||||||
osmo-cbc (0.1) UNRELEASED; urgency=medium
|
osmo-cbc (0.2.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
* Initial release.
|
* 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}
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
Description: OsmoCBC: Osmocom's Cell Broadcast Center
|
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
|
Package: osmo-cbc-dbg
|
||||||
Section: debug
|
Section: debug
|
||||||
Architecture: any
|
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
|
/etc/osmocom/osmo-cbc.cfg
|
||||||
lib/systemd/system/osmo-cbc.service
|
lib/systemd/system/osmo-cbc.service
|
||||||
usr/bin/osmo-cbc
|
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)
|
dh_auto_configure -- $(CONFIGURE_FLAGS)
|
||||||
#
|
#
|
||||||
# Do not install libtool archive, python .pyc .pyo
|
# Do not install libtool archive, python .pyc .pyo
|
||||||
#override_dh_install:
|
override_dh_install:
|
||||||
# dh_install --list-missing -X.la -X.pyc -X.pyo
|
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
|
# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
|
||||||
override_dh_strip:
|
override_dh_strip:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ EXTRA_DIST = osmocbc-usermanual.adoc \
|
|||||||
osmocbc-vty-reference.xml \
|
osmocbc-vty-reference.xml \
|
||||||
regen_doc.sh \
|
regen_doc.sh \
|
||||||
chapters \
|
chapters \
|
||||||
|
images \
|
||||||
vty
|
vty
|
||||||
|
|
||||||
if BUILD_MANUALS
|
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
|
authorities for civil protection, and the various components within the 3GPP
|
||||||
network to actually deliver those broadcast and/or emergency messages.
|
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]]
|
||||||
=== About OsmoCBC
|
=== 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
|
the CBC doesn't need to know each and every BSC in the network. It
|
||||||
simply only accepts incoming CBSP connections.
|
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
|
3GPP does not specify the external interface by which competent
|
||||||
`cbc.schema.json` and `smscb.schema.json`, which are part of the OsmoCBC
|
authorities can submit SMSCB and/or ETWS messages to a CBC.
|
||||||
distribution.
|
|
||||||
|
|
||||||
The REST interface currently binds to TCP port 12345 (on INADRR_ANY) and
|
Hence, a non-standard, Osmocom specific HTTP/REST/JSON based interface
|
||||||
can be reached at http://localhost:1234/api/ecbe/v1"
|
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
|
For more information, see <<ecbe>> on the ECBE API definition and <<config-ecbe>>
|
||||||
interface endpoint to ensure only legitimate users can access it. This
|
on how it is configured.
|
||||||
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.
|
|
||||||
|
|||||||
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/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::./common/chapters/counters-overview.adoc[]
|
||||||
|
|
||||||
include::{srcdir}/chapters/counters.adoc[]
|
include::{srcdir}/chapters/counters.adoc[]
|
||||||
|
|||||||
@@ -165,6 +165,14 @@ struct cbc_message {
|
|||||||
struct cbc {
|
struct cbc {
|
||||||
struct {
|
struct {
|
||||||
bool permit_unknown_peers;
|
bool permit_unknown_peers;
|
||||||
|
struct {
|
||||||
|
char *local_host;
|
||||||
|
int local_port;
|
||||||
|
} cbsp;
|
||||||
|
struct {
|
||||||
|
char *local_host;
|
||||||
|
int local_port;
|
||||||
|
} ecbe;
|
||||||
} config;
|
} config;
|
||||||
|
|
||||||
struct llist_head messages; /* cbc_message.list */
|
struct llist_head messages; /* cbc_message.list */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Osmocom CBC (Cell Broacast Centre) */
|
/* 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
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0+
|
* 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->peers);
|
||||||
INIT_LLIST_HEAD(&g_cbc->messages);
|
INIT_LLIST_HEAD(&g_cbc->messages);
|
||||||
INIT_LLIST_HEAD(&g_cbc->expired_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();
|
cbc_vty_init();
|
||||||
|
|
||||||
@@ -240,9 +244,17 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
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());
|
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);
|
g_cbc->it_q.rest2main = osmo_it_q_alloc(g_cbc, "rest2main", 10, rest2main_read_cb, NULL);
|
||||||
|
|||||||
106
src/cbc_vty.c
106
src/cbc_vty.c
@@ -1,6 +1,6 @@
|
|||||||
/* Osmocom CBC (Cell Broacast Centre) */
|
/* 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
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0+
|
* SPDX-License-Identifier: AGPL-3.0+
|
||||||
@@ -267,6 +267,8 @@ DEFUN(show_messages_etws, show_messages_etws_cmd,
|
|||||||
enum cbc_vty_node {
|
enum cbc_vty_node {
|
||||||
CBC_NODE = _LAST_OSMOVTY_NODE + 1,
|
CBC_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||||
PEER_NODE,
|
PEER_NODE,
|
||||||
|
CBSP_NODE,
|
||||||
|
ECBE_NODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cmd_node cbc_node = {
|
static struct cmd_node cbc_node = {
|
||||||
@@ -310,6 +312,96 @@ static int config_write_cbc(struct vty *vty)
|
|||||||
return CMD_SUCCESS;
|
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 */
|
/* PEER */
|
||||||
|
|
||||||
DEFUN(cfg_cbc_peer, cfg_cbc_peer_cmd,
|
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,
|
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"
|
"Configure remote IP of peer\n"
|
||||||
"Remote IP address of peer\n")
|
"Remote IP address of peer\n")
|
||||||
{
|
{
|
||||||
@@ -418,6 +510,16 @@ void cbc_vty_init(void)
|
|||||||
install_node(&cbc_node, config_write_cbc);
|
install_node(&cbc_node, config_write_cbc);
|
||||||
install_lib_element(CBC_NODE, &cfg_permit_unknown_peers_cmd);
|
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_peer_cmd);
|
||||||
install_lib_element(CBC_NODE, &cfg_cbc_no_peer_cmd);
|
install_lib_element(CBC_NODE, &cfg_cbc_no_peer_cmd);
|
||||||
install_node(&peer_node, config_write_peer);
|
install_node(&peer_node, config_write_peer);
|
||||||
|
|||||||
@@ -26,13 +26,40 @@
|
|||||||
|
|
||||||
#include "charset.h"
|
#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 */
|
/* 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 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 */
|
/* FIXME: implement this for 'escape' characters outside 7bit alphabet */
|
||||||
gsm_7bit_encode_n_ussd(out, out_len, in, &octets);
|
num_septets = gsm_7bit_encode_n(out, out_len, in, &octets);
|
||||||
return 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 */
|
/* return number of output bytes written */
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ enum cbsp_server_event {
|
|||||||
|
|
||||||
|
|
||||||
/* rest_api.c */
|
/* 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);
|
void rest_api_fin(void);
|
||||||
|
|
||||||
/* cbc_vty.c */
|
/* cbc_vty.c */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Osmocom CBC (Cell Broacast Centre) */
|
/* 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
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0+
|
* SPDX-License-Identifier: AGPL-3.0+
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
#include <osmocom/core/sockaddr_str.h>
|
||||||
|
|
||||||
#include <osmocom/gsm/protocol/gsm_48_049.h>
|
#include <osmocom/gsm/protocol/gsm_48_049.h>
|
||||||
|
|
||||||
@@ -677,27 +678,48 @@ static void my_o_free(void *obj)
|
|||||||
}
|
}
|
||||||
#endif
|
#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;
|
int i;
|
||||||
|
|
||||||
#ifdef ULFIUS_MALLOC_NOT_BROKEN
|
#ifdef ULFIUS_MALLOC_NOT_BROKEN
|
||||||
|
/* See https://github.com/babelouest/ulfius/issues/63 */
|
||||||
g_tall_rest = ctx;
|
g_tall_rest = ctx;
|
||||||
o_set_alloc_funcs(my_o_malloc, my_o_realloc, my_o_free);
|
o_set_alloc_funcs(my_o_malloc, my_o_realloc, my_o_free);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ulfius_init_instance(&g_instance, port, NULL, NULL) != U_OK)
|
OSMO_STRLCPY_ARRAY(sastr.ip, bind_addr);
|
||||||
return -1;
|
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;
|
g_instance.mhd_response_copy_data = 1;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(api_endpoints); i++)
|
for (i = 0; i < ARRAY_SIZE(api_endpoints); i++)
|
||||||
ulfius_add_endpoint(&g_instance, &api_endpoints[i]);
|
ulfius_add_endpoint(&g_instance, &api_endpoints[i]);
|
||||||
|
|
||||||
if (ulfius_start_framework(&g_instance) != U_OK) {
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user