aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-07-19 16:48:42 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2017-08-30 14:09:31 +0200
commitbecfc4cb1ba9d759915a5b430aedc0d29c67858b (patch)
tree5dcf6925ed39c2433571f3718e8350e9e69b47f0
parentc4c794c6c735b63ba3b5021e016d4296ef601cca (diff)
move to osmo-mgw.git: osmo-bsc_mgcp and libmgcp as libosmo-legacy-mgcp
Rewire build and includes to libosmo-legacy-mgcp. Drop osmo-bsc_mgcp and related python tests, now found in osmo-mgw.git. libosmo-legacy-mgcp is installed from osmo-mgw, hence add the dependency to jenkins.sh (so far using the pre_release branch). Change-Id: Ic99d681759edce11564da62500c2aac5cf5fffe2
-rw-r--r--configure.ac4
-rwxr-xr-xcontrib/jenkins.sh1
-rw-r--r--include/openbsc/Makefile.am4
-rw-r--r--include/openbsc/bsc_nat.h4
-rw-r--r--include/openbsc/gsm_data.h2
-rw-r--r--include/openbsc/mgcp.h300
-rw-r--r--include/openbsc/mgcp_internal.h337
-rw-r--r--include/openbsc/mgcp_transcode.h90
-rw-r--r--include/openbsc/mgcpgw_client.h111
-rw-r--r--osmoappdesc.py4
-rw-r--r--src/Makefile.am2
-rw-r--r--src/libfilter/bsc_msg_acc.c1
-rw-r--r--src/libmgcp/Makefile.am46
-rw-r--r--src/libmgcp/g711common.h187
-rw-r--r--src/libmgcp/mgcp_common.c54
-rw-r--r--src/libmgcp/mgcp_network.c1166
-rw-r--r--src/libmgcp/mgcp_osmux.c583
-rw-r--r--src/libmgcp/mgcp_protocol.c1639
-rw-r--r--src/libmgcp/mgcp_sdp.c305
-rw-r--r--src/libmgcp/mgcp_transcode.c612
-rw-r--r--src/libmgcp/mgcp_vty.c1555
-rw-r--r--src/libmgcp/mgcpgw_client.c616
-rw-r--r--src/libmgcp/mgcpgw_client_vty.c167
-rw-r--r--src/libmsc/a_iface.c2
-rw-r--r--src/libmsc/msc_ifaces.c6
-rw-r--r--src/libmsc/msc_vty.c2
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c2
-rw-r--r--src/osmo-bsc_mgcp/Makefile.am36
-rw-r--r--src/osmo-bsc_mgcp/mgcp_main.c313
-rw-r--r--src/osmo-bsc_nat/Makefile.am4
-rw-r--r--src/osmo-bsc_nat/bsc_mgcp_utils.c4
-rw-r--r--src/osmo-bsc_nat/bsc_nat_ctrl.c1
-rw-r--r--src/osmo-bsc_nat/bsc_nat_vty.c8
-rw-r--r--src/osmo-bsc_nat/bsc_ussd.c1
-rw-r--r--src/osmo-msc/Makefile.am4
-rw-r--r--src/osmo-msc/msc_main.c2
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/bsc-nat-trie/Makefile.am10
-rw-r--r--tests/bsc-nat/Makefile.am4
-rw-r--r--tests/bsc/Makefile.am4
-rw-r--r--tests/mgcp/Makefile.am93
-rw-r--r--tests/mgcp/mgcp_test.c1227
-rw-r--r--tests/mgcp/mgcp_test.ok480
-rw-r--r--tests/mgcp/mgcp_transcoding_test.c654
-rw-r--r--tests/mgcp/mgcp_transcoding_test.ok539
-rw-r--r--tests/mgcp/mgcpgw_client_test.c165
-rw-r--r--tests/mgcp/mgcpgw_client_test.err1
-rw-r--r--tests/mgcp/mgcpgw_client_test.ok31
-rw-r--r--tests/msc_vlr/Makefile.am4
-rw-r--r--tests/sms_queue/Makefile.am4
-rw-r--r--tests/testsuite.at20
-rw-r--r--tests/vty_test_runner.py59
52 files changed, 47 insertions, 11424 deletions
diff --git a/configure.ac b/configure.ac
index 80f50e80d..e97198528 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,6 +48,7 @@ PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran) # TODO version?
PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
+PKG_CHECK_MODULES(LIBOSMOLEGACYMGCP, libosmo-legacy-mgcp >= 0.0.1)
# Enabke/disable the NAT?
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
@@ -230,14 +231,12 @@ AC_OUTPUT(
src/libbsc/Makefile
src/libmsc/Makefile
src/libvlr/Makefile
- src/libmgcp/Makefile
src/libcommon/Makefile
src/libfilter/Makefile
src/libcommon-cs/Makefile
src/osmo-msc/Makefile
src/osmo-bsc/Makefile
src/osmo-bsc_nat/Makefile
- src/osmo-bsc_mgcp/Makefile
src/ipaccess/Makefile
src/utils/Makefile
src/gprs/Makefile
@@ -248,7 +247,6 @@ AC_OUTPUT(
tests/bsc/Makefile
tests/bsc-nat/Makefile
tests/bsc-nat-trie/Makefile
- tests/mgcp/Makefile
tests/gprs/Makefile
tests/gbproxy/Makefile
tests/abis/Makefile
diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
index 2b667ad04..7380189a9 100755
--- a/contrib/jenkins.sh
+++ b/contrib/jenkins.sh
@@ -29,6 +29,7 @@ osmo-build-dep.sh libosmo-netif
osmo-build-dep.sh libosmo-sccp
PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34
osmo-build-dep.sh openggsn
+osmo-build-dep.sh osmo-mgw pre_release # move to 'master' once the split is complete
if [ "x$IU" = "x--enable-iu" ]; then
osmo-build-dep.sh libasn1c
diff --git a/include/openbsc/Makefile.am b/include/openbsc/Makefile.am
index 89e0338f5..c1cb6a3fb 100644
--- a/include/openbsc/Makefile.am
+++ b/include/openbsc/Makefile.am
@@ -54,10 +54,6 @@ noinst_HEADERS = \
iu_dummy.h \
meas_feed.h \
meas_rep.h \
- mgcp.h \
- mgcp_internal.h \
- mgcp_transcode.h \
- mgcpgw_client.h \
misdn.h \
mncc.h \
mncc_int.h \
diff --git a/include/openbsc/bsc_nat.h b/include/openbsc/bsc_nat.h
index 94ab0e5ff..452daf2ab 100644
--- a/include/openbsc/bsc_nat.h
+++ b/include/openbsc/bsc_nat.h
@@ -21,9 +21,9 @@
#ifndef BSC_NAT_H
#define BSC_NAT_H
-#include "mgcp.h"
-#include "bsc_msg_filter.h"
+#include <osmocom/legacy_mgcp/mgcp.h>
+#include "bsc_msg_filter.h"
#include <osmocom/core/select.h>
#include <osmocom/core/msgb.h>
diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h
index 6079900a1..88a4f1067 100644
--- a/include/openbsc/gsm_data.h
+++ b/include/openbsc/gsm_data.h
@@ -17,7 +17,7 @@
#include <openbsc/common.h>
#include <openbsc/rest_octets.h>
#include <openbsc/common_cs.h>
-#include <openbsc/mgcpgw_client.h>
+#include <osmocom/legacy_mgcp/mgcpgw_client.h>
/** annotations for msgb ownership */
diff --git a/include/openbsc/mgcp.h b/include/openbsc/mgcp.h
deleted file mode 100644
index 7cf83b27c..000000000
--- a/include/openbsc/mgcp.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
-
-/*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
- * 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/>.
- *
- */
-
-#ifndef OPENBSC_MGCP_H
-#define OPENBSC_MGCP_H
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/write_queue.h>
-#include <osmocom/core/timer.h>
-
-#include "debug.h"
-
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#define RTP_PORT_DEFAULT 4000
-#define RTP_PORT_NET_DEFAULT 16000
-
-/**
- * Calculate the RTP audio port for the given multiplex
- * and the direction. This allows a semi static endpoint
- * to port calculation removing the need for the BSC
- * and the MediaGateway to communicate.
- *
- * Port usage explained:
- * base + (multiplex * 2) + 0 == local port to wait for network packets
- * base + (multiplex * 2) + 1 == local port for rtcp
- *
- * The above port will receive packets from the BTS that need
- * to be patched and forwarded to the network.
- * The above port will receive packets from the network that
- * need to be patched and forwarded to the BTS.
- *
- * We assume to have a static BTS IP address so we can differentiate
- * network and BTS.
- *
- */
-static inline int rtp_calculate_port(int multiplex, int base)
-{
- return base + (multiplex * 2);
-}
-
-
-/*
- * Handling of MGCP Endpoints and the MGCP Config
- */
-struct mgcp_endpoint;
-struct mgcp_config;
-struct mgcp_trunk_config;
-struct mgcp_rtp_end;
-
-#define MGCP_ENDP_CRCX 1
-#define MGCP_ENDP_DLCX 2
-#define MGCP_ENDP_MDCX 3
-
-/*
- * what to do with the msg?
- * - continue as usual?
- * - reject and send a failure code?
- * - defer? do not send anything
- */
-#define MGCP_POLICY_CONT 4
-#define MGCP_POLICY_REJECT 5
-#define MGCP_POLICY_DEFER 6
-
-typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
-typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
-typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
-typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg);
-typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone);
-
-/**
- * Return:
- * < 0 in case no audio was processed
- * >= 0 in case audio was processed. The remaining payload
- * length will be returned.
- */
-typedef int (*mgcp_processing)(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- char *data, int *len, int buf_size);
-typedef int (*mgcp_processing_setup)(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- struct mgcp_rtp_end *src_end);
-
-typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
- int *payload_type,
- const char**subtype_name,
- const char**fmtp_extra);
-
-#define PORT_ALLOC_STATIC 0
-#define PORT_ALLOC_DYNAMIC 1
-
-/**
- * This holds information on how to allocate ports
- */
-struct mgcp_port_range {
- int mode;
-
- /* addr or NULL to fall-back to default */
- char *bind_addr;
-
- /* pre-allocated from a base? */
- int base_port;
-
- /* dynamically allocated */
- int range_start;
- int range_end;
- int last_port;
-};
-
-#define MGCP_KEEPALIVE_ONCE (-1)
-
-struct mgcp_trunk_config {
- struct llist_head entry;
-
- struct mgcp_config *cfg;
-
- int trunk_nr;
- int trunk_type;
-
- char *audio_fmtp_extra;
- char *audio_name;
- int audio_payload;
- int audio_send_ptime;
- int audio_send_name;
- int audio_loop;
-
- int no_audio_transcoding;
-
- int omit_rtcp;
- int keepalive_interval;
-
- /* RTP patching */
- int force_constant_ssrc; /* 0: don't, 1: once */
- int force_aligned_timing;
-
- /* spec handling */
- int force_realloc;
-
- /* timer */
- struct osmo_timer_list keepalive_timer;
-
- unsigned int number_endpoints;
- struct mgcp_endpoint *endpoints;
-};
-
-enum mgcp_role {
- MGCP_BSC = 0,
- MGCP_BSC_NAT,
-};
-
-enum mgcp_connection_mode {
- MGCP_CONN_NONE = 0,
- MGCP_CONN_RECV_ONLY = 1,
- MGCP_CONN_SEND_ONLY = 2,
- MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
- MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND,
-};
-
-extern const struct value_string mgcp_connection_mode_strs[];
-
-static inline const char *mgcp_cmode_name(enum mgcp_connection_mode mode)
-{
- return get_value_string(mgcp_connection_mode_strs, mode);
-}
-
-struct mgcp_config {
- int source_port;
- char *local_ip;
- char *source_addr;
- char *bts_ip;
- char *call_agent_addr;
-
- struct in_addr bts_in;
-
- /* transcoder handling */
- char *transcoder_ip;
- struct in_addr transcoder_in;
- int transcoder_remote_base;
-
- /* RTP processing */
- mgcp_processing rtp_processing_cb;
- mgcp_processing_setup setup_rtp_processing_cb;
-
- mgcp_get_format get_net_downlink_format_cb;
-
- struct osmo_wqueue gw_fd;
-
- struct mgcp_port_range bts_ports;
- struct mgcp_port_range net_ports;
- struct mgcp_port_range transcoder_ports;
- int endp_dscp;
-
- int bts_force_ptime;
-
- mgcp_change change_cb;
- mgcp_policy policy_cb;
- mgcp_reset reset_cb;
- mgcp_realloc realloc_cb;
- mgcp_rqnt rqnt_cb;
- void *data;
-
- uint32_t last_call_id;
-
- /* trunk handling */
- struct mgcp_trunk_config trunk;
- struct llist_head trunks;
-
- /* only used for start with a static configuration */
- int last_net_port;
- int last_bts_port;
-
- enum mgcp_role role;
-
- /* osmux translator: 0 means disabled, 1 means enabled */
- int osmux;
- /* addr to bind the server to */
- char *osmux_addr;
- /* The BSC-NAT may ask for enabling osmux on demand. This tells us if
- * the osmux socket is already initialized.
- */
- int osmux_init;
- /* osmux batch factor: from 1 to 4 maximum */
- int osmux_batch;
- /* osmux batch size (in bytes) */
- int osmux_batch_size;
- /* osmux port */
- uint16_t osmux_port;
- /* Pad circuit with dummy messages until we see the first voice
- * message.
- */
- uint16_t osmux_dummy;
-};
-
-/* config management */
-struct mgcp_config *mgcp_config_alloc(void);
-int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
- enum mgcp_role role);
-int mgcp_vty_init(void);
-int mgcp_endpoints_allocate(struct mgcp_trunk_config *cfg);
-void mgcp_release_endp(struct mgcp_endpoint *endp);
-void mgcp_initialize_endp(struct mgcp_endpoint *endp);
-int mgcp_reset_transcoder(struct mgcp_config *cfg);
-void mgcp_format_stats(struct mgcp_endpoint *endp, char *stats, size_t size);
-int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, uint32_t *pr, uint32_t *_or, int *loss, uint32_t *jitter);
-
-void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval);
-
-/*
- * format helper functions
- */
-struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
-
-/* adc helper */
-static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
-{
- if (timeslot == 0) {
- LOGP(DMGCP, LOGL_ERROR, "Timeslot should not be 0\n");
- timeslot = 255;
- }
-
- return timeslot + (32 * multiplex);
-}
-
-static inline void mgcp_endpoint_to_timeslot(int endpoint, int *multiplex, int *timeslot)
-{
- *multiplex = endpoint / 32;
- *timeslot = endpoint % 32;
-}
-
-int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint);
-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_send(struct mgcp_endpoint *endp, int dest, int is_rtp, struct sockaddr_in *addr, char *buf, int rc);
-int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len);
-
-#endif
diff --git a/include/openbsc/mgcp_internal.h b/include/openbsc/mgcp_internal.h
deleted file mode 100644
index b2c24089d..000000000
--- a/include/openbsc/mgcp_internal.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/* MGCP Private Data */
-
-/*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
- * 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
-
-#include <string.h>
-
-#include <osmocom/core/select.h>
-
-#define CI_UNUSED 0
-
-enum mgcp_trunk_type {
- MGCP_TRUNK_VIRTUAL,
- MGCP_TRUNK_E1,
-};
-
-struct mgcp_rtp_stream_state {
- uint32_t ssrc;
- uint16_t last_seq;
- uint32_t last_timestamp;
- uint32_t err_ts_counter;
- int32_t last_tsdelta;
- uint32_t last_arrival_time;
-};
-
-struct mgcp_rtp_state {
- int initialized;
- int patch_ssrc;
-
- uint32_t orig_ssrc;
-
- int seq_offset;
-
- int32_t timestamp_offset;
- uint32_t packet_duration;
-
- struct mgcp_rtp_stream_state in_stream;
- struct mgcp_rtp_stream_state out_stream;
-
- /* jitter and packet loss calculation */
- int stats_initialized;
- uint16_t stats_base_seq;
- uint16_t stats_max_seq;
- uint32_t stats_ssrc;
- uint32_t stats_jitter;
- int32_t stats_transit;
- int stats_cycles;
- bool patched_first_rtp_payload; /* FIXME: drop this, see OS#2459 */
-};
-
-struct mgcp_rtp_codec {
- uint32_t rate;
- int channels;
- uint32_t frame_duration_num;
- uint32_t frame_duration_den;
-
- int payload_type;
- char *audio_name;
- char *subtype_name;
-};
-
-struct mgcp_rtp_end {
- /* statistics */
- unsigned int packets;
- unsigned int octets;
- unsigned int dropped_packets;
- struct in_addr addr;
-
- /* in network byte order */
- int rtp_port, rtcp_port;
-
- /* audio codec information */
- struct mgcp_rtp_codec codec;
- struct mgcp_rtp_codec alt_codec; /* TODO/XXX: make it generic */
-
- /* per endpoint data */
- int frames_per_packet;
- uint32_t packet_duration_ms;
- char *fmtp_extra;
- int output_enabled;
- int force_output_ptime;
-
- /* RTP patching */
- int force_constant_ssrc; /* -1: always, 0: don't, 1: once */
- int force_aligned_timing;
- void *rtp_process_data;
-
- /*
- * Each end has a socket...
- */
- struct osmo_fd rtp;
- struct osmo_fd rtcp;
-
- int local_port;
- int local_alloc;
-};
-
-enum {
- MGCP_TAP_BTS_IN,
- MGCP_TAP_BTS_OUT,
- MGCP_TAP_NET_IN,
- MGCP_TAP_NET_OUT,
-
- /* last element */
- MGCP_TAP_COUNT
-};
-
-struct mgcp_rtp_tap {
- int enabled;
- struct sockaddr_in forward;
-};
-
-struct mgcp_lco {
- char *string;
- char *codec;
- int pkt_period_min; /* time in ms */
- int pkt_period_max; /* time in ms */
-};
-
-enum mgcp_type {
- MGCP_RTP_DEFAULT = 0,
- MGCP_RTP_TRANSCODED,
- MGCP_OSMUX_BSC,
- MGCP_OSMUX_BSC_NAT,
-};
-
-#include <openbsc/osmux.h>
-
-struct mgcp_endpoint {
- int allocated;
- uint32_t ci;
- char *callid;
- struct mgcp_lco local_options;
- int conn_mode;
- int orig_mode;
-
- /* backpointer */
- struct mgcp_config *cfg;
- struct mgcp_trunk_config *tcfg;
-
- /* port status for bts/net */
- struct mgcp_rtp_end bts_end;
- struct mgcp_rtp_end net_end;
-
- /*
- * For transcoding we will send from the local_port
- * of trans_bts and it will arrive at trans_net from
- * where we will forward it to the network.
- */
- struct mgcp_rtp_end trans_bts;
- struct mgcp_rtp_end trans_net;
- enum mgcp_type type;
-
- /* sequence bits */
- struct mgcp_rtp_state net_state;
- struct mgcp_rtp_state bts_state;
-
- /* fields for re-transmission */
- char *last_trans;
- char *last_response;
-
- /* tap for the endpoint */
- struct mgcp_rtp_tap taps[MGCP_TAP_COUNT];
-
- struct {
- /* Osmux state: disabled, activating, active */
- enum osmux_state state;
- /* Allocated Osmux circuit ID for this endpoint */
- int allocated_cid;
- /* Used Osmux circuit ID for this endpoint */
- uint8_t cid;
- /* handle to batch messages */
- struct osmux_in_handle *in;
- /* handle to unbatch messages */
- struct osmux_out_handle out;
- /* statistics */
- struct {
- uint32_t chunks;
- uint32_t octets;
- } stats;
- } osmux;
-};
-
-#define for_each_line(line, save) \
- for (line = strline_r(NULL, &save); line;\
- line = strline_r(NULL, &save))
-
-static inline char *strline_r(char *str, char **saveptr)
-{
- char *result;
-
- if (str)
- *saveptr = str;
-
- result = *saveptr;
-
- if (*saveptr != NULL) {
- *saveptr = strpbrk(*saveptr, "\r\n");
-
- if (*saveptr != NULL) {
- char *eos = *saveptr;
-
- if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
- (*saveptr)++;
- (*saveptr)++;
- if ((*saveptr)[0] == '\0')
- *saveptr = NULL;
-
- *eos = '\0';
- }
- }
-
- return result;
-}
-
-
-
-#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
-
-/**
- * Internal structure while parsing a request
- */
-struct mgcp_parse_data {
- struct mgcp_config *cfg;
- struct mgcp_endpoint *endp;
- char *trans;
- char *save;
- int found;
-};
-
-int mgcp_send_dummy(struct mgcp_endpoint *endp);
-int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
-int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
-int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
-int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
-int mgcp_free_rtp_port(struct mgcp_rtp_end *end);
-
-/* For transcoding we need to manage an in and an output that are connected */
-static inline int endp_back_channel(int endpoint)
-{
- return endpoint + 60;
-}
-
-struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);
-struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);
-
-void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
- struct mgcp_rtp_end *rtp);
-uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *rtp);
-
-void mgcp_state_calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *,
- uint32_t *expected, int *loss);
-uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *);
-
-/* payload processing default functions */
-int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end,
- char *data, int *len, int buf_size);
-
-int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- struct mgcp_rtp_end *src_end);
-
-void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
- int *payload_type,
- const char**subtype_name,
- const char**fmtp_extra);
-
-/* internal RTP Annex A counting */
-void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
- const uint16_t seq, const int32_t transit,
- const uint32_t ssrc);
-
-int mgcp_set_ip_tos(int fd, int tos);
-
-enum {
- MGCP_DEST_NET = 0,
- MGCP_DEST_BTS,
-};
-
-
-#define MGCP_DUMMY_LOAD 0x23
-
-
-/**
- * SDP related information
- */
-/* Assume audio frame length of 20ms */
-#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
-#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
-#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
-#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
-#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
-
-#define PTYPE_UNDEFINED (-1)
-int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p);
-int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
- int payload_type, const char *audio_name);
-
-
-/**
- * Internal network related
- */
-static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
-{
- if (endp->cfg->net_ports.bind_addr)
- return endp->cfg->net_ports.bind_addr;
- return endp->cfg->source_addr;
-}
-
-static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
-{
- if (endp->cfg->bts_ports.bind_addr)
- return endp->cfg->bts_ports.bind_addr;
- return endp->cfg->source_addr;
-}
-
-int mgcp_msg_terminate_nul(struct msgb *msg);
diff --git a/include/openbsc/mgcp_transcode.h b/include/openbsc/mgcp_transcode.h
deleted file mode 100644
index 147e48bba..000000000
--- a/include/openbsc/mgcp_transcode.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * (C) 2014 by On-Waves
- * 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/>.
- *
- */
-#ifndef OPENBSC_MGCP_TRANSCODE_H
-#define OPENBSC_MGCP_TRANSCODE_H
-
-#include "bscconfig.h"
-
-#include <gsm.h>
-#ifdef HAVE_BCG729
-#include <bcg729/decoder.h>
-#include <bcg729/encoder.h>
-#endif
-
-enum audio_format {
- AF_INVALID,
- AF_S16,
- AF_L16,
- AF_GSM,
- AF_G729,
- AF_PCMA,
- AF_PCMU
-};
-
-
-struct mgcp_process_rtp_state {
- /* decoding */
- enum audio_format src_fmt;
- union {
- gsm gsm_handle;
-#ifdef HAVE_BCG729
- bcg729DecoderChannelContextStruct *g729_dec;
-#endif
- } src;
- size_t src_frame_size;
- size_t src_samples_per_frame;
-
- /* processing */
-
- /* encoding */
- enum audio_format dst_fmt;
- union {
- gsm gsm_handle;
-#ifdef HAVE_BCG729
- bcg729EncoderChannelContextStruct *g729_enc;
-#endif
- } dst;
- size_t dst_frame_size;
- size_t dst_samples_per_frame;
- int dst_packet_duration;
-
- int is_running;
- uint16_t next_seq;
- uint32_t next_time;
- int16_t samples[10*160];
- size_t sample_cnt;
- size_t sample_offs;
-};
-
-
-int mgcp_transcoding_setup(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- struct mgcp_rtp_end *src_end);
-
-void mgcp_transcoding_net_downlink_format(struct mgcp_endpoint *endp,
- int *payload_type,
- const char**audio_name,
- const char**fmtp_extra);
-
-int mgcp_transcoding_process_rtp(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- char *data, int *len, int buf_size);
-
-int mgcp_transcoding_get_frame_size(void *state_, int nsamples, int dst);
-#endif /* OPENBSC_MGCP_TRANSCODE_H */
diff --git a/include/openbsc/mgcpgw_client.h b/include/openbsc/mgcpgw_client.h
deleted file mode 100644
index b1b5fd42b..000000000
--- a/include/openbsc/mgcpgw_client.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/write_queue.h>
-
-enum mgcp_connection_mode;
-
-struct msgb;
-struct vty;
-
-#define MGCPGW_CLIENT_LOCAL_ADDR_DEFAULT "0.0.0.0"
-#define MGCPGW_CLIENT_LOCAL_PORT_DEFAULT 0
-#define MGCPGW_CLIENT_REMOTE_ADDR_DEFAULT "127.0.0.1"
-#define MGCPGW_CLIENT_REMOTE_PORT_DEFAULT 2427
-
-#define MSGB_CB_MGCP_TRANS_ID 0
-
-typedef unsigned int mgcp_trans_id_t;
-
-struct mgcpgw_client_conf {
- const char *local_addr;
- int local_port;
- const char *remote_addr;
- int remote_port;
- uint16_t first_endpoint;
- uint16_t last_endpoint;
- uint16_t bts_base;
-};
-
-struct mgcp_response_head {
- int response_code;
- mgcp_trans_id_t trans_id;
- const char *comment;
-};
-
-struct mgcp_response {
- char *body;
- struct mgcp_response_head head;
- uint16_t audio_port;
-};
-
-struct mgcpgw_client {
- struct mgcpgw_client_conf actual;
- uint32_t remote_addr;
- struct osmo_wqueue wq;
- mgcp_trans_id_t next_trans_id;
- struct llist_head responses_pending;
- struct llist_head inuse_endpoints;
-};
-
-struct mgcp_inuse_endpoint {
- struct llist_head entry;
- uint16_t id;
-};
-
-/* Invoked when an MGCP response is received or sending failed. When the
- * response is passed as NULL, this indicates failure during transmission. */
-typedef void (* mgcp_response_cb_t )(struct mgcp_response *response, void *priv);
-
-struct mgcp_response_pending {
- struct llist_head entry;
-
- mgcp_trans_id_t trans_id;
- mgcp_response_cb_t response_cb;
- void *priv;
-};
-
-
-void mgcpgw_client_conf_init(struct mgcpgw_client_conf *conf);
-
-struct mgcpgw_client *mgcpgw_client_init(void *ctx,
- struct mgcpgw_client_conf *conf);
-int mgcpgw_client_connect(struct mgcpgw_client *mgcp);
-
-const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp);
-uint16_t mgcpgw_client_remote_port(struct mgcpgw_client *mgcp);
-uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp);
-
-/* Find and seize an unsused endpoint id */
-int mgcpgw_client_next_endpoint(struct mgcpgw_client *client);
-
-/* Release a seized endpoint id to make it available again for other calls */
-void mgcpgw_client_release_endpoint(uint16_t id, struct mgcpgw_client *client);
-
-int mgcp_response_parse_params(struct mgcp_response *r);
-
-int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg,
- mgcp_response_cb_t response_cb, void *priv);
-
-struct msgb *mgcp_msg_crcx(struct mgcpgw_client *mgcp,
- uint16_t rtp_endpoint, unsigned int call_id,
- enum mgcp_connection_mode mode);
-
-struct msgb *mgcp_msg_mdcx(struct mgcpgw_client *mgcp,
- uint16_t rtp_endpoint, const char *rtp_conn_addr,
- uint16_t rtp_port, enum mgcp_connection_mode mode);
-
-struct msgb *mgcp_msg_dlcx(struct mgcpgw_client *mgcp, uint16_t rtp_endpoint,
- unsigned int call_id);
-
-void mgcpgw_client_vty_init(int node, struct mgcpgw_client_conf *conf);
-int mgcpgw_client_config_write(struct vty *vty, const char *indent);
-
-struct mgcp_response_pending * mgcpgw_client_pending_add(
- struct mgcpgw_client *mgcp,
- mgcp_trans_id_t trans_id,
- mgcp_response_cb_t response_cb,
- void *priv);
-int mgcpgw_client_rx(struct mgcpgw_client *mgcp, struct msgb *msg);
diff --git a/osmoappdesc.py b/osmoappdesc.py
index 170c83bb2..22210d5bf 100644
--- a/osmoappdesc.py
+++ b/osmoappdesc.py
@@ -30,7 +30,6 @@ nitb_e1_configs = [
app_configs = {
"osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg"],
"nat": ["doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"],
- "mgcp": ["doc/examples/osmo-bsc_mgcp/mgcp.cfg"],
"gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg",
"doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"],
"sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
@@ -41,7 +40,6 @@ app_configs = {
apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"),
(4244, "src/osmo-bsc_nat/osmo-bsc_nat", "OsmoBSCNAT", "nat"),
- (4243, "src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp"),
(4246, "src/gprs/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
(4245, "src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn"),
(4254, "src/osmo-msc/osmo-msc", "OsmoMSC", "msc"),
@@ -51,4 +49,4 @@ apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"),
vty_command = ["./src/osmo-msc/osmo-msc", "-c",
"doc/examples/osmo-msc/osmo-msc.cfg"]
-vty_app = apps[5] # reference apps[] entry for osmo-nitb
+vty_app = apps[4] # reference apps[] entry for osmo-msc
diff --git a/src/Makefile.am b/src/Makefile.am
index bd697385f..70e53ac3e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,6 @@ AM_LDFLAGS = \
SUBDIRS = \
libcommon \
libvlr \
- libmgcp \
libbsc \
libmsc \
libtrau \
@@ -34,7 +33,6 @@ SUBDIRS = \
# Programs
SUBDIRS += \
osmo-msc \
- osmo-bsc_mgcp \
utils \
ipaccess \
gprs \
diff --git a/src/libfilter/bsc_msg_acc.c b/src/libfilter/bsc_msg_acc.c
index bfc5bdd3f..a42206db8 100644
--- a/src/libfilter/bsc_msg_acc.c
+++ b/src/libfilter/bsc_msg_acc.c
@@ -20,6 +20,7 @@
#include <openbsc/bsc_msg_filter.h>
#include <openbsc/bsc_nat.h>
+#include <openbsc/debug.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
diff --git a/src/libmgcp/Makefile.am b/src/libmgcp/Makefile.am
deleted file mode 100644
index 5d7844da4..000000000
--- a/src/libmgcp/Makefile.am
+++ /dev/null
@@ -1,46 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_builddir) \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOVTY_CFLAGS) \
- $(LIBOSMONETIF_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- $(LIBBCG729_CFLAGS) \
- $(NULL)
-
-AM_LDFLAGS = \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMONETIF_LIBS) \
- $(COVERAGE_LDFLAGS) \
- $(LIBBCG729_LIBS) \
- $(NULL)
-
-noinst_LIBRARIES = \
- libmgcp.a \
- $(NULL)
-
-noinst_HEADERS = \
- g711common.h \
- $(NULL)
-
-libmgcp_a_SOURCES = \
- mgcp_common.c \
- mgcp_protocol.c \
- mgcp_network.c \
- mgcp_vty.c \
- mgcp_osmux.c \
- mgcp_sdp.c \
- mgcpgw_client.c \
- mgcpgw_client_vty.c \
- $(NULL)
-if BUILD_MGCP_TRANSCODING
-libmgcp_a_SOURCES += \
- mgcp_transcode.c \
- $(NULL)
-endif
diff --git a/src/libmgcp/g711common.h b/src/libmgcp/g711common.h
deleted file mode 100644
index cb35fc651..000000000
--- a/src/libmgcp/g711common.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * PCM - A-Law conversion
- * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- * Wrapper for linphone Codec class by Simon Morlat <simon.morlat@linphone.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-static inline int val_seg(int val)
-{
- int r = 0;
- val >>= 7; /*7 = 4 + 3*/
- if (val & 0xf0) {
- val >>= 4;
- r += 4;
- }
- if (val & 0x0c) {
- val >>= 2;
- r += 2;
- }
- if (val & 0x02)
- r += 1;
- return r;
-}
-
-/*
- * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
- *
- * s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data.
- *
- * Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 0000000wxyza 000wxyz
- * 0000001wxyza 001wxyz
- * 000001wxyzab 010wxyz
- * 00001wxyzabc 011wxyz
- * 0001wxyzabcd 100wxyz
- * 001wxyzabcde 101wxyz
- * 01wxyzabcdef 110wxyz
- * 1wxyzabcdefg 111wxyz
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- * G711 is designed for 13 bits input signal, this function add extra shifting to take this into account.
- */
-
-static inline unsigned char s16_to_alaw(int pcm_val)
-{
- int mask;
- int seg;
- unsigned char aval;
-
- if (pcm_val >= 0) {
- mask = 0xD5;
- } else {
- mask = 0x55;
- pcm_val = -pcm_val;
- if (pcm_val > 0x7fff)
- pcm_val = 0x7fff;
- }
-
- if (pcm_val < 256) /*256 = 32 << 3*/
- aval = pcm_val >> 4; /*4 = 1 + 3*/
- else {
- /* Convert the scaled magnitude to segment number. */
- seg = val_seg(pcm_val);
- aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
- }
- return aval ^ mask;
-}
-
-/*
- * alaw_to_s16() - Convert an A-law value to 16-bit linear PCM
- *
- */
-static inline int alaw_to_s16(unsigned char a_val)
-{
- int t;
- int seg;
-
- a_val ^= 0x55;
- t = a_val & 0x7f;
- if (t < 16)
- t = (t << 4) + 8;
- else {
- seg = (t >> 4) & 0x07;
- t = ((t & 0x0f) << 4) + 0x108;
- t <<= seg -1;
- }
- return ((a_val & 0x80) ? t : -t);
-}
-/*
- * s16_to_ulaw() - Convert a linear PCM value to u-law
- *
- * In order to simplify the encoding process, the original linear magnitude
- * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
- * (33 - 8191). The result can be seen in the following encoding table:
- *
- * Biased Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 00000001wxyza 000wxyz
- * 0000001wxyzab 001wxyz
- * 000001wxyzabc 010wxyz
- * 00001wxyzabcd 011wxyz
- * 0001wxyzabcde 100wxyz
- * 001wxyzabcdef 101wxyz
- * 01wxyzabcdefg 110wxyz
- * 1wxyzabcdefgh 111wxyz
- *
- * Each biased linear code has a leading 1 which identifies the segment
- * number. The value of the segment number is equal to 7 minus the number
- * of leading 0's. The quantization interval is directly available as the
- * four bits wxyz. * The trailing bits (a - h) are ignored.
- *
- * Ordinarily the complement of the resulting code word is used for
- * transmission, and so the code word is complemented before it is returned.
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-
-static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */
-{
- int mask;
- int seg;
- unsigned char uval;
-
- if (pcm_val < 0) {
- pcm_val = 0x84 - pcm_val;
- mask = 0x7f;
- } else {
- pcm_val += 0x84;
- mask = 0xff;
- }
- if (pcm_val > 0x7fff)
- pcm_val = 0x7fff;
-
- /* Convert the scaled magnitude to segment number. */
- seg = val_seg(pcm_val);
-
- /*
- * Combine the sign, segment, quantization bits;
- * and complement the code word.
- */
- uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
- return uval ^ mask;
-}
-
-/*
- * ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM
- *
- * First, a biased linear code is derived from the code word. An unbiased
- * output can then be obtained by subtracting 33 from the biased code.
- *
- * Note that this function expects to be passed the complement of the
- * original code word. This is in keeping with ISDN conventions.
- */
-static inline int ulaw_to_s16(unsigned char u_val)
-{
- int t;
-
- /* Complement to obtain normal u-law value. */
- u_val = ~u_val;
-
- /*
- * Extract and bias the quantization bits. Then
- * shift up by the segment number and subtract out the bias.
- */
- t = ((u_val & 0x0f) << 3) + 0x84;
- t <<= (u_val & 0x70) >> 4;
-
- return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
-}
diff --git a/src/libmgcp/mgcp_common.c b/src/libmgcp/mgcp_common.c
deleted file mode 100644
index 43c866768..000000000
--- a/src/libmgcp/mgcp_common.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Media Gateway Control Protocol Media Gateway: RFC 3435 */
-/* Implementations useful both for the MGCP GW as well as MGCP GW clients */
-
-/*
- * (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <errno.h>
-
-#include <osmocom/core/utils.h>
-#include <openbsc/mgcp.h>
-
-const struct value_string mgcp_connection_mode_strs[] = {
- { MGCP_CONN_NONE, "none" },
- { MGCP_CONN_RECV_SEND, "sendrecv" },
- { MGCP_CONN_SEND_ONLY, "sendonly" },
- { MGCP_CONN_RECV_ONLY, "recvonly" },
- { MGCP_CONN_LOOPBACK, "loopback" },
- { 0, NULL }
-};
-
-/* Ensure that the msg->l2h is NUL terminated. */
-int mgcp_msg_terminate_nul(struct msgb *msg)
-{
- unsigned char *tail = msg->l2h + msgb_l2len(msg); /* char after l2 data */
- if (tail[-1] == '\0')
- /* nothing to do */;
- else if (msgb_tailroom(msg) > 0)
- tail[0] = '\0';
- else if (tail[-1] == '\r' || tail[-1] == '\n')
- tail[-1] = '\0';
- else {
- LOGP(DMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: "
- "Length: %d, Buffer size: %d\n",
- msgb_l2len(msg), msg->data_len);
- return -ENOTSUP;
- }
- return 0;
-}
diff --git a/src/libmgcp/mgcp_network.c b/src/libmgcp/mgcp_network.c
deleted file mode 100644
index 399dc8fe1..000000000
--- a/src/libmgcp/mgcp_network.c
+++ /dev/null
@@ -1,1166 +0,0 @@
-/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
-/* The protocol implementation */
-
-/*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
- * 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 <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <time.h>
-#include <limits.h>
-
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/select.h>
-
-#include <osmocom/netif/rtp.h>
-
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-
-#include <openbsc/osmux.h>
-
-#warning "Make use of the rtp proxy code"
-
-
-#define RTP_SEQ_MOD (1 << 16)
-#define RTP_MAX_DROPOUT 3000
-#define RTP_MAX_MISORDER 100
-#define RTP_BUF_SIZE 4096
-
-enum {
- MGCP_PROTO_RTP,
- MGCP_PROTO_RTCP,
-};
-
-/**
- * This does not need to be a precision timestamp and
- * is allowed to wrap quite fast. The returned value is
- * 1/unit seconds.
- */
-static uint32_t get_current_ts(unsigned unit)
-{
- struct timespec tp;
- uint64_t ret;
-
- if (!unit)
- return 0;
-
- memset(&tp, 0, sizeof(tp));
- if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0)
- LOGP(DMGCP, LOGL_NOTICE,
- "Getting the clock failed.\n");
-
- /* convert it to 1/unit seconds */
- ret = tp.tv_sec;
- ret *= unit;
- ret += (int64_t)tp.tv_nsec * unit / 1000 / 1000 / 1000;
-
- return ret;
-}
-
-int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
-{
- struct sockaddr_in out;
- out.sin_family = AF_INET;
- out.sin_port = port;
- memcpy(&out.sin_addr, addr, sizeof(*addr));
-
- return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
-}
-
-int mgcp_send_dummy(struct mgcp_endpoint *endp)
-{
- static char buf[] = { MGCP_DUMMY_LOAD };
- int rc;
- int was_rtcp = 0;
-
- rc = mgcp_udp_send(endp->net_end.rtp.fd, &endp->net_end.addr,
- endp->net_end.rtp_port, buf, 1);
-
- if (rc == -1)
- goto failed;
-
- if (endp->tcfg->omit_rtcp)
- return rc;
-
- was_rtcp = 1;
- rc = mgcp_udp_send(endp->net_end.rtcp.fd, &endp->net_end.addr,
- endp->net_end.rtcp_port, buf, 1);
-
- if (rc >= 0)
- return rc;
-
-failed:
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to send dummy %s packet: %s on: 0x%x to %s:%d\n",
- was_rtcp ? "RTCP" : "RTP",
- strerror(errno), ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr),
- was_rtcp ? endp->net_end.rtcp_port : endp->net_end.rtp_port);
-
- return -1;
-}
-
-static int32_t compute_timestamp_aligment_error(struct mgcp_rtp_stream_state *sstate,
- int ptime, uint32_t timestamp)
-{
- int32_t timestamp_delta;
-
- if (ptime == 0)
- return 0;
-
- /* Align according to: T - Tlast = k * Tptime */
- timestamp_delta = timestamp - sstate->last_timestamp;
-
- return timestamp_delta % ptime;
-}
-
-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 sockaddr_in *addr,
- uint16_t seq, uint32_t timestamp,
- const char *text, int32_t *tsdelta_out)
-{
- int32_t tsdelta;
- int32_t timestamp_error;
-
- /* Not fully intialized, skip */
- if (sstate->last_tsdelta == 0 && timestamp == sstate->last_timestamp)
- return 0;
-
- if (seq == sstate->last_seq) {
- if (timestamp != sstate->last_timestamp) {
- sstate->err_ts_counter += 1;
- LOGP(DMGCP, LOGL_ERROR,
- "The %s timestamp delta is != 0 but the sequence "
- "number %d is the same, "
- "TS offset: %d, SeqNo offset: %d "
- "on 0x%x SSRC: %u timestamp: %u "
- "from %s:%d in %d\n",
- text, seq,
- state->timestamp_offset, state->seq_offset,
- ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- }
- return 0;
- }
-
- tsdelta =
- (int32_t)(timestamp - sstate->last_timestamp) /
- (int16_t)(seq - sstate->last_seq);
-
- if (tsdelta == 0) {
- /* Don't update *tsdelta_out */
- LOGP(DMGCP, LOGL_NOTICE,
- "The %s timestamp delta is %d "
- "on 0x%x SSRC: %u timestamp: %u "
- "from %s:%d in %d\n",
- text, tsdelta,
- ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
-
- return 0;
- }
-
- if (sstate->last_tsdelta != tsdelta) {
- if (sstate->last_tsdelta) {
- LOGP(DMGCP, LOGL_INFO,
- "The %s timestamp delta changes from %d to %d "
- "on 0x%x SSRC: %u timestamp: %u from %s:%d in %d\n",
- text, sstate->last_tsdelta, tsdelta,
- ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- }
- }
-
- if (tsdelta_out)
- *tsdelta_out = tsdelta;
-
- timestamp_error =
- compute_timestamp_aligment_error(sstate, state->packet_duration,
- timestamp);
-
- if (timestamp_error) {
- sstate->err_ts_counter += 1;
- LOGP(DMGCP, LOGL_NOTICE,
- "The %s timestamp has an alignment error of %d "
- "on 0x%x SSRC: %u "
- "SeqNo delta: %d, TS delta: %d, dTS/dSeq: %d "
- "from %s:%d in mode %d. ptime: %d\n",
- text, timestamp_error,
- ENDPOINT_NUMBER(endp), sstate->ssrc,
- (int16_t)(seq - sstate->last_seq),
- (int32_t)(timestamp - sstate->last_timestamp),
- tsdelta,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode, state->packet_duration);
- }
- return 1;
-}
-
-/* Set the timestamp offset according to the packet duration. */
-static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
- struct mgcp_rtp_state *state,
- struct mgcp_rtp_end *rtp_end,
- 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;
-
- if (tsdelta == 0) {
- tsdelta = state->out_stream.last_tsdelta;
- if (tsdelta != 0) {
- LOGP(DMGCP, LOGL_NOTICE,
- "A fixed packet duration is not available on 0x%x, "
- "using last output timestamp delta instead: %d "
- "from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp), tsdelta,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- } else {
- tsdelta = rtp_end->codec.rate * 20 / 1000;
- LOGP(DMGCP, LOGL_NOTICE,
- "Fixed packet duration and last timestamp delta "
- "are not available on 0x%x, "
- "using fixed 20ms instead: %d "
- "from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp), tsdelta,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- }
- }
-
- out_timestamp = state->out_stream.last_timestamp + delta_seq * tsdelta;
- timestamp_offset = out_timestamp - in_timestamp;
-
- if (state->timestamp_offset != timestamp_offset) {
- state->timestamp_offset = timestamp_offset;
-
- LOGP(DMGCP, LOGL_NOTICE,
- "Timestamp offset change on 0x%x SSRC: %u "
- "SeqNo delta: %d, TS offset: %d, "
- "from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
- delta_seq, state->timestamp_offset,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- }
-
- return timestamp_offset;
-}
-
-/* Set the timestamp offset according to the packet duration. */
-static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp,
- struct mgcp_rtp_state *state,
- struct mgcp_rtp_end *rtp_end,
- struct sockaddr_in *addr,
- uint32_t timestamp)
-{
- int timestamp_error = 0;
- int ptime = state->packet_duration;
-
- /* Align according to: T + Toffs - Tlast = k * Tptime */
-
- timestamp_error = compute_timestamp_aligment_error(
- &state->out_stream, ptime,
- timestamp + state->timestamp_offset);
-
- if (timestamp_error) {
- state->timestamp_offset += ptime - timestamp_error;
-
- LOGP(DMGCP, LOGL_NOTICE,
- "Corrected timestamp alignment error of %d on 0x%x SSRC: %u "
- "new TS offset: %d, "
- "from %s:%d in %d\n",
- timestamp_error,
- ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
- state->timestamp_offset, inet_ntoa(addr->sin_addr),
- ntohs(addr->sin_port), endp->conn_mode);
- }
-
- OSMO_ASSERT(compute_timestamp_aligment_error(&state->out_stream, ptime,
- timestamp + state->timestamp_offset) == 0);
-
- return timestamp_error;
-}
-
-int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end,
- char *data, int *len, int buf_size)
-{
- return 0;
-}
-
-int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- struct mgcp_rtp_end *src_end)
-{
- return 0;
-}
-
-void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
- int *payload_type,
- const char**audio_name,
- const char**fmtp_extra)
-{
- /* Use the BTS side parameters when passing the SDP data (for
- * downlink) to the net peer.
- */
- *payload_type = endp->bts_end.codec.payload_type;
- *audio_name = endp->bts_end.codec.audio_name;
- *fmtp_extra = endp->bts_end.fmtp_extra;
-}
-
-
-void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
- const uint16_t seq, const int32_t transit,
- const uint32_t ssrc)
-{
- int32_t d;
-
- /* initialize or re-initialize */
- if (!state->stats_initialized || state->stats_ssrc != ssrc) {
- state->stats_initialized = 1;
- state->stats_base_seq = seq;
- state->stats_max_seq = seq - 1;
- state->stats_ssrc = ssrc;
- state->stats_jitter = 0;
- state->stats_transit = transit;
- state->stats_cycles = 0;
- } else {
- uint16_t udelta;
-
- /*
- * The below takes the shape of the validation of
- * Appendix A. Check if there is something weird with
- * the sequence number, otherwise check for a wrap
- * around in the sequence number.
- * It can't wrap during the initialization so let's
- * skip it here. The Appendix A probably doesn't have
- * this issue because of the probation.
- */
- udelta = seq - state->stats_max_seq;
- if (udelta < RTP_MAX_DROPOUT) {
- if (seq < state->stats_max_seq)
- state->stats_cycles += RTP_SEQ_MOD;
- } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
- LOGP(DMGCP, LOGL_NOTICE,
- "RTP seqno made a very large jump on 0x%x delta: %u\n",
- ENDPOINT_NUMBER(endp), udelta);
- }
- }
-
- /*
- * Calculate the jitter between the two packages. The TS should be
- * taken closer to the read function. This was taken from the
- * Appendix A of RFC 3550. Timestamp and arrival_time have a 1/rate
- * resolution.
- */
- d = transit - state->stats_transit;
- state->stats_transit = transit;
- if (d < 0)
- d = -d;
- state->stats_jitter += d - ((state->stats_jitter + 8) >> 4);
- state->stats_max_seq = seq;
-}
-
-
-
-/**
- * The RFC 3550 Appendix A assumes there are multiple sources but
- * some of the supported endpoints (e.g. the nanoBTS) can only handle
- * one source and this code will patch RTP header to appear as if there
- * is only one source.
- * There is also no probation period for new sources. Every RTP header
- * we receive will be seen as a switch in streams.
- */
-void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
- struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr,
- char *data, int len)
-{
- uint32_t arrival_time;
- int32_t transit;
- uint16_t seq;
- uint32_t timestamp, ssrc;
- struct rtp_hdr *rtp_hdr;
- int payload = rtp_end->codec.payload_type;
-
- if (len < sizeof(*rtp_hdr))
- return;
-
- rtp_hdr = (struct rtp_hdr *) data;
- seq = ntohs(rtp_hdr->sequence);
- timestamp = ntohl(rtp_hdr->timestamp);
- arrival_time = get_current_ts(rtp_end->codec.rate);
- ssrc = ntohl(rtp_hdr->ssrc);
- transit = arrival_time - timestamp;
-
- mgcp_rtp_annex_count(endp, state, seq, transit, ssrc);
-
- if (!state->initialized) {
- state->initialized = 1;
- state->in_stream.last_seq = seq - 1;
- state->in_stream.ssrc = state->orig_ssrc = ssrc;
- state->in_stream.last_tsdelta = 0;
- state->packet_duration = mgcp_rtp_packet_duration(endp, rtp_end);
- state->out_stream = state->in_stream;
- state->out_stream.last_timestamp = timestamp;
- state->out_stream.ssrc = ssrc - 1; /* force output SSRC change */
- LOGP(DMGCP, LOGL_INFO,
- "Initializing stream on 0x%x SSRC: %u timestamp: %u "
- "pkt-duration: %d, from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
- state->seq_offset, state->packet_duration,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- if (state->packet_duration == 0) {
- state->packet_duration = rtp_end->codec.rate * 20 / 1000;
- LOGP(DMGCP, LOGL_NOTICE,
- "Fixed packet duration is not available on 0x%x, "
- "using fixed 20ms instead: %d from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp), state->packet_duration,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- }
- } else if (state->in_stream.ssrc != ssrc) {
- LOGP(DMGCP, LOGL_NOTICE,
- "The SSRC changed on 0x%x: %u -> %u "
- "from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp),
- state->in_stream.ssrc, rtp_hdr->ssrc,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
-
- state->in_stream.ssrc = ssrc;
- if (rtp_end->force_constant_ssrc) {
- int16_t delta_seq;
-
- /* Always increment seqno by 1 */
- state->seq_offset =
- (state->out_stream.last_seq + 1) - seq;
-
- /* Estimate number of packets that would have been sent */
- delta_seq =
- (arrival_time - state->in_stream.last_arrival_time
- + state->packet_duration/2) /
- state->packet_duration;
-
- adjust_rtp_timestamp_offset(endp, state, rtp_end, addr,
- delta_seq, timestamp);
-
- state->patch_ssrc = 1;
- ssrc = state->orig_ssrc;
- if (rtp_end->force_constant_ssrc != -1)
- rtp_end->force_constant_ssrc -= 1;
-
- LOGP(DMGCP, LOGL_NOTICE,
- "SSRC patching enabled on 0x%x SSRC: %u "
- "SeqNo offset: %d, TS offset: %d "
- "from %s:%d in %d\n",
- ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
- state->seq_offset, state->timestamp_offset,
- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
- endp->conn_mode);
- }
-
- state->in_stream.last_tsdelta = 0;
- } else {
- /* Compute current per-packet timestamp delta */
- check_rtp_timestamp(endp, state, &state->in_stream, rtp_end, addr,
- seq, timestamp, "input",
- &state->in_stream.last_tsdelta);
-
- if (state->patch_ssrc)
- ssrc = state->orig_ssrc;
- }
-
- /* Save before patching */
- state->in_stream.last_timestamp = timestamp;
- state->in_stream.last_seq = seq;
- state->in_stream.last_arrival_time = arrival_time;
-
- if (rtp_end->force_aligned_timing &&
- state->out_stream.ssrc == ssrc && state->packet_duration)
- /* Align the timestamp offset */
- align_rtp_timestamp_offset(endp, state, rtp_end, addr, timestamp);
-
- /* Store the updated SSRC back to the packet */
- if (state->patch_ssrc)
- rtp_hdr->ssrc = htonl(ssrc);
-
- /* Apply the offset and store it back to the packet.
- * This won't change anything if the offset is 0, so the conditional is
- * omitted. */
- seq += state->seq_offset;
- rtp_hdr->sequence = htons(seq);
- timestamp += state->timestamp_offset;
- rtp_hdr->timestamp = htonl(timestamp);
-
- /* Check again, whether the timestamps are still valid */
- if (state->out_stream.ssrc == ssrc)
- check_rtp_timestamp(endp, state, &state->out_stream, rtp_end,
- addr, seq, timestamp, "output",
- &state->out_stream.last_tsdelta);
-
- /* Save output values */
- state->out_stream.last_seq = seq;
- state->out_stream.last_timestamp = timestamp;
- state->out_stream.ssrc = ssrc;
-
- if (payload < 0)
- return;
-
-#if 0
- DEBUGP(DMGCP, "Payload hdr payload %u -> endp payload %u\n",
- rtp_hdr->payload_type, payload);
- rtp_hdr->payload_type = payload;
-#endif
-}
-
-/*
- * The below code is for dispatching. We have a dedicated port for
- * the data coming from the net and one to discover the BTS.
- */
-static int forward_data(int fd, struct mgcp_rtp_tap *tap, const char *buf, int len)
-{
- if (!tap->enabled)
- return 0;
-
- return sendto(fd, buf, len, 0,
- (struct sockaddr *)&tap->forward, sizeof(tap->forward));
-}
-
-static int mgcp_send_transcoder(struct mgcp_rtp_end *end,
- struct mgcp_config *cfg, int is_rtp,
- const char *buf, int len)
-{
- int rc;
- int port;
- struct sockaddr_in addr;
-
- port = is_rtp ? end->rtp_port : end->rtcp_port;
-
- addr.sin_family = AF_INET;
- addr.sin_addr = cfg->transcoder_in;
- addr.sin_port = port;
-
- rc = sendto(is_rtp ?
- end->rtp.fd :
- end->rtcp.fd, buf, len, 0,
- (struct sockaddr *) &addr, sizeof(addr));
-
- if (rc != len)
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to send data to the transcoder: %s\n",
- strerror(errno));
-
- return rc;
-}
-
-int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
- struct sockaddr_in *addr, char *buf, int rc)
-{
- struct mgcp_trunk_config *tcfg = endp->tcfg;
- struct mgcp_rtp_end *rtp_end;
- struct mgcp_rtp_state *rtp_state;
- int tap_idx;
-
- LOGP(DMGCP, LOGL_DEBUG,
- "endpoint %x dest %s tcfg->audio_loop %d endp->conn_mode %d (== loopback: %d)\n",
- ENDPOINT_NUMBER(endp),
- dest == MGCP_DEST_NET? "net" : "bts",
- tcfg->audio_loop,
- endp->conn_mode,
- endp->conn_mode == MGCP_CONN_LOOPBACK);
-
- /* For loop toggle the destination and then dispatch. */
- if (tcfg->audio_loop)
- dest = !dest;
-
- /* Loop based on the conn_mode, maybe undoing the above */
- if (endp->conn_mode == MGCP_CONN_LOOPBACK)
- dest = !dest;
-
- if (dest == MGCP_DEST_NET) {
- rtp_end = &endp->net_end;
- rtp_state = &endp->bts_state;
- tap_idx = MGCP_TAP_NET_OUT;
- } else {
- rtp_end = &endp->bts_end;
- rtp_state = &endp->net_state;
- tap_idx = MGCP_TAP_BTS_OUT;
- }
- LOGP(DMGCP, LOGL_DEBUG,
- "endpoint %x dest %s net_end %s %d %d bts_end %s %d %d rtp_end %s %d %d\n",
- ENDPOINT_NUMBER(endp),
- dest == MGCP_DEST_NET? "net" : "bts",
-
- inet_ntoa(endp->net_end.addr),
- ntohs(endp->net_end.rtp_port),
- ntohs(endp->net_end.rtcp_port),
-
- inet_ntoa(endp->bts_end.addr),
- ntohs(endp->bts_end.rtp_port),
- ntohs(endp->bts_end.rtcp_port),
-
- inet_ntoa(rtp_end->addr),
- ntohs(rtp_end->rtp_port),
- ntohs(rtp_end->rtcp_port)
- );
-
- if (!rtp_end->output_enabled) {
- rtp_end->dropped_packets += 1;
- LOGP(DMGCP, LOGL_DEBUG,
- "endpoint %x output disabled, drop to %s %s %d %d\n",
- ENDPOINT_NUMBER(endp),
- dest == MGCP_DEST_NET? "net" : "bts",
- inet_ntoa(rtp_end->addr),
- ntohs(rtp_end->rtp_port),
- ntohs(rtp_end->rtcp_port)
- );
- } else if (is_rtp) {
- int cont;
- int nbytes = 0;
- int len = rc;
- do {
- cont = endp->cfg->rtp_processing_cb(endp, rtp_end,
- buf, &len, RTP_BUF_SIZE);
- if (cont < 0)
- break;
-
- mgcp_patch_and_count(endp, rtp_state, rtp_end, addr, buf, len);
- LOGP(DMGCP, LOGL_DEBUG,
- "endpoint %x process/send to %s %s %d %d\n",
- ENDPOINT_NUMBER(endp),
- (dest == MGCP_DEST_NET)? "net" : "bts",
- inet_ntoa(rtp_end->addr),
- ntohs(rtp_end->rtp_port),
- ntohs(rtp_end->rtcp_port)
- );
- forward_data(rtp_end->rtp.fd, &endp->taps[tap_idx],
- buf, len);
-
- /* FIXME: HACK HACK HACK. See OS#2459.
- * The ip.access nano3G needs the first RTP payload's first two bytes to read hex
- * 'e400', or it will reject the RAB assignment. It seems to not harm other femto
- * cells (as long as we patch only the first RTP payload in each stream).
- */
- if (tap_idx == MGCP_TAP_BTS_OUT
- && !rtp_state->patched_first_rtp_payload) {
- uint8_t *data = (uint8_t*)&buf[12];
- data[0] = 0xe4;
- data[1] = 0x00;
- rtp_state->patched_first_rtp_payload = true;
- }
-
- rc = mgcp_udp_send(rtp_end->rtp.fd,
- &rtp_end->addr,
- rtp_end->rtp_port, buf, len);
-
- if (rc <= 0)
- return rc;
- nbytes += rc;
- len = cont;
- } while (len > 0);
- return nbytes;
- } else if (!tcfg->omit_rtcp) {
- LOGP(DMGCP, LOGL_DEBUG,
- "endpoint %x send to %s %s %d %d\n",
- ENDPOINT_NUMBER(endp),
- dest == MGCP_DEST_NET? "net" : "bts",
- inet_ntoa(rtp_end->addr),
- ntohs(rtp_end->rtp_port),
- ntohs(rtp_end->rtcp_port)
- );
-
- return mgcp_udp_send(rtp_end->rtcp.fd,
- &rtp_end->addr,
- rtp_end->rtcp_port, buf, rc);
- }
-
- return 0;
-}
-
-static int receive_from(struct mgcp_endpoint *endp, int fd, struct sockaddr_in *addr,
- char *buf, int bufsize)
-{
- int rc;
- socklen_t slen = sizeof(*addr);
-
- rc = recvfrom(fd, buf, bufsize, 0,
- (struct sockaddr *) addr, &slen);
- if (rc < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x errno: %d/%s\n",
- ENDPOINT_NUMBER(endp), errno, strerror(errno));
- return -1;
- }
-
- /* do not forward aynthing... maybe there is a packet from the bts */
- if (!endp->allocated)
- return -1;
-
- #warning "Slight spec violation. With connection mode recvonly we should attempt to forward."
-
- return rc;
-}
-
-static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
-{
- char buf[RTP_BUF_SIZE];
- struct sockaddr_in addr;
- struct mgcp_endpoint *endp;
- int rc, proto;
-
- endp = (struct mgcp_endpoint *) fd->data;
-
- rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf));
- if (rc <= 0)
- return -1;
-
- LOGP(DMGCP, LOGL_DEBUG,
- "endpoint %x",
- ENDPOINT_NUMBER(endp));
- LOGPC(DMGCP, LOGL_DEBUG,
- " from net %s %d",
- inet_ntoa(addr.sin_addr),
- ntohs(addr.sin_port));
- LOGPC(DMGCP, LOGL_DEBUG,
- " net_end %s %d %d",
- inet_ntoa(endp->net_end.addr),
- ntohs(endp->net_end.rtp_port),
- ntohs(endp->net_end.rtcp_port));
- LOGPC(DMGCP, LOGL_DEBUG,
- " bts_end %s %d %d\n",
- inet_ntoa(endp->bts_end.addr),
- ntohs(endp->bts_end.rtp_port),
- ntohs(endp->bts_end.rtcp_port)
- );
-
- if (memcmp(&addr.sin_addr, &endp->net_end.addr, sizeof(addr.sin_addr)) != 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "rtp_data_net: Endpoint 0x%x data from wrong address %s vs. ",
- ENDPOINT_NUMBER(endp), inet_ntoa(addr.sin_addr));
- LOGPC(DMGCP, LOGL_ERROR,
- "%s\n", inet_ntoa(endp->net_end.addr));
- return -1;
- }
-
- switch(endp->type) {
- case MGCP_RTP_DEFAULT:
- case MGCP_RTP_TRANSCODED:
- if (endp->net_end.rtp_port != addr.sin_port &&
- endp->net_end.rtcp_port != addr.sin_port) {
- LOGP(DMGCP, LOGL_ERROR,
- "rtp_data_net: Data from wrong source port %d on 0x%x\n",
- ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
- return -1;
- }
- break;
- case MGCP_OSMUX_BSC:
- case MGCP_OSMUX_BSC_NAT:
- break;
- }
-
- LOGP(DMGCP, LOGL_DEBUG,
- "rtp_data_net: Endpoint %x data from %s %d\n",
- ENDPOINT_NUMBER(endp),
- inet_ntoa(addr.sin_addr),
- ntohs(addr.sin_port));
-
- /* throw away the dummy message */
- if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
- LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from network on 0x%x\n",
- ENDPOINT_NUMBER(endp));
- return 0;
- }
-
- proto = fd == &endp->net_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
- endp->net_end.packets += 1;
- endp->net_end.octets += rc;
-
- forward_data(fd->fd, &endp->taps[MGCP_TAP_NET_IN], buf, rc);
-
- switch (endp->type) {
- case MGCP_RTP_DEFAULT:
- return mgcp_send(endp, MGCP_DEST_BTS, proto == MGCP_PROTO_RTP,
- &addr, buf, rc);
- case MGCP_RTP_TRANSCODED:
- return mgcp_send_transcoder(&endp->trans_net, endp->cfg,
- proto == MGCP_PROTO_RTP, buf, rc);
- case MGCP_OSMUX_BSC_NAT:
- return osmux_xfrm_to_osmux(MGCP_DEST_BTS, buf, rc, endp);
- case MGCP_OSMUX_BSC: /* Should not happen */
- break;
- }
-
- LOGP(DMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n",
- endp->type, ENDPOINT_NUMBER(endp));
- return 0;
-}
-
-static void discover_bts(struct mgcp_endpoint *endp, int proto, struct sockaddr_in *addr)
-{
- struct mgcp_config *cfg = endp->cfg;
-
- if (proto == MGCP_PROTO_RTP && endp->bts_end.rtp_port == 0) {
- if (!cfg->bts_ip ||
- memcmp(&addr->sin_addr,
- &cfg->bts_in, sizeof(cfg->bts_in)) == 0 ||
- memcmp(&addr->sin_addr,
- &endp->bts_end.addr, sizeof(endp->bts_end.addr)) == 0) {
-
- endp->bts_end.rtp_port = addr->sin_port;
- endp->bts_end.addr = addr->sin_addr;
-
- LOGP(DMGCP, LOGL_NOTICE,
- "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
- ENDPOINT_NUMBER(endp), ntohs(endp->bts_end.rtp_port),
- ntohs(endp->bts_end.rtcp_port), inet_ntoa(addr->sin_addr));
- }
- } else if (proto == MGCP_PROTO_RTCP && endp->bts_end.rtcp_port == 0) {
- if (memcmp(&endp->bts_end.addr, &addr->sin_addr,
- sizeof(endp->bts_end.addr)) == 0) {
- endp->bts_end.rtcp_port = addr->sin_port;
- }
- }
-}
-
-static int rtp_data_bts(struct osmo_fd *fd, unsigned int what)
-{
- char buf[RTP_BUF_SIZE];
- struct sockaddr_in addr;
- struct mgcp_endpoint *endp;
- int rc, proto;
-
- endp = (struct mgcp_endpoint *) fd->data;
-
- rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf));
- if (rc <= 0)
- return -1;
-
- proto = fd == &endp->bts_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
-
- /* We have no idea who called us, maybe it is the BTS. */
- /* it was the BTS... */
- discover_bts(endp, proto, &addr);
-
- if (memcmp(&endp->bts_end.addr, &addr.sin_addr, sizeof(addr.sin_addr)) != 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "rtp_data_bts: Data from wrong bts %s on 0x%x\n",
- inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(endp));
- return -1;
- }
-
- if (endp->bts_end.rtp_port != addr.sin_port &&
- endp->bts_end.rtcp_port != addr.sin_port) {
- LOGP(DMGCP, LOGL_ERROR,
- "rtp_data_bts: ata from wrong bts source port %d on 0x%x\n",
- ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
- return -1;
- }
-
- LOGP(DMGCP, LOGL_DEBUG,
- "rtp_data_bts: Endpoint %x data from %s %d\n",
- ENDPOINT_NUMBER(endp),
- inet_ntoa(addr.sin_addr),
- ntohs(addr.sin_port));
-
- /* throw away the dummy message */
- if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
- LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from bts on 0x%x\n",
- ENDPOINT_NUMBER(endp));
- return 0;
- }
-
- /* do this before the loop handling */
- endp->bts_end.packets += 1;
- endp->bts_end.octets += rc;
-
- forward_data(fd->fd, &endp->taps[MGCP_TAP_BTS_IN], buf, rc);
-
- switch (endp->type) {
- case MGCP_RTP_DEFAULT:
- LOGP(DMGCP, LOGL_DEBUG,
- "rtp_data_bts: Endpoint %x MGCP_RTP_DEFAULT\n",
- ENDPOINT_NUMBER(endp));
- return mgcp_send(endp, MGCP_DEST_NET, proto == MGCP_PROTO_RTP,
- &addr, buf, rc);
- case MGCP_RTP_TRANSCODED:
- return mgcp_send_transcoder(&endp->trans_bts, endp->cfg,
- proto == MGCP_PROTO_RTP, buf, rc);
- case MGCP_OSMUX_BSC:
- /* OSMUX translation: BTS -> BSC */
- return osmux_xfrm_to_osmux(MGCP_DEST_NET, buf, rc, endp);
- case MGCP_OSMUX_BSC_NAT:
- break; /* Should not happen */
- }
-
- LOGP(DMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n",
- endp->type, ENDPOINT_NUMBER(endp));
- return 0;
-}
-
-static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_endp,
- int dest, struct osmo_fd *fd)
-{
- char buf[RTP_BUF_SIZE];
- struct sockaddr_in addr;
- struct mgcp_config *cfg;
- int rc, proto;
-
- cfg = _endp->cfg;
- rc = receive_from(_endp, fd->fd, &addr, buf, sizeof(buf));
- if (rc <= 0)
- return -1;
-
- proto = fd == &end->rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
-
- if (memcmp(&addr.sin_addr, &cfg->transcoder_in, sizeof(addr.sin_addr)) != 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Data not coming from transcoder dest: %d %s on 0x%x\n",
- dest, inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(_endp));
- return -1;
- }
-
- if (end->rtp_port != addr.sin_port &&
- end->rtcp_port != addr.sin_port) {
- LOGP(DMGCP, LOGL_ERROR,
- "Data from wrong transcoder dest %d source port %d on 0x%x\n",
- dest, ntohs(addr.sin_port), ENDPOINT_NUMBER(_endp));
- return -1;
- }
-
- /* throw away the dummy message */
- if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
- LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from transcoder dest %d on 0x%x\n",
- dest, ENDPOINT_NUMBER(_endp));
- return 0;
- }
-
- end->packets += 1;
- return mgcp_send(_endp, dest, proto == MGCP_PROTO_RTP, &addr, buf, rc);
-}
-
-static int rtp_data_trans_net(struct osmo_fd *fd, unsigned int what)
-{
- struct mgcp_endpoint *endp;
- endp = (struct mgcp_endpoint *) fd->data;
-
- return rtp_data_transcoder(&endp->trans_net, endp, MGCP_DEST_NET, fd);
-}
-
-static int rtp_data_trans_bts(struct osmo_fd *fd, unsigned int what)
-{
- struct mgcp_endpoint *endp;
- endp = (struct mgcp_endpoint *) fd->data;
-
- return rtp_data_transcoder(&endp->trans_bts, endp, MGCP_DEST_BTS, fd);
-}
-
-int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port)
-{
- struct sockaddr_in addr;
- int on = 1;
-
- fd->fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd->fd < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to create UDP port.\n");
- return -1;
- }
-
- setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- inet_aton(source_addr, &addr.sin_addr);
-
- if (bind(fd->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- close(fd->fd);
- fd->fd = -1;
- return -1;
- }
-
- return 0;
-}
-
-int mgcp_set_ip_tos(int fd, int tos)
-{
- int ret;
- ret = setsockopt(fd, IPPROTO_IP, IP_TOS,
- &tos, sizeof(tos));
- return ret != 0;
-}
-
-static int bind_rtp(struct mgcp_config *cfg, const char *source_addr,
- struct mgcp_rtp_end *rtp_end, int endpno)
-{
- if (mgcp_create_bind(source_addr, &rtp_end->rtp,
- rtp_end->local_port) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
- source_addr, rtp_end->local_port, endpno);
- goto cleanup0;
- }
-
- if (mgcp_create_bind(source_addr, &rtp_end->rtcp,
- rtp_end->local_port + 1) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
- source_addr, rtp_end->local_port + 1, endpno);
- goto cleanup1;
- }
-
- 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 = BSC_FD_READ;
- if (osmo_fd_register(&rtp_end->rtp) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
- rtp_end->local_port, endpno);
- goto cleanup2;
- }
-
- rtp_end->rtcp.when = BSC_FD_READ;
- if (osmo_fd_register(&rtp_end->rtcp) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
- rtp_end->local_port + 1, endpno);
- goto cleanup3;
- }
-
- return 0;
-
-cleanup3:
- osmo_fd_unregister(&rtp_end->rtp);
-cleanup2:
- close(rtp_end->rtcp.fd);
- rtp_end->rtcp.fd = -1;
-cleanup1:
- close(rtp_end->rtp.fd);
- rtp_end->rtp.fd = -1;
-cleanup0:
- return -1;
-}
-
-static int int_bind(const char *port,
- struct mgcp_rtp_end *end, int (*cb)(struct osmo_fd *, unsigned),
- struct mgcp_endpoint *_endp,
- const char *source_addr, int rtp_port)
-{
- if (end->rtp.fd != -1 || end->rtcp.fd != -1) {
- LOGP(DMGCP, LOGL_ERROR, "Previous %s was still bound on %d\n",
- port, ENDPOINT_NUMBER(_endp));
- mgcp_free_rtp_port(end);
- }
-
- end->local_port = rtp_port;
- end->rtp.cb = cb;
- end->rtp.data = _endp;
- end->rtcp.data = _endp;
- end->rtcp.cb = cb;
- return bind_rtp(_endp->cfg, source_addr, end, ENDPOINT_NUMBER(_endp));
-}
-
-int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
-{
- return int_bind("bts-port", &endp->bts_end,
- rtp_data_bts, endp,
- mgcp_bts_src_addr(endp), rtp_port);
-}
-
-int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
-{
- return int_bind("net-port", &endp->net_end,
- rtp_data_net, endp,
- mgcp_net_src_addr(endp), rtp_port);
-}
-
-int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
-{
- return int_bind("trans-net", &endp->trans_net,
- rtp_data_trans_net, endp,
- endp->cfg->source_addr, rtp_port);
-}
-
-int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
-{
- return int_bind("trans-bts", &endp->trans_bts,
- rtp_data_trans_bts, endp,
- endp->cfg->source_addr, rtp_port);
-}
-
-int mgcp_free_rtp_port(struct mgcp_rtp_end *end)
-{
- if (end->rtp.fd != -1) {
- close(end->rtp.fd);
- end->rtp.fd = -1;
- osmo_fd_unregister(&end->rtp);
- }
-
- if (end->rtcp.fd != -1) {
- close(end->rtcp.fd);
- end->rtcp.fd = -1;
- osmo_fd_unregister(&end->rtcp);
- }
-
- return 0;
-}
-
-
-void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
- struct mgcp_rtp_end *end, uint32_t *expected,
- int *loss)
-{
- *expected = state->stats_cycles + state->stats_max_seq;
- *expected = *expected - state->stats_base_seq + 1;
-
- if (!state->stats_initialized) {
- *expected = 0;
- *loss = 0;
- return;
- }
-
- /*
- * Make sure the sign is correct and use the biggest
- * positive/negative number that fits.
- */
- *loss = *expected - end->packets;
- if (*expected < end->packets) {
- if (*loss > 0)
- *loss = INT_MIN;
- } else {
- if (*loss < 0)
- *loss = INT_MAX;
- }
-}
-
-uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *state)
-{
- if (!state->stats_initialized)
- return 0;
- return state->stats_jitter >> 4;
-}
diff --git a/src/libmgcp/mgcp_osmux.c b/src/libmgcp/mgcp_osmux.c
deleted file mode 100644
index c52984b32..000000000
--- a/src/libmgcp/mgcp_osmux.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * (C) 2012-2013 by Pablo Neira Ayuso <pablo@gnumonks.org>
- * (C) 2012-2013 by On Waves ehf <http://www.on-waves.com>
- * All rights not specifically granted under this license are 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.
- */
-
-#include <stdio.h> /* for printf */
-#include <string.h> /* for memcpy */
-#include <stdlib.h> /* for abs */
-#include <inttypes.h> /* for PRIu64 */
-#include <netinet/in.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-
-#include <osmocom/netif/osmux.h>
-#include <osmocom/netif/rtp.h>
-
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-#include <openbsc/osmux.h>
-
-static struct osmo_fd osmux_fd;
-
-static LLIST_HEAD(osmux_handle_list);
-
-struct osmux_handle {
- struct llist_head head;
- struct osmux_in_handle *in;
- struct in_addr rem_addr;
- int rem_port;
- int refcnt;
-};
-
-static void *osmux;
-
-static void osmux_deliver(struct msgb *batch_msg, void *data)
-{
- struct osmux_handle *handle = data;
- 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));
- msgb_free(batch_msg);
-}
-
-static struct osmux_handle *
-osmux_handle_find_get(struct in_addr *addr, int rem_port)
-{
- struct osmux_handle *h;
-
- /* Lookup for existing OSMUX handle for this destination address. */
- llist_for_each_entry(h, &osmux_handle_list, head) {
- if (memcmp(&h->rem_addr, addr, sizeof(struct in_addr)) == 0 &&
- h->rem_port == rem_port) {
- LOGP(DMGCP, LOGL_DEBUG, "using existing OSMUX handle "
- "for addr=%s:%d\n",
- inet_ntoa(*addr), ntohs(rem_port));
- h->refcnt++;
- return h;
- }
- }
-
- return NULL;
-}
-
-static void osmux_handle_put(struct osmux_in_handle *in)
-{
- struct osmux_handle *h;
-
- /* Lookup for existing OSMUX handle for this destination address. */
- llist_for_each_entry(h, &osmux_handle_list, head) {
- if (h->in == in) {
- if (--h->refcnt == 0) {
- LOGP(DMGCP, LOGL_INFO,
- "Releasing unused osmux handle for %s:%d\n",
- inet_ntoa(h->rem_addr),
- ntohs(h->rem_port));
- LOGP(DMGCP, LOGL_INFO, "Stats: "
- "input RTP msgs: %u bytes: %"PRIu64" "
- "output osmux msgs: %u bytes: %"PRIu64"\n",
- in->stats.input_rtp_msgs,
- in->stats.input_rtp_bytes,
- in->stats.output_osmux_msgs,
- in->stats.output_osmux_bytes);
- llist_del(&h->head);
- osmux_xfrm_input_fini(h->in);
- talloc_free(h);
- }
- return;
- }
- }
- LOGP(DMGCP, LOGL_ERROR, "cannot find Osmux input handle %p\n", in);
-}
-
-static struct osmux_handle *
-osmux_handle_alloc(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
-{
- struct osmux_handle *h;
-
- h = talloc_zero(osmux, struct osmux_handle);
- if (!h)
- return NULL;
- h->rem_addr = *addr;
- h->rem_port = rem_port;
- h->refcnt++;
-
- h->in = talloc_zero(h, struct osmux_in_handle);
- if (!h->in) {
- talloc_free(h);
- return NULL;
- }
-
- h->in->osmux_seq = 0; /* sequence number to start OSmux message from */
- h->in->batch_factor = cfg->osmux_batch;
- /* If batch size is zero, the library defaults to 1470 bytes. */
- h->in->batch_size = cfg->osmux_batch_size;
- h->in->deliver = osmux_deliver;
- osmux_xfrm_input_init(h->in);
- h->in->data = h;
-
- llist_add(&h->head, &osmux_handle_list);
-
- LOGP(DMGCP, LOGL_DEBUG, "created new OSMUX handle for addr=%s:%d\n",
- inet_ntoa(*addr), ntohs(rem_port));
-
- return h;
-}
-
-static struct osmux_in_handle *
-osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
-{
- struct osmux_handle *h;
-
- h = osmux_handle_find_get(addr, rem_port);
- if (h != NULL)
- return h->in;
-
- h = osmux_handle_alloc(cfg, addr, rem_port);
- if (h == NULL)
- return NULL;
-
- return h->in;
-}
-
-int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp)
-{
- int ret;
- struct msgb *msg;
-
- msg = msgb_alloc(4096, "RTP");
- if (!msg)
- return 0;
-
- memcpy(msg->data, buf, rc);
- msgb_put(msg, rc);
-
- while ((ret = osmux_xfrm_input(endp->osmux.in, msg, endp->osmux.cid)) > 0) {
- /* batch full, build and deliver it */
- osmux_xfrm_input_deliver(endp->osmux.in);
- }
- return 0;
-}
-
-static struct mgcp_endpoint *
-endpoint_lookup(struct mgcp_config *cfg, int cid,
- struct in_addr *from_addr, int type)
-{
- struct mgcp_endpoint *tmp = NULL;
- int i;
-
- /* Lookup for the endpoint that corresponds to this port */
- for (i=0; i<cfg->trunk.number_endpoints; i++) {
- struct in_addr *this;
-
- tmp = &cfg->trunk.endpoints[i];
-
- if (!tmp->allocated)
- continue;
-
- switch(type) {
- case MGCP_DEST_NET:
- this = &tmp->net_end.addr;
- break;
- case MGCP_DEST_BTS:
- this = &tmp->bts_end.addr;
- break;
- default:
- /* Should not ever happen */
- LOGP(DMGCP, LOGL_ERROR, "Bad type %d. Fix your code.\n", type);
- return NULL;
- }
-
- if (tmp->osmux.cid == cid && this->s_addr == from_addr->s_addr)
- return tmp;
- }
-
- LOGP(DMGCP, LOGL_ERROR, "Cannot find endpoint with cid=%d\n", cid);
-
- return NULL;
-}
-
-static void scheduled_tx_net_cb(struct msgb *msg, void *data)
-{
- struct mgcp_endpoint *endp = data;
- struct sockaddr_in addr = {
- .sin_addr = endp->net_end.addr,
- .sin_port = endp->net_end.rtp_port,
- };
-
- endp->bts_end.octets += msg->len;
- endp->bts_end.packets++;
-
- mgcp_send(endp, MGCP_DEST_NET, 1, &addr, (char *)msg->data, msg->len);
- msgb_free(msg);
-}
-
-static void scheduled_tx_bts_cb(struct msgb *msg, void *data)
-{
- struct mgcp_endpoint *endp = data;
- struct sockaddr_in addr = {
- .sin_addr = endp->bts_end.addr,
- .sin_port = endp->bts_end.rtp_port,
- };
-
- endp->net_end.octets += msg->len;
- endp->net_end.packets++;
-
- mgcp_send(endp, MGCP_DEST_BTS, 1, &addr, (char *)msg->data, msg->len);
- msgb_free(msg);
-}
-
-static struct msgb *osmux_recv(struct osmo_fd *ofd, struct sockaddr_in *addr)
-{
- struct msgb *msg;
- socklen_t slen = sizeof(*addr);
- int ret;
-
- msg = msgb_alloc(4096, "OSMUX");
- if (!msg) {
- LOGP(DMGCP, LOGL_ERROR, "cannot allocate message\n");
- return NULL;
- }
- ret = recvfrom(ofd->fd, msg->data, msg->data_len, 0,
- (struct sockaddr *)addr, &slen);
- if (ret <= 0) {
- msgb_free(msg);
- LOGP(DMGCP, LOGL_ERROR, "cannot receive message\n");
- return NULL;
- }
- msgb_put(msg, ret);
-
- return msg;
-}
-
-#define osmux_chunk_length(msg, rem) (rem - msg->len);
-
-int osmux_read_from_bsc_nat_cb(struct osmo_fd *ofd, unsigned int what)
-{
- struct msgb *msg;
- struct osmux_hdr *osmuxh;
- struct llist_head list;
- struct sockaddr_in addr;
- struct mgcp_config *cfg = ofd->data;
- uint32_t rem;
-
- msg = osmux_recv(ofd, &addr);
- if (!msg)
- return -1;
-
- /* not any further processing dummy messages */
- if (msg->data[0] == MGCP_DUMMY_LOAD)
- goto out;
-
- rem = msg->len;
- while((osmuxh = osmux_xfrm_output_pull(msg)) != NULL) {
- struct mgcp_endpoint *endp;
-
- /* Yes, we use MGCP_DEST_NET to locate the origin */
- endp = endpoint_lookup(cfg, osmuxh->circuit_id,
- &addr.sin_addr, MGCP_DEST_NET);
- if (!endp) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot find an endpoint for circuit_id=%d\n",
- osmuxh->circuit_id);
- goto out;
- }
- endp->osmux.stats.octets += osmux_chunk_length(msg, rem);
- endp->osmux.stats.chunks++;
- rem = msg->len;
-
- osmux_xfrm_output(osmuxh, &endp->osmux.out, &list);
- osmux_tx_sched(&list, scheduled_tx_bts_cb, endp);
- }
-out:
- msgb_free(msg);
- return 0;
-}
-
-/* This is called from the bsc-nat */
-static int osmux_handle_dummy(struct mgcp_config *cfg, struct sockaddr_in *addr,
- struct msgb *msg)
-{
- struct mgcp_endpoint *endp;
- uint8_t osmux_cid;
-
- if (msg->len < 1 + sizeof(osmux_cid)) {
- LOGP(DMGCP, LOGL_ERROR,
- "Discarding truncated Osmux dummy load\n");
- goto out;
- }
-
- LOGP(DMGCP, LOGL_DEBUG, "Received Osmux dummy load from %s\n",
- inet_ntoa(addr->sin_addr));
-
- if (!cfg->osmux) {
- LOGP(DMGCP, LOGL_ERROR,
- "bsc wants to use Osmux but bsc-nat did not request it\n");
- goto out;
- }
-
- /* extract the osmux CID from the dummy message */
- memcpy(&osmux_cid, &msg->data[1], sizeof(osmux_cid));
-
- endp = endpoint_lookup(cfg, osmux_cid, &addr->sin_addr, MGCP_DEST_BTS);
- if (!endp) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot find endpoint for Osmux CID %d\n", osmux_cid);
- goto out;
- }
-
- if (endp->osmux.state == OSMUX_STATE_ENABLED)
- goto out;
-
- if (osmux_enable_endpoint(endp, &addr->sin_addr, addr->sin_port) < 0 ) {
- LOGP(DMGCP, LOGL_ERROR,
- "Could not enable osmux in endpoint %d\n",
- ENDPOINT_NUMBER(endp));
- goto out;
- }
-
- LOGP(DMGCP, LOGL_INFO, "Enabling osmux in endpoint %d for %s:%u\n",
- ENDPOINT_NUMBER(endp), inet_ntoa(addr->sin_addr),
- ntohs(addr->sin_port));
-out:
- msgb_free(msg);
- return 0;
-}
-
-int osmux_read_from_bsc_cb(struct osmo_fd *ofd, unsigned int what)
-{
- struct msgb *msg;
- struct osmux_hdr *osmuxh;
- struct llist_head list;
- struct sockaddr_in addr;
- struct mgcp_config *cfg = ofd->data;
- uint32_t rem;
-
- msg = osmux_recv(ofd, &addr);
- if (!msg)
- return -1;
-
- /* not any further processing dummy messages */
- if (msg->data[0] == MGCP_DUMMY_LOAD)
- return osmux_handle_dummy(cfg, &addr, msg);
-
- rem = msg->len;
- while((osmuxh = osmux_xfrm_output_pull(msg)) != NULL) {
- struct mgcp_endpoint *endp;
-
- /* Yes, we use MGCP_DEST_BTS to locate the origin */
- endp = endpoint_lookup(cfg, osmuxh->circuit_id,
- &addr.sin_addr, MGCP_DEST_BTS);
- if (!endp) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot find an endpoint for circuit_id=%d\n",
- osmuxh->circuit_id);
- goto out;
- }
- endp->osmux.stats.octets += osmux_chunk_length(msg, rem);
- endp->osmux.stats.chunks++;
- rem = msg->len;
-
- osmux_xfrm_output(osmuxh, &endp->osmux.out, &list);
- osmux_tx_sched(&list, scheduled_tx_net_cb, endp);
- }
-out:
- msgb_free(msg);
- return 0;
-}
-
-int osmux_init(int role, struct mgcp_config *cfg)
-{
- int ret;
-
- switch(role) {
- case OSMUX_ROLE_BSC:
- osmux_fd.cb = osmux_read_from_bsc_nat_cb;
- break;
- case OSMUX_ROLE_BSC_NAT:
- osmux_fd.cb = osmux_read_from_bsc_cb;
- break;
- default:
- LOGP(DMGCP, LOGL_ERROR, "wrong role for OSMUX\n");
- return -1;
- }
- osmux_fd.data = cfg;
-
- ret = mgcp_create_bind(cfg->osmux_addr, &osmux_fd, cfg->osmux_port);
- if (ret < 0) {
- LOGP(DMGCP, LOGL_ERROR, "cannot bind OSMUX socket\n");
- return ret;
- }
- mgcp_set_ip_tos(osmux_fd.fd, cfg->endp_dscp);
- osmux_fd.when |= BSC_FD_READ;
-
- ret = osmo_fd_register(&osmux_fd);
- if (ret < 0) {
- LOGP(DMGCP, LOGL_ERROR, "cannot register OSMUX socket\n");
- return ret;
- }
- cfg->osmux_init = 1;
-
- return 0;
-}
-
-int osmux_enable_endpoint(struct mgcp_endpoint *endp, 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
- * allocated based on the circuit ID (endp->osmux.cid), which is unique
- * in the local scope to the BSC/BSC-NAT. We use it to divide the RTP
- * SSRC space (2^32) by the 256 possible circuit IDs, then randomly
- * select one value from that window. Thus, we have no chance to have
- * overlapping RTP SSRC traveling to the BTSes behind the BSC,
- * similarly, for flows traveling to the MSC.
- */
- static const uint32_t rtp_ssrc_winlen = UINT32_MAX / 256;
-
- if (endp->osmux.state == OSMUX_STATE_DISABLED) {
- LOGP(DMGCP, LOGL_ERROR, "Endpoint %u didn't request Osmux\n",
- ENDPOINT_NUMBER(endp));
- return -1;
- }
-
- osmux_xfrm_output_init(&endp->osmux.out,
- (endp->osmux.cid * rtp_ssrc_winlen) +
- (random() % rtp_ssrc_winlen));
-
- endp->osmux.in = osmux_handle_lookup(endp->cfg, addr, port);
- if (!endp->osmux.in) {
- LOGP(DMGCP, LOGL_ERROR, "Cannot allocate input osmux handle\n");
- return -1;
- }
- if (!osmux_xfrm_input_open_circuit(endp->osmux.in, endp->osmux.cid,
- endp->cfg->osmux_dummy)) {
- LOGP(DMGCP, LOGL_ERROR, "Cannot open osmux circuit %u\n",
- endp->osmux.cid);
- return -1;
- }
-
- switch (endp->cfg->role) {
- case MGCP_BSC_NAT:
- endp->type = MGCP_OSMUX_BSC_NAT;
- break;
- case MGCP_BSC:
- endp->type = MGCP_OSMUX_BSC;
- break;
- }
- endp->osmux.state = OSMUX_STATE_ENABLED;
-
- return 0;
-}
-
-void osmux_disable_endpoint(struct mgcp_endpoint *endp)
-{
- LOGP(DMGCP, LOGL_INFO, "Releasing endpoint %u using Osmux CID %u\n",
- ENDPOINT_NUMBER(endp), endp->osmux.cid);
- osmux_xfrm_input_close_circuit(endp->osmux.in, endp->osmux.cid);
- endp->osmux.state = OSMUX_STATE_DISABLED;
- endp->osmux.cid = -1;
- osmux_handle_put(endp->osmux.in);
-}
-
-void osmux_release_cid(struct mgcp_endpoint *endp)
-{
- if (endp->osmux.allocated_cid >= 0)
- osmux_put_cid(endp->osmux.allocated_cid);
- endp->osmux.allocated_cid = -1;
-}
-
-void osmux_allocate_cid(struct mgcp_endpoint *endp)
-{
- osmux_release_cid(endp);
- endp->osmux.allocated_cid = osmux_get_cid();
-}
-
-/* We don't need to send the dummy load for osmux so often as another endpoint
- * may have already punched the hole in the firewall. This approach is simple
- * though.
- */
-int osmux_send_dummy(struct mgcp_endpoint *endp)
-{
- char buf[1 + sizeof(uint8_t)];
- struct in_addr addr_unset = {};
-
- buf[0] = MGCP_DUMMY_LOAD;
- memcpy(&buf[1], &endp->osmux.cid, sizeof(endp->osmux.cid));
-
- /* Wait until we have the connection information from MDCX */
- if (memcmp(&endp->net_end.addr, &addr_unset, sizeof(addr_unset)) == 0)
- return 0;
-
- if (endp->osmux.state == OSMUX_STATE_ACTIVATING) {
- if (osmux_enable_endpoint(endp, &endp->net_end.addr,
- htons(endp->cfg->osmux_port)) < 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Could not activate osmux in endpoint %d\n",
- ENDPOINT_NUMBER(endp));
- }
- LOGP(DMGCP, LOGL_ERROR,
- "Osmux CID %u for %s:%u is now enabled\n",
- endp->osmux.cid, inet_ntoa(endp->net_end.addr),
- endp->cfg->osmux_port);
- }
- LOGP(DMGCP, LOGL_DEBUG,
- "sending OSMUX dummy load to %s CID %u\n",
- inet_ntoa(endp->net_end.addr), endp->osmux.cid);
-
- return mgcp_udp_send(osmux_fd.fd, &endp->net_end.addr,
- htons(endp->cfg->osmux_port), buf, sizeof(buf));
-}
-
-/* bsc-nat allocates/releases the Osmux circuit ID */
-static uint8_t osmux_cid_bitmap[(OSMUX_CID_MAX + 1) / 8];
-
-int osmux_used_cid(void)
-{
- int i, j, used = 0;
-
- for (i = 0; i < sizeof(osmux_cid_bitmap); i++) {
- for (j = 0; j < 8; j++) {
- if (osmux_cid_bitmap[i] & (1 << j))
- used += 1;
- }
- }
-
- return used;
-}
-
-int osmux_get_cid(void)
-{
- int i, j;
-
- for (i = 0; i < sizeof(osmux_cid_bitmap); i++) {
- for (j = 0; j < 8; j++) {
- if (osmux_cid_bitmap[i] & (1 << j))
- continue;
-
- osmux_cid_bitmap[i] |= (1 << j);
- LOGP(DMGCP, LOGL_DEBUG,
- "Allocating Osmux CID %u from pool\n", (i * 8) + j);
- return (i * 8) + j;
- }
- }
-
- LOGP(DMGCP, LOGL_ERROR, "All Osmux circuits are in use!\n");
- return -1;
-}
-
-void osmux_put_cid(uint8_t osmux_cid)
-{
- LOGP(DMGCP, LOGL_DEBUG, "Osmux CID %u is back to the pool\n", osmux_cid);
- osmux_cid_bitmap[osmux_cid / 8] &= ~(1 << (osmux_cid % 8));
-}
diff --git a/src/libmgcp/mgcp_protocol.c b/src/libmgcp/mgcp_protocol.c
deleted file mode 100644
index c8b6e8660..000000000
--- a/src/libmgcp/mgcp_protocol.c
+++ /dev/null
@@ -1,1639 +0,0 @@
-/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
-/* The protocol implementation */
-
-/*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
- * 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 <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-
-#define for_each_non_empty_line(line, save) \
- for (line = strtok_r(NULL, "\r\n", &save); line;\
- line = strtok_r(NULL, "\r\n", &save))
-
-
-static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end);
-
-struct mgcp_request {
- char *name;
- struct msgb *(*handle_request) (struct mgcp_parse_data *data);
- char *debug_name;
-};
-
-#define MGCP_REQUEST(NAME, REQ, DEBUG_NAME) \
- { .name = NAME, .handle_request = REQ, .debug_name = DEBUG_NAME },
-
-static struct msgb *handle_audit_endpoint(struct mgcp_parse_data *data);
-static struct msgb *handle_create_con(struct mgcp_parse_data *data);
-static struct msgb *handle_delete_con(struct mgcp_parse_data *data);
-static struct msgb *handle_modify_con(struct mgcp_parse_data *data);
-static struct msgb *handle_rsip(struct mgcp_parse_data *data);
-static struct msgb *handle_noti_req(struct mgcp_parse_data *data);
-
-static void create_transcoder(struct mgcp_endpoint *endp);
-static void delete_transcoder(struct mgcp_endpoint *endp);
-
-static int setup_rtp_processing(struct mgcp_endpoint *endp);
-
-static int mgcp_analyze_header(struct mgcp_parse_data *parse, char *data);
-
-/* Display an mgcp message on the log output */
-void display_mgcp_message(unsigned char *message, unsigned int len,
- char *preamble)
-{
- unsigned char line[80];
- unsigned char *ptr;
- unsigned int consumed = 0;
- unsigned int consumed_line = 0;
- unsigned int line_count = 0;
-
- if (!log_check_level(DMGCP, LOGL_DEBUG))
- return;
-
- while (1) {
- memset(line, 0, sizeof(line));
- ptr = line;
- consumed_line = 0;
- do {
- if (*message != '\n' && *message != '\r') {
- *ptr = *message;
- ptr++;
- }
- message++;
- consumed++;
- consumed_line++;
- } while (*message != '\n' && consumed < len
- && consumed_line < sizeof(line));
-
- if (strlen((const char *)line)) {
- LOGP(DMGCP, LOGL_DEBUG, "%s: line #%02u: %s\n",
- preamble, line_count, line);
- line_count++;
- }
-
- if (consumed >= len)
- return;
- }
-}
-
-static int mgcp_check_param(const struct mgcp_endpoint *endp, const char *line)
-{
- const size_t line_len = strlen(line);
- if (line[0] != '\0' && line_len < 2) {
- LOGP(DMGCP, LOGL_ERROR,
- "Wrong MGCP option format: '%s' on 0x%x\n",
- line, ENDPOINT_NUMBER(endp));
- return 0;
- }
-
- return 1;
-}
-
-static uint32_t generate_call_id(struct mgcp_config *cfg)
-{
- int i;
-
- /* use the call id */
- ++cfg->last_call_id;
-
- /* handle wrap around */
- if (cfg->last_call_id == CI_UNUSED)
- ++cfg->last_call_id;
-
- /* callstack can only be of size number_of_endpoints */
- /* verify that the call id is free, e.g. in case of overrun */
- for (i = 1; i < cfg->trunk.number_endpoints; ++i)
- if (cfg->trunk.endpoints[i].ci == cfg->last_call_id)
- return generate_call_id(cfg);
-
- return cfg->last_call_id;
-}
-
-/*
- * array of function pointers for handling various
- * messages. In the future this might be binary sorted
- * for performance reasons.
- */
-static const struct mgcp_request mgcp_requests [] = {
- MGCP_REQUEST("AUEP", handle_audit_endpoint, "AuditEndpoint")
- MGCP_REQUEST("CRCX", handle_create_con, "CreateConnection")
- MGCP_REQUEST("DLCX", handle_delete_con, "DeleteConnection")
- MGCP_REQUEST("MDCX", handle_modify_con, "ModifiyConnection")
- MGCP_REQUEST("RQNT", handle_noti_req, "NotificationRequest")
-
- /* SPEC extension */
- MGCP_REQUEST("RSIP", handle_rsip, "ReSetInProgress")
-};
-
-static struct msgb *mgcp_msgb_alloc(void)
-{
- struct msgb *msg;
- msg = msgb_alloc_headroom(4096, 128, "MGCP msg");
- if (!msg)
- LOGP(DMGCP, LOGL_ERROR, "Failed to msgb for MGCP data.\n");
-
- return msg;
-}
-
-static struct msgb *do_retransmission(const struct mgcp_endpoint *endp)
-{
- struct msgb *msg = mgcp_msgb_alloc();
- if (!msg)
- return NULL;
-
- msg->l2h = msgb_put(msg, strlen(endp->last_response));
- memcpy(msg->l2h, endp->last_response, msgb_l2len(msg));
- return msg;
-}
-
-static struct msgb *create_resp(struct mgcp_endpoint *endp, int code,
- const char *txt, const char *msg,
- const char *trans, const char *param,
- const char *sdp)
-{
- int len;
- struct msgb *res;
-
- res = mgcp_msgb_alloc();
- if (!res)
- return NULL;
-
- len = snprintf((char *) res->data, 2048, "%d %s%s%s\r\n%s",
- code, trans, txt, param ? param : "", sdp ? sdp : "");
- if (len < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to sprintf MGCP response.\n");
- msgb_free(res);
- return NULL;
- }
-
- res->l2h = msgb_put(res, len);
- LOGP(DMGCP, LOGL_DEBUG, "Generated response: code=%d\n", code);
- display_mgcp_message(res->l2h, msgb_l2len(res), "Generated response");
-
- /*
- * Remember the last transmission per endpoint.
- */
- if (endp) {
- struct mgcp_trunk_config *tcfg = endp->tcfg;
- talloc_free(endp->last_response);
- talloc_free(endp->last_trans);
- endp->last_trans = talloc_strdup(tcfg->endpoints, trans);
- endp->last_response = talloc_strndup(tcfg->endpoints,
- (const char *) res->l2h,
- msgb_l2len(res));
- }
-
- return res;
-}
-
-static struct msgb *create_ok_resp_with_param(struct mgcp_endpoint *endp,
- int code, const char *msg,
- const char *trans, const char *param)
-{
- return create_resp(endp, code, " OK", msg, trans, param, NULL);
-}
-
-static struct msgb *create_ok_response(struct mgcp_endpoint *endp,
- int code, const char *msg, const char *trans)
-{
- return create_ok_resp_with_param(endp, code, msg, trans, NULL);
-}
-
-static struct msgb *create_err_response(struct mgcp_endpoint *endp,
- int code, const char *msg, const char *trans)
-{
- return create_resp(endp, code, " FAIL", msg, trans, NULL, NULL);
-}
-
-static int write_response_sdp(struct mgcp_endpoint *endp,
- char *sdp_record, size_t size, const char *addr)
-{
- const char *fmtp_extra;
- const char *audio_name;
- int payload_type;
- int len;
- int nchars;
-
- endp->cfg->get_net_downlink_format_cb(endp, &payload_type,
- &audio_name, &fmtp_extra);
-
- len = snprintf(sdp_record, size,
- "v=0\r\n"
- "o=- %u 23 IN IP4 %s\r\n"
- "s=-\r\n"
- "c=IN IP4 %s\r\n"
- "t=0 0\r\n",
- endp->ci, addr, addr);
-
- if (len < 0 || len >= size)
- goto buffer_too_small;
-
- if (payload_type >= 0) {
- nchars = snprintf(sdp_record + len, size - len,
- "m=audio %d RTP/AVP %d\r\n",
- endp->net_end.local_port, payload_type);
- if (nchars < 0 || nchars >= size - len)
- goto buffer_too_small;
-
- len += nchars;
-
- if (audio_name && endp->tcfg->audio_send_name) {
- nchars = snprintf(sdp_record + len, size - len,
- "a=rtpmap:%d %s\r\n",
- payload_type, audio_name);
-
- if (nchars < 0 || nchars >= size - len)
- goto buffer_too_small;
-
- len += nchars;
- }
-
- if (fmtp_extra) {
- nchars = snprintf(sdp_record + len, size - len,
- "%s\r\n", fmtp_extra);
-
- if (nchars < 0 || nchars >= size - len)
- goto buffer_too_small;
-
- len += nchars;
- }
- }
- if (endp->bts_end.packet_duration_ms > 0 && endp->tcfg->audio_send_ptime) {
- nchars = snprintf(sdp_record + len, size - len,
- "a=ptime:%d\r\n",
- endp->bts_end.packet_duration_ms);
- if (nchars < 0 || nchars >= size - len)
- goto buffer_too_small;
-
- len += nchars;
- }
-
- return len;
-
-buffer_too_small:
- LOGP(DMGCP, LOGL_ERROR, "SDP buffer too small: %zu (needed %d)\n",
- size, len);
- return -1;
-}
-
-static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
- const char *msg, const char *trans_id)
-{
- const char *addr = endp->cfg->local_ip;
- char sdp_record[4096];
- int len;
- int nchars;
- char osmux_extension[strlen("\nX-Osmux: 255") + 1];
-
- if (!addr)
- addr = mgcp_net_src_addr(endp);
-
- if (endp->osmux.state == OSMUX_STATE_NEGOTIATING) {
- sprintf(osmux_extension, "\nX-Osmux: %u", endp->osmux.cid);
- endp->osmux.state = OSMUX_STATE_ACTIVATING;
- } else {
- osmux_extension[0] = '\0';
- }
-
- len = snprintf(sdp_record, sizeof(sdp_record),
- "I: %u%s\n\n", endp->ci, osmux_extension);
- if (len < 0)
- return NULL;
-
- nchars = write_response_sdp(endp, sdp_record + len,
- sizeof(sdp_record) - len - 1, addr);
- if (nchars < 0)
- return NULL;
-
- len += nchars;
-
- sdp_record[sizeof(sdp_record) - 1] = '\0';
-
- return create_resp(endp, 200, " OK", msg, trans_id, NULL, sdp_record);
-}
-
-static void send_dummy(struct mgcp_endpoint *endp)
-{
- if (endp->osmux.state != OSMUX_STATE_DISABLED)
- osmux_send_dummy(endp);
- else
- mgcp_send_dummy(endp);
-}
-
-/*
- * handle incoming messages:
- * - this can be a command (four letters, space, transaction id)
- * - or a response (three numbers, space, transaction id)
- */
-struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg)
-{
- struct mgcp_parse_data pdata;
- int i, code, handled = 0;
- struct msgb *resp = NULL;
- char *data;
-
- if (msgb_l2len(msg) < 4) {
- LOGP(DMGCP, LOGL_ERROR, "msg too short: %d\n", msg->len);
- return NULL;
- }
-
- if (mgcp_msg_terminate_nul(msg))
- return NULL;
-
- display_mgcp_message(msg->l2h, msgb_l2len(msg), "Received message");
-
- /* attempt to treat it as a response */
- if (sscanf((const char *)&msg->l2h[0], "%3d %*s", &code) == 1) {
- LOGP(DMGCP, LOGL_DEBUG, "Response: Code: %d\n", code);
- return NULL;
- }
-
- msg->l3h = &msg->l2h[4];
-
-
- /*
- * Check for a duplicate message and respond.
- */
- memset(&pdata, 0, sizeof(pdata));
- pdata.cfg = cfg;
- data = strline_r((char *) msg->l3h, &pdata.save);
- pdata.found = mgcp_analyze_header(&pdata, data);
- if (pdata.endp && pdata.trans
- && pdata.endp->last_trans
- && strcmp(pdata.endp->last_trans, pdata.trans) == 0) {
- return do_retransmission(pdata.endp);
- }
-
- for (i = 0; i < ARRAY_SIZE(mgcp_requests); ++i) {
- if (strncmp(mgcp_requests[i].name, (const char *) &msg->l2h[0], 4) == 0) {
- handled = 1;
- resp = mgcp_requests[i].handle_request(&pdata);
- break;
- }
- }
-
- if (!handled)
- LOGP(DMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n", &msg->l2h[0]);
-
- return resp;
-}
-
-/**
- * We have a null terminated string with the endpoint name here. We only
- * support two kinds. Simple ones as seen on the BSC level and the ones
- * seen on the trunk side.
- */
-static struct mgcp_endpoint *find_e1_endpoint(struct mgcp_config *cfg,
- const char *mgcp)
-{
- char *rest = NULL;
- struct mgcp_trunk_config *tcfg;
- int trunk, endp;
-
- trunk = strtoul(mgcp + 6, &rest, 10);
- if (rest == NULL || rest[0] != '/' || trunk < 1) {
- LOGP(DMGCP, LOGL_ERROR, "Wrong trunk name '%s'\n", mgcp);
- return NULL;
- }
-
- endp = strtoul(rest + 1, &rest, 10);
- if (rest == NULL || rest[0] != '@') {
- LOGP(DMGCP, LOGL_ERROR, "Wrong endpoint name '%s'\n", mgcp);
- return NULL;
- }
-
- /* signalling is on timeslot 1 */
- if (endp == 1)
- return NULL;
-
- tcfg = mgcp_trunk_num(cfg, trunk);
- if (!tcfg) {
- LOGP(DMGCP, LOGL_ERROR, "The trunk %d is not declared.\n", trunk);
- return NULL;
- }
-
- if (!tcfg->endpoints) {
- LOGP(DMGCP, LOGL_ERROR, "Endpoints of trunk %d not allocated.\n", trunk);
- return NULL;
- }
-
- if (endp < 1 || endp >= tcfg->number_endpoints) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to find endpoint '%s'\n", mgcp);
- return NULL;
- }
-
- return &tcfg->endpoints[endp];
-}
-
-static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *mgcp)
-{
- char *endptr = NULL;
- unsigned int gw = INT_MAX;
-
- if (strncmp(mgcp, "ds/e1", 5) == 0)
- return find_e1_endpoint(cfg, mgcp);
-
- gw = strtoul(mgcp, &endptr, 16);
- if (gw > 0 && gw < cfg->trunk.number_endpoints && endptr[0] == '@')
- return &cfg->trunk.endpoints[gw];
-
- LOGP(DMGCP, LOGL_ERROR, "Not able to find the endpoint: '%s'\n", mgcp);
- return NULL;
-}
-
-/**
- * @returns 0 when the status line was complete and transaction_id and
- * endp out parameters are set.
- */
-static int mgcp_analyze_header(struct mgcp_parse_data *pdata, char *data)
-{
- int i = 0;
- char *elem, *save = NULL;
-
- OSMO_ASSERT(data);
- pdata->trans = "000000";
-
- for (elem = strtok_r(data, " ", &save); elem;
- elem = strtok_r(NULL, " ", &save)) {
- switch (i) {
- case 0:
- pdata->trans = elem;
- break;
- case 1:
- pdata->endp = find_endpoint(pdata->cfg, elem);
- if (!pdata->endp) {
- LOGP(DMGCP, LOGL_ERROR,
- "Unable to find Endpoint `%s'\n", elem);
- return -1;
- }
- break;
- case 2:
- if (strcmp("MGCP", elem)) {
- LOGP(DMGCP, LOGL_ERROR,
- "MGCP header parsing error\n");
- return -1;
- }
- break;
- case 3:
- if (strcmp("1.0", elem)) {
- LOGP(DMGCP, LOGL_ERROR, "MGCP version `%s' "
- "not supported\n", elem);
- return -1;
- }
- break;
- }
- i++;
- }
-
- if (i != 4) {
- LOGP(DMGCP, LOGL_ERROR, "MGCP status line too short.\n");
- pdata->trans = "000000";
- pdata->endp = NULL;
- return -1;
- }
-
- return 0;
-}
-
-static int verify_call_id(const struct mgcp_endpoint *endp,
- const char *callid)
-{
- if (strcmp(endp->callid, callid) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "CallIDs does not match on 0x%x. '%s' != '%s'\n",
- ENDPOINT_NUMBER(endp), endp->callid, callid);
- return -1;
- }
-
- return 0;
-}
-
-static int verify_ci(const struct mgcp_endpoint *endp,
- const char *_ci)
-{
- uint32_t ci = strtoul(_ci, NULL, 10);
-
- if (ci != endp->ci) {
- LOGP(DMGCP, LOGL_ERROR, "ConnectionIdentifiers do not match on 0x%x. %u != %s\n",
- ENDPOINT_NUMBER(endp), endp->ci, _ci);
- return -1;
- }
-
- return 0;
-}
-
-static struct msgb *handle_audit_endpoint(struct mgcp_parse_data *p)
-{
- if (p->found != 0)
- return create_err_response(NULL, 500, "AUEP", p->trans);
- else
- return create_ok_response(p->endp, 200, "AUEP", p->trans);
-}
-
-static int parse_conn_mode(const char *msg, struct mgcp_endpoint *endp)
-{
- int ret = 0;
- if (strcmp(msg, "recvonly") == 0)
- endp->conn_mode = MGCP_CONN_RECV_ONLY;
- else if (strcmp(msg, "sendrecv") == 0)
- endp->conn_mode = MGCP_CONN_RECV_SEND;
- else if (strcmp(msg, "sendonly") == 0)
- endp->conn_mode = MGCP_CONN_SEND_ONLY;
- else if (strcmp(msg, "loopback") == 0)
- endp->conn_mode = MGCP_CONN_LOOPBACK;
- else {
- LOGP(DMGCP, LOGL_ERROR, "Unknown connection mode: '%s'\n", msg);
- ret = -1;
- }
-
- endp->net_end.output_enabled =
- endp->conn_mode & MGCP_CONN_SEND_ONLY ? 1 : 0;
- endp->bts_end.output_enabled =
- endp->conn_mode & MGCP_CONN_RECV_ONLY ? 1 : 0;
-
- LOGP(DMGCP, LOGL_DEBUG, "endpoint %x connection mode '%s' %d output_enabled net %d bts %d\n",
- ENDPOINT_NUMBER(endp),
- msg, endp->conn_mode, endp->net_end.output_enabled,
- endp->bts_end.output_enabled);
-
- return ret;
-}
-
-static int allocate_port(struct mgcp_endpoint *endp, struct mgcp_rtp_end *end,
- struct mgcp_port_range *range,
- int (*alloc)(struct mgcp_endpoint *endp, int port))
-{
- int i;
-
- if (range->mode == PORT_ALLOC_STATIC) {
- end->local_alloc = PORT_ALLOC_STATIC;
- return 0;
- }
-
- /* attempt to find a port */
- for (i = 0; i < 200; ++i) {
- int rc;
-
- if (range->last_port >= range->range_end)
- range->last_port = range->range_start;
-
- rc = alloc(endp, range->last_port);
-
- range->last_port += 2;
- if (rc == 0) {
- end->local_alloc = PORT_ALLOC_DYNAMIC;
- return 0;
- }
-
- }
-
- LOGP(DMGCP, LOGL_ERROR, "Allocating a RTP/RTCP port failed 200 times 0x%x.\n",
- ENDPOINT_NUMBER(endp));
- return -1;
-}
-
-static int allocate_ports(struct mgcp_endpoint *endp)
-{
- if (allocate_port(endp, &endp->net_end, &endp->cfg->net_ports,
- mgcp_bind_net_rtp_port) != 0)
- return -1;
-
- if (allocate_port(endp, &endp->bts_end, &endp->cfg->bts_ports,
- mgcp_bind_bts_rtp_port) != 0) {
- mgcp_rtp_end_reset(&endp->net_end);
- return -1;
- }
-
- if (endp->cfg->transcoder_ip && endp->tcfg->trunk_type == MGCP_TRUNK_VIRTUAL) {
- if (allocate_port(endp, &endp->trans_net,
- &endp->cfg->transcoder_ports,
- mgcp_bind_trans_net_rtp_port) != 0) {
- mgcp_rtp_end_reset(&endp->net_end);
- mgcp_rtp_end_reset(&endp->bts_end);
- return -1;
- }
-
- if (allocate_port(endp, &endp->trans_bts,
- &endp->cfg->transcoder_ports,
- mgcp_bind_trans_bts_rtp_port) != 0) {
- mgcp_rtp_end_reset(&endp->net_end);
- mgcp_rtp_end_reset(&endp->bts_end);
- mgcp_rtp_end_reset(&endp->trans_net);
- return -1;
- }
-
- /* remember that we have set up transcoding */
- endp->type = MGCP_RTP_TRANSCODED;
- }
-
- return 0;
-}
-
-/* Set the LCO from a string (see RFC 3435).
- * The string is stored in the 'string' field. A NULL string is handled excatly
- * like an empty string, the 'string' field is never NULL after this function
- * has been called. */
-static void set_local_cx_options(void *ctx, struct mgcp_lco *lco,
- const char *options)
-{
- char *p_opt, *a_opt;
- char codec[9];
-
- talloc_free(lco->string);
- talloc_free(lco->codec);
- lco->codec = NULL;
- lco->pkt_period_min = lco->pkt_period_max = 0;
- lco->string = talloc_strdup(ctx, options ? options : "");
-
- p_opt = strstr(lco->string, "p:");
- if (p_opt && sscanf(p_opt, "p:%d-%d",
- &lco->pkt_period_min, &lco->pkt_period_max) == 1)
- lco->pkt_period_max = lco->pkt_period_min;
-
- a_opt = strstr(lco->string, "a:");
- if (a_opt && sscanf(a_opt, "a:%8[^,]", codec) == 1)
- lco->codec = talloc_strdup(ctx, codec);
-}
-
-void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
- struct mgcp_rtp_end *rtp)
-{
- struct mgcp_trunk_config *tcfg = endp->tcfg;
-
- int patch_ssrc = expect_ssrc_change && tcfg->force_constant_ssrc;
-
- rtp->force_aligned_timing = tcfg->force_aligned_timing;
- rtp->force_constant_ssrc = patch_ssrc ? 1 : 0;
-
- LOGP(DMGCP, LOGL_DEBUG,
- "Configuring RTP endpoint: local port %d%s%s\n",
- ntohs(rtp->rtp_port),
- rtp->force_aligned_timing ? ", force constant timing" : "",
- rtp->force_constant_ssrc ? ", force constant ssrc" : "");
-}
-
-uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *rtp)
-{
- int f = 0;
-
- /* Get the number of frames per channel and packet */
- if (rtp->frames_per_packet)
- f = rtp->frames_per_packet;
- else if (rtp->packet_duration_ms && rtp->codec.frame_duration_num) {
- int den = 1000 * rtp->codec.frame_duration_num;
- f = (rtp->packet_duration_ms * rtp->codec.frame_duration_den + den/2)
- / den;
- }
-
- return rtp->codec.rate * f * rtp->codec.frame_duration_num / rtp->codec.frame_duration_den;
-}
-
-static int mgcp_parse_osmux_cid(const char *line)
-{
- int osmux_cid;
-
- if (sscanf(line + 2, "Osmux: %u", &osmux_cid) != 1)
- return -1;
-
- if (osmux_cid > OSMUX_CID_MAX) {
- LOGP(DMGCP, LOGL_ERROR, "Osmux ID too large: %u > %u\n",
- osmux_cid, OSMUX_CID_MAX);
- return -1;
- }
- LOGP(DMGCP, LOGL_DEBUG, "bsc-nat offered Osmux CID %u\n", osmux_cid);
-
- return osmux_cid;
-}
-
-static int mgcp_osmux_setup(struct mgcp_endpoint *endp, const char *line)
-{
- if (!endp->cfg->osmux_init) {
- if (osmux_init(OSMUX_ROLE_BSC, endp->cfg) < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Cannot init OSMUX\n");
- return -1;
- }
- LOGP(DMGCP, LOGL_NOTICE, "OSMUX socket has been set up\n");
- }
-
- return mgcp_parse_osmux_cid(line);
-}
-
-static struct msgb *handle_create_con(struct mgcp_parse_data *p)
-{
- struct mgcp_trunk_config *tcfg;
- struct mgcp_endpoint *endp = p->endp;
- int error_code = 400;
-
- const char *local_options = NULL;
- const char *callid = NULL;
- const char *mode = NULL;
- char *line;
- int have_sdp = 0, osmux_cid = -1;
-
- if (p->found != 0)
- return create_err_response(NULL, 510, "CRCX", p->trans);
-
- /* parse CallID C: and LocalParameters L: */
- for_each_line(line, p->save) {
- if (!mgcp_check_param(endp, line))
- continue;
-
- switch (line[0]) {
- case 'L':
- local_options = (const char *) line + 3;
- break;
- case 'C':
- callid = (const char *) line + 3;
- break;
- case 'M':
- mode = (const char *) line + 3;
- break;
- case 'X':
- /* Osmux is not enabled in this bsc, ignore it so the
- * bsc-nat knows that we don't want to use Osmux.
- */
- if (!p->endp->cfg->osmux)
- break;
-
- if (strncmp("Osmux: ", line + 2, strlen("Osmux: ")) == 0)
- osmux_cid = mgcp_osmux_setup(endp, line);
- break;
- case '\0':
- have_sdp = 1;
- goto mgcp_header_done;
- default:
- LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
- *line, *line, ENDPOINT_NUMBER(endp));
- break;
- }
- }
-
-mgcp_header_done:
- tcfg = p->endp->tcfg;
-
- /* Check required data */
- if (!callid || !mode) {
- LOGP(DMGCP, LOGL_ERROR, "Missing callid and mode in CRCX on 0x%x\n",
- ENDPOINT_NUMBER(endp));
- return create_err_response(endp, 400, "CRCX", p->trans);
- }
-
- if (endp->allocated) {
- if (tcfg->force_realloc) {
- LOGP(DMGCP, LOGL_NOTICE, "Endpoint 0x%x already allocated. Forcing realloc.\n",
- ENDPOINT_NUMBER(endp));
- mgcp_release_endp(endp);
- if (p->cfg->realloc_cb)
- p->cfg->realloc_cb(tcfg, ENDPOINT_NUMBER(endp));
- } else {
- LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n",
- ENDPOINT_NUMBER(endp));
- return create_err_response(endp, 400, "CRCX", p->trans);
- }
- }
-
- /* copy some parameters */
- endp->callid = talloc_strdup(tcfg->endpoints, callid);
-
- set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
- local_options);
-
- if (parse_conn_mode(mode, endp) != 0) {
- error_code = 517;
- goto error2;
- }
-
- /* initialize */
- endp->net_end.rtp_port = endp->net_end.rtcp_port = endp->bts_end.rtp_port = endp->bts_end.rtcp_port = 0;
- mgcp_rtp_end_config(endp, 0, &endp->net_end);
- mgcp_rtp_end_config(endp, 0, &endp->bts_end);
-
- /* set to zero until we get the info */
- memset(&endp->net_end.addr, 0, sizeof(endp->net_end.addr));
-
- /* bind to the port now */
- if (allocate_ports(endp) != 0)
- goto error2;
-
- /* assign a local call identifier or fail */
- endp->ci = generate_call_id(p->cfg);
- if (endp->ci == CI_UNUSED)
- goto error2;
-
- /* Annotate Osmux circuit ID and set it to negotiating state until this
- * is fully set up from the dummy load.
- */
- endp->osmux.state = OSMUX_STATE_DISABLED;
- if (osmux_cid >= 0) {
- endp->osmux.cid = osmux_cid;
- endp->osmux.state = OSMUX_STATE_NEGOTIATING;
- } else if (endp->cfg->osmux == OSMUX_USAGE_ONLY) {
- LOGP(DMGCP, LOGL_ERROR,
- "Osmux only and no osmux offered on 0x%x\n", ENDPOINT_NUMBER(endp));
- goto error2;
- }
-
- endp->allocated = 1;
-
- /* set up RTP media parameters */
- mgcp_set_audio_info(p->cfg, &endp->bts_end.codec, tcfg->audio_payload, tcfg->audio_name);
- endp->bts_end.fmtp_extra = talloc_strdup(tcfg->endpoints,
- tcfg->audio_fmtp_extra);
- if (have_sdp)
- mgcp_parse_sdp_data(endp, &endp->net_end, p);
- else if (endp->local_options.codec)
- mgcp_set_audio_info(p->cfg, &endp->net_end.codec,
- PTYPE_UNDEFINED, endp->local_options.codec);
-
- if (p->cfg->bts_force_ptime) {
- endp->bts_end.packet_duration_ms = p->cfg->bts_force_ptime;
- endp->bts_end.force_output_ptime = 1;
- }
-
- if (setup_rtp_processing(endp) != 0)
- goto error2;
-
- /* policy CB */
- if (p->cfg->policy_cb) {
- int rc;
- rc = p->cfg->policy_cb(tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_CRCX, p->trans);
- switch (rc) {
- case MGCP_POLICY_REJECT:
- LOGP(DMGCP, LOGL_NOTICE, "CRCX rejected by policy on 0x%x\n",
- ENDPOINT_NUMBER(endp));
- mgcp_release_endp(endp);
- return create_err_response(endp, 400, "CRCX", p->trans);
- break;
- case MGCP_POLICY_DEFER:
- /* stop processing */
- create_transcoder(endp);
- return NULL;
- break;
- case MGCP_POLICY_CONT:
- /* just continue */
- break;
- }
- }
-
- LOGP(DMGCP, LOGL_DEBUG, "Creating endpoint on: 0x%x CI: %u port: %u/%u\n",
- ENDPOINT_NUMBER(endp), endp->ci,
- endp->net_end.local_port, endp->bts_end.local_port);
- if (p->cfg->change_cb)
- p->cfg->change_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX);
-
- if (endp->conn_mode & MGCP_CONN_RECV_ONLY && tcfg->keepalive_interval != 0) {
- send_dummy(endp);
- }
-
- create_transcoder(endp);
- return create_response_with_sdp(endp, "CRCX", p->trans);
-error2:
- mgcp_release_endp(endp);
- LOGP(DMGCP, LOGL_NOTICE, "Resource error on 0x%x\n", ENDPOINT_NUMBER(endp));
- return create_err_response(endp, error_code, "CRCX", p->trans);
-}
-
-static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
-{
- struct mgcp_endpoint *endp = p->endp;
- int error_code = 500;
- int silent = 0;
- int have_sdp = 0;
- char *line;
- const char *local_options = NULL;
-
- if (p->found != 0)
- return create_err_response(NULL, 510, "MDCX", p->trans);
-
- if (endp->ci == CI_UNUSED) {
- LOGP(DMGCP, LOGL_ERROR, "Endpoint is not "
- "holding a connection. 0x%x\n", ENDPOINT_NUMBER(endp));
- return create_err_response(endp, 400, "MDCX", p->trans);
- }
-
- for_each_line(line, p->save) {
- if (!mgcp_check_param(endp, line))
- continue;
-
- switch (line[0]) {
- case 'C': {
- if (verify_call_id(endp, line + 3) != 0)
- goto error3;
- break;
- }
- case 'I': {
- if (verify_ci(endp, line + 3) != 0)
- goto error3;
- break;
- }
- case 'L':
- local_options = (const char *) line + 3;
- break;
- case 'M':
- if (parse_conn_mode(line + 3, endp) != 0) {
- error_code = 517;
- goto error3;
- }
- endp->orig_mode = endp->conn_mode;
- break;
- case 'Z':
- silent = strcmp("noanswer", line + 3) == 0;
- break;
- case '\0':
- /* SDP file begins */
- have_sdp = 1;
- mgcp_parse_sdp_data(endp, &endp->net_end, p);
- /* This will exhaust p->save, so the loop will
- * terminate next time.
- */
- break;
- default:
- LOGP(DMGCP, LOGL_NOTICE, "Unhandled MGCP option: '%c'/%d on 0x%x\n",
- line[0], line[0], ENDPOINT_NUMBER(endp));
- break;
- }
- }
-
- set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
- local_options);
-
- if (!have_sdp && endp->local_options.codec)
- mgcp_set_audio_info(p->cfg, &endp->net_end.codec,
- PTYPE_UNDEFINED, endp->local_options.codec);
-
- if (setup_rtp_processing(endp) != 0)
- goto error3;
-
- /* policy CB */
- if (p->cfg->policy_cb) {
- int rc;
- rc = p->cfg->policy_cb(endp->tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_MDCX, p->trans);
- switch (rc) {
- case MGCP_POLICY_REJECT:
- LOGP(DMGCP, LOGL_NOTICE, "MDCX rejected by policy on 0x%x\n",
- ENDPOINT_NUMBER(endp));
- if (silent)
- goto out_silent;
- return create_err_response(endp, 400, "MDCX", p->trans);
- break;
- case MGCP_POLICY_DEFER:
- /* stop processing */
- LOGP(DMGCP, LOGL_DEBUG, "endp %x MDCX defer\n",
- ENDPOINT_NUMBER(endp));
- return NULL;
- break;
- case MGCP_POLICY_CONT:
- /* just continue */
- break;
- }
- }
-
- mgcp_rtp_end_config(endp, 1, &endp->net_end);
- mgcp_rtp_end_config(endp, 1, &endp->bts_end);
-
- /* modify */
- LOGP(DMGCP, LOGL_DEBUG, "Modified endpoint on: 0x%x Server: %s:%u\n",
- ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port));
- if (p->cfg->change_cb)
- p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX);
-
- if (endp->conn_mode & MGCP_CONN_RECV_ONLY &&
- endp->tcfg->keepalive_interval != 0)
- send_dummy(endp);
-
- if (silent)
- goto out_silent;
-
- return create_response_with_sdp(endp, "MDCX", p->trans);
-
-error3:
- return create_err_response(endp, error_code, "MDCX", p->trans);
-
-
-out_silent:
- LOGP(DMGCP, LOGL_DEBUG, "endp %x Modify endpoint: silent exit\n",
- ENDPOINT_NUMBER(endp));
- return NULL;
-}
-
-static struct msgb *handle_delete_con(struct mgcp_parse_data *p)
-{
- struct mgcp_endpoint *endp = p->endp;
- int error_code = 400;
- int silent = 0;
- char *line;
- char stats[1048];
-
- if (p->found != 0)
- return create_err_response(NULL, error_code, "DLCX", p->trans);
-
- if (!p->endp->allocated) {
- LOGP(DMGCP, LOGL_ERROR, "Endpoint is not used. 0x%x\n",
- ENDPOINT_NUMBER(endp));
- return create_err_response(endp, 400, "DLCX", p->trans);
- }
-
- for_each_line(line, p->save) {
- if (!mgcp_check_param(endp, line))
- continue;
-
- switch (line[0]) {
- case 'C':
- if (verify_call_id(endp, line + 3) != 0)
- goto error3;
- break;
- case 'I':
- if (verify_ci(endp, line + 3) != 0)
- goto error3;
- break;
- case 'Z':
- silent = strcmp("noanswer", line + 3) == 0;
- break;
- default:
- LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
- line[0], line[0], ENDPOINT_NUMBER(endp));
- break;
- }
- }
-
- /* policy CB */
- if (p->cfg->policy_cb) {
- int rc;
- rc = p->cfg->policy_cb(endp->tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_DLCX, p->trans);
- switch (rc) {
- case MGCP_POLICY_REJECT:
- LOGP(DMGCP, LOGL_NOTICE, "DLCX rejected by policy on 0x%x\n",
- ENDPOINT_NUMBER(endp));
- if (silent)
- goto out_silent;
- return create_err_response(endp, 400, "DLCX", p->trans);
- break;
- case MGCP_POLICY_DEFER:
- /* stop processing */
- delete_transcoder(endp);
- return NULL;
- break;
- case MGCP_POLICY_CONT:
- /* just continue */
- break;
- }
- }
-
- /* free the connection */
- LOGP(DMGCP, LOGL_DEBUG, "Deleted endpoint on: 0x%x Server: %s:%u\n",
- ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port));
-
- /* save the statistics of the current call */
- mgcp_format_stats(endp, stats, sizeof(stats));
-
- delete_transcoder(endp);
- mgcp_release_endp(endp);
- if (p->cfg->change_cb)
- p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX);
-
- if (silent)
- goto out_silent;
- return create_ok_resp_with_param(endp, 250, "DLCX", p->trans, stats);
-
-error3:
- return create_err_response(endp, error_code, "DLCX", p->trans);
-
-out_silent:
- return NULL;
-}
-
-static struct msgb *handle_rsip(struct mgcp_parse_data *p)
-{
- if (p->found != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to find the endpoint.\n");
- return NULL;
- }
-
- if (p->cfg->reset_cb)
- p->cfg->reset_cb(p->endp->tcfg);
- return NULL;
-}
-
-static char extract_tone(const char *line)
-{
- const char *str = strstr(line, "D/");
- if (!str)
- return CHAR_MAX;
-
- return str[2];
-}
-
-/*
- * This can request like DTMF detection and forward, fax detection... it
- * can also request when the notification should be send and such. We don't
- * do this right now.
- */
-static struct msgb *handle_noti_req(struct mgcp_parse_data *p)
-{
- int res = 0;
- char *line;
- char tone = CHAR_MAX;
-
- if (p->found != 0)
- return create_err_response(NULL, 400, "RQNT", p->trans);
-
- for_each_line(line, p->save) {
- switch (line[0]) {
- case 'S':
- tone = extract_tone(line);
- break;
- }
- }
-
- /* we didn't see a signal request with a tone */
- if (tone == CHAR_MAX)
- return create_ok_response(p->endp, 200, "RQNT", p->trans);
-
- if (p->cfg->rqnt_cb)
- res = p->cfg->rqnt_cb(p->endp, tone);
-
- return res == 0 ?
- create_ok_response(p->endp, 200, "RQNT", p->trans) :
- create_err_response(p->endp, res, "RQNT", p->trans);
-}
-
-static void mgcp_keepalive_timer_cb(void *_tcfg)
-{
- struct mgcp_trunk_config *tcfg = _tcfg;
- int i;
- LOGP(DMGCP, LOGL_DEBUG, "Triggered trunk %d keepalive timer.\n",
- tcfg->trunk_nr);
-
- if (tcfg->keepalive_interval <= 0)
- return;
-
- for (i = 1; i < tcfg->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &tcfg->endpoints[i];
- if (endp->conn_mode == MGCP_CONN_RECV_ONLY)
- send_dummy(endp);
- }
-
- LOGP(DMGCP, LOGL_DEBUG, "Rescheduling trunk %d keepalive timer.\n",
- tcfg->trunk_nr);
- osmo_timer_schedule(&tcfg->keepalive_timer, tcfg->keepalive_interval, 0);
-}
-
-void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval)
-{
- tcfg->keepalive_interval = interval;
- osmo_timer_setup(&tcfg->keepalive_timer, mgcp_keepalive_timer_cb, tcfg);
-
- if (interval <= 0)
- osmo_timer_del(&tcfg->keepalive_timer);
- else
- osmo_timer_schedule(&tcfg->keepalive_timer,
- tcfg->keepalive_interval, 0);
-}
-
-struct mgcp_config *mgcp_config_alloc(void)
-{
- struct mgcp_config *cfg;
-
- cfg = talloc_zero(NULL, struct mgcp_config);
- if (!cfg) {
- LOGP(DMGCP, LOGL_FATAL, "Failed to allocate config.\n");
- return NULL;
- }
-
- cfg->source_port = 2427;
- cfg->source_addr = talloc_strdup(cfg, "0.0.0.0");
- cfg->osmux_addr = talloc_strdup(cfg, "0.0.0.0");
-
- cfg->transcoder_remote_base = 4000;
-
- cfg->bts_ports.base_port = RTP_PORT_DEFAULT;
- cfg->net_ports.base_port = RTP_PORT_NET_DEFAULT;
-
- cfg->rtp_processing_cb = &mgcp_rtp_processing_default;
- cfg->setup_rtp_processing_cb = &mgcp_setup_rtp_processing_default;
-
- cfg->get_net_downlink_format_cb = &mgcp_get_net_downlink_format_default;
-
- /* default trunk handling */
- cfg->trunk.cfg = cfg;
- cfg->trunk.trunk_nr = 0;
- cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
- cfg->trunk.audio_name = talloc_strdup(cfg, "AMR/8000");
- cfg->trunk.audio_payload = 126;
- cfg->trunk.audio_send_ptime = 1;
- cfg->trunk.audio_send_name = 1;
- cfg->trunk.omit_rtcp = 0;
- mgcp_trunk_set_keepalive(&cfg->trunk, MGCP_KEEPALIVE_ONCE);
-
- INIT_LLIST_HEAD(&cfg->trunks);
-
- return cfg;
-}
-
-struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr)
-{
- struct mgcp_trunk_config *trunk;
-
- trunk = talloc_zero(cfg, struct mgcp_trunk_config);
- if (!trunk) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to allocate.\n");
- return NULL;
- }
-
- trunk->cfg = cfg;
- trunk->trunk_type = MGCP_TRUNK_E1;
- trunk->trunk_nr = nr;
- trunk->audio_name = talloc_strdup(cfg, "AMR/8000");
- trunk->audio_payload = 126;
- trunk->audio_send_ptime = 1;
- trunk->audio_send_name = 1;
- trunk->number_endpoints = 33;
- trunk->omit_rtcp = 0;
- mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
- llist_add_tail(&trunk->entry, &cfg->trunks);
- return trunk;
-}
-
-struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index)
-{
- struct mgcp_trunk_config *trunk;
-
- llist_for_each_entry(trunk, &cfg->trunks, entry)
- if (trunk->trunk_nr == index)
- return trunk;
-
- return NULL;
-}
-
-static void mgcp_rtp_codec_reset(struct mgcp_rtp_codec *codec)
-{
- codec->payload_type = -1;
- talloc_free(codec->subtype_name);
- codec->subtype_name = NULL;
- talloc_free(codec->audio_name);
- codec->audio_name = NULL;
- codec->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM;
- codec->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN;
- codec->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE;
- codec->channels = DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS;
-}
-
-static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
-{
- if (end->local_alloc == PORT_ALLOC_DYNAMIC) {
- mgcp_free_rtp_port(end);
- end->local_port = 0;
- }
-
- end->packets = 0;
- end->octets = 0;
- end->dropped_packets = 0;
- memset(&end->addr, 0, sizeof(end->addr));
- end->rtp_port = end->rtcp_port = 0;
- end->local_alloc = -1;
- talloc_free(end->fmtp_extra);
- end->fmtp_extra = NULL;
- talloc_free(end->rtp_process_data);
- end->rtp_process_data = NULL;
-
- /* Set default values */
- end->frames_per_packet = 0; /* unknown */
- end->packet_duration_ms = DEFAULT_RTP_AUDIO_PACKET_DURATION_MS;
- end->output_enabled = 0;
-
- mgcp_rtp_codec_reset(&end->codec);
- mgcp_rtp_codec_reset(&end->alt_codec);
-}
-
-static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
-{
- mgcp_rtp_end_reset(end);
- end->rtp.fd = -1;
- end->rtcp.fd = -1;
-}
-
-int mgcp_endpoints_allocate(struct mgcp_trunk_config *tcfg)
-{
- int i;
-
- /* Initialize all endpoints */
- tcfg->endpoints = _talloc_zero_array(tcfg->cfg,
- sizeof(struct mgcp_endpoint),
- tcfg->number_endpoints, "endpoints");
- if (!tcfg->endpoints)
- return -1;
-
- for (i = 0; i < tcfg->number_endpoints; ++i) {
- tcfg->endpoints[i].osmux.allocated_cid = -1;
- tcfg->endpoints[i].ci = CI_UNUSED;
- tcfg->endpoints[i].cfg = tcfg->cfg;
- tcfg->endpoints[i].tcfg = tcfg;
- mgcp_rtp_end_init(&tcfg->endpoints[i].net_end);
- mgcp_rtp_end_init(&tcfg->endpoints[i].bts_end);
- mgcp_rtp_end_init(&tcfg->endpoints[i].trans_net);
- mgcp_rtp_end_init(&tcfg->endpoints[i].trans_bts);
- }
-
- return 0;
-}
-
-void mgcp_release_endp(struct mgcp_endpoint *endp)
-{
- LOGP(DMGCP, LOGL_DEBUG, "Releasing endpoint on: 0x%x\n", ENDPOINT_NUMBER(endp));
- endp->ci = CI_UNUSED;
- endp->allocated = 0;
-
- 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;
-
- mgcp_rtp_end_reset(&endp->bts_end);
- mgcp_rtp_end_reset(&endp->net_end);
- mgcp_rtp_end_reset(&endp->trans_net);
- mgcp_rtp_end_reset(&endp->trans_bts);
- endp->type = MGCP_RTP_DEFAULT;
-
- memset(&endp->net_state, 0, sizeof(endp->net_state));
- memset(&endp->bts_state, 0, sizeof(endp->bts_state));
-
- endp->conn_mode = endp->orig_mode = MGCP_CONN_NONE;
-
- if (endp->osmux.state == OSMUX_STATE_ENABLED)
- osmux_disable_endpoint(endp);
-
- /* release the circuit ID if it had been allocated */
- osmux_release_cid(endp);
-
- memset(&endp->taps, 0, sizeof(endp->taps));
-}
-
-void mgcp_initialize_endp(struct mgcp_endpoint *endp)
-{
- return mgcp_release_endp(endp);
-}
-
-static int send_trans(struct mgcp_config *cfg, const char *buf, int len)
-{
- struct sockaddr_in addr;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr = cfg->transcoder_in;
- addr.sin_port = htons(2427);
- return sendto(cfg->gw_fd.bfd.fd, buf, len, 0,
- (struct sockaddr *) &addr, sizeof(addr));
-}
-
-static void send_msg(struct mgcp_endpoint *endp, int endpoint, int port,
- const char *msg, const char *mode)
-{
- char buf[2096];
- int len;
- int nchars;
-
- /* hardcoded to AMR right now, we do not know the real type at this point */
- len = snprintf(buf, sizeof(buf),
- "%s 42 %x@mgw MGCP 1.0\r\n"
- "C: 4256\r\n"
- "M: %s\r\n"
- "\r\n",
- msg, endpoint, mode);
-
- if (len < 0)
- return;
-
- nchars = write_response_sdp(endp, buf + len, sizeof(buf) + len - 1, NULL);
- if (nchars < 0)
- return;
-
- len += nchars;
-
- buf[sizeof(buf) - 1] = '\0';
-
- send_trans(endp->cfg, buf, len);
-}
-
-static void send_dlcx(struct mgcp_endpoint *endp, int endpoint)
-{
- char buf[2096];
- int len;
-
- len = snprintf(buf, sizeof(buf),
- "DLCX 43 %x@mgw MGCP 1.0\r\n"
- "C: 4256\r\n"
- , endpoint);
-
- if (len < 0)
- return;
-
- buf[sizeof(buf) - 1] = '\0';
-
- send_trans(endp->cfg, buf, len);
-}
-
-static int send_agent(struct mgcp_config *cfg, const char *buf, int len)
-{
- return write(cfg->gw_fd.bfd.fd, buf, len);
-}
-
-int mgcp_send_reset_all(struct mgcp_config *cfg)
-{
- static const char mgcp_reset[] = {
- "RSIP 1 *@mgw MGCP 1.0\r\n"
- };
-
- return send_agent(cfg, mgcp_reset, sizeof mgcp_reset -1);
-}
-
-int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint)
-{
- char buf[128];
- int len;
-
- len = snprintf(buf, sizeof(buf),
- "RSIP 39 %x@mgw MGCP 1.0\r\n"
- , endpoint);
- if (len < 0)
- return len;
-
- buf[sizeof(buf) - 1] = '\0';
-
- return send_agent(endp->cfg, buf, len);
-}
-
-static int setup_rtp_processing(struct mgcp_endpoint *endp)
-{
- int rc = 0;
- struct mgcp_config *cfg = endp->cfg;
-
- if (endp->type != MGCP_RTP_DEFAULT)
- return 0;
-
- if (endp->conn_mode == MGCP_CONN_LOOPBACK)
- return 0;
-
- if (endp->conn_mode & MGCP_CONN_SEND_ONLY)
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end);
- else
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->net_end, NULL);
-
- if (endp->conn_mode & MGCP_CONN_RECV_ONLY)
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->bts_end, &endp->net_end);
- else
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->bts_end, NULL);
- return rc;
-}
-
-static void create_transcoder(struct mgcp_endpoint *endp)
-{
- int port;
- int in_endp = ENDPOINT_NUMBER(endp);
- int out_endp = endp_back_channel(in_endp);
-
- if (endp->type != MGCP_RTP_TRANSCODED)
- return;
-
- send_msg(endp, in_endp, endp->trans_bts.local_port, "CRCX", "sendrecv");
- send_msg(endp, in_endp, endp->trans_bts.local_port, "MDCX", "sendrecv");
- send_msg(endp, out_endp, endp->trans_net.local_port, "CRCX", "sendrecv");
- send_msg(endp, out_endp, endp->trans_net.local_port, "MDCX", "sendrecv");
-
- port = rtp_calculate_port(in_endp, endp->cfg->transcoder_remote_base);
- endp->trans_bts.rtp_port = htons(port);
- endp->trans_bts.rtcp_port = htons(port + 1);
-
- port = rtp_calculate_port(out_endp, endp->cfg->transcoder_remote_base);
- endp->trans_net.rtp_port = htons(port);
- endp->trans_net.rtcp_port = htons(port + 1);
-}
-
-static void delete_transcoder(struct mgcp_endpoint *endp)
-{
- int in_endp = ENDPOINT_NUMBER(endp);
- int out_endp = endp_back_channel(in_endp);
-
- if (endp->type != MGCP_RTP_TRANSCODED)
- return;
-
- send_dlcx(endp, in_endp);
- send_dlcx(endp, out_endp);
-}
-
-int mgcp_reset_transcoder(struct mgcp_config *cfg)
-{
- if (!cfg->transcoder_ip)
- return 0;
-
- static const char mgcp_reset[] = {
- "RSIP 1 13@mgw MGCP 1.0\r\n"
- };
-
- return send_trans(cfg, mgcp_reset, sizeof mgcp_reset -1);
-}
-
-void mgcp_format_stats(struct mgcp_endpoint *endp, char *msg, size_t size)
-{
- uint32_t expected, jitter;
- int ploss;
- int nchars;
- mgcp_state_calc_loss(&endp->net_state, &endp->net_end,
- &expected, &ploss);
- jitter = mgcp_state_calc_jitter(&endp->net_state);
-
- nchars = snprintf(msg, size,
- "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u",
- endp->bts_end.packets, endp->bts_end.octets,
- endp->net_end.packets, endp->net_end.octets,
- ploss, jitter);
- if (nchars < 0 || nchars >= size)
- goto truncate;
-
- msg += nchars;
- size -= nchars;
-
- /* Error Counter */
- nchars = snprintf(msg, size,
- "\r\nX-Osmo-CP: EC TIS=%u, TOS=%u, TIR=%u, TOR=%u",
- endp->net_state.in_stream.err_ts_counter,
- endp->net_state.out_stream.err_ts_counter,
- endp->bts_state.in_stream.err_ts_counter,
- endp->bts_state.out_stream.err_ts_counter);
- if (nchars < 0 || nchars >= size)
- goto truncate;
-
- msg += nchars;
- size -= nchars;
-
- if (endp->osmux.state == OSMUX_STATE_ENABLED) {
- snprintf(msg, size,
- "\r\nX-Osmux-ST: CR=%u, BR=%u",
- endp->osmux.stats.chunks,
- endp->osmux.stats.octets);
- }
-truncate:
- msg[size - 1] = '\0';
-}
-
-int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os,
- uint32_t *pr, uint32_t *_or, int *loss, uint32_t *jitter)
-{
- char *line, *save;
- int rc;
-
- /* initialize with bad values */
- *ps = *os = *pr = *_or = *jitter = UINT_MAX;
- *loss = INT_MAX;
-
-
- line = strtok_r((char *) msg->l2h, "\r\n", &save);
- if (!line)
- return -1;
-
- /* this can only parse the message that is created above... */
- for_each_non_empty_line(line, save) {
- switch (line[0]) {
- case 'P':
- rc = sscanf(line, "P: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d, JI=%u",
- ps, os, pr, _or, loss, jitter);
- return rc == 6 ? 0 : -1;
- }
- }
-
- return -1;
-}
diff --git a/src/libmgcp/mgcp_sdp.c b/src/libmgcp/mgcp_sdp.c
deleted file mode 100644
index b64894496..000000000
--- a/src/libmgcp/mgcp_sdp.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Some SDP file parsing...
- *
- * (C) 2009-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2014 by On-Waves
- * 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 <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-
-#include <errno.h>
-
-struct sdp_rtp_map {
- /* the type */
- int payload_type;
- /* null, static or later dynamic codec name */
- char *codec_name;
- /* A pointer to the original line for later parsing */
- char *map_line;
-
- int rate;
- int channels;
-};
-
-int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
- int payload_type, const char *audio_name)
-{
- int rate = codec->rate;
- int channels = codec->channels;
- char audio_codec[64];
-
- talloc_free(codec->subtype_name);
- codec->subtype_name = NULL;
- talloc_free(codec->audio_name);
- codec->audio_name = NULL;
-
- if (payload_type != PTYPE_UNDEFINED)
- codec->payload_type = payload_type;
-
- if (!audio_name) {
- switch (payload_type) {
- case 0: audio_name = "PCMU/8000/1"; break;
- case 3: audio_name = "GSM/8000/1"; break;
- case 8: audio_name = "PCMA/8000/1"; break;
- case 18: audio_name = "G729/8000/1"; break;
- default:
- /* Payload type is unknown, don't change rate and
- * channels. */
- /* TODO: return value? */
- return 0;
- }
- }
-
- if (sscanf(audio_name, "%63[^/]/%d/%d",
- audio_codec, &rate, &channels) < 1)
- return -EINVAL;
-
- codec->rate = rate;
- codec->channels = channels;
- codec->subtype_name = talloc_strdup(ctx, audio_codec);
- codec->audio_name = talloc_strdup(ctx, audio_name);
-
- if (!strcmp(audio_codec, "G729")) {
- codec->frame_duration_num = 10;
- codec->frame_duration_den = 1000;
- } else {
- codec->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM;
- codec->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN;
- }
-
- if (payload_type < 0) {
- payload_type = 96;
- if (rate == 8000 && channels == 1) {
- if (!strcmp(audio_codec, "GSM"))
- payload_type = 3;
- else if (!strcmp(audio_codec, "PCMA"))
- payload_type = 8;
- else if (!strcmp(audio_codec, "PCMU"))
- payload_type = 0;
- else if (!strcmp(audio_codec, "G729"))
- payload_type = 18;
- }
-
- codec->payload_type = payload_type;
- }
-
- if (channels != 1)
- LOGP(DMGCP, LOGL_NOTICE,
- "Channels != 1 in SDP: '%s'\n", audio_name);
-
- return 0;
-}
-
-void codecs_initialize(void *ctx, struct sdp_rtp_map *codecs, int used)
-{
- int i;
-
- for (i = 0; i < used; ++i) {
- switch (codecs[i].payload_type) {
- case 0:
- codecs[i].codec_name = "PCMU";
- codecs[i].rate = 8000;
- codecs[i].channels = 1;
- break;
- case 3:
- codecs[i].codec_name = "GSM";
- codecs[i].rate = 8000;
- codecs[i].channels = 1;
- break;
- case 8:
- codecs[i].codec_name = "PCMA";
- codecs[i].rate = 8000;
- codecs[i].channels = 1;
- break;
- case 18:
- codecs[i].codec_name = "G729";
- codecs[i].rate = 8000;
- codecs[i].channels = 1;
- break;
- }
- }
-}
-
-void codecs_update(void *ctx, struct sdp_rtp_map *codecs, int used, int payload, char *audio_name)
-{
- int i;
-
- for (i = 0; i < used; ++i) {
- char audio_codec[64];
- int rate = -1;
- int channels = -1;
- if (codecs[i].payload_type != payload)
- continue;
- if (sscanf(audio_name, "%63[^/]/%d/%d",
- audio_codec, &rate, &channels) < 1) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to parse '%s'\n", audio_name);
- continue;
- }
-
- codecs[i].map_line = talloc_strdup(ctx, audio_name);
- codecs[i].codec_name = talloc_strdup(ctx, audio_codec);
- codecs[i].rate = rate;
- codecs[i].channels = channels;
- return;
- }
-
- LOGP(DMGCP, LOGL_ERROR, "Unconfigured PT(%d) with %s\n", payload, audio_name);
-}
-
-int is_codec_compatible(struct mgcp_endpoint *endp, struct sdp_rtp_map *codec)
-{
- char *bts_codec;
- char audio_codec[64];
-
- if (!codec->codec_name)
- return 0;
-
- /*
- * GSM, GSM/8000 and GSM/8000/1 should all be compatible.. let's go
- * by name first.
- */
- bts_codec = endp->tcfg->audio_name;
- if (sscanf(bts_codec, "%63[^/]/%*d/%*d", audio_codec) < 1)
- return 0;
-
- return strcasecmp(audio_codec, codec->codec_name) == 0;
-}
-
-int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
-{
- struct sdp_rtp_map codecs[10];
- int codecs_used = 0;
- char *line;
- int maxptime = -1;
- int i;
- int codecs_assigned = 0;
- void *tmp_ctx = talloc_new(NULL);
-
- memset(&codecs, 0, sizeof(codecs));
-
- for_each_line(line, p->save) {
- switch (line[0]) {
- case 'o':
- case 's':
- case 't':
- case 'v':
- /* skip these SDP attributes */
- break;
- case 'a': {
- int payload;
- int ptime, ptime2 = 0;
- char audio_name[64];
-
-
- if (sscanf(line, "a=rtpmap:%d %63s",
- &payload, audio_name) == 2) {
- codecs_update(tmp_ctx, codecs, codecs_used, payload, audio_name);
- } else if (sscanf(line, "a=ptime:%d-%d",
- &ptime, &ptime2) >= 1) {
- if (ptime2 > 0 && ptime2 != ptime)
- rtp->packet_duration_ms = 0;
- else
- rtp->packet_duration_ms = ptime;
- } else if (sscanf(line, "a=maxptime:%d", &ptime2) == 1) {
- maxptime = ptime2;
- }
- break;
- }
- case 'm': {
- int port, rc;
-
- rc = sscanf(line, "m=audio %d RTP/AVP %d %d %d %d %d %d %d %d %d %d",
- &port,
- &codecs[0].payload_type,
- &codecs[1].payload_type,
- &codecs[2].payload_type,
- &codecs[3].payload_type,
- &codecs[4].payload_type,
- &codecs[5].payload_type,
- &codecs[6].payload_type,
- &codecs[7].payload_type,
- &codecs[8].payload_type,
- &codecs[9].payload_type);
- if (rc >= 2) {
- rtp->rtp_port = htons(port);
- rtp->rtcp_port = htons(port + 1);
- codecs_used = rc - 1;
- codecs_initialize(tmp_ctx, codecs, codecs_used);
- }
- break;
- }
- case 'c': {
- char ipv4[16];
-
- if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) {
- inet_aton(ipv4, &rtp->addr);
- }
- break;
- }
- default:
- if (p->endp)
- LOGP(DMGCP, LOGL_NOTICE,
- "Unhandled SDP option: '%c'/%d on 0x%x\n",
- line[0], line[0], ENDPOINT_NUMBER(p->endp));
- else
- LOGP(DMGCP, LOGL_NOTICE,
- "Unhandled SDP option: '%c'/%d\n",
- line[0], line[0]);
- break;
- }
- }
-
- /* Now select the primary and alt_codec */
- for (i = 0; i < codecs_used && codecs_assigned < 2; ++i) {
- struct mgcp_rtp_codec *codec = codecs_assigned == 0 ?
- &rtp->codec : &rtp->alt_codec;
-
- if (endp->tcfg->no_audio_transcoding &&
- !is_codec_compatible(endp, &codecs[i])) {
- LOGP(DMGCP, LOGL_NOTICE, "Skipping codec %s\n",
- codecs[i].codec_name);
- continue;
- }
-
- mgcp_set_audio_info(p->cfg, codec,
- codecs[i].payload_type,
- codecs[i].map_line);
- codecs_assigned += 1;
- }
-
- if (codecs_assigned > 0) {
- /* TODO/XXX: Store this per codec and derive it on use */
- if (maxptime >= 0 && maxptime * rtp->codec.frame_duration_den >
- rtp->codec.frame_duration_num * 1500) {
- /* more than 1 frame */
- rtp->packet_duration_ms = 0;
- }
-
- LOGP(DMGCP, LOGL_NOTICE,
- "Got media info via SDP: port %d, payload %d (%s), "
- "duration %d, addr %s\n",
- ntohs(rtp->rtp_port), rtp->codec.payload_type,
- rtp->codec.subtype_name ? rtp->codec.subtype_name : "unknown",
- rtp->packet_duration_ms, inet_ntoa(rtp->addr));
- }
-
- talloc_free(tmp_ctx);
- return codecs_assigned > 0;
-}
-
diff --git a/src/libmgcp/mgcp_transcode.c b/src/libmgcp/mgcp_transcode.c
deleted file mode 100644
index f31e7aefb..000000000
--- a/src/libmgcp/mgcp_transcode.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * (C) 2014 by On-Waves
- * 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 <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-
-#include "g711common.h"
-
-#include <openbsc/debug.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-#include <openbsc/mgcp_transcode.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/netif/rtp.h>
-
-int mgcp_transcoding_get_frame_size(void *state_, int nsamples, int dst)
-{
- struct mgcp_process_rtp_state *state = state_;
- if (dst)
- return (nsamples >= 0 ?
- nsamples / state->dst_samples_per_frame :
- 1) * state->dst_frame_size;
- else
- return (nsamples >= 0 ?
- nsamples / state->src_samples_per_frame :
- 1) * state->src_frame_size;
-}
-
-static enum audio_format get_audio_format(const struct mgcp_rtp_codec *codec)
-{
- if (codec->subtype_name) {
- if (!strcasecmp("GSM", codec->subtype_name))
- return AF_GSM;
- if (!strcasecmp("PCMA", codec->subtype_name))
- return AF_PCMA;
- if (!strcasecmp("PCMU", codec->subtype_name))
- return AF_PCMU;
-#ifdef HAVE_BCG729
- if (!strcasecmp("G729", codec->subtype_name))
- return AF_G729;
-#endif
- if (!strcasecmp("L16", codec->subtype_name))
- return AF_L16;
- }
-
- switch (codec->payload_type) {
- case 0 /* PCMU */:
- return AF_PCMU;
- case 3 /* GSM */:
- return AF_GSM;
- case 8 /* PCMA */:
- return AF_PCMA;
-#ifdef HAVE_BCG729
- case 18 /* G.729 */:
- return AF_G729;
-#endif
- case 11 /* L16 */:
- return AF_L16;
- default:
- return AF_INVALID;
- }
-}
-
-static void l16_encode(short *sample, unsigned char *buf, size_t n)
-{
- for (; n > 0; --n, ++sample, buf += 2) {
- buf[0] = sample[0] >> 8;
- buf[1] = sample[0] & 0xff;
- }
-}
-
-static void l16_decode(unsigned char *buf, short *sample, size_t n)
-{
- for (; n > 0; --n, ++sample, buf += 2)
- sample[0] = ((short)buf[0] << 8) | buf[1];
-}
-
-static void alaw_encode(short *sample, unsigned char *buf, size_t n)
-{
- for (; n > 0; --n)
- *(buf++) = s16_to_alaw(*(sample++));
-}
-
-static void alaw_decode(unsigned char *buf, short *sample, size_t n)
-{
- for (; n > 0; --n)
- *(sample++) = alaw_to_s16(*(buf++));
-}
-
-static void ulaw_encode(short *sample, unsigned char *buf, size_t n)
-{
- for (; n > 0; --n)
- *(buf++) = s16_to_ulaw(*(sample++));
-}
-
-static void ulaw_decode(unsigned char *buf, short *sample, size_t n)
-{
- for (; n > 0; --n)
- *(sample++) = ulaw_to_s16(*(buf++));
-}
-
-static int processing_state_destructor(struct mgcp_process_rtp_state *state)
-{
- switch (state->src_fmt) {
- case AF_GSM:
- if (state->src.gsm_handle)
- gsm_destroy(state->src.gsm_handle);
- break;
-#ifdef HAVE_BCG729
- case AF_G729:
- if (state->src.g729_dec)
- closeBcg729DecoderChannel(state->src.g729_dec);
- break;
-#endif
- default:
- break;
- }
- switch (state->dst_fmt) {
- case AF_GSM:
- if (state->dst.gsm_handle)
- gsm_destroy(state->dst.gsm_handle);
- break;
-#ifdef HAVE_BCG729
- case AF_G729:
- if (state->dst.g729_enc)
- closeBcg729EncoderChannel(state->dst.g729_enc);
- break;
-#endif
- default:
- break;
- }
- return 0;
-}
-
-int mgcp_transcoding_setup(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- struct mgcp_rtp_end *src_end)
-{
- struct mgcp_process_rtp_state *state;
- enum audio_format src_fmt, dst_fmt;
- const struct mgcp_rtp_codec *dst_codec = &dst_end->codec;
-
- /* cleanup first */
- if (dst_end->rtp_process_data) {
- talloc_free(dst_end->rtp_process_data);
- dst_end->rtp_process_data = NULL;
- }
-
- if (!src_end)
- return 0;
-
- const struct mgcp_rtp_codec *src_codec = &src_end->codec;
-
- if (endp->tcfg->no_audio_transcoding) {
- LOGP(DMGCP, LOGL_NOTICE,
- "Transcoding disabled on endpoint 0x%x\n",
- ENDPOINT_NUMBER(endp));
- return 0;
- }
-
- src_fmt = get_audio_format(src_codec);
- dst_fmt = get_audio_format(dst_codec);
-
- LOGP(DMGCP, LOGL_ERROR,
- "Checking transcoding: %s (%d) -> %s (%d)\n",
- src_codec->subtype_name, src_codec->payload_type,
- dst_codec->subtype_name, dst_codec->payload_type);
-
- if (src_fmt == AF_INVALID || dst_fmt == AF_INVALID) {
- if (!src_codec->subtype_name || !dst_codec->subtype_name)
- /* Not enough info, do nothing */
- return 0;
-
- if (strcasecmp(src_codec->subtype_name, dst_codec->subtype_name) == 0)
- /* Nothing to do */
- return 0;
-
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot transcode: %s codec not supported (%s -> %s).\n",
- src_fmt != AF_INVALID ? "destination" : "source",
- src_codec->audio_name, dst_codec->audio_name);
- return -EINVAL;
- }
-
- if (src_codec->rate && dst_codec->rate && src_codec->rate != dst_codec->rate) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot transcode: rate conversion (%d -> %d) not supported.\n",
- src_codec->rate, dst_codec->rate);
- return -EINVAL;
- }
-
- state = talloc_zero(endp->tcfg->cfg, struct mgcp_process_rtp_state);
- talloc_set_destructor(state, processing_state_destructor);
- dst_end->rtp_process_data = state;
-
- state->src_fmt = src_fmt;
-
- switch (state->src_fmt) {
- case AF_L16:
- case AF_S16:
- state->src_frame_size = 80 * sizeof(short);
- state->src_samples_per_frame = 80;
- break;
- case AF_GSM:
- state->src_frame_size = sizeof(gsm_frame);
- state->src_samples_per_frame = 160;
- state->src.gsm_handle = gsm_create();
- if (!state->src.gsm_handle) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to initialize GSM decoder.\n");
- return -EINVAL;
- }
- break;
-#ifdef HAVE_BCG729
- case AF_G729:
- state->src_frame_size = 10;
- state->src_samples_per_frame = 80;
- state->src.g729_dec = initBcg729DecoderChannel();
- if (!state->src.g729_dec) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to initialize G.729 decoder.\n");
- return -EINVAL;
- }
- break;
-#endif
- case AF_PCMU:
- case AF_PCMA:
- state->src_frame_size = 80;
- state->src_samples_per_frame = 80;
- break;
- default:
- break;
- }
-
- state->dst_fmt = dst_fmt;
-
- switch (state->dst_fmt) {
- case AF_L16:
- case AF_S16:
- state->dst_frame_size = 80*sizeof(short);
- state->dst_samples_per_frame = 80;
- break;
- case AF_GSM:
- state->dst_frame_size = sizeof(gsm_frame);
- state->dst_samples_per_frame = 160;
- state->dst.gsm_handle = gsm_create();
- if (!state->dst.gsm_handle) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to initialize GSM encoder.\n");
- return -EINVAL;
- }
- break;
-#ifdef HAVE_BCG729
- case AF_G729:
- state->dst_frame_size = 10;
- state->dst_samples_per_frame = 80;
- state->dst.g729_enc = initBcg729EncoderChannel();
- if (!state->dst.g729_enc) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to initialize G.729 decoder.\n");
- return -EINVAL;
- }
- break;
-#endif
- case AF_PCMU:
- case AF_PCMA:
- state->dst_frame_size = 80;
- state->dst_samples_per_frame = 80;
- break;
- default:
- break;
- }
-
- if (dst_end->force_output_ptime)
- state->dst_packet_duration = mgcp_rtp_packet_duration(endp, dst_end);
-
- LOGP(DMGCP, LOGL_INFO,
- "Initialized RTP processing on: 0x%x "
- "conv: %d (%d, %d, %s) -> %d (%d, %d, %s)\n",
- ENDPOINT_NUMBER(endp),
- src_fmt, src_codec->payload_type, src_codec->rate, src_end->fmtp_extra,
- dst_fmt, dst_codec->payload_type, dst_codec->rate, dst_end->fmtp_extra);
-
- return 0;
-}
-
-void mgcp_transcoding_net_downlink_format(struct mgcp_endpoint *endp,
- int *payload_type,
- const char**audio_name,
- const char**fmtp_extra)
-{
- struct mgcp_process_rtp_state *state = endp->net_end.rtp_process_data;
- struct mgcp_rtp_codec *net_codec = &endp->net_end.codec;
- struct mgcp_rtp_codec *bts_codec = &endp->bts_end.codec;
-
- if (!state || net_codec->payload_type < 0) {
- *payload_type = bts_codec->payload_type;
- *audio_name = bts_codec->audio_name;
- *fmtp_extra = endp->bts_end.fmtp_extra;
- return;
- }
-
- *payload_type = net_codec->payload_type;
- *audio_name = net_codec->audio_name;
- *fmtp_extra = endp->net_end.fmtp_extra;
-}
-
-static int decode_audio(struct mgcp_process_rtp_state *state,
- uint8_t **src, size_t *nbytes)
-{
- while (*nbytes >= state->src_frame_size) {
- if (state->sample_cnt + state->src_samples_per_frame > ARRAY_SIZE(state->samples)) {
- LOGP(DMGCP, LOGL_ERROR,
- "Sample buffer too small: %zu > %zu.\n",
- state->sample_cnt + state->src_samples_per_frame,
- ARRAY_SIZE(state->samples));
- return -ENOSPC;
- }
- switch (state->src_fmt) {
- case AF_GSM:
- if (gsm_decode(state->src.gsm_handle,
- (gsm_byte *)*src, state->samples + state->sample_cnt) < 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to decode GSM.\n");
- return -EINVAL;
- }
- break;
-#ifdef HAVE_BCG729
- case AF_G729:
- bcg729Decoder(state->src.g729_dec, *src, 0, state->samples + state->sample_cnt);
- break;
-#endif
- case AF_PCMU:
- ulaw_decode(*src, state->samples + state->sample_cnt,
- state->src_samples_per_frame);
- break;
- case AF_PCMA:
- alaw_decode(*src, state->samples + state->sample_cnt,
- state->src_samples_per_frame);
- break;
- case AF_S16:
- memmove(state->samples + state->sample_cnt, *src,
- state->src_frame_size);
- break;
- case AF_L16:
- l16_decode(*src, state->samples + state->sample_cnt,
- state->src_samples_per_frame);
- break;
- default:
- break;
- }
- *src += state->src_frame_size;
- *nbytes -= state->src_frame_size;
- state->sample_cnt += state->src_samples_per_frame;
- }
- return 0;
-}
-
-static int encode_audio(struct mgcp_process_rtp_state *state,
- uint8_t *dst, size_t buf_size, size_t max_samples)
-{
- int nbytes = 0;
- size_t nsamples = 0;
- /* Encode samples into dst */
- while (nsamples + state->dst_samples_per_frame <= max_samples) {
- if (nbytes + state->dst_frame_size > buf_size) {
- if (nbytes > 0)
- break;
-
- /* Not even one frame fits into the buffer */
- LOGP(DMGCP, LOGL_INFO,
- "Encoding (RTP) buffer too small: %zu > %zu.\n",
- nbytes + state->dst_frame_size, buf_size);
- return -ENOSPC;
- }
- switch (state->dst_fmt) {
- case AF_GSM:
- gsm_encode(state->dst.gsm_handle,
- state->samples + state->sample_offs, dst);
- break;
-#ifdef HAVE_BCG729
- case AF_G729:
- bcg729Encoder(state->dst.g729_enc,
- state->samples + state->sample_offs, dst);
- break;
-#endif
- case AF_PCMU:
- ulaw_encode(state->samples + state->sample_offs, dst,
- state->src_samples_per_frame);
- break;
- case AF_PCMA:
- alaw_encode(state->samples + state->sample_offs, dst,
- state->src_samples_per_frame);
- break;
- case AF_S16:
- memmove(dst, state->samples + state->sample_offs,
- state->dst_frame_size);
- break;
- case AF_L16:
- l16_encode(state->samples + state->sample_offs, dst,
- state->src_samples_per_frame);
- break;
- default:
- break;
- }
- dst += state->dst_frame_size;
- nbytes += state->dst_frame_size;
- state->sample_offs += state->dst_samples_per_frame;
- nsamples += state->dst_samples_per_frame;
- }
- state->sample_cnt -= nsamples;
- return nbytes;
-}
-
-static struct mgcp_rtp_end *source_for_dest(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end)
-{
- if (&endp->bts_end == dst_end)
- return &endp->net_end;
- else if (&endp->net_end == dst_end)
- return &endp->bts_end;
- OSMO_ASSERT(0);
-}
-
-/*
- * With some modems we get offered multiple codecs
- * and we have selected one of them. It might not
- * be the right one and we need to detect this with
- * the first audio packets. One difficulty is that
- * we patch the rtp payload type in place, so we
- * need to discuss this.
- */
-struct mgcp_process_rtp_state *check_transcode_state(
- struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- struct rtp_hdr *rtp_hdr)
-{
- struct mgcp_rtp_end *src_end;
-
- /* Only deal with messages from net to bts */
- if (&endp->bts_end != dst_end)
- goto done;
-
- src_end = source_for_dest(endp, dst_end);
-
- /* Already patched */
- if (rtp_hdr->payload_type == dst_end->codec.payload_type)
- goto done;
- /* The payload we expect */
- if (rtp_hdr->payload_type == src_end->codec.payload_type)
- goto done;
- /* The matching alternate payload type? Then switch */
- if (rtp_hdr->payload_type == src_end->alt_codec.payload_type) {
- struct mgcp_config *cfg = endp->cfg;
- struct mgcp_rtp_codec tmp_codec = src_end->alt_codec;
- src_end->alt_codec = src_end->codec;
- src_end->codec = tmp_codec;
- cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end);
- cfg->setup_rtp_processing_cb(endp, &endp->bts_end, &endp->net_end);
- }
-
-done:
- return dst_end->rtp_process_data;
-}
-
-int mgcp_transcoding_process_rtp(struct mgcp_endpoint *endp,
- struct mgcp_rtp_end *dst_end,
- char *data, int *len, int buf_size)
-{
- struct mgcp_process_rtp_state *state;
- const size_t rtp_hdr_size = sizeof(struct rtp_hdr);
- struct rtp_hdr *rtp_hdr = (struct rtp_hdr *) data;
- char *payload_data = (char *) &rtp_hdr->data[0];
- int payload_len = *len - rtp_hdr_size;
- uint8_t *src = (uint8_t *)payload_data;
- uint8_t *dst = (uint8_t *)payload_data;
- size_t nbytes = payload_len;
- size_t nsamples;
- size_t max_samples;
- uint32_t ts_no;
- int rc;
-
- state = check_transcode_state(endp, dst_end, rtp_hdr);
- if (!state)
- return 0;
-
- if (state->src_fmt == state->dst_fmt) {
- if (!state->dst_packet_duration)
- return 0;
-
- /* TODO: repackage without transcoding */
- }
-
- /* If the remaining samples do not fit into a fixed ptime,
- * a) discard them, if the next packet is much later
- * b) add silence and * send it, if the current packet is not
- * yet too late
- * c) append the sample data, if the timestamp matches exactly
- */
-
- /* TODO: check payload type (-> G.711 comfort noise) */
-
- if (payload_len > 0) {
- ts_no = ntohl(rtp_hdr->timestamp);
- if (!state->is_running) {
- state->next_seq = ntohs(rtp_hdr->sequence);
- state->next_time = ts_no;
- state->is_running = 1;
- }
-
-
- if (state->sample_cnt > 0) {
- int32_t delta = ts_no - state->next_time;
- /* TODO: check sequence? reordering? packet loss? */
-
- if (delta > state->sample_cnt) {
- /* There is a time gap between the last packet
- * and the current one. Just discard the
- * partial data that is left in the buffer.
- * TODO: This can be improved by adding silence
- * instead if the delta is small enough.
- */
- LOGP(DMGCP, LOGL_NOTICE,
- "0x%x dropping sample buffer due delta=%d sample_cnt=%zu\n",
- ENDPOINT_NUMBER(endp), delta, state->sample_cnt);
- state->sample_cnt = 0;
- state->next_time = ts_no;
- } else if (delta < 0) {
- LOGP(DMGCP, LOGL_NOTICE,
- "RTP time jumps backwards, delta = %d, "
- "discarding buffered samples\n",
- delta);
- state->sample_cnt = 0;
- state->sample_offs = 0;
- return -EAGAIN;
- }
-
- /* Make sure the samples start without offset */
- if (state->sample_offs && state->sample_cnt)
- memmove(&state->samples[0],
- &state->samples[state->sample_offs],
- state->sample_cnt *
- sizeof(state->samples[0]));
- }
-
- state->sample_offs = 0;
-
- /* Append decoded audio to samples */
- decode_audio(state, &src, &nbytes);
-
- if (nbytes > 0)
- LOGP(DMGCP, LOGL_NOTICE,
- "Skipped audio frame in RTP packet: %zu octets\n",
- nbytes);
- } else
- ts_no = state->next_time;
-
- if (state->sample_cnt < state->dst_packet_duration)
- return -EAGAIN;
-
- max_samples =
- state->dst_packet_duration ?
- state->dst_packet_duration : state->sample_cnt;
-
- nsamples = state->sample_cnt;
-
- rc = encode_audio(state, dst, buf_size, max_samples);
- /*
- * There were no samples to encode?
- * TODO: how does this work for comfort noise?
- */
- if (rc == 0)
- return -ENOMSG;
- /* Any other error during the encoding */
- if (rc < 0)
- return rc;
-
- nsamples -= state->sample_cnt;
-
- *len = rtp_hdr_size + rc;
- rtp_hdr->sequence = htons(state->next_seq);
- rtp_hdr->timestamp = htonl(ts_no);
-
- state->next_seq += 1;
- state->next_time = ts_no + nsamples;
-
- /*
- * XXX: At this point we should always have consumed
- * samples. So doing OSMO_ASSERT(nsamples > 0) and returning
- * rtp_hdr_size should be fine.
- */
- return nsamples ? rtp_hdr_size : 0;
-}
diff --git a/src/libmgcp/mgcp_vty.c b/src/libmgcp/mgcp_vty.c
deleted file mode 100644
index 51889d9a4..000000000
--- a/src/libmgcp/mgcp_vty.c
+++ /dev/null
@@ -1,1555 +0,0 @@
-/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
-/* The protocol implementation */
-
-/*
- * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2011 by On-Waves
- * 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/core/talloc.h>
-
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-#include <openbsc/vty.h>
-
-#include <string.h>
-
-#define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
-#define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
-#define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"
-
-static struct mgcp_config *g_cfg = NULL;
-
-static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
-{
- struct mgcp_trunk_config *trunk;
-
- if (nr == 0)
- trunk = &cfg->trunk;
- else
- trunk = mgcp_trunk_num(cfg, nr);
-
- return trunk;
-}
-
-/*
- * vty code for mgcp below
- */
-struct cmd_node mgcp_node = {
- MGCP_NODE,
- "%s(config-mgcp)# ",
- 1,
-};
-
-struct cmd_node trunk_node = {
- TRUNK_NODE,
- "%s(config-mgcp-trunk)# ",
- 1,
-};
-
-static int config_write_mgcp(struct vty *vty)
-{
- vty_out(vty, "mgcp%s", VTY_NEWLINE);
- if (g_cfg->local_ip)
- vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE);
- if (g_cfg->bts_ip && strlen(g_cfg->bts_ip) != 0)
- vty_out(vty, " bts ip %s%s", g_cfg->bts_ip, VTY_NEWLINE);
- vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
- vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
-
- if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC)
- vty_out(vty, " rtp bts-base %u%s", g_cfg->bts_ports.base_port, VTY_NEWLINE);
- else
- vty_out(vty, " rtp bts-range %u %u%s",
- g_cfg->bts_ports.range_start, g_cfg->bts_ports.range_end, VTY_NEWLINE);
- if (g_cfg->bts_ports.bind_addr)
- vty_out(vty, " rtp bts-bind-ip %s%s", g_cfg->bts_ports.bind_addr, VTY_NEWLINE);
-
- if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC)
- vty_out(vty, " rtp net-base %u%s", g_cfg->net_ports.base_port, VTY_NEWLINE);
- else
- vty_out(vty, " rtp net-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)
- vty_out(vty, " rtp net-bind-ip %s%s", g_cfg->net_ports.bind_addr, VTY_NEWLINE);
-
- vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
- if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
- vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
- else if (g_cfg->trunk.keepalive_interval)
- vty_out(vty, " rtp keep-alive %d%s",
- g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
- else
- vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
-
- if (g_cfg->trunk.omit_rtcp)
- vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
- else
- vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
- if (g_cfg->trunk.force_constant_ssrc || g_cfg->trunk.force_aligned_timing) {
- vty_out(vty, " %srtp-patch ssrc%s",
- g_cfg->trunk.force_constant_ssrc ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %srtp-patch timestamp%s",
- g_cfg->trunk.force_aligned_timing ? "" : "no ", VTY_NEWLINE);
- } else
- vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
- if (g_cfg->trunk.audio_payload != -1)
- vty_out(vty, " sdp audio-payload number %d%s",
- g_cfg->trunk.audio_payload, VTY_NEWLINE);
- if (g_cfg->trunk.audio_name)
- vty_out(vty, " sdp audio-payload name %s%s",
- g_cfg->trunk.audio_name, VTY_NEWLINE);
- if (g_cfg->trunk.audio_fmtp_extra)
- vty_out(vty, " sdp audio fmtp-extra %s%s",
- g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
- vty_out(vty, " %ssdp audio-payload send-ptime%s",
- g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %ssdp audio-payload send-name%s",
- g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " loop %u%s", !!g_cfg->trunk.audio_loop, VTY_NEWLINE);
- vty_out(vty, " number endpoints %u%s", g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
- vty_out(vty, " %sallow-transcoding%s",
- g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
- if (g_cfg->call_agent_addr)
- vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
- if (g_cfg->transcoder_ip)
- vty_out(vty, " transcoder-mgw %s%s", g_cfg->transcoder_ip, VTY_NEWLINE);
-
- if (g_cfg->transcoder_ports.mode == PORT_ALLOC_STATIC)
- vty_out(vty, " rtp transcoder-base %u%s", g_cfg->transcoder_ports.base_port, VTY_NEWLINE);
- else
- vty_out(vty, " rtp transcoder-range %u %u%s",
- g_cfg->transcoder_ports.range_start, g_cfg->transcoder_ports.range_end, VTY_NEWLINE);
- if (g_cfg->bts_force_ptime > 0)
- vty_out(vty, " rtp force-ptime %d%s", g_cfg->bts_force_ptime, VTY_NEWLINE);
- vty_out(vty, " transcoder-remote-base %u%s", g_cfg->transcoder_remote_base, VTY_NEWLINE);
-
- switch (g_cfg->osmux) {
- case OSMUX_USAGE_ON:
- vty_out(vty, " osmux on%s", VTY_NEWLINE);
- break;
- case OSMUX_USAGE_ONLY:
- vty_out(vty, " osmux only%s", VTY_NEWLINE);
- break;
- case OSMUX_USAGE_OFF:
- default:
- vty_out(vty, " osmux off%s", VTY_NEWLINE);
- break;
- }
- if (g_cfg->osmux) {
- vty_out(vty, " osmux bind-ip %s%s",
- g_cfg->osmux_addr, VTY_NEWLINE);
- vty_out(vty, " osmux batch-factor %d%s",
- g_cfg->osmux_batch, VTY_NEWLINE);
- vty_out(vty, " osmux batch-size %u%s",
- g_cfg->osmux_batch_size, VTY_NEWLINE);
- vty_out(vty, " osmux port %u%s",
- g_cfg->osmux_port, VTY_NEWLINE);
- vty_out(vty, " osmux dummy %s%s",
- g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
- }
- return CMD_SUCCESS;
-}
-
-static void dump_rtp_end(const char *end_name, struct vty *vty,
- struct mgcp_rtp_state *state, struct mgcp_rtp_end *end)
-{
- struct mgcp_rtp_codec *codec = &end->codec;
-
- vty_out(vty,
- " %s%s"
- " Timestamp Errs: %d->%d%s"
- " Dropped Packets: %d%s"
- " Payload Type: %d Rate: %u Channels: %d %s"
- " Frame Duration: %u Frame Denominator: %u%s"
- " FPP: %d Packet Duration: %u%s"
- " FMTP-Extra: %s Audio-Name: %s Sub-Type: %s%s"
- " Output-Enabled: %d Force-PTIME: %d%s",
- end_name, VTY_NEWLINE,
- state->in_stream.err_ts_counter,
- state->out_stream.err_ts_counter, VTY_NEWLINE,
- end->dropped_packets, VTY_NEWLINE,
- codec->payload_type, codec->rate, codec->channels, VTY_NEWLINE,
- codec->frame_duration_num, codec->frame_duration_den, VTY_NEWLINE,
- end->frames_per_packet, end->packet_duration_ms, VTY_NEWLINE,
- end->fmtp_extra, codec->audio_name, codec->subtype_name, VTY_NEWLINE,
- end->output_enabled, end->force_output_ptime, VTY_NEWLINE);
-}
-
-static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int verbose)
-{
- int i;
-
- vty_out(vty, "%s trunk nr %d with %d endpoints:%s",
- cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
- cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
-
- if (!cfg->endpoints) {
- vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
- return;
- }
-
- for (i = 1; i < cfg->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &cfg->endpoints[i];
- vty_out(vty,
- " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s "
- "traffic received bts: %u remote: %u transcoder: %u/%u%s",
- i, endp->ci,
- ntohs(endp->net_end.rtp_port), ntohs(endp->net_end.rtcp_port),
- ntohs(endp->bts_end.rtp_port), ntohs(endp->bts_end.rtcp_port),
- inet_ntoa(endp->bts_end.addr),
- endp->bts_end.packets, endp->net_end.packets,
- endp->trans_net.packets, endp->trans_bts.packets,
- VTY_NEWLINE);
-
- if (verbose && endp->allocated) {
- dump_rtp_end("Net->BTS", vty, &endp->bts_state, &endp->bts_end);
- dump_rtp_end("BTS->Net", vty, &endp->net_state, &endp->net_end);
- }
- }
-}
-
-DEFUN(show_mcgp, show_mgcp_cmd,
- "show mgcp [stats]",
- SHOW_STR
- "Display information about the MGCP Media Gateway\n"
- "Include Statistics\n")
-{
- struct mgcp_trunk_config *trunk;
- int show_stats = argc >= 1;
-
- dump_trunk(vty, &g_cfg->trunk, show_stats);
-
- llist_for_each_entry(trunk, &g_cfg->trunks, entry)
- dump_trunk(vty, trunk, show_stats);
-
- if (g_cfg->osmux)
- vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(), VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp,
- cfg_mgcp_cmd,
- "mgcp",
- "Configure the MGCP")
-{
- vty->node = MGCP_NODE;
- return CMD_SUCCESS;
-}
-
-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;
-}
-
-DEFUN(cfg_mgcp_bts_ip,
- cfg_mgcp_bts_ip_cmd,
- "bts ip A.B.C.D",
- "BTS Audio source/destination options\n"
- IP_STR
- "IPv4 Address of the BTS\n")
-{
- osmo_talloc_replace_string(g_cfg, &g_cfg->bts_ip, argv[0]);
- inet_aton(g_cfg->bts_ip, &g_cfg->bts_in);
- return CMD_SUCCESS;
-}
-
-#define BIND_STR "Listen/Bind related socket option\n"
-DEFUN(cfg_mgcp_bind_ip,
- cfg_mgcp_bind_ip_cmd,
- "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;
-}
-
-DEFUN(cfg_mgcp_bind_port,
- cfg_mgcp_bind_port_cmd,
- "bind port <0-65534>",
- BIND_STR
- "Port information\n"
- "UDP port to listen for MGCP messages\n")
-{
- unsigned int port = atoi(argv[0]);
- g_cfg->source_port = port;
- return CMD_SUCCESS;
-}
-
-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")
-{
- vty_out(vty, "bind early is deprecated, remove it from the config.\n");
- return CMD_WARNING;
-}
-
-static void parse_base(struct mgcp_port_range *range, const char **argv)
-{
- unsigned int port = atoi(argv[0]);
- range->mode = PORT_ALLOC_STATIC;
- range->base_port = port;
-}
-
-static void parse_range(struct mgcp_port_range *range, const char **argv)
-{
- range->mode = PORT_ALLOC_DYNAMIC;
- range->range_start = atoi(argv[0]);
- range->range_end = atoi(argv[1]);
- range->last_port = g_cfg->bts_ports.range_start;
-}
-
-
-#define RTP_STR "RTP configuration\n"
-#define BTS_START_STR "First UDP port allocated for the BTS side\n"
-#define NET_START_STR "First UDP port allocated for the NET side\n"
-#define UDP_PORT_STR "UDP Port number\n"
-DEFUN(cfg_mgcp_rtp_bts_base_port,
- cfg_mgcp_rtp_bts_base_port_cmd,
- "rtp bts-base <0-65534>",
- RTP_STR
- BTS_START_STR
- UDP_PORT_STR)
-{
- parse_base(&g_cfg->bts_ports, argv);
- return CMD_SUCCESS;
-}
-
-#define RANGE_START_STR "Start of the range of ports\n"
-#define RANGE_END_STR "End of the range of ports\n"
-DEFUN(cfg_mgcp_rtp_bts_range,
- cfg_mgcp_rtp_bts_range_cmd,
- "rtp bts-range <0-65534> <0-65534>",
- RTP_STR "Range of ports to use for the BTS side\n"
- RANGE_START_STR RANGE_END_STR)
-{
- parse_range(&g_cfg->bts_ports, argv);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_net_range,
- cfg_mgcp_rtp_net_range_cmd,
- "rtp net-range <0-65534> <0-65534>",
- RTP_STR "Range of ports to use for the NET side\n"
- RANGE_START_STR RANGE_END_STR)
-{
- parse_range(&g_cfg->net_ports, argv);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_net_base_port,
- cfg_mgcp_rtp_net_base_port_cmd,
- "rtp net-base <0-65534>",
- RTP_STR NET_START_STR UDP_PORT_STR)
-{
- parse_base(&g_cfg->net_ports, argv);
- return CMD_SUCCESS;
-}
-
-ALIAS_DEPRECATED(cfg_mgcp_rtp_bts_base_port, cfg_mgcp_rtp_base_port_cmd,
- "rtp base <0-65534>",
- RTP_STR BTS_START_STR UDP_PORT_STR)
-
-DEFUN(cfg_mgcp_rtp_transcoder_range,
- cfg_mgcp_rtp_transcoder_range_cmd,
- "rtp transcoder-range <0-65534> <0-65534>",
- RTP_STR "Range of ports to use for the Transcoder\n"
- RANGE_START_STR RANGE_END_STR)
-{
- parse_range(&g_cfg->transcoder_ports, argv);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_transcoder_base,
- cfg_mgcp_rtp_transcoder_base_cmd,
- "rtp transcoder-base <0-65534>",
- RTP_STR "First UDP port allocated for the Transcoder side\n"
- UDP_PORT_STR)
-{
- parse_base(&g_cfg->transcoder_ports, argv);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_bts_bind_ip,
- cfg_mgcp_rtp_bts_bind_ip_cmd,
- "rtp bts-bind-ip A.B.C.D",
- RTP_STR "Bind endpoints facing the BTS\n" "Address to bind to\n")
-{
- osmo_talloc_replace_string(g_cfg, &g_cfg->bts_ports.bind_addr, argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_no_bts_bind_ip,
- cfg_mgcp_rtp_no_bts_bind_ip_cmd,
- "no rtp bts-bind-ip",
- NO_STR RTP_STR "Bind endpoints facing the BTS\n" "Address to bind to\n")
-{
- talloc_free(g_cfg->bts_ports.bind_addr);
- g_cfg->bts_ports.bind_addr = NULL;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_net_bind_ip,
- cfg_mgcp_rtp_net_bind_ip_cmd,
- "rtp net-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, argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_rtp_no_net_bind_ip,
- cfg_mgcp_rtp_no_net_bind_ip_cmd,
- "no rtp net-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);
- g_cfg->net_ports.bind_addr = NULL;
- return CMD_SUCCESS;
-}
-
-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;
- return CMD_SUCCESS;
-}
-
-ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd,
- "rtp ip-tos <0-255>",
- 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 to the BTS"
-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->bts_force_ptime = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-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->bts_force_ptime = 0;
- return CMD_SUCCESS;
-}
-
-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")
-{
- char *txt = argv_concat(argv, argc, 0);
- if (!txt)
- return CMD_WARNING;
-
- osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
- talloc_free(txt);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_allow_transcoding,
- cfg_mgcp_allow_transcoding_cmd,
- "allow-transcoding",
- "Allow transcoding\n")
-{
- g_cfg->trunk.no_audio_transcoding = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_no_allow_transcoding,
- cfg_mgcp_no_allow_transcoding_cmd,
- "no allow-transcoding",
- NO_STR "Allow transcoding\n")
-{
- g_cfg->trunk.no_audio_transcoding = 1;
- return CMD_SUCCESS;
-}
-
-#define SDP_STR "SDP File related options\n"
-#define AUDIO_STR "Audio payload options\n"
-DEFUN(cfg_mgcp_sdp_payload_number,
- cfg_mgcp_sdp_payload_number_cmd,
- "sdp audio-payload number <0-255>",
- SDP_STR AUDIO_STR
- "Number\n" "Payload number\n")
-{
- unsigned int payload = atoi(argv[0]);
- g_cfg->trunk.audio_payload = payload;
- return CMD_SUCCESS;
-}
-
-ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_number, cfg_mgcp_sdp_payload_number_cmd_old,
- "sdp audio payload number <0-255>",
- SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload number\n")
-
-
-DEFUN(cfg_mgcp_sdp_payload_name,
- cfg_mgcp_sdp_payload_name_cmd,
- "sdp audio-payload name NAME",
- SDP_STR AUDIO_STR "Name\n" "Payload name\n")
-{
- osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
- return CMD_SUCCESS;
-}
-
-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(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")
-{
- g_cfg->trunk.audio_send_ptime = 1;
- return CMD_SUCCESS;
-}
-
-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")
-{
- g_cfg->trunk.audio_send_ptime = 0;
- return CMD_SUCCESS;
-}
-
-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")
-{
- g_cfg->trunk.audio_send_name = 1;
- return CMD_SUCCESS;
-}
-
-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")
-{
- g_cfg->trunk.audio_send_name = 0;
- return CMD_SUCCESS;
-}
-
-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")
-{
- if (g_cfg->osmux) {
- vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- g_cfg->trunk.audio_loop = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-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")
-{
- g_cfg->trunk.force_realloc = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_number_endp,
- cfg_mgcp_number_endp_cmd,
- "number endpoints <0-65534>",
- "Number options\n" "Endpoints available\n" "Number endpoints\n")
-{
- /* + 1 as we start counting at one */
- g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_omit_rtcp,
- cfg_mgcp_omit_rtcp_cmd,
- "rtcp-omit",
- RTCP_OMIT_STR)
-{
- g_cfg->trunk.omit_rtcp = 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_no_omit_rtcp,
- cfg_mgcp_no_omit_rtcp_cmd,
- "no rtcp-omit",
- NO_STR RTCP_OMIT_STR)
-{
- g_cfg->trunk.omit_rtcp = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_patch_rtp_ssrc,
- cfg_mgcp_patch_rtp_ssrc_cmd,
- "rtp-patch ssrc",
- RTP_PATCH_STR
- "Force a fixed SSRC\n"
- )
-{
- g_cfg->trunk.force_constant_ssrc = 1;
- return CMD_SUCCESS;
-}
-
-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"
- )
-{
- g_cfg->trunk.force_constant_ssrc = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_patch_rtp_ts,
- cfg_mgcp_patch_rtp_ts_cmd,
- "rtp-patch timestamp",
- RTP_PATCH_STR
- "Adjust RTP timestamp\n"
- )
-{
- g_cfg->trunk.force_aligned_timing = 1;
- return CMD_SUCCESS;
-}
-
-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"
- )
-{
- g_cfg->trunk.force_aligned_timing = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_no_patch_rtp,
- cfg_mgcp_no_patch_rtp_cmd,
- "no rtp-patch",
- NO_STR RTP_PATCH_STR)
-{
- g_cfg->trunk.force_constant_ssrc = 0;
- g_cfg->trunk.force_aligned_timing = 0;
- return CMD_SUCCESS;
-}
-
-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"
- )
-{
- mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
-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"
- )
-{
- mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_no_rtp_keepalive,
- cfg_mgcp_no_rtp_keepalive_cmd,
- "no rtp keep-alive",
- NO_STR RTP_STR RTP_KEEPALIVE_STR
- )
-{
- mgcp_trunk_set_keepalive(&g_cfg->trunk, 0);
- return CMD_SUCCESS;
-}
-
-
-
-#define CALL_AGENT_STR "Callagent information\n"
-DEFUN(cfg_mgcp_agent_addr,
- cfg_mgcp_agent_addr_cmd,
- "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;
-}
-
-ALIAS_DEPRECATED(cfg_mgcp_agent_addr, cfg_mgcp_agent_addr_cmd_old,
- "call agent ip A.B.C.D",
- CALL_AGENT_STR CALL_AGENT_STR IP_STR
- "IPv4 Address of the callagent\n")
-
-
-DEFUN(cfg_mgcp_transcoder,
- cfg_mgcp_transcoder_cmd,
- "transcoder-mgw A.B.C.D",
- "Use a MGW to detranscoder RTP\n"
- "The IP address of the MGW")
-{
- osmo_talloc_replace_string(g_cfg, &g_cfg->transcoder_ip, argv[0]);
- inet_aton(g_cfg->transcoder_ip, &g_cfg->transcoder_in);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_no_transcoder,
- cfg_mgcp_no_transcoder_cmd,
- "no transcoder-mgw",
- NO_STR "Disable the transcoding\n")
-{
- if (g_cfg->transcoder_ip) {
- LOGP(DMGCP, LOGL_NOTICE, "Disabling transcoding on future calls.\n");
- talloc_free(g_cfg->transcoder_ip);
- g_cfg->transcoder_ip = NULL;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_transcoder_remote_base,
- cfg_mgcp_transcoder_remote_base_cmd,
- "transcoder-remote-base <0-65534>",
- "Set the base port for the transcoder\n" "The RTP base port on the transcoder")
-{
- g_cfg->transcoder_remote_base = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
- "trunk <1-64>",
- "Configure a SS7 trunk\n" "Trunk Nr\n")
-{
- struct mgcp_trunk_config *trunk;
- int index = atoi(argv[0]);
-
- trunk = mgcp_trunk_num(g_cfg, index);
- if (!trunk)
- trunk = mgcp_trunk_alloc(g_cfg, index);
-
- if (!trunk) {
- vty_out(vty, "%%Unable to allocate trunk %u.%s",
- index, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- vty->node = TRUNK_NODE;
- vty->index = trunk;
- return CMD_SUCCESS;
-}
-
-static int config_write_trunk(struct vty *vty)
-{
- struct mgcp_trunk_config *trunk;
-
- llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
- vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
- vty_out(vty, " sdp audio-payload number %d%s",
- trunk->audio_payload, VTY_NEWLINE);
- vty_out(vty, " sdp audio-payload name %s%s",
- trunk->audio_name, VTY_NEWLINE);
- vty_out(vty, " %ssdp audio-payload send-ptime%s",
- trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %ssdp audio-payload send-name%s",
- trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
-
- if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
- vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
- else if (trunk->keepalive_interval)
- vty_out(vty, " rtp keep-alive %d%s",
- 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);
- if (trunk->omit_rtcp)
- vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
- else
- vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
- if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {
- vty_out(vty, " %srtp-patch ssrc%s",
- trunk->force_constant_ssrc ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %srtp-patch timestamp%s",
- trunk->force_aligned_timing ? "" : "no ", VTY_NEWLINE);
- } else
- vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
- if (trunk->audio_fmtp_extra)
- vty_out(vty, " sdp audio fmtp-extra %s%s",
- trunk->audio_fmtp_extra, VTY_NEWLINE);
- vty_out(vty, " %sallow-transcoding%s",
- trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- char *txt = argv_concat(argv, argc, 0);
- if (!txt)
- return CMD_WARNING;
-
- osmo_talloc_replace_string(g_cfg, &trunk->audio_fmtp_extra, txt);
- talloc_free(txt);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trunk_payload_number,
- cfg_trunk_payload_number_cmd,
- "sdp audio-payload number <0-255>",
- SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
-{
- struct mgcp_trunk_config *trunk = vty->index;
- unsigned int payload = atoi(argv[0]);
-
- trunk->audio_payload = payload;
- return CMD_SUCCESS;
-}
-
-ALIAS_DEPRECATED(cfg_trunk_payload_number, cfg_trunk_payload_number_cmd_old,
- "sdp audio payload number <0-255>",
- SDP_STR AUDIO_STR AUDIO_STR "Number\n" "Payload Number\n")
-
-DEFUN(cfg_trunk_payload_name,
- cfg_trunk_payload_name_cmd,
- "sdp audio-payload name NAME",
- SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
-{
- struct mgcp_trunk_config *trunk = vty->index;
-
- osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
- return CMD_SUCCESS;
-}
-
-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(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_config *trunk = vty->index;
-
- 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(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_config *trunk = vty->index;
- trunk->audio_send_ptime = 1;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->audio_send_ptime = 0;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->audio_send_name = 1;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->audio_send_name = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trunk_omit_rtcp,
- cfg_trunk_omit_rtcp_cmd,
- "rtcp-omit",
- RTCP_OMIT_STR)
-{
- struct mgcp_trunk_config *trunk = vty->index;
- trunk->omit_rtcp = 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trunk_no_omit_rtcp,
- cfg_trunk_no_omit_rtcp_cmd,
- "no rtcp-omit",
- NO_STR RTCP_OMIT_STR)
-{
- struct mgcp_trunk_config *trunk = vty->index;
- trunk->omit_rtcp = 0;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->force_constant_ssrc = 1;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->force_constant_ssrc = 0;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->force_aligned_timing = 1;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- trunk->force_aligned_timing = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trunk_no_patch_rtp,
- cfg_trunk_no_patch_rtp_cmd,
- "no rtp-patch",
- NO_STR RTP_PATCH_STR)
-{
- struct mgcp_trunk_config *trunk = vty->index;
- trunk->force_constant_ssrc = 0;
- trunk->force_aligned_timing = 0;
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
- return CMD_SUCCESS;
-}
-
-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_config *trunk = vty->index;
- mgcp_trunk_set_keepalive(trunk, 0);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trunk_allow_transcoding,
- cfg_trunk_allow_transcoding_cmd,
- "allow-transcoding",
- "Allow transcoding\n")
-{
- struct mgcp_trunk_config *trunk = vty->index;
- trunk->no_audio_transcoding = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trunk_no_allow_transcoding,
- cfg_trunk_no_allow_transcoding_cmd,
- "no allow-transcoding",
- NO_STR "Allow transcoding\n")
-{
- struct mgcp_trunk_config *trunk = vty->index;
- trunk->no_audio_transcoding = 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(loop_endp,
- loop_endp_cmd,
- "loop-endpoint <0-64> NAME (0|1)",
- "Loop a given endpoint\n" "Trunk number\n"
- "The name in hex of the endpoint\n" "Disable the loop\n" "Enable the loop\n")
-{
- struct mgcp_trunk_config *trunk;
- struct mgcp_endpoint *endp;
-
- trunk = find_trunk(g_cfg, atoi(argv[0]));
- if (!trunk) {
- vty_out(vty, "%%Trunk %d not found in the config.%s",
- atoi(argv[0]), VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!trunk->endpoints) {
- vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
- trunk->trunk_nr, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- int endp_no = strtoul(argv[1], NULL, 16);
- if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
- vty_out(vty, "Loopback number %s/%d is invalid.%s",
- argv[1], endp_no, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
-
- endp = &trunk->endpoints[endp_no];
- int loop = atoi(argv[2]);
-
- if (loop)
- endp->conn_mode = MGCP_CONN_LOOPBACK;
- else
- endp->conn_mode = endp->orig_mode;
-
- /* Handle it like a MDCX, switch on SSRC patching if enabled */
- mgcp_rtp_end_config(endp, 1, &endp->bts_end);
- mgcp_rtp_end_config(endp, 1, &endp->net_end);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(tap_call,
- tap_call_cmd,
- "tap-call <0-64> ENDPOINT (bts-in|bts-out|net-in|net-out) A.B.C.D <0-65534>",
- "Forward data on endpoint to a different system\n" "Trunk number\n"
- "The endpoint in hex\n"
- "Forward the data coming from the bts\n"
- "Forward the data coming from the bts leaving to the network\n"
- "Forward the data coming from the net\n"
- "Forward the data coming from the net leaving to the bts\n"
- "destination IP of the data\n" "destination port\n")
-{
- struct mgcp_rtp_tap *tap;
- struct mgcp_trunk_config *trunk;
- struct mgcp_endpoint *endp;
- int port = 0;
-
- trunk = find_trunk(g_cfg, atoi(argv[0]));
- if (!trunk) {
- vty_out(vty, "%%Trunk %d not found in the config.%s",
- atoi(argv[0]), VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!trunk->endpoints) {
- vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
- trunk->trunk_nr, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- int endp_no = strtoul(argv[1], NULL, 16);
- if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
- vty_out(vty, "Endpoint number %s/%d is invalid.%s",
- argv[1], endp_no, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- endp = &trunk->endpoints[endp_no];
-
- if (strcmp(argv[2], "bts-in") == 0) {
- port = MGCP_TAP_BTS_IN;
- } else if (strcmp(argv[2], "bts-out") == 0) {
- port = MGCP_TAP_BTS_OUT;
- } else if (strcmp(argv[2], "net-in") == 0) {
- port = MGCP_TAP_NET_IN;
- } else if (strcmp(argv[2], "net-out") == 0) {
- port = MGCP_TAP_NET_OUT;
- } else {
- vty_out(vty, "Unknown mode... tricked vty?%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- tap = &endp->taps[port];
- memset(&tap->forward, 0, sizeof(tap->forward));
- inet_aton(argv[3], &tap->forward.sin_addr);
- tap->forward.sin_port = htons(atoi(argv[4]));
- tap->enabled = 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(free_endp, free_endp_cmd,
- "free-endpoint <0-64> NUMBER",
- "Free the given endpoint\n" "Trunk number\n"
- "Endpoint number in hex.\n")
-{
- struct mgcp_trunk_config *trunk;
- struct mgcp_endpoint *endp;
-
- trunk = find_trunk(g_cfg, atoi(argv[0]));
- if (!trunk) {
- vty_out(vty, "%%Trunk %d not found in the config.%s",
- atoi(argv[0]), VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!trunk->endpoints) {
- vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
- trunk->trunk_nr, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- int endp_no = strtoul(argv[1], NULL, 16);
- if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
- vty_out(vty, "Endpoint number %s/%d is invalid.%s",
- argv[1], endp_no, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- endp = &trunk->endpoints[endp_no];
- mgcp_release_endp(endp);
- return CMD_SUCCESS;
-}
-
-DEFUN(reset_endp, reset_endp_cmd,
- "reset-endpoint <0-64> NUMBER",
- "Reset the given endpoint\n" "Trunk number\n"
- "Endpoint number in hex.\n")
-{
- struct mgcp_trunk_config *trunk;
- struct mgcp_endpoint *endp;
- int endp_no, rc;
-
- trunk = find_trunk(g_cfg, atoi(argv[0]));
- if (!trunk) {
- vty_out(vty, "%%Trunk %d not found in the config.%s",
- atoi(argv[0]), VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!trunk->endpoints) {
- vty_out(vty, "%%Trunk %d has no endpoints allocated.%s",
- trunk->trunk_nr, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- endp_no = strtoul(argv[1], NULL, 16);
- if (endp_no < 1 || endp_no >= trunk->number_endpoints) {
- vty_out(vty, "Endpoint number %s/%d is invalid.%s",
- argv[1], endp_no, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- endp = &trunk->endpoints[endp_no];
- rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
- if (rc < 0) {
- vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN(reset_all_endp, reset_all_endp_cmd,
- "reset-all-endpoints",
- "Reset all endpoints\n")
-{
- int rc;
-
- rc = mgcp_send_reset_all(g_cfg);
- if (rc < 0) {
- vty_out(vty, "Error %d during endpoint reset.%s",
- rc, VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-#define OSMUX_STR "RTP multiplexing\n"
-DEFUN(cfg_mgcp_osmux,
- cfg_mgcp_osmux_cmd,
- "osmux (on|off|only)",
- OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
-{
- if (strcmp(argv[0], "off") == 0) {
- g_cfg->osmux = OSMUX_USAGE_OFF;
- return CMD_SUCCESS;
- }
-
- if (strcmp(argv[0], "on") == 0)
- g_cfg->osmux = OSMUX_USAGE_ON;
- else if (strcmp(argv[0], "only") == 0)
- g_cfg->osmux = OSMUX_USAGE_ONLY;
-
- if (g_cfg->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 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;
-}
-
-DEFUN(cfg_mgcp_osmux_batch_factor,
- cfg_mgcp_osmux_batch_factor_cmd,
- "osmux batch-factor <1-8>",
- OSMUX_STR "Batching factor\n" "Number of messages in the batch\n")
-{
- g_cfg->osmux_batch = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_osmux_batch_size,
- cfg_mgcp_osmux_batch_size_cmd,
- "osmux batch-size <1-65535>",
- OSMUX_STR "batch size\n" "Batch size in bytes\n")
-{
- g_cfg->osmux_batch_size = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_osmux_port,
- cfg_mgcp_osmux_port_cmd,
- "osmux port <1-65535>",
- OSMUX_STR "port\n" "UDP port\n")
-{
- g_cfg->osmux_port = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcp_osmux_dummy,
- cfg_mgcp_osmux_dummy_cmd,
- "osmux dummy (on|off)",
- OSMUX_STR "Dummy padding\n" "Enable dummy padding\n" "Disable dummy padding\n")
-{
- if (strcmp(argv[0], "on") == 0)
- g_cfg->osmux_dummy = 1;
- else if (strcmp(argv[0], "off") == 0)
- g_cfg->osmux_dummy = 0;
-
- return CMD_SUCCESS;
-}
-
-int mgcp_vty_init(void)
-{
- install_element_ve(&show_mgcp_cmd);
- install_element(ENABLE_NODE, &loop_endp_cmd);
- install_element(ENABLE_NODE, &tap_call_cmd);
- install_element(ENABLE_NODE, &free_endp_cmd);
- install_element(ENABLE_NODE, &reset_endp_cmd);
- install_element(ENABLE_NODE, &reset_all_endp_cmd);
-
- install_element(CONFIG_NODE, &cfg_mgcp_cmd);
- install_node(&mgcp_node, config_write_mgcp);
-
- vty_install_default(MGCP_NODE);
- install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_bts_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_base_port_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_net_base_port_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_range_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_bind_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_no_bts_bind_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_range_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_transcoder_base_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_rtp_force_ptime_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_rtp_keepalive_once_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_rtp_keepalive_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd_old);
- install_element(MGCP_NODE, &cfg_mgcp_transcoder_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_transcoder_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_transcoder_remote_base_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd_old);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd_old);
- install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_force_realloc_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_omit_rtcp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_omit_rtcp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ssrc_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ssrc_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_name_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_name_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_osmux_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_osmux_ip_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_factor_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_osmux_batch_size_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_osmux_port_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
- install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
-
-
- install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
- install_node(&trunk_node, config_write_trunk);
- vty_install_default(TRUNK_NODE);
- install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_rtp_keepalive_once_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_rtp_keepalive_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_payload_number_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_payload_name_cmd);
- 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_omit_rtcp_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_omit_rtcp_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_name_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_name_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_allow_transcoding_cmd);
- install_element(TRUNK_NODE, &cfg_trunk_no_allow_transcoding_cmd);
-
- return 0;
-}
-
-static int allocate_trunk(struct mgcp_trunk_config *trunk)
-{
- int i;
- struct mgcp_config *cfg = trunk->cfg;
-
- if (mgcp_endpoints_allocate(trunk) != 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to allocate %d endpoints on trunk %d.\n",
- trunk->number_endpoints, trunk->trunk_nr);
- return -1;
- }
-
- /* early bind */
- for (i = 1; i < trunk->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &trunk->endpoints[i];
-
- if (cfg->bts_ports.mode == PORT_ALLOC_STATIC) {
- cfg->last_bts_port += 2;
- if (mgcp_bind_bts_rtp_port(endp, cfg->last_bts_port) != 0) {
- LOGP(DMGCP, LOGL_FATAL,
- "Failed to bind: %d\n", cfg->last_bts_port);
- return -1;
- }
- endp->bts_end.local_alloc = PORT_ALLOC_STATIC;
- }
-
- if (cfg->net_ports.mode == PORT_ALLOC_STATIC) {
- cfg->last_net_port += 2;
- if (mgcp_bind_net_rtp_port(endp, cfg->last_net_port) != 0) {
- LOGP(DMGCP, LOGL_FATAL,
- "Failed to bind: %d\n", cfg->last_net_port);
- return -1;
- }
- endp->net_end.local_alloc = PORT_ALLOC_STATIC;
- }
-
- if (trunk->trunk_type == MGCP_TRUNK_VIRTUAL &&
- cfg->transcoder_ip && cfg->transcoder_ports.mode == PORT_ALLOC_STATIC) {
- int rtp_port;
-
- /* network side */
- rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
- cfg->transcoder_ports.base_port);
- if (mgcp_bind_trans_net_rtp_port(endp, rtp_port) != 0) {
- LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
- return -1;
- }
- endp->trans_net.local_alloc = PORT_ALLOC_STATIC;
-
- /* bts side */
- rtp_port = rtp_calculate_port(endp_back_channel(ENDPOINT_NUMBER(endp)),
- cfg->transcoder_ports.base_port);
- if (mgcp_bind_trans_bts_rtp_port(endp, rtp_port) != 0) {
- LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
- return -1;
- }
- endp->trans_bts.local_alloc = PORT_ALLOC_STATIC;
- }
- }
-
- return 0;
-}
-
-int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
- enum mgcp_role role)
-{
- int rc;
- struct mgcp_trunk_config *trunk;
-
- cfg->osmux_port = OSMUX_PORT;
- cfg->osmux_batch = 4;
- cfg->osmux_batch_size = OSMUX_BATCH_DEFAULT_MAX;
-
- g_cfg = cfg;
- rc = vty_read_config_file(config_file, NULL);
- if (rc < 0) {
- fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
- return rc;
- }
-
-
- if (!g_cfg->bts_ip)
- fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n");
-
- if (!g_cfg->source_addr) {
- fprintf(stderr, "You need to specify a bind address.\n");
- return -1;
- }
-
- /* initialize the last ports */
- g_cfg->last_bts_port = rtp_calculate_port(0, g_cfg->bts_ports.base_port);
- g_cfg->last_net_port = rtp_calculate_port(0, g_cfg->net_ports.base_port);
-
- if (allocate_trunk(&g_cfg->trunk) != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to initialize the virtual trunk.\n");
- return -1;
- }
-
- llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
- if (allocate_trunk(trunk) != 0) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to initialize E1 trunk %d.\n", trunk->trunk_nr);
- return -1;
- }
- }
- cfg->role = role;
-
- return 0;
-}
-
diff --git a/src/libmgcp/mgcpgw_client.c b/src/libmgcp/mgcpgw_client.c
deleted file mode 100644
index 1910a9f35..000000000
--- a/src/libmgcp/mgcpgw_client.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/* mgcp_utils - common functions to setup an MGCP connection
- */
-/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/core/select.h>
-#include <osmocom/core/write_queue.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-
-#include <openbsc/mgcpgw_client.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-#include <openbsc/debug.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-
-void mgcpgw_client_conf_init(struct mgcpgw_client_conf *conf)
-{
- /* NULL and -1 default to MGCPGW_CLIENT_*_DEFAULT values */
- *conf = (struct mgcpgw_client_conf){
- .local_addr = NULL,
- .local_port = -1,
- .remote_addr = NULL,
- .remote_port = -1,
- .first_endpoint = 0,
- .last_endpoint = 0,
- .bts_base = 0,
- };
-}
-
-/* Test if a given endpoint id is currently in use */
-static bool endpoint_in_use(uint16_t id, struct mgcpgw_client *client)
-{
- struct mgcp_inuse_endpoint *endpoint;
- llist_for_each_entry(endpoint, &client->inuse_endpoints, entry) {
- if (endpoint->id == id)
- return true;
- }
-
- return false;
-}
-
-/* Find and seize an unsused endpoint id */
-int mgcpgw_client_next_endpoint(struct mgcpgw_client *client)
-{
- int i;
- uint16_t first_endpoint = client->actual.first_endpoint;
- uint16_t last_endpoint = client->actual.last_endpoint;
- struct mgcp_inuse_endpoint *endpoint;
-
- /* Use the maximum permitted range if the VTY
- * configuration does not specify a range */
- if (client->actual.last_endpoint == 0) {
- first_endpoint = 1;
- last_endpoint = 65534;
- }
-
- /* Test the permitted endpoint range for an endpoint
- * number that is not in use. When a suitable endpoint
- * number can be found, seize it by adding it to the
- * inuse list. */
- for (i=first_endpoint;i<last_endpoint;i++)
- {
- if (endpoint_in_use(i,client) == false) {
- endpoint = talloc_zero(client, struct mgcp_inuse_endpoint);
- endpoint->id = i;
- llist_add_tail(&endpoint->entry, &client->inuse_endpoints);
- return endpoint->id;
- }
- }
-
- /* All endpoints are busy! */
- return -EINVAL;
-}
-
-/* Release a seized endpoint id to make it available again for other calls */
-void mgcpgw_client_release_endpoint(uint16_t id, struct mgcpgw_client *client)
-{
- struct mgcp_inuse_endpoint *endpoint;
- struct mgcp_inuse_endpoint *endpoint_tmp;
- llist_for_each_entry_safe(endpoint, endpoint_tmp, &client->inuse_endpoints, entry) {
- if (endpoint->id == id) {
- llist_del(&endpoint->entry);
- talloc_free(endpoint);
- }
- }
-}
-
-static void mgcpgw_client_handle_response(struct mgcpgw_client *mgcp,
- struct mgcp_response_pending *pending,
- struct mgcp_response *response)
-{
- if (!pending) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot handle NULL response\n");
- return;
- }
- if (pending->response_cb)
- pending->response_cb(response, pending->priv);
- else
- LOGP(DMGCP, LOGL_INFO, "MGCP response ignored (NULL cb)\n");
- talloc_free(pending);
-}
-
-static int mgcp_response_parse_head(struct mgcp_response *r, struct msgb *msg)
-{
- int comment_pos;
- char *end;
-
- if (mgcp_msg_terminate_nul(msg))
- goto response_parse_failure;
-
- r->body = (char *)msg->data;
-
- if (sscanf(r->body, "%3d %u %n",
- &r->head.response_code, &r->head.trans_id,
- &comment_pos) != 2)
- goto response_parse_failure;
-
- r->head.comment = r->body + comment_pos;
- end = strchr(r->head.comment, '\r');
- if (!end)
- goto response_parse_failure;
- /* Mark the end of the comment */
- *end = '\0';
- r->body = end + 1;
- if (r->body[0] == '\n')
- r->body ++;
- return 0;
-
-response_parse_failure:
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to parse MGCP response header\n");
- return -EINVAL;
-}
-
-/* TODO undup against mgcp_protocol.c:mgcp_check_param() */
-static bool mgcp_line_is_valid(const char *line)
-{
- const size_t line_len = strlen(line);
- if (line[0] == '\0')
- return true;
-
- if (line_len < 2
- || line[1] != '=') {
- LOGP(DMGCP, LOGL_ERROR,
- "Wrong MGCP option format: '%s'\n",
- line);
- return false;
- }
-
- return true;
-}
-
-/* Parse a line like "m=audio 16002 RTP/AVP 98" */
-static int mgcp_parse_audio(struct mgcp_response *r, const char *line)
-{
- if (sscanf(line, "m=audio %hu",
- &r->audio_port) != 1)
- goto response_parse_failure;
-
- return 0;
-
-response_parse_failure:
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to parse MGCP response header\n");
- return -EINVAL;
-}
-
-int mgcp_response_parse_params(struct mgcp_response *r)
-{
- char *line;
- int rc;
- OSMO_ASSERT(r->body);
- char *data = strstr(r->body, "\n\n");
-
- if (!data) {
- LOGP(DMGCP, LOGL_ERROR,
- "MGCP response: cannot find start of parameters\n");
- return -EINVAL;
- }
-
- /* Advance to after the \n\n, replace the second \n with \0. That's
- * where the parameters start. */
- data ++;
- *data = '\0';
- data ++;
-
- for_each_line(line, data) {
- if (!mgcp_line_is_valid(line))
- return -EINVAL;
-
- switch (line[0]) {
- case 'm':
- rc = mgcp_parse_audio(r, line);
- if (rc)
- return rc;
- break;
- default:
- /* skip unhandled parameters */
- break;
- }
- }
- return 0;
-}
-
-static struct mgcp_response_pending *mgcpgw_client_response_pending_get(
- struct mgcpgw_client *mgcp,
- struct mgcp_response *r)
-{
- struct mgcp_response_pending *pending;
- if (!r)
- return NULL;
- llist_for_each_entry(pending, &mgcp->responses_pending, entry) {
- if (pending->trans_id == r->head.trans_id) {
- llist_del(&pending->entry);
- return pending;
- }
- }
- return NULL;
-}
-
-/* Feed an MGCP message into the receive processing.
- * Parse the head and call any callback registered for the transaction id found
- * in the MGCP message. This is normally called directly from the internal
- * mgcp_do_read that reads from the socket connected to the MGCP gateway. This
- * function is published mainly to be able to feed data from the test suite.
- */
-int mgcpgw_client_rx(struct mgcpgw_client *mgcp, struct msgb *msg)
-{
- struct mgcp_response r = { 0 };
- struct mgcp_response_pending *pending;
- int rc;
-
- rc = mgcp_response_parse_head(&r, msg);
- if (rc) {
- LOGP(DMGCP, LOGL_ERROR, "Cannot parse MGCP response\n");
- return -1;
- }
-
- pending = mgcpgw_client_response_pending_get(mgcp, &r);
- if (!pending) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot find matching MGCP transaction for trans_id %d\n",
- r.head.trans_id);
- return -1;
- }
-
- mgcpgw_client_handle_response(mgcp, pending, &r);
- return 0;
-}
-
-static int mgcp_do_read(struct osmo_fd *fd)
-{
- struct mgcpgw_client *mgcp = fd->data;
- struct msgb *msg;
- int ret;
-
- msg = msgb_alloc_headroom(4096, 128, "mgcp_from_gw");
- if (!msg) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to allocate MGCP message.\n");
- return -1;
- }
-
- ret = read(fd->fd, msg->data, 4096 - 128);
- if (ret <= 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to read: %d/%s\n", errno, strerror(errno));
- msgb_free(msg);
- return -1;
- } else if (ret > 4096 - 128) {
- LOGP(DMGCP, LOGL_ERROR, "Too much data: %d\n", ret);
- msgb_free(msg);
- return -1;
- }
-
- msg->l2h = msgb_put(msg, ret);
- ret = mgcpgw_client_rx(mgcp, msg);
- talloc_free(msg);
- return ret;
-}
-
-static int mgcp_do_write(struct osmo_fd *fd, struct msgb *msg)
-{
- int ret;
- static char strbuf[4096];
- unsigned int l = msg->len < sizeof(strbuf) ? msg->len : sizeof(strbuf);
- unsigned int i;
-
- strncpy(strbuf, (const char*)msg->data, l);
- for (i = 0; i < sizeof(strbuf); i++) {
- if (strbuf[i] == '\n' || strbuf[i] == '\r') {
- strbuf[i] = '\0';
- break;
- }
- }
- DEBUGP(DMGCP, "Tx MGCP msg to MGCP GW: '%s'\n", strbuf);
-
- LOGP(DMGCP, LOGL_DEBUG, "Sending msg to MGCP GW size: %u\n", msg->len);
-
- ret = write(fd->fd, msg->data, msg->len);
- if (ret != msg->len)
- LOGP(DMGCP, LOGL_ERROR, "Failed to forward message to MGCP"
- " GW: %s\n", strerror(errno));
-
- return ret;
-}
-
-struct mgcpgw_client *mgcpgw_client_init(void *ctx,
- struct mgcpgw_client_conf *conf)
-{
- struct mgcpgw_client *mgcp;
-
- mgcp = talloc_zero(ctx, struct mgcpgw_client);
-
- INIT_LLIST_HEAD(&mgcp->responses_pending);
- INIT_LLIST_HEAD(&mgcp->inuse_endpoints);
-
- mgcp->next_trans_id = 1;
-
- mgcp->actual.local_addr = conf->local_addr ? conf->local_addr :
- MGCPGW_CLIENT_LOCAL_ADDR_DEFAULT;
- mgcp->actual.local_port = conf->local_port >= 0 ? (uint16_t)conf->local_port :
- MGCPGW_CLIENT_LOCAL_PORT_DEFAULT;
-
- mgcp->actual.remote_addr = conf->remote_addr ? conf->remote_addr :
- MGCPGW_CLIENT_REMOTE_ADDR_DEFAULT;
- mgcp->actual.remote_port = conf->remote_port >= 0 ? (uint16_t)conf->remote_port :
- MGCPGW_CLIENT_REMOTE_PORT_DEFAULT;
-
- mgcp->actual.first_endpoint = conf->first_endpoint > 0 ? (uint16_t)conf->first_endpoint : 0;
- mgcp->actual.last_endpoint = conf->last_endpoint > 0 ? (uint16_t)conf->last_endpoint : 0;
- mgcp->actual.bts_base = conf->bts_base > 0 ? (uint16_t)conf->bts_base : 4000;
-
- return mgcp;
-}
-
-int mgcpgw_client_connect(struct mgcpgw_client *mgcp)
-{
- int on;
- struct sockaddr_in addr;
- struct osmo_wqueue *wq;
- int rc;
-
- if (!mgcp) {
- LOGP(DMGCP, LOGL_FATAL, "MGCPGW client not initialized properly\n");
- return -EINVAL;
- }
-
- wq = &mgcp->wq;
-
- wq->bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (wq->bfd.fd < 0) {
- LOGP(DMGCP, LOGL_FATAL, "Failed to create UDP socket errno: %d\n", errno);
- return -errno;
- }
-
- on = 1;
- if (setsockopt(wq->bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
- LOGP(DMGCP, LOGL_FATAL,
- "Failed to initialize socket for MGCP GW: %s\n",
- strerror(errno));
- rc = -errno;
- goto error_close_fd;
- }
-
- /* bind socket */
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- inet_aton(mgcp->actual.local_addr, &addr.sin_addr);
- addr.sin_port = htons(mgcp->actual.local_port);
- if (bind(wq->bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- LOGP(DMGCP, LOGL_FATAL,
- "Failed to bind for MGCP GW to %s %u\n",
- mgcp->actual.local_addr, mgcp->actual.local_port);
- rc = -errno;
- goto error_close_fd;
- }
-
- /* connect to the remote */
- inet_aton(mgcp->actual.remote_addr, &addr.sin_addr);
- addr.sin_port = htons(mgcp->actual.remote_port);
- if (connect(wq->bfd.fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- LOGP(DMGCP, LOGL_FATAL,
- "Failed to connect to MGCP GW at %s %u: %s\n",
- mgcp->actual.remote_addr, mgcp->actual.remote_port,
- strerror(errno));
- rc = -errno;
- goto error_close_fd;
- }
-
- mgcp->remote_addr = htonl(addr.sin_addr.s_addr);
-
- osmo_wqueue_init(wq, 10);
- wq->bfd.when = BSC_FD_READ;
- wq->bfd.data = mgcp;
- wq->read_cb = mgcp_do_read;
- wq->write_cb = mgcp_do_write;
-
- if (osmo_fd_register(&wq->bfd) != 0) {
- LOGP(DMGCP, LOGL_FATAL, "Failed to register BFD\n");
- rc = -EIO;
- goto error_close_fd;
- }
- LOGP(DMGCP, LOGL_INFO, "MGCP GW connection: %s:%u -> %s:%u\n",
- mgcp->actual.local_addr, mgcp->actual.local_port,
- mgcp->actual.remote_addr, mgcp->actual.remote_port);
-
- return 0;
-error_close_fd:
- close(wq->bfd.fd);
- wq->bfd.fd = -1;
- return rc;
-}
-
-const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp)
-{
- return mgcp->actual.remote_addr;
-}
-
-uint16_t mgcpgw_client_remote_port(struct mgcpgw_client *mgcp)
-{
- return mgcp->actual.remote_port;
-}
-
-/* Return the MGCP GW binary IPv4 address in network byte order. */
-uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp)
-{
- return mgcp->remote_addr;
-}
-
-struct mgcp_response_pending * mgcpgw_client_pending_add(
- struct mgcpgw_client *mgcp,
- mgcp_trans_id_t trans_id,
- mgcp_response_cb_t response_cb,
- void *priv)
-{
- struct mgcp_response_pending *pending;
-
- pending = talloc_zero(mgcp, struct mgcp_response_pending);
- pending->trans_id = trans_id;
- pending->response_cb = response_cb;
- pending->priv = priv;
- llist_add_tail(&pending->entry, &mgcp->responses_pending);
-
- return pending;
-}
-
-/* Send the MGCP message in msg to the MGCP GW and handle a response with
- * response_cb. NOTE: the response_cb still needs to call
- * mgcp_response_parse_params(response) to get the parsed parameters -- to
- * potentially save some CPU cycles, only the head line has been parsed when
- * the response_cb is invoked. */
-int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg,
- mgcp_response_cb_t response_cb, void *priv)
-{
- struct mgcp_response_pending *pending;
- mgcp_trans_id_t trans_id;
- int rc;
-
- trans_id = msg->cb[MSGB_CB_MGCP_TRANS_ID];
- if (!trans_id) {
- LOGP(DMGCP, LOGL_ERROR,
- "Unset transaction id in mgcp send request\n");
- talloc_free(msg);
- return -EINVAL;
- }
-
- pending = mgcpgw_client_pending_add(mgcp, trans_id, response_cb, priv);
-
- if (msgb_l2len(msg) > 4096) {
- LOGP(DMGCP, LOGL_ERROR,
- "Cannot send, MGCP message too large: %u\n",
- msgb_l2len(msg));
- msgb_free(msg);
- rc = -EINVAL;
- goto mgcp_tx_error;
- }
-
- rc = osmo_wqueue_enqueue(&mgcp->wq, msg);
- if (rc) {
- LOGP(DMGCP, LOGL_FATAL, "Could not queue message to MGCP GW\n");
- msgb_free(msg);
- goto mgcp_tx_error;
- } else
- LOGP(DMGCP, LOGL_INFO, "Queued %u bytes for MGCP GW\n",
- msgb_l2len(msg));
- return 0;
-
-mgcp_tx_error:
- /* Pass NULL to response cb to indicate an error */
- mgcpgw_client_handle_response(mgcp, pending, NULL);
- return -1;
-}
-
-static struct msgb *mgcp_msg_from_buf(mgcp_trans_id_t trans_id,
- const char *buf, int len)
-{
- struct msgb *msg;
-
- if (len > (4096 - 128)) {
- LOGP(DMGCP, LOGL_ERROR, "Cannot send to MGCP GW:"
- " message too large: %d\n", len);
- return NULL;
- }
-
- msg = msgb_alloc_headroom(4096, 128, "MGCP tx");
- OSMO_ASSERT(msg);
-
- char *dst = (char*)msgb_put(msg, len);
- memcpy(dst, buf, len);
- msg->l2h = msg->data;
- msg->cb[MSGB_CB_MGCP_TRANS_ID] = trans_id;
-
- return msg;
-}
-
-static struct msgb *mgcp_msg_from_str(mgcp_trans_id_t trans_id,
- const char *fmt, ...)
-{
- static char compose[4096 - 128];
- va_list ap;
- int len;
- OSMO_ASSERT(fmt);
-
- va_start(ap, fmt);
- len = vsnprintf(compose, sizeof(compose), fmt, ap);
- va_end(ap);
- if (len >= sizeof(compose)) {
- LOGP(DMGCP, LOGL_ERROR,
- "Message too large: trans_id=%u len=%d\n",
- trans_id, len);
- return NULL;
- }
- if (len < 1) {
- LOGP(DMGCP, LOGL_ERROR,
- "Failed to compose message: trans_id=%u len=%d\n",
- trans_id, len);
- return NULL;
- }
- return mgcp_msg_from_buf(trans_id, compose, len);
-}
-
-static mgcp_trans_id_t mgcpgw_client_next_trans_id(struct mgcpgw_client *mgcp)
-{
- /* avoid zero trans_id to distinguish from unset trans_id */
- if (!mgcp->next_trans_id)
- mgcp->next_trans_id ++;
- return mgcp->next_trans_id ++;
-}
-
-struct msgb *mgcp_msg_crcx(struct mgcpgw_client *mgcp,
- uint16_t rtp_endpoint, unsigned int call_id,
- enum mgcp_connection_mode mode)
-{
- mgcp_trans_id_t trans_id = mgcpgw_client_next_trans_id(mgcp);
- return mgcp_msg_from_str(trans_id,
- "CRCX %u %x@mgw MGCP 1.0\r\n"
- "C: %x\r\n"
- "L: p:20, a:AMR, nt:IN\r\n"
- "M: %s\r\n"
- ,
- trans_id,
- rtp_endpoint,
- call_id,
- mgcp_cmode_name(mode));
-}
-
-struct msgb *mgcp_msg_mdcx(struct mgcpgw_client *mgcp,
- uint16_t rtp_endpoint, const char *rtp_conn_addr,
- uint16_t rtp_port, enum mgcp_connection_mode mode)
-
-{
- mgcp_trans_id_t trans_id = mgcpgw_client_next_trans_id(mgcp);
- return mgcp_msg_from_str(trans_id,
- "MDCX %u %x@mgw MGCP 1.0\r\n"
- "M: %s\r\n"
- "\r\n"
- "c=IN IP4 %s\r\n"
- "m=audio %u RTP/AVP 255\r\n"
- ,
- trans_id,
- rtp_endpoint,
- mgcp_cmode_name(mode),
- rtp_conn_addr,
- rtp_port);
-}
-
-struct msgb *mgcp_msg_dlcx(struct mgcpgw_client *mgcp, uint16_t rtp_endpoint,
- unsigned int call_id)
-{
- mgcp_trans_id_t trans_id = mgcpgw_client_next_trans_id(mgcp);
- return mgcp_msg_from_str(trans_id,
- "DLCX %u %x@mgw MGCP 1.0\r\n"
- "C: %x\r\n", trans_id, rtp_endpoint, call_id);
-}
diff --git a/src/libmgcp/mgcpgw_client_vty.c b/src/libmgcp/mgcpgw_client_vty.c
deleted file mode 100644
index 806800078..000000000
--- a/src/libmgcp/mgcpgw_client_vty.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* MGCPGW client interface to quagga VTY */
-/* (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
- * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2011 by Holger Hans Peter Freyther
- * 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 <inttypes.h>
-#include <stdlib.h>
-#include <talloc.h>
-
-#include <osmocom/vty/command.h>
-
-#include <openbsc/vty.h>
-#include <openbsc/mgcpgw_client.h>
-
-#define MGCPGW_STR "MGCP gateway configuration for RTP streams\n"
-
-struct mgcpgw_client_conf *global_mgcpgw_client_conf = NULL;
-
-DEFUN(cfg_mgcpgw_local_ip, cfg_mgcpgw_local_ip_cmd,
- "mgcpgw local-ip A.B.C.D",
- MGCPGW_STR "local bind to connect to MGCP gateway with\n"
- "local bind IP address\n")
-{
- if (!global_mgcpgw_client_conf)
- return CMD_ERR_NOTHING_TODO;
- global_mgcpgw_client_conf->local_addr =
- talloc_strdup(gsmnet_from_vty(vty), argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcpgw_local_port, cfg_mgcpgw_local_port_cmd,
- "mgcpgw local-port <0-65535>",
- MGCPGW_STR "local bind to connect to MGCP gateway with\n"
- "local bind port\n")
-{
- if (!global_mgcpgw_client_conf)
- return CMD_ERR_NOTHING_TODO;
- global_mgcpgw_client_conf->local_port = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcpgw_remote_ip, cfg_mgcpgw_remote_ip_cmd,
- "mgcpgw remote-ip A.B.C.D",
- MGCPGW_STR "remote bind to connect to MGCP gateway with\n"
- "remote bind IP address\n")
-{
- if (!global_mgcpgw_client_conf)
- return CMD_ERR_NOTHING_TODO;
- global_mgcpgw_client_conf->remote_addr =
- talloc_strdup(gsmnet_from_vty(vty), argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcpgw_remote_port, cfg_mgcpgw_remote_port_cmd,
- "mgcpgw remote-port <0-65535>",
- MGCPGW_STR "remote bind to connect to MGCP gateway with\n"
- "remote bind port\n")
-{
- if (!global_mgcpgw_client_conf)
- return CMD_ERR_NOTHING_TODO;
- global_mgcpgw_client_conf->remote_port = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_mgcpgw_endpoint_range, cfg_mgcpgw_endpoint_range_cmd,
- "mgcpgw endpoint-range <1-65534> <1-65534>",
- MGCPGW_STR "usable range of endpoint identifiers\n"
- "set first useable endpoint identifier\n"
- "set the last useable endpoint identifier\n")
-{
- uint16_t first_endpoint = atoi(argv[0]);
- uint16_t last_endpoint = atoi(argv[1]);
-
- if (last_endpoint < first_endpoint) {
- vty_out(vty, "last endpoint must be greater than first endpoint!%s",
- VTY_NEWLINE);
- return CMD_SUCCESS;
- }
-
- global_mgcpgw_client_conf->first_endpoint = first_endpoint;
- global_mgcpgw_client_conf->last_endpoint = last_endpoint;
- return CMD_SUCCESS;
-}
-
-#define BTS_START_STR "First UDP port allocated for the BTS side\n"
-#define UDP_PORT_STR "UDP Port number\n"
-DEFUN(cfg_mgcp_rtp_bts_base_port,
- cfg_mgcp_rtp_bts_base_port_cmd,
- "mgcpgw bts-base <0-65534>",
- MGCPGW_STR
- BTS_START_STR
- UDP_PORT_STR)
-{
- global_mgcpgw_client_conf->bts_base = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-int mgcpgw_client_config_write(struct vty *vty, const char *indent)
-{
- const char *addr;
- int port;
- uint16_t first_endpoint;
- uint16_t last_endpoint;
- uint16_t bts_base;
-
- addr = global_mgcpgw_client_conf->local_addr;
- if (addr)
- vty_out(vty, "%smgcpgw local-ip %s%s", indent, addr,
- VTY_NEWLINE);
- port = global_mgcpgw_client_conf->local_port;
- if (port >= 0)
- vty_out(vty, "%smgcpgw local-port %u%s", indent,
- (uint16_t)port, VTY_NEWLINE);
-
- addr = global_mgcpgw_client_conf->remote_addr;
- if (addr)
- vty_out(vty, "%smgcpgw remote-ip %s%s", indent, addr,
- VTY_NEWLINE);
- port = global_mgcpgw_client_conf->remote_port;
- if (port >= 0)
- vty_out(vty, "%smgcpgw remote-port %u%s", indent,
- (uint16_t)port, VTY_NEWLINE);
-
- first_endpoint = global_mgcpgw_client_conf->first_endpoint;
- last_endpoint = global_mgcpgw_client_conf->last_endpoint;
- if (last_endpoint != 0) {
- vty_out(vty, "%smgcpgw endpoint-range %u %u%s", indent,
- first_endpoint, last_endpoint, VTY_NEWLINE);
- }
-
- bts_base = global_mgcpgw_client_conf->bts_base;
- if (bts_base) {
- vty_out(vty, "%smgcpgw bts-base %u%s", indent,
- bts_base, VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
-void mgcpgw_client_vty_init(int node, struct mgcpgw_client_conf *conf)
-{
- global_mgcpgw_client_conf = conf;
-
- 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_mgcp_rtp_bts_base_port_cmd);
-}
diff --git a/src/libmsc/a_iface.c b/src/libmsc/a_iface.c
index 93e8ab5e9..e473b7526 100644
--- a/src/libmsc/a_iface.c
+++ b/src/libmsc/a_iface.c
@@ -34,7 +34,7 @@
#include <openbsc/a_iface.h>
#include <openbsc/a_iface_bssap.h>
#include <openbsc/transaction.h>
-#include <openbsc/mgcpgw_client.h>
+#include <osmocom/legacy_mgcp/mgcpgw_client.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/sccp/sccp_types.h>
#include <openbsc/a_reset.h>
diff --git a/src/libmsc/msc_ifaces.c b/src/libmsc/msc_ifaces.c
index 262bf98a3..161a10019 100644
--- a/src/libmsc/msc_ifaces.c
+++ b/src/libmsc/msc_ifaces.c
@@ -25,8 +25,8 @@
#include <openbsc/msc_ifaces.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/transaction.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcpgw_client.h>
+#include <osmocom/legacy_mgcp/mgcp.h>
+#include <osmocom/legacy_mgcp/mgcpgw_client.h>
#include <openbsc/vlr.h>
#include <openbsc/a_iface.h>
@@ -249,7 +249,7 @@ int msc_call_assignment(struct gsm_trans *trans)
* its RTP traffic to that port on the MGCPGW side. The MGCPGW only
* gets the endpoint ID via the CRCX. It will do the same calculation
* on his side too to get knowledge of the rtp port. */
- bts_base = mgcp->actual.bts_base;
+ bts_base = mgcpgw_client_conf_actual(mgcp)->bts_base;
conn->rtp.port_subscr = bts_base + 2 * conn->rtp.mgcp_rtp_endpoint;
/* Establish the RTP stream first as looping back to the originator.
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 6ae4529a1..50679aa01 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -155,7 +155,7 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
- mgcpgw_client_vty_init(MSC_NODE, &msc_network->mgcpgw.conf);
+ mgcpgw_client_vty_init(msc_network, MSC_NODE, &msc_network->mgcpgw.conf);
#ifdef BUILD_IU
ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
#endif
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 4353b9ad0..9a5288bdc 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -24,7 +24,7 @@
#include <openbsc/bsc_msc_data.h>
#include <openbsc/debug.h>
#include <openbsc/bsc_subscriber.h>
-#include <openbsc/mgcp.h>
+#include <osmocom/legacy_mgcp/mgcp.h>
#include <openbsc/paging.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
diff --git a/src/osmo-bsc_mgcp/Makefile.am b/src/osmo-bsc_mgcp/Makefile.am
deleted file mode 100644
index b4e0d8564..000000000
--- a/src/osmo-bsc_mgcp/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_builddir) \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGSM_CFLAGS) \
- $(LIBOSMOVTY_CFLAGS) \
- $(LIBOSMOABIS_CFLAGS) \
- $(LIBOSMONETIF_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- $(NULL)
-
-bin_PROGRAMS = \
- osmo-bsc_mgcp \
- $(NULL)
-
-osmo_bsc_mgcp_SOURCES = \
- mgcp_main.c \
- $(NULL)
-
-osmo_bsc_mgcp_LDADD = \
- $(top_builddir)/src/libcommon/libcommon.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
- $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMONETIF_LIBS) \
- $(LIBBCG729_LIBS) \
- $(LIBRARY_GSM) \
- $(LIBOSMOSIGTRAN_LIBS) \
- -lrt \
- $(NULL)
diff --git a/src/osmo-bsc_mgcp/mgcp_main.c b/src/osmo-bsc_mgcp/mgcp_main.c
deleted file mode 100644
index 6cf9ab786..000000000
--- a/src/osmo-bsc_mgcp/mgcp_main.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
-/* The main method to drive it as a standalone process */
-
-/*
- * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2011 by On-Waves
- * 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 <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#include <unistd.h>
-
-#include <sys/socket.h>
-
-#include <openbsc/debug.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-#include <openbsc/vty.h>
-
-#include <osmocom/core/application.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/stats.h>
-#include <osmocom/core/rate_ctr.h>
-
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/logging.h>
-#include <osmocom/vty/ports.h>
-#include <osmocom/vty/command.h>
-#include <osmocom/vty/stats.h>
-
-#include "../../bscconfig.h"
-
-#ifdef BUILD_MGCP_TRANSCODING
-#include "openbsc/mgcp_transcode.h"
-#endif
-
-#define _GNU_SOURCE
-#include <getopt.h>
-
-#warning "Make use of the rtp proxy code"
-
-static struct mgcp_config *cfg;
-static struct mgcp_trunk_config *reset_trunk;
-static int reset_endpoints = 0;
-static int daemonize = 0;
-
-const char *openbsc_copyright =
- "Copyright (C) 2009-2010 Holger Freyther and On-Waves\r\n"
- "Contributions by Daniel Willmann, Jan Lübbe, Stefan Schmidt\r\n"
- "Dieter Spaar, Andreas Eversberg, Harald Welte\r\n\r\n"
- "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
- "This is free software: you are free to change and redistribute it.\r\n"
- "There is NO WARRANTY, to the extent permitted by law.\r\n";
-
-static char *config_file = "mgcp.cfg";
-
-/* used by msgb and mgcp */
-void *tall_bsc_ctx = NULL;
-
-static void print_help()
-{
- 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");
-}
-
-static void handle_options(int argc, char **argv)
-{
- while (1) {
- int option_index = 0, c;
- static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"config-file", 1, 0, 'c'},
- {"daemonize", 0, 0, 'D'},
- {"version", 0, 0, 'V'},
- {"disable-color", 0, 0, 's'},
- {0, 0, 0, 0},
- };
-
- c = getopt_long(argc, argv, "hc:VD", long_options, &option_index);
-
- if (c == -1)
- break;
-
- switch(c) {
- case 'h':
- print_help();
- exit(0);
- break;
- case 'c':
- config_file = talloc_strdup(tall_bsc_ctx, optarg);
- break;
- case 's':
- log_set_use_color(osmo_stderr_target, 0);
- break;
- case 'V':
- print_version(1);
- exit(0);
- break;
- case 'D':
- daemonize = 1;
- break;
- default:
- /* ignore */
- break;
- };
- }
-}
-
-/* simply remember this */
-static int mgcp_rsip_cb(struct mgcp_trunk_config *tcfg)
-{
- reset_endpoints = 1;
- reset_trunk = tcfg;
-
- return 0;
-}
-
-static int read_call_agent(struct osmo_fd *fd, unsigned int what)
-{
- struct sockaddr_in addr;
- socklen_t slen = sizeof(addr);
- struct msgb *msg;
- struct msgb *resp;
- int i;
-
- msg = (struct msgb *) fd->data;
-
- /* read one less so we can use it as a \0 */
- int rc = recvfrom(cfg->gw_fd.bfd.fd, msg->data, msg->data_len - 1, 0,
- (struct sockaddr *) &addr, &slen);
- if (rc < 0) {
- perror("Gateway failed to read");
- return -1;
- } else if (slen > sizeof(addr)) {
- fprintf(stderr, "Gateway received message from outerspace: %zu %zu\n",
- (size_t) slen, sizeof(addr));
- return -1;
- }
-
- /* handle message now */
- msg->l2h = msgb_put(msg, rc);
- resp = mgcp_handle_message(cfg, msg);
- msgb_reset(msg);
-
- if (resp) {
- sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr));
- msgb_free(resp);
- }
-
- if (reset_endpoints) {
- LOGP(DMGCP, LOGL_NOTICE,
- "Asked to reset endpoints: %d/%d\n",
- reset_trunk->trunk_nr, reset_trunk->trunk_type);
- reset_endpoints = 0;
-
- /* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */
- for (i = 1; i < reset_trunk->number_endpoints; ++i)
- mgcp_release_endp(&reset_trunk->endpoints[i]);
- }
-
- return 0;
-}
-
-extern int bsc_vty_go_parent(struct vty *vty);
-
-static struct vty_app_info vty_info = {
- .name = "OpenBSC MGCP",
- .version = PACKAGE_VERSION,
- .go_parent_cb = bsc_vty_go_parent,
- .is_config_node = bsc_vty_is_config_node,
-};
-
-int main(int argc, char **argv)
-{
- struct gsm_network dummy_network;
- struct sockaddr_in addr;
- int on = 1, rc;
-
- tall_bsc_ctx = talloc_named_const(NULL, 1, "mgcp-callagent");
- msgb_talloc_ctx_init(tall_bsc_ctx, 0);
-
- osmo_init_ignore_signals();
- osmo_init_logging(&log_info);
-
- cfg = mgcp_config_alloc();
- if (!cfg)
- return -1;
-
-#ifdef BUILD_MGCP_TRANSCODING
- cfg->setup_rtp_processing_cb = &mgcp_transcoding_setup;
- cfg->rtp_processing_cb = &mgcp_transcoding_process_rtp;
- cfg->get_net_downlink_format_cb = &mgcp_transcoding_net_downlink_format;
-#endif
-
- cfg->trunk.force_realloc = 1;
-
- vty_info.copyright = openbsc_copyright;
- vty_init(&vty_info);
- logging_vty_add_cmds(NULL);
- osmo_stats_vty_add_cmds(&log_info);
- mgcp_vty_init();
-
- handle_options(argc, argv);
-
- 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_bsc_ctx, &dummy_network,
- vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP);
- if (rc < 0)
- return rc;
-
- /* set some callbacks */
- cfg->reset_cb = mgcp_rsip_cb;
-
- /* we need to bind a socket */
- if (rc == 0) {
- cfg->gw_fd.bfd.when = BSC_FD_READ;
- cfg->gw_fd.bfd.cb = read_call_agent;
- cfg->gw_fd.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (cfg->gw_fd.bfd.fd < 0) {
- perror("Gateway failed to listen");
- return -1;
- }
-
- setsockopt(cfg->gw_fd.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(cfg->source_port);
- inet_aton(cfg->source_addr, &addr.sin_addr);
-
- if (bind(cfg->gw_fd.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("Gateway failed to bind");
- return -1;
- }
-
- cfg->gw_fd.bfd.data = msgb_alloc(4096, "mgcp-msg");
- if (!cfg->gw_fd.bfd.data) {
- fprintf(stderr, "Gateway memory error.\n");
- return -1;
- }
-
- if (cfg->call_agent_addr) {
- addr.sin_port = htons(2727);
- inet_aton(cfg->call_agent_addr, &addr.sin_addr);
- if (connect(cfg->gw_fd.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to connect to: '%s'. errno: %d\n",
- cfg->call_agent_addr, errno);
- close(cfg->gw_fd.bfd.fd);
- cfg->gw_fd.bfd.fd = -1;
- return -1;
- }
- }
-
- if (osmo_fd_register(&cfg->gw_fd.bfd) != 0) {
- LOGP(DMGCP, LOGL_FATAL, "Failed to register the fd\n");
- return -1;
- }
-
- LOGP(DMGCP, LOGL_NOTICE, "Configured for MGCP.\n");
- }
-
- /* initialisation */
- srand(time(NULL));
-
- if (daemonize) {
- rc = osmo_daemonize();
- if (rc < 0) {
- perror("Error during daemonize");
- exit(1);
- }
- }
-
- /* main loop */
- while (1) {
- osmo_select_main(0);
- }
-
-
- return 0;
-}
diff --git a/src/osmo-bsc_nat/Makefile.am b/src/osmo-bsc_nat/Makefile.am
index b7c13ad3e..1eec7aa1c 100644
--- a/src/osmo-bsc_nat/Makefile.am
+++ b/src/osmo-bsc_nat/Makefile.am
@@ -13,6 +13,7 @@ AM_CFLAGS = \
$(LIBOSMOSCCP_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
$(LIBCRYPTO_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(NULL)
@@ -40,7 +41,6 @@ osmo_bsc_nat_SOURCES = \
$(NULL)
osmo_bsc_nat_LDADD = \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libfilter/libfilter.a \
$(top_builddir)/src/libbsc/libbsc.a \
$(top_builddir)/src/libcommon-cs/libcommon-cs.a \
@@ -54,6 +54,8 @@ osmo_bsc_nat_LDADD = \
$(LIBOSMOABIS_LIBS) \
$(LIBOSMONETIF_LIBS) \
$(LIBOSMOSIGTRAN_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
$(LIBCRYPTO_LIBS) \
+ $(LIBRARY_GSM) \
-lrt \
$(NULL)
diff --git a/src/osmo-bsc_nat/bsc_mgcp_utils.c b/src/osmo-bsc_nat/bsc_mgcp_utils.c
index 7df362f89..49050fc89 100644
--- a/src/osmo-bsc_nat/bsc_mgcp_utils.c
+++ b/src/osmo-bsc_nat/bsc_mgcp_utils.c
@@ -48,8 +48,8 @@
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <openbsc/ipaccess.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
+#include <osmocom/legacy_mgcp/mgcp.h>
+#include <osmocom/legacy_mgcp/mgcp_internal.h>
#include <openbsc/osmux.h>
#include <osmocom/ctrl/control_cmd.h>
diff --git a/src/osmo-bsc_nat/bsc_nat_ctrl.c b/src/osmo-bsc_nat/bsc_nat_ctrl.c
index 128ea6518..ff6a73978 100644
--- a/src/osmo-bsc_nat/bsc_nat_ctrl.c
+++ b/src/osmo-bsc_nat/bsc_nat_ctrl.c
@@ -32,6 +32,7 @@
#include <openbsc/bsc_msg_filter.h>
#include <openbsc/vty.h>
#include <openbsc/gsm_data.h>
+#include <openbsc/debug.h>
#include <unistd.h>
#include <string.h>
diff --git a/src/osmo-bsc_nat/bsc_nat_vty.c b/src/osmo-bsc_nat/bsc_nat_vty.c
index a11ae151e..fed530676 100644
--- a/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -25,7 +25,7 @@
#include <openbsc/bsc_msg_filter.h>
#include <openbsc/bsc_msc.h>
#include <openbsc/gsm_04_08.h>
-#include <openbsc/mgcp.h>
+#include <osmocom/legacy_mgcp/mgcp.h>
#include <openbsc/vty.h>
#include <openbsc/nat_rewrite_trie.h>
@@ -1213,15 +1213,15 @@ DEFUN(cfg_bsc_osmux,
conf->osmux = OSMUX_USAGE_ONLY;
if (old == 0 && conf->osmux > 0 && !conf->nat->mgcp_cfg->osmux_init) {
- LOGP(DMGCP, LOGL_NOTICE, "Setting up OSMUX socket\n");
+ LOGP(DLMGCP, LOGL_NOTICE, "Setting up OSMUX socket\n");
if (osmux_init(OSMUX_ROLE_BSC_NAT, conf->nat->mgcp_cfg) < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Cannot init OSMUX\n");
+ LOGP(DLMGCP, LOGL_ERROR, "Cannot init OSMUX\n");
vty_out(vty, "%% failed to create Osmux socket%s",
VTY_NEWLINE);
return CMD_WARNING;
}
} else if (old > 0 && conf->osmux == 0) {
- LOGP(DMGCP, LOGL_NOTICE, "Disabling OSMUX socket\n");
+ LOGP(DLMGCP, LOGL_NOTICE, "Disabling OSMUX socket\n");
/* Don't stop the socket, we may already have ongoing voice
* flows already using Osmux. This just switch indicates that
* new upcoming flows should use RTP.
diff --git a/src/osmo-bsc_nat/bsc_ussd.c b/src/osmo-bsc_nat/bsc_ussd.c
index 0ba63270d..9769bbd39 100644
--- a/src/osmo-bsc_nat/bsc_ussd.c
+++ b/src/osmo-bsc_nat/bsc_ussd.c
@@ -25,6 +25,7 @@
#include <openbsc/bsc_msg_filter.h>
#include <openbsc/ipaccess.h>
#include <openbsc/socket.h>
+#include <openbsc/debug.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0480.h>
diff --git a/src/osmo-msc/Makefile.am b/src/osmo-msc/Makefile.am
index 87b6133f9..0d4876fa9 100644
--- a/src/osmo-msc/Makefile.am
+++ b/src/osmo-msc/Makefile.am
@@ -17,6 +17,7 @@ AM_CFLAGS = \
$(LIBOSMORANAP_CFLAGS) \
$(LIBASN1C_CFLAGS) \
$(LIBOSMOSIGTRAN_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
@@ -37,7 +38,6 @@ osmo_msc_LDADD = \
$(top_builddir)/src/libcommon-cs/libcommon-cs.a \
$(top_builddir)/src/libtrau/libtrau.a \
$(top_builddir)/src/libcommon/libcommon.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
$(LIBOSMOCORE_LIBS) \
@@ -46,6 +46,8 @@ osmo_msc_LDADD = \
$(LIBSMPP34_LIBS) \
$(LIBCRYPTO_LIBS) \
$(LIBOSMOSIGTRAN_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
+ $(LIBRARY_GSM) \
-ldbi \
$(NULL)
if BUILD_IU
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index de6af5dd6..30b11d983 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -64,7 +64,7 @@
#include <openbsc/osmo_bsc_rf.h>
#include <openbsc/smpp.h>
#include <osmocom/sigtran/osmo_ss7.h>
-#include <openbsc/mgcpgw_client.h>
+#include <osmocom/legacy_mgcp/mgcpgw_client.h>
#ifdef BUILD_IU
#include <osmocom/ranap/iu_client.h>
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 38890a8f5..7e17ad8de 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,6 @@
SUBDIRS = \
gsm0408 \
channel \
- mgcp \
gprs \
abis \
gbproxy \
diff --git a/tests/bsc-nat-trie/Makefile.am b/tests/bsc-nat-trie/Makefile.am
index cf8ebaf20..6663897bf 100644
--- a/tests/bsc-nat-trie/Makefile.am
+++ b/tests/bsc-nat-trie/Makefile.am
@@ -1,5 +1,7 @@
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS)
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
+ $(NULL)
AM_LDFLAGS = $(COVERAGE_LDFLAGS)
EXTRA_DIST = bsc_nat_trie_test.ok prefixes.csv
@@ -9,9 +11,11 @@ noinst_PROGRAMS = bsc_nat_trie_test
bsc_nat_trie_test_SOURCES = bsc_nat_trie_test.c \
$(top_srcdir)/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c
bsc_nat_trie_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libtrau/libtrau.a \
$(top_builddir)/src/libcommon/libcommon.a \
$(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \
$(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOABIS_LIBS)
+ $(LIBOSMOABIS_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
+ $(LIBRARY_GSM) \
+ $(NULL)
diff --git a/tests/bsc-nat/Makefile.am b/tests/bsc-nat/Makefile.am
index 40be3a32f..74838a984 100644
--- a/tests/bsc-nat/Makefile.am
+++ b/tests/bsc-nat/Makefile.am
@@ -12,6 +12,7 @@ AM_CFLAGS = \
$(LIBOSMOSCCP_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(NULL)
@@ -45,7 +46,6 @@ bsc_nat_test_LDADD = \
$(top_builddir)/src/libfilter/libfilter.a \
$(top_builddir)/src/libbsc/libbsc.a \
$(top_builddir)/src/libcommon-cs/libcommon-cs.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libtrau/libtrau.a \
$(top_builddir)/src/libcommon/libcommon.a \
$(LIBOSMOCORE_LIBS) \
@@ -55,5 +55,7 @@ bsc_nat_test_LDADD = \
$(LIBOSMOABIS_LIBS) \
$(LIBOSMONETIF_LIBS) \
$(LIBOSMOCTRL_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
+ $(LIBRARY_GSM) \
-lrt \
$(NULL)
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index 904bdfcd7..90bbb4ac7 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -10,6 +10,7 @@ AM_CFLAGS = \
$(LIBOSMOGSM_CFLAGS) \
$(LIBOSMOSCCP_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(NULL)
@@ -33,7 +34,6 @@ bsc_test_SOURCES = \
bsc_test_LDADD = \
$(top_builddir)/src/libbsc/libbsc.a \
$(top_builddir)/src/libcommon-cs/libcommon-cs.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libtrau/libtrau.a \
$(top_builddir)/src/libcommon/libcommon.a \
$(LIBOSMOCORE_LIBS) \
@@ -41,5 +41,7 @@ bsc_test_LDADD = \
$(LIBOSMOSCCP_LIBS) \
$(LIBOSMOVTY_LIBS) \
$(LIBOSMOABIS_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
+ $(LIBRARY_GSM) \
-lrt \
$(NULL)
diff --git a/tests/mgcp/Makefile.am b/tests/mgcp/Makefile.am
deleted file mode 100644
index af9216fb5..000000000
--- a/tests/mgcp/Makefile.am
+++ /dev/null
@@ -1,93 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir) \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- -ggdb3 \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGSM_FLAGS) \
- $(LIBOSMONETIF_CFLAGS) \
- $(LIBOSMOSCCP_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- $(LIBBCG729_CFLAGS) \
- $(NULL)
-
-AM_LDFLAGS = \
- $(COVERAGE_LDFLAGS) \
- $(NULL)
-
-EXTRA_DIST = \
- mgcp_test.ok \
- mgcp_transcoding_test.ok \
- mgcpgw_client_test.ok \
- mgcpgw_client_test.err \
- $(NULL)
-
-noinst_PROGRAMS = \
- mgcp_test \
- mgcpgw_client_test \
- $(NULL)
-if BUILD_MGCP_TRANSCODING
-noinst_PROGRAMS += \
- mgcp_transcoding_test \
- $(NULL)
-endif
-
-mgcp_test_SOURCES = \
- mgcp_test.c \
- $(NULL)
-
-mgcp_test_LDADD = \
- $(top_builddir)/src/libbsc/libbsc.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
- $(top_builddir)/src/libcommon/libcommon.a \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOSCCP_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBRARY_DL) \
- $(LIBOSMONETIF_LIBS) \
- -lrt \
- -lm \
- $(NULL)
-
-mgcp_transcoding_test_SOURCES = \
- mgcp_transcoding_test.c \
- $(NULL)
-
-mgcp_transcoding_test_LDADD = \
- $(top_builddir)/src/libbsc/libbsc.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
- $(top_builddir)/src/libcommon/libcommon.a \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBBCG729_LIBS) \
- $(LIBOSMOSCCP_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBRARY_DL) \
- $(LIBOSMONETIF_LIBS) \
- $(LIBRARY_GSM) \
- -lrt \
- -lm \
- $(NULL)
-
-mgcpgw_client_test_SOURCES = \
- mgcpgw_client_test.c \
- $(NULL)
-
-mgcpgw_client_test_LDADD = \
- $(top_builddir)/src/libbsc/libbsc.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
- $(top_builddir)/src/libcommon/libcommon.a \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOSCCP_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBRARY_DL) \
- $(LIBOSMONETIF_LIBS) \
- -lrt \
- -lm \
- $(NULL)
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
deleted file mode 100644
index 43a453af8..000000000
--- a/tests/mgcp/mgcp_test.c
+++ /dev/null
@@ -1,1227 +0,0 @@
-/*
- * (C) 2011-2012,2014 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2011-2012,2014 by On-Waves
- * 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/>.
- */
-#undef _GNU_SOURCE
-#define _GNU_SOURCE
-
-#include <openbsc/mgcp.h>
-#include <openbsc/vty.h>
-#include <openbsc/mgcp_internal.h>
-
-#include <osmocom/core/application.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <string.h>
-#include <limits.h>
-#include <dlfcn.h>
-#include <time.h>
-#include <math.h>
-
-char *strline_r(char *str, char **saveptr);
-
-const char *strline_test_data =
- "one CR\r"
- "two CR\r"
- "\r"
- "one CRLF\r\n"
- "two CRLF\r\n"
- "\r\n"
- "one LF\n"
- "two LF\n"
- "\n"
- "mixed (4 lines)\r\r\n\n\r\n";
-
-#define EXPECTED_NUMBER_OF_LINES 13
-
-static void test_strline(void)
-{
- char *save = NULL;
- char *line;
- char buf[2048];
- int counter = 0;
-
- osmo_strlcpy(buf, strline_test_data, sizeof(buf));
-
- for (line = strline_r(buf, &save); line;
- line = strline_r(NULL, &save)) {
- printf("line: '%s'\n", line);
- counter++;
- }
-
- OSMO_ASSERT(counter == EXPECTED_NUMBER_OF_LINES);
-}
-
-#define AUEP1 "AUEP 158663169 ds/e1-1/2@172.16.6.66 MGCP 1.0\r\n"
-#define AUEP1_RET "200 158663169 OK\r\n"
-#define AUEP2 "AUEP 18983213 ds/e1-2/1@172.16.6.66 MGCP 1.0\r\n"
-#define AUEP2_RET "500 18983213 FAIL\r\n"
-#define EMPTY "\r\n"
-#define EMPTY_RET NULL
-#define SHORT "CRCX \r\n"
-#define SHORT_RET "510 000000 FAIL\r\n"
-
-#define MDCX_WRONG_EP "MDCX 18983213 ds/e1-3/1@172.16.6.66 MGCP 1.0\r\n"
-#define MDCX_ERR_RET "510 18983213 FAIL\r\n"
-#define MDCX_UNALLOCATED "MDCX 18983214 ds/e1-1/2@172.16.6.66 MGCP 1.0\r\n"
-#define MDCX_RET "400 18983214 FAIL\r\n"
-#define MDCX3 "MDCX 18983215 1@mgw MGCP 1.0\r\n"
-#define MDCX3_RET "200 18983215 OK\r\n" \
- "I: 1\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=rtpmap:126 AMR/8000\r\n" \
- "a=ptime:20\r\n"
-#define MDCX3_FMTP_RET "200 18983215 OK\r\n" \
- "I: 3\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 3 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=rtpmap:126 AMR/8000\r\n" \
- "a=fmtp:126 0/1/2\r\n" \
- "a=ptime:20\r\n"
-#define MDCX4 "MDCX 18983216 1@mgw MGCP 1.0\r\n" \
- "M: sendrecv\r" \
- "C: 2\r\n" \
- "I: 1\r\n" \
- "L: p:20, a:AMR, nt:IN\r\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 4441 RTP/AVP 99\r\n" \
- "a=rtpmap:99 AMR/8000\r\n" \
- "a=ptime:40\r\n"
-#define MDCX4_RET(Ident) "200 " Ident " OK\r\n" \
- "I: 1\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=rtpmap:126 AMR/8000\r\n" \
- "a=ptime:20\r\n"
-
-#define MDCX4_PT1 "MDCX 18983217 1@mgw MGCP 1.0\r\n" \
- "M: sendrecv\r" \
- "C: 2\r\n" \
- "I: 1\r\n" \
- "L: p:20-40, a:AMR, nt:IN\r\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 4441 RTP/AVP 99\r\n" \
- "a=rtpmap:99 AMR/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define MDCX4_PT2 "MDCX 18983218 1@mgw MGCP 1.0\r\n" \
- "M: sendrecv\r" \
- "C: 2\r\n" \
- "I: 1\r\n" \
- "L: p:20-20, a:AMR, nt:IN\r\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 4441 RTP/AVP 99\r\n" \
- "a=rtpmap:99 AMR/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define MDCX4_PT3 "MDCX 18983219 1@mgw MGCP 1.0\r\n" \
- "M: sendrecv\r" \
- "C: 2\r\n" \
- "I: 1\r\n" \
- "L: a:AMR, nt:IN\r\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 4441 RTP/AVP 99\r\n" \
- "a=rtpmap:99 AMR/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define MDCX4_SO "MDCX 18983220 1@mgw MGCP 1.0\r\n" \
- "M: sendonly\r" \
- "C: 2\r\n" \
- "I: 1\r\n" \
- "L: p:20, a:AMR, nt:IN\r\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 4441 RTP/AVP 99\r\n" \
- "a=rtpmap:99 AMR/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define MDCX4_RO "MDCX 18983221 1@mgw MGCP 1.0\r\n" \
- "M: recvonly\r" \
- "C: 2\r\n" \
- "I: 1\r\n" \
- "L: p:20, a:AMR, nt:IN\r\n"
-
-#define SHORT2 "CRCX 1"
-#define SHORT2_RET "510 000000 FAIL\r\n"
-#define SHORT3 "CRCX 1 1@mgw"
-#define SHORT4 "CRCX 1 1@mgw MGCP"
-#define SHORT5 "CRCX 1 1@mgw MGCP 1.0"
-
-#define CRCX "CRCX 2 1@mgw MGCP 1.0\r\n" \
- "M: recvonly\r\n" \
- "C: 2\r\n" \
- "X\r\n" \
- "L: p:20\r\n" \
- "\r\n" \
- "v=0\r\n" \
- "c=IN IP4 123.12.12.123\r\n" \
- "m=audio 5904 RTP/AVP 97\r\n" \
- "a=rtpmap:97 GSM-EFR/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define CRCX_RET "200 2 OK\r\n" \
- "I: 1\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=rtpmap:126 AMR/8000\r\n" \
- "a=ptime:20\r\n"
-
-#define CRCX_RET_NO_RTPMAP "200 2 OK\r\n" \
- "I: 1\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 1 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=ptime:20\r\n"
-
-#define CRCX_FMTP_RET "200 2 OK\r\n" \
- "I: 3\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 3 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=rtpmap:126 AMR/8000\r\n" \
- "a=fmtp:126 0/1/2\r\n" \
- "a=ptime:20\r\n"
-
-#define CRCX_ZYN "CRCX 2 1@mgw MGCP 1.0\r" \
- "M: recvonly\r" \
- "C: 2\r\r" \
- "v=0\r" \
- "c=IN IP4 123.12.12.123\r" \
- "m=audio 5904 RTP/AVP 97\r" \
- "a=rtpmap:97 GSM-EFR/8000\r"
-
-#define CRCX_ZYN_RET "200 2 OK\r\n" \
- "I: 2\n" \
- "\n" \
- "v=0\r\n" \
- "o=- 2 23 IN IP4 0.0.0.0\r\n" \
- "s=-\r\n" \
- "c=IN IP4 0.0.0.0\r\n" \
- "t=0 0\r\n" \
- "m=audio 0 RTP/AVP 126\r\n" \
- "a=rtpmap:126 AMR/8000\r\n" \
- "a=ptime:20\r\n"
-
-#define DLCX "DLCX 7 1@mgw MGCP 1.0\r\n" \
- "C: 2\r\n"
-
-#define DLCX_RET "250 7 OK\r\n" \
- "P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0\r\n" \
- "X-Osmo-CP: EC TIS=0, TOS=0, TIR=0, TOR=0\r\n"
-
-#define RQNT "RQNT 186908780 1@mgw MGCP 1.0\r\n" \
- "X: B244F267488\r\n" \
- "S: D/9\r\n"
-
-#define RQNT2 "RQNT 186908781 1@mgw MGCP 1.0\r\n" \
- "X: ADD4F26746F\r\n" \
- "R: D/[0-9#*](N), G/ft, fxr/t38\r\n"
-
-#define RQNT1_RET "200 186908780 OK\r\n"
-#define RQNT2_RET "200 186908781 OK\r\n"
-
-#define PTYPE_IGNORE 0 /* == default initializer */
-#define PTYPE_NONE 128
-#define PTYPE_NYI PTYPE_NONE
-
-#define CRCX_MULT_1 "CRCX 2 1@mgw MGCP 1.0\r\n" \
- "M: recvonly\r\n" \
- "C: 2\r\n" \
- "X\r\n" \
- "L: p:20\r\n" \
- "\r\n" \
- "v=0\r\n" \
- "c=IN IP4 123.12.12.123\r\n" \
- "m=audio 5904 RTP/AVP 18 97\r\n"\
- "a=rtpmap:18 G729/8000\r\n" \
- "a=rtpmap:97 GSM-EFR/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define CRCX_MULT_2 "CRCX 2 2@mgw MGCP 1.0\r\n" \
- "M: recvonly\r\n" \
- "C: 2\r\n" \
- "X\r\n" \
- "L: p:20\r\n" \
- "\r\n" \
- "v=0\r\n" \
- "c=IN IP4 123.12.12.123\r\n" \
- "m=audio 5904 RTP/AVP 18 97 101\r\n"\
- "a=rtpmap:18 G729/8000\r\n" \
- "a=rtpmap:97 GSM-EFR/8000\r\n" \
- "a=rtpmap:101 FOO/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define CRCX_MULT_3 "CRCX 2 3@mgw MGCP 1.0\r\n" \
- "M: recvonly\r\n" \
- "C: 2\r\n" \
- "X\r\n" \
- "L: p:20\r\n" \
- "\r\n" \
- "v=0\r\n" \
- "c=IN IP4 123.12.12.123\r\n" \
- "m=audio 5904 RTP/AVP\r\n" \
- "a=rtpmap:18 G729/8000\r\n" \
- "a=rtpmap:97 GSM-EFR/8000\r\n" \
- "a=rtpmap:101 FOO/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define CRCX_MULT_4 "CRCX 2 4@mgw MGCP 1.0\r\n" \
- "M: recvonly\r\n" \
- "C: 2\r\n" \
- "X\r\n" \
- "L: p:20\r\n" \
- "\r\n" \
- "v=0\r\n" \
- "c=IN IP4 123.12.12.123\r\n" \
- "m=audio 5904 RTP/AVP 18\r\n" \
- "a=rtpmap:18 G729/8000\r\n" \
- "a=rtpmap:97 GSM-EFR/8000\r\n" \
- "a=rtpmap:101 FOO/8000\r\n" \
- "a=ptime:40\r\n"
-
-#define CRCX_MULT_GSM_EXACT \
- "CRCX 259260421 5@mgw MGCP 1.0\r\n" \
- "C: 1355c6041e\r\n" \
- "I: 3\r\n" \
- "L: p:20, a:GSM, nt:IN\r\n" \
- "M: recvonly\r\n" \
- "\r\n" \
- "v=0\r\n" \
- "o=- 1439038275 1439038275 IN IP4 192.168.181.247\r\n" \
- "s=-\r\nc=IN IP4 192.168.181.247\r\n" \
- "t=0 0\r\nm=audio 29084 RTP/AVP 255 0 8 3 18 4 96 97 101\r\n" \
- "a=rtpmap:0 PCMU/8000\r\n" \
- "a=rtpmap:8 PCMA/8000\r\n" \
- "a=rtpmap:3 gsm/8000\r\n" \
- "a=rtpmap:18 G729/8000\r\n" \
- "a=fmtp:18 annexb=no\r\n" \
- "a=rtpmap:4 G723/8000\r\n" \
- "a=rtpmap:96 iLBC/8000\r\n" \
- "a=fmtp:96 mode=20\r\n" \
- "a=rtpmap:97 iLBC/8000\r\n" \
- "a=fmtp:97 mode=30\r\n" \
- "a=rtpmap:101 telephone-event/8000\r\n" \
- "a=fmtp:101 0-15\r\n" \
- "a=recvonly\r\n"
-#define MDCX_NAT_DUMMY \
- "MDCX 23 5@mgw MGCP 1.0\r\n" \
- "C: 1355c6041e\r\n" \
- "\r\n" \
- "c=IN IP4 8.8.8.8\r\n" \
- "m=audio 16434 RTP/AVP 255\r\n"
-
-
-struct mgcp_test {
- const char *name;
- const char *req;
- const char *exp_resp;
- int exp_net_ptype;
- int exp_bts_ptype;
-
- const char *extra_fmtp;
-};
-
-static const struct mgcp_test tests[] = {
- { "AUEP1", AUEP1, AUEP1_RET },
- { "AUEP2", AUEP2, AUEP2_RET },
- { "MDCX1", MDCX_WRONG_EP, MDCX_ERR_RET },
- { "MDCX2", MDCX_UNALLOCATED, MDCX_RET },
- { "CRCX", CRCX, CRCX_RET, 97, 126 },
- { "MDCX3", MDCX3, MDCX3_RET, PTYPE_NONE, 126 },
- { "MDCX4", MDCX4, MDCX4_RET("18983216"), 99, 126 },
- { "MDCX4_PT1", MDCX4_PT1, MDCX4_RET("18983217"), 99, 126 },
- { "MDCX4_PT2", MDCX4_PT2, MDCX4_RET("18983218"), 99, 126 },
- { "MDCX4_PT3", MDCX4_PT3, MDCX4_RET("18983219"), 99, 126 },
- { "MDCX4_SO", MDCX4_SO, MDCX4_RET("18983220"), 99, 126 },
- { "MDCX4_RO", MDCX4_RO, MDCX4_RET("18983221"), PTYPE_IGNORE, 126 },
- { "DLCX", DLCX, DLCX_RET, -1, -1 },
- { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, 97, 126 },
- { "EMPTY", EMPTY, EMPTY_RET },
- { "SHORT1", SHORT, SHORT_RET },
- { "SHORT2", SHORT2, SHORT2_RET },
- { "SHORT3", SHORT3, SHORT2_RET },
- { "SHORT4", SHORT4, SHORT2_RET },
- { "RQNT1", RQNT, RQNT1_RET },
- { "RQNT2", RQNT2, RQNT2_RET },
- { "DLCX", DLCX, DLCX_RET, -1, -1 },
- { "CRCX", CRCX, CRCX_FMTP_RET, 97, 126, .extra_fmtp = "a=fmtp:126 0/1/2" },
- { "MDCX3", MDCX3, MDCX3_FMTP_RET, PTYPE_NONE, 126 , .extra_fmtp = "a=fmtp:126 0/1/2" },
- { "DLCX", DLCX, DLCX_RET, -1, -1 , .extra_fmtp = "a=fmtp:126 0/1/2" },
-};
-
-static const struct mgcp_test retransmit[] = {
- { "CRCX", CRCX, CRCX_RET },
- { "RQNT1", RQNT, RQNT1_RET },
- { "RQNT2", RQNT2, RQNT2_RET },
- { "MDCX3", MDCX3, MDCX3_RET },
- { "DLCX", DLCX, DLCX_RET },
-};
-
-static struct msgb *create_msg(const char *str)
-{
- struct msgb *msg;
-
- msg = msgb_alloc_headroom(4096, 128, "MGCP msg");
- int len = sprintf((char *)msg->data, "%s", str);
- msg->l2h = msgb_put(msg, len);
- return msg;
-}
-
-static int last_endpoint = -1;
-
-static int mgcp_test_policy_cb(struct mgcp_trunk_config *cfg, int endpoint,
- int state, const char *transactio_id)
-{
- fprintf(stderr, "Policy CB got state %d on endpoint %d\n",
- state, endpoint);
- last_endpoint = endpoint;
- return MGCP_POLICY_CONT;
-}
-
-#define MGCP_DUMMY_LOAD 0x23
-static int dummy_packets = 0;
-/* override and forward */
-ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
- const struct sockaddr *dest_addr, socklen_t addrlen)
-{
- typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
- const struct sockaddr *, socklen_t);
- static sendto_t real_sendto = NULL;
- uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
- int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
-
- if (!real_sendto)
- real_sendto = dlsym(RTLD_NEXT, "sendto");
-
- if (len == 1 && ((const char *)buf)[0] == MGCP_DUMMY_LOAD ) {
- fprintf(stderr, "Dummy packet to 0x%08x:%d, msg length %zu\n%s\n\n",
- dest_host, dest_port,
- len, osmo_hexdump(buf, len));
- dummy_packets += 1;
- }
-
- return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
-}
-
-static int64_t force_monotonic_time_us = -1;
-/* override and forward */
-int clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
- typedef int (*clock_gettime_t)(clockid_t clk_id, struct timespec *tp);
- static clock_gettime_t real_clock_gettime = NULL;
-
- if (!real_clock_gettime)
- real_clock_gettime = dlsym(RTLD_NEXT, "clock_gettime");
-
- if (clk_id == CLOCK_MONOTONIC && force_monotonic_time_us >= 0) {
- tp->tv_sec = force_monotonic_time_us / 1000000;
- tp->tv_nsec = (force_monotonic_time_us % 1000000) * 1000;
- return 0;
- }
-
- return real_clock_gettime(clk_id, tp);
-}
-
-#define CONN_UNMODIFIED (0x1000)
-
-static void test_values(void)
-{
- /* Check that NONE disables all output */
- OSMO_ASSERT((MGCP_CONN_NONE & MGCP_CONN_RECV_SEND) == 0)
-
- /* Check that LOOPBACK enables all output */
- OSMO_ASSERT((MGCP_CONN_LOOPBACK & MGCP_CONN_RECV_SEND) ==
- MGCP_CONN_RECV_SEND)
-}
-
-
-static void test_messages(void)
-{
- struct mgcp_config *cfg;
- struct mgcp_endpoint *endp;
- int i;
-
- cfg = mgcp_config_alloc();
-
- cfg->trunk.number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
-
- cfg->policy_cb = mgcp_test_policy_cb;
-
- mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
-
- /* reset endpoints */
- for (i = 0; i < cfg->trunk.number_endpoints; i++) {
- endp = &cfg->trunk.endpoints[i];
- endp->net_end.codec.payload_type = PTYPE_NONE;
- endp->net_end.packet_duration_ms = -1;
-
- OSMO_ASSERT(endp->conn_mode == MGCP_CONN_NONE);
- endp->conn_mode |= CONN_UNMODIFIED;
- }
-
- for (i = 0; i < ARRAY_SIZE(tests); i++) {
- const struct mgcp_test *t = &tests[i];
- struct msgb *inp;
- struct msgb *msg;
-
- printf("Testing %s\n", t->name);
-
- last_endpoint = -1;
- dummy_packets = 0;
-
- osmo_talloc_replace_string(cfg, &cfg->trunk.audio_fmtp_extra, t->extra_fmtp);
-
- inp = create_msg(t->req);
- msg = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- if (!t->exp_resp) {
- if (msg)
- printf("%s failed '%s'\n", t->name, (char *) msg->data);
- } else if (strcmp((char *) msg->data, t->exp_resp) != 0)
- printf("%s failed '%s'\n", t->name, (char *) msg->data);
- msgb_free(msg);
-
- if (dummy_packets)
- printf("Dummy packets: %d\n", dummy_packets);
-
- if (last_endpoint != -1) {
- endp = &cfg->trunk.endpoints[last_endpoint];
-
- if (endp->net_end.packet_duration_ms != -1)
- printf("Detected packet duration: %d\n",
- endp->net_end.packet_duration_ms);
- else
- printf("Packet duration not set\n");
- if (endp->local_options.pkt_period_min ||
- endp->local_options.pkt_period_max)
- printf("Requested packetetization period: "
- "%d-%d\n",
- endp->local_options.pkt_period_min,
- endp->local_options.pkt_period_max);
- else
- printf("Requested packetization period not set\n");
-
- if ((endp->conn_mode & CONN_UNMODIFIED) == 0) {
- printf("Connection mode: %d:%s%s%s%s\n",
- endp->conn_mode,
- !endp->conn_mode ? " NONE" : "",
- endp->conn_mode & MGCP_CONN_SEND_ONLY ?
- " SEND" : "",
- endp->conn_mode & MGCP_CONN_RECV_ONLY ?
- " RECV" : "",
- endp->conn_mode & MGCP_CONN_LOOPBACK &
- ~MGCP_CONN_RECV_SEND ?
- " LOOP" : "");
- fprintf(stderr,
- "BTS output %sabled, NET output %sabled\n",
- endp->bts_end.output_enabled ? "en" : "dis",
- endp->net_end.output_enabled ? "en" : "dis");
- } else
- printf("Connection mode not set\n");
-
- OSMO_ASSERT(endp->net_end.output_enabled ==
- (endp->conn_mode & MGCP_CONN_SEND_ONLY ? 1 : 0));
- OSMO_ASSERT(endp->bts_end.output_enabled ==
- (endp->conn_mode & MGCP_CONN_RECV_ONLY ? 1 : 0));
-
- endp->net_end.packet_duration_ms = -1;
- endp->local_options.pkt_period_min = 0;
- endp->local_options.pkt_period_max = 0;
- endp->conn_mode |= CONN_UNMODIFIED;
- }
-
-
- /* Check detected payload type */
- if (t->exp_net_ptype != PTYPE_IGNORE ||
- t->exp_bts_ptype != PTYPE_IGNORE) {
- OSMO_ASSERT(last_endpoint != -1);
- endp = &cfg->trunk.endpoints[last_endpoint];
-
- fprintf(stderr, "endpoint %d: "
- "payload type BTS %d (exp %d), NET %d (exp %d)\n",
- last_endpoint,
- endp->bts_end.codec.payload_type, t->exp_bts_ptype,
- endp->net_end.codec.payload_type, t->exp_net_ptype);
-
- if (t->exp_bts_ptype != PTYPE_IGNORE)
- OSMO_ASSERT(endp->bts_end.codec.payload_type ==
- t->exp_bts_ptype);
- if (t->exp_net_ptype != PTYPE_IGNORE)
- OSMO_ASSERT(endp->net_end.codec.payload_type ==
- t->exp_net_ptype);
-
- /* Reset them again for next test */
- endp->net_end.codec.payload_type = PTYPE_NONE;
- }
- }
-
- talloc_free(cfg);
-}
-
-static void test_retransmission(void)
-{
- struct mgcp_config *cfg;
- int i;
-
- cfg = mgcp_config_alloc();
-
- cfg->trunk.number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
-
- mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
-
- /* reset endpoints */
- for (i = 0; i < cfg->trunk.number_endpoints; i++) {
- struct mgcp_endpoint *endp;
- endp = &cfg->trunk.endpoints[i];
- endp->bts_end.packet_duration_ms = 20;
- }
-
- for (i = 0; i < ARRAY_SIZE(retransmit); i++) {
- const struct mgcp_test *t = &retransmit[i];
- struct msgb *inp;
- struct msgb *msg;
-
- printf("Testing %s\n", t->name);
-
- inp = create_msg(t->req);
- msg = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- if (strcmp((char *) msg->data, t->exp_resp) != 0)
- printf("%s failed '%s'\n", t->name, (char *) msg->data);
- msgb_free(msg);
-
- /* Retransmit... */
- printf("Re-transmitting %s\n", t->name);
- inp = create_msg(t->req);
- msg = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- if (strcmp((char *) msg->data, t->exp_resp) != 0)
- printf("%s failed '%s'\n", t->name, (char *) msg->data);
- msgb_free(msg);
- }
-
- talloc_free(cfg);
-}
-
-static int rqnt_cb(struct mgcp_endpoint *endp, char _tone)
-{
- ptrdiff_t tone = _tone;
- endp->cfg->data = (void *) tone;
- return 0;
-}
-
-static void test_rqnt_cb(void)
-{
- struct mgcp_config *cfg;
- struct msgb *inp, *msg;
-
- cfg = mgcp_config_alloc();
- cfg->rqnt_cb = rqnt_cb;
-
- cfg->trunk.number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
-
- mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
-
- inp = create_msg(CRCX);
- msgb_free(mgcp_handle_message(cfg, inp));
- msgb_free(inp);
-
- /* send the RQNT and check for the CB */
- inp = create_msg(RQNT);
- msg = mgcp_handle_message(cfg, inp);
- if (strncmp((const char *) msg->l2h, "200", 3) != 0) {
- printf("FAILED: message is not 200. '%s'\n", msg->l2h);
- abort();
- }
-
- if (cfg->data != (void *) '9') {
- printf("FAILED: callback not called: %p\n", cfg->data);
- abort();
- }
-
- msgb_free(msg);
- msgb_free(inp);
-
- inp = create_msg(DLCX);
- msgb_free(mgcp_handle_message(cfg, inp));
- msgb_free(inp);
- talloc_free(cfg);
-}
-
-struct pl_test {
- int cycles;
- uint16_t base_seq;
- uint16_t max_seq;
- uint32_t packets;
-
- uint32_t expected;
- int loss;
-};
-
-static const struct pl_test pl_test_dat[] = {
- /* basic.. just one package */
- { .cycles = 0, .base_seq = 0, .max_seq = 0, .packets = 1, .expected = 1, .loss = 0},
- /* some packages and a bit of loss */
- { .cycles = 0, .base_seq = 0, .max_seq = 100, .packets = 100, .expected = 101, .loss = 1},
- /* wrap around */
- { .cycles = 1<<16, .base_seq = 0xffff, .max_seq = 2, .packets = 4, .expected = 4, .loss = 0},
- /* min loss */
- { .cycles = 0, .base_seq = 0, .max_seq = 0, .packets = UINT_MAX, .expected = 1, .loss = INT_MIN },
- /* max loss, with wrap around on expected max */
- { .cycles = INT_MAX, .base_seq = 0, .max_seq = UINT16_MAX, .packets = 0, .expected = ((uint32_t)(INT_MAX) + UINT16_MAX + 1), .loss = INT_MAX },
-};
-
-static void test_packet_loss_calc(void)
-{
- int i;
- printf("Testing packet loss calculation.\n");
-
- for (i = 0; i < ARRAY_SIZE(pl_test_dat); ++i) {
- uint32_t expected;
- int loss;
- struct mgcp_rtp_state state;
- struct mgcp_rtp_end rtp;
- memset(&state, 0, sizeof(state));
- memset(&rtp, 0, sizeof(rtp));
-
- state.stats_initialized = 1;
- state.stats_base_seq = pl_test_dat[i].base_seq;
- state.stats_max_seq = pl_test_dat[i].max_seq;
- state.stats_cycles = pl_test_dat[i].cycles;
-
- rtp.packets = pl_test_dat[i].packets;
- mgcp_state_calc_loss(&state, &rtp, &expected, &loss);
-
- if (loss != pl_test_dat[i].loss || expected != pl_test_dat[i].expected) {
- printf("FAIL: Wrong exp/loss at idx(%d) Loss(%d vs. %d) Exp(%u vs. %u)\n",
- i, loss, pl_test_dat[i].loss,
- expected, pl_test_dat[i].expected);
- }
- }
-}
-
-static void test_mgcp_stats(void)
-{
- printf("Testing stat parsing\n");
-
- uint32_t bps, bos, pr, _or, jitter;
- struct msgb *msg;
- int loss;
- int rc;
-
- msg = create_msg(DLCX_RET);
- rc = mgcp_parse_stats(msg, &bps, &bos, &pr, &_or, &loss, &jitter);
- printf("Parsing result: %d\n", rc);
- if (bps != 0 || bos != 0 || pr != 0 || _or != 0 || loss != 0 || jitter != 0)
- printf("FAIL: Parsing failed1.\n");
- msgb_free(msg);
-
- msg = create_msg("250 7 OK\r\nP: PS=10, OS=20, PR=30, OR=40, PL=-3, JI=40\r\n");
- rc = mgcp_parse_stats(msg, &bps, &bos, &pr, &_or, &loss, &jitter);
- printf("Parsing result: %d\n", rc);
- if (bps != 10 || bos != 20 || pr != 30 || _or != 40 || loss != -3 || jitter != 40)
- printf("FAIL: Parsing failed2.\n");
- msgb_free(msg);
-}
-
-struct rtp_packet_info {
- float txtime;
- int len;
- char *data;
-};
-
-struct rtp_packet_info test_rtp_packets1[] = {
- /* RTP: SeqNo=0, TS=0 */
- {0.000000, 20, "\x80\x62\x00\x00\x00\x00\x00\x00\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 20, "\x80\x62\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=2, TS=320 */
- {0.040000, 20, "\x80\x62\x00\x02\x00\x00\x01\x40\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* Repeat RTP timestamp: */
- /* RTP: SeqNo=3, TS=320 */
- {0.060000, 20, "\x80\x62\x00\x03\x00\x00\x01\x40\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=4, TS=480 */
- {0.080000, 20, "\x80\x62\x00\x04\x00\x00\x01\xE0\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=5, TS=640 */
- {0.100000, 20, "\x80\x62\x00\x05\x00\x00\x02\x80\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* Double skip RTP timestamp (delta = 2*160): */
- /* RTP: SeqNo=6, TS=960 */
- {0.120000, 20, "\x80\x62\x00\x06\x00\x00\x03\xC0\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=7, TS=1120 */
- {0.140000, 20, "\x80\x62\x00\x07\x00\x00\x04\x60\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=8, TS=1280 */
- {0.160000, 20, "\x80\x62\x00\x08\x00\x00\x05\x00\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* Non 20ms RTP timestamp (delta = 120): */
- /* RTP: SeqNo=9, TS=1400 */
- {0.180000, 20, "\x80\x62\x00\x09\x00\x00\x05\x78\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=10, TS=1560 */
- {0.200000, 20, "\x80\x62\x00\x0A\x00\x00\x06\x18\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=11, TS=1720 */
- {0.220000, 20, "\x80\x62\x00\x0B\x00\x00\x06\xB8\x11\x22\x33\x44"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* SSRC changed to 0x10203040, RTP timestamp jump */
- /* RTP: SeqNo=12, TS=34688 */
- {0.240000, 20, "\x80\x62\x00\x0C\x00\x00\x87\x80\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=13, TS=34848 */
- {0.260000, 20, "\x80\x62\x00\x0D\x00\x00\x88\x20\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=14, TS=35008 */
- {0.280000, 20, "\x80\x62\x00\x0E\x00\x00\x88\xC0\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* Non 20ms RTP timestamp (delta = 120): */
- /* RTP: SeqNo=15, TS=35128 */
- {0.300000, 20, "\x80\x62\x00\x0F\x00\x00\x89\x38\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=16, TS=35288 */
- {0.320000, 20, "\x80\x62\x00\x10\x00\x00\x89\xD8\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=17, TS=35448 */
- {0.340000, 20, "\x80\x62\x00\x11\x00\x00\x8A\x78\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x8A\xAB\xCD\xEF"},
- /* SeqNo increment by 2, RTP timestamp delta = 320: */
- /* RTP: SeqNo=19, TS=35768 */
- {0.360000, 20, "\x80\x62\x00\x13\x00\x00\x8B\xB8\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=20, TS=35928 */
- {0.380000, 20, "\x80\x62\x00\x14\x00\x00\x8C\x58\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=21, TS=36088 */
- {0.380000, 20, "\x80\x62\x00\x15\x00\x00\x8C\xF8\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* Repeat last packet */
- /* RTP: SeqNo=21, TS=36088 */
- {0.400000, 20, "\x80\x62\x00\x15\x00\x00\x8C\xF8\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=22, TS=36248 */
- {0.420000, 20, "\x80\x62\x00\x16\x00\x00\x8D\x98\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=23, TS=36408 */
- {0.440000, 20, "\x80\x62\x00\x17\x00\x00\x8E\x38\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* Don't increment SeqNo but increment timestamp by 160 */
- /* RTP: SeqNo=23, TS=36568 */
- {0.460000, 20, "\x80\x62\x00\x17\x00\x00\x8E\xD8\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=24, TS=36728 */
- {0.480000, 20, "\x80\x62\x00\x18\x00\x00\x8F\x78\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=25, TS=36888 */
- {0.500000, 20, "\x80\x62\x00\x19\x00\x00\x90\x18\x10\x20\x30\x40"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* SSRC changed to 0x50607080, RTP timestamp jump, Delay of 1.5s,
- * SeqNo jump */
- /* RTP: SeqNo=1000, TS=160000 */
- {2.000000, 20, "\x80\x62\x03\xE8\x00\x02\x71\x00\x50\x60\x70\x80"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=1001, TS=160160 */
- {2.020000, 20, "\x80\x62\x03\xE9\x00\x02\x71\xA0\x50\x60\x70\x80"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
- /* RTP: SeqNo=1002, TS=160320 */
- {2.040000, 20, "\x80\x62\x03\xEA\x00\x02\x72\x40\x50\x60\x70\x80"
- "\x01\x23\x45\x67\x89\xAB\xCD\xEF"},
-};
-
-void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
- struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr,
- char *data, int len);
-
-static void test_packet_error_detection(int patch_ssrc, int patch_ts)
-{
- int i;
-
- struct mgcp_trunk_config trunk;
- struct mgcp_endpoint endp;
- struct mgcp_rtp_state state;
- struct mgcp_rtp_end *rtp = &endp.net_end;
- struct sockaddr_in addr = {0};
- char buffer[4096];
- uint32_t last_ssrc = 0;
- uint32_t last_timestamp = 0;
- uint32_t last_seqno = 0;
- int last_in_ts_err_cnt = 0;
- int last_out_ts_err_cnt = 0;
-
- printf("Testing packet error detection%s%s.\n",
- patch_ssrc ? ", patch SSRC" : "",
- patch_ts ? ", patch timestamps" : "");
-
- memset(&trunk, 0, sizeof(trunk));
- memset(&endp, 0, sizeof(endp));
- memset(&state, 0, sizeof(state));
-
- trunk.number_endpoints = 1;
- trunk.endpoints = &endp;
- trunk.force_constant_ssrc = patch_ssrc;
- trunk.force_aligned_timing = patch_ts;
-
- endp.tcfg = &trunk;
-
- mgcp_initialize_endp(&endp);
-
- rtp->codec.payload_type = 98;
-
- for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) {
- struct rtp_packet_info *info = test_rtp_packets1 + i;
-
- force_monotonic_time_us = round(1000000.0 * info->txtime);
-
- OSMO_ASSERT(info->len <= sizeof(buffer));
- OSMO_ASSERT(info->len >= 0);
- memmove(buffer, info->data, info->len);
-
- mgcp_rtp_end_config(&endp, 1, rtp);
-
- mgcp_patch_and_count(&endp, &state, rtp, &addr,
- buffer, info->len);
-
- if (state.out_stream.ssrc != last_ssrc) {
- printf("Output SSRC changed to %08x\n",
- state.out_stream.ssrc);
- last_ssrc = state.out_stream.ssrc;
- }
-
- printf("In TS: %d, dTS: %d, Seq: %d\n",
- state.in_stream.last_timestamp,
- state.in_stream.last_tsdelta,
- state.in_stream.last_seq);
-
- printf("Out TS change: %d, dTS: %d, Seq change: %d, "
- "TS Err change: in %+d, out %+d\n",
- state.out_stream.last_timestamp - last_timestamp,
- state.out_stream.last_tsdelta,
- state.out_stream.last_seq - last_seqno,
- state.in_stream.err_ts_counter - last_in_ts_err_cnt,
- state.out_stream.err_ts_counter - last_out_ts_err_cnt);
-
- printf("Stats: Jitter = %u, Transit = %d\n",
- mgcp_state_calc_jitter(&state), state.stats_transit);
-
- last_in_ts_err_cnt = state.in_stream.err_ts_counter;
- last_out_ts_err_cnt = state.out_stream.err_ts_counter;
- last_timestamp = state.out_stream.last_timestamp;
- last_seqno = state.out_stream.last_seq;
- }
-
- force_monotonic_time_us = -1;
-}
-
-static void test_multilple_codec(void)
-{
- struct mgcp_config *cfg;
- struct mgcp_endpoint *endp;
- struct msgb *inp, *resp;
- struct in_addr addr;
-
- printf("Testing multiple payload types\n");
-
- cfg = mgcp_config_alloc();
- cfg->trunk.number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
- cfg->policy_cb = mgcp_test_policy_cb;
- mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
-
- /* Allocate endpoint 1@mgw with two codecs */
- last_endpoint = -1;
- inp = create_msg(CRCX_MULT_1);
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
-
- OSMO_ASSERT(last_endpoint == 1);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == 18);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 97);
-
- /* Allocate 2@mgw with three codecs, last one ignored */
- last_endpoint = -1;
- inp = create_msg(CRCX_MULT_2);
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
-
- OSMO_ASSERT(last_endpoint == 2);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == 18);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 97);
-
- /* Allocate 3@mgw with no codecs, check for PT == -1 */
- last_endpoint = -1;
- inp = create_msg(CRCX_MULT_3);
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
-
- OSMO_ASSERT(last_endpoint == 3);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == -1);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1);
-
- /* Allocate 4@mgw with a single codec */
- last_endpoint = -1;
- inp = create_msg(CRCX_MULT_4);
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
-
- OSMO_ASSERT(last_endpoint == 4);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == 18);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1);
-
- /* Allocate 5@mgw at select GSM.. */
- last_endpoint = -1;
- inp = create_msg(CRCX_MULT_GSM_EXACT);
- talloc_free(cfg->trunk.audio_name);
- cfg->trunk.audio_name = "GSM/8000";
- cfg->trunk.no_audio_transcoding = 1;
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
-
- OSMO_ASSERT(last_endpoint == 5);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == 3);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1);
-
- inp = create_msg(MDCX_NAT_DUMMY);
- last_endpoint = -1;
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
- OSMO_ASSERT(last_endpoint == 5);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == 3);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1);
- OSMO_ASSERT(endp->net_end.rtp_port == htons(16434));
- memset(&addr, 0, sizeof(addr));
- inet_aton("8.8.8.8", &addr);
- OSMO_ASSERT(endp->net_end.addr.s_addr == addr.s_addr);
-
- /* Check what happens without that flag */
-
- /* Free the previous endpoint and the data ... */
- mgcp_release_endp(endp);
- talloc_free(endp->last_response);
- talloc_free(endp->last_trans);
- endp->last_response = endp->last_trans = NULL;
-
- last_endpoint = -1;
- inp = create_msg(CRCX_MULT_GSM_EXACT);
- cfg->trunk.no_audio_transcoding = 0;
- resp = mgcp_handle_message(cfg, inp);
- msgb_free(inp);
- msgb_free(resp);
-
- OSMO_ASSERT(last_endpoint == 5);
- endp = &cfg->trunk.endpoints[last_endpoint];
- OSMO_ASSERT(endp->net_end.codec.payload_type == 255);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 0);
-
- talloc_free(cfg);
-}
-
-static void test_no_cycle(void)
-{
- struct mgcp_config *cfg;
- struct mgcp_endpoint *endp;
-
- printf("Testing no sequence flow on initial packet\n");
-
- cfg = mgcp_config_alloc();
- cfg->trunk.number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
-
- endp = &cfg->trunk.endpoints[1];
- OSMO_ASSERT(endp->net_state.stats_initialized == 0);
-
- mgcp_rtp_annex_count(endp, &endp->net_state, 0, 0, 2342);
- OSMO_ASSERT(endp->net_state.stats_initialized == 1);
- OSMO_ASSERT(endp->net_state.stats_cycles == 0);
- OSMO_ASSERT(endp->net_state.stats_max_seq == 0);
-
- mgcp_rtp_annex_count(endp, &endp->net_state, 1, 0, 2342);
- OSMO_ASSERT(endp->net_state.stats_initialized == 1);
- OSMO_ASSERT(endp->net_state.stats_cycles == 0);
- OSMO_ASSERT(endp->net_state.stats_max_seq == 1);
-
- /* now jump.. */
- mgcp_rtp_annex_count(endp, &endp->net_state, UINT16_MAX, 0, 2342);
- OSMO_ASSERT(endp->net_state.stats_initialized == 1);
- OSMO_ASSERT(endp->net_state.stats_cycles == 0);
- OSMO_ASSERT(endp->net_state.stats_max_seq == UINT16_MAX);
-
- /* and wrap */
- mgcp_rtp_annex_count(endp, &endp->net_state, 0, 0, 2342);
- OSMO_ASSERT(endp->net_state.stats_initialized == 1);
- OSMO_ASSERT(endp->net_state.stats_cycles == UINT16_MAX + 1);
- OSMO_ASSERT(endp->net_state.stats_max_seq == 0);
-
- talloc_free(cfg);
-}
-
-static void test_no_name(void)
-{
- struct mgcp_config *cfg;
- struct mgcp_endpoint *endp;
- struct msgb *inp, *msg;
- int i;
-
- printf("Testing no rtpmap name\n");
- cfg = mgcp_config_alloc();
-
- cfg->trunk.number_endpoints = 64;
- cfg->trunk.audio_send_name = 0;
- mgcp_endpoints_allocate(&cfg->trunk);
-
- cfg->policy_cb = mgcp_test_policy_cb;
-
- mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
-
- /* reset endpoints */
- for (i = 0; i < cfg->trunk.number_endpoints; i++) {
- endp = &cfg->trunk.endpoints[i];
- endp->net_end.codec.payload_type = PTYPE_NONE;
- endp->net_end.packet_duration_ms = -1;
-
- OSMO_ASSERT(endp->conn_mode == MGCP_CONN_NONE);
- endp->conn_mode |= CONN_UNMODIFIED;
- }
-
- inp = create_msg(CRCX);
- msg = mgcp_handle_message(cfg, inp);
- if (strcmp((char *) msg->data, CRCX_RET_NO_RTPMAP) != 0)
- printf("FAILED: there should not be a RTPMAP: %s\n",
- (char *) msg->data);
- msgb_free(inp);
- msgb_free(msg);
-
- mgcp_release_endp(&cfg->trunk.endpoints[1]);
- talloc_free(cfg);
-}
-
-static void test_osmux_cid(void)
-{
- int id, i;
-
- OSMO_ASSERT(osmux_used_cid() == 0);
- id = osmux_get_cid();
- OSMO_ASSERT(id == 0);
- OSMO_ASSERT(osmux_used_cid() == 1);
- osmux_put_cid(id);
- OSMO_ASSERT(osmux_used_cid() == 0);
-
- for (i = 0; i < 256; ++i) {
- id = osmux_get_cid();
- OSMO_ASSERT(id == i);
- OSMO_ASSERT(osmux_used_cid() == i + 1);
- }
-
- id = osmux_get_cid();
- OSMO_ASSERT(id == -1);
-
- for (i = 0; i < 256; ++i)
- osmux_put_cid(i);
- OSMO_ASSERT(osmux_used_cid() == 0);
-}
-
-int main(int argc, char **argv)
-{
- msgb_talloc_ctx_init(NULL, 0);
- osmo_init_logging(&log_info);
-
- test_strline();
- test_values();
- test_messages();
- test_retransmission();
- test_packet_loss_calc();
- test_rqnt_cb();
- test_mgcp_stats();
- test_packet_error_detection(1, 0);
- test_packet_error_detection(0, 0);
- test_packet_error_detection(0, 1);
- test_packet_error_detection(1, 1);
- test_multilple_codec();
- test_no_cycle();
- test_no_name();
- test_osmux_cid();
-
- printf("Done\n");
- return EXIT_SUCCESS;
-}
diff --git a/tests/mgcp/mgcp_test.ok b/tests/mgcp/mgcp_test.ok
deleted file mode 100644
index 4e27282ee..000000000
--- a/tests/mgcp/mgcp_test.ok
+++ /dev/null
@@ -1,480 +0,0 @@
-line: 'one CR'
-line: 'two CR'
-line: ''
-line: 'one CRLF'
-line: 'two CRLF'
-line: ''
-line: 'one LF'
-line: 'two LF'
-line: ''
-line: 'mixed (4 lines)'
-line: ''
-line: ''
-line: ''
-Testing AUEP1
-Testing AUEP2
-Testing MDCX1
-Testing MDCX2
-Testing CRCX
-Dummy packets: 1
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 1: RECV
-Testing MDCX3
-Dummy packets: 1
-Packet duration not set
-Requested packetization period not set
-Connection mode not set
-Testing MDCX4
-Dummy packets: 1
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 3: SEND RECV
-Testing MDCX4_PT1
-Dummy packets: 1
-Detected packet duration: 40
-Requested packetetization period: 20-40
-Connection mode: 3: SEND RECV
-Testing MDCX4_PT2
-Dummy packets: 1
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 3: SEND RECV
-Testing MDCX4_PT3
-Dummy packets: 1
-Detected packet duration: 40
-Requested packetization period not set
-Connection mode: 3: SEND RECV
-Testing MDCX4_SO
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 2: SEND
-Testing MDCX4_RO
-Dummy packets: 1
-Packet duration not set
-Requested packetetization period: 20-20
-Connection mode: 1: RECV
-Testing DLCX
-Detected packet duration: 20
-Requested packetization period not set
-Connection mode: 0: NONE
-Testing CRCX_ZYN
-Dummy packets: 1
-Packet duration not set
-Requested packetization period not set
-Connection mode: 1: RECV
-Testing EMPTY
-Testing SHORT1
-Testing SHORT2
-Testing SHORT3
-Testing SHORT4
-Testing RQNT1
-Testing RQNT2
-Testing DLCX
-Detected packet duration: 20
-Requested packetization period not set
-Connection mode: 0: NONE
-Testing CRCX
-Dummy packets: 1
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 1: RECV
-Testing MDCX3
-Dummy packets: 1
-Packet duration not set
-Requested packetization period not set
-Connection mode not set
-Testing DLCX
-Detected packet duration: 20
-Requested packetization period not set
-Connection mode: 0: NONE
-Testing CRCX
-Re-transmitting CRCX
-Testing RQNT1
-Re-transmitting RQNT1
-Testing RQNT2
-Re-transmitting RQNT2
-Testing MDCX3
-Re-transmitting MDCX3
-Testing DLCX
-Re-transmitting DLCX
-Testing packet loss calculation.
-Testing stat parsing
-Parsing result: 0
-Parsing result: 0
-Testing packet error detection, patch SSRC.
-Output SSRC changed to 11223344
-In TS: 0, dTS: 0, Seq: 0
-Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 160, dTS: 160, Seq: 1
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 2
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 3
-Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 10, Transit = 160
-In TS: 480, dTS: 160, Seq: 4
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 9, Transit = 160
-In TS: 640, dTS: 160, Seq: 5
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 8, Transit = 160
-In TS: 960, dTS: 320, Seq: 6
-Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 18, Transit = 0
-In TS: 1120, dTS: 160, Seq: 7
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 17, Transit = 0
-In TS: 1280, dTS: 160, Seq: 8
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 0
-In TS: 1400, dTS: 120, Seq: 9
-Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1
-Stats: Jitter = 17, Transit = 40
-In TS: 1560, dTS: 160, Seq: 10
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 40
-In TS: 1720, dTS: 160, Seq: 11
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 15, Transit = 40
-In TS: 34688, dTS: 0, Seq: 12
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 34848, dTS: 160, Seq: 13
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35008, dTS: 160, Seq: 14
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35128, dTS: 120, Seq: 15
-Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1
-Stats: Jitter = 2, Transit = -32728
-In TS: 35288, dTS: 160, Seq: 16
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35448, dTS: 160, Seq: 17
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35768, dTS: 160, Seq: 19
-Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
-Stats: Jitter = 12, Transit = -32888
-In TS: 35928, dTS: 160, Seq: 20
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 11, Transit = -32888
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 20, Transit = -33048
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 29, Transit = -32888
-In TS: 36248, dTS: 160, Seq: 22
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 27, Transit = -32888
-In TS: 36408, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 25, Transit = -32888
-In TS: 36568, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
-Stats: Jitter = 24, Transit = -32888
-In TS: 36728, dTS: 160, Seq: 24
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 22, Transit = -32888
-In TS: 36888, dTS: 160, Seq: 25
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 21, Transit = -32888
-In TS: 160000, dTS: 0, Seq: 1000
-Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160160, dTS: 160, Seq: 1001
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160320, dTS: 160, Seq: 1002
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-Testing packet error detection.
-Output SSRC changed to 11223344
-In TS: 0, dTS: 0, Seq: 0
-Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 160, dTS: 160, Seq: 1
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 2
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 3
-Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 10, Transit = 160
-In TS: 480, dTS: 160, Seq: 4
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 9, Transit = 160
-In TS: 640, dTS: 160, Seq: 5
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 8, Transit = 160
-In TS: 960, dTS: 320, Seq: 6
-Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 18, Transit = 0
-In TS: 1120, dTS: 160, Seq: 7
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 17, Transit = 0
-In TS: 1280, dTS: 160, Seq: 8
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 0
-In TS: 1400, dTS: 120, Seq: 9
-Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1
-Stats: Jitter = 17, Transit = 40
-In TS: 1560, dTS: 160, Seq: 10
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 40
-In TS: 1720, dTS: 160, Seq: 11
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 15, Transit = 40
-Output SSRC changed to 10203040
-In TS: 34688, dTS: 0, Seq: 12
-Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 34848, dTS: 160, Seq: 13
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35008, dTS: 160, Seq: 14
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35128, dTS: 120, Seq: 15
-Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1
-Stats: Jitter = 2, Transit = -32728
-In TS: 35288, dTS: 160, Seq: 16
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35448, dTS: 160, Seq: 17
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35768, dTS: 160, Seq: 19
-Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
-Stats: Jitter = 12, Transit = -32888
-In TS: 35928, dTS: 160, Seq: 20
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 11, Transit = -32888
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 20, Transit = -33048
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 29, Transit = -32888
-In TS: 36248, dTS: 160, Seq: 22
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 27, Transit = -32888
-In TS: 36408, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 25, Transit = -32888
-In TS: 36568, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
-Stats: Jitter = 24, Transit = -32888
-In TS: 36728, dTS: 160, Seq: 24
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 22, Transit = -32888
-In TS: 36888, dTS: 160, Seq: 25
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 21, Transit = -32888
-Output SSRC changed to 50607080
-In TS: 160000, dTS: 0, Seq: 1000
-Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160160, dTS: 160, Seq: 1001
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160320, dTS: 160, Seq: 1002
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-Testing packet error detection, patch timestamps.
-Output SSRC changed to 11223344
-In TS: 0, dTS: 0, Seq: 0
-Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 160, dTS: 160, Seq: 1
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 2
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 3
-Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 10, Transit = 160
-In TS: 480, dTS: 160, Seq: 4
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 9, Transit = 160
-In TS: 640, dTS: 160, Seq: 5
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 8, Transit = 160
-In TS: 960, dTS: 320, Seq: 6
-Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 18, Transit = 0
-In TS: 1120, dTS: 160, Seq: 7
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 17, Transit = 0
-In TS: 1280, dTS: 160, Seq: 8
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 0
-In TS: 1400, dTS: 120, Seq: 9
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0
-Stats: Jitter = 17, Transit = 40
-In TS: 1560, dTS: 160, Seq: 10
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 40
-In TS: 1720, dTS: 160, Seq: 11
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 15, Transit = 40
-Output SSRC changed to 10203040
-In TS: 34688, dTS: 0, Seq: 12
-Out TS change: 32968, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 34848, dTS: 160, Seq: 13
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35008, dTS: 160, Seq: 14
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35128, dTS: 120, Seq: 15
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35288, dTS: 160, Seq: 16
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35448, dTS: 160, Seq: 17
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35768, dTS: 160, Seq: 19
-Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
-Stats: Jitter = 12, Transit = -32888
-In TS: 35928, dTS: 160, Seq: 20
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 11, Transit = -32888
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 20, Transit = -33048
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 29, Transit = -32888
-In TS: 36248, dTS: 160, Seq: 22
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 27, Transit = -32888
-In TS: 36408, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 25, Transit = -32888
-In TS: 36568, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
-Stats: Jitter = 24, Transit = -32888
-In TS: 36728, dTS: 160, Seq: 24
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 22, Transit = -32888
-In TS: 36888, dTS: 160, Seq: 25
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 21, Transit = -32888
-Output SSRC changed to 50607080
-In TS: 160000, dTS: 0, Seq: 1000
-Out TS change: 123112, dTS: 160, Seq change: 975, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160160, dTS: 160, Seq: 1001
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160320, dTS: 160, Seq: 1002
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-Testing packet error detection, patch SSRC, patch timestamps.
-Output SSRC changed to 11223344
-In TS: 0, dTS: 0, Seq: 0
-Out TS change: 0, dTS: 0, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 160, dTS: 160, Seq: 1
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 2
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = 0
-In TS: 320, dTS: 160, Seq: 3
-Out TS change: 0, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 10, Transit = 160
-In TS: 480, dTS: 160, Seq: 4
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 9, Transit = 160
-In TS: 640, dTS: 160, Seq: 5
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 8, Transit = 160
-In TS: 960, dTS: 320, Seq: 6
-Out TS change: 320, dTS: 320, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 18, Transit = 0
-In TS: 1120, dTS: 160, Seq: 7
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 17, Transit = 0
-In TS: 1280, dTS: 160, Seq: 8
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 0
-In TS: 1400, dTS: 120, Seq: 9
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0
-Stats: Jitter = 17, Transit = 40
-In TS: 1560, dTS: 160, Seq: 10
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 16, Transit = 40
-In TS: 1720, dTS: 160, Seq: 11
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 15, Transit = 40
-In TS: 34688, dTS: 0, Seq: 12
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 34848, dTS: 160, Seq: 13
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35008, dTS: 160, Seq: 14
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
-In TS: 35128, dTS: 120, Seq: 15
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35288, dTS: 160, Seq: 16
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35448, dTS: 160, Seq: 17
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
-In TS: 35768, dTS: 160, Seq: 19
-Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
-Stats: Jitter = 12, Transit = -32888
-In TS: 35928, dTS: 160, Seq: 20
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 11, Transit = -32888
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 20, Transit = -33048
-In TS: 36088, dTS: 160, Seq: 21
-Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 29, Transit = -32888
-In TS: 36248, dTS: 160, Seq: 22
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 27, Transit = -32888
-In TS: 36408, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 25, Transit = -32888
-In TS: 36568, dTS: 160, Seq: 23
-Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
-Stats: Jitter = 24, Transit = -32888
-In TS: 36728, dTS: 160, Seq: 24
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 22, Transit = -32888
-In TS: 36888, dTS: 160, Seq: 25
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 21, Transit = -32888
-In TS: 160000, dTS: 0, Seq: 1000
-Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160160, dTS: 160, Seq: 1001
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-In TS: 160320, dTS: 160, Seq: 1002
-Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
-Testing multiple payload types
-Testing no sequence flow on initial packet
-Testing no rtpmap name
-Done
diff --git a/tests/mgcp/mgcp_transcoding_test.c b/tests/mgcp/mgcp_transcoding_test.c
deleted file mode 100644
index c5c0a0bab..000000000
--- a/tests/mgcp/mgcp_transcoding_test.c
+++ /dev/null
@@ -1,654 +0,0 @@
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <err.h>
-#include <stdint.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/application.h>
-
-#include <osmocom/netif/rtp.h>
-
-#include <openbsc/debug.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcp_internal.h>
-
-#include "bscconfig.h"
-#ifndef BUILD_MGCP_TRANSCODING
-#error "Requires MGCP transcoding enabled (see --enable-mgcp-transcoding)"
-#endif
-
-#include "openbsc/mgcp_transcode.h"
-
-uint8_t *audio_frame_l16[] = {
-};
-
-struct rtp_packets {
- float t;
- int len;
- char *data;
-};
-
-struct rtp_packets audio_packets_l16[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 332,
- "\x80\x0B\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
- },
-};
-
-struct rtp_packets audio_packets_gsm[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 45,
- "\x80\x03\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\xD4\x7C\xE3\xE9\x62\x50\x39\xF0\xF8\xB4\x68\xEA\x6C\x0E\x81\x1B"
- "\x56\x2A\xD5\xBC\x69\x9C\xD1\xF0\x66\x7A\xEC\x49\x7A\x33\x3D\x0A"
- "\xDE"
- },
-};
-
-struct rtp_packets audio_packets_gsm_invalid_size[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 41,
- "\x80\x03\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\xD4\x7C\xE3\xE9\x62\x50\x39\xF0\xF8\xB4\x68\xEA\x6C\x0E\x81\x1B"
- "\x56\x2A\xD5\xBC\x69\x9C\xD1\xF0\x66\x7A\xEC\x49\x7A\x33\x3D\x0A"
- "\xDE"
- },
-};
-
-struct rtp_packets audio_packets_gsm_invalid_data[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 45,
- "\x80\x03\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
- "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
- "\xEE"
- },
-};
-
-struct rtp_packets audio_packets_gsm_invalid_ptype[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 45,
- "\x80\x08\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\xD4\x7C\xE3\xE9\x62\x50\x39\xF0\xF8\xB4\x68\xEA\x6C\x0E\x81\x1B"
- "\x56\x2A\xD5\xBC\x69\x9C\xD1\xF0\x66\x7A\xEC\x49\x7A\x33\x3D\x0A"
- "\xDE"
- },
-};
-
-struct rtp_packets audio_packets_g729[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 32,
- "\x80\x12\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\xAF\xC2\x81\x40\x00\xFA\xCE\xA4\x21\x7C\xC5\xC3\x4F\xA5\x98\xF5"
- "\xB2\x95\xC4\xAD"
- },
-};
-
-struct rtp_packets audio_packets_pcma[] = {
- /* RTP: SeqNo=1, TS=160 */
- {0.020000, 172,
- "\x80\x08\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
- },
- /* RTP: SeqNo=26527, TS=232640 */
- {0.020000, 92,
- "\x80\x08\x67\x9f\x00\x03\x8c\xc0\x04\xaa\x67\x9f\xd5\xd5\xd5\xd5"
- "\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5"
- "\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5"
- "\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5"
- "\xd5\xd5\xd5\xd5\xd5\xd5\x55\x55\xd5\xd5\x55\x55\xd5\xd5\x55\x55"
- "\xd5\xd5\xd5\x55\x55\xd5\xd5\xd5\x55\x55\xd5\xd5"
- },
- /* RTP: SeqNo=26528, TS=232720 */
- {0.020000, 92,
- "\x80\x08\x67\xa0\x00\x03\x8d\x10\x04\xaa\x67\x9f\x55\xd5\xd5\x55"
- "\xd5\x55\xd5\xd5\xd5\x55\xd5\x55\xd5\xd5\x55\xd5\x55\xd5\x55\xd5"
- "\x55\x55\xd5\x55\xd5\xd5\x55\x55\x55\x55\x55\xd5\xd5\x55\xd5\xd5"
- "\xd5\x55\xd5\xd5\xd5\x55\x54\x55\xd5\xd5\x55\xd5\xd5\xd5\xd5\x55"
- "\x54\x55\xd5\x55\xd5\x55\x55\x55\x55\x55\xd5\xd5\xd5\xd5\xd5\xd4"
- "\xd5\x54\x55\xd5\xd4\xd5\x54\xd5\x55\xd5\xd5\xd5"
- },
-};
-
-
-
-static int audio_name_to_type(const char *name)
-{
- if (!strcasecmp(name, "gsm"))
- return 3;
-#ifdef HAVE_BCG729
- else if (!strcasecmp(name, "g729"))
- return 18;
-#endif
- else if (!strcasecmp(name, "pcma"))
- return 8;
- else if (!strcasecmp(name, "l16"))
- return 11;
- return -1;
-}
-
-int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
-
-static int given_configured_endpoint(int in_samples, int out_samples,
- const char *srcfmt, const char *dstfmt,
- void **out_ctx, struct mgcp_endpoint **out_endp)
-{
- int rc;
- struct mgcp_rtp_end *dst_end;
- struct mgcp_rtp_end *src_end;
- struct mgcp_config *cfg;
- struct mgcp_trunk_config *tcfg;
- struct mgcp_endpoint *endp;
-
- cfg = mgcp_config_alloc();
- tcfg = talloc_zero(cfg, struct mgcp_trunk_config);
- endp = talloc_zero(tcfg, struct mgcp_endpoint);
-
- cfg->setup_rtp_processing_cb = mgcp_transcoding_setup;
- cfg->rtp_processing_cb = mgcp_transcoding_process_rtp;
- cfg->get_net_downlink_format_cb = mgcp_transcoding_net_downlink_format;
-
- tcfg->endpoints = endp;
- tcfg->number_endpoints = 1;
- tcfg->cfg = cfg;
- endp->tcfg = tcfg;
- endp->cfg = cfg;
- mgcp_initialize_endp(endp);
-
- dst_end = &endp->bts_end;
- dst_end->codec.payload_type = audio_name_to_type(dstfmt);
-
- src_end = &endp->net_end;
- src_end->codec.payload_type = audio_name_to_type(srcfmt);
-
- if (out_samples) {
- dst_end->codec.frame_duration_den = dst_end->codec.rate;
- dst_end->codec.frame_duration_num = out_samples;
- dst_end->frames_per_packet = 1;
- dst_end->force_output_ptime = 1;
- }
-
- rc = mgcp_transcoding_setup(endp, dst_end, src_end);
- if (rc < 0) {
- printf("setup failed: %s", strerror(-rc));
- abort();
- }
-
- *out_ctx = cfg;
- *out_endp = endp;
- return 0;
-}
-
-
-static int transcode_test(const char *srcfmt, const char *dstfmt,
- uint8_t *src_pkts, size_t src_pkt_size)
-{
- char buf[4096] = {0x80, 0};
- void *ctx;
-
- struct mgcp_rtp_end *dst_end;
- struct mgcp_process_rtp_state *state;
- struct mgcp_endpoint *endp;
- int in_size;
- const int in_samples = 160;
- int len, cont;
-
- printf("== Transcoding test ==\n");
- printf("converting %s -> %s\n", srcfmt, dstfmt);
-
- given_configured_endpoint(in_samples, 0, srcfmt, dstfmt, &ctx, &endp);
-
- dst_end = &endp->bts_end;
- state = dst_end->rtp_process_data;
- OSMO_ASSERT(state != NULL);
-
- in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
- OSMO_ASSERT(sizeof(buf) >= in_size + 12);
-
- memcpy(buf, src_pkts, src_pkt_size);
-
- len = src_pkt_size;
-
- cont = mgcp_transcoding_process_rtp(endp, dst_end,
- buf, &len, sizeof(buf));
- if (cont < 0) {
- printf("Nothing encoded due: %s\n", strerror(-cont));
- talloc_free(ctx);
- return -1;
- }
-
- if (len < 24) {
- printf("encoded: %s\n", osmo_hexdump((unsigned char *)buf, len));
- } else {
- const char *str = osmo_hexdump((unsigned char *)buf, len);
- int i = 0;
- const int prefix = 4;
- const int cutlen = 48;
- int nchars = 0;
-
- printf("encoded:\n");
- do {
- nchars = printf("%*s%-.*s", prefix, "", cutlen, str + i);
- i += nchars - prefix;
- printf("\n");
- } while (nchars - prefix >= cutlen);
- }
- printf("counted: %d\n", cont);
- talloc_free(ctx);
- return 0;
-}
-
-static void test_rtp_seq_state(void)
-{
- char buf[4096];
- int len;
- int cont;
- void *ctx;
- struct mgcp_endpoint *endp;
- struct mgcp_process_rtp_state *state;
- struct rtp_hdr *hdr;
- uint32_t ts_no;
- uint16_t seq_no;
-
- given_configured_endpoint(160, 0, "pcma", "l16", &ctx, &endp);
- state = endp->bts_end.rtp_process_data;
- OSMO_ASSERT(!state->is_running);
- OSMO_ASSERT(state->next_seq == 0);
- OSMO_ASSERT(state->next_time == 0);
-
- /* initialize packet */
- len = audio_packets_pcma[0].len;
- memcpy(buf, audio_packets_pcma[0].data, len);
- cont = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, len);
- OSMO_ASSERT(cont >= 0);
- OSMO_ASSERT(state->is_running);
- OSMO_ASSERT(state->next_seq == 2);
- OSMO_ASSERT(state->next_time == 240);
-
- /* verify that the right timestamp was written */
- OSMO_ASSERT(len == audio_packets_pcma[0].len);
- hdr = (struct rtp_hdr *) &buf[0];
-
- memcpy(&ts_no, &hdr->timestamp, sizeof(ts_no));
- OSMO_ASSERT(htonl(ts_no) == 160);
- memcpy(&seq_no, &hdr->sequence, sizeof(seq_no));
- OSMO_ASSERT(htons(seq_no) == 1);
- /* Check the right sequence number is written */
- state->next_seq = 1234;
- len = audio_packets_pcma[0].len;
- memcpy(buf, audio_packets_pcma[0].data, len);
- cont = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, len);
- OSMO_ASSERT(cont >= 0);
- OSMO_ASSERT(len == audio_packets_pcma[0].len);
- hdr = (struct rtp_hdr *) &buf[0];
-
- memcpy(&seq_no, &hdr->sequence, sizeof(seq_no));
- OSMO_ASSERT(htons(seq_no) == 1234);
-
- talloc_free(ctx);
-}
-
-static void test_transcode_result(void)
-{
- char buf[4096];
- int len, res;
- void *ctx;
- struct mgcp_endpoint *endp;
- struct mgcp_process_rtp_state *state;
-
- {
- /* from GSM to PCMA and same ptime */
- given_configured_endpoint(160, 0, "gsm", "pcma", &ctx, &endp);
- state = endp->bts_end.rtp_process_data;
-
- /* result */
- len = audio_packets_gsm[0].len;
- memcpy(buf, audio_packets_gsm[0].data, len);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res == sizeof(struct rtp_hdr));
- OSMO_ASSERT(state->sample_cnt == 0);
-
- len = res;
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res == -ENOMSG);
-
- talloc_free(ctx);
- }
-
- {
- /* from GSM to PCMA and same ptime */
- given_configured_endpoint(160, 160, "gsm", "pcma", &ctx, &endp);
- state = endp->bts_end.rtp_process_data;
-
- /* result */
- len = audio_packets_gsm[0].len;
- memcpy(buf, audio_packets_gsm[0].data, len);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res == sizeof(struct rtp_hdr));
- OSMO_ASSERT(state->sample_cnt == 0);
-
- len = res;
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res == -EAGAIN);
-
- talloc_free(ctx);
- }
-
- {
- /* from PCMA to GSM and wrong different ptime */
- given_configured_endpoint(80, 160, "pcma", "gsm", &ctx, &endp);
- state = endp->bts_end.rtp_process_data;
-
- /* Add the first sample */
- len = audio_packets_pcma[1].len;
- memcpy(buf, audio_packets_pcma[1].data, len);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(state->sample_cnt == 80);
- OSMO_ASSERT(state->next_time == 232640);
- OSMO_ASSERT(res < 0);
-
- /* Add the second sample and it should be consumable */
- len = audio_packets_pcma[2].len;
- memcpy(buf, audio_packets_pcma[2].data, len);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(state->sample_cnt == 0);
- OSMO_ASSERT(state->next_time == 232640 + 80 + 160);
- OSMO_ASSERT(res == sizeof(struct rtp_hdr));
-
- talloc_free(ctx);
- }
-
- {
- /* from PCMA to GSM with a big time jump */
- struct rtp_hdr *hdr;
- uint32_t ts;
-
- given_configured_endpoint(80, 160, "pcma", "gsm", &ctx, &endp);
- state = endp->bts_end.rtp_process_data;
-
- /* Add the first sample */
- len = audio_packets_pcma[1].len;
- memcpy(buf, audio_packets_pcma[1].data, len);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(state->sample_cnt == 80);
- OSMO_ASSERT(state->next_time == 232640);
- OSMO_ASSERT(state->next_seq == 26527);
- OSMO_ASSERT(res < 0);
-
- /* Add a skip to the packet to force a 'resync' */
- len = audio_packets_pcma[2].len;
- memcpy(buf, audio_packets_pcma[2].data, len);
- hdr = (struct rtp_hdr *) &buf[0];
- /* jump the time and add alignment error */
- ts = ntohl(hdr->timestamp) + 123 * 80 + 2;
- hdr->timestamp = htonl(ts);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res < 0);
- OSMO_ASSERT(state->sample_cnt == 80);
- OSMO_ASSERT(state->next_time == ts);
- OSMO_ASSERT(state->next_seq == 26527);
- /* TODO: this can create alignment errors */
-
-
- /* Now attempt to consume 160 samples */
- len = audio_packets_pcma[2].len;
- memcpy(buf, audio_packets_pcma[2].data, len);
- hdr = (struct rtp_hdr *) &buf[0];
- ts += 80;
- hdr->timestamp = htonl(ts);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res == 12);
- OSMO_ASSERT(state->sample_cnt == 0);
- OSMO_ASSERT(state->next_time == ts + 160);
- OSMO_ASSERT(state->next_seq == 26528);
-
- talloc_free(ctx);
- }
-}
-
-static void test_transcode_change(void)
-{
- char buf[4096] = {0x80, 0};
- void *ctx;
-
- struct mgcp_endpoint *endp;
- struct mgcp_process_rtp_state *state;
- struct rtp_hdr *hdr;
-
- int len, res;
-
- {
- /* from GSM to PCMA and same ptime */
- printf("Testing Initial L16->GSM, PCMA->GSM\n");
- given_configured_endpoint(160, 0, "l16", "gsm", &ctx, &endp);
- endp->net_end.alt_codec = endp->net_end.codec;
- endp->net_end.alt_codec.payload_type = audio_name_to_type("pcma");
- state = endp->bts_end.rtp_process_data;
-
- /* initial transcoding work */
- OSMO_ASSERT(state->src_fmt == AF_L16);
- OSMO_ASSERT(state->dst_fmt == AF_GSM);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 8);
- OSMO_ASSERT(endp->net_end.codec.payload_type == 11);
-
- /* result */
- len = audio_packets_pcma[0].len;
- memcpy(buf, audio_packets_pcma[0].data, len);
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- state = endp->bts_end.rtp_process_data;
- OSMO_ASSERT(res == sizeof(struct rtp_hdr));
- OSMO_ASSERT(state->sample_cnt == 0);
- OSMO_ASSERT(state->src_fmt == AF_PCMA);
- OSMO_ASSERT(state->dst_fmt == AF_GSM);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 11);
- OSMO_ASSERT(endp->net_end.codec.payload_type == 8);
-
- len = res;
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(res == -ENOMSG);
- OSMO_ASSERT(state == endp->bts_end.rtp_process_data);
-
-
- /* now check that comfort noise doesn't change anything */
- len = audio_packets_pcma[1].len;
- memcpy(buf, audio_packets_pcma[1].data, len);
- hdr = (struct rtp_hdr *) buf;
- hdr->payload_type = 12;
- res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
- OSMO_ASSERT(state == endp->bts_end.rtp_process_data);
- OSMO_ASSERT(state->sample_cnt == 80);
- OSMO_ASSERT(state->src_fmt == AF_PCMA);
- OSMO_ASSERT(state->dst_fmt == AF_GSM);
- OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 11);
- OSMO_ASSERT(endp->net_end.codec.payload_type == 8);
-
- talloc_free(ctx);
- }
-}
-
-static int test_repacking(int in_samples, int out_samples, int no_transcode)
-{
- char buf[4096] = {0x80, 0};
- int cc;
- struct mgcp_endpoint *endp;
- void *ctx;
-
- struct mgcp_process_rtp_state *state;
- int in_cnt;
- int out_size;
- int in_size;
- uint32_t ts = 0;
- uint16_t seq = 0;
- const char *srcfmt = "pcma";
- const char *dstfmt = no_transcode ? "pcma" : "l16";
-
- printf("== Transcoding test ==\n");
- printf("converting %s -> %s\n", srcfmt, dstfmt);
-
- given_configured_endpoint(in_samples, out_samples, srcfmt, dstfmt, &ctx, &endp);
-
- state = endp->bts_end.rtp_process_data;
- OSMO_ASSERT(state != NULL);
-
- in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
- OSMO_ASSERT(sizeof(buf) >= in_size + 12);
-
- out_size = mgcp_transcoding_get_frame_size(state, -1, 1);
- OSMO_ASSERT(sizeof(buf) >= out_size + 12);
-
- buf[1] = endp->net_end.codec.payload_type;
- *(uint16_t*)(buf+2) = htons(1);
- *(uint32_t*)(buf+4) = htonl(0);
- *(uint32_t*)(buf+8) = htonl(0xaabbccdd);
-
- for (in_cnt = 0; in_cnt < 16; in_cnt++) {
- int cont;
- int len;
-
- /* fake PCMA data */
- printf("generating %d %s input samples\n", in_samples, srcfmt);
- for (cc = 0; cc < in_samples; cc++)
- buf[12+cc] = cc;
-
- *(uint16_t*)(buf+2) = htonl(seq);
- *(uint32_t*)(buf+4) = htonl(ts);
-
- seq += 1;
- ts += in_samples;
-
- cc += 12; /* include RTP header */
-
- len = cc;
-
- do {
- cont = mgcp_transcoding_process_rtp(endp, &endp->bts_end,
- buf, &len, sizeof(buf));
- if (cont == -EAGAIN) {
- fprintf(stderr, "Got EAGAIN\n");
- break;
- }
-
- if (cont < 0) {
- printf("processing failed: %s", strerror(-cont));
- abort();
- }
-
- len -= 12; /* ignore RTP header */
-
- printf("got %d %s output frames (%d octets) count=%d\n",
- len / out_size, dstfmt, len, cont);
-
- len = cont;
- } while (len > 0);
- }
-
- talloc_free(ctx);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- int rc;
- osmo_init_logging(&log_info);
-
- printf("=== Transcoding Good Cases ===\n");
-
- transcode_test("l16", "l16",
- (uint8_t *)audio_packets_l16[0].data,
- audio_packets_l16[0].len);
- transcode_test("l16", "gsm",
- (uint8_t *)audio_packets_l16[0].data,
- audio_packets_l16[0].len);
- transcode_test("l16", "pcma",
- (uint8_t *)audio_packets_l16[0].data,
- audio_packets_l16[0].len);
- transcode_test("gsm", "l16",
- (uint8_t *)audio_packets_gsm[0].data,
- audio_packets_gsm[0].len);
- transcode_test("gsm", "gsm",
- (uint8_t *)audio_packets_gsm[0].data,
- audio_packets_gsm[0].len);
- transcode_test("gsm", "pcma",
- (uint8_t *)audio_packets_gsm[0].data,
- audio_packets_gsm[0].len);
- transcode_test("pcma", "l16",
- (uint8_t *)audio_packets_pcma[0].data,
- audio_packets_pcma[0].len);
- transcode_test("pcma", "gsm",
- (uint8_t *)audio_packets_pcma[0].data,
- audio_packets_pcma[0].len);
- transcode_test("pcma", "pcma",
- (uint8_t *)audio_packets_pcma[0].data,
- audio_packets_pcma[0].len);
-
- printf("=== Transcoding Bad Cases ===\n");
-
- printf("Invalid size:\n");
- rc = transcode_test("gsm", "pcma",
- (uint8_t *)audio_packets_gsm_invalid_size[0].data,
- audio_packets_gsm_invalid_size[0].len);
- OSMO_ASSERT(rc < 0);
-
- printf("Invalid data:\n");
- rc = transcode_test("gsm", "pcma",
- (uint8_t *)audio_packets_gsm_invalid_data[0].data,
- audio_packets_gsm_invalid_data[0].len);
- OSMO_ASSERT(rc < 0);
-
- printf("Invalid payload type:\n");
- rc = transcode_test("gsm", "pcma",
- (uint8_t *)audio_packets_gsm_invalid_ptype[0].data,
- audio_packets_gsm_invalid_ptype[0].len);
- OSMO_ASSERT(rc == 0);
-
- printf("=== Repacking ===\n");
-
- test_repacking(160, 160, 0);
- test_repacking(160, 160, 1);
- test_repacking(160, 80, 0);
- test_repacking(160, 80, 1);
- test_repacking(160, 320, 0);
- test_repacking(160, 320, 1);
- test_repacking(160, 240, 0);
- test_repacking(160, 240, 1);
- test_repacking(160, 100, 0);
- test_repacking(160, 100, 1);
- test_rtp_seq_state();
- test_transcode_result();
- test_transcode_change();
-
- return 0;
-}
-
diff --git a/tests/mgcp/mgcp_transcoding_test.ok b/tests/mgcp/mgcp_transcoding_test.ok
deleted file mode 100644
index 387cfd275..000000000
--- a/tests/mgcp/mgcp_transcoding_test.ok
+++ /dev/null
@@ -1,539 +0,0 @@
-=== Transcoding Good Cases ===
-== Transcoding test ==
-converting l16 -> l16
-encoded:
- 80 0b 00 01 00 00 00 a0 11 22 33 44 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed 00 00 40 13
- 5a 9e 40 13 00 00 bf ed a5 62 bf ed
-counted: 0
-== Transcoding test ==
-converting l16 -> gsm
-encoded:
- 80 0b 00 01 00 00 00 a0 11 22 33 44 d4 7c e3 e9
- 62 50 39 f0 f8 b4 68 ea 6c 0e 81 1b 56 2a d5 bc
- 69 9c d1 f0 66 7a ec 49 7a 33 3d 0a de
-counted: 12
-== Transcoding test ==
-converting l16 -> pcma
-encoded:
- 80 0b 00 01 00 00 00 a0 11 22 33 44 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25
-counted: 12
-== Transcoding test ==
-converting gsm -> l16
-encoded:
- 80 03 00 01 00 00 00 a0 11 22 33 44 00 00 54 00
- 59 f0 34 20 c4 c8 b9 f8 e2 18 f1 e8 f2 28 f0 e0
- 46 08 4f 80 2c a0 a9 c8 80 00 c0 58 3f 80 63 c0
- 24 b8 fa b8 f6 88 0b a0 c8 70 a8 b0 c8 c0 3b a8
- 66 a0 2e 38 d1 f8 98 98 aa 18 e8 30 26 a0 37 40
- 37 e8 17 00 ee 50 b7 80 b1 88 de 28 18 40 45 b0
- 4f 48 21 d8 df 78 ae 68 ab 98 d6 b8 18 18 48 90
- 4e 70 27 40 e8 10 b5 b0 ac 80 d4 60 14 50 48 48
- 50 10 2a 00 ec 08 ba 00 af 58 d1 c0 10 60 45 c8
- 54 10 30 78 f1 a8 bb 18 ad 48 ce 30 0a e8 3f 30
- 4f 10 32 18 f6 18 bf 20 ac 30 cd 80 0b d0 43 d8
- 55 e0 34 a0 f5 78 bc 98 ad 98 cd c8 0a 80 40 58
- 51 c0 35 40 f9 60 c1 68 ac c8 cb 38 08 00 40 98
- 51 e0 34 d8 fa 28 c2 f0 ae 40 c7 70 02 d0 3c a8
- 54 78 38 a0 fc 68 c2 08 ad 50 c7 78 01 60 39 c0
- 51 38 3a e8 00 e8 c6 38 ab d8 c4 00 fe 08 39 18
- 50 30 39 50 01 d8 ca 70 b1 80 c4 c8 fc 58 36 40
- 51 d8 3b 08 02 80 c8 58 b0 60 c5 a8 fb d0 33 e8
- 4e 80 3c e0 06 10 cb 90 ae 48 c2 60 f9 58 34 08
- 4d a0 3a a8 06 48 cf 80 b4 60 c3 e8 f7 90 30 18
- 4d a0 3b 98 07 90 cf 18 b4 68 c4 88
-counted: 12
-== Transcoding test ==
-converting gsm -> gsm
-encoded:
- 80 03 00 01 00 00 00 a0 11 22 33 44 d4 7c e3 e9
- 62 50 39 f0 f8 b4 68 ea 6c 0e 81 1b 56 2a d5 bc
- 69 9c d1 f0 66 7a ec 49 7a 33 3d 0a de
-counted: 0
-== Transcoding test ==
-converting gsm -> pcma
-encoded:
- 80 03 00 01 00 00 00 a0 11 22 33 44 d5 a0 a3 bf
- 38 24 08 19 1e 1b a4 a6 b3 20 2a 3a ba ad b7 60
- 17 92 3e 20 3e b8 ac b2 32 2c 20 02 b6 be be 82
- 04 27 26 35 8d a4 a6 b5 35 21 20 31 8d a7 a6 b6
- 02 27 21 30 81 a7 a1 b0 06 24 21 32 85 a4 a0 bd
- 19 24 21 3d 90 ba a6 bc 16 25 21 3c 92 a5 a0 bf
- 10 25 21 3c 90 a5 a1 bf 6f 3a 21 3f 95 a5 a1 bf
- 62 3b 21 39 f3 bb a0 b9 79 3b 21 39 c3 b9 a1 b8
- db 39 20 3b 4a b9 a1 b9 c8 3f 26 38 78 be a1 b8
- f1 3e 26 38 65 bc a6 bb ed 3f 21 3b 6f bf a6 b8
- ec 3d 27 3b 15 bd a6 b8 eb 3d 27 38
-counted: 12
-== Transcoding test ==
-converting pcma -> l16
-encoded:
- 80 08 00 01 00 00 00 a0 11 22 33 44 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00 00 08 42 00
- 5a 00 42 00 00 08 be 00 a6 00 be 00
-counted: 12
-== Transcoding test ==
-converting pcma -> gsm
-encoded:
- 80 08 00 01 00 00 00 a0 11 22 33 44 d4 b9 f4 5d
- d9 50 5a e1 a0 cd 76 ea 52 0e 87 53 ad d4 ea a2
- 0a 63 ca e9 60 79 e2 2a 25 d2 c0 f3 39
-counted: 12
-== Transcoding test ==
-converting pcma -> pcma
-encoded:
- 80 08 00 01 00 00 00 a0 11 22 33 44 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25 d5 a5 a3 a5
- d5 25 23 25 d5 a5 a3 a5 d5 25 23 25
-counted: 0
-=== Transcoding Bad Cases ===
-Invalid size:
-== Transcoding test ==
-converting gsm -> pcma
-Nothing encoded due: No message of desired type
-Invalid data:
-== Transcoding test ==
-converting gsm -> pcma
-Nothing encoded due: No message of desired type
-Invalid payload type:
-== Transcoding test ==
-converting gsm -> pcma
-encoded:
- 80 08 00 01 00 00 00 a0 11 22 33 44 d5 a0 a3 bf
- 38 24 08 19 1e 1b a4 a6 b3 20 2a 3a ba ad b7 60
- 17 92 3e 20 3e b8 ac b2 32 2c 20 02 b6 be be 82
- 04 27 26 35 8d a4 a6 b5 35 21 20 31 8d a7 a6 b6
- 02 27 21 30 81 a7 a1 b0 06 24 21 32 85 a4 a0 bd
- 19 24 21 3d 90 ba a6 bc 16 25 21 3c 92 a5 a0 bf
- 10 25 21 3c 90 a5 a1 bf 6f 3a 21 3f 95 a5 a1 bf
- 62 3b 21 39 f3 bb a0 b9 79 3b 21 39 c3 b9 a1 b8
- db 39 20 3b 4a b9 a1 b9 c8 3f 26 38 78 be a1 b8
- f1 3e 26 38 65 bc a6 bb ed 3f 21 3b 6f bf a6 b8
- ec 3d 27 3b 15 bd a6 b8 eb 3d 27 38
-counted: 12
-=== Repacking ===
-== Transcoding test ==
-converting pcma -> l16
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-generating 160 pcma input samples
-got 2 l16 output frames (320 octets) count=12
-== Transcoding test ==
-converting pcma -> pcma
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-generating 160 pcma input samples
-got 2 pcma output frames (160 octets) count=12
-== Transcoding test ==
-converting pcma -> l16
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-== Transcoding test ==
-converting pcma -> pcma
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-== Transcoding test ==
-converting pcma -> l16
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 l16 output frames (640 octets) count=12
-== Transcoding test ==
-converting pcma -> pcma
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 4 pcma output frames (320 octets) count=12
-== Transcoding test ==
-converting pcma -> l16
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 l16 output frames (480 octets) count=12
-== Transcoding test ==
-converting pcma -> pcma
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-generating 160 pcma input samples
-generating 160 pcma input samples
-got 3 pcma output frames (240 octets) count=12
-== Transcoding test ==
-converting pcma -> l16
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-generating 160 pcma input samples
-got 1 l16 output frames (160 octets) count=12
-got 1 l16 output frames (160 octets) count=12
-== Transcoding test ==
-converting pcma -> pcma
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-generating 160 pcma input samples
-got 1 pcma output frames (80 octets) count=12
-got 1 pcma output frames (80 octets) count=12
-Testing Initial L16->GSM, PCMA->GSM
diff --git a/tests/mgcp/mgcpgw_client_test.c b/tests/mgcp/mgcpgw_client_test.c
deleted file mode 100644
index 20e9b78da..000000000
--- a/tests/mgcp/mgcpgw_client_test.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved
- *
- * Author: Neels Hofmeyr
- *
- * 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 <string.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/application.h>
-#include <openbsc/mgcp.h>
-#include <openbsc/mgcpgw_client.h>
-
-void *ctx;
-
-#define buf_len 4096
-
-#if 0
-static struct msgb *from_hex(const char *hex)
-{
- struct msgb *msg = msgb_alloc(buf_len, "mgcpgw_test_from_hex");
- unsigned int l = osmo_hexparse(hex, msg->data, buf_len);
- msg->l2h = msgb_put(msg, l);
- return msg;
-}
-
-static struct msgb *mgcp_from_str(const char *head, const char *params)
-{
- struct msgb *msg = msgb_alloc(buf_len, "mgcp_from_str");
- unsigned int l;
- char *data;
- l = strlen(head);
- msg->l2h = msgb_put(msg, l);
- data = (char*)msgb_l2(msg);
- strncpy(data, head, l);
-
- data = (char*)msgb_put(msg, 1);
- *data = '\n';
-
- l = strlen(params);
- data = (char*)msgb_put(msg, l);
- strncpy(data, params, l);
-
- return msg;
-}
-#endif
-
-static struct msgb *from_str(const char *str)
-{
- struct msgb *msg = msgb_alloc(buf_len, "from_str");
- unsigned int l = strlen(str);
- char *data;
- msg->l2h = msgb_put(msg, l);
- data = (char*)msgb_l2(msg);
- strncpy(data, str, l);
- return msg;
-}
-
-static struct mgcpgw_client_conf conf;
-struct mgcpgw_client *mgcp = NULL;
-
-static void reply_to(mgcp_trans_id_t trans_id, int code, const char *comment,
- int conn_id, const char *params)
-{
- static char compose[4096 - 128];
- int len;
-
- len = snprintf(compose, sizeof(compose),
- "%d %u %s\r\nI: %d\n\n%s",
- code, trans_id, comment, conn_id, params);
- OSMO_ASSERT(len < sizeof(compose));
- OSMO_ASSERT(len > 0);
-
- printf("composed response:\n-----\n%s\n-----\n",
- compose);
- mgcpgw_client_rx(mgcp, from_str(compose));
-}
-
-void test_response_cb(struct mgcp_response *response, void *priv)
-{
- OSMO_ASSERT(priv == mgcp);
- mgcp_response_parse_params(response);
-
- printf("response cb received:\n"
- " head.response_code = %d\n"
- " head.trans_id = %u\n"
- " head.comment = %s\n"
- " audio_port = %u\n",
- response->head.response_code,
- response->head.trans_id,
- response->head.comment,
- response->audio_port
- );
-}
-
-mgcp_trans_id_t dummy_mgcp_send(struct msgb *msg)
-{
- mgcp_trans_id_t trans_id;
- trans_id = msg->cb[MSGB_CB_MGCP_TRANS_ID];
- char *end;
-
- OSMO_ASSERT(mgcpgw_client_pending_add(mgcp, trans_id, test_response_cb, mgcp));
-
- end = (char*)msgb_put(msg, 1);
- *end = '\0';
- printf("composed:\n-----\n%s\n-----\n",
- (char*)msgb_l2(msg));
-
- talloc_free(msg);
- return trans_id;
-}
-
-void test_crcx(void)
-{
- struct msgb *msg;
- mgcp_trans_id_t trans_id;
-
- printf("\n===== %s =====\n", __func__);
-
- if (mgcp)
- talloc_free(mgcp);
- mgcp = mgcpgw_client_init(ctx, &conf);
-
- msg = mgcp_msg_crcx(mgcp, 23, 42, MGCP_CONN_LOOPBACK);
- trans_id = dummy_mgcp_send(msg);
-
- reply_to(trans_id, 200, "OK", 1,
- "v=0\r\n"
- "o=- 1 23 IN IP4 10.9.1.120\r\n"
- "s=-\r\n"
- "c=IN IP4 10.9.1.120\r\n"
- "t=0 0\r\n"
- "m=audio 16002 RTP/AVP 98\r\n"
- "a=rtpmap:98 AMR/8000\r\n"
- "a=ptime:20\r\n");
-}
-
-int main(int argc, char **argv)
-{
- ctx = talloc_named_const(NULL, 1, "mgcpgw_client_test");
- msgb_talloc_ctx_init(ctx, 0);
- osmo_init_logging(&log_info);
-
- mgcpgw_client_conf_init(&conf);
-
- test_crcx();
-
- printf("Done\n");
- fprintf(stderr, "Done\n");
- return EXIT_SUCCESS;
-}
diff --git a/tests/mgcp/mgcpgw_client_test.err b/tests/mgcp/mgcpgw_client_test.err
deleted file mode 100644
index a965a70ed..000000000
--- a/tests/mgcp/mgcpgw_client_test.err
+++ /dev/null
@@ -1 +0,0 @@
-Done
diff --git a/tests/mgcp/mgcpgw_client_test.ok b/tests/mgcp/mgcpgw_client_test.ok
deleted file mode 100644
index d35f2d6b0..000000000
--- a/tests/mgcp/mgcpgw_client_test.ok
+++ /dev/null
@@ -1,31 +0,0 @@
-
-===== test_crcx =====
-composed:
------
-CRCX 1 17@mgw MGCP 1.0
-C: 2a
-L: p:20, a:AMR, nt:IN
-M: loopback
-
------
-composed response:
------
-200 1 OK
-I: 1
-
-v=0
-o=- 1 23 IN IP4 10.9.1.120
-s=-
-c=IN IP4 10.9.1.120
-t=0 0
-m=audio 16002 RTP/AVP 98
-a=rtpmap:98 AMR/8000
-a=ptime:20
-
------
-response cb received:
- head.response_code = 200
- head.trans_id = 1
- head.comment = OK
- audio_port = 16002
-Done
diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am
index 3ae0c84fc..10184fa4b 100644
--- a/tests/msc_vlr/Makefile.am
+++ b/tests/msc_vlr/Makefile.am
@@ -15,6 +15,7 @@ AM_CFLAGS = \
$(LIBOSMOSIGTRAN_CFLAGS) \
$(LIBOSMORANAP_CFLAGS) \
$(LIBASN1C_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
$(NULL)
noinst_HEADERS = \
@@ -48,7 +49,6 @@ COMMON_LDADD = \
$(top_builddir)/src/libvlr/libvlr.a \
$(top_builddir)/src/libbsc/libbsc.a \
$(top_builddir)/src/libtrau/libtrau.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libcommon/libcommon.a \
$(LIBSMPP34_LIBS) \
$(LIBOSMOCORE_LIBS) \
@@ -59,6 +59,8 @@ COMMON_LDADD = \
$(LIBOSMOSIGTRAN_LIBS) \
$(LIBOSMORANAP_LIBS) \
$(LIBASN1C_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
+ $(LIBRARY_GSM) \
-ldbi \
-lrt \
$(NULL)
diff --git a/tests/sms_queue/Makefile.am b/tests/sms_queue/Makefile.am
index 62c479bab..06c54bcec 100644
--- a/tests/sms_queue/Makefile.am
+++ b/tests/sms_queue/Makefile.am
@@ -14,6 +14,7 @@ AM_CFLAGS = \
$(LIBOSMOSIGTRAN_CFLAGS) \
$(LIBOSMORANAP_CFLAGS) \
$(LIBASN1C_CFLAGS) \
+ $(LIBOSMOLEGACYMGCP_CFLAGS) \
$(NULL)
EXTRA_DIST = \
@@ -34,7 +35,6 @@ sms_queue_test_LDADD = \
$(top_builddir)/src/libvlr/libvlr.a \
$(top_builddir)/src/libbsc/libbsc.a \
$(top_builddir)/src/libtrau/libtrau.a \
- $(top_builddir)/src/libmgcp/libmgcp.a \
$(top_builddir)/src/libcommon/libcommon.a \
$(top_builddir)/src/libcommon-cs/libcommon-cs.a \
$(LIBSMPP34_LIBS) \
@@ -46,6 +46,8 @@ sms_queue_test_LDADD = \
$(LIBOSMOSIGTRAN_LIBS) \
$(LIBOSMORANAP_LIBS) \
$(LIBASN1C_LIBS) \
+ $(LIBOSMOLEGACYMGCP_LIBS) \
+ $(LIBRARY_GSM) \
-ldbi \
-lrt \
$(NULL)
diff --git a/tests/testsuite.at b/tests/testsuite.at
index f21ba0c4d..7a8d84bbe 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -20,26 +20,6 @@ cat $abs_srcdir/channel/channel_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/channel/channel_test], [], [expout], [ignore])
AT_CLEANUP
-AT_SETUP([mgcp])
-AT_KEYWORDS([mgcp])
-cat $abs_srcdir/mgcp/mgcp_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/mgcp/mgcp_test], [], [expout], [ignore])
-AT_CLEANUP
-
-AT_SETUP([mgcp-trans])
-AT_KEYWORDS([mgcp-trans])
-AT_CHECK([test "$enable_mgcp_transcoding_test" == yes || exit 77])
-cat $abs_srcdir/mgcp/mgcp_transcoding_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/mgcp/mgcp_transcoding_test], [], [expout], [ignore])
-AT_CLEANUP
-
-AT_SETUP([mgcpgw_client])
-AT_KEYWORDS([mgcpgw_client])
-cat $abs_srcdir/mgcp/mgcpgw_client_test.ok > expout
-cat $abs_srcdir/mgcp/mgcpgw_client_test.err > experr
-AT_CHECK([$abs_top_builddir/tests/mgcp/mgcpgw_client_test], [], [expout], [experr])
-AT_CLEANUP
-
AT_SETUP([gprs])
AT_KEYWORDS([gprs])
cat $abs_srcdir/gprs/gprs_test.ok > expout
diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py
index 7d4e12187..c4a3c8fbc 100644
--- a/tests/vty_test_runner.py
+++ b/tests/vty_test_runner.py
@@ -71,64 +71,6 @@ class TestVTYBase(unittest.TestCase):
self.vty = None
osmoutil.end_proc(self.proc)
-class TestVTYMGCP(TestVTYBase):
- def vty_command(self):
- return ["./src/osmo-bsc_mgcp/osmo-bsc_mgcp", "-c",
- "doc/examples/osmo-bsc_mgcp/mgcp.cfg"]
-
- def vty_app(self):
- return (4243, "./src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp")
-
- def testForcePtime(self):
- self.vty.enable()
- res = self.vty.command("show running-config")
- self.assert_(res.find(' rtp force-ptime 20\r') > 0)
- self.assertEquals(res.find(' no rtp force-ptime\r'), -1)
-
- self.vty.command("configure terminal")
- self.vty.command("mgcp")
- self.vty.command("no rtp force-ptime")
- res = self.vty.command("show running-config")
- self.assertEquals(res.find(' rtp force-ptime 20\r'), -1)
- self.assertEquals(res.find(' no rtp force-ptime\r'), -1)
-
- def testOmitAudio(self):
- self.vty.enable()
- res = self.vty.command("show running-config")
- self.assert_(res.find(' sdp audio-payload send-name\r') > 0)
- self.assertEquals(res.find(' no sdp audio-payload send-name\r'), -1)
-
- self.vty.command("configure terminal")
- self.vty.command("mgcp")
- self.vty.command("no sdp audio-payload send-name")
- res = self.vty.command("show running-config")
- self.assertEquals(res.find(' rtp sdp audio-payload send-name\r'), -1)
- self.assert_(res.find(' no sdp audio-payload send-name\r') > 0)
-
- # TODO: test it for the trunk!
-
- def testBindAddr(self):
- self.vty.enable()
-
- self.vty.command("configure terminal")
- self.vty.command("mgcp")
-
- # enable.. disable bts-bind-ip
- self.vty.command("rtp bts-bind-ip 254.253.252.250")
- res = self.vty.command("show running-config")
- self.assert_(res.find('rtp bts-bind-ip 254.253.252.250') > 0)
- self.vty.command("no rtp bts-bind-ip")
- res = self.vty.command("show running-config")
- self.assertEquals(res.find(' rtp bts-bind-ip'), -1)
-
- # enable.. disable net-bind-ip
- self.vty.command("rtp net-bind-ip 254.253.252.250")
- res = self.vty.command("show running-config")
- self.assert_(res.find('rtp net-bind-ip 254.253.252.250') > 0)
- self.vty.command("no rtp net-bind-ip")
- res = self.vty.command("show running-config")
- self.assertEquals(res.find(' rtp net-bind-ip'), -1)
-
class TestVTYGenericBSC(TestVTYBase):
@@ -1152,7 +1094,6 @@ if __name__ == '__main__':
os.chdir(workdir)
print "Running tests for specific VTY commands"
suite = unittest.TestSuite()
- suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYMGCP))
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYMSC))
add_bsc_test(suite, workdir)
add_nat_test(suite, workdir)