[mgcp] Add option to route audio back to both ends

This is a simple echo functionality in the MGCP... it
will send the audio back to the network|bts..
This commit is contained in:
Holger Hans Peter Freyther 2009-11-18 18:32:31 +01:00
parent 9a26b7c27d
commit e6de05e14c
1 changed files with 36 additions and 23 deletions

View File

@ -61,6 +61,7 @@ static struct in_addr bts_in;
static int first_request = 1;
static const char *audio_name = "GSM-EFR/8000";
static int audio_payload = 97;
static int audio_loop = 0;
static int early_bind = 0;
static char *config_file = "mgcp.cfg";
@ -75,6 +76,16 @@ enum mgcp_connection_mode {
MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
};
enum {
DEST_NETWORK = 0,
DEST_BTS = 1,
};
enum {
PROTO_RTP,
PROTO_RTCP,
};
#define CI_UNUSED 0
static unsigned int last_call_id = 0;
@ -211,7 +222,7 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
struct sockaddr_in addr;
socklen_t slen = sizeof(addr);
struct mgcp_endpoint *endp;
int rc, is_remote;
int rc, dest, proto;
endp = (struct mgcp_endpoint *) fd->data;
@ -231,22 +242,12 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
* able to tell if this is legitimate.
*/
#warning "Slight spec violation. With connection mode recvonly we should attempt to forward."
is_remote = memcmp(&addr.sin_addr, &endp->remote, sizeof(addr.sin_addr)) == 0;
if (is_remote) {
if (endp->rtp == addr.sin_port) {
return _send(fd->fd, &bts_in, endp->bts_rtp, buf, rc);
} else if (endp->rtcp == addr.sin_port) {
return _send(fd->fd, &bts_in, endp->bts_rtcp, buf, rc);
} else {
DEBUGP(DMGCP, "Unknown remote port. Not able to forward on 0x%x port: %d\n",
ENDPOINT_NUMBER(endp), ntohs(addr.sin_port));
}
return -1;
}
dest = memcmp(&addr.sin_addr, &endp->remote, sizeof(addr.sin_addr)) == 0
? DEST_BTS : DEST_NETWORK;
proto = fd == &endp->local_rtp ? PROTO_RTP : PROTO_RTCP;
/* We have no idea who called us, maybe it is the BTS. */
if (endp->bts_rtp == 0) {
if (dest == DEST_NETWORK && endp->bts_rtp == 0) {
/* it was the BTS... */
if (memcmp(&addr.sin_addr, &bts_in, sizeof(bts_in)) == 0) {
if (fd == &endp->local_rtp) {
@ -262,16 +263,18 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
}
}
if (endp->bts_rtp == 0 || endp->conn_mode == MGCP_CONN_RECV_ONLY) {
DEBUGP(DMGCP, "Not forwarding data from possible BTS conn: %d on 0x%x\n",
endp->conn_mode, ENDPOINT_NUMBER(endp));
return -1;
}
/* dispatch */
if (audio_loop)
dest = !dest;
if (fd == &endp->local_rtp) {
return _send(fd->fd, &endp->remote, endp->rtp, buf, rc);
if (dest == DEST_NETWORK) {
return _send(fd->fd, &endp->remote,
proto == PROTO_RTP ? endp->rtp : endp->rtcp,
buf, rc);
} else {
return _send(fd->fd, &endp->remote, endp->rtcp, buf, rc);
return _send(fd->fd, &bts_in,
proto == PROTO_RTP ? endp->bts_rtp : endp->bts_rtcp,
buf, rc);
}
}
@ -1007,6 +1010,15 @@ DEFUN(cfg_mgcp_sdp_payload_name,
return CMD_SUCCESS;
}
DEFUN(cfg_mgcp_loop,
cfg_mgcp_loop_cmd,
"loop (0|1)",
"Loop the audio")
{
audio_loop = atoi(argv[0]);
return CMD_SUCCESS;
}
static void mgcp_vty_init()
{
cmd_init(1);
@ -1023,6 +1035,7 @@ static void mgcp_vty_init()
install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_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_loop_cmd);
}
int main(int argc, char** argv)