mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 13:03:33 +00:00
Compare commits
2 Commits
neels/iuup
...
review/msu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e14ee36650 | ||
|
|
cd35f724f0 |
@@ -24,3 +24,6 @@
|
||||
# If any interfaces have been removed or changed since the last public release, a=0.
|
||||
#
|
||||
#library what description / commit summary line
|
||||
libosmo-netif >1.2.0 OSMUX_DEFAULT_PORT, osmux_xfrm_output_*, osmux_xfrm_input_*
|
||||
libosmocore >1.7.0 osmo_sockaddr_is_any()
|
||||
libmgcp-client NEW APIs mgcp_client_pool_member_...(), mgcp_client_pool_config_write()
|
||||
15
configure.ac
15
configure.ac
@@ -44,13 +44,13 @@ AC_SEARCH_LIBS([dlsym], [dl dld], [LIBRARY_DLSYM="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_DLSYM)
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.4.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.2.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.3.0)
|
||||
|
||||
CFLAGS="$CFLAGS -pthread"
|
||||
LDFLAGS="$LDFLAGS -pthread"
|
||||
@@ -79,7 +79,6 @@ AC_ARG_ENABLE(werror,
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Werror=implicit-int -Werror=int-conversion -Werror=old-style-definition"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
CFLAGS="$CFLAGS $WERROR_FLAGS"
|
||||
|
||||
@@ -29,30 +29,31 @@ BuildRequires: pkgconfig >= 0.20
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.3.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmocoding) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.4.0
|
||||
BuildRequires: pkgconfig(libosmotrau) >= 1.4.0
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.2.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmocoding) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.3.0
|
||||
BuildRequires: pkgconfig(libosmotrau) >= 1.3.0
|
||||
Requires(pre): shadow
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
OsmoMGW is Osmocom's Media Gateway for 2G and 3G circuit-switched mobile networks.
|
||||
|
||||
%package -n libosmo-mgcp-client11
|
||||
%package -n libosmo-mgcp-client9
|
||||
Summary: Osmocom's Media Gateway Control Protocol client library
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libosmo-mgcp-client11
|
||||
%description -n libosmo-mgcp-client9
|
||||
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-client11 = %{version}
|
||||
Requires: libosmo-mgcp-client9 = %{version}
|
||||
|
||||
%description -n libosmo-mgcp-client-devel
|
||||
Osmocom's Media Gateway Control Protocol client librarary.
|
||||
@@ -90,8 +91,8 @@ find %{buildroot} -type f -name "*.la" -delete -print
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%post -n libosmo-mgcp-client11 -p /sbin/ldconfig
|
||||
%postun -n libosmo-mgcp-client11 -p /sbin/ldconfig
|
||||
%post -n libosmo-mgcp-client9 -p /sbin/ldconfig
|
||||
%postun -n libosmo-mgcp-client9 -p /sbin/ldconfig
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%preun
|
||||
@@ -101,10 +102,17 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
%service_del_postun osmo-mgw.service
|
||||
|
||||
%pre
|
||||
getent group osmocom >/dev/null || groupadd --system osmocom
|
||||
getent passwd osmocom >/dev/null || useradd --system --gid osmocom --home-dir /var/lib/osmocom \
|
||||
--shell /sbin/nologin --comment "Open Source Mobile Communications" osmocom
|
||||
%service_add_pre osmo-mgw.service
|
||||
|
||||
%post
|
||||
%service_add_post osmo-mgw.service
|
||||
chown osmocom:osmocom /etc/osmocom/osmo-mgw.cfg
|
||||
chmod 0660 /etc/osmocom/osmo-mgw.cfg
|
||||
chown root:osmocom /etc/osmocom
|
||||
chmod 2775 /etc/osmocom
|
||||
%endif
|
||||
|
||||
%files
|
||||
@@ -119,8 +127,8 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-mgw.cfg
|
||||
|
||||
%files -n libosmo-mgcp-client11
|
||||
%{_libdir}/libosmo-mgcp-client.so.11*
|
||||
%files -n libosmo-mgcp-client9
|
||||
%{_libdir}/libosmo-mgcp-client.so.9*
|
||||
|
||||
%files -n libosmo-mgcp-client-devel
|
||||
%{_libdir}/libosmo-mgcp-client.so
|
||||
|
||||
@@ -5,6 +5,8 @@ Description=Osmocom Media Gateway (MGW)
|
||||
Type=simple
|
||||
StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
User=osmocom
|
||||
Group=osmocom
|
||||
Restart=always
|
||||
ExecStart=/usr/bin/osmo-mgw -s -c /etc/osmocom/osmo-mgw.cfg
|
||||
RestartSec=2
|
||||
|
||||
135
debian/changelog
vendored
135
debian/changelog
vendored
@@ -1,138 +1,3 @@
|
||||
osmo-mgw (1.11.0) unstable; urgency=medium
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* mgcp-client: Remove impossible code path
|
||||
* mgcp_osmux: Drop duplicated conn_osmux_release_cid() in code path
|
||||
* Use Osmux default port define from libosmo-netif
|
||||
* osmux: Use new osmux APIs to let libosmo-netif alloc struct osmux_out_handle
|
||||
* mgw: Fix osmux conn local IP selection
|
||||
* cosmetic: osmux: Fix wrong indentation
|
||||
* mgw: Use X-Osmux string define
|
||||
* Add Osmux log category
|
||||
* cosmetic: main: Properly format log_info_cat
|
||||
* osmux: Use better name for function which may allocate a new struct
|
||||
* osmux: Use osmo_sockaddr wherever possible
|
||||
* osmux: Log refcounting of osmux_handle_list
|
||||
* osmux: Fix memleak on error code path
|
||||
* osmux: don't store conn ptr inside shared osmux_handle
|
||||
* osmux: set log level of expected code path to INFO
|
||||
* cosmetic: vty: Fix indentation whitespace
|
||||
* osmux: Log sendto() error
|
||||
* cosmetic: mgcp_conn.h: fix indentation whitespace
|
||||
* osmux: Attach osmux to virtual trunk
|
||||
* osmux: Clean up helper macro osmux_chunk_length()
|
||||
* osmux: Get rid of static NULL talloc context
|
||||
* Fix typo in ratectr description
|
||||
* mgcp_conn: rename field s/rate_ctr_group/ctrg/g
|
||||
* Use 'static const' instead of 'const static' everywhere
|
||||
* osmux: Add connection and global rate counters
|
||||
* cosmetic: osmux: Fix formatting of if-else brackets
|
||||
* osmux: Rename field osmux usage policy and define it with proper type
|
||||
* Use bool type instead of int in config field
|
||||
* osmux: Support local CID != remote CID
|
||||
* osmux: Fix incorrect rate_ctr_group used in mgcp_osmux.c
|
||||
* osmux: Improve per-conn tx rate counters
|
||||
* vty: show per-connection Osmux VTY stats
|
||||
* osmux: Rename field s/init/initialized
|
||||
* osmux: Allocate rate counters during initialization of osmux conn
|
||||
* cosmetic: osmux: Drop extra empty line
|
||||
* osmux: Drop unneeded comment block
|
||||
* osmux: Lower log level when osmux batch received for unknown CID
|
||||
* osmux: Keep decoding osmux pkt if a batch contains an unknown CID
|
||||
* Allocate struct osmux_in_handle through new libosmo-netif APIs
|
||||
* osmux: Drop logging of osmux internal counters
|
||||
* osmux: cleanup misleading code calling rtp_bridge_cb
|
||||
* osmux: Unify rtp_conn osmux type into a single type
|
||||
* osmux: Match remote address in osmux_conn_lookup()
|
||||
* osmux: Fill in from_addr in struct osmo_rtp_msg_ctx
|
||||
* osmux: Log remote address upon rx of osmux pkt
|
||||
* send_dummy: Use proper condition to test if conn is osmux
|
||||
* Fix regression in detection of legacy dummy packets
|
||||
* Use new libosmocore API osmo_sockaddr_is_any()
|
||||
* Get rid of separate rtp_port field
|
||||
* osmux: Use available API to check if remote end is known
|
||||
* Add Osmux IPv6 support
|
||||
* Clean up local var pointers in mgcp_get_local_addr()
|
||||
* osmux: Change couple log lines to OSMUX category
|
||||
* osmux: Add square brackets around IPv6 address to distinguish port in log line
|
||||
* osmux: Drop unused role parameter
|
||||
* osmux: cosmetic: Fix indentation
|
||||
* Check once if remote addr is available when sending dummy packet
|
||||
* osmux: Simplify and constify param passing
|
||||
* osmux: Set conn->type during osmux_init_conn()
|
||||
* osmux: Make conn_osmux_{allocate,release}_local_cid() APIs static
|
||||
* osmux: Define osmux_dummy cfg as boolean
|
||||
* osmux: Move setting OSMUX_STATE_DISABLED to initializer function
|
||||
* osmux: Erase references to bsc-nat
|
||||
* mgcp_conn_dump(): Separate dump for osmux and iuup connections
|
||||
* osmux: Introduce osmux peer-behind-nat (on|off) and rework conn activation
|
||||
* osmux: Clean up mgcp_config osmux fields
|
||||
* cosmetic: Fix typo in comment
|
||||
* mgcp-client: pool: Improve documentation of some internal fields
|
||||
* mgcp-client: Avoid double iteration picking client from pool
|
||||
* mgcp-client: Fix typo in internal function name
|
||||
* mgcp-client: Rename internal field in mgcp_client_pool
|
||||
* mgcp-client: Move & rename helper function outside of vty code
|
||||
* mgcp-client: Create alloc() and free() internal APIs for mgcp_client_pool_member
|
||||
* mgcp-client: Move internal API acting on mgcp_client_pool to the correct file section
|
||||
* mgcp-client: Refactor reinit of mgcp clients
|
||||
* mgcp-client: Rearrange order of structs and APIs in header
|
||||
* mgcp-client: Rearrange internal backpointers
|
||||
* mgcp-client: Introduce APIs to manually select mgcp_client from pool
|
||||
* mgcp-client: vty: Write deprecation warning using non-mgw nodes
|
||||
* mgcp-client: Use random free local port by default
|
||||
* mgcp-client: Convert users supporting new MGW Pool VTY node during write-config
|
||||
* mgcp-client: Introduce API mgcp_client_pool_config_write
|
||||
* mgcp-client: Add new VTY commands under mgw node without mgw prefix
|
||||
* mgcp-client: Fix 'mgw endpoint-range' command dropped from old VTY node
|
||||
* mgcp-client: Refactor system keeping old users not calling mgcp_client_pool_config_write() working
|
||||
* mgcp-client: Fix no 'mgw ' prefix written in old VTY node
|
||||
* Fix misleading error log
|
||||
* mgcp_send: Use mgcp_conn_rtp_is_iuup() helper
|
||||
* cosmetic: Clarify and fix typos in comment
|
||||
* mgw: Log unexpected RTP AMR OA-vs-BE payload
|
||||
* Rename and move func checking if amr mode is explicitly configured
|
||||
* mgw: rx_rtp(): reorder checks and handlings
|
||||
* mgw: Rename s/mgcp_send_rtp/mgcp_conn_rtp_dispatch_rtp/
|
||||
* osmux: Rename function and pass msgb directly to it
|
||||
* osmux: Make sure RTP AMR feed to osmux is in octet-aligned mode
|
||||
* Improve logging on AMR OA<->BWE conversion failure
|
||||
* osmux: Rotate over available Osmux CID when allocating a new one
|
||||
* osmux: Use new osmux_xfrm_input API to set name on each link
|
||||
* iuup: Use osmo_amr_ft_valid() API
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* libosmo-mgcp-client: add -no-undefined to *_la_LDFLAGS
|
||||
|
||||
[ Philipp Maier ]
|
||||
* mgcp_e1: fix apidoc
|
||||
* mgcp_network: improve coment
|
||||
|
||||
[ Max ]
|
||||
* Set working directory in systemd service file
|
||||
* Add realtime scheduling and set priority in service file
|
||||
* ctrl: take both address and port from vty config
|
||||
|
||||
[ Harald Welte ]
|
||||
* Make osmo_mgcpc_ep_fsm_pre_term() static
|
||||
* Support building with -Werror=strict-prototypes / -Werror=old-style-definition
|
||||
* Add -Werror=implicit-int -Werror=int-conversion -Werror=old-style-definition
|
||||
* update outdated vty copyright statement
|
||||
|
||||
[ Oliver Smith ]
|
||||
* mgcp_client_pool.h: add missing stdbool include
|
||||
* Fix various typos
|
||||
* mgcp_client: add new clearmode codec
|
||||
|
||||
[ Neels Hofmeyr ]
|
||||
* AMR->IuUP: do not crash on AMR data before IuUP Init
|
||||
* AMR->IuUP: properly translate Q -> FQC
|
||||
* IuUP->AMR: do not patch payload type a second time
|
||||
* IuUP->AMR: log whether converting to AMR OA or BE
|
||||
* AMR->IuUP: log conversion, like for the flipside
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 16:58:41 +0100
|
||||
|
||||
osmo-mgw (1.10.0) unstable; urgency=medium
|
||||
|
||||
[ Eric ]
|
||||
|
||||
14
debian/control
vendored
14
debian/control
vendored
@@ -6,10 +6,10 @@ Build-Depends: debhelper (>=9),
|
||||
dh-autoreconf,
|
||||
pkg-config,
|
||||
autotools-dev,
|
||||
libosmocore-dev (>= 1.8.0),
|
||||
libosmo-netif-dev (>= 1.3.0),
|
||||
libosmo-abis-dev (>= 1.4.0),
|
||||
osmo-gsm-manuals-dev (>= 1.4.0)
|
||||
libosmocore-dev (>= 1.7.0),
|
||||
libosmo-netif-dev (>= 1.2.0),
|
||||
libosmo-abis-dev (>= 1.3.0),
|
||||
osmo-gsm-manuals-dev (>= 1.3.0)
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw
|
||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw
|
||||
@@ -18,10 +18,10 @@ Homepage: https://osmocom.org/projects/osmo-mgw
|
||||
Package: osmo-mgw
|
||||
Architecture: any
|
||||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, adduser
|
||||
Description: OsmoMGW: Osmocom's Media Gateway for 2G and 3G circuit-switched mobile networks
|
||||
|
||||
Package: libosmo-mgcp-client11
|
||||
Package: libosmo-mgcp-client9
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
@@ -33,7 +33,7 @@ Package: libosmo-mgcp-client-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: libosmo-mgcp-client11 (= ${binary:Version}), ${misc:Depends}
|
||||
Depends: libosmo-mgcp-client9 (= ${binary:Version}), ${misc:Depends}
|
||||
Description: libosmo-mgcp-client: Osmocom's Media Gateway Control Protocol client utilities
|
||||
|
||||
Package: osmo-mgw-doc
|
||||
|
||||
39
debian/postinst
vendored
Executable file
39
debian/postinst
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Create 'osmocom' user and group (if it doesn't exist yet) and adjust permissions
|
||||
# of directories which are not automatically adjusted by systemd from previous (root-owned)
|
||||
# install.
|
||||
|
||||
# N. B: the user is intentionally NOT removed during package uninstall:
|
||||
# see https://wiki.debian.org/AccountHandlingInMaintainerScripts for reasoning.
|
||||
chperms() {
|
||||
# chperms <user> <group> <perms> <file>
|
||||
if ! OVERRIDE=`dpkg-statoverride --list $4 2>&1`; then
|
||||
if [ -e $4 ]; then
|
||||
chown $1:$2 $4
|
||||
chmod $3 $4
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
if ! getent passwd osmocom > /dev/null; then
|
||||
adduser --quiet \
|
||||
--system \
|
||||
--group \
|
||||
--no-create-home \
|
||||
--disabled-password \
|
||||
--home /var/lib/osmocom \
|
||||
--gecos "Open Source Mobile Communications" \
|
||||
osmocom
|
||||
fi
|
||||
# Set permissions according to https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
|
||||
chperms osmocom osmocom 0660 /etc/osmocom/osmo-mgw.cfg
|
||||
chperms root osmocom 2775 /etc/osmocom
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb(1) will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
#DEBHELPER#
|
||||
@@ -6,6 +6,7 @@ noinst_HEADERS = \
|
||||
mgcp_endp.h \
|
||||
mgcp_sdp.h \
|
||||
mgcp_codec.h \
|
||||
mgcp_ctrl.h \
|
||||
mgcp_trunk.h \
|
||||
debug.h \
|
||||
mgcp_ratectr.h \
|
||||
|
||||
@@ -14,9 +14,8 @@ void mgcp_codec_summary(struct mgcp_conn_rtp *conn);
|
||||
void mgcp_codec_reset_all(struct mgcp_conn_rtp *conn);
|
||||
int mgcp_codec_add(struct mgcp_conn_rtp *conn, int payload_type, const char *audio_name, const struct mgcp_codec_param *param);
|
||||
int mgcp_codec_decide(struct mgcp_conn_rtp *conn);
|
||||
struct mgcp_rtp_codec *mgcp_codec_find_convertible(struct mgcp_conn_rtp *conn, struct mgcp_rtp_codec *codec);
|
||||
int mgcp_codec_pt_translate(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst, int payload_type);
|
||||
const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn_rtp *conn,
|
||||
const char *subtype_name, unsigned int match_nr);
|
||||
bool mgcp_codec_amr_align_mode_is_indicated(const struct mgcp_rtp_codec *codec);
|
||||
bool mgcp_codec_amr_is_octet_aligned(const struct mgcp_rtp_codec *codec);
|
||||
struct mgcp_rtp_codec *mgcp_codec_from_pt(struct mgcp_conn_rtp *conn, int payload_type);
|
||||
|
||||
24
include/osmocom/mgcp/mgcp_ctrl.h
Normal file
24
include/osmocom/mgcp/mgcp_ctrl.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* (C) 2020 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct ctrl_handle *mgw_ctrl_interface_setup(struct mgcp_config *cfg,
|
||||
const char *bind_addr, uint16_t port);
|
||||
|
||||
@@ -23,5 +23,5 @@ static const uint8_t e1_offsets[] = { 0, 0, 4, 0, 2, 4, 6, 0, 1, 2, 3, 4, 5, 6,
|
||||
|
||||
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, uint8_t ts);
|
||||
void mgcp_e1_endp_release(struct mgcp_endpoint *endp);
|
||||
int mgcp_e1_send_rtp(struct mgcp_endpoint *endp, struct mgcp_rtp_codec *codec, struct msgb *msg);
|
||||
|
||||
@@ -130,6 +130,7 @@ struct mgcp_endpoint {
|
||||
};
|
||||
|
||||
struct mgcp_endpoint *mgcp_endp_alloc(struct mgcp_trunk *trunk, unsigned int index);
|
||||
void mgcp_endp_release(struct mgcp_endpoint *endp);
|
||||
int mgcp_endp_claim(struct mgcp_endpoint *endp, const char *callid);
|
||||
void mgcp_endp_update(struct mgcp_endpoint *endp);
|
||||
bool mgcp_endp_is_wildcarded(const char *epname);
|
||||
@@ -144,4 +145,3 @@ void mgcp_endp_strip_name(char *epname_stripped, const char *epname,
|
||||
const struct mgcp_trunk *trunk);
|
||||
struct mgcp_endpoint *mgcp_endp_find_specific(const char *epname,
|
||||
const struct mgcp_trunk *trunk);
|
||||
void mgcp_endp_release(struct mgcp_endpoint *endp);
|
||||
|
||||
@@ -66,7 +66,7 @@ struct mgcp_trunk {
|
||||
/* E1 specific */
|
||||
struct {
|
||||
unsigned int vty_line_nr;
|
||||
uint8_t ts_usecount[NUM_E1_TS-1];
|
||||
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
|
||||
|
||||
@@ -50,7 +50,6 @@ enum mgcp_codecs {
|
||||
CODEC_AMR_8000_1 = 112,
|
||||
CODEC_AMRWB_16000_1 = 113,
|
||||
CODEC_IUFP = 96,
|
||||
CODEC_CLEARMODE = 120, /* 3GPP TS 48.103 table 5.4.2.2.1 */
|
||||
};
|
||||
/* Note: when new codec types are added, the corresponding value strings
|
||||
* in mgcp_client.c (codec_table) must be updated as well. Enumerations
|
||||
|
||||
@@ -13,6 +13,12 @@ AM_CFLAGS = \
|
||||
$(COVERAGE_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
# Libraries
|
||||
SUBDIRS = \
|
||||
libosmo-mgcp-client \
|
||||
|
||||
@@ -14,12 +14,14 @@ AM_CFLAGS = \
|
||||
$(NULL)
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOVTY_LIBS) \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
# 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=11:0:0
|
||||
MGCP_CLIENT_LIBVERSION=10:0:1
|
||||
|
||||
lib_LTLIBRARIES = \
|
||||
libosmo-mgcp-client.la \
|
||||
@@ -38,8 +40,3 @@ libosmo_mgcp_client_la_LDFLAGS = \
|
||||
-version-info $(MGCP_CLIENT_LIBVERSION) \
|
||||
-no-undefined \
|
||||
$(NULL)
|
||||
|
||||
libosmo_mgcp_client_la_LIBADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOVTY_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
@@ -60,7 +60,6 @@ const struct value_string osmo_mgcpc_codec_names[] = {
|
||||
{ CODEC_AMR_8000_1, "AMR/8000/1" },
|
||||
{ CODEC_AMRWB_16000_1, "AMR-WB/16000/1" },
|
||||
{ CODEC_IUFP, "VND.3GPP.IUFP/16000" },
|
||||
{ CODEC_CLEARMODE, "CLEARMODE/8000" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
@@ -907,10 +906,10 @@ void mgcp_client_disconnect(struct mgcp_client *mgcp)
|
||||
wq = &mgcp->wq;
|
||||
osmo_wqueue_clear(wq);
|
||||
LOGPMGW(mgcp, LOGL_INFO, "MGCP association: %s -- closed!\n", osmo_sock_get_name2(wq->bfd.fd));
|
||||
if (osmo_fd_is_registered(&wq->bfd))
|
||||
osmo_fd_unregister(&wq->bfd);
|
||||
close(wq->bfd.fd);
|
||||
wq->bfd.fd = -1;
|
||||
if (osmo_fd_is_registered(&wq->bfd))
|
||||
osmo_fd_unregister(&wq->bfd);
|
||||
}
|
||||
|
||||
/*! Get the IP-Aaddress of the associated MGW as string.
|
||||
@@ -1006,8 +1005,11 @@ const char *mgcp_client_e1_epname(void *ctx, const struct mgcp_client *mgcp, uin
|
||||
return epname;
|
||||
}
|
||||
|
||||
struct mgcp_response_pending *mgcp_client_pending_add(struct mgcp_client *mgcp, mgcp_trans_id_t trans_id,
|
||||
mgcp_response_cb_t response_cb, void *priv)
|
||||
struct mgcp_response_pending * mgcp_client_pending_add(
|
||||
struct mgcp_client *mgcp,
|
||||
mgcp_trans_id_t trans_id,
|
||||
mgcp_response_cb_t response_cb,
|
||||
void *priv)
|
||||
{
|
||||
struct mgcp_response_pending *pending;
|
||||
|
||||
@@ -1389,10 +1391,8 @@ struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg)
|
||||
if (!use_sdp
|
||||
&& (mgcp_msg->verb == MGCP_VERB_CRCX
|
||||
|| mgcp_msg->verb == MGCP_VERB_MDCX)) {
|
||||
if (add_lco(msg, mgcp_msg) < 0) {
|
||||
LOGPMGW(mgcp, LOGL_ERROR, "Failed to add LCO, can not generate MGCP message\n");
|
||||
if (add_lco(msg, mgcp_msg) < 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add mode */
|
||||
@@ -1427,10 +1427,8 @@ struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg)
|
||||
if (use_sdp
|
||||
&& (mgcp_msg->verb == MGCP_VERB_CRCX
|
||||
|| mgcp_msg->verb == MGCP_VERB_MDCX)) {
|
||||
if (add_sdp(msg, mgcp_msg, mgcp) < 0) {
|
||||
LOGPMGW(mgcp, LOGL_ERROR, "Failed to add SDP, can not generate MGCP message\n");
|
||||
if (add_sdp(msg, mgcp_msg, mgcp) < 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
|
||||
@@ -626,11 +626,6 @@ void osmo_mgcpc_ep_ci_request(struct osmo_mgcpc_ep_ci *ci,
|
||||
LOGP(DLMGCP, LOGL_ERROR, "Invalid MGW endpoint request: no ci\n");
|
||||
goto dispatch_error;
|
||||
}
|
||||
if (ci->pending) {
|
||||
LOG_CI(ci, LOGL_ERROR, "verb %s is already pending, wait for notify event before requesting %s\n",
|
||||
osmo_mgcp_verb_name(ci->verb), osmo_mgcp_verb_name(verb));
|
||||
goto dispatch_error;
|
||||
}
|
||||
if (!verb_info && verb != MGCP_VERB_DLCX) {
|
||||
LOG_CI(ci, LOGL_ERROR, "Invalid MGW endpoint request: missing verb details for %s\n",
|
||||
osmo_mgcp_verb_name(verb));
|
||||
|
||||
@@ -55,7 +55,7 @@ struct mgcp_client_conf *get_mgcp_client_config(struct vty *vty)
|
||||
|
||||
/* Global single MGCP config, deprecated: */
|
||||
vty_out(vty, "%% MGCP commands outside of 'mgw' nodes are deprecated. "
|
||||
"You should consider reading the User Manual and migrating to 'mgw' node.%s",
|
||||
"You should consider reading User Manual and migrating to 'mgw' node.%s",
|
||||
VTY_NEWLINE);
|
||||
|
||||
return global_mgcp_client_conf;
|
||||
|
||||
@@ -16,6 +16,12 @@ AM_CFLAGS = \
|
||||
$(NULL)
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
$(LIBOSMOVTY_LIBS) \
|
||||
$(LIBOSMONETIF_LIBS) \
|
||||
$(LIBOSMOABIS_LIBS) \
|
||||
$(LIBOSMOTRAU_LIBS) \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
@@ -39,6 +45,7 @@ libosmo_mgcp_a_SOURCES = \
|
||||
mgcp_stat.c \
|
||||
mgcp_endp.c \
|
||||
mgcp_trunk.c \
|
||||
mgcp_ctrl.c \
|
||||
mgcp_ratectr.c \
|
||||
mgcp_e1.c \
|
||||
mgcp_iuup.c \
|
||||
|
||||
@@ -376,15 +376,10 @@ bool mgcp_codec_amr_is_octet_aligned(const struct mgcp_rtp_codec *codec)
|
||||
return codec->param.amr_octet_aligned;
|
||||
}
|
||||
|
||||
/* Compare two codecs, all parameters must match up */
|
||||
/* Compare two codecs, all parameters must match up, except for the payload type
|
||||
* number. */
|
||||
static bool codecs_same(struct mgcp_rtp_codec *codec_a, struct mgcp_rtp_codec *codec_b)
|
||||
{
|
||||
/* All codec properties must match up, except the payload type number. Even though standardisd payload numbers
|
||||
* exist for certain situations, the call agent may still assign them freely. Hence we must not insist on equal
|
||||
* payload type numbers. Also the audio_name is not checked since it is already parsed into subtype_name, rate,
|
||||
* and channels, which are checked. */
|
||||
if (strcmp(codec_a->subtype_name, codec_b->subtype_name))
|
||||
return false;
|
||||
if (codec_a->rate != codec_b->rate)
|
||||
return false;
|
||||
if (codec_a->channels != codec_b->channels)
|
||||
@@ -393,73 +388,61 @@ static bool codecs_same(struct mgcp_rtp_codec *codec_a, struct mgcp_rtp_codec *c
|
||||
return false;
|
||||
if (codec_a->frame_duration_den != codec_b->frame_duration_den)
|
||||
return false;
|
||||
|
||||
/* AMR payload may be formatted in two different payload formats, it is still the same codec but since the
|
||||
* formatting of the payload is different, conversation is required, so we must treat it as a different
|
||||
* codec here. */
|
||||
if (strcmp(codec_a->subtype_name, "AMR") == 0) {
|
||||
if (mgcp_codec_amr_is_octet_aligned(codec_a) != mgcp_codec_amr_is_octet_aligned(codec_b))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Compare two codecs, all parameters must match up, except parameters related to payload formatting (not checked). */
|
||||
static bool codecs_convertible(struct mgcp_rtp_codec *codec_a, struct mgcp_rtp_codec *codec_b)
|
||||
{
|
||||
/* OsmoMGW currently has no ability to transcode from one codec to another. However OsmoMGW is still able to
|
||||
* translate between different payload formats as long as the encoded voice data itself does not change.
|
||||
* Therefore we must insist on equal codecs but still allow different payload formatting. */
|
||||
if (strcmp(codec_a->subtype_name, codec_b->subtype_name))
|
||||
return false;
|
||||
if (codec_a->rate != codec_b->rate)
|
||||
return false;
|
||||
if (codec_a->channels != codec_b->channels)
|
||||
return false;
|
||||
if (codec_a->frame_duration_num != codec_b->frame_duration_num)
|
||||
return false;
|
||||
if (codec_a->frame_duration_den != codec_b->frame_duration_den)
|
||||
return false;
|
||||
|
||||
/* Note: AMR allows to set the RTP payload format to octet-aligned or bandwith-efficient (octet-aligned=0)
|
||||
* via SDP. This difference concerns payload format only, but not the actual codec. It is not a difference
|
||||
* within the meaning of this function. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! For a given codec, find a convertible codec in the given connection.
|
||||
* \param[in] conn connection to search for a convertible codec
|
||||
* \param[in] codec for which a convertible codec shall be found.
|
||||
* \returns codec on success, -NULL on failure. */
|
||||
struct mgcp_rtp_codec *mgcp_codec_find_convertible(struct mgcp_conn_rtp *conn, struct mgcp_rtp_codec *codec)
|
||||
/*! Translate a given payload type number that belongs to the packet of a
|
||||
* source connection to the equivalent payload type number that matches the
|
||||
* configuration of a destination connection.
|
||||
* \param[in] conn_src related source rtp-connection.
|
||||
* \param[in] conn_dst related destination rtp-connection.
|
||||
* \param[in] payload_type number from the source packet or source connection.
|
||||
* \returns translated payload type number on success, -EINVAL on failure. */
|
||||
int mgcp_codec_pt_translate(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst, int payload_type)
|
||||
{
|
||||
struct mgcp_rtp_end *rtp_end;
|
||||
struct mgcp_rtp_end *rtp_src;
|
||||
struct mgcp_rtp_end *rtp_dst;
|
||||
struct mgcp_rtp_codec *codec_src = NULL;
|
||||
struct mgcp_rtp_codec *codec_dst = NULL;
|
||||
unsigned int i;
|
||||
unsigned int codecs_assigned;
|
||||
struct mgcp_rtp_codec *codec_convertible = NULL;
|
||||
|
||||
rtp_end = &conn->end;
|
||||
rtp_src = &conn_src->end;
|
||||
rtp_dst = &conn_dst->end;
|
||||
|
||||
/* Use the codec information from the source and try to find the equivalent of it on the destination side. In
|
||||
* the first run we will look for an exact match. */
|
||||
codecs_assigned = rtp_end->codecs_assigned;
|
||||
/* Find the codec information that is used on the source side */
|
||||
codecs_assigned = rtp_src->codecs_assigned;
|
||||
OSMO_ASSERT(codecs_assigned <= MGCP_MAX_CODECS);
|
||||
for (i = 0; i < codecs_assigned; i++) {
|
||||
if (codecs_same(codec, &rtp_end->codecs[i])) {
|
||||
codec_convertible = &rtp_end->codecs[i];
|
||||
if (payload_type == rtp_src->codecs[i].payload_type) {
|
||||
codec_src = &rtp_src->codecs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!codec_src)
|
||||
return -EINVAL;
|
||||
|
||||
/* In case we weren't able to find an exact match, we will try to find a match that is the same codec, but the
|
||||
* payload format may be different. This alternative will require a frame format conversion (i.e. AMR bwe->oe) */
|
||||
if (!codec_convertible) {
|
||||
for (i = 0; i < codecs_assigned; i++) {
|
||||
if (codecs_convertible(codec, &rtp_end->codecs[i])) {
|
||||
codec_convertible = &rtp_end->codecs[i];
|
||||
break;
|
||||
}
|
||||
/* Use the codec information from the source and try to find the
|
||||
* equivalent of it on the destination side */
|
||||
codecs_assigned = rtp_dst->codecs_assigned;
|
||||
OSMO_ASSERT(codecs_assigned <= MGCP_MAX_CODECS);
|
||||
for (i = 0; i < codecs_assigned; i++) {
|
||||
if (codecs_same(codec_src, &rtp_dst->codecs[i])) {
|
||||
codec_dst = &rtp_dst->codecs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return codec_convertible;
|
||||
if (!codec_dst)
|
||||
return -EINVAL;
|
||||
|
||||
return codec_dst->payload_type;
|
||||
}
|
||||
|
||||
/* Find the payload type number configured for a specific codec by SDP.
|
||||
@@ -469,7 +452,8 @@ struct mgcp_rtp_codec *mgcp_codec_find_convertible(struct mgcp_conn_rtp *conn, s
|
||||
* \param subtype_name SDP codec name without parameters (e.g. "AMR").
|
||||
* \param match_nr Index for the match found, first being match_nr == 0. Iterate all matches by calling multiple times
|
||||
* with incrementing match_nr.
|
||||
* \return codec definition for that conn matching the subtype_name, or NULL if no such match_nr is found. */
|
||||
* \return codec definition for that conn matching the subtype_name, or NULL if no such match_nr is found.
|
||||
*/
|
||||
const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn_rtp *conn,
|
||||
const char *subtype_name, unsigned int match_nr)
|
||||
{
|
||||
@@ -485,26 +469,3 @@ const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Lookup a codec that is assigned to a connection by its payload type number.
|
||||
* \param[in] conn related rtp-connection.
|
||||
* \param[in] payload_type number of the codec to look up.
|
||||
* \returns pointer to codec struct on success, NULL on failure. */
|
||||
struct mgcp_rtp_codec *mgcp_codec_from_pt(struct mgcp_conn_rtp *conn, int payload_type)
|
||||
{
|
||||
struct mgcp_rtp_end *rtp_end = &conn->end;
|
||||
unsigned int codecs_assigned = rtp_end->codecs_assigned;
|
||||
struct mgcp_rtp_codec *codec = NULL;
|
||||
size_t i;
|
||||
|
||||
OSMO_ASSERT(codecs_assigned <= MGCP_MAX_CODECS);
|
||||
|
||||
for (i = 0; i < codecs_assigned; i++) {
|
||||
if (payload_type == rtp_end->codecs[i].payload_type) {
|
||||
codec = &rtp_end->codecs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return codec;
|
||||
}
|
||||
|
||||
36
src/libosmo-mgcp/mgcp_ctrl.c
Normal file
36
src/libosmo-mgcp/mgcp_ctrl.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* (C) 2020 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
|
||||
|
||||
static int mgw_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
||||
void **node_data, int *i)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct ctrl_handle *mgw_ctrl_interface_setup(struct mgcp_config *cfg,
|
||||
const char *bind_addr, uint16_t port)
|
||||
{
|
||||
return ctrl_interface_setup_dynip2(cfg, bind_addr, port, mgw_ctrl_node_lookup,
|
||||
_LAST_CTRL_NODE);
|
||||
}
|
||||
@@ -222,7 +222,7 @@ static void e1_i460_mux_empty_cb(struct osmo_i460_subchan *schan, void *user_dat
|
||||
osmo_i460_mux_enqueue(endp->e1.schan, msg);
|
||||
}
|
||||
|
||||
/* called by I.460 de-multiplexer; feed output of I.460 demux into TRAU frame sync */
|
||||
/* called by I.460 de-multeiplexer; feed output of I.460 demux into TRAU frame sync */
|
||||
static void e1_i460_demux_bits_cb(struct osmo_i460_subchan *schan, void *user_data, const ubit_t *bits,
|
||||
unsigned int num_bits)
|
||||
{
|
||||
@@ -309,8 +309,8 @@ skip:
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle outgoing E1 traffic */
|
||||
static void e1_send_ts_frame(struct e1inp_ts *ts, struct mgcp_trunk *trunk)
|
||||
/* Function to handle outgoing E1 traffic */
|
||||
static void e1_send(struct e1inp_ts *ts, struct mgcp_trunk *trunk)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc_c(trunk, E1_TS_BYTES, "E1-TX-timeslot-bytes");
|
||||
uint8_t *ptr;
|
||||
@@ -359,17 +359,19 @@ static void e1_recv_cb(struct e1inp_ts *ts, struct msgb *msg)
|
||||
osmo_i460_demux_in(&trunk->e1.i460_ts[ts->num - 1], msgb_data(msg), msgb_length(msg));
|
||||
|
||||
/* Trigger sending of pending E1 traffic */
|
||||
e1_send_ts_frame(ts, trunk);
|
||||
e1_send(ts, trunk);
|
||||
|
||||
/* e1inp_rx_ts(), the caller of this callback does not free() msgb. */
|
||||
/* e1inp_rx_ts() does not free() msgb */
|
||||
msgb_free(msg);
|
||||
}
|
||||
|
||||
static int e1_open(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
static int e1_init(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
{
|
||||
/*! One E1 timeslot may serve multiple I.460 subslots. The timeslot is opened as soon as an I.460 subslot is
|
||||
* opened and will stay open until the last I.460 subslot is closed (see e1_close below). This function must
|
||||
* be called any time a new I.460 subslot is opened in order to maintain constancy of the ts_usecount counter. */
|
||||
/*! Each timeslot needs only to be configured once. The Timeslot then
|
||||
* stays open and permanently receives data. It is then up to the
|
||||
* I.460 demultiplexer to add/remove subchannels as needed. It is
|
||||
* allowed to call this function multiple times since we check if the
|
||||
* timeslot is already configured. */
|
||||
|
||||
struct e1inp_line *e1_line;
|
||||
int rc;
|
||||
@@ -377,14 +379,12 @@ static int e1_open(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
OSMO_ASSERT(ts_nr > 0 || ts_nr < NUM_E1_TS);
|
||||
cfg = trunk->cfg;
|
||||
|
||||
if (trunk->e1.ts_usecount[ts_nr - 1] > 0) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_INFO, "E1 timeslot %u already set up and in use by %u subslot(s), using it as it is...\n",
|
||||
ts_nr, trunk->e1.ts_usecount[ts_nr - 1]);
|
||||
trunk->e1.ts_usecount[ts_nr - 1]++;
|
||||
if (trunk->e1.ts_in_use[ts_nr - 1]) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_INFO, "E1 timeslot %u already set up, skipping...\n", ts_nr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find E1 line */
|
||||
/* Get E1 line */
|
||||
e1_line = e1inp_line_find(trunk->e1.vty_line_nr);
|
||||
if (!e1_line) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "no such E1 line %u - check VTY config!\n",
|
||||
@@ -401,61 +401,12 @@ static int e1_open(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
}
|
||||
rc = e1inp_line_update(e1_line);
|
||||
if (rc < 0) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "failed to update E1 line %u.\n", ts_nr);
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "failed to update E1 timeslot %u.\n", ts_nr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOGPTRUNK(trunk, DE1, LOGL_INFO, "E1 timeslot %u set up successfully.\n", ts_nr);
|
||||
trunk->e1.ts_usecount[ts_nr - 1]++;
|
||||
OSMO_ASSERT(trunk->e1.ts_usecount[ts_nr - 1] == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e1_close(struct mgcp_trunk *trunk, uint8_t ts_nr)
|
||||
{
|
||||
/* See also comment above (e1_open). This function must be called any time an I.460 subslot is closed */
|
||||
|
||||
struct e1inp_line *e1_line;
|
||||
int rc;
|
||||
|
||||
OSMO_ASSERT(ts_nr > 0 || ts_nr < NUM_E1_TS);
|
||||
cfg = trunk->cfg;
|
||||
|
||||
if (trunk->e1.ts_usecount[ts_nr - 1] > 1) {
|
||||
trunk->e1.ts_usecount[ts_nr - 1]--;
|
||||
LOGPTRUNK(trunk, DE1, LOGL_INFO, "E1 timeslot %u still in use by %u other subslot(s), leaving it open...\n",
|
||||
ts_nr, trunk->e1.ts_usecount[ts_nr - 1]);
|
||||
return 0;
|
||||
} else if (trunk->e1.ts_usecount[ts_nr - 1] == 0) {
|
||||
/* This should not be as it means we close the timeslot too often. */
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "E1 timeslot %u already closed, leaving it as it is...\n", ts_nr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Find E1 line */
|
||||
e1_line = e1inp_line_find(trunk->e1.vty_line_nr);
|
||||
if (!e1_line) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "no such E1 line %u - check VTY config!\n",
|
||||
trunk->e1.vty_line_nr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Release E1 timeslot */
|
||||
rc = e1inp_ts_config_none(&e1_line->ts[ts_nr - 1], e1_line);
|
||||
if (rc < 0) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "failed to disable E1 timeslot %u.\n", ts_nr);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = e1inp_line_update(e1_line);
|
||||
if (rc < 0) {
|
||||
LOGPTRUNK(trunk, DE1, LOGL_ERROR, "failed to update E1 line %u.\n", trunk->e1.vty_line_nr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOGPTRUNK(trunk, DE1, LOGL_INFO, "E1 timeslot %u closed.\n", ts_nr);
|
||||
trunk->e1.ts_usecount[ts_nr - 1]--;
|
||||
OSMO_ASSERT(trunk->e1.ts_usecount[ts_nr - 1] == 0);
|
||||
trunk->e1.ts_in_use[ts_nr - 1] = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -545,7 +496,7 @@ static bool tf_type_is_amr(enum osmo_trau_frame_type ft)
|
||||
}
|
||||
}
|
||||
|
||||
/*! Equip E1 endpoint with I.460 mux and E1 timeslot resources.
|
||||
/*! Equip E1 endpoint with I.460 mux resources.
|
||||
* \param[in] endp endpoint to equip
|
||||
* \param[in] ts E1 timeslot number.
|
||||
* \param[in] ss E1 subslot number.
|
||||
@@ -566,7 +517,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_open(endp->trunk, ts);
|
||||
rc = e1_init(endp->trunk, ts);
|
||||
if (rc != 0)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -653,15 +604,9 @@ void mgcp_e1_endp_update(struct mgcp_endpoint *endp)
|
||||
}
|
||||
|
||||
/*! Remove E1 resources from endpoint
|
||||
* \param[in] endp endpoint to release.
|
||||
* \param[in] ts E1 timeslot number. */
|
||||
void mgcp_e1_endp_release(struct mgcp_endpoint *endp, uint8_t ts)
|
||||
* \param[in] endp endpoint to release. */
|
||||
void mgcp_e1_endp_release(struct mgcp_endpoint *endp)
|
||||
{
|
||||
/* Guard against multiple calls. In case we don't see a subchannel anymore we can safely assume that all work
|
||||
* is done. */
|
||||
if (!(endp->e1.schan || endp->e1.trau_rtp_st || endp->e1.trau_sync_fi))
|
||||
return;
|
||||
|
||||
LOGPENDP(endp, DE1, LOGL_DEBUG, "removing I.460 subchannel and sync...\n");
|
||||
|
||||
if (endp->e1.schan)
|
||||
@@ -670,10 +615,8 @@ void mgcp_e1_endp_release(struct mgcp_endpoint *endp, uint8_t ts)
|
||||
talloc_free(endp->e1.trau_rtp_st);
|
||||
if (endp->e1.trau_sync_fi)
|
||||
osmo_fsm_inst_term(endp->e1.trau_sync_fi, OSMO_FSM_TERM_REGULAR, NULL);
|
||||
memset(&endp->e1, 0, sizeof(endp->e1));
|
||||
|
||||
/* Close E1 timeslot */
|
||||
e1_close(endp->trunk, ts);
|
||||
memset(&endp->e1, 0, sizeof(endp->e1));
|
||||
}
|
||||
|
||||
/*! Accept RTP message buffer with RTP data and enqueue voice data for E1 transmit.
|
||||
|
||||
@@ -110,6 +110,36 @@ struct mgcp_endpoint *mgcp_endp_alloc(struct mgcp_trunk *trunk,
|
||||
return endp;
|
||||
}
|
||||
|
||||
/*! release endpoint, all open connections are closed.
|
||||
* \param[in] endp endpoint to release */
|
||||
void mgcp_endp_release(struct mgcp_endpoint *endp)
|
||||
{
|
||||
LOGPENDP(endp, DLMGCP, LOGL_DEBUG, "Releasing endpoint\n");
|
||||
|
||||
/* Normally this function should only be called when
|
||||
* all connections have been removed already. In case
|
||||
* that there are still connections open (e.g. when
|
||||
* RSIP is executed), free them all at once. */
|
||||
mgcp_conn_free_all(endp);
|
||||
|
||||
/* We must only decrement the stat item when the endpoint as actually
|
||||
* claimed. An endpoint is claimed when a call-id is set */
|
||||
if (endp->callid)
|
||||
osmo_stat_item_dec(osmo_stat_item_group_get_item(endp->trunk->stats.common,
|
||||
TRUNK_STAT_ENDPOINTS_USED), 1);
|
||||
|
||||
/* Reset endpoint parameters and states */
|
||||
talloc_free(endp->callid);
|
||||
endp->callid = NULL;
|
||||
talloc_free(endp->local_options.string);
|
||||
endp->local_options.string = NULL;
|
||||
talloc_free(endp->local_options.codec);
|
||||
endp->local_options.codec = NULL;
|
||||
|
||||
if (endp->trunk->trunk_type == MGCP_TRUNK_E1)
|
||||
mgcp_e1_endp_release(endp);
|
||||
}
|
||||
|
||||
/* Check if the endpoint name contains the prefix (e.g. "rtpbridge/" or
|
||||
* "ds/e1-") and write the epname without the prefix back to the memory
|
||||
* pointed at by epname. (per trunk the prefix is the same for all endpoints,
|
||||
@@ -157,6 +187,7 @@ static void chop_epname_suffix(char *epname, const struct mgcp_trunk *trunk)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Convert all characters in epname to lowercase and strip trunk prefix and
|
||||
* endpoint name suffix (domain name) from epname. The result is written to
|
||||
* to the memory pointed at by epname_stripped. The expected size of the
|
||||
@@ -644,36 +675,3 @@ void mgcp_endp_remove_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn)
|
||||
if (llist_empty(&endp->conns))
|
||||
mgcp_endp_release(endp);
|
||||
}
|
||||
|
||||
/*! release endpoint, all open connections are closed.
|
||||
* \param[in] endp endpoint to release */
|
||||
void mgcp_endp_release(struct mgcp_endpoint *endp)
|
||||
{
|
||||
LOGPENDP(endp, DLMGCP, LOGL_DEBUG, "Releasing endpoint\n");
|
||||
|
||||
/* Normally this function should only be called when
|
||||
* all connections have been removed already. In case
|
||||
* that there are still connections open (e.g. when
|
||||
* RSIP is executed), free them all at once. */
|
||||
mgcp_conn_free_all(endp);
|
||||
|
||||
/* We must only decrement the stat item when the endpoint as actually
|
||||
* claimed. An endpoint is claimed when a call-id is set */
|
||||
if (endp->callid)
|
||||
osmo_stat_item_dec(osmo_stat_item_group_get_item(endp->trunk->stats.common,
|
||||
TRUNK_STAT_ENDPOINTS_USED), 1);
|
||||
|
||||
/* Reset endpoint parameters and states */
|
||||
talloc_free(endp->callid);
|
||||
endp->callid = NULL;
|
||||
talloc_free(endp->local_options.string);
|
||||
endp->local_options.string = NULL;
|
||||
talloc_free(endp->local_options.codec);
|
||||
endp->local_options.codec = NULL;
|
||||
|
||||
if (endp->trunk->trunk_type == MGCP_TRUNK_E1) {
|
||||
uint8_t ts = e1_ts_nr_from_epname(endp->name);
|
||||
mgcp_e1_endp_release(endp, ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -672,7 +672,7 @@ int mgcp_conn_iuup_send_rtp(struct mgcp_conn_rtp *conn_src_rtp, struct mgcp_conn
|
||||
"Bridge RTP=>IuUP: too short for AMR OA hdr (%u)\n", msgb_length(msg));
|
||||
goto free_ret;
|
||||
}
|
||||
if (!osmo_amr_ft_valid(amr_hdr->ft)) {
|
||||
if (amr_hdr->ft >= AMR_FT_MAX) {
|
||||
LOG_CONN_RTP(conn_src_rtp, LOGL_NOTICE, "Bridge RTP=>IuUP: wrong AMR OA ft=%u\n", amr_hdr->ft);
|
||||
goto free_ret;
|
||||
}
|
||||
@@ -695,7 +695,7 @@ int mgcp_conn_iuup_send_rtp(struct mgcp_conn_rtp *conn_src_rtp, struct mgcp_conn
|
||||
goto free_ret;
|
||||
}
|
||||
ft = ((amr_bwe_hdr[0] & 0x07) << 1) | ((amr_bwe_hdr[1] & 0x80) >> 7);
|
||||
if (!osmo_amr_ft_valid(ft)) {
|
||||
if (ft >= AMR_FT_MAX) {
|
||||
LOG_CONN_RTP(conn_src_rtp, LOGL_NOTICE, "Bridge RTP=>IuUP: wrong AMR BE ft=%u\n", ft);
|
||||
goto free_ret;
|
||||
}
|
||||
|
||||
@@ -493,57 +493,27 @@ void mgcp_rtp_annex_count(const struct mgcp_endpoint *endp,
|
||||
/* There may be different payload type numbers negotiated for two connections.
|
||||
* Patch the payload type of an RTP packet so that it uses the payload type
|
||||
* that is valid for the destination connection (conn_dst) */
|
||||
static int mgcp_patch_pt(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst, struct msgb *msg)
|
||||
static int mgcp_patch_pt(struct mgcp_conn_rtp *conn_src,
|
||||
struct mgcp_conn_rtp *conn_dst, struct msgb *msg)
|
||||
{
|
||||
struct rtp_hdr *rtp_hdr;
|
||||
struct mgcp_rtp_codec *codec_src;
|
||||
struct mgcp_rtp_codec *codec_dst;
|
||||
uint8_t pt_in;
|
||||
int pt_out;
|
||||
|
||||
if (msgb_length(msg) < sizeof(struct rtp_hdr)) {
|
||||
LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTP packet too short (%u < %zu)\n",
|
||||
msgb_length(msg), sizeof(struct rtp_hdr));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtp_hdr = (struct rtp_hdr *)msgb_data(msg);
|
||||
|
||||
/* Find the codec information that is used on the source side */
|
||||
codec_src = mgcp_codec_from_pt(conn_src, rtp_hdr->payload_type);
|
||||
if (!codec_src) {
|
||||
LOG_CONN_RTP(conn_src, LOGL_ERROR,
|
||||
"Cannot translate payload type nr %d: src has no such payload type defined\n",
|
||||
rtp_hdr->payload_type);
|
||||
if (log_check_level(DLMGCP, LOGL_DEBUG)) {
|
||||
int i;
|
||||
for (i = 0; i < conn_src->end.codecs_assigned; i++) {
|
||||
struct mgcp_rtp_codec *src_codec_i = &conn_src->end.codecs[i];
|
||||
LOGP(DLMGCP, LOGL_DEBUG, "Cannot translate PT %d: mismatches %d %s\n",
|
||||
rtp_hdr->payload_type, src_codec_i->payload_type, src_codec_i->audio_name);
|
||||
}
|
||||
}
|
||||
pt_in = rtp_hdr->payload_type;
|
||||
pt_out = mgcp_codec_pt_translate(conn_src, conn_dst, pt_in);
|
||||
if (pt_out < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Lookup a suitable codec in the destination connection. (The codec must be of the same type or at least
|
||||
* convertible) */
|
||||
codec_dst = mgcp_codec_find_convertible(conn_dst, codec_src);
|
||||
if (!codec_dst) {
|
||||
LOG_CONN_RTP(conn_src, LOGL_ERROR,
|
||||
"Cannot translate payload type number %d = %s: dst has no such codec\n",
|
||||
rtp_hdr->payload_type, codec_src->audio_name);
|
||||
if (log_check_level(DLMGCP, LOGL_DEBUG)) {
|
||||
int i;
|
||||
for (i = 0; i < conn_dst->end.codecs_assigned; i++) {
|
||||
struct mgcp_rtp_codec *dst_codec_i = &conn_dst->end.codecs[i];
|
||||
LOGP(DLMGCP, LOGL_DEBUG,
|
||||
"Cannot translate payload type nr %d = %s: mismatches %d = %s\n",
|
||||
rtp_hdr->payload_type, codec_src->audio_name,
|
||||
dst_codec_i->payload_type, dst_codec_i->audio_name);
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtp_hdr->payload_type = (uint8_t) codec_dst->payload_type;
|
||||
rtp_hdr->payload_type = (uint8_t) pt_out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1567,11 +1537,12 @@ static int rx_rtp(struct msgb *msg)
|
||||
if (!trunk->rtp_accept_all && check_rtp_origin(conn_src, from_addr))
|
||||
return -1;
|
||||
|
||||
/* Handle AMR frame format conversion (octet-aligned vs. bandwith-efficient) */
|
||||
/* If AMR is configured for the ingress connection and conversion of the
|
||||
* framing mode (octet-aligned vs. bandwith-efficient) is explicitly
|
||||
* defined, then we check if the incoming payload matches that
|
||||
* expectation. */
|
||||
if (mc->proto == MGCP_PROTO_RTP &&
|
||||
mgcp_codec_amr_align_mode_is_indicated(conn_src->end.codec)) {
|
||||
/* Make sure that the incoming AMR frame format matches the frame format that the call agent has
|
||||
* communicated via SDP when the connection was created/modfied. */
|
||||
int oa = amr_oa_check((char*)msgb_data(msg), msgb_length(msg));
|
||||
if (oa < 0)
|
||||
return -1;
|
||||
@@ -1706,14 +1677,14 @@ int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port,
|
||||
void mgcp_free_rtp_port(struct mgcp_rtp_end *end)
|
||||
{
|
||||
if (end->rtp.fd != -1) {
|
||||
osmo_fd_unregister(&end->rtp);
|
||||
close(end->rtp.fd);
|
||||
end->rtp.fd = -1;
|
||||
osmo_fd_unregister(&end->rtp);
|
||||
}
|
||||
|
||||
if (end->rtcp.fd != -1) {
|
||||
osmo_fd_unregister(&end->rtcp);
|
||||
close(end->rtcp.fd);
|
||||
end->rtcp.fd = -1;
|
||||
osmo_fd_unregister(&end->rtcp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,6 @@ osmux_handle_alloc(const struct mgcp_trunk *trunk, const struct osmo_sockaddr *r
|
||||
{
|
||||
struct osmux_handle *h;
|
||||
const struct mgcp_config *cfg = trunk->cfg;
|
||||
char name[128] = "r=";
|
||||
|
||||
h = talloc_zero(trunk, struct osmux_handle);
|
||||
if (!h)
|
||||
@@ -168,9 +167,6 @@ osmux_handle_alloc(const struct mgcp_trunk *trunk, const struct osmo_sockaddr *r
|
||||
talloc_free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osmo_sockaddr_to_str_buf(name + 2, sizeof(name) - 2, rem_addr);
|
||||
osmux_xfrm_input_set_name(h->in, name);
|
||||
/* sequence number to start OSMUX message from */
|
||||
osmux_xfrm_input_set_initial_seqnum(h->in, 0);
|
||||
osmux_xfrm_input_set_batch_factor(h->in, cfg->osmux.batch_factor);
|
||||
@@ -738,46 +734,26 @@ int osmux_cid_pool_count_used(void)
|
||||
return used;
|
||||
}
|
||||
|
||||
/*! Find and reserve a free OSMUX cid. Keep state of last allocated CID to
|
||||
* rotate allocated CIDs over time. This helps in letting CIDs unused for some
|
||||
* time after last use.
|
||||
/*! take a free OSMUX cid.
|
||||
* \returns OSMUX cid */
|
||||
int osmux_cid_pool_get_next(void)
|
||||
{
|
||||
static uint8_t next_free_osmux_cid_lookup = 0;
|
||||
uint8_t start_i, start_j;
|
||||
uint8_t i, j, cid;
|
||||
int i, j;
|
||||
|
||||
/* i = octet index, j = bit index inside ith octet */
|
||||
start_i = next_free_osmux_cid_lookup >> 3;
|
||||
start_j = next_free_osmux_cid_lookup & 0x07;
|
||||
|
||||
for (i = start_i; i < sizeof(osmux_cid_bitmap); i++) {
|
||||
for (j = start_j; j < 8; j++) {
|
||||
for (i = 0; i < sizeof(osmux_cid_bitmap); i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (osmux_cid_bitmap[i] & (1 << j))
|
||||
continue;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= start_i; i++) {
|
||||
for (j = 0; j < start_j; j++) {
|
||||
if (osmux_cid_bitmap[i] & (1 << j))
|
||||
continue;
|
||||
goto found;
|
||||
osmux_cid_bitmap[i] |= (1 << j);
|
||||
LOGP(DOSMUX, LOGL_DEBUG,
|
||||
"Allocating Osmux CID %u from pool\n", (i * 8) + j);
|
||||
return (i * 8) + j;
|
||||
}
|
||||
}
|
||||
|
||||
LOGP(DOSMUX, LOGL_ERROR, "All Osmux circuits are in use!\n");
|
||||
return -1;
|
||||
|
||||
found:
|
||||
osmux_cid_bitmap[i] |= (1 << j);
|
||||
cid = (i << 3) | j;
|
||||
next_free_osmux_cid_lookup = (cid + 1) & 0xff;
|
||||
LOGP(DOSMUX, LOGL_DEBUG,
|
||||
"Allocating Osmux CID %u from pool\n", cid);
|
||||
return cid;
|
||||
}
|
||||
|
||||
/*! take a specific OSMUX cid.
|
||||
|
||||
@@ -1026,7 +1026,7 @@ mgcp_header_done:
|
||||
&endp->local_options, local_options);
|
||||
if (rc != 0) {
|
||||
LOGPCONN(_conn, DLMGCP, LOGL_ERROR,
|
||||
"CRCX: invalid local connection options!\n");
|
||||
"CRCX: inavlid local connection options!\n");
|
||||
error_code = rc;
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_INVALID_CONN_OPTIONS));
|
||||
goto error2;
|
||||
|
||||
@@ -239,12 +239,13 @@ static int fmtp_from_sdp(void *ctx, struct sdp_fmtp_param *fmtp_param, char *sdp
|
||||
if (delimiter == ';' || delimiter == ',')
|
||||
str_ptr[strlen(str_ptr) - 1] = '\0';
|
||||
|
||||
/* AMR octet aligned parameter (see also RFC 3267, section 8.3) */
|
||||
/* AMR octet aligned parameter */
|
||||
if (sscanf(param_str, "octet-align=%d", &amr_octet_aligned) == 1) {
|
||||
fmtp_param->param.amr_octet_aligned_present = true;
|
||||
fmtp_param->param.amr_octet_aligned = false;
|
||||
if (amr_octet_aligned == 1)
|
||||
fmtp_param->param.amr_octet_aligned = true;
|
||||
|
||||
}
|
||||
|
||||
param_str = strtok(NULL, " ");
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <osmocom/mgcp/debug.h>
|
||||
#include <osmocom/mgcp/mgcp_endp.h>
|
||||
#include <osmocom/mgcp/mgcp_trunk.h>
|
||||
#include <osmocom/mgcp/mgcp_ctrl.h>
|
||||
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
@@ -50,7 +51,7 @@
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
|
||||
#include <osmocom/ctrl/control_vty.h>
|
||||
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
@@ -82,7 +83,7 @@ static int daemonize = 0;
|
||||
|
||||
const char *osmomgw_copyright =
|
||||
"Copyright (C) 2009-2010 Holger Freyther and On-Waves\r\n"
|
||||
"Copyright (C) 2017-2022 by sysmocom s.f.m.c. GmbH\r\n"
|
||||
"Copyright (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>\r\n"
|
||||
"Contributions by Pablo Neira Ayuso, Jacob Erlbeck, Neels Hofmeyr\r\n"
|
||||
"Philipp Maier\r\n\r\n"
|
||||
"License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
|
||||
@@ -360,11 +361,12 @@ int main(int argc, char **argv)
|
||||
return rc;
|
||||
|
||||
/* start telnet after reading config for vty_get_bind_addr() */
|
||||
rc = telnet_init_default(tall_mgw_ctx, NULL, OSMO_VTY_PORT_MGW);
|
||||
rc = telnet_init_dynif(tall_mgw_ctx, NULL,
|
||||
vty_get_bind_addr(), OSMO_VTY_PORT_MGW);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
cfg->ctrl = ctrl_interface_setup(cfg, OSMO_CTRL_PORT_MGW, NULL);
|
||||
cfg->ctrl = mgw_ctrl_interface_setup(cfg, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_MGW);
|
||||
if (!cfg->ctrl) {
|
||||
fprintf(stderr, "Failed to init the control interface on %s:%u. Exiting\n",
|
||||
ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_MGW);
|
||||
|
||||
@@ -18,7 +18,6 @@ AM_CFLAGS = \
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
-no-install \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
||||
@@ -838,7 +838,7 @@ static void test_messages(void)
|
||||
if (endp->local_options.pkt_period_min ||
|
||||
endp->local_options.pkt_period_max)
|
||||
printf
|
||||
("Requested packetization period: "
|
||||
("Requested packetetization period: "
|
||||
"%d-%d\n",
|
||||
endp->local_options.pkt_period_min,
|
||||
endp->
|
||||
@@ -1632,8 +1632,7 @@ static void test_osmux_cid(void)
|
||||
|
||||
for (i = 0; i < 256; ++i) {
|
||||
id = osmux_cid_pool_get_next();
|
||||
/* We called osmux_cid_pool_get_next() above, so next CID is i+1. */
|
||||
OSMO_ASSERT(id == ((i + 1) & 0xff));
|
||||
OSMO_ASSERT(id == i);
|
||||
OSMO_ASSERT(osmux_cid_pool_count_used() == i + 1);
|
||||
}
|
||||
|
||||
@@ -1769,26 +1768,26 @@ static const struct mgcp_codec_param amr_param_octet_aligned_unset = {
|
||||
.amr_octet_aligned_present = false,
|
||||
};
|
||||
|
||||
struct testcase_mgcp_codec_find_convertible_codec {
|
||||
struct testcase_mgcp_codec_pt_translate_codec {
|
||||
int payload_type;
|
||||
const char *audio_name;
|
||||
const struct mgcp_codec_param *param;
|
||||
int expect_rc;
|
||||
};
|
||||
|
||||
struct testcase_mgcp_codec_find_convertible_expect {
|
||||
struct testcase_mgcp_codec_pt_translate_expect {
|
||||
bool end;
|
||||
int payload_type_map[2];
|
||||
};
|
||||
|
||||
struct testcase_mgcp_codec_find_convertible {
|
||||
struct testcase_mgcp_codec_pt_translate {
|
||||
const char *descr;
|
||||
/* two conns on an endpoint, each with N configured codecs */
|
||||
struct testcase_mgcp_codec_find_convertible_codec codecs[2][10];
|
||||
struct testcase_mgcp_codec_find_convertible_expect expect[32];
|
||||
struct testcase_mgcp_codec_pt_translate_codec codecs[2][10];
|
||||
struct testcase_mgcp_codec_pt_translate_expect expect[32];
|
||||
};
|
||||
|
||||
static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_convertible_cases[] = {
|
||||
static const struct testcase_mgcp_codec_pt_translate test_mgcp_codec_pt_translate_cases[] = {
|
||||
{
|
||||
.descr = "same order, but differing payload type numbers",
|
||||
.codecs = {
|
||||
@@ -1851,7 +1850,6 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
|
||||
{ .payload_type_map = {96, 97}, },
|
||||
{ .payload_type_map = {97, 96}, },
|
||||
{ .payload_type_map = {0, 0}, },
|
||||
{ .payload_type_map = {123, -EINVAL} },
|
||||
{ .end = true },
|
||||
},
|
||||
},
|
||||
@@ -1898,22 +1896,18 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
|
||||
.codecs = {
|
||||
{
|
||||
{ 111, "AMR/8000", &amr_param_octet_aligned_true, },
|
||||
{ 112, "AMR/8000", &amr_param_octet_aligned_false, },
|
||||
},
|
||||
{
|
||||
{ 122, "AMR/8000", &amr_param_octet_aligned_false, },
|
||||
{ 121, "AMR/8000", &amr_param_octet_aligned_true, },
|
||||
},
|
||||
},
|
||||
.expect = {
|
||||
{ .payload_type_map = {111, 121}, },
|
||||
{ .payload_type_map = {112, 122} },
|
||||
{ .payload_type_map = {123, -EINVAL} },
|
||||
{ .payload_type_map = {111, 122}, },
|
||||
{ .end = true },
|
||||
},
|
||||
},
|
||||
{
|
||||
.descr = "test AMR with missing octet-aligned settings (oa <-> unset)",
|
||||
.descr = "test AMR with missing octet-aligned settings (defaults to 0)",
|
||||
.codecs = {
|
||||
{
|
||||
{ 111, "AMR/8000", &amr_param_octet_aligned_true, },
|
||||
@@ -1924,57 +1918,21 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
|
||||
},
|
||||
.expect = {
|
||||
{ .payload_type_map = {111, 122}, },
|
||||
{ .payload_type_map = {55, -EINVAL}, },
|
||||
{ .end = true },
|
||||
},
|
||||
},
|
||||
{
|
||||
.descr = "test AMR with missing octet-aligned settings (bwe <-> unset)",
|
||||
.descr = "test AMR with NULL param (defaults to 0)",
|
||||
.codecs = {
|
||||
{
|
||||
{ 111, "AMR/8000", &amr_param_octet_aligned_false, },
|
||||
{ 111, "AMR/8000", &amr_param_octet_aligned_true, },
|
||||
},
|
||||
{
|
||||
{ 122, "AMR/8000", &amr_param_octet_aligned_unset, },
|
||||
{ 122, "AMR/8000", NULL, },
|
||||
},
|
||||
},
|
||||
.expect = {
|
||||
{ .payload_type_map = {111, 122}, },
|
||||
{ .payload_type_map = {55, -EINVAL}, },
|
||||
{ .end = true },
|
||||
},
|
||||
},
|
||||
{
|
||||
.descr = "test AMR with NULL param (oa <-> null)",
|
||||
.codecs = {
|
||||
{
|
||||
{ 112, "AMR/8000", &amr_param_octet_aligned_true, },
|
||||
},
|
||||
{
|
||||
{ 122, "AMR/8000", NULL, },
|
||||
},
|
||||
},
|
||||
.expect = {
|
||||
/* Note: Both 111, anbd 112 will translate to 122. The translation from 112 */
|
||||
{ .payload_type_map = {112, 122} },
|
||||
{ .payload_type_map = {55, -EINVAL}, },
|
||||
{ .end = true },
|
||||
},
|
||||
},
|
||||
{
|
||||
.descr = "test AMR with NULL param (bwe <-> null)",
|
||||
.codecs = {
|
||||
{
|
||||
{ 112, "AMR/8000", &amr_param_octet_aligned_false, },
|
||||
},
|
||||
{
|
||||
{ 122, "AMR/8000", NULL, },
|
||||
},
|
||||
},
|
||||
.expect = {
|
||||
/* Note: Both 111, anbd 112 will translate to 122. The translation from 112 */
|
||||
{ .payload_type_map = {112, 122} },
|
||||
{ .payload_type_map = {55, -EINVAL}, },
|
||||
{ .end = true },
|
||||
},
|
||||
},
|
||||
@@ -2044,39 +2002,14 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
|
||||
},
|
||||
};
|
||||
|
||||
static int pt_translate(struct mgcp_conn_rtp *conn, unsigned int index_src, unsigned int index_dst, int payload_type)
|
||||
{
|
||||
struct mgcp_rtp_codec *codec_src = NULL;
|
||||
struct mgcp_rtp_codec *codec_dst = NULL;
|
||||
struct mgcp_conn_rtp *conn_src = &conn[index_src];
|
||||
struct mgcp_conn_rtp *conn_dst = &conn[index_dst];
|
||||
|
||||
/* Find the codec information that is used on the source side */
|
||||
codec_src = mgcp_codec_from_pt(conn_src, payload_type);
|
||||
if (!codec_src) {
|
||||
printf(" - mgcp_codec_from_pt(conn%u, %d) -> NO RESULT\n", index_src, payload_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
printf(" - mgcp_codec_from_pt(conn%u, %d) -> %s\n", index_src, payload_type, codec_src->subtype_name);
|
||||
|
||||
codec_dst = mgcp_codec_find_convertible(conn_dst, codec_src);
|
||||
if (!codec_dst) {
|
||||
printf(" - mgcp_codec_find_convertible(conn%u, %s) -> NO RESULT\n", index_dst, codec_src->subtype_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
printf(" - mgcp_codec_find_convertible(conn%u, %s) -> %s -> %u\n",
|
||||
index_dst, codec_src->subtype_name, codec_dst->subtype_name, codec_dst->payload_type);
|
||||
return codec_dst->payload_type;
|
||||
}
|
||||
|
||||
static void test_mgcp_codec_find_convertible(void)
|
||||
static void test_mgcp_codec_pt_translate(void)
|
||||
{
|
||||
int i;
|
||||
bool ok = true;
|
||||
printf("\nTesting mgcp_codec_find_convertible()\n");
|
||||
printf("\nTesting mgcp_codec_pt_translate()\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_mgcp_codec_find_convertible_cases); i++) {
|
||||
const struct testcase_mgcp_codec_find_convertible *t = &test_mgcp_codec_find_convertible_cases[i];
|
||||
for (i = 0; i < ARRAY_SIZE(test_mgcp_codec_pt_translate_cases); i++) {
|
||||
const struct testcase_mgcp_codec_pt_translate *t = &test_mgcp_codec_pt_translate_cases[i];
|
||||
struct mgcp_conn_rtp conn[2] = {};
|
||||
int rc;
|
||||
int conn_i;
|
||||
@@ -2087,7 +2020,7 @@ static void test_mgcp_codec_find_convertible(void)
|
||||
for (conn_i = 0; conn_i < 2; conn_i++) {
|
||||
printf(" - add codecs on conn%d:\n", conn_i);
|
||||
for (c = 0; c < ARRAY_SIZE(t->codecs[conn_i]); c++) {
|
||||
const struct testcase_mgcp_codec_find_convertible_codec *codec = &t->codecs[conn_i][c];
|
||||
const struct testcase_mgcp_codec_pt_translate_codec *codec = &t->codecs[conn_i][c];
|
||||
if (!codec->audio_name)
|
||||
break;
|
||||
|
||||
@@ -2111,13 +2044,15 @@ static void test_mgcp_codec_find_convertible(void)
|
||||
}
|
||||
|
||||
for (c = 0; c < ARRAY_SIZE(t->expect); c++) {
|
||||
const struct testcase_mgcp_codec_find_convertible_expect *expect = &t->expect[c];
|
||||
const struct testcase_mgcp_codec_pt_translate_expect *expect = &t->expect[c];
|
||||
int result;
|
||||
|
||||
if (expect->end)
|
||||
break;
|
||||
|
||||
result = pt_translate(conn, 0, 1, expect->payload_type_map[0]);
|
||||
result = mgcp_codec_pt_translate(&conn[0], &conn[1], expect->payload_type_map[0]);
|
||||
printf(" - mgcp_codec_pt_translate(conn0, conn1, %d) -> %d\n",
|
||||
expect->payload_type_map[0], result);
|
||||
if (result != expect->payload_type_map[1]) {
|
||||
printf(" ERROR: expected -> %d\n", expect->payload_type_map[1]);
|
||||
ok = false;
|
||||
@@ -2127,7 +2062,9 @@ static void test_mgcp_codec_find_convertible(void)
|
||||
if (expect->payload_type_map[1] < 0)
|
||||
continue;
|
||||
|
||||
result = pt_translate(conn, 1, 0, expect->payload_type_map[1]);
|
||||
result = mgcp_codec_pt_translate(&conn[1], &conn[0], expect->payload_type_map[1]);
|
||||
printf(" - mgcp_codec_pt_translate(conn1, conn0, %d) -> %d\n",
|
||||
expect->payload_type_map[1], result);
|
||||
if (result != expect->payload_type_map[0]) {
|
||||
printf(" ERROR: expected -> %d\n", expect->payload_type_map[0]);
|
||||
ok = false;
|
||||
@@ -2295,7 +2232,7 @@ int main(int argc, char **argv)
|
||||
test_osmux_cid();
|
||||
test_get_lco_identifier();
|
||||
test_check_local_cx_options(ctx);
|
||||
test_mgcp_codec_find_convertible();
|
||||
test_mgcp_codec_pt_translate();
|
||||
test_conn_id_matching();
|
||||
test_e1_trunk_nr_from_epname();
|
||||
test_mgcp_is_rtp_dummy_payload();
|
||||
|
||||
@@ -1276,7 +1276,7 @@ p:10, a:PCMU -> p:10, a:PCMU
|
||||
Response matches our expectations.
|
||||
Testing get_lco_identifier()
|
||||
p:10, a:PCMU -> p:10, a:PCMU
|
||||
p:10, a:PCMU -> p:10, a:PCMU
|
||||
p:10, a:PCMU -> p:10, a:PCMU
|
||||
'XXXX, p:10, a:PCMU' -> 'p:10, a:PCMU'
|
||||
'XXXX,p:10,a:PCMU' -> 'p:10,a:PCMU'
|
||||
'10,a:PCMU' -> 'a:PCMU'
|
||||
@@ -1286,19 +1286,13 @@ Testing mgcp_codec_find_convertible()
|
||||
', a:PCMU' -> 'a:PCMU'
|
||||
' a:PCMU' -> 'a:PCMU'
|
||||
'' -> '(null)'
|
||||
p10, aPCMU -> (null)
|
||||
'10,a :PCMU' -> '(null)'
|
||||
|
||||
Testing mgcp_codec_find_convertible()
|
||||
#0: same order, but differing payload type numbers
|
||||
- add codecs on conn0:
|
||||
0: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 96 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 97 GSM-HR-08/8000/1 -> rc=0
|
||||
p10, aPCMU -> (null)
|
||||
'10,a :PCMU' -> '(null)'
|
||||
|
||||
Testing mgcp_codec_pt_translate()
|
||||
#0: same order, but differing payload type numbers
|
||||
- add codecs on conn0:
|
||||
0: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
@@ -1308,19 +1302,13 @@ Testing mgcp_codec_find_convertible()
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 112) -> 96
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 96) -> 112
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> 0
|
||||
- mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
|
||||
- mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
|
||||
- mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
|
||||
- mgcp_codec_from_pt(conn0, 123) -> NO RESULT
|
||||
#1: different order and different payload type numbers
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 97 GSM-HR-08/8000/1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 96 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 0) -> 0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> 97
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 97) -> 111
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 123) -> -22
|
||||
#1: different order and different payload type numbers
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
@@ -1330,19 +1318,12 @@ Testing mgcp_codec_find_convertible()
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 112) -> 96
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 96) -> 112
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> 0
|
||||
- mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
|
||||
- mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
|
||||
- mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
|
||||
- mgcp_codec_from_pt(conn0, 123) -> NO RESULT
|
||||
#2: both sides have the same payload_type numbers assigned to differing codecs
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 96 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 97 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 97 GSM-HR-08/8000/1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 96 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 0) -> 0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> 97
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 97) -> 111
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 123) -> -22
|
||||
#2: both sides have the same payload_type numbers assigned to differing codecs
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 96 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 97 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
@@ -1350,9 +1331,9 @@ Testing mgcp_codec_find_convertible()
|
||||
0: 97 GSM-HR-08/8000/1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 96 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 97
|
||||
- mgcp_codec_from_pt(conn0, 0) -> PCMU
|
||||
- mgcp_codec_find_convertible(conn1, PCMU) -> PCMU -> 0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 96) -> 97
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 97) -> 96
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 97) -> 96
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 96) -> 97
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> 0
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 0) -> 0
|
||||
@@ -1360,69 +1341,31 @@ Testing mgcp_codec_find_convertible()
|
||||
- add codecs on conn0:
|
||||
(none)
|
||||
- add codecs on conn1:
|
||||
0: 96 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 97 GSM-HR-08/8000/1 -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 112) -> NO RESULT
|
||||
- mgcp_codec_from_pt(conn0, 0) -> NO RESULT
|
||||
- mgcp_codec_from_pt(conn0, 111) -> NO RESULT
|
||||
0: 96 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 97 GSM-HR-08/8000/1 -> rc=0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 112) -> -22
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> -22
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> -22
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
#4: conn1 has no codecs
|
||||
- add codecs on conn0:
|
||||
(none)
|
||||
- mgcp_codec_from_pt(conn0, 112) -> AMR
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> NO RESULT
|
||||
- mgcp_codec_from_pt(conn0, 0) -> PCMU
|
||||
- mgcp_codec_find_convertible(conn1, PCMU) -> NO RESULT
|
||||
- mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
|
||||
- mgcp_codec_find_convertible(conn1, GSM-HR-08) -> NO RESULT
|
||||
#5: test AMR with differing octet-aligned settings
|
||||
- add codecs on conn0:
|
||||
0: 111 AMR/8000 octet-aligned=1 -> rc=0
|
||||
1: 112 AMR/8000 octet-aligned=0 -> rc=0
|
||||
0: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
1: 0 PCMU/8000/1 -> rc=0
|
||||
2: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
(none)
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 112) -> -22
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> -22
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 121
|
||||
- mgcp_codec_from_pt(conn1, 121) -> AMR
|
||||
- mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 111
|
||||
- mgcp_codec_from_pt(conn0, 112) -> AMR
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
|
||||
- mgcp_codec_from_pt(conn1, 122) -> AMR
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> -22
|
||||
#5: test AMR with differing octet-aligned settings
|
||||
- add codecs on conn0:
|
||||
0: 111 AMR/8000 octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 123) -> NO RESULT
|
||||
#6: test AMR with missing octet-aligned settings (oa <-> unset)
|
||||
- add codecs on conn0:
|
||||
0: 111 AMR/8000 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 122 AMR/8000 octet-aligned=unset -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 111) -> AMR
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
|
||||
- mgcp_codec_from_pt(conn1, 122) -> AMR
|
||||
- mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 111
|
||||
- mgcp_codec_from_pt(conn0, 55) -> NO RESULT
|
||||
- add codecs on conn1:
|
||||
0: 122 AMR/8000 octet-aligned=0 -> rc=0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> 122
|
||||
0: 111 AMR/8000 octet-aligned=0 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 122 AMR/8000 octet-aligned=unset -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 111) -> AMR
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
|
||||
- mgcp_codec_from_pt(conn1, 122) -> AMR
|
||||
- mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 111
|
||||
- mgcp_codec_from_pt(conn0, 55) -> NO RESULT
|
||||
#8: test AMR with NULL param (oa <-> null)
|
||||
- add codecs on conn0:
|
||||
0: 112 AMR/8000 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 122 AMR/8000 -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 112) -> AMR
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
|
||||
- mgcp_codec_from_pt(conn1, 122) -> AMR
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 122) -> 111
|
||||
#6: test AMR with missing octet-aligned settings (defaults to 0)
|
||||
- add codecs on conn0:
|
||||
0: 111 AMR/8000 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 122 AMR/8000 octet-aligned=unset -> rc=0
|
||||
@@ -1431,20 +1374,14 @@ Testing mgcp_codec_find_convertible()
|
||||
#7: test AMR with NULL param (defaults to 0)
|
||||
- add codecs on conn0:
|
||||
0: 111 AMR/8000 octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
|
||||
- mgcp_codec_from_pt(conn1, 122) -> AMR
|
||||
- mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
|
||||
- mgcp_codec_from_pt(conn0, 55) -> NO RESULT
|
||||
#10: match FOO/8000/1 and FOO/8000 as identical, single channel is implicit
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 97 GSM-HR-08/8000 -> rc=0
|
||||
1: 0 PCMU/8000 -> rc=0
|
||||
2: 96 AMR/8000 octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 112) -> AMR
|
||||
- add codecs on conn1:
|
||||
0: 122 AMR/8000 -> rc=0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> 122
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 122) -> 111
|
||||
#8: match FOO/8000/1 and FOO/8000 as identical, single channel is implicit
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 97 GSM-HR-08/8000 -> rc=0
|
||||
@@ -1453,20 +1390,14 @@ Testing mgcp_codec_find_convertible()
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 112) -> 96
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 96) -> 112
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> 0
|
||||
- mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
|
||||
- mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
|
||||
- mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
|
||||
- mgcp_codec_from_pt(conn0, 123) -> NO RESULT
|
||||
#11: match FOO/8000/1 and FOO as identical, 8k and single channel are implicit
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 97 GSM-HR-08 -> rc=0
|
||||
1: 0 PCMU -> rc=0
|
||||
2: 96 AMR octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_from_pt(conn0, 112) -> AMR
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 0) -> 0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> 97
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 97) -> 111
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 123) -> -22
|
||||
#9: match FOO/8000/1 and FOO as identical, 8k and single channel are implicit
|
||||
- add codecs on conn0:
|
||||
0: 0 PCMU/8000/1 -> rc=0
|
||||
1: 111 GSM-HR-08/8000/1 -> rc=0
|
||||
2: 112 AMR/8000/1 octet-aligned=1 -> rc=0
|
||||
- add codecs on conn1:
|
||||
0: 97 GSM-HR-08 -> rc=0
|
||||
@@ -1474,12 +1405,10 @@ Testing mgcp_codec_find_convertible()
|
||||
2: 96 AMR octet-aligned=1 -> rc=0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 112) -> 96
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 96) -> 112
|
||||
- mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
|
||||
- mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
|
||||
- mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
|
||||
- mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
|
||||
- mgcp_codec_from_pt(conn0, 123) -> NO RESULT
|
||||
#12: test whether channel number matching is waterproof
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 0) -> 0
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 0) -> 0
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 111) -> 97
|
||||
- mgcp_codec_pt_translate(conn1, conn0, 97) -> 111
|
||||
- mgcp_codec_pt_translate(conn0, conn1, 123) -> -22
|
||||
#10: test whether channel number matching is waterproof
|
||||
- add codecs on conn0:
|
||||
|
||||
@@ -15,7 +15,6 @@ AM_CFLAGS = \
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
-no-install \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
DLMGCP MGW(mgw) MGCP client: using endpoint domain '@mgw'
|
||||
DLMGCP MGW(mgw) Message buffer to small, can not generate MGCP message (SDP)
|
||||
DLMGCP MGW(mgw) Failed to add SDP, can not generate MGCP message
|
||||
|
||||
test_mgcp_client_cancel():
|
||||
DLMGCP MGW(mgw) MGCP client: using endpoint domain '@mgw'
|
||||
|
||||
Reference in New Issue
Block a user