aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-01-05 12:21:36 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-01-05 12:21:36 +0100
commitd1a2563a749d2e25b94b73b8af8c36172c008f3d (patch)
tree5b33daa2baea050b584cdc58616d9e91ed4e0957
parent7d3ef919cef8837bd31bc2e0716b9f4142630c53 (diff)
[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.
-rw-r--r--openbsc/src/bsc_mgcp.c86
1 files changed, 61 insertions, 25 deletions
diff --git a/openbsc/src/bsc_mgcp.c b/openbsc/src/bsc_mgcp.c
index 045dff29..9daad7ab 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 */