From patchwork Thu May 15 08:29:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Erlbeck X-Patchwork-Id: 349094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ganesha.gnumonks.org (ganesha.gnumonks.org [IPv6:2001:780:45:1d:225:90ff:fe52:c662]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DF5771400DA for ; Thu, 15 May 2014 18:43:44 +1000 (EST) Received: from localhost ([127.0.0.1] helo=ganesha.gnumonks.org) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WkrG6-0008K6-Tq; Thu, 15 May 2014 10:43:24 +0200 Received: from mail.sysmocom.de ([2a01:4f8:191:444c::2:4]) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WkrDh-0007xC-WB for openbsc@lists.osmocom.org; Thu, 15 May 2014 10:41:01 +0200 Received: from sysmocom-tmp.home (24-134-58-61-dynip.superkabel.de [24.134.58.61]) by mail.sysmocom.de (Postfix) with ESMTPSA id EE49258EFE; Thu, 15 May 2014 08:40:52 +0000 (UTC) From: Jacob Erlbeck To: openbsc@lists.osmocom.org Subject: [PATCH 01/11] mgcp: Add callbacks for payload processing Date: Thu, 15 May 2014 10:29:09 +0200 Message-Id: <1400142559-26788-1-git-send-email-jerlbeck@sysmocom.de> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1399891147-31419-1-git-send-email-jerlbeck@sysmocom.de> References: <1399891147-31419-1-git-send-email-jerlbeck@sysmocom.de> X-Spam-Score: 0.2 (/) X-Spam-Report: SpamASsassin versoin 3.3.1 on ganesha.gnumonks.org summary: Content analysis details: (0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.1 TW_CF BODY: Odd Letter Triples with CF 0.1 TW_MG BODY: Odd Letter Triples with MG 0.1 TW_GC BODY: Odd Letter Triples with GC Cc: Jacob Erlbeck X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: openbsc-bounces@lists.osmocom.org Errors-To: openbsc-bounces@lists.osmocom.org This patch adds the callbacks rtp_processing_cb and setup_rtp_processing_cb to mgcp_config to support arbitrary RTP payload processing. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp.h | 10 +++++++++ openbsc/include/openbsc/mgcp_internal.h | 8 ++++++++ openbsc/src/libmgcp/mgcp_network.c | 20 +++++++++++++++--- openbsc/src/libmgcp/mgcp_protocol.c | 34 ++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 1d74078..6ba0769 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -65,6 +65,7 @@ static inline int rtp_calculate_port(int multiplex, int base) struct mgcp_endpoint; struct mgcp_config; struct mgcp_trunk_config; +struct mgcp_rtp_end; #define MGCP_ENDP_CRCX 1 #define MGCP_ENDP_DLCX 2 @@ -86,6 +87,11 @@ typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int stat typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg); typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone); +typedef int (*mgcp_processing)(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); #define PORT_ALLOC_STATIC 0 #define PORT_ALLOC_DYNAMIC 1 @@ -156,6 +162,10 @@ 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; + struct osmo_wqueue gw_fd; struct mgcp_port_range bts_ports; diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 9b97165..56c280d 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -91,6 +91,7 @@ struct mgcp_rtp_end { /* 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... @@ -197,5 +198,12 @@ 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_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); #endif diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c index 8a5656a..4d1ad35 100644 --- a/openbsc/src/libmgcp/mgcp_network.c +++ b/openbsc/src/libmgcp/mgcp_network.c @@ -77,6 +77,7 @@ struct rtp_hdr { #define RTP_SEQ_MOD (1 << 16) #define RTP_MAX_DROPOUT 3000 #define RTP_MAX_MISORDER 100 +#define RTP_BUF_SIZE 4096 enum { @@ -347,6 +348,18 @@ static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp, return timestamp_error; } +int mgcp_rtp_processing_default(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; +} /** * The RFC 3550 Appendix A assumes there are multiple sources but @@ -597,6 +610,7 @@ static int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, rtp_end->dropped_packets += 1; else if (is_rtp) { mgcp_patch_and_count(endp, rtp_state, rtp_end, addr, buf, rc); + endp->cfg->rtp_processing_cb(rtp_end, buf, &rc, RTP_BUF_SIZE); forward_data(rtp_end->rtp.fd, &endp->taps[tap_idx], buf, rc); return mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr, @@ -635,7 +649,7 @@ static int receive_from(struct mgcp_endpoint *endp, int fd, struct sockaddr_in * static int rtp_data_net(struct osmo_fd *fd, unsigned int what) { - char buf[4096]; + char buf[RTP_BUF_SIZE]; struct sockaddr_in addr; struct mgcp_endpoint *endp; int rc, proto; @@ -719,7 +733,7 @@ static void discover_bts(struct mgcp_endpoint *endp, int proto, struct sockaddr_ static int rtp_data_bts(struct osmo_fd *fd, unsigned int what) { - char buf[4096]; + char buf[RTP_BUF_SIZE]; struct sockaddr_in addr; struct mgcp_endpoint *endp; int rc, proto; @@ -781,7 +795,7 @@ static int rtp_data_bts(struct osmo_fd *fd, unsigned int what) static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_endp, int dest, struct osmo_fd *fd) { - char buf[4096]; + char buf[RTP_BUF_SIZE]; struct sockaddr_in addr; struct mgcp_config *cfg; int rc, proto; diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 5c88c9d..0f8614c 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -107,6 +107,8 @@ 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 void setup_rtp_processing(struct mgcp_endpoint *endp); + static int mgcp_analyze_header(struct mgcp_parse_data *parse, char *data); static uint32_t generate_call_id(struct mgcp_config *cfg) @@ -827,8 +829,10 @@ mgcp_header_done: endp->bts_end.payload_type = tcfg->audio_payload; endp->bts_end.fmtp_extra = talloc_strdup(tcfg->endpoints, tcfg->audio_fmtp_extra); - if (have_sdp) + if (have_sdp) { parse_sdp_data(&endp->net_end, p); + setup_rtp_processing(endp); + } /* policy CB */ if (p->cfg->policy_cb) { @@ -929,6 +933,8 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) set_local_cx_options(endp->tcfg->endpoints, &endp->local_options, local_options); + setup_rtp_processing(endp); + /* policy CB */ if (p->cfg->policy_cb) { int rc; @@ -1169,6 +1175,9 @@ 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; + /* default trunk handling */ cfg->trunk.cfg = cfg; cfg->trunk.trunk_nr = 0; @@ -1234,6 +1243,8 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) 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->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM; @@ -1388,6 +1399,27 @@ int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint) return send_agent(endp->cfg, buf, len); } +static void setup_rtp_processing(struct mgcp_endpoint *endp) +{ + struct mgcp_config *cfg = endp->cfg; + + if (endp->type != MGCP_RTP_DEFAULT) + return; + + if (endp->conn_mode == MGCP_CONN_LOOPBACK) + return; + + if (endp->conn_mode & MGCP_CONN_SEND_ONLY) + cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end); + else + cfg->setup_rtp_processing_cb(endp, &endp->net_end, NULL); + + if (endp->conn_mode & MGCP_CONN_RECV_ONLY) + cfg->setup_rtp_processing_cb(endp, &endp->bts_end, &endp->net_end); + else + cfg->setup_rtp_processing_cb(endp, &endp->bts_end, NULL); +} + static void create_transcoder(struct mgcp_endpoint *endp) { int port;