Browse Source

Drop osmo-hnbgw

OsmoHNBGW is now available in its own repository osmo-hnbgw.git.

Change-Id: I4e17c578b432f0c997ea4e13b1c468b112278854
changes/70/26770/2
Pau Espin 7 months ago
parent
commit
e91b57d963
  1. 2
      Makefile.am
  2. 12
      README.md
  3. 4
      configure.ac
  4. 1
      contrib/Makefile.am
  5. 13
      contrib/osmo-iuh.spec.in
  6. 6
      contrib/systemd/Makefile.am
  7. 11
      contrib/systemd/osmo-hnbgw.service
  8. 24
      debian/control
  9. 4
      debian/osmo-hnbgw.install
  10. 1
      debian/rules
  11. 3
      doc/Makefile.am
  12. 27
      doc/examples/Makefile.am
  13. 25
      doc/examples/osmo-hnbgw.cfg
  14. 25
      doc/manuals/Makefile.am
  15. 56
      doc/manuals/chapters/overview.adoc
  16. 119
      doc/manuals/chapters/running.adoc
  17. 51
      doc/manuals/osmohnbgw-usermanual-docinfo.xml
  18. 37
      doc/manuals/osmohnbgw-usermanual.adoc
  19. 38
      doc/manuals/osmohnbgw-vty-reference.xml
  20. 17
      doc/manuals/regen_doc.sh
  21. 2
      doc/manuals/vty/hnbgw_vty_additions.xml
  22. 60
      doc/protocols_around_hnbgw.txt
  23. 4
      include/osmocom/iuh/Makefile.am
  24. 51
      include/osmocom/iuh/context_map.h
  25. 174
      include/osmocom/iuh/hnbgw.h
  26. 5
      include/osmocom/iuh/hnbgw_cn.h
  27. 6
      include/osmocom/iuh/hnbgw_hnbap.h
  28. 6
      include/osmocom/iuh/hnbgw_ranap.h
  29. 13
      include/osmocom/iuh/hnbgw_rua.h
  30. 11
      include/osmocom/iuh/vty.h
  31. 14
      src/Makefile.am
  32. 181
      src/context_map.c
  33. 698
      src/hnbgw.c
  34. 559
      src/hnbgw_cn.c
  35. 632
      src/hnbgw_hnbap.c
  36. 210
      src/hnbgw_ranap.c
  37. 566
      src/hnbgw_rua.c
  38. 418
      src/hnbgw_vty.c

2
Makefile.am

@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2
SUBDIRS = src include doc contrib
SUBDIRS = src include doc
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libosmo-hnbap.pc libosmo-ranap.pc libosmo-rua.pc libosmo-sabp.pc

12
README.md

