aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-04-07 22:54:07 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-04-07 22:54:07 +0200
commit91b5a31a2ce73b988fa1c7f28e3a2cc2c8b77b90 (patch)
tree794f00fa8e4afc237af410733f15dee769399b01
parent54fa7991295d64a01a39f7863f585ff8ab08ed13 (diff)
parent575b89585f7fa7cb4104eeb9f853561af16603d3 (diff)
Merge branch 'on-waves/mgcp'
-rwxr-xr-xopenbsc/contrib/mgcp_server.py30
-rw-r--r--openbsc/include/openbsc/mgcp.h15
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h13
-rw-r--r--openbsc/src/mgcp/mgcp_main.c60
-rw-r--r--openbsc/src/mgcp/mgcp_network.c22
-rw-r--r--openbsc/src/mgcp/mgcp_protocol.c85
-rw-r--r--openbsc/src/mgcp/mgcp_vty.c35
7 files changed, 166 insertions, 94 deletions
diff --git a/openbsc/contrib/mgcp_server.py b/openbsc/contrib/mgcp_server.py
index cf3ef3845..05c489db5 100755
--- a/openbsc/contrib/mgcp_server.py
+++ b/openbsc/contrib/mgcp_server.py
@@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n"""
audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
-mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 4400 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
+mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
def hexdump(src, length=8):
"""Recipe is from http://code.activestate.com/recipes/142812/"""
@@ -25,15 +25,24 @@ def hexdump(src, length=8):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
-server_socket.setblocking(0)
+server_socket.setblocking(1)
-
-def send_receive(packet):
+last_ci = 1
+def send_and_receive(packet):
+ global last_ci
server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
try:
data, addr = server_socket.recvfrom(4096)
+
+ # attempt to store the CI of the response
+ list = data.split("\n")
+ for item in list:
+ if item.startswith("I: "):
+ last_ci = int(item[3:])
+
print hexdump(data), addr
- except socket.error:
+ except socket.error, e:
+ print e
pass
def generate_tid():
@@ -42,13 +51,10 @@ def generate_tid():
-i = 1
while True:
- send_receive(rsip_resp)
- send_receive(audit_packet)
- send_receive(crcx_packet % generate_tid() )
- send_receive(mdcx_packet % (generate_tid(), i))
- send_receive(dlcx_packet % (generate_tid(), i))
- i = i + 1
+ send_and_receive(audit_packet % generate_tid())
+ send_and_receive(crcx_packet % generate_tid() )
+ send_and_receive(mdcx_packet % (generate_tid(), last_ci))
+ send_and_receive(dlcx_packet % (generate_tid(), last_ci))
time.sleep(3)
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index f7e800bd8..71b7fc14e 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -77,6 +77,7 @@ struct mgcp_config;
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
+typedef int (*mgcp_reset)(struct mgcp_config *cfg);
struct mgcp_config {
int source_port;
@@ -84,6 +85,7 @@ struct mgcp_config {
char *source_addr;
unsigned int number_endpoints;
char *bts_ip;
+ char *call_agent_addr;
struct in_addr bts_in;
char *audio_name;
@@ -95,8 +97,12 @@ struct mgcp_config {
char *forward_ip;
int forward_port;
+ /* spec handling */
+ int force_realloc;
+
mgcp_change change_cb;
mgcp_policy policy_cb;
+ mgcp_reset reset_cb;
void *data;
struct mgcp_endpoint *endpoints;
@@ -115,8 +121,15 @@ void mgcp_free_endp(struct mgcp_endpoint *endp);
* format helper functions
*/
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
-struct msgb *mgcp_create_rsip(void);
struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data);
+/* adc helper */
+static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
+{
+ if (timeslot == 0)
+ timeslot = 1;
+ return timeslot + (31 * multiplex);
+}
+
#endif
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 10d0ca6ae..3a2832436 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -57,8 +57,21 @@ struct mgcp_endpoint {
/* backpointer */
struct mgcp_config *cfg;
+
+ /* statistics */
+ unsigned int in_bts;
+ unsigned int in_remote;
};
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
+struct mgcp_msg_ptr {
+ unsigned int start;
+ unsigned int length;
+};
+
+int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
+ struct mgcp_msg_ptr *ptr, int size,
+ const char **transaction_id, struct mgcp_endpoint **endp);
+
#endif
diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c
index 147a765f0..5e337e902 100644
--- a/openbsc/src/mgcp/mgcp_main.c
+++ b/openbsc/src/mgcp/mgcp_main.c
@@ -38,8 +38,11 @@
#include <openbsc/gsm_data.h>
#include <osmocore/select.h>
#include <openbsc/mgcp.h>
+#include <openbsc/mgcp_internal.h>
#include <openbsc/telnet_interface.h>
+#include <vty/command.h>
+
#include "../../bscconfig.h"
/* this is here for the vty... it will never be called */
@@ -51,8 +54,9 @@ void subscr_put() { abort(); }
#warning "Make use of the rtp proxy code"
static struct bsc_fd bfd;
-static int first_request = 1;
static struct mgcp_config *cfg;
+static int reset_endpoints = 0;
+
const char *openbsc_version = "OpenBSC MGCP " PACKAGE_VERSION;
const char *openbsc_copyright =
"Copyright (C) 2009-2010 Holger Freyther and On-Waves\n"
@@ -74,10 +78,10 @@ static void print_help()
printf(" -c --config-file filename The config file to use.\n");
}
-static void print_version()
+static void print_mgcp_version()
{
printf("%s\n\n", openbsc_version);
- printf(openbsc_copyright);
+ printf("%s", openbsc_copyright);
}
static void handle_options(int argc, char** argv)
@@ -105,7 +109,7 @@ static void handle_options(int argc, char** argv)
config_file = talloc_strdup(tall_bsc_ctx, optarg);
break;
case 'V':
- print_version();
+ print_mgcp_version();
exit(0);
break;
default:
@@ -115,12 +119,21 @@ static void handle_options(int argc, char** argv)
}
}
+/* simply remember this */
+static int mgcp_rsip_cb(struct mgcp_config *cfg)
+{
+ reset_endpoints = 1;
+
+ return 0;
+}
+
static int read_call_agent(struct bsc_fd *fd, unsigned int what)
{
struct sockaddr_in addr;
socklen_t slen = sizeof(addr);
struct msgb *msg;
struct msgb *resp;
+ int i;
msg = (struct msgb *) fd->data;
@@ -136,18 +149,6 @@ static int read_call_agent(struct bsc_fd *fd, unsigned int what)
return -1;
}
- if (first_request) {
- first_request = 0;
- resp = mgcp_create_rsip();
-
- if (resp) {
- sendto(bfd.fd, resp->l2h, msgb_l2len(resp), 0,
- (struct sockaddr *) &addr, sizeof(addr));
- msgb_free(resp);
- }
- return 0;
- }
-
/* handle message now */
msg->l2h = msgb_put(msg, rc);
resp = mgcp_handle_message(cfg, msg);
@@ -157,6 +158,16 @@ static int read_call_agent(struct bsc_fd *fd, unsigned int what)
sendto(bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr));
msgb_free(resp);
}
+
+ if (reset_endpoints) {
+ LOGP(DMGCP, LOGL_NOTICE, "Asked to reset endpoints.\n");
+ reset_endpoints = 0;
+
+ /* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */
+ for (i = 1; i < cfg->number_endpoints; ++i)
+ mgcp_free_endp(&cfg->endpoints[i]);
+ }
+
return 0;
}
@@ -186,6 +197,8 @@ int main(int argc, char** argv)
if (rc < 0)
return rc;
+ /* set some callbacks */
+ cfg->reset_cb = mgcp_rsip_cb;
/* we need to bind a socket */
if (rc == 0) {
@@ -217,11 +230,11 @@ int main(int argc, char** argv)
if (bsc_register_fd(&bfd) != 0) {
- DEBUGP(DMGCP, "Failed to register the fd\n");
+ LOGP(DMGCP, LOGL_FATAL, "Failed to register the fd\n");
return -1;
}
- DEBUGP(DMGCP, "Configured for MGCP.\n");
+ LOGP(DMGCP, LOGL_NOTICE, "Configured for MGCP.\n");
}
/* initialisation */
@@ -235,3 +248,14 @@ int main(int argc, char** argv)
return 0;
}
+
+struct gsm_network;
+int bsc_vty_init(struct gsm_network *dummy)
+{
+ cmd_init(1);
+ vty_init();
+
+ mgcp_vty_init();
+ return 0;
+}
+
diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c
index b76ca4732..cd10d2a8c 100644
--- a/openbsc/src/mgcp/mgcp_network.c
+++ b/openbsc/src/mgcp/mgcp_network.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>
#include <endian.h>
+#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -90,6 +91,9 @@ static void patch_payload(int payload, char *data, int len)
if (len < sizeof(*rtp_hdr))
return;
+ if (payload < 0)
+ return;
+
rtp_hdr = (struct rtp_hdr *) data;
rtp_hdr->payload_type = payload;
}
@@ -119,16 +123,14 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
rc = recvfrom(fd->fd, &buf, sizeof(buf), 0,
(struct sockaddr *) &addr, &slen);
if (rc < 0) {
- LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x\n",
- ENDPOINT_NUMBER(endp));
+ LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x errno: %d/%s\n",
+ ENDPOINT_NUMBER(endp), errno, strerror(errno));
return -1;
}
/* do not forward aynthing... maybe there is a packet from the bts */
- if (endp->ci == CI_UNUSED) {
- LOGP(DMGCP, LOGL_ERROR, "Unknown message on endpoint: 0x%x\n", ENDPOINT_NUMBER(endp));
+ if (endp->ci == CI_UNUSED)
return -1;
- }
/*
* Figure out where to forward it to. This code assumes that we
@@ -146,7 +148,9 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
/* We have no idea who called us, maybe it is the BTS. */
if (dest == DEST_NETWORK && (endp->bts_rtp == 0 || cfg->forward_ip)) {
/* it was the BTS... */
- if (!cfg->bts_ip || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0) {
+ if (!cfg->bts_ip
+ || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0
+ || memcmp(&addr.sin_addr, &endp->bts, sizeof(endp->bts)) == 0) {
if (fd == &endp->local_rtp) {
endp->bts_rtp = addr.sin_port;
} else {
@@ -159,6 +163,12 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
}
}
+ /* do this before the loop handling */
+ if (dest == DEST_NETWORK)
+ ++endp->in_bts;
+ else
+ ++endp->in_remote;
+
/* dispatch */
if (cfg->audio_loop)
dest = !dest;
diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c
index f7ef5470d..76eb7c2a0 100644
--- a/openbsc/src/mgcp/mgcp_protocol.c
+++ b/openbsc/src/mgcp/mgcp_protocol.c
@@ -80,11 +80,6 @@ enum mgcp_connection_mode {
}
-struct mgcp_msg_ptr {
- unsigned int start;
- unsigned int length;
-};
-
struct mgcp_request {
char *name;
struct msgb *(*handle_request) (struct mgcp_config *cfg, struct msgb *msg);
@@ -98,6 +93,7 @@ static struct msgb *handle_audit_endpoint(struct mgcp_config *cfg, struct msgb *
static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg);
static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg);
static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg);
+static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg);
static int generate_call_id(struct mgcp_config *cfg)
{
@@ -119,12 +115,6 @@ static int generate_call_id(struct mgcp_config *cfg)
return cfg->last_call_id;
}
-/* FIXIME/TODO: need to have a list of pending transactions and check that */
-static unsigned int generate_transaction_id()
-{
- return abs(rand());
-}
-
/*
* array of function pointers for handling various
* messages. In the future this might be binary sorted
@@ -135,6 +125,9 @@ static const struct mgcp_request mgcp_requests [] = {
MGCP_REQUEST("CRCX", handle_create_con, "CreateConnection")
MGCP_REQUEST("DLCX", handle_delete_con, "DeleteConnection")
MGCP_REQUEST("MDCX", handle_modify_con, "ModifiyConnection")
+
+ /* SPEC extension */
+ MGCP_REQUEST("RSIP", handle_rsip, "ReSetInProgress")
};
static struct msgb *mgcp_msgb_alloc(void)
@@ -194,23 +187,6 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
return mgcp_create_response_with_data(200, msg, trans_id, sdp_record);
}
-/* send a static record */
-struct msgb *mgcp_create_rsip(void)
-{
- struct msgb *msg;
- int len;
-
- msg = mgcp_msgb_alloc();
- if (!msg)
- return NULL;
-
- len = snprintf((char *) msg->data, 2048,
- "RSIP %u *@mgw MGCP 1.0\n"
- "RM: restart\n", generate_transaction_id());
- msg->l2h = msgb_put(msg, len);
- return msg;
-}
-
/*
* handle incoming messages:
* - this can be a command (four letters, space, transaction id)
@@ -221,25 +197,25 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg)
int code;
struct msgb *resp = NULL;
- if (msg->len < 4) {
+ if (msgb_l2len(msg) < 4) {
LOGP(DMGCP, LOGL_ERROR, "mgs too short: %d\n", msg->len);
return NULL;
}
/* attempt to treat it as a response */
- if (sscanf((const char *)&msg->data[0], "%3d %*s", &code) == 1) {
+ if (sscanf((const char *)&msg->l2h[0], "%3d %*s", &code) == 1) {
LOGP(DMGCP, LOGL_DEBUG, "Response: Code: %d\n", code);
} else {
int i, handled = 0;
msg->l3h = &msg->l2h[4];
for (i = 0; i < ARRAY_SIZE(mgcp_requests); ++i)
- if (strncmp(mgcp_requests[i].name, (const char *) &msg->data[0], 4) == 0) {
+ if (strncmp(mgcp_requests[i].name, (const char *) &msg->l2h[0], 4) == 0) {
handled = 1;
resp = mgcp_requests[i].handle_request(cfg, msg);
break;
}
if (!handled) {
- LOGP(DMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n", &msg->data[0]);
+ LOGP(DMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n", &msg->l2h[0]);
}
}
@@ -296,9 +272,9 @@ static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *
return &cfg->endpoints[gw];
}
-static int analyze_header(struct mgcp_config *cfg, struct msgb *msg,
- struct mgcp_msg_ptr *ptr, int size,
- const char **transaction_id, struct mgcp_endpoint **endp)
+int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
+ struct mgcp_msg_ptr *ptr, int size,
+ const char **transaction_id, struct mgcp_endpoint **endp)
{
int found;
@@ -334,8 +310,11 @@ static int analyze_header(struct mgcp_config *cfg, struct msgb *msg,
}
*transaction_id = (const char *)&msg->l3h[ptr[0].start];
- *endp = find_endpoint(cfg, (const char *)&msg->l3h[ptr[1].start]);
- return *endp == NULL;
+ if (endp) {
+ *endp = find_endpoint(cfg, (const char *)&msg->l3h[ptr[1].start]);
+ return *endp == NULL;
+ }
+ return 0;
}
static int verify_call_id(const struct mgcp_endpoint *endp,
@@ -369,7 +348,7 @@ static struct msgb *handle_audit_endpoint(struct mgcp_config *cfg, struct msgb *
const char *trans_id;
struct mgcp_endpoint *endp;
- found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
+ found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
response = 500;
else
@@ -402,13 +381,19 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
int error_code = 500;
int port;
- found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
+ found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
return create_response(500, "CRCX", trans_id);
if (endp->ci != CI_UNUSED) {
- LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n", ENDPOINT_NUMBER(endp));
- return create_response(500, "CRCX", trans_id);
+ if (cfg->force_realloc) {
+ LOGP(DMGCP, LOGL_NOTICE, "Endpoint 0x%x already allocated. Forcing realloc.\n",
+ ENDPOINT_NUMBER(endp));
+ } else {
+ LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n",
+ ENDPOINT_NUMBER(endp));
+ return create_response(500, "CRCX", trans_id);
+ }
}
/* parse CallID C: and LocalParameters L: */
@@ -501,7 +486,7 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
struct mgcp_endpoint *endp;
int error_code = 500;
- found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
+ found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
return create_response(error_code, "MDCX", trans_id);
@@ -614,7 +599,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
struct mgcp_endpoint *endp;
int error_code = 500;
- found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
+ found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
return create_response(error_code, "DLCX", trans_id);
@@ -678,6 +663,13 @@ error3:
return create_response(error_code, "DLCX", trans_id);
}
+static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg)
+{
+ if (cfg->reset_cb)
+ cfg->reset_cb(cfg);
+ return NULL;
+}
+
struct mgcp_config *mgcp_config_alloc(void)
{
struct mgcp_config *cfg;
@@ -722,7 +714,7 @@ int mgcp_endpoints_allocate(struct mgcp_config *cfg)
void mgcp_free_endp(struct mgcp_endpoint *endp)
{
- LOGP(DMGCP, LOGL_NOTICE, "Deleting endpoint on: 0x%x\n", ENDPOINT_NUMBER(endp));
+ LOGP(DMGCP, LOGL_DEBUG, "Deleting endpoint on: 0x%x\n", ENDPOINT_NUMBER(endp));
endp->ci= CI_UNUSED;
if (endp->callid) {
@@ -732,7 +724,7 @@ void mgcp_free_endp(struct mgcp_endpoint *endp)
if (endp->local_options) {
talloc_free(endp->local_options);
- endp->callid = NULL;
+ endp->local_options = NULL;
}
if (!endp->cfg->early_bind) {
@@ -742,4 +734,7 @@ void mgcp_free_endp(struct mgcp_endpoint *endp)
endp->net_rtp = endp->net_rtcp = endp->bts_rtp = endp->bts_rtcp = 0;
endp->net_payload_type = endp->bts_payload_type = -1;
+ endp->in_bts = endp->in_remote = 0;
+ memset(&endp->remote, 0, sizeof(endp->remote));
+ memset(&endp->bts, 0, sizeof(endp->bts));
}
diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c
index f13b3cfa7..af762c57e 100644
--- a/openbsc/src/mgcp/mgcp_vty.c
+++ b/openbsc/src/mgcp/mgcp_vty.c
@@ -63,6 +63,8 @@ static int config_write_mgcp(struct vty *vty)
vty_out(vty, " forward audio ip %s%s", g_cfg->forward_ip, VTY_NEWLINE);
if (g_cfg->forward_port != 0)
vty_out(vty, " forward audio port %d%s", g_cfg->forward_port, VTY_NEWLINE);
+ if (g_cfg->call_agent_addr)
+ vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -75,10 +77,12 @@ DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
vty_out(vty, "MGCP is up and running with %u endpoints:%s", g_cfg->number_endpoints - 1, VTY_NEWLINE);
for (i = 1; i < g_cfg->number_endpoints; ++i) {
struct mgcp_endpoint *endp = &g_cfg->endpoints[i];
- vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u%s",
+ vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic in :%u/%u%s",
i, endp->ci,
ntohs(endp->net_rtp), ntohs(endp->net_rtcp),
- ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), VTY_NEWLINE);
+ ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp),
+ inet_ntoa(endp->bts), endp->in_bts, endp->in_remote,
+ VTY_NEWLINE);
}
return CMD_SUCCESS;
@@ -237,6 +241,17 @@ DEFUN(cfg_mgcp_forward_port,
return CMD_SUCCESS;
}
+DEFUN(cfg_mgcp_agent_addr,
+ cfg_mgcp_agent_addr_cmd,
+ "call agent ip IP",
+ "Set the address of the call agent.")
+{
+ if (g_cfg->call_agent_addr)
+ talloc_free(g_cfg->call_agent_addr);
+ g_cfg->call_agent_addr = talloc_strdup(g_cfg, argv[0]);
+ return CMD_SUCCESS;
+}
+
int mgcp_vty_init(void)
{
install_element(VIEW_NODE, &show_mgcp_cmd);
@@ -256,6 +271,7 @@ int mgcp_vty_init(void)
install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
install_element(MGCP_NODE, &cfg_mgcp_forward_ip_cmd);
install_element(MGCP_NODE, &cfg_mgcp_forward_port_cmd);
+ install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd);
return 0;
}
@@ -274,6 +290,11 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
if (!g_cfg->bts_ip)
fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n");
+ if (!g_cfg->source_addr) {
+ fprintf(stderr, "You need to specify a bind address.\n");
+ return -1;
+ }
+
if (mgcp_endpoints_allocate(g_cfg) != 0) {
fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n", g_cfg->number_endpoints);
return -1;
@@ -327,13 +348,3 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
return !!g_cfg->forward_ip;
}
-struct gsm_network;
-int bsc_vty_init(struct gsm_network *dummy)
-{
- cmd_init(1);
- vty_init();
-
- mgcp_vty_init();
- return 0;
-}
-