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.
diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c
new file mode 100644
index 0000000..55dad38
--- /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 c7c6c41..1568230 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -193,6 +193,13 @@
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 @@
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 3e44193..f1bb4b5 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -79,6 +79,7 @@
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);
}