@ -1,10 +1,9 @@
osmo-iuh - Osmocom Iuh and HNB-GW implementation
osmo-iuh - Osmocom Iuh implementation
================================================
This repository contains a C-language implementation of the 3GPP Iuh
interface, together with a HNB-GW (Home NodeB Gateway). You can use it
to interface Iuh-speaking femtocells/small cells to Iu-speaking MSCs and
SGSNs.
interface. You can use it to interface Iuh-speaking femtocells/small cells to
Iu-speaking MSCs and SGSNs.
It is part of the [Osmocom](https://osmocom.org/) Open Source Mobile
Communications project.
@ -87,11 +86,6 @@ Using
Note: osmo-iuh just left very active development (December 2015, January
2016), so your mileage may vary.
If you run the 'hnbgw' executable, it will open a listening SCTP socket
and wait for incoming Iuh connections. It will accept any
HNB-REGISTER-REQUEST, and it will establish Iu (over SUA) connections
towards the MSC and SGSN.
Regenerating C code from ASN.1 source
-------------------------------------

4
configure.ac

@ -169,9 +169,5 @@ AC_OUTPUT(
include/osmocom/sabp/Makefile
include/osmocom/iuh/Makefile
doc/Makefile
doc/examples/Makefile
doc/manuals/Makefile
contrib/Makefile
contrib/systemd/Makefile
contrib/osmo-iuh.spec
)

1
contrib/Makefile.am

@ -1 +0,0 @@
SUBDIRS = systemd

13
contrib/osmo-iuh.spec.in

@ -138,22 +138,9 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%post -n libosmo-sabp1 -p /sbin/ldconfig
%postun -n libosmo-sabp1 -p /sbin/ldconfig
%if 0%{?suse_version}
%pre %service_add_pre osmo-hnbgw.service
%post %service_add_post osmo-hnbgw.service
%preun %service_del_preun osmo-hnbgw.service
%postun %service_del_postun osmo-hnbgw.service
%endif
%files
%license COPYING
%doc README.md
%dir %{_docdir}/%{name}/examples
%{_docdir}/%{name}/examples/osmo-hnbgw.cfg
%{_bindir}/osmo-hnbgw
%dir %{_sysconfdir}/osmocom
%config %{_sysconfdir}/osmocom/osmo-hnbgw.cfg
%{_unitdir}/osmo-hnbgw.service
%files -n libosmo-hnbap0
%{_libdir}/libosmo-hnbap.so.0*

6
contrib/systemd/Makefile.am

@ -1,6 +0,0 @@
EXTRA_DIST = osmo-hnbgw.service
if HAVE_SYSTEMD
systemdsystemunit_DATA = \
osmo-hnbgw.service
endif

11
contrib/systemd/osmo-hnbgw.service

@ -1,11 +0,0 @@
[Unit]
Description=Osmocom Home Nodeb Gateway (OsmoHNBGW)
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/osmo-hnbgw -c /etc/osmocom/osmo-hnbgw.cfg
RestartSec=2
[Install]
WantedBy=multi-user.target

24
debian/control vendored

@ -21,30 +21,6 @@ Vcs-Git: git://git.osmocom.org/osmo-iuh.git
Vcs-Browser: https://git.osmocom.org/osmo-iuh/
Homepage: https://projects.osmocom.org/projects/osmohnbgw
Package: osmo-hnbgw
Section: net
Architecture: any
Multi-Arch: no
Pre-Depends: ${misc:Pre-Depends}
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: osmocom Home Node B Gateway
Package: osmo-hnbgw-dbg
Section: debug
Architecture: any
Multi-Arch: no
Pre-Depends: ${misc:Pre-Depends}
Depends: osmo-hnbgw (= ${binary:Version}), ${misc:Depends}
Description: osmocom Home Node B Gateway
Package: osmo-hnbgw-doc
Section: doc
Architecture: all
Depends: ${misc:Depends}
Description: ${misc:Package} PDF documentation
Various manuals: user manual, VTY reference manual and/or
protocol/interface manuals.
Package: libosmo-hnbap0
Section: libs
Architecture: any

4
debian/osmo-hnbgw.install vendored

@ -1,4 +0,0 @@
etc/osmocom/osmo-hnbgw.cfg
lib/systemd/system/osmo-hnbgw.service
usr/bin/osmo-hnbgw
usr/share/doc/osmo-iuh/examples/osmo-hnbgw.cfg

1
debian/rules vendored

@ -18,7 +18,6 @@ override_dh_strip:
dh_strip -plibosmo-ranap5 --dbg-package=libosmo-ranap-dbg
dh_strip -plibosmo-rua0 --dbg-package=libosmo-rua-dbg
dh_strip -plibosmo-sabp1 --dbg-package=libosmo-sabp-dbg
dh_strip -posmo-hnbgw --dbg-package=osmo-hnbgw-dbg
# Print test results in case of a failure
override_dh_auto_test:

3
doc/Makefile.am

@ -1,6 +1,4 @@
SUBDIRS = \
examples \
manuals \
$(NULL)
EXTRA_DIST = \
@ -11,5 +9,4 @@ EXTRA_DIST = \
hnb_cs_mt_sms.msc \
hnb_ps_lu.msc \
hnb_ps_pdp_act.msc \
protocols_around_hnbgw.txt \
README

27
doc/examples/Makefile.am

@ -1,27 +0,0 @@
osmoconfdir = $(sysconfdir)/osmocom
osmoconf_DATA = osmo-hnbgw.cfg
EXTRA_DIST = osmo-hnbgw.cfg
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
dist-hook:
for f in $$($(CFG_FILES)); do \
j="$(distdir)/$$f" && \
mkdir -p "$$(dirname $$j)" && \
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
done
install-data-hook:
for f in $$($(CFG_FILES)); do \
j="$(DESTDIR)$(docdir)/examples/$$f" && \
mkdir -p "$$(dirname $$j)" && \
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
done
uninstall-hook:
@$(PRE_UNINSTALL)
for f in $$($(CFG_FILES)); do \
j="$(DESTDIR)$(docdir)/examples/$$f" && \
$(RM) $$j; \
done

25
doc/examples/osmo-hnbgw.cfg

@ -1,25 +0,0 @@
!
! OsmoHNBGW (0) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 1
logging timestamp 1
logging print extended-timestamp 1
logging level all debug
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp notice
logging level lstats notice
hnbgw
iuh
local-ip 0.0.0.0
hnbap-allow-tmsi 1

25
doc/manuals/Makefile.am

@ -1,25 +0,0 @@
EXTRA_DIST = \
osmohnbgw-usermanual.adoc \
osmohnbgw-usermanual-docinfo.xml \
chapters \
osmohnbgw-vty-reference.xml \
regen_doc.sh \
vty
if BUILD_MANUALS
ASCIIDOC = osmohnbgw-usermanual.adoc
ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
VTY_REFERENCE = osmohnbgw-vty-reference.xml
BUILT_REFERENCE_XML = $(builddir)/vty/hnbgw_vty_reference.xml
$(builddir)/vty/hnbgw_vty_reference.xml: $(top_builddir)/src/osmo-hnbgw
mkdir -p $(builddir)/vty
$(top_builddir)/src/osmo-hnbgw --vty-ref-xml > $@
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
OSMO_REPOSITORY = osmo-hnbgw
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
endif

56
doc/manuals/chapters/overview.adoc

@ -1,56 +0,0 @@
[[overview]]
== Overview
[[intro_overview]]
=== About OsmoHNBGW
OsmoHNBGW implements the Home NodeB Gateway function in the 3G network architecture. It serves
as a gateway between the classic 3G core network (CN) domain with its IuCS and IuPS interface
and the femtocell based RAN.
A typical 3G network consisting of Osmocom components will look as illustrated in the following
diagram:
[[fig-3g]]
.Typical 3G network architecture used with OsmoHNBGW
----
+------------+ +--------+ +----------+ +---------+
UE <-->| hNodeB |<--Iuh---->| HNB-GW |<--IuCS-->| OsmoMSC |<--GSUP-->| OsmoHLR |
UE <-->| femto cell | ...-->| | ...-->| | | |
| | | | +----------+ +---------|
+------------+<--GTP-U | |
\ | | +------+ +------+
| | |<--IuPS-->| SGSN |<--GTP-C-->| GGSN |
| +--------+ ...-->| | GTP-U-->| |
| +------+ / +------+
\_______________________________/
----
The HNB-GW performs a translation interface between the IuCS/IuPS interfaces on the one hand
side, and the Iuh interface on the or ther hand:
----
Iuh IuCS/IuPS
NAS +----+----+ +----+----+
Non-Access Stratum | CC | MM | | CC | MM |
- - - - - - - - - - - +----+----+-------+ +----+----+
| RANAP | | H | RANAP |
Access Stratum +---------+ HNBAP | N +---------+ - - SCCP USER SAP
| RUA | | B | SUA | \
+---------+-------+ - +---------+ |
| SCTP | G | SCTP | } SIGTRAN
+-----------------+ W +---------+ |
| IP | | IP | /
+-----------------+ +---------+
----
On the femtocell (Home NodeB) side, OsmoHNBGW implements the Iuh interface as specified by 3GPP.
=== The Iuh interface
Iuh consists of the following sub-layers:
- HNBAP (Home NodeB Application Part)
- RUA (RANAP User Adaptation, between RANAP and SCTP

119
doc/manuals/chapters/running.adoc

@ -1,119 +0,0 @@
== Running OsmoHNBGW
The OsmoHNBGW executable (`osmo-hnbgw`) offers the following command-line
arguments:
=== SYNOPSIS
*osmo-hnbgw* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-T] [-e 'LOGLEVEL']
=== OPTIONS
*-h, --help*::
Print a short help message about the supported options
*-V, --version*::
Print the compile-time version number of the OsmoHNBGW program
*-d, --debug 'DBGMASK','DBGLEVELS'*::
Set the log subsystems and levels for logging to stderr. This
has mostly been superseded by VTY-based logging configuration,
see <<logging>> for further information.
*-D, --daemonize*::
Fork the process as a daemon into background.
*-c, --config-file 'CONFIGFILE'*::
Specify the file and path name of the configuration file to be
used. If none is specified, use `osmo-msc.cfg` in the current
working directory.
*-s, --disable-color*::
Disable colors for logging to stderr. This has mostly been
deprecated by VTY based logging configuration, see <<logging>>
for more information.
*-T, --timestamp*::
Enable time-stamping of log messages to stderr. This has mostly
been deprecated by VTY based logging configuration, see
<<logging>> for more information.
*-e, --log-level 'LOGLEVEL'*::
Set the global log level for logging to stderr. This has mostly
been deprecated by VTY based logging configuration, see
<<logging>> for more information.
=== Multiple instances
Running multiple instances of `osmo-hnbgw` on the same computer is possible if
all interfaces (VTY, CTRL, Iuh) are separated using the appropriate
configuration options. The IP based interfaces are binding to local host by
default. In order to separate the processes, the user has to bind those
services to specific but different IP addresses and/or ports.
The VTY and the Control interface can be bound to IP addresses from the loopback
address range, for example:
----
line vty
bind 127.0.0.2
ctrl
bind 127.0.0.2
----
The Iuh interface can be bound to an individual port:
----
hnbgw
iuh
local-ip 0.0.0.0
local-port 29169
----
For the following links, OsmoHNBGW acts as a client and does not listen/bind to a
specific interface, and will hence not encounter conflicts for multiple instances
running on the same interface:
- The SCCP/M3UA links are established by OsmoHNBGW contacting an STP.
To run multiple OsmoHNBGW instances on the same SCCP routing, each HNBGW has to
configure a distinct point-code, see <<configure_iucs_iups>>.
=== Configuring Primary Links
[[configure_iucs_iups]]
==== Configure SCCP/M3UA to connect to an MSC's _IuCS_ and an SGSN's _IuPS_ interface
OsmoHNBGW acts as client to contact an STP instance and establish an SCCP/M3UA
link.
An example configuration of OsmoHNBGW's SCCP link:
----
cs7 instance 0
point-code 0.23.5
asp asp-clnt-OsmoHNBGW 2905 0 m3ua
remote-ip 127.0.0.1
sctp-role client
sccp-address msc
routing-indicator PC
point-code 0.23.1
sccp-address sgsn
routing-indicator PC
point-code 0.23.2
hnbgw
iucs
remote-addr msc
iups
remote-addr sgsn
----
This configuration is explained in detail in <<cs7_config>>.
==== Configure RUA to accept Iuh connections from hNodeB
OsmoHNBGW acts as server to accept Iuh connections from hNodeB devices.
An example configuration for OsmoHNBGW's RUA server:
----
hnbgw
iuh
local-ip 10.9.8.7
local-port 29169
----

