aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-11-10 10:17:05 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-11-15 20:06:50 +0100
commitdbc698aef010abfb8efc4be310a6f9fe043cdb5a (patch)
treed247eb546b2274a76d3008a11a42cc825c179cc5 /openbsc
parent50c579b8c5de7ce9d0c88e3d4f608f4051184470 (diff)
bsc: Implement DTAP coming from the MSC and forward to the BSC API
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/src/bsc/osmo_bsc_bssap.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/openbsc/src/bsc/osmo_bsc_bssap.c b/openbsc/src/bsc/osmo_bsc_bssap.c
index 97ce68a07..c6bf4f4dd 100644
--- a/openbsc/src/bsc/osmo_bsc_bssap.c
+++ b/openbsc/src/bsc/osmo_bsc_bssap.c
@@ -444,7 +444,44 @@ static int bssmap_rcvmsg_dt1(struct osmo_bsc_sccp_con *conn,
static int dtap_rcvmsg(struct osmo_bsc_sccp_con *conn,
struct msgb *msg, unsigned int length)
{
- return -1;
+ struct dtap_header *header;
+ struct msgb *gsm48;
+ uint8_t *data;
+
+ if (!conn->conn) {
+ LOGP(DMSC, LOGL_ERROR, "No subscriber connection available\n");
+ return -1;
+ }
+
+ header = (struct dtap_header *) msg->l3h;
+ if (sizeof(*header) >= length) {
+ LOGP(DMSC, LOGL_ERROR, "The DTAP header does not fit. Wanted: %u got: %u\n", sizeof(*header), length);
+ LOGP(DMSC, LOGL_ERROR, "hex: %s\n", hexdump(msg->l3h, length));
+ return -1;
+ }
+
+ if (header->length > length - sizeof(*header)) {
+ LOGP(DMSC, LOGL_ERROR, "The DTAP l4 information does not fit: header: %u length: %u\n", header->length, length);
+ LOGP(DMSC, LOGL_ERROR, "hex: %s\n", hexdump(msg->l3h, length));
+ return -1;
+ }
+
+ LOGP(DMSC, LOGL_DEBUG, "DTAP message: SAPI: %u CHAN: %u\n", header->link_id & 0x07, header->link_id & 0xC0);
+
+ /* forward the data */
+ gsm48 = gsm48_msgb_alloc();
+ if (!gsm48) {
+ LOGP(DMSC, LOGL_ERROR, "Allocation of the message failed.\n");
+ return -1;
+ }
+
+ gsm48->l3h = gsm48->data;
+ data = msgb_put(gsm48, length - sizeof(*header));
+ memcpy(data, msg->l3h + sizeof(*header), length - sizeof(*header));
+
+ /* pass it to the filter for extra actions */
+ bsc_scan_msc_msg(conn->conn, gsm48);
+ return gsm0808_submit_dtap(conn->conn, gsm48, header->link_id, 1);
}
int bsc_handle_udt(struct gsm_network *network,