Merge remote branch 'origin/on-waves/sccp'
diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c
index 9cd7c9c..b1da2c7 100644
--- a/openbsc/src/sccp/sccp.c
+++ b/openbsc/src/sccp/sccp.c
@@ -471,6 +471,25 @@
 	return 0;
 }
 
+static int _sccp_parse_it(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static const u_int32_t header_size = sizeof(struct sccp_data_it);
+
+	struct sccp_data_it *it;
+
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	it = (struct sccp_data_it *) msgb->l2h;
+	result->data_len = 0;
+	result->source_local_reference = &it->source_local_reference;
+	result->destination_local_reference = &it->destination_local_reference;
+	return 0;
+}
+
 
 /*
  * Send UDT. Currently we have a fixed address...
@@ -1307,8 +1326,12 @@
 	case SCCP_MSG_TYPE_UDT:
 		return _sccp_parse_udt(msg, result);
 		break;
+	case SCCP_MSG_TYPE_IT:
+		return _sccp_parse_it(msg, result);
+		break;
 	};
 
+	LOGP(DSCCP, LOGL_ERROR, "Unimplemented MSG Type: 0x%x\n", type);
 	return -1;
 }
 
diff --git a/openbsc/tests/sccp/sccp_test.c b/openbsc/tests/sccp/sccp_test.c
index 982c168..eb41d3e 100644
--- a/openbsc/tests/sccp/sccp_test.c
+++ b/openbsc/tests/sccp/sccp_test.c
@@ -244,6 +244,52 @@
 	},
 };
 
+struct sccp_parse_header_result {
+	/* results */
+	int msg_type;
+	int wanted_len;
+	int src_ssn;
+	int dst_ssn;
+
+	int has_src_ref, has_dst_ref;
+	struct sccp_source_reference src_ref;
+	struct sccp_source_reference dst_ref;
+
+	/* the input */
+	const u_int8_t *input;
+	int input_len;
+};
+
+static const u_int8_t it_test[] = {
+0x10, 0x01, 0x07, 
+0x94, 0x01, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 };
+
+static const struct sccp_parse_header_result parse_result[] = {
+	{
+		.msg_type	= SCCP_MSG_TYPE_IT,
+		.wanted_len	= 0,
+		.src_ssn	= -1,
+		.dst_ssn	= -1,
+		.has_src_ref	= 1,
+		.has_dst_ref	= 1,
+
+		.src_ref	= {
+			.octet1 = 0x01,
+			.octet2 = 0x04,
+			.octet3 = 0x00
+		},
+		.dst_ref	= {
+			.octet1 = 0x01,
+			.octet2 = 0x07,
+			.octet3 = 0x94,
+		},
+
+		.input		= it_test,
+		.input_len	= sizeof(it_test),
+	},
+};
+
+
 /* testing procedure:
  *	- we will use sccp_write and see what will be set in the
  *	  outgoing callback
@@ -714,6 +760,59 @@
 	printf("survived\n");
 }
 
+static void test_sccp_parsing(void)
+{
+	for (current_test = 0; current_test < ARRAY_SIZE(parse_result); ++current_test) {
+		struct msgb *msg;
+		struct sccp_parse_result result;
+
+		msg = msgb_alloc_headroom(1024, 128, "parse-test");
+		msgb_put(msg, 1);
+		msg->l2h = msgb_put(msg, parse_result[current_test].input_len);
+		memcpy(msg->l2h, parse_result[current_test].input, msgb_l2len(msg));
+
+		memset(&result, 0, sizeof(result));
+		if (sccp_parse_header(msg, &result) != 0) {
+			fprintf(stderr, "Failed to parse test: %d\n", current_test);
+		} else {
+			if (parse_result[current_test].wanted_len != result.data_len) {
+				fprintf(stderr, "Unexpected data length.\n");
+				abort();
+			}
+
+			if (parse_result[current_test].has_src_ref) {
+				if (memcmp(result.source_local_reference,
+					   &parse_result[current_test].src_ref,
+					   sizeof(struct sccp_source_reference)) != 0) {
+					fprintf(stderr, "SRC REF did not match\n");
+					abort();
+				}
+			}
+
+			if (parse_result[current_test].has_dst_ref) {
+				if (memcmp(result.destination_local_reference,
+					   &parse_result[current_test].dst_ref,
+					   sizeof(struct sccp_source_reference)) != 0) {
+					fprintf(stderr, "DST REF did not match\n");
+					abort();
+				}
+			}
+
+			if (parse_result[current_test].src_ssn != -1) {
+				fprintf(stderr, "Not implemented.\n");
+				abort();
+			}
+
+			if (parse_result[current_test].dst_ssn != -1) {
+				fprintf(stderr, "Not implemented.\n");
+				abort();
+			}
+		}
+
+		msgb_free(msg);
+	}
+}
+
 
 int main(int argc, char **argv)
 {
@@ -722,6 +821,7 @@
 	test_sccp_udt_communication();
 	test_sccp_connection();
 	test_sccp_system_crash();
+	test_sccp_parsing();
 	return 0;
 }