51
doc/manuals/osmohnbgw-usermanual-docinfo.xml

@ -1,51 +0,0 @@
<revhistory>
<revision>
<revnumber>1</revnumber>
<date>November 30th, 2019</date>
<authorinitials>HW</authorinitials>
<revremark>
Initial version
</revremark>
</revision>
</revhistory>
<authorgroup>
<author>
<firstname>Harald</firstname>
<surname>Welte</surname>
<email>hwelte@sysmocom.de</email>
<authorinitials>HW</authorinitials>
<affiliation>
<shortaffil>sysmocom</shortaffil>
<orgname>sysmocom - s.f.m.c. GmbH</orgname>
<jobtitle>Managing Director</jobtitle>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2019</year>
<holder>sysmocom - s.f.m.c. GmbH</holder>
</copyright>
<legalnotice>
<para>
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.3 or any later version published by the Free Software
Foundation; with the Invariant Sections being just 'Foreword',
'Acknowledgements' and 'Preface', with no Front-Cover Texts,
and no Back-Cover Texts. A copy of the license is included in
the section entitled "GNU Free Documentation License".
</para>
<para>
The Asciidoc source code of this manual can be found at
<ulink url="http://git.osmocom.org/osmo-hnbgw/">
http://git.osmocom.org/osmo-hnbgw/
</ulink>
and of the common chapters at
<ulink url="http://git.osmocom.org/osmo-gsm-manuals/">
http://git.osmocom.org/osmo-gsm-manuals/
</ulink>
</para>
</legalnotice>

