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;
-- 
1.7.9.5


Reply via email to