From d1a2563a749d2e25b94b73b8af8c36172c008f3d Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 5 Jan 2010 12:21:36 +0100 Subject: [bsc_mgcp] Add a new forward only mode to the bsc_mgcp With forward IP in the config and early bind on we will simply forward RTP data on the endpoints from BTS to the forward IP address. This is implemented by disabling MGCP functionality when a forward IP address was specified, setting the forward IP in the endp->remote and assigning a ci != CI_UNUSED. Early bind will make sure the sockets are created, the BSC FD's are registered and then the normal dispatch code will do the forwarding. --- openbsc/src/bsc_mgcp.c | 86 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/openbsc/src/bsc_mgcp.c b/openbsc/src/bsc_mgcp.c index 045dff29c..9daad7ab4 100644 --- a/openbsc/src/bsc_mgcp.c +++ b/openbsc/src/bsc_mgcp.c @@ -65,6 +65,7 @@ static int audio_loop = 0; static int early_bind = 0; static int rtp_base_port = 0; +static char *forward_ip = NULL; static char *config_file = "mgcp.cfg"; /* used by msgb and mgcp */ @@ -1056,6 +1057,17 @@ DEFUN(cfg_mgcp_number_endp, return CMD_SUCCESS; } +DEFUN(cfg_mgcp_forward, + cfg_mgcp_forward_cmd, + "forward audio IP", + "Forward packets from and to the IP. This disables most of the MGCP feature.") +{ + if (forward_ip) + talloc_free(forward_ip); + forward_ip = talloc_strdup(tall_bsc_ctx, argv[0]); + return CMD_SUCCESS; +} + int bsc_vty_init(struct gsm_network *dummy) { cmd_init(1); @@ -1077,6 +1089,7 @@ int bsc_vty_init(struct gsm_network *dummy) install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd); install_element(MGCP_NODE, &cfg_mgcp_loop_cmd); install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd); + install_element(MGCP_NODE, &cfg_mgcp_forward_cmd); return 0; } @@ -1117,37 +1130,60 @@ int main(int argc, char** argv) endpoints[i].ci = CI_UNUSED; } - /* initialize the socket */ - bfd.when = BSC_FD_READ; - bfd.cb = read_call_agent; - bfd.fd = socket(AF_INET, SOCK_DGRAM, 0); - if (bfd.fd < 0) { - perror("Gateway failed to listen"); - return -1; - } + /* + * This application supports two modes. + * 1.) a true MGCP gateway with support for AUEP, CRCX, MDCX, DLCX + * 2.) plain forwarding of RTP packets on the endpoints. + * both modes are mutual exclusive + */ + if (forward_ip) { - setsockopt(bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (!early_bind) { + DEBUGP(DMGCP, "Forwarding requires early bind.\n"); + return -1; + } - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(source_port); - inet_aton(source_addr, &addr.sin_addr); + /* + * Store the forward IP and assign a ci. For early bind + * the sockets will be created after this. + */ + for (i = 1; i < number_endpoints; ++i) { + struct mgcp_endpoint *endp = &endpoints[i]; + inet_aton(forward_ip, &endp->remote); + endp->ci = CI_UNUSED + 23; + } + } else { + bfd.when = BSC_FD_READ; + bfd.cb = read_call_agent; + bfd.fd = socket(AF_INET, SOCK_DGRAM, 0); + if (bfd.fd < 0) { + perror("Gateway failed to listen"); + return -1; + } - if (bind(bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Gateway failed to bind"); - return -1; - } + setsockopt(bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - bfd.data = msgb_alloc(4096, "mgcp-msg"); - if (!bfd.data) { - fprintf(stderr, "Gateway memory error.\n"); - return -1; - } + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(source_port); + inet_aton(source_addr, &addr.sin_addr); + if (bind(bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Gateway failed to bind"); + return -1; + } - if (bsc_register_fd(&bfd) != 0) { - DEBUGP(DMGCP, "Failed to register the fd\n"); - return -1; + bfd.data = msgb_alloc(4096, "mgcp-msg"); + if (!bfd.data) { + fprintf(stderr, "Gateway memory error.\n"); + return -1; + } + + + if (bsc_register_fd(&bfd) != 0) { + DEBUGP(DMGCP, "Failed to register the fd\n"); + return -1; + } } /* initialisation */ -- cgit v1.2.3