37
doc/manuals/osmohnbgw-usermanual.adoc

@ -1,37 +0,0 @@
:gfdl-enabled:
:program-name: OsmoHNBGW
OsmoHNBGW User Manual
=====================
Harald Welte <hwelte@sysmocom.de>
include::./common/chapters/preface.adoc[]
include::{srcdir}/chapters/overview.adoc[]
include::{srcdir}/chapters/running.adoc[]
// include::{srcdir}/chapters/control.adoc[]
// include::./common/chapters/counters-overview.adoc[]
// include::{srcdir}/chapters/counters.adoc[]
include::./common/chapters/vty.adoc[]
include::./common/chapters/logging.adoc[]
include::./common/chapters/cs7-config.adoc[]
// include::{srcdir}/chapters/net.adoc[]
// include::./common/chapters/control_if.adoc[]
include::./common/chapters/port_numbers.adoc[]
include::./common/chapters/bibliography.adoc[]
include::./common/chapters/glossary.adoc[]
include::./common/chapters/gfdl.adoc[]

38
doc/manuals/osmohnbgw-vty-reference.xml

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
ex:ts=2:sw=42sts=2:et
-*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
<!ENTITY sections-vty SYSTEM "generated/docbook_vty.xml" >
]>
<book>
<info>
<revhistory>
<revision>
<revnumber>v1</revnumber>
<date>29th July 2019</date>
<authorinitials>dw</authorinitials>
<revremark>Initial</revremark>
</revision>
</revhistory>
<title>OsmoHNBGW VTY Reference</title>
<copyright>
<year>2019</year>
</copyright>
<legalnotice>
<para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
</para>
</legalnotice>
</info>
<!-- Main chapters-->
&chapter-vty;
</book>

17
doc/manuals/regen_doc.sh

@ -1,17 +0,0 @@
#!/bin/sh -x
if [ -z "$DOCKER_PLAYGROUND" ]; then
echo "You need to set DOCKER_PLAYGROUND"
exit 1
fi
SCRIPT=$(realpath "$0")
MANUAL_DIR=$(dirname "$SCRIPT")
COMMIT=${COMMIT:-$(git log -1 --format=format:%H)}
cd "$DOCKER_PLAYGROUND/scripts" || exit 1
OSMO_SGSN_BRANCH=$COMMIT ./regen_doc.sh osmo-hnbgw 4261 \
"$MANUAL_DIR/chapters/counters_generated.adoc" \
"$MANUAL_DIR/vty/hnbgw_vty_reference.xml"

2
doc/manuals/vty/hnbgw_vty_additions.xml

@ -1,2 +0,0 @@
<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
</vtydoc>

60
doc/protocols_around_hnbgw.txt

