mgcp: Add callbacks for payload processing

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
This commit is contained in:
Jacob Erlbeck 2014-03-13 14:24:52 +01:00
parent b492d39177
commit a0d64ce063
4 changed files with 69 additions and 4 deletions

View File

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

View File

@ -90,6 +90,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...
@ -205,6 +206,14 @@ 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);
enum {
MGCP_DEST_NET = 0,
MGCP_DEST_BTS,

View File

@ -79,6 +79,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 {
MGCP_PROTO_RTP,
@ -339,6 +340,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
@ -589,6 +602,7 @@ 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,
@ -627,7 +641,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;
@ -723,7 +737,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;
@ -790,7 +804,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;

View File

@ -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 int mgcp_check_param(const struct mgcp_endpoint *endp, const char *line)
@ -852,8 +854,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) {
@ -980,6 +984,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;
@ -1223,6 +1229,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;
@ -1288,6 +1297,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;
@ -1442,6 +1453,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;