@@ -1,8 +1,8 @@
/* 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
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2016 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -69,6 +69,7 @@ struct mgcp_endpoint;
struct mgcp_config;
struct mgcp_trunk_config;
struct mgcp_rtp_end;
+struct mgcp_transcoding;
#define MGCP_ENDP_CRCX 1
#define MGCP_ENDP_DLCX 2
@@ -158,6 +159,9 @@ struct mgcp_trunk_config {
/* spec handling */
int force_realloc;
+ /* transcoding */
+ const struct mgcp_transcoding *transcoder;
+
/* timer */
struct osmo_timer_list keepalive_timer;
@@ -184,12 +188,6 @@ struct mgcp_config {
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;
@@ -1,8 +1,8 @@
/* MGCP Private Data */
/*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2016 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -150,6 +150,17 @@ enum mgcp_type {
MGCP_OSMUX_BSC_NAT,
};
+/**
+ * Function pointers for RTP processing/transcoding
+ */
+struct mgcp_transcoding {
+ mgcp_processing processing_cb;
+ mgcp_processing_setup setup_processing_cb;
+ mgcp_get_format get_net_downlink_format_cb;
+};
+
+extern const struct mgcp_transcoding *mgcp_default_transcoder;
+
#include <openbsc/osmux.h>
struct mgcp_endpoint {
@@ -37,6 +37,8 @@ enum audio_format {
AF_PCMU
};
+struct mgcp_transcoding;
+extern const struct mgcp_transcoding mgcp_sw_transcoder;
struct mgcp_process_rtp_state {
/* decoding */
@@ -584,6 +584,7 @@ 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;
+ const struct mgcp_transcoding *trans = tcfg->transcoder;
struct mgcp_rtp_end *rtp_end;
struct mgcp_rtp_state *rtp_state;
int tap_idx;
@@ -613,7 +614,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
int nbytes = 0;
int len = rc;
do {
- cont = endp->cfg->rtp_processing_cb(endp, rtp_end,
+ cont = trans->processing_cb(endp, rtp_end,
buf, &len, RTP_BUF_SIZE);
if (cont < 0)
break;
@@ -2,8 +2,8 @@
/* The protocol implementation */
/*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2016 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -66,6 +66,14 @@ static int setup_rtp_processing(struct mgcp_endpoint *endp);
static int mgcp_analyze_header(struct mgcp_parse_data *parse, char *data);
+static const struct mgcp_transcoding no_transcoder = {
+ .processing_cb = &mgcp_rtp_processing_default,
+ .setup_processing_cb = &mgcp_setup_rtp_processing_default,
+ .get_net_downlink_format_cb = &mgcp_get_net_downlink_format_default,
+};
+
+const struct mgcp_transcoding *mgcp_default_transcoder = &no_transcoder;
+
static int mgcp_check_param(const struct mgcp_endpoint *endp, const char *line)
{
const size_t line_len = strlen(line);
@@ -197,13 +205,15 @@ static struct msgb *create_err_response(struct mgcp_endpoint *endp,
static int write_response_sdp(struct mgcp_endpoint *endp,
char *sdp_record, size_t size, const char *addr)
{
+ const struct mgcp_transcoding *trans;
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,
+ trans = endp->tcfg->transcoder;
+ trans->get_net_downlink_format_cb(endp, &payload_type,
&audio_name, &fmtp_extra);
len = snprintf(sdp_record, size,
@@ -1200,12 +1210,8 @@ struct mgcp_config *mgcp_config_alloc(void)
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.transcoder = mgcp_default_transcoder;
cfg->trunk.cfg = cfg;
cfg->trunk.trunk_nr = 0;
cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
@@ -1231,6 +1237,7 @@ struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr)
return NULL;
}
+ trunk->transcoder = mgcp_default_transcoder;
trunk->cfg = cfg;
trunk->trunk_type = MGCP_TRUNK_E1;
trunk->trunk_nr = nr;
@@ -1459,7 +1466,7 @@ int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint)
static int setup_rtp_processing(struct mgcp_endpoint *endp)
{
int rc = 0;
- struct mgcp_config *cfg = endp->cfg;
+ const struct mgcp_transcoding *trans = endp->tcfg->transcoder;
if (endp->type != MGCP_RTP_DEFAULT)
return 0;
@@ -1468,14 +1475,14 @@ static int setup_rtp_processing(struct mgcp_endpoint *endp)
return 0;
if (endp->conn_mode & MGCP_CONN_SEND_ONLY)
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end);
+ rc |= trans->setup_processing_cb(endp, &endp->net_end, &endp->bts_end);
else
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->net_end, NULL);
+ rc |= trans->setup_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);
+ rc |= trans->setup_processing_cb(endp, &endp->bts_end, &endp->net_end);
else
- rc |= cfg->setup_rtp_processing_cb(endp, &endp->bts_end, NULL);
+ rc |= trans->setup_processing_cb(endp, &endp->bts_end, NULL);
return rc;
}
@@ -32,6 +32,12 @@
#include <osmocom/core/talloc.h>
#include <osmocom/netif/rtp.h>
+const struct mgcp_transcoding mgcp_sw_transcoder = {
+ .processing_cb = mgcp_transcoding_process_rtp,
+ .setup_processing_cb = mgcp_transcoding_setup,
+ .get_net_downlink_format_cb = mgcp_transcoding_net_downlink_format,
+};
+
int mgcp_transcoding_get_frame_size(void *state_, int nsamples, int dst)
{
struct mgcp_process_rtp_state *state = state_;
@@ -470,12 +476,12 @@ struct mgcp_process_rtp_state *check_transcode_state(
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;
+ const struct mgcp_transcoding *trans = endp->tcfg->transcoder;
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);
+ trans->setup_processing_cb(endp, &endp->net_end, &endp->bts_end);
+ trans->setup_processing_cb(endp, &endp->bts_end, &endp->net_end);
}
done:
@@ -207,16 +207,14 @@ int main(int argc, char **argv)
osmo_init_ignore_signals();
osmo_init_logging(&log_info);
+#ifdef BUILD_MGCP_TRANSCODING
+ mgcp_default_transcoder = &mgcp_sw_transcoder;
+#endif
+
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
-
vty_info.copyright = openbsc_copyright;
vty_init(&vty_info);
logging_vty_add_cmds(&log_info);
@@ -161,6 +161,12 @@ static int audio_name_to_type(const char *name)
int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
+static const struct mgcp_transcoding test_transcoder = {
+ .setup_processing_cb = mgcp_transcoding_setup,
+ .processing_cb = mgcp_transcoding_process_rtp,
+ .get_net_downlink_format_cb = mgcp_transcoding_net_downlink_format,
+};
+
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)
@@ -176,10 +182,7 @@ static int given_configured_endpoint(int in_samples, int out_samples,
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->transcoder = &test_transcoder;
tcfg->endpoints = endp;
tcfg->number_endpoints = 1;
tcfg->cfg = cfg;
From: Holger Hans Peter Freyther <holger@moiji-mobile.com> We will have the NOOP implementation (e.g. used by the NAT), the SW implementation (using software codecs), a HW assisted one that will use a DSP to do transcoding and in theory the RTP based one (but I will remove that code). --- openbsc/include/openbsc/mgcp.h | 14 ++++++------- openbsc/include/openbsc/mgcp_internal.h | 15 ++++++++++++-- openbsc/include/openbsc/mgcp_transcode.h | 2 ++ openbsc/src/libmgcp/mgcp_network.c | 3 ++- openbsc/src/libmgcp/mgcp_protocol.c | 33 ++++++++++++++++++------------ openbsc/src/libmgcp/mgcp_transcode.c | 12 ++++++++--- openbsc/src/osmo-bsc_mgcp/mgcp_main.c | 10 ++++----- openbsc/tests/mgcp/mgcp_transcoding_test.c | 11 ++++++---- 8 files changed, 63 insertions(+), 37 deletions(-)