@ -1,60 +0,0 @@
Protocols Around the Home Node B Gateway
========================================
+--------+
,-->| Osmo |
/ | MGCPGW |
| | |<--MGCP
| +--------+ \
/ |
+------------+<--RTP +--------+ `->+----------+
UE <-->| hNodeB | | Osmo | | OsmoMSC | +------+
UE <-->| femto cell |<--Iuh---->| HNB-GW |<--IuCS-->| | | Osmo |
| | | | | (VLR)|<-GSUP->| HLR |
| | | | +----------+ GSUP->+------+
+------------+<--GTP-U | | /
\ | | +------+<---' +------+
| | |<--IuPS-->| Osmo |<--GTP-C--->| Open |
| +--------+ | SGSN | GTP-U--->| GGSN |
| +------+ / +------+
\_______________________________/
Iuh IuCS/IuPS
NAS +----+----+ +----+----+
Non-Access Stratum | CC | MM | | CC | MM |
- - - - - - - - - - - +----+----+-------+ +----+----+
| RANAP | | H | RANAP |
Access Stratum +---------+ HNBAP | N +---------+ - - SCCP USER SAP
| RUA | | B | SUA | \
+---------+-------+ - +---------+ |
| SCTP | G | SCTP | } SIGTRAN
+-----------------+ W +---------+ |
| IP | | IP | /
+-----------------+ +---------+
Various SIGTRAN implementations:
IuCS/IuPS
usual
| simplest
| |
v v
+------+------+------+-----+
| SCCP | SCCP | | |
+------+------+ SCCP | |
| MTP3 | MTP3 | | |
+------+------+------+ SUA |
| MTP2 | | | |
+------+ M2UA | M3UA | |
| M2PA | | | |
+------+------+------+-----+
| SCTP |
+--------------------------+
| IP |
+--------------------------+
UE (User Endpoint) == MS (Mobile Subscriber) == mobile device

4
include/osmocom/iuh/Makefile.am

@ -1,4 +1,2 @@
noinst_HEADERS = \
vty.h \
context_map.h hnbgw.h hnbgw_cn.h \
hnbgw_hnbap.h hnbgw_rua.h hnbgw_ranap.h
iu_common.h

51
include/osmocom/iuh/context_map.h

@ -1,51 +0,0 @@
#pragma once
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
enum hnbgw_context_map_state {
MAP_S_NULL,
MAP_S_ACTIVE, /* currently active map */
MAP_S_RESERVED1, /* just disconnected, still resrved */
MAP_S_RESERVED2, /* still reserved */
MAP_S_NUM_STATES /* Number of states, keep this at the end */
};
extern const struct value_string hnbgw_context_map_state_names[];
static inline const char *hnbgw_context_map_state_name(enum hnbgw_context_map_state val)
{ return get_value_string(hnbgw_context_map_state_names, val); }
struct hnb_context;
struct hnbgw_cnlink;
struct hnbgw_context_map {
/* entry in the per-CN list of mappings */
struct llist_head cn_list;
/* entry in the per-HNB list of mappings */
struct llist_head hnb_list;
/* pointer to HNB */
struct hnb_context *hnb_ctx;
/* pointer to CN */
struct hnbgw_cnlink *cn_link;
/* RUA contxt ID */
uint32_t rua_ctx_id;
/* False for CS, true for PS */
bool is_ps;
/* SCCP User SAP connection ID */
uint32_t scu_conn_id;
enum hnbgw_context_map_state state;
};
struct hnbgw_context_map *
context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
bool is_ps,
struct hnbgw_cnlink *cn_if_new);
struct hnbgw_context_map *
context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id);
void context_map_deactivate(struct hnbgw_context_map *map);
int context_map_init(struct hnb_gw *gw);

174
include/osmocom/iuh/hnbgw.h

@ -1,174 +0,0 @@
#pragma once
#include <osmocom/core/select.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/timer.h>
#include <osmocom/sigtran/sccp_sap.h>
#include <osmocom/sigtran/osmo_ss7.h>
#include <osmocom/ctrl/control_if.h>
#define DEBUG
#include <osmocom/core/logging.h>
enum {
DMAIN,
DHNBAP,
DRUA,
DRANAP,
};
#define LOGHNB(x, ss, lvl, fmt, args ...) \
LOGP(ss, lvl, "%s " fmt, hnb_context_name(x), ## args)
enum hnb_ctrl_node {
CTRL_NODE_HNB = _LAST_CTRL_NODE,
_LAST_CTRL_NODE_HNB
};
#define HNBGW_LOCAL_IP_DEFAULT "0.0.0.0"
/* TODO: CS and PS now both connect to OsmoSTP, i.e. that's always going to be the same address. Drop the
* duplicity. */
#define HNBGW_IUCS_REMOTE_IP_DEFAULT "127.0.0.1"
#define HNBGW_IUPS_REMOTE_IP_DEFAULT "127.0.0.1"
/* 25.467 Section 7.1 */
#define IUH_DEFAULT_SCTP_PORT 29169
#define RNA_DEFAULT_SCTP_PORT 25471
#define IUH_PPI_RUA 19
#define IUH_PPI_HNBAP 20
#define IUH_PPI_SABP 31
#define IUH_PPI_RNA 42
#define IUH_PPI_PUA 55
#define IUH_MSGB_SIZE 2048
struct umts_cell_id {
uint16_t mcc; /*!< Mobile Country Code */
uint16_t mnc; /*!< Mobile Network Code */
uint16_t lac; /*!< Locaton Area Code */
uint16_t rac; /*!< Routing Area Code */
uint16_t sac; /*!< Service Area Code */
uint32_t cid; /*!< Cell ID */
};
struct hnb_gw;
enum hnbgw_cnlink_state {
/* we have just been initialized or were disconnected */
CNLINK_S_NULL,
/* establishment of the SUA/SCCP link is pending */
CNLINK_S_EST_PEND,
/* establishment of the SUA/SCCP link was confirmed */
CNLINK_S_EST_CONF,
/* we have esnt the RANAP RESET and wait for the ACK */
CNLINK_S_EST_RST_TX_WAIT_ACK,
/* we have received the RANAP RESET ACK and are active */
CNLINK_S_EST_ACTIVE,
};
struct hnbgw_cnlink {
struct llist_head list;
enum hnbgw_cnlink_state state;
struct hnb_gw *gw;
/* timer for re-transmitting the RANAP Reset */
struct osmo_timer_list T_RafC;
/* reference to the SCCP User SAP by which we communicate */
struct osmo_sccp_instance *sccp;
struct osmo_sccp_user *sccp_user;
uint32_t next_conn_id;
/* linked list of hnbgw_context_map */
struct llist_head map_list;
};
struct hnb_context {
/*! Entry in HNB-global list of HNB */
struct llist_head list;
/*! HNB-GW we are part of */
struct hnb_gw *gw;
/*! SCTP socket + write queue for Iuh to this specific HNB */
struct osmo_stream_srv *conn;
/*! copied from HNB-Identity-Info IE */
char identity_info[256];
/*! copied from Cell Identity IE */
struct umts_cell_id id;
/*! SCTP stream ID for HNBAP */
uint16_t hnbap_stream;
/*! SCTP stream ID for RUA */
uint16_t rua_stream;
/*! True if a HNB-REGISTER-REQ from this HNB has been accepted. Note that
* this entire data structure is freed if the HNB sends HNB-DE-REGISTER-REQ. */
bool hnb_registered;
/* linked list of hnbgw_context_map */
struct llist_head map_list;
};
struct ue_context {
/*! Entry in the HNB-global list of UE */
struct llist_head list;
/*! Unique Context ID for this UE */
uint32_t context_id;
char imsi[16+1];
uint32_t tmsi;
/*! UE is serviced via this HNB */
struct hnb_context *hnb;
};
struct hnb_gw {
struct {
const char *iuh_local_ip;
/*! SCTP port for Iuh listening */
uint16_t iuh_local_port;
/*! The UDP port where we receive multiplexed CS user
* plane traffic from HNBs */
uint16_t iuh_cs_mux_port;
const char *iucs_remote_addr_name;
const char *iups_remote_addr_name;
uint16_t rnc_id;
bool hnbap_allow_tmsi;
/*! print hnb-id (true) or MCC-MNC-LAC-RAC-SAC (false) in logs */
bool log_prefix_hnb_id;
} config;
/*! SCTP listen socket for incoming connections */
struct osmo_stream_srv_link *iuh;
/* list of struct hnb_context */
struct llist_head hnb_list;
/* list of struct ue_context */
struct llist_head ue_list;
/* next availble UE Context ID */
uint32_t next_ue_ctx_id;
struct ctrl_handle *ctrl;
/* currently active CN links for CS and PS */
struct {
struct osmo_sccp_instance *client;
struct hnbgw_cnlink *cnlink;
struct osmo_sccp_addr local_addr;
struct osmo_sccp_addr iucs_remote_addr;
struct osmo_sccp_addr iups_remote_addr;
} sccp;
};
extern void *talloc_asn1_ctx;
struct hnb_context *hnb_context_by_id(struct hnb_gw *gw, uint32_t cid);
struct hnb_context *hnb_context_by_identity_info(struct hnb_gw *gw, const char *identity_info);
const char *hnb_context_name(struct hnb_context *ctx);
unsigned hnb_contexts(const struct hnb_gw *gw);
struct ue_context *ue_context_by_id(struct hnb_gw *gw, uint32_t id);
struct ue_context *ue_context_by_imsi(struct hnb_gw *gw, const char *imsi);
struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi);
struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi,
uint32_t tmsi);
void ue_context_free(struct ue_context *ue);
struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd);
void hnb_context_release(struct hnb_context *ctx);
void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx);
int hnbgw_vty_go_parent(struct vty *vty);

5
include/osmocom/iuh/hnbgw_cn.h

@ -1,5 +0,0 @@
#pragma once
#include <osmocom/iuh/hnbgw.h>
int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port, const char *local_ip);

6
include/osmocom/iuh/hnbgw_hnbap.h

@ -1,6 +0,0 @@
#pragma once
#include <osmocom/iuh/hnbgw.h>
int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg);
int hnbgw_hnbap_init(void);

6
include/osmocom/iuh/hnbgw_ranap.h

@ -1,6 +0,0 @@
#pragma once
#include <osmocom/iuh/hnbgw.h>
int hnbgw_ranap_rx(struct msgb *msg, uint8_t *data, size_t len);
int hnbgw_ranap_init(void);

13
include/osmocom/iuh/hnbgw_rua.h

@ -1,13 +0,0 @@
#pragma once
#include <osmocom/iuh/hnbgw.h>
#include <osmocom/rua/RUA_Cause.h>
int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg);
int hnbgw_rua_init(void);
int rua_tx_udt(struct hnb_context *hnb, const uint8_t *data, unsigned int len);
int rua_tx_dt(struct hnb_context *hnb, int is_ps, uint32_t context_id,
const uint8_t *data, unsigned int len);
int rua_tx_disc(struct hnb_context *hnb, int is_ps, uint32_t context_id,
const RUA_Cause_t *cause, const uint8_t *data, unsigned int len);

11
include/osmocom/iuh/vty.h

@ -1,11 +0,0 @@
#pragma once
#include <osmocom/vty/vty.h>
enum osmo_iuh_vty_node {
HNBGW_NODE = _LAST_OSMOVTY_NODE + 1,
IUH_NODE,
IUCS_NODE,
IUPS_NODE,
};

14
src/Makefile.am

@ -88,20 +88,6 @@ libosmo_sabp_la_LIBADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOVTY_LIBS) $(OSMO
libosmo_sabp_la_SOURCES = sabp_common.c sabp_encoder.c sabp_decoder.c
# build the actual HomeNodeB gateway
#
bin_PROGRAMS = osmo-hnbgw
osmo_hnbgw_SOURCES = hnbgw.c hnbgw_hnbap.c hnbgw_rua.c hnbgw_ranap.c \
hnbgw_vty.c \
context_map.c hnbgw_cn.c
osmo_hnbgw_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOVTY_LIBS) $(OSMOCTRL_LIBS) \
$(ASN1C_LIBS) $(OSMOSIGTRAN_LIBS) \
$(OSMONETIF_LIBS) \
libosmo-hnbap.la libosmo-rua.la libosmo-ranap.la
regen: regenerate-from-asn1-source
regenerate-from-asn1-source:

181
src/context_map.c

@ -1,181 +0,0 @@
/* Mapper between RUA ContextID (24 bit, per HNB) and the SUA/SCCP
* Connection ID (32bit, per signalling link) */
/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* an expired mapping is destroyed after 1..2 * EXPIRY_TIMER_SECS */
#define EXPIRY_TIMER_SECS 23
#include <osmocom/core/timer.h>
#include <osmocom/iuh/hnbgw.h>
#include <osmocom/iuh/context_map.h>
const struct value_string hnbgw_context_map_state_names[] = {
{MAP_S_NULL , "not-initialized"},
{MAP_S_ACTIVE , "active"},
{MAP_S_RESERVED1, "inactive-reserved"},
{MAP_S_RESERVED2, "inactive-discard"},
{0, NULL}
};
/* is a given SCCP USER SAP Connection ID in use for a given CN link? */
static int cn_id_in_use(struct hnbgw_cnlink *cn, uint32_t id)
{
struct hnbgw_context_map *map;
llist_for_each_entry(map, &cn->map_list, cn_list) {
if (map->scu_conn_id == id)
return 1;
}
return 0;
}
/* try to allocate a new SCCP User SAP Connection ID */
static int alloc_cn_conn_id(struct hnbgw_cnlink *cn, uint32_t *id_out)
{
uint32_t i;
uint32_t id;
for (i = 0; i < 0xffffffff; i++) {
id = cn->next_conn_id++;
if (!cn_id_in_use(cn, id)) {
*id_out = id;
return 1;
}
}
return -1;
}
/* Map from a HNB + ContextID to the SCCP-side Connection ID */
struct hnbgw_context_map *
context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
bool is_ps,
struct hnbgw_cnlink *cn_if_new)
{
struct hnbgw_context_map *map;
uint32_t new_scu_conn_id;
llist_for_each_entry(map, &hnb->map_list, hnb_list) {
if (map->state != MAP_S_ACTIVE)
continue;
if (map->cn_link != cn_if_new) {
continue;
}
if (map->rua_ctx_id == rua_ctx_id
&& map->is_ps == is_ps) {
return map;
}
}
if (alloc_cn_conn_id(cn_if_new, &new_scu_conn_id) < 0) {
LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate CN connection ID\n");
return NULL;
}
LOGHNB(hnb, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %p/%u <-> SCU Conn ID %p/%u\n",
hnb, rua_ctx_id, cn_if_new, new_scu_conn_id);
/* alloate a new map entry */
map = talloc_zero(hnb, struct hnbgw_context_map);
map->state = MAP_S_NULL;
map->cn_link = cn_if_new;
map->hnb_ctx = hnb;
map->rua_ctx_id = rua_ctx_id;
map->is_ps = is_ps;
map->scu_conn_id = new_scu_conn_id;
/* put it into both lists */
llist_add_tail(&map->hnb_list, &hnb->map_list);
llist_add_tail(&map->cn_list, &cn_if_new->map_list);
map->state = MAP_S_ACTIVE;
return map;
}
/* Map from a CN + Connection ID to HNB + Context ID */
struct hnbgw_context_map *
context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id)
{
struct hnbgw_context_map *map;
llist_for_each_entry(map, &cn->map_list, cn_list) {
if (map->state != MAP_S_ACTIVE)
continue;
if (map->scu_conn_id == scu_conn_id) {
return map;
}
}
/* we don't allocate new mappings in the CN->HNB
* direction, as the RUA=SCCP=SUA connections are always
* established from HNB towards CN. */
LOGP(DMAIN, LOGL_NOTICE, "Unable to resolve map for CN " "connection ID %p/%u\n", cn, scu_conn_id);
return NULL;
}
void context_map_deactivate(struct hnbgw_context_map *map)
{
/* set the state to reserved. We still show up in the list and
* avoid re-allocation of the context-id until we are cleaned up
* by the context_map garbage collector timer */
if (map->state != MAP_S_RESERVED2)
map->state = MAP_S_RESERVED1;
}
static struct osmo_timer_list context_map_tmr;
static void context_map_tmr_cb(void *data)
{
struct hnb_gw *gw = data;
struct hnbgw_cnlink *cn = gw->sccp.cnlink;
struct hnbgw_context_map *map, *next_map;
DEBUGP(DMAIN, "Running context mapper garbage collection\n");
llist_for_each_entry_safe(map, next_map, &cn->map_list, cn_list) {
switch (map->state) {
case MAP_S_RESERVED1:
/* first time we see this reserved
* entry: mark it for stage 2 */
map->state = MAP_S_RESERVED2;
break;
case MAP_S_RESERVED2:
/* second time we see this reserved
* entry: remove it */
map->state = MAP_S_NULL;
llist_del(&map->cn_list);
llist_del(&map->hnb_list);
talloc_free(map);
break;
default:
break;
}
}
/* re-schedule this timer */
osmo_timer_schedule(&context_map_tmr, EXPIRY_TIMER_SECS, 0);
}
int context_map_init(struct hnb_gw *gw)
{
context_map_tmr.cb = context_map_tmr_cb;
context_map_tmr.data = gw;
osmo_timer_schedule(&context_map_tmr, EXPIRY_TIMER_SECS, 0);
return 0;
}

698
src/hnbgw.c

@ -1,698 +0,0 @@
/* main application for hnb-gw part of osmo-iuh */
/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <osmocom/core/application.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/control_cmd.h>
#include <osmocom/ctrl/control_vty.h>
#include <osmocom/ctrl/ports.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/ports.h>
#include <osmocom/netif/stream.h>
#include <osmocom/ranap/ranap_common.h>
#include <osmocom/sigtran/protocol/m3ua.h>
#include <osmocom/sigtran/sccp_sap.h>
#include <osmocom/iuh/hnbgw.h>
#include <osmocom/iuh/hnbgw_hnbap.h>
#include <osmocom/iuh/hnbgw_rua.h>
#include <osmocom/iuh/hnbgw_cn.h>
#include <osmocom/iuh/context_map.h>
static const char * const osmo_hnbgw_copyright =
"OsmoHNBGW - Osmocom Home Node B Gateway implementation\r\n"
"Copyright (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>\r\n"
"Contributions by Daniel Willmann, Harald Welte, Neels Hofmeyr\r\n"
"License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
"This is free software: you are free to change and redistribute it.\r\n"
"There is NO WARRANTY, to the extent permitted by law.\r\n";
static void *tall_hnb_ctx;
static struct hnb_gw *g_hnb_gw;
static struct hnb_gw *hnb_gw_create(void *ctx)
{
struct hnb_gw *gw = talloc_zero(ctx, struct hnb_gw);
/* strdup so we can easily talloc_free in the VTY code */
gw->config.iuh_local_ip = talloc_strdup(gw, HNBGW_LOCAL_IP_DEFAULT);
gw->config.iuh_local_port = IUH_DEFAULT_SCTP_PORT;
gw->config.log_prefix_hnb_id = true;
gw->next_ue_ctx_id = 23;
INIT_LLIST_HEAD(&gw->hnb_list);
INIT_LLIST_HEAD(&gw->ue_list);
context_map_init(gw);
return gw;
}
struct hnb_context *hnb_context_by_id(struct hnb_gw *gw, uint32_t cid)
{
struct hnb_context *hnb;
llist_for_each_entry(hnb, &gw->hnb_list, list) {
if (hnb->id.cid == cid)
return hnb;
}
return NULL;
}
struct hnb_context *hnb_context_by_identity_info(struct hnb_gw *gw, const char *identity_info)
{
struct hnb_context *hnb;
llist_for_each_entry(hnb, &gw->hnb_list, list) {
if (strcmp(identity_info, hnb->identity_info) == 0)
return hnb;
}
return NULL;
}
unsigned hnb_contexts(const struct hnb_gw *gw)
{
unsigned num_ctx = 0;
struct hnb_context *hnb;
llist_for_each_entry(hnb, &gw->hnb_list, list) {
num_ctx++;
}
return num_ctx;
}
struct ue_context *ue_context_by_id(struct hnb_gw *gw, uint32_t id)
{
struct ue_context *ue;
llist_for_each_entry(ue, &gw->ue_list, list) {
if (ue->context_id == id)
return ue;
}
return NULL;
}
struct ue_context *ue_context_by_imsi(struct hnb_gw *gw, const char *imsi)
{
struct ue_context *ue;
llist_for_each_entry(ue, &gw->ue_list, list) {
if (!strcmp(ue->imsi, imsi))
return ue;
}
return NULL;
}
struct ue_context *ue_context_by_tmsi(struct hnb_gw *gw, uint32_t tmsi)
{
struct ue_context *ue;
llist_for_each_entry(ue, &gw->ue_list, list) {
if (ue->tmsi == tmsi)
return ue;
}
return NULL;
}
void ue_context_free_by_hnb(struct hnb_gw *gw, const struct hnb_context *hnb)
{
struct ue_context *ue, *tmp;
llist_for_each_entry_safe(ue, tmp, &gw->ue_list, list) {
if (ue->hnb == hnb)
ue_context_free(ue);
}
}
static uint32_t get_next_ue_ctx_id(struct hnb_gw *gw)
{
uint32_t id;
do {
id = gw->next_ue_ctx_id++;
} while (ue_context_by_id(gw, id));
return id;
}
struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi,
uint32_t tmsi)
{
struct ue_context *ue;
ue = talloc_zero(tall_hnb_ctx, struct ue_context);
if (!ue)
return NULL;
ue->hnb = hnb;
if (imsi)
OSMO_STRLCPY_ARRAY(ue->imsi, imsi);
else
ue->imsi[0] = '\0';
ue->tmsi = tmsi;
ue->context_id = get_next_ue_ctx_id(hnb->gw);
llist_add_tail(&ue->list, &hnb->gw->ue_list);
LOGP(DHNBAP, LOGL_INFO, "created UE context: id 0x%x, imsi %s, tmsi 0x%x\n",
ue->context_id, imsi? imsi : "-", tmsi);
return ue;
}
void ue_context_free(struct ue_context *ue)
{
llist_del(&ue->list);
talloc_free(ue);
}
static int hnb_read_cb(struct osmo_stream_srv *conn)
{
struct hnb_context *hnb = osmo_stream_srv_get_data(conn);
struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
int rc;
if (!msg)
return -ENOMEM;
/* we store a reference to the HomeNodeB in the msg->dest for the
* benefit of varoius downstream processing functions */
msg->dst = hnb;
rc = osmo_stream_srv_recv(conn, msg);
if (rc == -EAGAIN) {
/* Notification received */
msgb_free(msg);
return 0;
} else if (rc < 0) {
LOGHNB(hnb, DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
/* FIXME: clean up after disappeared HNB */
hnb_context_release(hnb);
goto out;
} else if (rc == 0) {
hnb_context_release(hnb);
rc = -1;
goto out;
} else {
msgb_put(msg, rc);
}
switch (msgb_sctp_ppid(msg)) {
case IUH_PPI_HNBAP:
hnb->hnbap_stream = msgb_sctp_stream(msg);
rc = hnbgw_hnbap_rx(hnb, msg);
break;
case IUH_PPI_RUA:
hnb->rua_stream = msgb_sctp_stream(msg);
rc = hnbgw_rua_rx(hnb, msg);
break;
case IUH_PPI_SABP:
case IUH_PPI_RNA:
case IUH_PPI_PUA:
LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%lu received\n", msgb_sctp_ppid(msg));
rc = 0;
break;
default:
LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%lu received\n", msgb_sctp_ppid(msg));
rc = 0;
break;
}
out:
msgb_free(msg);
return rc;
}
struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd)
{
struct hnb_context *ctx;
ctx = talloc_zero(tall_hnb_ctx, struct hnb_context);
if (!ctx)
return NULL;
INIT_LLIST_HEAD(&ctx->map_list);
ctx->gw = gw;
ctx->conn = osmo_stream_srv_create(tall_hnb_ctx, link, new_fd, hnb_read_cb, NULL, ctx);
if (!ctx->conn) {
LOGP(DMAIN, LOGL_INFO, "error while creating connection\n");
talloc_free(ctx);
return NULL;
}
llist_add_tail(&ctx->list, &gw->hnb_list);
return ctx;
}
static const char *umts_cell_id_name(const struct umts_cell_id *ucid)
{
static __thread char buf[40];
snprintf(buf, sizeof(buf), "%u-%u-L%u-R%u-S%u", ucid->mcc, ucid->mnc, ucid->lac, ucid->rac, ucid->sac);
return buf;
}
const char *hnb_context_name(struct hnb_context *ctx)
{
if (!ctx)
return "NULL";
if (ctx->gw->config.log_prefix_hnb_id)
return ctx->identity_info;
else
return umts_cell_id_name(&ctx->id);
}
void hnb_context_release(struct hnb_context *ctx)
{