mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 04:53:24 +00:00
Compare commits
1 Commits
1.8.0
...
pmaier/mgw
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a71251229 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,7 +16,6 @@ src/osmo-mgw/osmo-mgw
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.pc
|
||||
*~
|
||||
|
||||
#configure
|
||||
aclocal.m4
|
||||
|
||||
16
configure.ac
16
configure.ac
@@ -9,8 +9,6 @@ AC_CONFIG_AUX_DIR([.])
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
|
||||
CFLAGS="$CFLAGS -std=gnu11"
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
@@ -49,13 +47,13 @@ AC_SEARCH_LIBS([dlsym], [dl dld], [LIBRARY_DLSYM="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_DLSYM)
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.6.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.6.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 0.6.0)
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
|
||||
@@ -36,6 +36,7 @@ osmo-build-dep.sh libosmo-netif
|
||||
# Additional configure options and depends
|
||||
CONFIG=""
|
||||
if [ "$WITH_MANUALS" = "1" ]; then
|
||||
osmo-build-dep.sh osmo-gsm-manuals
|
||||
CONFIG="--enable-manuals"
|
||||
fi
|
||||
|
||||
@@ -55,12 +56,12 @@ LD_LIBRARY_PATH="$inst/lib" $MAKE check \
|
||||
|| cat-testlogs.sh
|
||||
LD_LIBRARY_PATH="$inst/lib" \
|
||||
DISTCHECK_CONFIGURE_FLAGS="--enable-vty-tests --enable-external-tests $CONFIG" \
|
||||
$MAKE $PARALLEL_MAKE distcheck \
|
||||
$MAKE distcheck \
|
||||
|| cat-testlogs.sh
|
||||
|
||||
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||
make -C "$base/doc/manuals" publish
|
||||
fi
|
||||
|
||||
$MAKE $PARALLEL_MAKE maintainer-clean
|
||||
$MAKE maintainer-clean
|
||||
osmo-clean-workspace.sh
|
||||
|
||||
@@ -29,30 +29,28 @@ BuildRequires: pkgconfig >= 0.20
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.1.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmocoding) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.1.0
|
||||
BuildRequires: pkgconfig(libosmotrau) >= 1.1.0
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 0.6.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.0.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.1.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.0.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.0.0
|
||||
BuildRequires: pkgconfig(libosmocoding) >= 1.0.0
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
OsmoMGW is Osmocom's Media Gateway for 2G and 3G circuit-switched mobile networks.
|
||||
|
||||
%package -n libosmo-mgcp-client8
|
||||
%package -n libosmo-mgcp-client6
|
||||
Summary: Osmocom's Media Gateway Control Protocol client library
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libosmo-mgcp-client8
|
||||
%description -n libosmo-mgcp-client6
|
||||
Osmocom's Media Gateway Control Protocol client library.
|
||||
|
||||
%package -n libosmo-mgcp-client-devel
|
||||
Summary: Development files for Osmocom's Media Gateway Control Protocol client library
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: libosmo-mgcp-client8 = %{version}
|
||||
Requires: libosmo-mgcp-client6 = %{version}
|
||||
|
||||
%description -n libosmo-mgcp-client-devel
|
||||
Osmocom's Media Gateway Control Protocol client librarary.
|
||||
@@ -90,8 +88,8 @@ find %{buildroot} -type f -name "*.la" -delete -print
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%post -n libosmo-mgcp-client8 -p /sbin/ldconfig
|
||||
%postun -n libosmo-mgcp-client8 -p /sbin/ldconfig
|
||||
%post -n libosmo-mgcp-client6 -p /sbin/ldconfig
|
||||
%postun -n libosmo-mgcp-client6 -p /sbin/ldconfig
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%preun
|
||||
@@ -113,13 +111,12 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
%dir %{_docdir}/%{name}/examples
|
||||
%dir %{_docdir}/%{name}/examples/osmo-mgw
|
||||
%{_docdir}/%{name}/examples/osmo-mgw/osmo-mgw.cfg
|
||||
%{_docdir}/%{name}/examples/osmo-mgw/osmo-mgw-abis_e1.cfg
|
||||
%{_bindir}/osmo-mgw
|
||||
%{_unitdir}/osmo-mgw.service
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-mgw.cfg
|
||||
|
||||
%files -n libosmo-mgcp-client8
|
||||
%files -n libosmo-mgcp-client6
|
||||
%{_libdir}/libosmo-mgcp-client.so.6*
|
||||
|
||||
%files -n libosmo-mgcp-client-devel
|
||||
|
||||
160
debian/changelog
vendored
160
debian/changelog
vendored
@@ -1,163 +1,3 @@
|
||||
osmo-mgw (1.8.0) unstable; urgency=medium
|
||||
|
||||
[ Harald Welte ]
|
||||
* Fix number of endpoints of default trunk
|
||||
* Add CTRL interface to osmo-mgw
|
||||
* Update per-trunk global packet/byte counters in real-time
|
||||
* remove accidential TODO-RELEASE entry
|
||||
* mgcp_protocol: Avoid code duplication between virtual + other trunks
|
||||
* osmo-mgw.spec.in: Use %config(noreplace) to retain current config file
|
||||
* mgcp_client_init(): consider "talloc returns NULL" case
|
||||
* mgcp_client_pending_add(): Consider "talloc returns NULL" case
|
||||
* libosmo-mgcp-client: fix memleak in case if no response is received
|
||||
* debian/control + SPEC: Add missing build dependency to libosmo-abis
|
||||
* osmo-mgw.spec.in: Fix dependency to libosmoabis
|
||||
* osmo-mgw.spec.in: Add missing dependency to libosmotrau
|
||||
* Add example osmo-mgw configuration file for Abis/E1
|
||||
* use osmo_fd_setup() whenever applicable
|
||||
|
||||
[ Neels Hofmeyr ]
|
||||
* fix vty dump_trunk: start from zero, do not omit first CONN
|
||||
* allow larger MGCP client wqueue: 10 -> 1024
|
||||
* add osmo-mgw --vty-ref-xml: dump VTY ref XML to stdout
|
||||
* manuals: generate vty reference xml at build time
|
||||
* refactor: use msgb to receive, pass and send RTP packets
|
||||
* change timer T2427001 to X2427
|
||||
|
||||
[ Philipp Maier ]
|
||||
* doc: do not bind osmo-mgw to random ip-address
|
||||
* cosmetic: remove excess newlines
|
||||
* mgcp: remove unused callback pointer
|
||||
* mgcp: find better locations for LOGPCONN and LOGPENDP
|
||||
* vty: fix unreachable code (error msg on trunk alloc fail)
|
||||
* mgcp_vty: fix indentation
|
||||
* osmo-mgw: rename struct mgcp_trunk_config and symbol tcfg
|
||||
* mgcp_vty: fix indentation in VTY config write
|
||||
* osmo-mgw: refactor endpoint and trunk handling
|
||||
* mgcp_trunk: remove audio_name and audio_payload
|
||||
* ratectr: move rate counter definitions into mgcp_ratectr.h
|
||||
* cosmetic: fix doxygen
|
||||
* cosmetic: fix doxygen
|
||||
* cosmetic: fix doxygen for mgcp_cleanup_rtp_bridge_cb()
|
||||
* trunk: get rid of virt_trunk pointer
|
||||
* cosmetic: remove excess space
|
||||
* endp: move endpoint name generation into mgcp_endp.c
|
||||
* endp: add name generator function for E1 endpoints
|
||||
* mgcp_client: add docstring for mgcp_client_rtpbridge_wildcard()
|
||||
* mgcp_trunk: fix docstring for mgcp_trunk_alloc()
|
||||
* mgcp_osmux: remove unused define constants
|
||||
* mgcp_trunk: move enum mgcp_trunk_type to mgcp_trunk.h
|
||||
* mgcp_trunk: use enum type for trunk type variable
|
||||
* trunk: parse E1 trunk number
|
||||
* endp: add typeset for e1-endpoints
|
||||
* mgcp_conn: move struct mgcp_conn mgcp_conn.h
|
||||
* mgcp_internal: remove forward declaration struct mgcp_endpoint_type
|
||||
* endp: add E1 endpoint interlocking
|
||||
* endp: require domain name also for E1 endpoints
|
||||
* mgcp_trunk: pick trunk by number and type
|
||||
* mgcp_client: add function to generate e1-endpoint names
|
||||
* mgcp_endp: use define constant to define max number of E1 subslots
|
||||
* mgcp_endp.c: cosmetic: fix sourcecode formatting
|
||||
* mgcp_trunk: remove double check
|
||||
* mgcp_test: do not access endpoint array elements directly
|
||||
* mgcp_vty: fix endpoint number configuration
|
||||
* mgcp_test: remove trunk2 from unit-test
|
||||
* mgcp_trunk: use talloc_zero_array instead of _talloc_zero_array
|
||||
* mgcp_protocol: remove unused variable
|
||||
* mgcp_e1: finish E1 support, add E1 support from libosmoabis
|
||||
* get rid of mgcp_internal.h
|
||||
* mgcp_ratectr: fix comments in header file
|
||||
* mgcp_e1: use return value of e1inp_line_update()
|
||||
* mgcp_protocol: log when endpoint is unavailable
|
||||
* cosmetic: add missing new-line
|
||||
* mgcp_trunk: drop "trunk 0" limitation
|
||||
* mgcp_e1: make E1 ts initalization more debugable
|
||||
* mgcp_e1: remove unused struct member trunk->e1.line
|
||||
* mgcp_endp: use NUM_E1_TS from e1_input.h
|
||||
* mgcp_trunk: increase default number of virtual endpoints
|
||||
* cosmetic: mgcp_client_fsm: change error message.
|
||||
* mgcp_vty: remove remains of loopback functionality
|
||||
* mgcp_vty: deprecate bind early command
|
||||
* mgcp_e1: do not expose function mgcp_e1_init()
|
||||
* mgcp_vty: add user attributes to configuration commands
|
||||
* overview: update section limitations.
|
||||
* overview: fix graph "OsmoMGW used with OsmoBSC"
|
||||
* overview: fix graph "OsmoMGW used with OsmoMSC"
|
||||
* overview: add graph to show E1 integration
|
||||
* configuration: remove hint towards trunk 0 limit
|
||||
* configuration: drop note about lackin E1 support
|
||||
* configuration: add note that changes to trunks need a restart
|
||||
* mgcp_vty: fix config write for trunk 0
|
||||
* mgcp_vty: add missing VTY commands for E1 trunks
|
||||
* mgcp_trunk: get rid of magic numbers for E1 slots
|
||||
* configuration: add section about E1 trunks
|
||||
* usermanual: add chapter about mgcp endpoints
|
||||
* mgcp_client: get rid of magic numbers for E1 slots
|
||||
|
||||
[ Eric ]
|
||||
* tests: dlopen does not imply availability of dlsym..
|
||||
* configure.ac: fix libtool issue with clang and sanitizer
|
||||
|
||||
[ Alexander Chemeris ]
|
||||
* vty: Prepend VTY output of counters for better visual separation.
|
||||
* counters: Implement more useful counters.
|
||||
* mgcp_network: Fix a typo in the comment bahviour -> behaviour
|
||||
* rtp_bridge: Demote a chatty ERROR log message to DEBUG level.
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* Use OSMO_FD_* instead of deprecated BSC_FD_*
|
||||
* Support setting rt-prio and cpu-affinity mask through VTY
|
||||
* cosmetic: Rename main talloc ctx
|
||||
* mgcp-client: Support IPv6 in osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr() implementation
|
||||
* mgcp-client: Fix trailing whitespace in mgcp_client_fsm.h
|
||||
* mgcp_client: Use INET6_ADDRSTRLEN to store addresses in str format
|
||||
* mgcp_client: Allow submitting and parsing IPv6 addr in SDP
|
||||
* mgcp_client: Allow setting IPv6 addresses
|
||||
* mgcp_client: Make MGCP_CLIENT_LOCAL_ADDR_DEFAULT IPv6 compatible
|
||||
* mgcp_client: Support validating IPv6 addresses in CRCX and MDCX commands
|
||||
* mgcp_client: Deprecate unused IPv4-only API
|
||||
* mgcp_client: copy back Connection Information from MDCX ACK
|
||||
* mgw: Fix mgcp_rtp_end field description comment
|
||||
* mgw: Initial IPv6 support
|
||||
* mgw: Introduce VTY cmd 'rtp bind-ip-v6' command
|
||||
* mgw: Find and store RTP conn local_addr once during CRCX handling
|
||||
* mgw: Announce and rebind new local address if change required during MDCX
|
||||
* mgw: osmux: Avoid sending packets on recvonly connection
|
||||
* mgw: Release endpoint after last conn times out
|
||||
* mgw: osmux: Fix conn watchdog timeout not updated
|
||||
* mgw: Don't be case-sensitive when parsing X-Osmo-IGN param
|
||||
* cosmetic: Fix typo in comment
|
||||
* mgw: Avoid logging notice message each time we receive nt param in LCO
|
||||
* mgw: Fix return value documentation for API mgcp_verify_call_id
|
||||
* cosmetic: Fix typo in comment
|
||||
* contrib/jenkins: Enable parallel make in make distcheck
|
||||
* .gitignore: Ignore new autofoo tmp files
|
||||
* tests: Replace deprecated API log_set_print_filename
|
||||
|
||||
[ Oliver Smith ]
|
||||
* contrib: import RPM spec
|
||||
* contrib: integrate RPM spec
|
||||
* Makefile.am: EXTRA_DIST: debian, contrib/*.spec.in
|
||||
* contrib/jenkins: don't build osmo-gsm-manuals
|
||||
* configure.ac: set -std=gnu11
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* libosmo-mgcp-client: fix use-after-free in mgcp_client_tx()
|
||||
* libosmo-mgcp-client: fix use-after-free in mgcp_msg_gen()
|
||||
* libosmo-mgcp: fix unsigned compared against 0 in mgcp_trunk_by_name()
|
||||
* libosmo-mgcp: fix unused extra argument to printf() in add_fmtp()
|
||||
* libosmo-mgcp: always check result of msgb_printf() in add_fmtp()
|
||||
* libosmo-mgcp-client: mgcp_client_tx(): return rc on error
|
||||
* debian/control: change maintainer to the Osmocom team / mailing list
|
||||
* vty: use install_lib_element() and install_lib_element_ve()
|
||||
* main: add --vty-ref-mode, use vty_dump_xml_ref_mode()
|
||||
* fixup mgcp_trunk: increase default number of virtual endpoints
|
||||
|
||||
[ Alexander Couzens ]
|
||||
* configure.ac: require libosmoabis + libosmotrau >= 1.0.0
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 23 Feb 2021 18:28:45 +0100
|
||||
|
||||
osmo-mgw (1.7.0) unstable; urgency=medium
|
||||
|
||||
[ Neels Hofmeyr ]
|
||||
|
||||
13
debian/control
vendored
13
debian/control
vendored
@@ -1,15 +1,14 @@
|
||||
Source: osmo-mgw
|
||||
Section: net
|
||||
Priority: extra
|
||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Maintainer: Alexander Couzens <lynxis@fe80.eu>
|
||||
Build-Depends: debhelper (>=9),
|
||||
dh-autoreconf,
|
||||
pkg-config,
|
||||
autotools-dev,
|
||||
libosmocore-dev (>= 1.5.0),
|
||||
libosmo-netif-dev (>= 1.1.0),
|
||||
libosmo-abis-dev (>= 1.1.0),
|
||||
osmo-gsm-manuals-dev (>= 1.1.0)
|
||||
libosmocore-dev,
|
||||
libosmo-netif-dev,
|
||||
osmo-gsm-manuals-dev
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Git: git://git.osmocom.org/osmo-mgw.git
|
||||
Vcs-Browser: https://git.osmocom.org/osmo-mgw/
|
||||
@@ -21,7 +20,7 @@ Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: OsmoMGW: Osmocom's Media Gateway for 2G and 3G circuit-switched mobile networks
|
||||
|
||||
Package: libosmo-mgcp-client8
|
||||
Package: libosmo-mgcp-client6
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
@@ -33,7 +32,7 @@ Package: libosmo-mgcp-client-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: libosmo-mgcp-client8 (= ${binary:Version}), ${misc:Depends}
|
||||
Depends: libosmo-mgcp-client6 (= ${binary:Version}), ${misc:Depends}
|
||||
Description: libosmo-mgcp-client: Osmocom's Media Gateway Control Protocol client utilities
|
||||
|
||||
Package: osmo-mgw-doc
|
||||
|
||||
1
debian/osmo-mgw.install
vendored
1
debian/osmo-mgw.install
vendored
@@ -2,4 +2,3 @@ etc/osmocom/osmo-mgw.cfg
|
||||
lib/systemd/system/osmo-mgw.service
|
||||
usr/bin/osmo-mgw
|
||||
usr/share/doc/osmo-mgw/examples/osmo-mgw/osmo-mgw.cfg
|
||||
usr/share/doc/osmo-mgw/examples/osmo-mgw/osmo-mgw-abis_e1.cfg
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
!
|
||||
! MGCP configuration example
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 0
|
||||
mgcp
|
||||
bind ip 127.0.0.1
|
||||
rtp port-range 4002 16000
|
||||
rtp bind-ip 127.0.0.1
|
||||
rtp ip-probing
|
||||
rtp ip-tos 184
|
||||
bind port 2427
|
||||
sdp audio payload number 98
|
||||
sdp audio payload name GSM
|
||||
number endpoints 512
|
||||
loop 0
|
||||
force-realloc 1
|
||||
rtcp-omit
|
||||
rtp-patch ssrc
|
||||
rtp-patch timestamp
|
||||
trunk 1
|
||||
rtp keep-alive once
|
||||
no rtp keep-alive
|
||||
line 0
|
||||
@@ -10,7 +10,7 @@ mgcp
|
||||
bind port 2427
|
||||
sdp audio payload number 98
|
||||
sdp audio payload name GSM
|
||||
number endpoints 512
|
||||
number endpoints 31
|
||||
loop 0
|
||||
force-realloc 1
|
||||
rtcp-omit
|
||||
|
||||
@@ -23,13 +23,14 @@ OsmoMGW(config-mgcp)# local ip 127.0.0.1
|
||||
|
||||
=== Configuring the trunk
|
||||
|
||||
The first trunk is considered a virtual trunk in OsmoMGW. All
|
||||
The first trunk (trunk 0) is considered a virtual trunk in OsmoMGW. All
|
||||
endpoints of type "rtpbridge" are routed here. The virtual trunk is configured
|
||||
in the config-mgcp context.
|
||||
|
||||
All other trunks are configured in the config-mgcp-trunk context, but the
|
||||
commands used are identical. Right now trunks are considered only for "ds/e1"
|
||||
type endpoints.
|
||||
commands used are identical. Right now trunks are considered only for ds/e1
|
||||
type endpoints which are not yet implemented. Don't use trunks other than the
|
||||
"virtual" trunk 0.
|
||||
|
||||
.Example: MGCP trunk configuration
|
||||
----
|
||||
@@ -53,72 +54,4 @@ OsmoMGW(config-mgcp)# rtp-patch timestamp <3>
|
||||
<2> Hide SSRC changes
|
||||
<3> Ensure RTP timestamp is aligned with frame duration
|
||||
|
||||
NOTE: Changes to trunks that affect resource allocation, such as newly created
|
||||
trunks or a change of the number of available endpoints, require a full restart
|
||||
of osmo-mgw!
|
||||
|
||||
=== E1 trunk considerations
|
||||
|
||||
While the RTP bridge trunks are natively based on IP no special considerations
|
||||
are required during setup. E1 trunks are mapped on a physical E1 line, which has
|
||||
to be configured as shown below.
|
||||
|
||||
.Example: E1 line setup
|
||||
----
|
||||
OsmoMGW(config-e1_input)# e1_line 0 driver dahdi <1>
|
||||
OsmoMGW(config-e1_input)# e1_line 0 port 2 <2>
|
||||
----
|
||||
<1> Name of the libosmo-abis driver implementation ("dahdi")
|
||||
<2> Port number of the physical E1 port to use (2)
|
||||
|
||||
In osmo-mgw the e1_input node is used to configure the physical E1 line. The
|
||||
line number will be used internally to identify the configured E1 line. The
|
||||
port number is the physical E1 connector (sometimes called 'span') at the E1
|
||||
hardware. Per trunk an individual E1 line will be needed. Beware that the E1
|
||||
driver may also need configuration settings that are not discussed here.
|
||||
|
||||
.Example: E1 trunk setup
|
||||
----
|
||||
OsmoMGW(config-mgcp)# trunk 0 <1>
|
||||
OsmoMGW(config-mgcp-trunk)# line 0 <2>
|
||||
----
|
||||
<1> Creation of a trunk (0)
|
||||
<2> Reference to the E1 line to use (0)
|
||||
|
||||
The E1 trunk is created along with a number, typically starting at 0, but if
|
||||
required any number from 0-64 is allowed. The E1 trunk configuration concerning
|
||||
the IP related aspects is nearly identical to the configuration of the virtual
|
||||
trunk. However, it is important that the user assigns one of the E1 line numbers
|
||||
that were configured under the e1_input node.
|
||||
|
||||
.Example: A typical configuration with one E1 trunk
|
||||
----
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 2
|
||||
mgcp
|
||||
bind ip 127.0.0.1
|
||||
rtp net-range 6000 6011
|
||||
rtp net-bind-ip 192.168.100.130
|
||||
rtp ip-probing
|
||||
rtp ip-tos 184
|
||||
no rtp keep-alive
|
||||
bind port 2428
|
||||
number endpoints 30
|
||||
loop 0
|
||||
force-realloc 1
|
||||
osmux off
|
||||
rtp-patch rfc5993hr
|
||||
trunk 0
|
||||
rtp keep-alive once
|
||||
no rtp keep-alive
|
||||
line 0
|
||||
----
|
||||
|
||||
NOTE: One E1 trunk always covers a whole E1 line. All subslots (I.640) will be mapped
|
||||
to individual MGCP endpoints. As long as the endpoints remain unused the
|
||||
underlying E1 timeslot is not used.
|
||||
|
||||
NOTE: The E1 trunk implementation also works with T1 lines, however since T1 has
|
||||
24 instead of 31 usable timeslots only the endpoints that fall into that 1-24 timeslot
|
||||
range will be useable.
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
== MGCP Endpoints
|
||||
|
||||
MGCP organizes the switching resources in so called endpoints. Each endpoint is
|
||||
referenced by its unique identifier. While RFC 3435 specifies a naming scheme, the
|
||||
actual identifier naming is subject to the implementation and configuration.
|
||||
|
||||
=== RTP proxy / RTP bridge endpoints
|
||||
|
||||
OsmoMGW implements a freely configurable number of `rtpbridge` endpoints. Those
|
||||
endpoints are able to host two connections at a time to model the functionality
|
||||
of a tandem switch.
|
||||
|
||||
RTP bridge endpoint identifiers are referenced by the string `rtpbridge/`, a
|
||||
hexadecimal number without leading zeros and a domain name (configurable).
|
||||
|
||||
----
|
||||
rtpbridge/<number>@<domain>
|
||||
----
|
||||
|
||||
.Example: List of virtual endpoints
|
||||
----
|
||||
rtpbridge/1@mgw
|
||||
rtpbridge/2@mgw
|
||||
rtpbridge/3@mgw
|
||||
rtpbridge/4@mgw
|
||||
rtpbridge/5@mgw
|
||||
rtpbridge/6@mgw
|
||||
rtpbridge/7@mgw
|
||||
rtpbridge/8@mgw
|
||||
rtpbridge/9@mgw
|
||||
rtpbridge/a@mgw
|
||||
rtpbridge/b@mgw
|
||||
rtpbridge/c@mgw
|
||||
rtpbridge/d@mgw
|
||||
rtpbridge/e@mgw
|
||||
rtpbridge/f@mgw
|
||||
rtpbridge/10@mgw
|
||||
----
|
||||
|
||||
=== E1/T1 endpoints
|
||||
|
||||
OsmoMGW supports E1 subslot multiplexing as specified by I.460. All possible
|
||||
subslot combinations are mapped on individual endpoints. The endpoint names
|
||||
are prefixed with `ds/e1-` followed by the trunk number and the E1 timeslot.
|
||||
The subslot is defined by a bit rate and a bit offset.
|
||||
|
||||
----
|
||||
ds/e1-<trunk>/s-<timeslot>/su<bitrate>-<bitoffset>@<domain>
|
||||
----
|
||||
|
||||
.Example: List of endpoints on E1 trunk 0 at E1 timeslot 2
|
||||
----
|
||||
ds/e1-0/s-2/su64-0@mgw
|
||||
ds/e1-0/s-2/su32-0@mgw
|
||||
ds/e1-0/s-2/su32-4@mgw
|
||||
ds/e1-0/s-2/su16-0@mgw
|
||||
ds/e1-0/s-2/su16-2@mgw
|
||||
ds/e1-0/s-2/su16-4@mgw
|
||||
ds/e1-0/s-2/su16-6@mgw
|
||||
ds/e1-0/s-2/su8-0@mgw
|
||||
ds/e1-0/s-2/su8-1@mgw
|
||||
ds/e1-0/s-2/su8-2@mgw
|
||||
ds/e1-0/s-2/su8-3@mgw
|
||||
ds/e1-0/s-2/su8-4@mgw
|
||||
ds/e1-0/s-2/su8-5@mgw
|
||||
ds/e1-0/s-2/su8-6@mgw
|
||||
ds/e1-0/s-2/su8-7@mgw
|
||||
----
|
||||
|
||||
When creating connections on endpoints that reside in one E1 timeslot the call
|
||||
agent must make sure that no overlapping endpoints are used. It is for example
|
||||
not possible to use `ds/e1-0/s-2/su16-2@mgw` and `ds/e1-0/s-2/su8-3@mgw` at the
|
||||
same time because they overlap.
|
||||
|
||||
.Subslot overlapping
|
||||
[options="header"]
|
||||
|===
|
||||
| Bit offset 4+| Subslots
|
||||
| 0 | 8k .2+| 16k .4+| 32k .8+| 64k
|
||||
| 1 | 8k
|
||||
| 2 | 8k .2+| 16k
|
||||
| 3 | 8k
|
||||
| 4 | 8k .2+| 16k .4+| 32k
|
||||
| 5 | 8k
|
||||
| 6 | 8k .2+| 16k
|
||||
| 7 | 8k
|
||||
|===
|
||||
|
||||
NOTE: The current implementation (December 2020) only implements TRAU frame
|
||||
encoding/decoding for 16K and 8K subslots. Endpoints with other bitrates are
|
||||
not yet useable.
|
||||
|
||||
NOTE: the VTY command "show mgcp" can be used to get a list of all available
|
||||
endpoints (including identifiers)
|
||||
@@ -21,10 +21,10 @@ Protocol.
|
||||
digraph G {
|
||||
rankdir = LR;
|
||||
OsmoBTS -> OsmoBSC [label="Abis/IP"];
|
||||
OsmoBSC -> "core-network" [label="3GPP AoIP"];
|
||||
OsmoBSC -> OsmoMSC [label="3GPP AoIP"];
|
||||
OsmoBSC -> OsmoMGW [label="MGCP"];
|
||||
OsmoBTS -> OsmoMGW [label="RTP",dir=both];
|
||||
OsmoMGW -> "core-network" [label="RTP",dir=both];
|
||||
OsmoMGW -> OsmoMSC [label="RTP",dir=both];
|
||||
{rank=same OsmoBSC OsmoMGW}
|
||||
OsmoMGW [color=red];
|
||||
}
|
||||
@@ -36,9 +36,10 @@ digraph G {
|
||||
----
|
||||
digraph G {
|
||||
rankdir = LR;
|
||||
"2G BSS" -> OsmoMSC [label="3GPP AoIP"];
|
||||
BTS -> BSC [label="Abis"];
|
||||
BSC -> OsmoMSC [label="3GPP AoIP"];
|
||||
OsmoMSC -> OsmoMGW [label="MGCP"];
|
||||
"2G BSS" -> OsmoMGW [label="RTP",dir=both];
|
||||
BSC -> OsmoMGW [label="RTP",dir=both];
|
||||
OsmoMSC -> OsmoSIP [label="MNCC"];
|
||||
OsmoSIP -> PBX [label="SIP Trunk"];
|
||||
OsmoMGW -> PBX [label="RTP",dir=both];
|
||||
@@ -52,22 +53,6 @@ digraph G {
|
||||
}
|
||||
----
|
||||
|
||||
[[fig-bsc]]
|
||||
.Integration of legacy E1 BTS in AoIP network
|
||||
[graphviz]
|
||||
----
|
||||
digraph G {
|
||||
rankdir = LR;
|
||||
BTS -> OsmoBSC [label="Abis/E1"];
|
||||
OsmoBSC -> "core-network" [label="3GPP AoIP"];
|
||||
OsmoBSC -> OsmoMGW [label="MGCP"];
|
||||
BTS -> OsmoMGW [label="TRAU/E1",dir=both];
|
||||
OsmoMGW -> "core-network" [label="RTP",dir=both];
|
||||
{rank=same OsmoBSC OsmoMGW}
|
||||
OsmoMGW [color=red];
|
||||
}
|
||||
----
|
||||
|
||||
=== Software Components
|
||||
|
||||
OsmoMGW contains a variety of different software components, which we’ll
|
||||
@@ -92,14 +77,14 @@ Transcoding is currently not supported in OsmoMGW.
|
||||
|
||||
=== Limitations
|
||||
|
||||
At the moment (November 2020), OsmoMGW implements RTP proxy / RTP bridge
|
||||
type endpoints and E1/T1 16k/8k sub-slots with TRAU frames for classic BTS
|
||||
support. To the RTP proxy / RTP bridge endpoints two RTP connections can
|
||||
be established, which then work as a tandem. E1/T1 endpoints support one
|
||||
RTP connection at a time that is associated with a sub-slot on an E1 line.
|
||||
We are planning to add further endpoint types for:
|
||||
Osmux is not yet supported in OsmoMGW.
|
||||
|
||||
At the moment (July 2018), OsmoMGW only implements RTP proxy / RTP bridge
|
||||
type endpoints, to each of which two RTP connections can be established.
|
||||
We are planning to add endpoint types for:
|
||||
|
||||
- classic E1/T1 timeslots (64kBps alaw/ulaw)
|
||||
- classic E1/T1 16k sub-slots with TRAU frames for classic BTS support
|
||||
- announcement/playout end-points
|
||||
- conference endpoints
|
||||
|
||||
|
||||
@@ -18,16 +18,12 @@ include::./common/chapters/logging.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/configuration.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/mgcp_endpoints.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/mgcp_extensions.adoc[]
|
||||
|
||||
include::./common/chapters/osmux/osmux.adoc[]
|
||||
|
||||
//include::{srcdir}/chapters/counters.adoc[]
|
||||
|
||||
include::./common/chapters/vty_cpu_sched.adoc[]
|
||||
|
||||
include::./common/chapters/port_numbers.adoc[]
|
||||
|
||||
include::./common/chapters/bibliography.adoc[]
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
@@ -95,8 +94,7 @@ typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
|
||||
*/
|
||||
struct mgcp_port_range {
|
||||
/* addr or NULL to fall-back to default */
|
||||
char *bind_addr_v4;
|
||||
char *bind_addr_v6;
|
||||
char *bind_addr;
|
||||
|
||||
/* dynamically allocated */
|
||||
int range_start;
|
||||
@@ -209,4 +207,4 @@ int mgcp_send_reset_all(struct mgcp_config *cfg);
|
||||
|
||||
|
||||
int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port);
|
||||
int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, char *buf, int len);
|
||||
int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
static const uint8_t e1_rates[] = { 64, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8 };
|
||||
static const uint8_t e1_offsets[] = { 0, 0, 4, 0, 2, 4, 6, 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
int mgcp_e1_init(struct mgcp_trunk *trunk, uint8_t ts_nr);
|
||||
int mgcp_e1_endp_equip(struct mgcp_endpoint *endp, uint8_t ts, uint8_t ss, uint8_t offs);
|
||||
void mgcp_e1_endp_update(struct mgcp_endpoint *endp);
|
||||
void mgcp_e1_endp_release(struct mgcp_endpoint *endp);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/i460_mux.h>
|
||||
|
||||
struct sockaddr;
|
||||
struct sockaddr_in;
|
||||
struct mgcp_conn;
|
||||
struct mgcp_conn_rtp;
|
||||
struct mgcp_endpoint;
|
||||
@@ -42,7 +42,7 @@ LOGP(cat, level, "endpoint:%s " fmt, \
|
||||
struct osmo_rtp_msg_ctx {
|
||||
int proto;
|
||||
struct mgcp_conn_rtp *conn_src;
|
||||
struct osmo_sockaddr *from_addr;
|
||||
struct sockaddr_in *from_addr;
|
||||
};
|
||||
|
||||
#define OSMO_RTP_MSG_CTX(MSGB) ((struct osmo_rtp_msg_ctx*)(MSGB)->cb)
|
||||
@@ -139,5 +139,3 @@ struct mgcp_endpoint *mgcp_endp_by_name_trunk(int *cause, const char *epname,
|
||||
struct mgcp_endpoint *mgcp_endp_by_name(int *cause, const char *epname,
|
||||
struct mgcp_config *cfg);
|
||||
bool mgcp_endp_avail(struct mgcp_endpoint *endp);
|
||||
void mgcp_endp_add_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
|
||||
void mgcp_endp_remove_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
|
||||
#define MGCP_DUMMY_LOAD 0x23
|
||||
@@ -81,8 +78,8 @@ struct mgcp_rtp_codec {
|
||||
|
||||
/* 'mgcp_rtp_end': basically a wrapper around the RTP+RTCP ports */
|
||||
struct mgcp_rtp_end {
|
||||
/* remote IP address of the RTP socket */
|
||||
struct osmo_sockaddr addr;
|
||||
/* local IP address of the RTP socket */
|
||||
struct in_addr addr;
|
||||
|
||||
/* in network byte order */
|
||||
int rtp_port, rtcp_port;
|
||||
@@ -118,21 +115,18 @@ struct mgcp_rtp_end {
|
||||
|
||||
/* local UDP port number of the RTP socket; RTCP is +1 */
|
||||
int local_port;
|
||||
/* where the endpoint RTP connection binds to, set during CRCX and
|
||||
* possibly updated during MDCX */
|
||||
char local_addr[INET6_ADDRSTRLEN];
|
||||
};
|
||||
|
||||
struct mgcp_rtp_tap {
|
||||
/* is this tap active (1) or not (0) */
|
||||
int enabled;
|
||||
/* IP/port to which we're forwarding the tapped data */
|
||||
struct osmo_sockaddr forward;
|
||||
struct sockaddr_in forward;
|
||||
};
|
||||
|
||||
struct mgcp_conn;
|
||||
|
||||
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,
|
||||
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,
|
||||
struct msgb *msg, struct mgcp_conn_rtp *conn_src,
|
||||
struct mgcp_conn_rtp *conn_dst);
|
||||
int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);
|
||||
@@ -146,7 +140,7 @@ void mgcp_free_rtp_port(struct mgcp_rtp_end *end);
|
||||
void mgcp_patch_and_count(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr, struct msgb *msg);
|
||||
struct sockaddr_in *addr, struct msgb *msg);
|
||||
void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn);
|
||||
int mgcp_set_ip_tos(int fd, int tos);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/gsm/i460_mux.h>
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
|
||||
#define LOGPTRUNK(trunk, cat, level, fmt, args...) \
|
||||
LOGP(cat, level, "trunk:%u " fmt, \
|
||||
@@ -25,6 +24,7 @@ struct mgcp_trunk {
|
||||
char *audio_fmtp_extra;
|
||||
int audio_send_ptime;
|
||||
int audio_send_name;
|
||||
int audio_loop;
|
||||
|
||||
int no_audio_transcoding;
|
||||
|
||||
@@ -60,11 +60,9 @@ struct mgcp_trunk {
|
||||
/* E1 specific */
|
||||
struct {
|
||||
unsigned int vty_line_nr;
|
||||
bool ts_in_use[NUM_E1_TS-1];
|
||||
struct osmo_i460_timeslot i460_ts[NUM_E1_TS-1];
|
||||
/* Note: on an E1 line TS 0 is devoted to framing and
|
||||
* alignment and therefore only NUM_E1_TS-1 timeslots
|
||||
* are available for traffic. */
|
||||
struct e1inp_line *line;
|
||||
bool ts_in_use[31];
|
||||
struct osmo_i460_timeslot i460_ts[31];
|
||||
} e1;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
|
||||
#include <osmocom/netif/osmux.h>
|
||||
struct mgcp_conn_rtp;
|
||||
@@ -14,7 +13,7 @@ enum {
|
||||
|
||||
int osmux_init(int role, struct mgcp_config *cfg);
|
||||
int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
|
||||
struct osmo_sockaddr *addr, uint16_t port);
|
||||
struct in_addr *addr, uint16_t port);
|
||||
void conn_osmux_disable(struct mgcp_conn_rtp *conn);
|
||||
int conn_osmux_allocate_cid(struct mgcp_conn_rtp *conn, int osmux_cid);
|
||||
void conn_osmux_release_cid(struct mgcp_conn_rtp *conn);
|
||||
|
||||
@@ -6,7 +6,3 @@ enum mgcp_vty_node {
|
||||
MGCP_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
TRUNK_NODE,
|
||||
};
|
||||
|
||||
enum mgw_vty_cmd_attr {
|
||||
MGW_CMD_ATTR_NEWCONN = 0,
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <osmocom/mgcp_client/mgcp_common.h>
|
||||
|
||||
/* See also: RFC 3435, chapter 3.5 Transmission over UDP */
|
||||
#define MGCP_CLIENT_LOCAL_ADDR_DEFAULT NULL /* INADDR(6)_ANY */
|
||||
#define MGCP_CLIENT_LOCAL_ADDR_DEFAULT "0.0.0.0"
|
||||
#define MGCP_CLIENT_LOCAL_PORT_DEFAULT 2727
|
||||
#define MGCP_CLIENT_REMOTE_ADDR_DEFAULT "127.0.0.1"
|
||||
#define MGCP_CLIENT_REMOTE_PORT_DEFAULT 2427
|
||||
@@ -75,7 +75,7 @@ struct mgcp_response {
|
||||
char *body;
|
||||
struct mgcp_response_head head;
|
||||
uint16_t audio_port;
|
||||
char audio_ip[INET6_ADDRSTRLEN];
|
||||
char audio_ip[INET_ADDRSTRLEN];
|
||||
unsigned int ptime;
|
||||
enum mgcp_codecs codecs[MGCP_MAX_CODECS];
|
||||
unsigned int codecs_len;
|
||||
@@ -133,7 +133,7 @@ int mgcp_client_connect(struct mgcp_client *mgcp);
|
||||
|
||||
const char *mgcp_client_remote_addr_str(struct mgcp_client *mgcp);
|
||||
uint16_t mgcp_client_remote_port(struct mgcp_client *mgcp);
|
||||
uint32_t mgcp_client_remote_addr_n(struct mgcp_client *mgcp) OSMO_DEPRECATED("deprecated, returns 0");
|
||||
uint32_t mgcp_client_remote_addr_n(struct mgcp_client *mgcp);
|
||||
|
||||
const char *mgcp_client_endpoint_domain(const struct mgcp_client *mgcp);
|
||||
const char *mgcp_client_rtpbridge_wildcard(const struct mgcp_client *mgcp);
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
* (either remote or local). It is used to pass parameters (local) to the FSM
|
||||
* and get responses (remote) from the FSM as pointer attached to the FSM
|
||||
* event.
|
||||
*
|
||||
*
|
||||
* When modifiying a connection, the endpoint and call_id members may be left
|
||||
* unpopulated. The call_id field is ignored in this case. If an endpoint
|
||||
* identifier is supplied it is checked against the internal state to make
|
||||
* sure it is correct. */
|
||||
struct mgcp_conn_peer {
|
||||
/*! RTP connection IP-Address (optional, string e.g. "127.0.0.1") */
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
|
||||
/*! RTP connection IP-Port (optional) */
|
||||
uint16_t port;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
struct mgcp_client {
|
||||
struct mgcp_client_conf actual;
|
||||
uint32_t remote_addr;
|
||||
struct osmo_wqueue wq;
|
||||
mgcp_trans_id_t next_trans_id;
|
||||
struct llist_head responses_pending;
|
||||
|
||||
@@ -9,7 +9,6 @@ AM_CFLAGS = \
|
||||
-Wall \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOVTY_CFLAGS) \
|
||||
$(LIBOSMOABIS_CFLAGS) \
|
||||
$(COVERAGE_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
@@ -21,7 +20,7 @@ AM_LDFLAGS = \
|
||||
|
||||
# This is not at all related to the release version, but a range of supported
|
||||
# API versions. Read TODO_RELEASE in the source tree's root!
|
||||
MGCP_CLIENT_LIBVERSION=8:0:0
|
||||
MGCP_CLIENT_LIBVERSION=7:0:1
|
||||
|
||||
lib_LTLIBRARIES = \
|
||||
libosmo-mgcp-client.la \
|
||||
|
||||
@@ -25,13 +25,10 @@
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/byteswap.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
|
||||
#include <osmocom/mgcp_client/mgcp_client.h>
|
||||
#include <osmocom/mgcp_client/mgcp_client_internal.h>
|
||||
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
@@ -373,37 +370,22 @@ static int mgcp_parse_audio_ptime_rtpmap(struct mgcp_response *r, const char *li
|
||||
/* Parse a line like "c=IN IP4 10.11.12.13" */
|
||||
static int mgcp_parse_audio_ip(struct mgcp_response *r, const char *line)
|
||||
{
|
||||
struct in6_addr ip_test;
|
||||
bool is_ipv6;
|
||||
struct in_addr ip_test;
|
||||
|
||||
if (strncmp("c=IN IP", line, 7) != 0)
|
||||
if (strlen(line) < 16)
|
||||
goto response_parse_failure;
|
||||
|
||||
/* The current implementation strictly supports IPV4 only ! */
|
||||
if (memcmp("c=IN IP4 ", line, 9) != 0)
|
||||
goto response_parse_failure;
|
||||
|
||||
/* Extract IP-Address */
|
||||
osmo_strlcpy(r->audio_ip, line + 9, sizeof(r->audio_ip));
|
||||
|
||||
/* Check IP-Address */
|
||||
if (inet_aton(r->audio_ip, &ip_test) == 0)
|
||||
goto response_parse_failure;
|
||||
line += 7;
|
||||
if (*line == '6')
|
||||
is_ipv6 = true;
|
||||
else if (*line == '4')
|
||||
is_ipv6 = false;
|
||||
else
|
||||
goto response_parse_failure;
|
||||
line++;
|
||||
if (*line != ' ')
|
||||
goto response_parse_failure;
|
||||
line++;
|
||||
|
||||
/* Extract and check IP-Address */
|
||||
if (is_ipv6) {
|
||||
/* 45 = INET6_ADDRSTRLEN -1 */
|
||||
if (sscanf(line, "%45s", r->audio_ip) != 1)
|
||||
goto response_parse_failure;
|
||||
if (inet_pton(AF_INET6, r->audio_ip, &ip_test) != 1)
|
||||
goto response_parse_failure;
|
||||
} else {
|
||||
/* 15 = INET_ADDRSTRLEN -1 */
|
||||
if (sscanf(line, "%15s", r->audio_ip) != 1)
|
||||
goto response_parse_failure;
|
||||
if (inet_pton(AF_INET, r->audio_ip, &ip_test) != 1)
|
||||
goto response_parse_failure;
|
||||
}
|
||||
return 0;
|
||||
|
||||
response_parse_failure:
|
||||
@@ -796,7 +778,7 @@ static int init_socket(struct mgcp_client *mgcp)
|
||||
|
||||
/* Initalize socket with the currently configured port
|
||||
* number */
|
||||
rc = osmo_sock_init2_ofd(&wq->bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, mgcp->actual.local_addr,
|
||||
rc = osmo_sock_init2_ofd(&wq->bfd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, mgcp->actual.local_addr,
|
||||
mgcp->actual.local_port, mgcp->actual.remote_addr, mgcp->actual.remote_port,
|
||||
OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT);
|
||||
if (rc > 0)
|
||||
@@ -825,6 +807,7 @@ static int init_socket(struct mgcp_client *mgcp)
|
||||
* \returns 0 on success, -EINVAL on error. */
|
||||
int mgcp_client_connect(struct mgcp_client *mgcp)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct osmo_wqueue *wq;
|
||||
int rc;
|
||||
|
||||
@@ -834,11 +817,6 @@ int mgcp_client_connect(struct mgcp_client *mgcp)
|
||||
}
|
||||
|
||||
wq = &mgcp->wq;
|
||||
osmo_wqueue_init(wq, 1024);
|
||||
wq->read_cb = mgcp_do_read;
|
||||
wq->write_cb = mgcp_do_write;
|
||||
|
||||
osmo_fd_setup(&wq->bfd, -1, OSMO_FD_READ, osmo_wqueue_bfd_cb, mgcp, 0);
|
||||
|
||||
rc = init_socket(mgcp);
|
||||
if (rc < 0) {
|
||||
@@ -849,6 +827,14 @@ int mgcp_client_connect(struct mgcp_client *mgcp)
|
||||
goto error_close_fd;
|
||||
}
|
||||
|
||||
inet_aton(mgcp->actual.remote_addr, &addr.sin_addr);
|
||||
mgcp->remote_addr = htonl(addr.sin_addr.s_addr);
|
||||
|
||||
osmo_wqueue_init(wq, 1024);
|
||||
wq->bfd.when = OSMO_FD_READ;
|
||||
wq->bfd.data = mgcp;
|
||||
wq->read_cb = mgcp_do_read;
|
||||
wq->write_cb = mgcp_do_write;
|
||||
|
||||
LOGP(DLMGCP, LOGL_INFO, "MGCP GW connection: %s\n", osmo_sock_get_name2(wq->bfd.fd));
|
||||
|
||||
@@ -875,13 +861,12 @@ uint16_t mgcp_client_remote_port(struct mgcp_client *mgcp)
|
||||
return mgcp->actual.remote_port;
|
||||
}
|
||||
|
||||
/*! Get the IP-Address of the associated MGW as its numeric representation.
|
||||
* DEPRECATED, DON'T USE.
|
||||
/*! Get the IP-Aaddress of the associated MGW as its numeric representation.
|
||||
* \param[in] mgcp MGCP client descriptor.
|
||||
* \returns IP-Address as 32 bit integer (network byte order) */
|
||||
uint32_t mgcp_client_remote_addr_n(struct mgcp_client *mgcp)
|
||||
{
|
||||
return 0;
|
||||
return mgcp->remote_addr;
|
||||
}
|
||||
|
||||
/* To compose endpoint names, usually for CRCX, use this as domain name.
|
||||
@@ -959,7 +944,7 @@ const char *mgcp_client_e1_epname(void *ctx, const struct mgcp_client *mgcp, uin
|
||||
|
||||
/* An E1 line has a maximum of 32 timeslots, while the first (ts=0) is
|
||||
* reserverd for framing and alignment, so we can not use it here. */
|
||||
if (ts == 0 || ts > NUM_E1_TS-1) {
|
||||
if (ts == 0 || ts > 31) {
|
||||
LOGP(DLMGCP, LOGL_ERROR,
|
||||
"Cannot compose MGCP e1-endpoint name (%s), E1-timeslot number (%u) is invalid!\n", epname, ts);
|
||||
talloc_free(epname);
|
||||
@@ -1136,8 +1121,7 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
|
||||
{
|
||||
unsigned int i;
|
||||
int rc = 0;
|
||||
char local_ip[INET6_ADDRSTRLEN];
|
||||
int local_ip_family, audio_ip_family;
|
||||
char local_ip[INET_ADDRSTRLEN];
|
||||
const char *codec;
|
||||
unsigned int pt;
|
||||
|
||||
@@ -1154,21 +1138,10 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
|
||||
msgb_free(msg);
|
||||
return -2;
|
||||
}
|
||||
local_ip_family = osmo_ip_str_type(local_ip);
|
||||
if (local_ip_family == AF_UNSPEC) {
|
||||
msgb_free(msg);
|
||||
return -2;
|
||||
}
|
||||
audio_ip_family = osmo_ip_str_type(mgcp_msg->audio_ip);
|
||||
if (audio_ip_family == AF_UNSPEC) {
|
||||
msgb_free(msg);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Add owner/creator (SDP) */
|
||||
rc += msgb_printf(msg, "o=- %x 23 IN IP%c %s\r\n", mgcp_msg->call_id,
|
||||
local_ip_family == AF_INET6 ? '6' : '4',
|
||||
local_ip);
|
||||
rc += msgb_printf(msg, "o=- %x 23 IN IP4 %s\r\n",
|
||||
mgcp_msg->call_id, local_ip);
|
||||
|
||||
/* Add session name (none) */
|
||||
rc += msgb_printf(msg, "s=-\r\n");
|
||||
@@ -1186,9 +1159,7 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
|
||||
msgb_free(msg);
|
||||
return -2;
|
||||
}
|
||||
rc += msgb_printf(msg, "c=IN IP%c %s\r\n",
|
||||
audio_ip_family == AF_INET6 ? '6' : '4',
|
||||
mgcp_msg->audio_ip);
|
||||
rc += msgb_printf(msg, "c=IN IP4 %s\r\n", mgcp_msg->audio_ip);
|
||||
|
||||
/* Add time description, active time (SDP) */
|
||||
rc += msgb_printf(msg, "t=0 0\r\n");
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <osmocom/core/fsm.h>
|
||||
#include <osmocom/core/byteswap.h>
|
||||
#include <osmocom/core/tdef.h>
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
|
||||
#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
|
||||
|
||||
@@ -236,6 +235,8 @@ static void fill_event_names()
|
||||
}
|
||||
}
|
||||
|
||||
/* T_defs is used to obtain an (Osmocom specific) T2427001: timeout for an MGCP response (note, 2427 corresponds to the
|
||||
* default MGCP port in osmo-mgw). */
|
||||
static __attribute__((constructor)) void osmo_mgcpc_ep_fsm_init()
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&osmo_mgcpc_ep_fsm) == 0);
|
||||
@@ -467,12 +468,14 @@ static void on_success(struct osmo_mgcpc_ep_ci *ci, void *data)
|
||||
|
||||
ci->pending = false;
|
||||
|
||||
rtp_info = data;
|
||||
|
||||
switch (ci->verb) {
|
||||
case MGCP_VERB_CRCX:
|
||||
/* If we sent a wildcarded endpoint name on CRCX, we need to store the resulting endpoint
|
||||
* name here. Also, we receive the MGW's RTP port information. */
|
||||
rtp_info = data;
|
||||
OSMO_ASSERT(rtp_info);
|
||||
ci->got_port_info = true;
|
||||
ci->rtp_info = *rtp_info;
|
||||
osmo_strlcpy(ci->mgcp_ci_str, mgcp_conn_get_ci(ci->mgcp_client_fi),
|
||||
sizeof(ci->mgcp_ci_str));
|
||||
if (rtp_info->endpoint[0]) {
|
||||
@@ -482,15 +485,6 @@ static void on_success(struct osmo_mgcpc_ep_ci *ci, void *data)
|
||||
return;
|
||||
}
|
||||
ci->ep->first_crcx_complete = true;
|
||||
OSMO_ASSERT(rtp_info);
|
||||
/* fall through */
|
||||
case MGCP_VERB_MDCX:
|
||||
/* Always update the received RTP ip/port information, since MGW
|
||||
* may provide new one after remote end params changed */
|
||||
if (rtp_info) {
|
||||
ci->got_port_info = true;
|
||||
ci->rtp_info = *rtp_info;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -523,33 +517,17 @@ const struct mgcp_conn_peer *osmo_mgcpc_ep_ci_get_rtp_info(const struct osmo_mgc
|
||||
bool osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(const struct osmo_mgcpc_ep_ci *ci, struct sockaddr_storage *dest)
|
||||
{
|
||||
const struct mgcp_conn_peer *rtp_info;
|
||||
int family;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
rtp_info = osmo_mgcpc_ep_ci_get_rtp_info(ci);
|
||||
if (!rtp_info)
|
||||
return false;
|
||||
|
||||
family = osmo_ip_str_type(rtp_info->addr);
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)dest;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = osmo_ntohs(rtp_info->port);
|
||||
if (inet_pton(AF_INET, rtp_info->addr, &sin->sin_addr) != 1)
|
||||
return false;
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)dest;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = osmo_ntohs(rtp_info->port);
|
||||
if (inet_pton(AF_INET6, rtp_info->addr, &sin6->sin6_addr) != 1)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
sin = (struct sockaddr_in *)dest;
|
||||
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = inet_addr(rtp_info->addr);
|
||||
sin->sin_port = osmo_ntohs(rtp_info->port);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -569,7 +547,7 @@ bool osmo_mgcpc_ep_ci_get_crcx_info_to_osmux_cid(const struct osmo_mgcpc_ep_ci *
|
||||
}
|
||||
|
||||
static const struct osmo_tdef_state_timeout osmo_mgcpc_ep_fsm_timeouts[32] = {
|
||||
[OSMO_MGCPC_EP_ST_WAIT_MGW_RESPONSE] = { .T=-2427 },
|
||||
[OSMO_MGCPC_EP_ST_WAIT_MGW_RESPONSE] = { .T=2427001 },
|
||||
};
|
||||
|
||||
/* Transition to a state, using the T timer defined in assignment_fsm_timeouts.
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <osmocom/core/byteswap.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
|
||||
/* Context information, this is attached to the priv pointer of the FSM and
|
||||
* is also handed back when dispatcheing events to the parent FSM. This is
|
||||
@@ -523,8 +522,8 @@ static void fsm_cleanup_cb(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause ca
|
||||
* connection. This is not the normal case. The user should always use
|
||||
* mgcp_conn_delete() to instruct the FSM to perform a graceful exit */
|
||||
if (strlen(mgcp_ctx->conn_id)) {
|
||||
LOGPFSML(fi, LOGL_NOTICE,
|
||||
"MGW/DLCX: FSM termination with connections still present, sending unconditional DLCX...\n");
|
||||
LOGPFSML(fi, LOGL_ERROR,
|
||||
"MGW/DLCX: abrupt FSM termination with connections still present, sending unconditional DLCX...\n");
|
||||
msg = make_dlcx_msg(mgcp_ctx);
|
||||
if (!msg)
|
||||
LOGPFSML(fi, LOGL_ERROR, "MGW/DLCX: Error composing DLCX message\n");
|
||||
@@ -608,16 +607,14 @@ struct osmo_fsm_inst *mgcp_conn_create(struct mgcp_client *mgcp, struct osmo_fsm
|
||||
{
|
||||
struct mgcp_ctx *mgcp_ctx;
|
||||
struct osmo_fsm_inst *fi;
|
||||
struct in6_addr ip_test;
|
||||
|
||||
struct in_addr ip_test;
|
||||
|
||||
OSMO_ASSERT(parent_fi);
|
||||
OSMO_ASSERT(mgcp);
|
||||
OSMO_ASSERT(conn_peer);
|
||||
|
||||
/* Check if IP/Port information in conn info makes sense */
|
||||
if (conn_peer->port && inet_pton(osmo_ip_str_type(conn_peer->addr),
|
||||
conn_peer->addr, &ip_test) != 1)
|
||||
if (conn_peer->port && inet_aton(conn_peer->addr, &ip_test) == 0)
|
||||
return NULL;
|
||||
|
||||
/* Allocate and configure a new fsm instance */
|
||||
@@ -647,7 +644,7 @@ int mgcp_conn_modify(struct osmo_fsm_inst *fi, uint32_t parent_evt, struct mgcp_
|
||||
{
|
||||
OSMO_ASSERT(fi);
|
||||
struct mgcp_ctx *mgcp_ctx = fi->priv;
|
||||
struct in6_addr ip_test;
|
||||
struct in_addr ip_test;
|
||||
|
||||
OSMO_ASSERT(mgcp_ctx);
|
||||
OSMO_ASSERT(conn_peer);
|
||||
@@ -671,8 +668,8 @@ int mgcp_conn_modify(struct osmo_fsm_inst *fi, uint32_t parent_evt, struct mgcp_
|
||||
LOGPFSML(fi, LOGL_ERROR, "Cannot MDCX, port == 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (inet_pton(osmo_ip_str_type(conn_peer->addr), conn_peer->addr, &ip_test) != 1) {
|
||||
LOGPFSML(fi, LOGL_ERROR, "Cannot MDCX, IP address %s\n", conn_peer->addr);
|
||||
if (inet_aton(conn_peer->addr, &ip_test) == 0) {
|
||||
LOGPFSML(fi, LOGL_ERROR, "Cannot MDCX, IP address == 0.0.0.0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,9 @@ void *global_mgcp_client_ctx = NULL;
|
||||
struct mgcp_client_conf *global_mgcp_client_conf = NULL;
|
||||
|
||||
DEFUN(cfg_mgw_local_ip, cfg_mgw_local_ip_cmd,
|
||||
"mgw local-ip " VTY_IPV46_CMD,
|
||||
"mgw local-ip A.B.C.D",
|
||||
MGW_STR "local bind to connect to MGW from\n"
|
||||
"local bind IPv4 address\n"
|
||||
"local bind IPv6 address\n")
|
||||
"local bind IP address\n")
|
||||
{
|
||||
if (!global_mgcp_client_conf)
|
||||
return CMD_ERR_NOTHING_TODO;
|
||||
@@ -70,10 +69,9 @@ ALIAS_DEPRECATED(cfg_mgw_local_port, cfg_mgcpgw_local_port_cmd,
|
||||
"local bind port\n")
|
||||
|
||||
DEFUN(cfg_mgw_remote_ip, cfg_mgw_remote_ip_cmd,
|
||||
"mgw remote-ip " VTY_IPV46_CMD,
|
||||
"mgw remote-ip A.B.C.D",
|
||||
MGW_STR "remote IP address to reach the MGW at\n"
|
||||
"remote IPv4 address\n"
|
||||
"remote IPv6 address\n")
|
||||
"remote IP address\n")
|
||||
{
|
||||
if (!global_mgcp_client_conf)
|
||||
return CMD_ERR_NOTHING_TODO;
|
||||
@@ -190,21 +188,21 @@ void mgcp_client_vty_init(void *talloc_ctx, int node, struct mgcp_client_conf *c
|
||||
global_mgcp_client_ctx = talloc_ctx;
|
||||
global_mgcp_client_conf = conf;
|
||||
|
||||
install_lib_element(node, &cfg_mgw_local_ip_cmd);
|
||||
install_lib_element(node, &cfg_mgw_local_port_cmd);
|
||||
install_lib_element(node, &cfg_mgw_remote_ip_cmd);
|
||||
install_lib_element(node, &cfg_mgw_remote_port_cmd);
|
||||
install_lib_element(node, &cfg_mgw_endpoint_range_cmd);
|
||||
install_lib_element(node, &cfg_mgw_rtp_bts_base_port_cmd);
|
||||
install_lib_element(node, &cfg_mgw_endpoint_domain_name_cmd);
|
||||
install_element(node, &cfg_mgw_local_ip_cmd);
|
||||
install_element(node, &cfg_mgw_local_port_cmd);
|
||||
install_element(node, &cfg_mgw_remote_ip_cmd);
|
||||
install_element(node, &cfg_mgw_remote_port_cmd);
|
||||
install_element(node, &cfg_mgw_endpoint_range_cmd);
|
||||
install_element(node, &cfg_mgw_rtp_bts_base_port_cmd);
|
||||
install_element(node, &cfg_mgw_endpoint_domain_name_cmd);
|
||||
|
||||
/* deprecated 'mgcpgw' commands */
|
||||
install_lib_element(node, &cfg_mgcpgw_local_ip_cmd);
|
||||
install_lib_element(node, &cfg_mgcpgw_local_port_cmd);
|
||||
install_lib_element(node, &cfg_mgcpgw_remote_ip_cmd);
|
||||
install_lib_element(node, &cfg_mgcpgw_remote_port_cmd);
|
||||
install_lib_element(node, &cfg_mgcpgw_endpoint_range_cmd);
|
||||
install_lib_element(node, &cfg_mgcpgw_rtp_bts_base_port_cmd);
|
||||
install_element(node, &cfg_mgcpgw_local_ip_cmd);
|
||||
install_element(node, &cfg_mgcpgw_local_port_cmd);
|
||||
install_element(node, &cfg_mgcpgw_remote_ip_cmd);
|
||||
install_element(node, &cfg_mgcpgw_remote_port_cmd);
|
||||
install_element(node, &cfg_mgcpgw_endpoint_range_cmd);
|
||||
install_element(node, &cfg_mgcpgw_rtp_bts_base_port_cmd);
|
||||
|
||||
osmo_fsm_vty_add_cmds();
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ struct mgcp_conn *mgcp_conn_alloc(void *ctx, struct mgcp_endpoint *endp,
|
||||
/* Initialize watchdog */
|
||||
osmo_timer_setup(&conn->watchdog, mgcp_conn_watchdog_cb, conn);
|
||||
mgcp_conn_watchdog_kick(conn);
|
||||
mgcp_endp_add_conn(endp, conn);
|
||||
llist_add(&conn->entry, &endp->conns);
|
||||
|
||||
return conn;
|
||||
}
|
||||
@@ -289,6 +289,12 @@ void mgcp_conn_free(struct mgcp_endpoint *endp, const char *id)
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
/* Run endpoint cleanup action. By this we inform the endpoint about
|
||||
* the removal of the connection and allow it to clean up its inner
|
||||
* state accordingly */
|
||||
if (endp->type->cleanup_cb)
|
||||
endp->type->cleanup_cb(endp, conn);
|
||||
|
||||
switch (conn->type) {
|
||||
case MGCP_CONN_TYPE_RTP:
|
||||
aggregate_rtp_conn_stats(endp, &conn->u.rtp);
|
||||
@@ -302,8 +308,7 @@ void mgcp_conn_free(struct mgcp_endpoint *endp, const char *id)
|
||||
}
|
||||
|
||||
osmo_timer_del(&conn->watchdog);
|
||||
mgcp_endp_remove_conn(endp, conn);
|
||||
/* WARN: endp may have be freed after call to mgcp_endp_remove_conn */
|
||||
llist_del(&conn->entry);
|
||||
talloc_free(conn);
|
||||
}
|
||||
|
||||
@@ -344,7 +349,6 @@ void mgcp_conn_free_all(struct mgcp_endpoint *endp)
|
||||
char *mgcp_conn_dump(struct mgcp_conn *conn)
|
||||
{
|
||||
static char str[sizeof(conn->name)+sizeof(conn->id)+256];
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (!conn) {
|
||||
snprintf(str, sizeof(str), "(null connection)");
|
||||
@@ -358,7 +362,7 @@ char *mgcp_conn_dump(struct mgcp_conn *conn)
|
||||
"rtp:%u rtcp:%u)",
|
||||
conn->name,
|
||||
conn->id,
|
||||
osmo_sockaddr_ntop(&conn->u.rtp.end.addr.u.sa, ipbuf),
|
||||
inet_ntoa(conn->u.rtp.end.addr),
|
||||
ntohs(conn->u.rtp.end.rtp_port),
|
||||
ntohs(conn->u.rtp.end.rtcp_port));
|
||||
break;
|
||||
|
||||
@@ -361,7 +361,11 @@ static void e1_recv_cb(struct e1inp_ts *ts, struct msgb *msg)
|
||||
e1_send(ts, trunk);
|
||||
}
|
||||
|
||||
static int e1_init(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
/*! Find an endpoint by its name on a specified trunk.
|
||||
* \param[in] trunk trunk configuration.
|
||||
* \param[in] ts_nr E1 timeslot number.
|
||||
* \returns -EINVAL on failure, 0 on success. */
|
||||
int mgcp_e1_init(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
{
|
||||
/*! Each timeslot needs only to be configured once. The Timeslot then
|
||||
* stays open and permanently receives data. It is then up to the
|
||||
@@ -381,25 +385,26 @@ static int e1_init(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
}
|
||||
|
||||
/* Get E1 line */
|
||||
e1_line = e1inp_line_find(trunk->e1.vty_line_nr);
|
||||
if (!e1_line) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_DEBUG, "no such E1 line %u - check VTY config!\n",
|
||||
trunk->e1.vty_line_nr);
|
||||
if (!trunk->e1.line) {
|
||||
e1_line = e1inp_line_find(trunk->e1.vty_line_nr);
|
||||
if (!e1_line) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_DEBUG, "no such E1 line %u - check VTY config!\n",
|
||||
trunk->e1.vty_line_nr);
|
||||
return -EINVAL;
|
||||
}
|
||||
e1inp_line_bind_ops(e1_line, &dummy_e1_line_ops);
|
||||
} else
|
||||
e1_line = trunk->e1.line;
|
||||
if (!e1_line)
|
||||
return -EINVAL;
|
||||
}
|
||||
e1inp_line_bind_ops(e1_line, &dummy_e1_line_ops);
|
||||
|
||||
/* Configure E1 timeslot */
|
||||
rc = e1inp_ts_config_raw(&e1_line->ts[ts_nr - 1], e1_line, e1_recv_cb);
|
||||
if (rc < 0) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "failed to put E1 timeslot %u in raw mode.\n", ts_nr);
|
||||
if (rc < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = e1inp_line_update(e1_line);
|
||||
if (rc < 0) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "failed to update E1 timeslot %u.\n", ts_nr);
|
||||
e1inp_line_update(e1_line);
|
||||
if (rc < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOGPTRUNK(trunk, DE1, LOGL_DEBUG, "E1 timeslot %u set up successfully.\n", ts_nr);
|
||||
trunk->e1.ts_in_use[ts_nr - 1] = true;
|
||||
@@ -513,7 +518,7 @@ int mgcp_e1_endp_equip(struct mgcp_endpoint *endp, uint8_t ts, uint8_t ss, uint8
|
||||
endp->e1.last_amr_ft = AMR_4_75;
|
||||
|
||||
/* Set up E1 line / timeslot */
|
||||
rc = e1_init(endp->trunk, ts);
|
||||
rc = mgcp_e1_init(endp->trunk, ts);
|
||||
if (rc != 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <osmocom/mgcp/mgcp_endp.h>
|
||||
#include <osmocom/mgcp/mgcp_trunk.h>
|
||||
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
#include <osmocom/mgcp/mgcp_e1.h>
|
||||
|
||||
#define E1_TIMESLOTS 32
|
||||
#define E1_RATE_MAX 64
|
||||
#define E1_OFFS_MAX 8
|
||||
|
||||
@@ -375,7 +375,7 @@ static uint8_t e1_ts_nr_from_epname(const char *epname)
|
||||
if (strncmp(token, "s-", 2) == 0) {
|
||||
errno = 0;
|
||||
res = strtoul(token + 2, NULL, 10);
|
||||
if (errno == ERANGE || res > NUM_E1_TS)
|
||||
if (errno == ERANGE || res > E1_TIMESLOTS)
|
||||
return 0xff;
|
||||
return (uint8_t) res;
|
||||
}
|
||||
@@ -641,7 +641,8 @@ int mgcp_endp_claim(struct mgcp_endpoint *endp, const char *callid)
|
||||
OSMO_ASSERT(false);
|
||||
}
|
||||
|
||||
/* Make sure the endpoint is released when claiming the endpoint fails. */
|
||||
/* Make sure the endpoint is released when claiming the endpoint
|
||||
* failes. */
|
||||
if (rc < 0)
|
||||
mgcp_endp_release(endp);
|
||||
|
||||
@@ -665,20 +666,3 @@ void mgcp_endp_update(struct mgcp_endpoint *endp)
|
||||
OSMO_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
void mgcp_endp_add_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn)
|
||||
{
|
||||
llist_add(&conn->entry, &endp->conns);
|
||||
}
|
||||
|
||||
void mgcp_endp_remove_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn)
|
||||
{
|
||||
/* Run endpoint cleanup action. By this we inform the endpoint about
|
||||
* the removal of the connection and allow it to clean up its inner
|
||||
* state accordingly */
|
||||
if (endp->type->cleanup_cb)
|
||||
endp->type->cleanup_cb(endp, conn);
|
||||
llist_del(&conn->entry);
|
||||
if (llist_empty(&endp->conns))
|
||||
mgcp_endp_release(endp);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ int mgcp_parse_conn_mode(const char *mode, struct mgcp_endpoint *endp,
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* Special handling for RTP connections */
|
||||
/* Special handling für RTP connections */
|
||||
if (conn->type == MGCP_CONN_TYPE_RTP) {
|
||||
conn->u.rtp.end.output_enabled =
|
||||
conn->mode & MGCP_CONN_SEND_ONLY ? 1 : 0;
|
||||
@@ -245,7 +245,7 @@ int mgcp_check_param(const struct mgcp_endpoint *endp, const char *line)
|
||||
/*! Check if the specified callid seems plausible.
|
||||
* \param[in] endp pointer to endpoint
|
||||
* \param{in] callid to verify
|
||||
* \returns 0 when callid seems plausible, -1 on error */
|
||||
* \returns 1 when callid seems plausible, 0 on error */
|
||||
int mgcp_verify_call_id(struct mgcp_endpoint *endp, const char *callid)
|
||||
{
|
||||
/*! This function compares the supplied callid with the called that is
|
||||
|
||||
@@ -77,16 +77,6 @@ static void rtpconn_rate_ctr_inc(struct mgcp_conn_rtp *conn_rtp, struct mgcp_end
|
||||
|
||||
static int rx_rtp(struct msgb *msg);
|
||||
|
||||
static bool addr_is_any(struct osmo_sockaddr *osa) {
|
||||
if (osa->u.sa.sa_family == AF_INET6) {
|
||||
struct in6_addr ip6_any = IN6ADDR_ANY_INIT;
|
||||
return memcmp(&osa->u.sin6.sin6_addr,
|
||||
&ip6_any, sizeof(ip6_any)) == 0;
|
||||
} else {
|
||||
return osa->u.sin.sin_addr.s_addr == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*! Determine the local rtp bind IP-address.
|
||||
* \param[out] addr caller provided memory to store the resulting IP-Address.
|
||||
* \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters.
|
||||
@@ -99,52 +89,39 @@ void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn)
|
||||
{
|
||||
|
||||
struct mgcp_endpoint *endp;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
int rc;
|
||||
endp = conn->conn->endp;
|
||||
bool rem_addr_set = !addr_is_any(&conn->end.addr);
|
||||
char *bind_addr;
|
||||
|
||||
/* Try probing the local IP-Address */
|
||||
if (endp->cfg->net_ports.bind_addr_probe && rem_addr_set) {
|
||||
rc = osmo_sock_local_ip(addr, osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));
|
||||
if (endp->cfg->net_ports.bind_addr_probe && conn->end.addr.s_addr != 0) {
|
||||
rc = osmo_sock_local_ip(addr, inet_ntoa(conn->end.addr));
|
||||
if (rc < 0)
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
|
||||
"local interface auto detection failed, using configured addresses...\n");
|
||||
else {
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
|
||||
"selected local rtp bind ip %s by probing using remote ip %s\n",
|
||||
addr, osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));
|
||||
addr, inet_ntoa(conn->end.addr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select from preconfigured IP-Addresses. We don't have bind_addr for Osmux (yet?). */
|
||||
if (rem_addr_set) {
|
||||
if (endp->cfg->net_ports.bind_addr) {
|
||||
/* Check there is a bind IP for the RTP traffic configured,
|
||||
* if so, use that IP-Address */
|
||||
bind_addr = conn->end.addr.u.sa.sa_family == AF_INET6 ?
|
||||
endp->cfg->net_ports.bind_addr_v6 :
|
||||
endp->cfg->net_ports.bind_addr_v4;
|
||||
} else {
|
||||
/* Choose any of the bind addresses, preferring v6 over v4 */
|
||||
bind_addr = endp->cfg->net_ports.bind_addr_v6;
|
||||
if (!bind_addr)
|
||||
bind_addr = endp->cfg->net_ports.bind_addr_v4;
|
||||
}
|
||||
if (bind_addr) {
|
||||
osmo_strlcpy(addr, endp->cfg->net_ports.bind_addr, INET_ADDRSTRLEN);
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
|
||||
"using configured rtp bind ip as local bind ip %s\n",
|
||||
bind_addr);
|
||||
addr);
|
||||
} else {
|
||||
/* No specific bind IP is configured for the RTP traffic, so
|
||||
* assume the IP where we listen for incoming MGCP messages
|
||||
* as bind IP */
|
||||
bind_addr = endp->cfg->source_addr;
|
||||
osmo_strlcpy(addr, endp->cfg->source_addr, INET_ADDRSTRLEN);
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
|
||||
"using mgcp bind ip as local rtp bind ip: %s\n", bind_addr);
|
||||
"using mgcp bind ip as local rtp bind ip: %s\n", addr);
|
||||
}
|
||||
osmo_strlcpy(addr, bind_addr, INET6_ADDRSTRLEN);
|
||||
}
|
||||
|
||||
/* This does not need to be a precision timestamp and
|
||||
@@ -177,26 +154,19 @@ static uint32_t get_current_ts(unsigned codec_rate)
|
||||
* \param[in] buf buffer that holds the data to be send.
|
||||
* \param[in] len length of the data to be sent.
|
||||
* \returns bytes sent, -1 on error. */
|
||||
int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, char *buf, int len)
|
||||
int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
size_t addr_len;
|
||||
bool is_ipv6 = addr->u.sa.sa_family == AF_INET6;
|
||||
struct sockaddr_in out;
|
||||
|
||||
LOGP(DRTP, LOGL_DEBUG,
|
||||
"sending %i bytes length packet to %s:%u ...\n", len,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
ntohs(port));
|
||||
"sending %i bytes length packet to %s:%u ...\n",
|
||||
len, inet_ntoa(*addr), ntohs(port));
|
||||
|
||||
if (is_ipv6) {
|
||||
addr->u.sin6.sin6_port = port;
|
||||
addr_len = sizeof(addr->u.sin6);
|
||||
} else {
|
||||
addr->u.sin.sin_port = port;
|
||||
addr_len = sizeof(addr->u.sin);
|
||||
}
|
||||
out.sin_family = AF_INET;
|
||||
out.sin_port = port;
|
||||
memcpy(&out.sin_addr, addr, sizeof(*addr));
|
||||
|
||||
return sendto(fd, buf, len, 0, &addr->u.sa, addr_len);
|
||||
return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
|
||||
}
|
||||
|
||||
/*! send RTP dummy packet (to keep NAT connection open).
|
||||
@@ -259,13 +229,12 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_stream_state *sstate,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr,
|
||||
struct sockaddr_in *addr,
|
||||
uint16_t seq, uint32_t timestamp,
|
||||
const char *text, int32_t * tsdelta_out)
|
||||
{
|
||||
int32_t tsdelta;
|
||||
int32_t timestamp_error;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
/* Not fully intialized, skip */
|
||||
if (sstate->last_tsdelta == 0 && timestamp == sstate->last_timestamp)
|
||||
@@ -282,9 +251,8 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp,
|
||||
"from %s:%d\n",
|
||||
text, seq,
|
||||
state->patch.timestamp_offset, state->patch.seq_offset,
|
||||
sstate->ssrc, timestamp,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
sstate->ssrc, timestamp, inet_ntoa(addr->sin_addr),
|
||||
ntohs(addr->sin_port));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -299,9 +267,9 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp,
|
||||
"The %s timestamp delta is %d "
|
||||
"on SSRC: %u timestamp: %u "
|
||||
"from %s:%d\n",
|
||||
text, tsdelta, sstate->ssrc, timestamp,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
text, tsdelta,
|
||||
sstate->ssrc, timestamp,
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -313,8 +281,7 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp,
|
||||
"on SSRC: %u timestamp: %u from %s:%d\n",
|
||||
text, sstate->last_tsdelta, tsdelta,
|
||||
sstate->ssrc, timestamp,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,8 +303,7 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp,
|
||||
(int16_t)(seq - sstate->last_seq),
|
||||
(int32_t)(timestamp - sstate->last_timestamp),
|
||||
tsdelta,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa),
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
|
||||
state->packet_duration);
|
||||
}
|
||||
return 1;
|
||||
@@ -347,13 +313,12 @@ static int check_rtp_timestamp(struct mgcp_endpoint *endp,
|
||||
static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr,
|
||||
struct sockaddr_in *addr,
|
||||
int16_t delta_seq, uint32_t in_timestamp)
|
||||
{
|
||||
int32_t tsdelta = state->packet_duration;
|
||||
int timestamp_offset;
|
||||
uint32_t out_timestamp;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (tsdelta == 0) {
|
||||
tsdelta = state->out_stream.last_tsdelta;
|
||||
@@ -362,8 +327,7 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
"A fixed packet duration is not available, "
|
||||
"using last output timestamp delta instead: %d "
|
||||
"from %s:%d\n", tsdelta,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
} else {
|
||||
tsdelta = rtp_end->codec->rate * 20 / 1000;
|
||||
LOGPENDP(endp, DRTP, LOGL_NOTICE,
|
||||
@@ -371,8 +335,7 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
"are not available, "
|
||||
"using fixed 20ms instead: %d "
|
||||
"from %s:%d\n", tsdelta,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,13 +344,13 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
|
||||
if (state->patch.timestamp_offset != timestamp_offset) {
|
||||
state->patch.timestamp_offset = timestamp_offset;
|
||||
|
||||
LOGPENDP(endp, DRTP, LOGL_NOTICE,
|
||||
"Timestamp offset change on SSRC: %u "
|
||||
"SeqNo delta: %d, TS offset: %d, "
|
||||
"from %s:%d\n", state->in_stream.ssrc,
|
||||
delta_seq, state->patch.timestamp_offset,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
}
|
||||
|
||||
return timestamp_offset;
|
||||
@@ -397,10 +360,9 @@ static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr,
|
||||
struct sockaddr_in *addr,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
int ts_error = 0;
|
||||
int ts_check = 0;
|
||||
int ptime = state->packet_duration;
|
||||
@@ -413,14 +375,14 @@ static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp,
|
||||
/* If there is an alignment error, we have to compensate it */
|
||||
if (ts_error) {
|
||||
state->patch.timestamp_offset += ptime - ts_error;
|
||||
|
||||
LOGPENDP(endp, DRTP, LOGL_NOTICE,
|
||||
"Corrected timestamp alignment error of %d on SSRC: %u "
|
||||
"new TS offset: %d, "
|
||||
"from %s:%d\n",
|
||||
ts_error, state->in_stream.ssrc,
|
||||
state->patch.timestamp_offset,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
state->patch.timestamp_offset, inet_ntoa(addr->sin_addr),
|
||||
ntohs(addr->sin_port));
|
||||
}
|
||||
|
||||
/* Check we really managed to compensate the timestamp
|
||||
@@ -559,9 +521,8 @@ static int mgcp_patch_pt(struct mgcp_conn_rtp *conn_src,
|
||||
void mgcp_patch_and_count(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr, struct msgb *msg)
|
||||
struct sockaddr_in *addr, struct msgb *msg)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
uint32_t arrival_time;
|
||||
int32_t transit;
|
||||
uint16_t seq;
|
||||
@@ -599,8 +560,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp,
|
||||
"pkt-duration: %d, from %s:%d\n",
|
||||
state->in_stream.ssrc,
|
||||
state->patch.seq_offset, state->packet_duration,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
if (state->packet_duration == 0) {
|
||||
state->packet_duration =
|
||||
rtp_end->codec->rate * 20 / 1000;
|
||||
@@ -608,16 +568,14 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp,
|
||||
"fixed packet duration is not available, "
|
||||
"using fixed 20ms instead: %d from %s:%d\n",
|
||||
state->packet_duration,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
}
|
||||
} else if (state->in_stream.ssrc != ssrc) {
|
||||
LOGPENDP(endp, DRTP, LOGL_NOTICE,
|
||||
"SSRC changed: %u -> %u "
|
||||
"from %s:%d\n",
|
||||
state->in_stream.ssrc, rtp_hdr->ssrc,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
|
||||
state->in_stream.ssrc = ssrc;
|
||||
if (rtp_end->force_constant_ssrc) {
|
||||
@@ -646,8 +604,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp,
|
||||
"SeqNo offset: %d, TS offset: %d "
|
||||
"from %s:%d\n", state->in_stream.ssrc,
|
||||
state->patch.seq_offset, state->patch.timestamp_offset,
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
|
||||
}
|
||||
|
||||
state->in_stream.last_tsdelta = 0;
|
||||
@@ -868,7 +825,7 @@ static void gen_rtp_header(struct msgb *msg, struct mgcp_rtp_end *rtp_end,
|
||||
* \param[in] conn_src associated source connection.
|
||||
* \param[in] conn_dst associated destination connection.
|
||||
* \returns 0 on success, -1 on ERROR. */
|
||||
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,
|
||||
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,
|
||||
struct msgb *msg, struct mgcp_conn_rtp *conn_src,
|
||||
struct mgcp_conn_rtp *conn_dst)
|
||||
{
|
||||
@@ -879,7 +836,6 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
|
||||
struct mgcp_trunk *trunk = endp->trunk;
|
||||
struct mgcp_rtp_end *rtp_end;
|
||||
struct mgcp_rtp_state *rtp_state;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
char *dest_name;
|
||||
int rc;
|
||||
int len;
|
||||
@@ -893,6 +849,10 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
|
||||
LOGPENDP(endp, DRTP, LOGL_DEBUG, "delivering RTCP packet...\n");
|
||||
}
|
||||
|
||||
LOGPENDP(endp, DRTP, LOGL_DEBUG, "loop:%d, mode:%d%s\n",
|
||||
trunk->audio_loop, conn_src->conn->mode,
|
||||
conn_src->conn->mode == MGCP_CONN_LOOPBACK ? " (loopback)" : "");
|
||||
|
||||
/* FIXME: It is legal that the payload type on the egress connection is
|
||||
* different from the payload type that has been negotiated on the
|
||||
* ingress connection. Essentially the codecs are the same so we can
|
||||
@@ -926,7 +886,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
|
||||
"output disabled, drop to %s %s "
|
||||
"rtp_port:%u rtcp_port:%u\n",
|
||||
dest_name,
|
||||
osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
|
||||
inet_ntoa(rtp_end->addr),
|
||||
ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
|
||||
);
|
||||
} else if (is_rtp) {
|
||||
@@ -972,8 +932,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
|
||||
LOGPENDP(endp, DRTP, LOGL_DEBUG,
|
||||
"process/send to %s %s "
|
||||
"rtp_port:%u rtcp_port:%u\n",
|
||||
dest_name,
|
||||
osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
|
||||
dest_name, inet_ntoa(rtp_end->addr),
|
||||
ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
|
||||
);
|
||||
|
||||
@@ -1016,7 +975,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
|
||||
} else if (!trunk->omit_rtcp) {
|
||||
LOGPENDP(endp, DRTP, LOGL_DEBUG,
|
||||
"send to %s %s rtp_port:%u rtcp_port:%u\n",
|
||||
dest_name, osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
|
||||
dest_name, inet_ntoa(rtp_end->addr),
|
||||
ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
|
||||
);
|
||||
|
||||
@@ -1036,11 +995,10 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
|
||||
|
||||
/* Check if the origin (addr) matches the address/port data of the RTP
|
||||
* connections. */
|
||||
static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *addr)
|
||||
static int check_rtp_origin(struct mgcp_conn_rtp *conn,
|
||||
struct sockaddr_in *addr)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (addr_is_any(&conn->end.addr)) {
|
||||
if (conn->end.addr.s_addr == 0) {
|
||||
switch (conn->conn->mode) {
|
||||
case MGCP_CONN_LOOPBACK:
|
||||
/* HACK: for IuUP, we want to reply with an IuUP Initialization ACK upon the first RTP
|
||||
@@ -1052,8 +1010,7 @@ static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *ad
|
||||
* MGCP port is in loopback mode, allow looping back the packet to any source. */
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
|
||||
"In loopback mode and remote address not set:"
|
||||
" allowing data from address: %s\n",
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf));
|
||||
" allowing data from address: %s\n", inet_ntoa(addr->sin_addr));
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@@ -1062,25 +1019,18 @@ static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *ad
|
||||
* confuse humans with expected errors. */
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_INFO,
|
||||
"Rx RTP from %s, but remote address not set:"
|
||||
" dropping early media\n",
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf));
|
||||
" dropping early media\n", inet_ntoa(addr->sin_addr));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: Check if the inbound RTP data comes from the same host to
|
||||
* which we send our outgoing RTP traffic. */
|
||||
if (conn->end.addr.u.sa.sa_family != addr->u.sa.sa_family ||
|
||||
(conn->end.addr.u.sa.sa_family == AF_INET &&
|
||||
conn->end.addr.u.sin.sin_addr.s_addr != addr->u.sin.sin_addr.s_addr) ||
|
||||
(conn->end.addr.u.sa.sa_family == AF_INET6 &&
|
||||
memcmp(&conn->end.addr.u.sin6.sin6_addr, &addr->u.sin6.sin6_addr,
|
||||
sizeof(struct in6_addr)))) {
|
||||
if (conn->end.addr.s_addr != addr->sin_addr.s_addr) {
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
|
||||
"data from wrong address: %s, ",
|
||||
osmo_sockaddr_ntop(&addr->u.sa, ipbuf));
|
||||
"data from wrong address: %s, ", inet_ntoa(addr->sin_addr));
|
||||
LOGPC(DRTP, LOGL_ERROR, "expected: %s\n",
|
||||
osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));
|
||||
inet_ntoa(conn->end.addr));
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR, "packet tossed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -1089,11 +1039,10 @@ static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *ad
|
||||
* the same as the remote port where we transmit outgoing RTP traffic
|
||||
* to (set by MDCX). We use this to check the origin of the data for
|
||||
* plausibility. */
|
||||
if (ntohs(conn->end.rtp_port) != osmo_sockaddr_port(&addr->u.sa) &&
|
||||
ntohs(conn->end.rtcp_port) != osmo_sockaddr_port(&addr->u.sa)) {
|
||||
if (conn->end.rtp_port != addr->sin_port &&
|
||||
conn->end.rtcp_port != addr->sin_port) {
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
|
||||
"data from wrong source port: %d, ",
|
||||
osmo_sockaddr_port(&addr->u.sa));
|
||||
"data from wrong source port: %d, ", ntohs(addr->sin_port));
|
||||
LOGPC(DRTP, LOGL_ERROR,
|
||||
"expected: %d for RTP or %d for RTCP\n",
|
||||
ntohs(conn->end.rtp_port), ntohs(conn->end.rtcp_port));
|
||||
@@ -1108,29 +1057,26 @@ static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *ad
|
||||
* makes sense */
|
||||
static int check_rtp_destin(struct mgcp_conn_rtp *conn)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
bool ip_is_any = addr_is_any(&conn->end.addr);
|
||||
|
||||
/* Note: it is legal to create a connection but never setting a port
|
||||
* and IP-address for outgoing data. */
|
||||
if (ip_is_any && conn->end.rtp_port == 0) {
|
||||
if (strcmp(inet_ntoa(conn->end.addr), "0.0.0.0") == 0 && conn->end.rtp_port == 0) {
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
|
||||
"destination IP-address and rtp port is (not yet) known (%s:%u)\n",
|
||||
osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);
|
||||
inet_ntoa(conn->end.addr), conn->end.rtp_port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ip_is_any) {
|
||||
if (strcmp(inet_ntoa(conn->end.addr), "0.0.0.0") == 0) {
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
|
||||
"destination IP-address is invalid (%s:%u)\n",
|
||||
osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);
|
||||
inet_ntoa(conn->end.addr), conn->end.rtp_port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->end.rtp_port == 0) {
|
||||
LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
|
||||
"destination rtp port is invalid (%s:%u)\n",
|
||||
osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);
|
||||
inet_ntoa(conn->end.addr), conn->end.rtp_port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1201,6 +1147,7 @@ static int mgcp_send_rtp(struct mgcp_conn_rtp *conn_dst, struct msgb *msg)
|
||||
struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
|
||||
enum rtp_proto proto = mc->proto;
|
||||
struct mgcp_conn_rtp *conn_src = mc->conn_src;
|
||||
struct sockaddr_in *from_addr = mc->from_addr;
|
||||
struct mgcp_endpoint *endp = conn_src->conn->endp;
|
||||
|
||||
LOGPENDP(endp, DRTP, LOGL_DEBUG, "destin conn:%s\n",
|
||||
@@ -1220,7 +1167,7 @@ static int mgcp_send_rtp(struct mgcp_conn_rtp *conn_dst, struct msgb *msg)
|
||||
"endpoint type is MGCP_RTP_DEFAULT, "
|
||||
"using mgcp_send() to forward data directly\n");
|
||||
return mgcp_send(endp, proto == MGCP_PROTO_RTP,
|
||||
mc->from_addr, msg, conn_src, conn_dst);
|
||||
from_addr, msg, conn_src, conn_dst);
|
||||
case MGCP_OSMUX_BSC_NAT:
|
||||
case MGCP_OSMUX_BSC:
|
||||
LOGPENDP(endp, DRTP, LOGL_DEBUG,
|
||||
@@ -1250,7 +1197,7 @@ int mgcp_dispatch_rtp_bridge_cb(struct msgb *msg)
|
||||
struct mgcp_conn_rtp *conn_src = mc->conn_src;
|
||||
struct mgcp_conn *conn = conn_src->conn;
|
||||
struct mgcp_conn *conn_dst;
|
||||
struct osmo_sockaddr *from_addr = mc->from_addr;
|
||||
struct sockaddr_in *from_addr = mc->from_addr;
|
||||
|
||||
/*! NOTE: This callback function implements the endpoint specific
|
||||
* dispatch behaviour of an rtp bridge/proxy endpoint. It is assumed
|
||||
@@ -1269,19 +1216,8 @@ int mgcp_dispatch_rtp_bridge_cb(struct msgb *msg)
|
||||
* address data from the UDP packet header to patch the
|
||||
* outgoing address in connection on the fly */
|
||||
if (conn->u.rtp.end.rtp_port == 0) {
|
||||
OSMO_ASSERT(conn->u.rtp.end.addr.u.sa.sa_family == from_addr->u.sa.sa_family);
|
||||
switch (from_addr->u.sa.sa_family) {
|
||||
case AF_INET:
|
||||
conn->u.rtp.end.addr.u.sin.sin_addr = from_addr->u.sin.sin_addr;
|
||||
conn->u.rtp.end.rtp_port = from_addr->u.sin.sin_port;
|
||||
break;
|
||||
case AF_INET6:
|
||||
conn->u.rtp.end.addr.u.sin6.sin6_addr = from_addr->u.sin6.sin6_addr;
|
||||
conn->u.rtp.end.rtp_port = from_addr->u.sin6.sin6_port;
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(false);
|
||||
}
|
||||
conn->u.rtp.end.addr = from_addr->sin_addr;
|
||||
conn->u.rtp.end.rtp_port = from_addr->sin_port;
|
||||
}
|
||||
return mgcp_send_rtp(conn_src, msg);
|
||||
}
|
||||
@@ -1330,7 +1266,7 @@ int mgcp_dispatch_e1_bridge_cb(struct msgb *msg)
|
||||
struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
|
||||
struct mgcp_conn_rtp *conn_src = mc->conn_src;
|
||||
struct mgcp_conn *conn = conn_src->conn;
|
||||
struct osmo_sockaddr *from_addr = mc->from_addr;
|
||||
struct sockaddr_in *from_addr = mc->from_addr;
|
||||
|
||||
/* Check if the connection is in loopback mode, if yes, just send the
|
||||
* incoming data back to the origin */
|
||||
@@ -1340,19 +1276,8 @@ int mgcp_dispatch_e1_bridge_cb(struct msgb *msg)
|
||||
* address data from the UDP packet header to patch the
|
||||
* outgoing address in connection on the fly */
|
||||
if (conn->u.rtp.end.rtp_port == 0) {
|
||||
OSMO_ASSERT(conn->u.rtp.end.addr.u.sa.sa_family == from_addr->u.sa.sa_family);
|
||||
switch (from_addr->u.sa.sa_family) {
|
||||
case AF_INET:
|
||||
conn->u.rtp.end.addr.u.sin.sin_addr = from_addr->u.sin.sin_addr;
|
||||
conn->u.rtp.end.rtp_port = from_addr->u.sin.sin_port;
|
||||
break;
|
||||
case AF_INET6:
|
||||
conn->u.rtp.end.addr.u.sin6.sin6_addr = from_addr->u.sin6.sin6_addr;
|
||||
conn->u.rtp.end.rtp_port = from_addr->u.sin6.sin6_port;
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(false);
|
||||
}
|
||||
conn->u.rtp.end.addr = from_addr->sin_addr;
|
||||
conn->u.rtp.end.rtp_port = from_addr->sin_port;
|
||||
}
|
||||
return mgcp_send_rtp(conn_src, msg);
|
||||
}
|
||||
@@ -1375,8 +1300,7 @@ void mgcp_cleanup_rtp_bridge_cb(struct mgcp_endpoint *endp, struct mgcp_conn *co
|
||||
* connections present when one connection is removed from the
|
||||
* endpoint. */
|
||||
llist_for_each_entry(conn_cleanup, &endp->conns, entry) {
|
||||
if (conn_cleanup->priv == conn)
|
||||
conn_cleanup->priv = NULL;
|
||||
conn_cleanup->priv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1407,9 +1331,8 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
|
||||
|
||||
struct mgcp_conn_rtp *conn_src;
|
||||
struct mgcp_endpoint *endp;
|
||||
struct osmo_sockaddr addr;
|
||||
struct sockaddr_in addr;
|
||||
socklen_t slen = sizeof(addr);
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
int ret;
|
||||
enum rtp_proto proto;
|
||||
struct osmo_rtp_msg_ctx *mc;
|
||||
@@ -1423,7 +1346,7 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
|
||||
|
||||
proto = (fd == &conn_src->end.rtp)? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
|
||||
|
||||
ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr.u.sa, &slen);
|
||||
ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr, &slen);
|
||||
|
||||
if (ret <= 0) {
|
||||
LOG_CONN_RTP(conn_src, LOGL_ERROR, "recvfrom error: %s\n", strerror(errno));
|
||||
@@ -1435,8 +1358,7 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
|
||||
|
||||
LOG_CONN_RTP(conn_src, LOGL_DEBUG, "%s: rx %u bytes from %s:%u\n",
|
||||
proto == MGCP_PROTO_RTP ? "RTP" : "RTPC",
|
||||
msgb_length(msg), osmo_sockaddr_ntop(&addr.u.sa, ipbuf),
|
||||
osmo_sockaddr_port(&addr.u.sa));
|
||||
msgb_length(msg), inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
||||
|
||||
if ((proto == MGCP_PROTO_RTP && check_rtp(conn_src, msg))
|
||||
|| (proto == MGCP_PROTO_RTCP && check_rtcp(conn_src, msg))) {
|
||||
@@ -1461,10 +1383,7 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
|
||||
};
|
||||
LOG_CONN_RTP(conn_src, LOGL_DEBUG, "msg ctx: %d %p %s\n",
|
||||
mc->proto, mc->conn_src,
|
||||
osmo_hexdump((void*)mc->from_addr,
|
||||
mc->from_addr->u.sa.sa_family == AF_INET6 ?
|
||||
sizeof(struct sockaddr_in6) :
|
||||
sizeof(struct sockaddr_in)));
|
||||
osmo_hexdump((void*)mc->from_addr, sizeof(struct sockaddr_in)));
|
||||
|
||||
/* Increment RX statistics */
|
||||
rate_ctr_inc(&conn_src->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR]);
|
||||
@@ -1485,7 +1404,7 @@ static int rx_rtp(struct msgb *msg)
|
||||
{
|
||||
struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
|
||||
struct mgcp_conn_rtp *conn_src = mc->conn_src;
|
||||
struct osmo_sockaddr *from_addr = mc->from_addr;
|
||||
struct sockaddr_in *from_addr = mc->from_addr;
|
||||
struct mgcp_conn *conn = conn_src->conn;
|
||||
struct mgcp_trunk *trunk = conn->endp->trunk;
|
||||
|
||||
@@ -1537,7 +1456,7 @@ int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, source_addr, port,
|
||||
rc = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, source_addr, port,
|
||||
NULL, 0, OSMO_SOCK_F_BIND);
|
||||
if (rc < 0) {
|
||||
LOGP(DRTP, LOGL_ERROR, "failed to bind UDP port (%s:%i).\n",
|
||||
@@ -1577,6 +1496,7 @@ static int bind_rtp(struct mgcp_config *cfg, const char *source_addr,
|
||||
mgcp_set_ip_tos(rtp_end->rtp.fd, cfg->endp_dscp);
|
||||
mgcp_set_ip_tos(rtp_end->rtcp.fd, cfg->endp_dscp);
|
||||
|
||||
rtp_end->rtp.when = OSMO_FD_READ;
|
||||
if (osmo_fd_register(&rtp_end->rtp) != 0) {
|
||||
LOGPENDP(endp, DRTP, LOGL_ERROR,
|
||||
"failed to register RTP port %d\n",
|
||||
@@ -1584,6 +1504,7 @@ static int bind_rtp(struct mgcp_config *cfg, const char *source_addr,
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
rtp_end->rtcp.when = OSMO_FD_READ;
|
||||
if (osmo_fd_register(&rtp_end->rtcp) != 0) {
|
||||
LOGPENDP(endp, DRTP, LOGL_ERROR,
|
||||
"failed to register RTCP port %d\n",
|
||||
@@ -1615,6 +1536,7 @@ int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port,
|
||||
{
|
||||
char name[512];
|
||||
struct mgcp_rtp_end *end;
|
||||
char local_ip_addr[INET_ADDRSTRLEN];
|
||||
|
||||
snprintf(name, sizeof(name), "%s-%s", conn->conn->name, conn->conn->id);
|
||||
end = &conn->end;
|
||||
@@ -1632,10 +1554,14 @@ int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port,
|
||||
}
|
||||
|
||||
end->local_port = rtp_port;
|
||||
osmo_fd_setup(&end->rtp, -1, OSMO_FD_READ, rtp_data_net, conn, 0);
|
||||
osmo_fd_setup(&end->rtcp, -1, OSMO_FD_READ, rtp_data_net, conn, 0);
|
||||
end->rtp.cb = rtp_data_net;
|
||||
end->rtp.data = conn;
|
||||
end->rtcp.data = conn;
|
||||
end->rtcp.cb = rtp_data_net;
|
||||
|
||||
return bind_rtp(endp->cfg, conn->end.local_addr, end, endp);
|
||||
mgcp_get_local_addr(local_ip_addr, conn);
|
||||
|
||||
return bind_rtp(endp->cfg, local_ip_addr, end, endp);
|
||||
}
|
||||
|
||||
/*! free allocated RTP and RTCP ports.
|
||||
|
||||
@@ -35,7 +35,6 @@ static LLIST_HEAD(osmux_handle_list);
|
||||
|
||||
struct osmux_handle {
|
||||
struct llist_head head;
|
||||
struct mgcp_conn_rtp *conn;
|
||||
struct osmux_in_handle *in;
|
||||
struct in_addr rem_addr;
|
||||
int rem_port; /* network byte order */
|
||||
@@ -48,17 +47,14 @@ static void *osmux;
|
||||
static void osmux_deliver_cb(struct msgb *batch_msg, void *data)
|
||||
{
|
||||
struct osmux_handle *handle = data;
|
||||
struct mgcp_conn_rtp *conn = handle->conn;
|
||||
struct sockaddr_in out = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = handle->rem_port,
|
||||
};
|
||||
|
||||
if (conn->end.output_enabled) {
|
||||
struct sockaddr_in out = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = handle->rem_port,
|
||||
};
|
||||
memcpy(&out.sin_addr, &handle->rem_addr, sizeof(handle->rem_addr));
|
||||
sendto(osmux_fd.fd, batch_msg->data, batch_msg->len, 0,
|
||||
(struct sockaddr *)&out, sizeof(out));
|
||||
}
|
||||
memcpy(&out.sin_addr, &handle->rem_addr, sizeof(handle->rem_addr));
|
||||
sendto(osmux_fd.fd, batch_msg->data, batch_msg->len, 0,
|
||||
(struct sockaddr *)&out, sizeof(out));
|
||||
msgb_free(batch_msg);
|
||||
}
|
||||
|
||||
@@ -113,15 +109,13 @@ static void osmux_handle_put(struct osmux_in_handle *in)
|
||||
|
||||
/* Allocate free OSMUX handle */
|
||||
static struct osmux_handle *
|
||||
osmux_handle_alloc(struct mgcp_conn_rtp *conn, struct in_addr *addr, int rem_port)
|
||||
osmux_handle_alloc(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
|
||||
{
|
||||
struct osmux_handle *h;
|
||||
struct mgcp_config *cfg = conn->conn->endp->cfg;
|
||||
|
||||
h = talloc_zero(osmux, struct osmux_handle);
|
||||
if (!h)
|
||||
return NULL;
|
||||
h->conn = conn;
|
||||
h->rem_addr = *addr;
|
||||
h->rem_port = rem_port;
|
||||
h->refcnt++;
|
||||
@@ -154,20 +148,15 @@ osmux_handle_alloc(struct mgcp_conn_rtp *conn, struct in_addr *addr, int rem_por
|
||||
/* Lookup existing handle for a specified address, if the handle can not be
|
||||
* found, the function will automatically allocate one */
|
||||
static struct osmux_in_handle *
|
||||
osmux_handle_lookup(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *addr, int rem_port)
|
||||
osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
|
||||
{
|
||||
struct osmux_handle *h;
|
||||
|
||||
if (addr->u.sa.sa_family != AF_INET) {
|
||||
LOGP(DLMGCP, LOGL_DEBUG, "IPv6 not supported in osmux yet!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h = osmux_handle_find_get(&addr->u.sin.sin_addr, rem_port);
|
||||
h = osmux_handle_find_get(addr, rem_port);
|
||||
if (h != NULL)
|
||||
return h->in;
|
||||
|
||||
h = osmux_handle_alloc(conn, &addr->u.sin.sin_addr, rem_port);
|
||||
h = osmux_handle_alloc(cfg, addr, rem_port);
|
||||
if (h == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -247,7 +236,7 @@ static void scheduled_from_osmux_tx_rtp_cb(struct msgb *msg, void *data)
|
||||
{
|
||||
struct mgcp_conn_rtp *conn = data;
|
||||
struct mgcp_endpoint *endp = conn->conn->endp;
|
||||
struct osmo_sockaddr addr = { /* FIXME: do we know the source address?? */ };
|
||||
struct sockaddr_in addr = { /* FIXME: do we know the source address?? */ };
|
||||
struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
|
||||
*mc = (struct osmo_rtp_msg_ctx){
|
||||
.proto = MGCP_PROTO_RTP,
|
||||
@@ -286,8 +275,6 @@ static struct msgb *osmux_recv(struct osmo_fd *ofd, struct sockaddr_in *addr)
|
||||
static int endp_osmux_state_check(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
|
||||
bool sending)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
switch(conn->osmux.state) {
|
||||
case OSMUX_STATE_ACTIVATING:
|
||||
if (osmux_enable_conn(endp, conn, &conn->end.addr, conn->end.rtp_port) < 0) {
|
||||
@@ -300,8 +287,7 @@ static int endp_osmux_state_check(struct mgcp_endpoint *endp, struct mgcp_conn_r
|
||||
LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
|
||||
"Osmux %s CID %u towards %s:%u is now enabled\n",
|
||||
sending ? "sent" : "received",
|
||||
conn->osmux.cid,
|
||||
osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),
|
||||
conn->osmux.cid, inet_ntoa(conn->end.addr),
|
||||
ntohs(conn->end.rtp_port));
|
||||
return 0;
|
||||
case OSMUX_STATE_ENABLED:
|
||||
@@ -390,8 +376,6 @@ static int osmux_read_fd_cb(struct osmo_fd *ofd, unsigned int what)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mgcp_conn_watchdog_kick(conn_src->conn);
|
||||
|
||||
/*conn_dst = mgcp_find_dst_conn(conn_src->conn);
|
||||
if (!conn_dst) {
|
||||
LOGP(DLMGCP, LOGL_ERROR,
|
||||
@@ -416,7 +400,8 @@ int osmux_init(int role, struct mgcp_config *cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
osmo_fd_setup(&osmux_fd, -1, OSMO_FD_READ, osmux_read_fd_cb, cfg, 0);
|
||||
osmux_fd.cb = osmux_read_fd_cb;
|
||||
osmux_fd.data = cfg;
|
||||
|
||||
ret = mgcp_create_bind(cfg->osmux_addr, &osmux_fd, cfg->osmux_port);
|
||||
if (ret < 0) {
|
||||
@@ -425,6 +410,7 @@ int osmux_init(int role, struct mgcp_config *cfg)
|
||||
return ret;
|
||||
}
|
||||
mgcp_set_ip_tos(osmux_fd.fd, cfg->endp_dscp);
|
||||
osmux_fd.when |= OSMO_FD_READ;
|
||||
|
||||
ret = osmo_fd_register(&osmux_fd);
|
||||
if (ret < 0) {
|
||||
@@ -447,7 +433,7 @@ int osmux_init(int role, struct mgcp_config *cfg)
|
||||
* \param[in] port portnumber of the remote OSMUX endpoint (in network byte order)
|
||||
* \returns 0 on success, -1 on ERROR */
|
||||
int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
|
||||
struct osmo_sockaddr *addr, uint16_t port)
|
||||
struct in_addr *addr, uint16_t port)
|
||||
{
|
||||
/*! If osmux is enabled, initialize the output handler. This handler is
|
||||
* used to reconstruct the RTP flow from osmux. The RTP SSRC is
|
||||
@@ -458,7 +444,7 @@ int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
|
||||
* overlapping RTP SSRC traveling to the BTSes behind the BSC,
|
||||
* similarly, for flows traveling to the MSC.
|
||||
*/
|
||||
struct in6_addr addr_unset = {};
|
||||
struct in_addr addr_unset = {};
|
||||
static const uint32_t rtp_ssrc_winlen = UINT32_MAX / (OSMUX_CID_MAX + 1);
|
||||
uint16_t osmux_dummy = endp->cfg->osmux_dummy;
|
||||
|
||||
@@ -471,16 +457,13 @@ int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
|
||||
}
|
||||
|
||||
/* Wait until we have the connection information from MDCX */
|
||||
if (memcmp(&conn->end.addr, &addr_unset,
|
||||
conn->end.addr.u.sa.sa_family == AF_INET6 ?
|
||||
sizeof(struct in6_addr) :
|
||||
sizeof(struct in_addr)) == 0) {
|
||||
if (memcmp(&conn->end.addr, &addr_unset, sizeof(addr_unset)) == 0) {
|
||||
LOGPCONN(conn->conn, DLMGCP, LOGL_INFO,
|
||||
"Osmux remote address/port still unknown\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn->osmux.in = osmux_handle_lookup(conn, addr, port);
|
||||
conn->osmux.in = osmux_handle_lookup(endp->cfg, addr, port);
|
||||
if (!conn->osmux.in) {
|
||||
LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
|
||||
"Cannot allocate input osmux handle for conn:%s\n",
|
||||
@@ -576,7 +559,6 @@ int conn_osmux_allocate_cid(struct mgcp_conn_rtp *conn, int osmux_cid)
|
||||
* \returns bytes sent, -1 on error */
|
||||
int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
struct osmux_hdr *osmuxh;
|
||||
int buf_len;
|
||||
struct in_addr addr_unset = {};
|
||||
@@ -606,8 +588,7 @@ int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)
|
||||
|
||||
LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,
|
||||
"sending OSMUX dummy load to %s:%u CID %u\n",
|
||||
osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),
|
||||
ntohs(conn->end.rtp_port), conn->osmux.cid);
|
||||
inet_ntoa(conn->end.addr), ntohs(conn->end.rtp_port), conn->osmux.cid);
|
||||
|
||||
return mgcp_udp_send(osmux_fd.fd, &conn->end.addr,
|
||||
conn->end.rtp_port, (char*)osmuxh, buf_len);
|
||||
|
||||
@@ -223,22 +223,24 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
|
||||
const char *trans_id,
|
||||
bool add_conn_params)
|
||||
{
|
||||
/* cfg->local_ip allows overwritting the announced IP address with
|
||||
* regards to the one we actually bind to. Useful in behind-NAT
|
||||
* scenarios.
|
||||
* TODO: we may want to define another local_ip_osmux var to
|
||||
* us for OSMUX connections. Perhaps adding a new internal API to get it
|
||||
* based on conn type.
|
||||
*/
|
||||
const char *addr = endp->cfg->local_ip ? : conn->end.local_addr;
|
||||
/* TODO: we may want to define another local_ip_osmux var to us for
|
||||
OSMUX connections. Perhaps adding a new internal API to get it based
|
||||
on conn type */
|
||||
const char *addr = endp->cfg->local_ip;
|
||||
struct msgb *sdp;
|
||||
int rc;
|
||||
struct msgb *result;
|
||||
char local_ip_addr[INET_ADDRSTRLEN];
|
||||
|
||||
sdp = msgb_alloc_headroom(4096, 128, "sdp record");
|
||||
if (!sdp)
|
||||
return NULL;
|
||||
|
||||
if (!addr) {
|
||||
mgcp_get_local_addr(local_ip_addr, conn);
|
||||
addr = local_ip_addr;
|
||||
}
|
||||
|
||||
/* Attach optional connection parameters */
|
||||
if (add_conn_params) {
|
||||
rc = add_params(sdp, endp, conn);
|
||||
@@ -524,7 +526,6 @@ static int set_local_cx_options(void *ctx, struct mgcp_lco *lco,
|
||||
{
|
||||
char *lco_id;
|
||||
char codec[17];
|
||||
char nt[17];
|
||||
int len;
|
||||
|
||||
if (!options)
|
||||
@@ -551,7 +552,7 @@ static int set_local_cx_options(void *ctx, struct mgcp_lco *lco,
|
||||
lco->pkt_period_max = lco->pkt_period_min;
|
||||
break;
|
||||
case 'a':
|
||||
/* FIXME: LCO also supports the negotiation of more than one codec.
|
||||
/* FIXME: LCO also supports the negotiation of more then one codec.
|
||||
* (e.g. a:PCMU;G726-32) But this implementation only supports a single
|
||||
* codec only. */
|
||||
if (sscanf(lco_id + 1, ":%16[^,]", codec) == 1) {
|
||||
@@ -563,10 +564,6 @@ static int set_local_cx_options(void *ctx, struct mgcp_lco *lco,
|
||||
osmo_str_toupper_buf(lco->codec, len + 1, codec);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
if (lco_id[1] == 't' && sscanf(lco_id + 2, ":%16[^,]", nt) == 1)
|
||||
break;
|
||||
/* else: fall throught to print notice log */
|
||||
default:
|
||||
LOGP(DLMGCP, LOGL_NOTICE,
|
||||
"LCO: unhandled option: '%c'/%d in \"%s\"\n",
|
||||
@@ -712,7 +709,7 @@ static bool parse_x_osmo_ign(struct mgcp_endpoint *endp, char *line)
|
||||
{
|
||||
char *saveptr = NULL;
|
||||
|
||||
if (strncasecmp(line, MGCP_X_OSMO_IGN_HEADER, strlen(MGCP_X_OSMO_IGN_HEADER)))
|
||||
if (strncmp(line, MGCP_X_OSMO_IGN_HEADER, strlen(MGCP_X_OSMO_IGN_HEADER)))
|
||||
return false;
|
||||
line += strlen(MGCP_X_OSMO_IGN_HEADER);
|
||||
|
||||
@@ -749,11 +746,8 @@ static struct msgb *handle_create_con(struct mgcp_parse_data *p)
|
||||
int rc;
|
||||
|
||||
LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "CRCX: creating new connection ...\n");
|
||||
|
||||
if (!mgcp_endp_avail(endp)) {
|
||||
rate_ctr_inc(&rate_ctrs->ctr[MGCP_CRCX_FAIL_AVAIL]);
|
||||
LOGPENDP(endp, DLMGCP, LOGL_ERROR,
|
||||
"CRCX: selected endpoint not available!\n");
|
||||
return create_err_response(NULL, 501, "CRCX", p->trans);
|
||||
}
|
||||
|
||||
@@ -946,9 +940,6 @@ mgcp_header_done:
|
||||
goto error2;
|
||||
}
|
||||
|
||||
/* Find a local address for conn based on policy and initial SDP remote
|
||||
information, then find a free port for it */
|
||||
mgcp_get_local_addr(conn->end.local_addr, conn);
|
||||
if (allocate_port(endp, conn) != 0) {
|
||||
rate_ctr_inc(&rate_ctrs->ctr[MGCP_CRCX_FAIL_BIND_PORT]);
|
||||
goto error2;
|
||||
@@ -1011,7 +1002,6 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
|
||||
{
|
||||
struct mgcp_endpoint *endp = p->endp;
|
||||
struct rate_ctr_group *rate_ctrs = endp->trunk->ratectr.mgcp_mdcx_ctr_group;
|
||||
char new_local_addr[INET6_ADDRSTRLEN];
|
||||
int error_code = 500;
|
||||
int silent = 0;
|
||||
int have_sdp = 0;
|
||||
@@ -1027,8 +1017,6 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
|
||||
|
||||
if (!mgcp_endp_avail(endp)) {
|
||||
rate_ctr_inc(&rate_ctrs->ctr[MGCP_MDCX_FAIL_AVAIL]);
|
||||
LOGPENDP(endp, DLMGCP, LOGL_ERROR,
|
||||
"MDCX: selected endpoint not available!\n");
|
||||
return create_err_response(NULL, 501, "MDCX", p->trans);
|
||||
}
|
||||
|
||||
@@ -1176,20 +1164,6 @@ mgcp_header_done:
|
||||
that conn. */
|
||||
}
|
||||
|
||||
/* MDCX may have provided a new remote address, which means we may need
|
||||
to update our announced IP addr and re-bind our local end. This can
|
||||
happen for instance if MGW initially provided an IPv4 during CRCX
|
||||
ACK, and now MDCX tells us the remote has an IPv6 address. */
|
||||
mgcp_get_local_addr(new_local_addr, conn);
|
||||
if (strcmp(new_local_addr, conn->end.local_addr)) {
|
||||
osmo_strlcpy(conn->end.local_addr, new_local_addr, sizeof(conn->end.local_addr));
|
||||
mgcp_free_rtp_port(&conn->end);
|
||||
if (allocate_port(endp, conn) != 0) {
|
||||
rate_ctr_inc(&rate_ctrs->ctr[MGCP_CRCX_FAIL_BIND_PORT]);
|
||||
goto error3;
|
||||
}
|
||||
}
|
||||
|
||||
if (setup_rtp_processing(endp, conn) != 0) {
|
||||
rate_ctr_inc(&rate_ctrs->ctr[MGCP_MDCX_FAIL_START_RTP]);
|
||||
goto error3;
|
||||
@@ -1269,8 +1243,6 @@ static struct msgb *handle_delete_con(struct mgcp_parse_data *p)
|
||||
|
||||
if (!mgcp_endp_avail(endp)) {
|
||||
rate_ctr_inc(&rate_ctrs->ctr[MGCP_DLCX_FAIL_AVAIL]);
|
||||
LOGPENDP(endp, DLMGCP, LOGL_ERROR,
|
||||
"DLCX: selected endpoint not available!\n");
|
||||
return create_err_response(NULL, 501, "DLCX", p->trans);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
*/
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
#include <osmocom/mgcp/osmux.h>
|
||||
#include <osmocom/mgcp/mgcp_conn.h>
|
||||
@@ -262,42 +259,6 @@ error:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int audio_ip_from_sdp(struct osmo_sockaddr *dst_addr, char *sdp)
|
||||
{
|
||||
bool is_ipv6;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
if (strncmp("c=IN IP", sdp, 7) != 0)
|
||||
return -1;
|
||||
sdp += 7;
|
||||
if (*sdp == '6')
|
||||
is_ipv6 = true;
|
||||
else if (*sdp == '4')
|
||||
is_ipv6 = false;
|
||||
else
|
||||
return -1;
|
||||
sdp++;
|
||||
if (*sdp != ' ')
|
||||
return -1;
|
||||
sdp++;
|
||||
if (is_ipv6) {
|
||||
/* 45 = INET6_ADDRSTRLEN -1 */
|
||||
if (sscanf(sdp, "%45s", ipbuf) != 1)
|
||||
return -1;
|
||||
if (inet_pton(AF_INET6, ipbuf, &dst_addr->u.sin6.sin6_addr) != 1)
|
||||
return -1;
|
||||
dst_addr->u.sa.sa_family = AF_INET6;
|
||||
} else {
|
||||
/* 15 = INET_ADDRSTRLEN -1 */
|
||||
if (sscanf(sdp, "%15s", ipbuf) != 1)
|
||||
return -1;
|
||||
if (inet_pton(AF_INET, ipbuf, &dst_addr->u.sin.sin_addr) != 1)
|
||||
return -1;
|
||||
dst_addr->u.sa.sa_family = AF_INET;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pick optional fmtp parameters by payload type, if there are no fmtp
|
||||
* parameters, a nullpointer is returned */
|
||||
static struct mgcp_codec_param *param_by_pt(int pt, struct sdp_fmtp_param *fmtp_params, unsigned int fmtp_params_len)
|
||||
@@ -328,7 +289,6 @@ int mgcp_parse_sdp_data(const struct mgcp_endpoint *endp,
|
||||
struct sdp_fmtp_param fmtp_params[MGCP_MAX_CODECS];
|
||||
unsigned int fmtp_used = 0;
|
||||
struct mgcp_codec_param *codec_param;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
char *line;
|
||||
unsigned int i;
|
||||
void *tmp_ctx = talloc_new(NULL);
|
||||
@@ -338,6 +298,7 @@ int mgcp_parse_sdp_data(const struct mgcp_endpoint *endp,
|
||||
int ptime, ptime2 = 0;
|
||||
char audio_name[64];
|
||||
int port, rc;
|
||||
char ipv4[16];
|
||||
|
||||
OSMO_ASSERT(endp);
|
||||
OSMO_ASSERT(conn);
|
||||
@@ -394,8 +355,10 @@ int mgcp_parse_sdp_data(const struct mgcp_endpoint *endp,
|
||||
codecs_used = rc;
|
||||
break;
|
||||
case 'c':
|
||||
if (audio_ip_from_sdp(&rtp->addr, line) < 0)
|
||||
return -1;
|
||||
|
||||
if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) {
|
||||
inet_aton(ipv4, &rtp->addr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (p->endp)
|
||||
@@ -430,7 +393,7 @@ int mgcp_parse_sdp_data(const struct mgcp_endpoint *endp,
|
||||
|
||||
LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,
|
||||
"Got media info via SDP: port:%d, addr:%s, duration:%d, payload-types:",
|
||||
ntohs(rtp->rtp_port), osmo_sockaddr_ntop(&rtp->addr.u.sa, ipbuf),
|
||||
ntohs(rtp->rtp_port), inet_ntoa(rtp->addr),
|
||||
rtp->packet_duration_ms);
|
||||
if (codecs_used == 0)
|
||||
LOGPC(DLMGCP, LOGL_NOTICE, "none");
|
||||
@@ -566,7 +529,6 @@ int mgcp_write_response_sdp(const struct mgcp_endpoint *endp,
|
||||
int local_port;
|
||||
struct sdp_fmtp_param fmtp_params[1];
|
||||
unsigned int fmtp_params_len = 0;
|
||||
bool addr_is_v6;
|
||||
|
||||
OSMO_ASSERT(endp);
|
||||
OSMO_ASSERT(conn);
|
||||
@@ -581,16 +543,12 @@ int mgcp_write_response_sdp(const struct mgcp_endpoint *endp,
|
||||
audio_name = codec->audio_name;
|
||||
payload_type = codec->payload_type;
|
||||
|
||||
addr_is_v6 = osmo_ip_str_type(addr) == AF_INET6;
|
||||
|
||||
rc = msgb_printf(sdp,
|
||||
"v=0\r\n"
|
||||
"o=- %s 23 IN IP%c %s\r\n"
|
||||
"o=- %s 23 IN IP4 %s\r\n"
|
||||
"s=-\r\n"
|
||||
"c=IN IP%c %s\r\n"
|
||||
"t=0 0\r\n", conn->conn->id,
|
||||
addr_is_v6 ? '6' : '4', addr,
|
||||
addr_is_v6 ? '6' : '4', addr);
|
||||
"c=IN IP4 %s\r\n"
|
||||
"t=0 0\r\n", conn->conn->id, addr, addr);
|
||||
|
||||
if (rc < 0)
|
||||
goto buffer_too_small;
|
||||
|
||||
@@ -50,7 +50,7 @@ struct mgcp_trunk *mgcp_trunk_alloc(struct mgcp_config *cfg, enum mgcp_trunk_typ
|
||||
|
||||
trunk->audio_send_ptime = 1;
|
||||
trunk->audio_send_name = 1;
|
||||
trunk->v.vty_number_endpoints = 512;
|
||||
trunk->v.vty_number_endpoints = 32;
|
||||
trunk->omit_rtcp = 0;
|
||||
|
||||
mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
*/
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
#include <osmocom/vty/misc.h>
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
#include <osmocom/mgcp/mgcp_common.h>
|
||||
@@ -42,7 +41,6 @@
|
||||
#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
|
||||
#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"
|
||||
|
||||
#define X(x) (1 << x)
|
||||
|
||||
static struct mgcp_config *g_cfg = NULL;
|
||||
|
||||
@@ -72,12 +70,9 @@ static int config_write_mgcp(struct vty *vty)
|
||||
vty_out(vty, " rtp port-range %u %u%s",
|
||||
g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
|
||||
VTY_NEWLINE);
|
||||
if (g_cfg->net_ports.bind_addr_v4)
|
||||
if (g_cfg->net_ports.bind_addr)
|
||||
vty_out(vty, " rtp bind-ip %s%s",
|
||||
g_cfg->net_ports.bind_addr_v4, VTY_NEWLINE);
|
||||
if (g_cfg->net_ports.bind_addr_v6)
|
||||
vty_out(vty, " rtp bind-ip-v6 %s%s",
|
||||
g_cfg->net_ports.bind_addr_v6, VTY_NEWLINE);
|
||||
g_cfg->net_ports.bind_addr, VTY_NEWLINE);
|
||||
if (g_cfg->net_ports.bind_addr_probe)
|
||||
vty_out(vty, " rtp ip-probing%s", VTY_NEWLINE);
|
||||
else
|
||||
@@ -116,6 +111,7 @@ static int config_write_mgcp(struct vty *vty)
|
||||
trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " %ssdp audio-payload send-name%s",
|
||||
trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " loop %u%s", ! !trunk->audio_loop, VTY_NEWLINE);
|
||||
vty_out(vty, " number endpoints %u%s",
|
||||
trunk->v.vty_number_endpoints, VTY_NEWLINE);
|
||||
vty_out(vty, " %sallow-transcoding%s",
|
||||
@@ -409,14 +405,11 @@ DEFUN(cfg_mgcp, cfg_mgcp_cmd, "mgcp", "Configure the MGCP")
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_local_ip,
|
||||
cfg_mgcp_local_ip_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"local ip " VTY_IPV46_CMD,
|
||||
"Local options for the SDP record\n"
|
||||
IP_STR
|
||||
"IPv4 Address to use in SDP record\n"
|
||||
"IPv6 Address to use in SDP record\n")
|
||||
DEFUN(cfg_mgcp_local_ip,
|
||||
cfg_mgcp_local_ip_cmd,
|
||||
"local ip A.B.C.D",
|
||||
"Local options for the SDP record\n"
|
||||
IP_STR "IPv4 Address to use in SDP record\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
@@ -425,10 +418,7 @@ DEFUN_USRATTR(cfg_mgcp_local_ip,
|
||||
#define BIND_STR "Listen/Bind related socket option\n"
|
||||
DEFUN(cfg_mgcp_bind_ip,
|
||||
cfg_mgcp_bind_ip_cmd,
|
||||
"bind ip " VTY_IPV46_CMD,
|
||||
BIND_STR IP_STR
|
||||
"IPv4 Address to bind to\n"
|
||||
"IPv6 Address to bind to\n")
|
||||
"bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
@@ -444,13 +434,14 @@ DEFUN(cfg_mgcp_bind_port,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_DEPRECATED(cfg_mgcp_bind_early,
|
||||
cfg_mgcp_bind_early_cmd,
|
||||
"bind early (0|1)",
|
||||
BIND_STR
|
||||
"Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
|
||||
DEFUN(cfg_mgcp_bind_early,
|
||||
cfg_mgcp_bind_early_cmd,
|
||||
"bind early (0|1)",
|
||||
BIND_STR
|
||||
"Bind local ports on start up\n" "Bind on demand\n" "Bind on startup\n")
|
||||
{
|
||||
return CMD_SUCCESS;
|
||||
vty_out(vty, "bind early is deprecated, remove it from the config.\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
#define RTP_STR "RTP configuration\n"
|
||||
@@ -501,14 +492,12 @@ ALIAS_DEPRECATED(cfg_mgcp_rtp_port_range,
|
||||
RTP_STR "Range of ports to use for the NET side\n"
|
||||
RANGE_START_STR RANGE_END_STR)
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_bind_ip,
|
||||
cfg_mgcp_rtp_bind_ip_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp bind-ip A.B.C.D",
|
||||
RTP_STR "Bind endpoints facing the Network\n"
|
||||
"IPv4 Address to bind to\n")
|
||||
DEFUN(cfg_mgcp_rtp_bind_ip,
|
||||
cfg_mgcp_rtp_bind_ip_cmd,
|
||||
"rtp bind-ip A.B.C.D",
|
||||
RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v4, argv[0]);
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
|
||||
@@ -516,15 +505,14 @@ ALIAS_DEPRECATED(cfg_mgcp_rtp_bind_ip,
|
||||
"rtp net-bind-ip A.B.C.D",
|
||||
RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_no_bind_ip,
|
||||
cfg_mgcp_rtp_no_bind_ip_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp bind-ip",
|
||||
NO_STR RTP_STR "Bind endpoints facing the Network\n"
|
||||
"Address to bind to\n")
|
||||
DEFUN(cfg_mgcp_rtp_no_bind_ip,
|
||||
cfg_mgcp_rtp_no_bind_ip_cmd,
|
||||
"no rtp bind-ip",
|
||||
NO_STR RTP_STR "Bind endpoints facing the Network\n"
|
||||
"Address to bind to\n")
|
||||
{
|
||||
talloc_free(g_cfg->net_ports.bind_addr_v4);
|
||||
g_cfg->net_ports.bind_addr_v4 = NULL;
|
||||
talloc_free(g_cfg->net_ports.bind_addr);
|
||||
g_cfg->net_ports.bind_addr = NULL;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
|
||||
@@ -533,55 +521,29 @@ ALIAS_DEPRECATED(cfg_mgcp_rtp_no_bind_ip,
|
||||
NO_STR RTP_STR "Bind endpoints facing the Network\n"
|
||||
"Address to bind to\n")
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_bind_ip_v6,
|
||||
cfg_mgcp_rtp_bind_ip_v6_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp bind-ip-v6 " VTY_IPV6_CMD,
|
||||
RTP_STR "Bind endpoints facing the Network\n"
|
||||
"IPv6 Address to bind to\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr_v6, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_no_bind_ip_v6,
|
||||
cfg_mgcp_rtp_no_bind_ip_v6_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp bind-ip-v6",
|
||||
NO_STR RTP_STR "Bind endpoints facing the Network\n"
|
||||
"Address to bind to\n")
|
||||
{
|
||||
talloc_free(g_cfg->net_ports.bind_addr_v6);
|
||||
g_cfg->net_ports.bind_addr_v6 = NULL;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_net_bind_ip_probing,
|
||||
cfg_mgcp_rtp_net_bind_ip_probing_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp ip-probing",
|
||||
RTP_STR "automatic rtp bind ip selection\n")
|
||||
DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
|
||||
cfg_mgcp_rtp_net_bind_ip_probing_cmd,
|
||||
"rtp ip-probing",
|
||||
RTP_STR "automatic rtp bind ip selection\n")
|
||||
{
|
||||
g_cfg->net_ports.bind_addr_probe = true;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_no_net_bind_ip_probing,
|
||||
cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp ip-probing",
|
||||
NO_STR RTP_STR "no automatic rtp bind ip selection\n")
|
||||
DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
|
||||
cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
|
||||
"no rtp ip-probing",
|
||||
NO_STR RTP_STR "no automatic rtp bind ip selection\n")
|
||||
{
|
||||
g_cfg->net_ports.bind_addr_probe = false;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_ip_dscp,
|
||||
cfg_mgcp_rtp_ip_dscp_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp ip-dscp <0-255>",
|
||||
RTP_STR
|
||||
"Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
|
||||
DEFUN(cfg_mgcp_rtp_ip_dscp,
|
||||
cfg_mgcp_rtp_ip_dscp_cmd,
|
||||
"rtp ip-dscp <0-255>",
|
||||
RTP_STR
|
||||
"Apply IP_TOS to the audio stream (including Osmux)\n" "The DSCP value\n")
|
||||
{
|
||||
int dscp = atoi(argv[0]);
|
||||
g_cfg->endp_dscp = dscp;
|
||||
@@ -593,32 +555,29 @@ ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
|
||||
RTP_STR
|
||||
"Apply IP_TOS to the audio stream\n" "The DSCP value\n")
|
||||
#define FORCE_PTIME_STR "Force a fixed ptime for packets sent"
|
||||
DEFUN_USRATTR(cfg_mgcp_rtp_force_ptime,
|
||||
cfg_mgcp_rtp_force_ptime_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp force-ptime (10|20|40)",
|
||||
RTP_STR FORCE_PTIME_STR
|
||||
"The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
|
||||
DEFUN(cfg_mgcp_rtp_force_ptime,
|
||||
cfg_mgcp_rtp_force_ptime_cmd,
|
||||
"rtp force-ptime (10|20|40)",
|
||||
RTP_STR FORCE_PTIME_STR
|
||||
"The required ptime (packet duration) in ms\n" "10 ms\n20 ms\n40 ms\n")
|
||||
{
|
||||
g_cfg->force_ptime = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_rtp_force_ptime,
|
||||
cfg_mgcp_no_rtp_force_ptime_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
|
||||
DEFUN(cfg_mgcp_no_rtp_force_ptime,
|
||||
cfg_mgcp_no_rtp_force_ptime_cmd,
|
||||
"no rtp force-ptime", NO_STR RTP_STR FORCE_PTIME_STR)
|
||||
{
|
||||
g_cfg->force_ptime = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_sdp_fmtp_extra,
|
||||
cfg_mgcp_sdp_fmtp_extra_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"sdp audio fmtp-extra .NAME",
|
||||
"Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
|
||||
"Extra Information\n")
|
||||
DEFUN(cfg_mgcp_sdp_fmtp_extra,
|
||||
cfg_mgcp_sdp_fmtp_extra_cmd,
|
||||
"sdp audio fmtp-extra .NAME",
|
||||
"Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
|
||||
"Extra Information\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -631,10 +590,9 @@ DEFUN_USRATTR(cfg_mgcp_sdp_fmtp_extra,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_allow_transcoding,
|
||||
cfg_mgcp_allow_transcoding_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"allow-transcoding", "Allow transcoding\n")
|
||||
DEFUN(cfg_mgcp_allow_transcoding,
|
||||
cfg_mgcp_allow_transcoding_cmd,
|
||||
"allow-transcoding", "Allow transcoding\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -642,10 +600,9 @@ DEFUN_USRATTR(cfg_mgcp_allow_transcoding,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_allow_transcoding,
|
||||
cfg_mgcp_no_allow_transcoding_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no allow-transcoding", NO_STR "Allow transcoding\n")
|
||||
DEFUN(cfg_mgcp_no_allow_transcoding,
|
||||
cfg_mgcp_no_allow_transcoding_cmd,
|
||||
"no allow-transcoding", NO_STR "Allow transcoding\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -680,11 +637,10 @@ ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, cfg_mgcp_sdp_payload_name_cmd_old,
|
||||
"sdp audio payload name NAME",
|
||||
SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_sdp_payload_send_ptime,
|
||||
cfg_mgcp_sdp_payload_send_ptime_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"sdp audio-payload send-ptime",
|
||||
SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
DEFUN(cfg_mgcp_sdp_payload_send_ptime,
|
||||
cfg_mgcp_sdp_payload_send_ptime_cmd,
|
||||
"sdp audio-payload send-ptime",
|
||||
SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -692,11 +648,10 @@ DEFUN_USRATTR(cfg_mgcp_sdp_payload_send_ptime,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_sdp_payload_send_ptime,
|
||||
cfg_mgcp_no_sdp_payload_send_ptime_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no sdp audio-payload send-ptime",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
|
||||
cfg_mgcp_no_sdp_payload_send_ptime_cmd,
|
||||
"no sdp audio-payload send-ptime",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -704,11 +659,10 @@ DEFUN_USRATTR(cfg_mgcp_no_sdp_payload_send_ptime,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_sdp_payload_send_name,
|
||||
cfg_mgcp_sdp_payload_send_name_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"sdp audio-payload send-name",
|
||||
SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
DEFUN(cfg_mgcp_sdp_payload_send_name,
|
||||
cfg_mgcp_sdp_payload_send_name_cmd,
|
||||
"sdp audio-payload send-name",
|
||||
SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -716,11 +670,10 @@ DEFUN_USRATTR(cfg_mgcp_sdp_payload_send_name,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_sdp_payload_send_name,
|
||||
cfg_mgcp_no_sdp_payload_send_name_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no sdp audio-payload send-name",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
DEFUN(cfg_mgcp_no_sdp_payload_send_name,
|
||||
cfg_mgcp_no_sdp_payload_send_name_cmd,
|
||||
"no sdp audio-payload send-name",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -728,20 +681,26 @@ DEFUN_USRATTR(cfg_mgcp_no_sdp_payload_send_name,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_DEPRECATED(cfg_mgcp_loop,
|
||||
cfg_mgcp_loop_cmd,
|
||||
"loop (0|1)",
|
||||
"Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
|
||||
DEFUN(cfg_mgcp_loop,
|
||||
cfg_mgcp_loop_cmd,
|
||||
"loop (0|1)",
|
||||
"Loop audio for all endpoints on main trunk\n" "Don't Loop\n" "Loop\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
if (g_cfg->osmux) {
|
||||
vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
trunk->audio_loop = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_force_realloc,
|
||||
cfg_mgcp_force_realloc_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"force-realloc (0|1)",
|
||||
"Force endpoint reallocation when the endpoint is still seized\n"
|
||||
"Don't force reallocation\n" "force reallocation\n")
|
||||
DEFUN(cfg_mgcp_force_realloc,
|
||||
cfg_mgcp_force_realloc_cmd,
|
||||
"force-realloc (0|1)",
|
||||
"Force endpoint reallocation when the endpoint is still seized\n"
|
||||
"Don't force reallocation\n" "force reallocation\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -749,12 +708,11 @@ DEFUN_USRATTR(cfg_mgcp_force_realloc,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_mgcp_rtp_accept_all,
|
||||
cfg_mgcp_rtp_accept_all_cmd,
|
||||
"rtp-accept-all (0|1)",
|
||||
"Accept all RTP packets, even when the originating IP/Port does not match\n"
|
||||
"enable filter\n" "disable filter\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_mgcp_rtp_accept_all,
|
||||
cfg_mgcp_rtp_accept_all_cmd,
|
||||
"rtp-accept-all (0|1)",
|
||||
"Accept all RTP packets, even when the originating IP/Port does not match\n"
|
||||
"enable filter\n" "disable filter\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -773,21 +731,15 @@ DEFUN(cfg_mgcp_number_endp,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_mgcp_omit_rtcp,
|
||||
cfg_mgcp_omit_rtcp_cmd,
|
||||
"rtcp-omit", RTCP_OMIT_STR,
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
trunk->omit_rtcp = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_mgcp_no_omit_rtcp,
|
||||
cfg_mgcp_no_omit_rtcp_cmd,
|
||||
"no rtcp-omit",
|
||||
NO_STR RTCP_OMIT_STR,
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_mgcp_no_omit_rtcp,
|
||||
cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -795,10 +747,9 @@ DEFUN_ATTR(cfg_mgcp_no_omit_rtcp,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_patch_rtp_ssrc,
|
||||
cfg_mgcp_patch_rtp_ssrc_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
DEFUN(cfg_mgcp_patch_rtp_ssrc,
|
||||
cfg_mgcp_patch_rtp_ssrc_cmd,
|
||||
"rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -806,10 +757,9 @@ DEFUN_USRATTR(cfg_mgcp_patch_rtp_ssrc,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_ssrc,
|
||||
cfg_mgcp_no_patch_rtp_ssrc_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
DEFUN(cfg_mgcp_no_patch_rtp_ssrc,
|
||||
cfg_mgcp_no_patch_rtp_ssrc_cmd,
|
||||
"no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -817,10 +767,9 @@ DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_ssrc,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_patch_rtp_ts,
|
||||
cfg_mgcp_patch_rtp_ts_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
DEFUN(cfg_mgcp_patch_rtp_ts,
|
||||
cfg_mgcp_patch_rtp_ts_cmd,
|
||||
"rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -828,10 +777,9 @@ DEFUN_USRATTR(cfg_mgcp_patch_rtp_ts,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_ts,
|
||||
cfg_mgcp_no_patch_rtp_ts_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
DEFUN(cfg_mgcp_no_patch_rtp_ts,
|
||||
cfg_mgcp_no_patch_rtp_ts_cmd,
|
||||
"no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -839,10 +787,9 @@ DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_ts,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_patch_rtp_rfc5993hr,
|
||||
cfg_mgcp_patch_rtp_rfc5993hr_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,
|
||||
cfg_mgcp_patch_rtp_rfc5993hr_cmd,
|
||||
"rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -850,10 +797,9 @@ DEFUN_USRATTR(cfg_mgcp_patch_rtp_rfc5993hr,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_rfc5993hr,
|
||||
cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,
|
||||
cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
|
||||
"no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -861,10 +807,8 @@ DEFUN_USRATTR(cfg_mgcp_no_patch_rtp_rfc5993hr,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_mgcp_no_patch_rtp,
|
||||
cfg_mgcp_no_patch_rtp_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch", NO_STR RTP_PATCH_STR)
|
||||
DEFUN(cfg_mgcp_no_patch_rtp,
|
||||
cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -874,11 +818,10 @@ DEFUN_USRATTR(cfg_mgcp_no_patch_rtp,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_mgcp_rtp_keepalive,
|
||||
cfg_mgcp_rtp_keepalive_cmd,
|
||||
"rtp keep-alive <1-120>",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_mgcp_rtp_keepalive,
|
||||
cfg_mgcp_rtp_keepalive_cmd,
|
||||
"rtp keep-alive <1-120>",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -886,11 +829,10 @@ DEFUN_ATTR(cfg_mgcp_rtp_keepalive,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_mgcp_rtp_keepalive_once,
|
||||
cfg_mgcp_rtp_keepalive_once_cmd,
|
||||
"rtp keep-alive once",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_mgcp_rtp_keepalive_once,
|
||||
cfg_mgcp_rtp_keepalive_once_cmd,
|
||||
"rtp keep-alive once",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -898,10 +840,9 @@ DEFUN_ATTR(cfg_mgcp_rtp_keepalive_once,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_mgcp_no_rtp_keepalive,
|
||||
cfg_mgcp_no_rtp_keepalive_cmd,
|
||||
"no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR,
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_mgcp_no_rtp_keepalive,
|
||||
cfg_mgcp_no_rtp_keepalive_cmd,
|
||||
"no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
|
||||
OSMO_ASSERT(trunk);
|
||||
@@ -909,13 +850,11 @@ DEFUN_ATTR(cfg_mgcp_no_rtp_keepalive,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define CALL_AGENT_STR "Call agent information\n"
|
||||
#define CALL_AGENT_STR "Callagent information\n"
|
||||
DEFUN(cfg_mgcp_agent_addr,
|
||||
cfg_mgcp_agent_addr_cmd,
|
||||
"call-agent ip " VTY_IPV46_CMD,
|
||||
CALL_AGENT_STR IP_STR
|
||||
"IPv4 Address of the call agent\n"
|
||||
"IPv6 Address of the call agent\n")
|
||||
"call-agent ip A.B.C.D",
|
||||
CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
@@ -958,8 +897,7 @@ static int config_write_trunk(struct vty *vty)
|
||||
config of trunk 0 here. The configuration for the virtual
|
||||
trunk is written by config_write_mgcp(). */
|
||||
|
||||
if (trunk->trunk_type == MGCP_TRUNK_VIRTUAL
|
||||
&& trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
|
||||
if (trunk->trunk_nr == MGCP_VIRT_TRUNK_ID)
|
||||
continue;
|
||||
|
||||
vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
|
||||
@@ -976,6 +914,7 @@ static int config_write_trunk(struct vty *vty)
|
||||
trunk->keepalive_interval, VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
|
||||
vty_out(vty, " loop %d%s", trunk->audio_loop, VTY_NEWLINE);
|
||||
vty_out(vty, " force-realloc %d%s",
|
||||
trunk->force_realloc, VTY_NEWLINE);
|
||||
vty_out(vty, " rtp-accept-all %d%s",
|
||||
@@ -1007,12 +946,11 @@ static int config_write_trunk(struct vty *vty)
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_sdp_fmtp_extra,
|
||||
cfg_trunk_sdp_fmtp_extra_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"sdp audio fmtp-extra .NAME",
|
||||
"Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
|
||||
"Extra Information\n")
|
||||
DEFUN(cfg_trunk_sdp_fmtp_extra,
|
||||
cfg_trunk_sdp_fmtp_extra_cmd,
|
||||
"sdp audio fmtp-extra .NAME",
|
||||
"Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
|
||||
"Extra Information\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
char *txt = argv_concat(argv, argc, 0);
|
||||
@@ -1048,168 +986,132 @@ ALIAS_DEPRECATED(cfg_trunk_payload_name, cfg_trunk_payload_name_cmd_old,
|
||||
"sdp audio payload name NAME",
|
||||
SDP_STR AUDIO_STR AUDIO_STR "Payload\n" "Payload Name\n")
|
||||
|
||||
DEFUN_DEPRECATED(cfg_trunk_loop,
|
||||
cfg_trunk_loop_cmd,
|
||||
"loop (0|1)",
|
||||
"Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
|
||||
{
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_force_realloc,
|
||||
cfg_trunk_force_realloc_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"force-realloc (0|1)",
|
||||
"Force endpoint reallocation when the endpoint is still seized\n"
|
||||
"Don't force reallocation\n" "force reallocation\n")
|
||||
DEFUN(cfg_trunk_loop,
|
||||
cfg_trunk_loop_cmd,
|
||||
"loop (0|1)",
|
||||
"Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
OSMO_ASSERT(trunk);
|
||||
trunk->force_realloc = atoi(argv[0]);
|
||||
|
||||
if (g_cfg->osmux) {
|
||||
vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
trunk->audio_loop = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_trunk_rtp_accept_all,
|
||||
cfg_trunk_rtp_accept_all_cmd,
|
||||
"rtp-accept-all (0|1)",
|
||||
"Accept all RTP packets, even when the originating IP/Port does not match\n"
|
||||
"enable filter\n" "disable filter\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
OSMO_ASSERT(trunk);
|
||||
trunk->rtp_accept_all = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_sdp_payload_send_ptime,
|
||||
cfg_trunk_sdp_payload_send_ptime_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"sdp audio-payload send-ptime",
|
||||
SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
DEFUN(cfg_trunk_sdp_payload_send_ptime,
|
||||
cfg_trunk_sdp_payload_send_ptime_cmd,
|
||||
"sdp audio-payload send-ptime",
|
||||
SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->audio_send_ptime = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_sdp_payload_send_ptime,
|
||||
cfg_trunk_no_sdp_payload_send_ptime_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no sdp audio-payload send-ptime",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
|
||||
cfg_trunk_no_sdp_payload_send_ptime_cmd,
|
||||
"no sdp audio-payload send-ptime",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->audio_send_ptime = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_sdp_payload_send_name,
|
||||
cfg_trunk_sdp_payload_send_name_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"sdp audio-payload send-name",
|
||||
SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
DEFUN(cfg_trunk_sdp_payload_send_name,
|
||||
cfg_trunk_sdp_payload_send_name_cmd,
|
||||
"sdp audio-payload send-name",
|
||||
SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->audio_send_name = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_sdp_payload_send_name,
|
||||
cfg_trunk_no_sdp_payload_send_name_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no sdp audio-payload send-name",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
DEFUN(cfg_trunk_no_sdp_payload_send_name,
|
||||
cfg_trunk_no_sdp_payload_send_name_cmd,
|
||||
"no sdp audio-payload send-name",
|
||||
NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->audio_send_name = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_trunk_omit_rtcp,
|
||||
cfg_trunk_omit_rtcp_cmd,
|
||||
"rtcp-omit", RTCP_OMIT_STR,
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->omit_rtcp = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_trunk_no_omit_rtcp,
|
||||
cfg_trunk_no_omit_rtcp_cmd,
|
||||
"no rtcp-omit", NO_STR RTCP_OMIT_STR,
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_trunk_no_omit_rtcp,
|
||||
cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->omit_rtcp = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_patch_rtp_ssrc,
|
||||
cfg_trunk_patch_rtp_ssrc_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
DEFUN(cfg_trunk_patch_rtp_ssrc,
|
||||
cfg_trunk_patch_rtp_ssrc_cmd,
|
||||
"rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->force_constant_ssrc = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_patch_rtp_ssrc,
|
||||
cfg_trunk_no_patch_rtp_ssrc_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
DEFUN(cfg_trunk_no_patch_rtp_ssrc,
|
||||
cfg_trunk_no_patch_rtp_ssrc_cmd,
|
||||
"no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->force_constant_ssrc = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_patch_rtp_ts,
|
||||
cfg_trunk_patch_rtp_ts_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
DEFUN(cfg_trunk_patch_rtp_ts,
|
||||
cfg_trunk_patch_rtp_ts_cmd,
|
||||
"rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->force_aligned_timing = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_patch_rtp_ts,
|
||||
cfg_trunk_no_patch_rtp_ts_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
DEFUN(cfg_trunk_no_patch_rtp_ts,
|
||||
cfg_trunk_no_patch_rtp_ts_cmd,
|
||||
"no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->force_aligned_timing = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_patch_rtp_rfc5993hr,
|
||||
cfg_trunk_patch_rtp_rfc5993hr_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
DEFUN(cfg_trunk_patch_rtp_rfc5993hr,
|
||||
cfg_trunk_patch_rtp_rfc5993hr_cmd,
|
||||
"rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->rfc5993_hr_convert = true;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_patch_rtp_rfc5993hr,
|
||||
cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,
|
||||
cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
|
||||
"no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->rfc5993_hr_convert = false;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_patch_rtp,
|
||||
cfg_trunk_no_patch_rtp_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no rtp-patch", NO_STR RTP_PATCH_STR)
|
||||
DEFUN(cfg_trunk_no_patch_rtp,
|
||||
cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->force_constant_ssrc = 0;
|
||||
@@ -1218,52 +1120,47 @@ DEFUN_USRATTR(cfg_trunk_no_patch_rtp,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_trunk_rtp_keepalive,
|
||||
cfg_trunk_rtp_keepalive_cmd,
|
||||
"rtp keep-alive <1-120>",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_trunk_rtp_keepalive,
|
||||
cfg_trunk_rtp_keepalive_cmd,
|
||||
"rtp keep-alive <1-120>",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_trunk_rtp_keepalive_once,
|
||||
cfg_trunk_rtp_keepalive_once_cmd,
|
||||
"rtp keep-alive once",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_trunk_rtp_keepalive_once,
|
||||
cfg_trunk_rtp_keepalive_once_cmd,
|
||||
"rtp keep-alive once",
|
||||
RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_trunk_no_rtp_keepalive,
|
||||
cfg_trunk_no_rtp_keepalive_cmd,
|
||||
"no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR,
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
DEFUN(cfg_trunk_no_rtp_keepalive,
|
||||
cfg_trunk_no_rtp_keepalive_cmd,
|
||||
"no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
mgcp_trunk_set_keepalive(trunk, 0);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_allow_transcoding,
|
||||
cfg_trunk_allow_transcoding_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"allow-transcoding", "Allow transcoding\n")
|
||||
DEFUN(cfg_trunk_allow_transcoding,
|
||||
cfg_trunk_allow_transcoding_cmd,
|
||||
"allow-transcoding", "Allow transcoding\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->no_audio_transcoding = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_trunk_no_allow_transcoding,
|
||||
cfg_trunk_no_allow_transcoding_cmd,
|
||||
X(MGW_CMD_ATTR_NEWCONN),
|
||||
"no allow-transcoding", NO_STR "Allow transcoding\n")
|
||||
DEFUN(cfg_trunk_no_allow_transcoding,
|
||||
cfg_trunk_no_allow_transcoding_cmd,
|
||||
"no allow-transcoding", NO_STR "Allow transcoding\n")
|
||||
{
|
||||
struct mgcp_trunk *trunk = vty->index;
|
||||
trunk->no_audio_transcoding = 1;
|
||||
@@ -1339,15 +1236,13 @@ DEFUN(loop_conn,
|
||||
|
||||
DEFUN(tap_rtp,
|
||||
tap_rtp_cmd,
|
||||
"tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
|
||||
"tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
|
||||
"Forward data on endpoint to a different system\n" "Trunk number\n"
|
||||
"The endpoint in hex\n"
|
||||
"The connection id in hex\n"
|
||||
"Forward incoming data\n"
|
||||
"Forward leaving data\n"
|
||||
"Destination IPv4 of the data\n"
|
||||
"Destination IPv6 of the data\n"
|
||||
"Destination port\n")
|
||||
"destination IP of the data\n" "destination port\n")
|
||||
{
|
||||
struct mgcp_rtp_tap *tap;
|
||||
struct mgcp_trunk *trunk;
|
||||
@@ -1395,22 +1290,8 @@ DEFUN(tap_rtp,
|
||||
}
|
||||
|
||||
memset(&tap->forward, 0, sizeof(tap->forward));
|
||||
|
||||
tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
|
||||
switch (tap->forward.u.sa.sa_family) {
|
||||
case AF_INET:
|
||||
if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
|
||||
return CMD_WARNING;
|
||||
tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
|
||||
return CMD_WARNING;
|
||||
tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
|
||||
break;
|
||||
default:
|
||||
return CMD_WARNING;
|
||||
}
|
||||
inet_aton(argv[4], &tap->forward.sin_addr);
|
||||
tap->forward.sin_port = htons(atoi(argv[5]));
|
||||
tap->enabled = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -1515,16 +1396,18 @@ DEFUN(cfg_mgcp_osmux,
|
||||
else if (strcmp(argv[0], "only") == 0)
|
||||
g_cfg->osmux = OSMUX_USAGE_ONLY;
|
||||
|
||||
if (trunk->audio_loop) {
|
||||
vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
DEFUN(cfg_mgcp_osmux_ip,
|
||||
cfg_mgcp_osmux_ip_cmd,
|
||||
"osmux bind-ip " VTY_IPV46_CMD,
|
||||
OSMUX_STR IP_STR
|
||||
"IPv4 Address to bind to\n"
|
||||
"IPv6 Address to bind to\n")
|
||||
"osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
|
||||
{
|
||||
osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
@@ -1615,10 +1498,8 @@ int mgcp_vty_init(void)
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_port_range_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_bind_ip_v6_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bind_ip_v6_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
|
||||
install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
|
||||
@@ -1673,8 +1554,6 @@ int mgcp_vty_init(void)
|
||||
install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd_old);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd_old);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_loop_cmd);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_force_realloc_cmd);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_rtp_accept_all_cmd);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_omit_rtcp_cmd);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
|
||||
install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
|
||||
|
||||
@@ -60,8 +60,6 @@
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/stats.h>
|
||||
#include <osmocom/vty/misc.h>
|
||||
#include <osmocom/vty/cpu_sched_vty.h>
|
||||
|
||||
#include <osmocom/abis/abis.h>
|
||||
|
||||
#include "../../bscconfig.h"
|
||||
@@ -93,45 +91,17 @@ const char *osmomgw_copyright =
|
||||
static char *config_file = "osmo-mgw.cfg";
|
||||
|
||||
/* used by msgb and mgcp */
|
||||
void *tall_mgw_ctx = NULL;
|
||||
void *tall_bsc_ctx = NULL;
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
printf("Some useful options:\n");
|
||||
printf("Some useful help...\n");
|
||||
printf(" -h --help is printing this text.\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -D --daemonize Fork the process into a background daemon\n");
|
||||
printf(" -V --version Print the version number\n");
|
||||
|
||||
printf("\nVTY reference generation:\n");
|
||||
printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n");
|
||||
printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
|
||||
}
|
||||
|
||||
static void handle_long_options(const char *prog_name, const int long_option)
|
||||
{
|
||||
static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
|
||||
|
||||
switch (long_option) {
|
||||
case 1:
|
||||
vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
|
||||
if (vty_ref_mode < 0) {
|
||||
fprintf(stderr, "%s: Unknown VTY reference generation "
|
||||
"mode '%s'\n", prog_name, optarg);
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
|
||||
get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
|
||||
get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
|
||||
vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
|
||||
exit(2);
|
||||
}
|
||||
printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
@@ -145,8 +115,7 @@ static void handle_options(int argc, char **argv)
|
||||
{"daemonize", 0, 0, 'D'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"vty-ref-mode", 1, &long_option, 1},
|
||||
{"vty-ref-xml", 0, &long_option, 2},
|
||||
{"vty-ref-xml", 0, &long_option, 1},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
@@ -161,10 +130,16 @@ static void handle_options(int argc, char **argv)
|
||||
exit(0);
|
||||
break;
|
||||
case 0:
|
||||
handle_long_options(argv[0], long_option);
|
||||
break;
|
||||
switch (long_option) {
|
||||
case 1:
|
||||
vty_dump_xml_ref(stdout);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "error parsing cmdline options\n");
|
||||
exit(2);
|
||||
}
|
||||
case 'c':
|
||||
config_file = talloc_strdup(tall_mgw_ctx, optarg);
|
||||
config_file = talloc_strdup(tall_bsc_ctx, optarg);
|
||||
break;
|
||||
case 's':
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
@@ -202,7 +177,7 @@ static int mgcp_rsip_cb(struct mgcp_trunk *trunk)
|
||||
|
||||
static int read_call_agent(struct osmo_fd *fd, unsigned int what)
|
||||
{
|
||||
struct osmo_sockaddr addr;
|
||||
struct sockaddr_in addr;
|
||||
socklen_t slen = sizeof(addr);
|
||||
struct msgb *msg;
|
||||
struct msgb *resp;
|
||||
@@ -228,7 +203,7 @@ static int read_call_agent(struct osmo_fd *fd, unsigned int what)
|
||||
msgb_reset(msg);
|
||||
|
||||
if (resp) {
|
||||
sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, &addr.u.sa, sizeof(addr));
|
||||
sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
msgb_free(resp);
|
||||
}
|
||||
|
||||
@@ -315,24 +290,20 @@ int main(int argc, char **argv)
|
||||
unsigned int flags;
|
||||
int rc;
|
||||
|
||||
tall_mgw_ctx = talloc_named_const(NULL, 1, "mgcp-callagent");
|
||||
vty_info.tall_ctx = tall_mgw_ctx;
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "mgcp-callagent");
|
||||
vty_info.tall_ctx = tall_bsc_ctx;
|
||||
|
||||
msgb_talloc_ctx_init(tall_mgw_ctx, 0);
|
||||
msgb_talloc_ctx_init(tall_bsc_ctx, 0);
|
||||
|
||||
osmo_init_ignore_signals();
|
||||
osmo_init_logging2(tall_mgw_ctx, &log_info);
|
||||
libosmo_abis_init(tall_mgw_ctx);
|
||||
osmo_init_logging2(tall_bsc_ctx, &log_info);
|
||||
libosmo_abis_init(tall_bsc_ctx);
|
||||
|
||||
cfg = mgcp_config_alloc();
|
||||
if (!cfg)
|
||||
return -1;
|
||||
|
||||
vty_info.copyright = osmomgw_copyright;
|
||||
vty_info.usr_attr_desc[MGW_CMD_ATTR_NEWCONN] = \
|
||||
"This command applies when a new connection is created";
|
||||
vty_info.usr_attr_letters[MGW_CMD_ATTR_NEWCONN] = 'n';
|
||||
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds();
|
||||
osmo_talloc_vty_add_cmds();
|
||||
@@ -340,19 +311,18 @@ int main(int argc, char **argv)
|
||||
mgcp_vty_init();
|
||||
ctrl_vty_init(cfg);
|
||||
e1inp_vty_init();
|
||||
osmo_cpu_sched_vty_init(tall_mgw_ctx);
|
||||
|
||||
handle_options(argc, argv);
|
||||
|
||||
rate_ctr_init(tall_mgw_ctx);
|
||||
osmo_stats_init(tall_mgw_ctx);
|
||||
rate_ctr_init(tall_bsc_ctx);
|
||||
osmo_stats_init(tall_bsc_ctx);
|
||||
|
||||
rc = mgcp_parse_config(config_file, cfg, MGCP_BSC);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* start telnet after reading config for vty_get_bind_addr() */
|
||||
rc = telnet_init_dynif(tall_mgw_ctx, NULL,
|
||||
rc = telnet_init_dynif(tall_bsc_ctx, NULL,
|
||||
vty_get_bind_addr(), OSMO_VTY_PORT_MGW);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@@ -372,7 +342,7 @@ int main(int argc, char **argv)
|
||||
if (cfg->call_agent_addr)
|
||||
flags |= OSMO_SOCK_F_CONNECT;
|
||||
|
||||
rc = osmo_sock_init2_ofd(&cfg->gw_fd.bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
|
||||
rc = osmo_sock_init2_ofd(&cfg->gw_fd.bfd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
|
||||
cfg->source_addr, cfg->source_port,
|
||||
cfg->call_agent_addr, cfg->call_agent_addr ? 2727 : 0, flags);
|
||||
if (rc < 0) {
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <dlfcn.h>
|
||||
@@ -1263,7 +1262,7 @@ struct rtp_packet_info test_rtp_packets1[] = {
|
||||
void mgcp_patch_and_count(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr, struct msgb *msg);
|
||||
struct sockaddr_in *addr, struct msgb *msg);
|
||||
|
||||
static void test_packet_error_detection(int patch_ssrc, int patch_ts)
|
||||
{
|
||||
@@ -1275,7 +1274,7 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts)
|
||||
struct mgcp_config cfg = {0};
|
||||
struct mgcp_rtp_state state;
|
||||
struct mgcp_rtp_end *rtp;
|
||||
struct osmo_sockaddr addr = { 0 };
|
||||
struct sockaddr_in addr = { 0 };
|
||||
uint32_t last_ssrc = 0;
|
||||
uint32_t last_timestamp = 0;
|
||||
uint32_t last_seqno = 0;
|
||||
@@ -1487,8 +1486,7 @@ static void test_multilple_codec(void)
|
||||
OSMO_ASSERT(conn->end.rtp_port == htons(16434));
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
inet_aton("8.8.8.8", &addr);
|
||||
OSMO_ASSERT(conn->end.addr.u.sa.sa_family == AF_INET);
|
||||
OSMO_ASSERT(conn->end.addr.u.sin.sin_addr.s_addr == addr.s_addr);
|
||||
OSMO_ASSERT(conn->end.addr.s_addr == addr.s_addr);
|
||||
|
||||
/* Check what happens without that flag */
|
||||
|
||||
@@ -2126,8 +2124,6 @@ void test_e1_trunk_nr_from_epname()
|
||||
/* Note: e1_trunk_nr_from_epname does not check the text
|
||||
* after the E1 trunk number, after the delimiter
|
||||
* character "/" arbitrary text may follow. */
|
||||
trunk_nr = e1_trunk_nr_from_epname("ds/e1-0/s-1/su16-0");
|
||||
OSMO_ASSERT(trunk_nr == 0);
|
||||
trunk_nr = e1_trunk_nr_from_epname("ds/e1-1/s-1/su16-0");
|
||||
OSMO_ASSERT(trunk_nr == 1);
|
||||
trunk_nr = e1_trunk_nr_from_epname("ds/e1-2/s-2/su16-0");
|
||||
@@ -2145,6 +2141,8 @@ void test_e1_trunk_nr_from_epname()
|
||||
* trunk number exceeds the valid range or the trunk prefix
|
||||
* is wrong. Also when the delimiter character "/" at the
|
||||
* end of the trunk is wrong the parsing should fail. */
|
||||
trunk_nr = e1_trunk_nr_from_epname("ds/e1-0/s-1/su16-0");
|
||||
OSMO_ASSERT(trunk_nr == -EINVAL);
|
||||
trunk_nr = e1_trunk_nr_from_epname("ds/e1-65/s-1/su16-0");
|
||||
OSMO_ASSERT(trunk_nr == -EINVAL);
|
||||
trunk_nr = e1_trunk_nr_from_epname("ds/e1--1/s-1/su16-0");
|
||||
|
||||
@@ -294,23 +294,11 @@ void test_mgcp_msg(void)
|
||||
MGCP_MSG_PRESENCE_CONN_ID | MGCP_MSG_PRESENCE_CONN_MODE |
|
||||
MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT);
|
||||
memset(audio_ip_overflow, 'X', sizeof(audio_ip_overflow));
|
||||
audio_ip_overflow[1] = '.';
|
||||
audio_ip_overflow[sizeof(audio_ip_overflow) - 1] = '\0';
|
||||
mgcp_msg.audio_ip = audio_ip_overflow;
|
||||
msg = mgcp_msg_gen(mgcp, &mgcp_msg);
|
||||
OSMO_ASSERT(msg == NULL);
|
||||
|
||||
printf("IPv6 test:\n");
|
||||
mgcp_msg.verb = MGCP_VERB_MDCX;
|
||||
mgcp_msg.presence =
|
||||
(MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID |
|
||||
MGCP_MSG_PRESENCE_CONN_ID | MGCP_MSG_PRESENCE_CONN_MODE |
|
||||
MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT);
|
||||
mgcp_msg.audio_ip = "2001:db8:1::ab9:c0a8:102";
|
||||
mgcp->actual.remote_addr = "::1";
|
||||
msg = mgcp_msg_gen(mgcp, &mgcp_msg);
|
||||
printf("%s\n", (char *)msg->data);
|
||||
|
||||
printf("\n");
|
||||
msgb_free(msg);
|
||||
}
|
||||
@@ -425,66 +413,6 @@ static struct sdp_section_start_test sdp_section_start_tests[] = {
|
||||
"m=audio 23\r\n",
|
||||
.expect_rc = 0,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 1.2.3.4\r\n",
|
||||
.expect_params = {
|
||||
.audio_ip = "1.2.3.4",
|
||||
},
|
||||
.expect_rc = 0,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP6 2001:db8:1::ab9:c0a8:102\r\n",
|
||||
.expect_params = {
|
||||
.audio_ip = "2001:db8:1::ab9:c0a8:102",
|
||||
},
|
||||
.expect_rc = 0,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP6 1.2.3.4\r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 ::1\r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 notanip\r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 1.2.3.4.5.6\r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 1.2 .3\r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 1.2 .3\r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
{
|
||||
.body = "some mgcp header data\r\nand header params"
|
||||
"\r\n\r\n"
|
||||
"c=IN IP4 \r\n",
|
||||
.expect_rc = -22,
|
||||
},
|
||||
};
|
||||
|
||||
void test_sdp_section_start()
|
||||
@@ -515,12 +443,7 @@ void test_sdp_section_start()
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stderr, "got audio_ip=\"%s\"\n", r->audio_ip);
|
||||
if (strcmp(r->audio_ip, t->expect_params.audio_ip)) {
|
||||
fprintf(stderr, "FAIL: Expected audio_ip=\"%s\"\n", t->expect_params.audio_ip);
|
||||
failures++;
|
||||
}
|
||||
fprintf(stderr, "got audio_port=%u\n", r->audio_port);
|
||||
fprintf(stderr, "got audio_port=%u\n", t->expect_params.audio_port);
|
||||
if (r->audio_port != t->expect_params.audio_port) {
|
||||
fprintf(stderr, "FAIL: Expected audio_port=%u\n", t->expect_params.audio_port);
|
||||
failures++;
|
||||
@@ -689,10 +612,9 @@ int main(int argc, char **argv)
|
||||
ctx = talloc_named_const(NULL, 1, "mgcp_client_test");
|
||||
msgb_talloc_ctx_init(ctx, 0);
|
||||
osmo_init_logging2(ctx, &log_info);
|
||||
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
|
||||
log_set_print_filename(osmo_stderr_target, 0);
|
||||
log_set_print_timestamp(osmo_stderr_target, 0);
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
log_set_print_category_hex(osmo_stderr_target, 0);
|
||||
log_set_print_category(osmo_stderr_target, 1);
|
||||
|
||||
log_set_category_filter(osmo_stderr_target, DLMGCP, 1, LOGL_DEBUG);
|
||||
|
||||
@@ -19,112 +19,55 @@ test_sdp_section_start() test [0]:
|
||||
body: ""
|
||||
DLMGCP MGCP response contains no SDP parameters
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [1]:
|
||||
body: "\n\n"
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [2]:
|
||||
body: "\r\n\r\n"
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [3]:
|
||||
body: "\n\r\n\r"
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [4]:
|
||||
body: "some mgcp header data\r\nand header params\n\nm=audio 23\r\n"
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=23
|
||||
|
||||
test_sdp_section_start() test [5]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nm=audio 23\r\n"
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=23
|
||||
|
||||
test_sdp_section_start() test [6]:
|
||||
body: "some mgcp header data\r\nand header params\n\r\n\rm=audio 23\r\n"
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=23
|
||||
|
||||
test_sdp_section_start() test [7]:
|
||||
body: "some mgcp header data\r\nand header params\n\r\nm=audio 23\r\n"
|
||||
DLMGCP MGCP response contains no SDP parameters
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [8]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\rm=audio 23\r\n"
|
||||
DLMGCP MGCP response contains no SDP parameters
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [9]:
|
||||
body: "some mgcp header data\r\nand header params\n\r\rm=audio 23\r\n"
|
||||
DLMGCP MGCP response contains no SDP parameters
|
||||
got rc=0
|
||||
got audio_ip=""
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [10]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2.3.4\r\n"
|
||||
got rc=0
|
||||
got audio_ip="1.2.3.4"
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [11]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP6 2001:db8:1::ab9:c0a8:102\r\n"
|
||||
got rc=0
|
||||
got audio_ip="2001:db8:1::ab9:c0a8:102"
|
||||
got audio_port=0
|
||||
|
||||
test_sdp_section_start() test [12]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP6 1.2.3.4\r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
|
||||
test_sdp_section_start() test [13]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 ::1\r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
|
||||
test_sdp_section_start() test [14]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 notanip\r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
|
||||
test_sdp_section_start() test [15]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2.3.4.5.6\r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
|
||||
test_sdp_section_start() test [16]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2 .3\r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
|
||||
test_sdp_section_start() test [17]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2 .3\r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
|
||||
test_sdp_section_start() test [18]:
|
||||
body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 \r\n"
|
||||
DLMGCP Failed to parse MGCP response header (audio ip)
|
||||
got rc=-22
|
||||
DLMGCP ptmap contains illegal mapping: codec=113 maps to pt=2
|
||||
DLMGCP ptmap contains illegal mapping: codec=0 maps to pt=100
|
||||
DLMGCP ptmap contains illegal mapping: codec=113 maps to pt=2
|
||||
|
||||
@@ -109,20 +109,6 @@ M: sendrecv
|
||||
X-Osmux: 2
|
||||
|
||||
Overfolow test:
|
||||
IPv6 test:
|
||||
MDCX 19 23@mgw MGCP 1.0
|
||||
C: 2f
|
||||
I: 11
|
||||
M: sendrecv
|
||||
|
||||
v=0
|
||||
o=- 2f 23 IN IP6 ::1
|
||||
s=-
|
||||
c=IN IP6 2001:db8:1::ab9:c0a8:102
|
||||
t=0 0
|
||||
m=audio 1234 RTP/AVP 3
|
||||
a=ptime:20
|
||||
|
||||
|
||||
|
||||
test_mgcp_client_cancel():
|
||||
@@ -163,24 +149,6 @@ test_sdp_section_start() test [7]:
|
||||
test_sdp_section_start() test [8]:
|
||||
|
||||
test_sdp_section_start() test [9]:
|
||||
|
||||
test_sdp_section_start() test [10]:
|
||||
|
||||
test_sdp_section_start() test [11]:
|
||||
|
||||
test_sdp_section_start() test [12]:
|
||||
|
||||
test_sdp_section_start() test [13]:
|
||||
|
||||
test_sdp_section_start() test [14]:
|
||||
|
||||
test_sdp_section_start() test [15]:
|
||||
|
||||
test_sdp_section_start() test [16]:
|
||||
|
||||
test_sdp_section_start() test [17]:
|
||||
|
||||
test_sdp_section_start() test [18]:
|
||||
110 => 96
|
||||
111 => 97
|
||||
112 => 98
|
||||
|
||||
Reference in New Issue
Block a user