aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-03-31 07:30:58 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-03-31 07:30:58 +0200
commit538ea6d5c64cb048ba10bf7ec7e6dae6385ce142 (patch)
tree613f9b41392a673007aec0225724035b5dda8e01
parente14ec0dab48029bb4746b6c49d22a0ee6fa6b47c (diff)
[nat] Send a RSIP down to the BSC after it connects
Make sure the MGCP attached to the BSC is resetting all endpoints whenever the BSC is connecting to us as we assume that all endpoints are available.
-rw-r--r--openbsc/include/openbsc/bsc_nat.h3
-rw-r--r--openbsc/src/nat/bsc_nat.c41
2 files changed, 43 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index ab80cb401..835a2ae88 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -35,7 +35,7 @@
#define DIR_BSC 1
#define DIR_MSC 2
-#define NAT_IPAC_PROTO_MGCP
+#define NAT_IPAC_PROTO_MGCP 0xfc
struct bsc_nat;
@@ -176,6 +176,7 @@ struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat
/**
* MGCP/Audio handling
*/
+int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
void bsc_mgcp_clear(struct sccp_connections *);
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index 744a30e6b..4cc6549eb 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -127,6 +127,15 @@ static void send_id_req(struct bsc_connection *bsc)
bsc_write(bsc, id_req, sizeof(id_req));
}
+static void send_mgcp_reset(struct bsc_connection *bsc)
+{
+ static const u_int8_t mgcp_reset[] = {
+ "RSIP 1 13@mgw MGCP 1.0\r\n"
+ };
+
+ bsc_write_mgcp(bsc, mgcp_reset, sizeof mgcp_reset - 1);
+}
+
/*
* Below is the handling of messages coming
* from the MSC and need to be forwarded to
@@ -166,6 +175,37 @@ static void bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned
}
}
+int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length)
+{
+ struct msgb *msg;
+
+ if (length > 4096 - 128) {
+ LOGP(DINP, LOGL_ERROR, "Can not send message of that size.\n");
+ return -1;
+ }
+
+ msg = msgb_alloc_headroom(4096, 128, "to-bsc");
+ if (!msg) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate memory for BSC msg.\n");
+ return -1;
+ }
+
+ /* copy the data */
+ msg->l3h = msgb_put(msg, length);
+ memcpy(msg->l3h, data, length);
+
+ /* prepend the header */
+ ipaccess_prepend_header(msg, NAT_IPAC_PROTO_MGCP);
+
+ if (write_queue_enqueue(&bsc->write_queue, msg) != 0) {
+ LOGP(DINP, LOGL_ERROR, "Failed to enqueue the write.\n");
+ msgb_free(msg);
+ return -1;
+ }
+
+ return 0;
+}
+
static int forward_sccp_to_bts(struct msgb *msg)
{
struct sccp_connections *con;
@@ -558,6 +598,7 @@ static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
llist_add(&bsc->list_entry, &nat->bsc_connections);
send_id_ack(bsc);
send_id_req(bsc);
+ send_mgcp_reset(bsc);
/*
* start the hangup timer