mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-cbc.git
				synced 2025-10-31 12:13:52 +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/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 | ||||
| @@ -168,6 +168,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(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 | ||||
| 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 | ||||
							
								
								
									
										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. | ||||
|   * 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[] | ||||
|   | ||||
| @@ -165,6 +165,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); | ||||
|   | ||||
							
								
								
									
										106
									
								
								src/cbc_vty.c
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								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") | ||||
| { | ||||
| @@ -418,6 +510,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); | ||||
|   | ||||
| @@ -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