aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-03-30 12:01:24 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-03-30 12:01:24 +0200
commit6b64b26d8b601f3f58ce151521d80c69cd4b217f (patch)
tree29d5f7528fd3f5d89afcf415b3935377bcb92f0d /openbsc
parent22252a98e3a2c094edb9d179db8eddede517e339 (diff)
nat: Look at the assignment command and remember on which timeslot the data is
This information will be needed when we are trying to forward MGCP connections to and from the BSC through the IPA protocol.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/bsc_nat.h10
-rw-r--r--openbsc/src/Makefile.am3
-rw-r--r--openbsc/src/nat/bsc_mgcp_utils.c66
-rw-r--r--openbsc/src/nat/bsc_nat.c12
-rw-r--r--openbsc/src/nat/bsc_nat_utils.c1
-rw-r--r--openbsc/tests/bsc-nat/Makefile.am1
-rw-r--r--openbsc/tests/bsc-nat/bsc_data.c7
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c38
8 files changed, 134 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index bdea43492..638791a8b 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -103,6 +103,10 @@ struct sccp_connections {
struct sccp_source_reference real_ref;
struct sccp_source_reference patched_ref;
struct sccp_source_reference remote_ref;
+
+ /* GSM audio handling. That is 32 * multiplex + ts */
+ int msc_timeslot;
+ int bsc_timeslot;
};
/**
@@ -162,4 +166,10 @@ void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bs
struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
+/**
+ * MGCP/Audio handling
+ */
+int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
+void bsc_mgcp_clear(struct sccp_connections *);
+
#endif
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index 615758bed..b552d2f83 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -53,5 +53,6 @@ bsc_mgcp_LDADD = libvty.a
ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c
bsc_nat_SOURCES = nat/bsc_nat.c nat/bsc_filter.c nat/bsc_sccp.c \
- nat/bsc_nat_utils.c nat/bsc_nat_vty.c bsc_msc.c bssap.c
+ nat/bsc_nat_utils.c nat/bsc_nat_vty.c nat/bsc_mgcp_utils.c \
+ bsc_msc.c bssap.c
bsc_nat_LDADD = libvty.a libbsc.a libsccp.a
diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c
new file mode 100644
index 000000000..55dad380a
--- /dev/null
+++ b/openbsc/src/nat/bsc_mgcp_utils.c
@@ -0,0 +1,66 @@
+/*
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <openbsc/bsc_nat.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/bssap.h>
+#include <openbsc/debug.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg)
+{
+ struct tlv_parsed tp;
+ u_int16_t cic;
+ u_int8_t timeslot;
+ u_int8_t multiplex;
+
+ if (!msg->l3h) {
+ LOGP(DNAT, LOGL_ERROR, "Assignment message should have l3h pointer.\n");
+ return -1;
+ }
+
+ if (msgb_l3len(msg) < 3) {
+ LOGP(DNAT, LOGL_ERROR, "Assignment message has not enough space for GSM0808.\n");
+ return -1;
+ }
+
+ tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 3, msgb_l3len(msg) - 3, 0, 0);
+ if (!TLVP_PRESENT(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) {
+ LOGP(DNAT, LOGL_ERROR, "Circuit identity code not found in assignment message.\n");
+ return -1;
+ }
+
+ cic = ntohs(*(u_int16_t *)TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE));
+ timeslot = cic & 0x1f;
+ multiplex = (cic & ~0x1f) >> 5;
+
+ con->msc_timeslot = (32 * multiplex) + timeslot;
+ con->bsc_timeslot = con->msc_timeslot;
+ return 0;
+}
+
+void bsc_mgcp_clear(struct sccp_connections *con)
+{
+ con->msc_timeslot = -1;
+ con->bsc_timeslot = -1;
+}
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index 4ad6b1abf..4a25dc39c 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -193,6 +193,13 @@ static int forward_sccp_to_bts(struct msgb *msg)
case SCCP_MSG_TYPE_CREF:
case SCCP_MSG_TYPE_DT1:
con = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
+ if (parsed->gsm_type == BSS_MAP_MSG_ASSIGMENT_RQST) {
+ if (con) {
+ if (bsc_mgcp_assign(con, msg) != 0)
+ LOGP(DNAT, LOGL_ERROR, "Failed to assign...\n");
+ } else
+ LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n");
+ }
break;
case SCCP_MSG_TYPE_CC:
con = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
@@ -401,7 +408,10 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg)
break;
case SCCP_MSG_TYPE_RLC:
con = patch_sccp_src_ref_to_msc(msg, parsed, nat);
- remove_sccp_src_ref(bsc, msg, parsed);
+ if (con) {
+ remove_sccp_src_ref(bsc, msg, parsed);
+ bsc_mgcp_clear(con);
+ }
break;
case SCCP_MSG_TYPE_UDT:
/* simply forward everything */
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index 08e9e8f8b..dc6cfec5c 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -79,6 +79,7 @@ void sccp_connection_destroy(struct sccp_connections *conn)
LOGP(DNAT, LOGL_DEBUG, "Destroy 0x%x <-> 0x%x mapping for con %p\n",
sccp_src_ref_to_int(&conn->real_ref),
sccp_src_ref_to_int(&conn->patched_ref), conn->bsc);
+ bsc_mgcp_clear(conn);
llist_del(&conn->list_entry);
talloc_free(conn);
}
diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am
index 7011fbd45..80fb0046c 100644
--- a/openbsc/tests/bsc-nat/Makefile.am
+++ b/openbsc/tests/bsc-nat/Makefile.am
@@ -9,6 +9,7 @@ bsc_nat_test_SOURCES = bsc_nat_test.c \
$(top_srcdir)/src/nat/bsc_filter.c \
$(top_srcdir)/src/nat/bsc_sccp.c \
$(top_srcdir)/src/nat/bsc_nat_utils.c \
+ $(top_srcdir)/src/nat/bsc_mgcp_utils.c \
$(top_srcdir)/src/bssap.c
bsc_nat_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libsccp.a $(LIBOSMOCORE_LIBS)
diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c
index b73aff118..ca170e2ac 100644
--- a/openbsc/tests/bsc-nat/bsc_data.c
+++ b/openbsc/tests/bsc-nat/bsc_data.c
@@ -80,3 +80,10 @@ static const u_int8_t paging_by_lac_cmd[] = {
0x10, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10, 0x02,
0x01, 0x50, 0x02, 0x30, 0x1a, 0x03, 0x05, 0x20,
0x15 };
+
+/* an assignment command */
+static const u_int8_t ass_cmd[] = {
+0x00, 0x12, 0xfd, 0x06,
+0x00, 0x00, 0x49, 0x00, 0x01, 0x0b, 0x00, 0x09,
+0x01, 0x0b, 0x03, 0x01, 0x0a, 0x11, 0x01, 0x00,
+0x15 };
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 3a1096001..70e98d721 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -335,6 +335,41 @@ static void test_paging(void)
talloc_free(parsed);
}
+static void test_mgcp(void)
+{
+ struct sccp_connections con;
+ struct bsc_nat_parsed *parsed;
+ struct msgb *msg;
+
+ fprintf(stderr, "Testing MGCP.\n");
+ memset(&con, 0, sizeof(con));
+
+ msg = msgb_alloc(4096, "foo");
+ copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
+ parsed = bsc_nat_parse(msg);
+ if (bsc_mgcp_assign(&con, msg) != 0) {
+ fprintf(stderr, "Failed to handle assignment.\n");
+ abort();
+ }
+
+ if (con.msc_timeslot != 21) {
+ fprintf(stderr, "Timeslot should be 21.\n");
+ abort();
+ }
+
+ if (con.bsc_timeslot != 21) {
+ fprintf(stderr, "Assigned timeslot should have been 21.\n");
+ abort();
+ }
+ talloc_free(parsed);
+
+ bsc_mgcp_clear(&con);
+ if (con.bsc_timeslot != -1 || con.msc_timeslot != -1) {
+ fprintf(stderr, "Clearing should remove the mapping.\n");
+ abort();
+ }
+}
+
int main(int argc, char **argv)
{
struct debug_target *stderr_target;
@@ -345,9 +380,8 @@ int main(int argc, char **argv)
test_filter();
test_contrack();
-
- debug_set_log_level(stderr_target, 1);
test_paging();
+ test_mgcp();
return 0;
}