[sccp] Implement sending the Inactivity Test on a connection..

Currently this will send a dummy inactivity test message,
there is currently no parsing or API to receive the messages.

The sequencing and credit entries are empty as sequencing
is currently not used at all.

The test is currently limited to send the message and see
if the application is crashing or not.
diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h
index 8ee4b68..3ad568c 100644
--- a/openbsc/include/sccp/sccp.h
+++ b/openbsc/include/sccp/sccp.h
@@ -101,6 +101,7 @@
  * Send data on an existing connection
  */
 int sccp_connection_write(struct sccp_connection *connection, struct msgb *data);
+int sccp_connection_send_it(struct sccp_connection *connection);
 int sccp_connection_close(struct sccp_connection *connection, int cause);
 int sccp_connection_free(struct sccp_connection *connection);
 
diff --git a/openbsc/include/sccp/sccp_types.h b/openbsc/include/sccp/sccp_types.h
index c6b1182..9310a6b 100644
--- a/openbsc/include/sccp/sccp_types.h
+++ b/openbsc/include/sccp/sccp_types.h
@@ -380,4 +380,15 @@
 	u_int8_t			data[0];
 } __attribute__((packed));
 
+struct sccp_data_it {
+	/* mandantory */
+	u_int8_t			type;
+	struct sccp_source_reference	destination_local_reference;
+	struct sccp_source_reference	source_local_reference;
+	u_int8_t			proto_class;
+
+	u_int8_t			sequencing[2];
+	u_int8_t			credit;
+} __attribute__((packed));
+
 #endif
diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c
index 8b111b2..522afcf 100644
--- a/openbsc/src/sccp/sccp.c
+++ b/openbsc/src/sccp/sccp.c
@@ -535,6 +535,31 @@
 	return ret;
 }
 
+static int _sccp_send_connection_it(struct sccp_connection *conn)
+{
+	struct msgb *msgb;
+	struct sccp_data_it *it;
+	int ret;
+
+	msgb = msgb_alloc_headroom(SCCP_MSG_SIZE,
+				   SCCP_MSG_HEADROOM, "sccp it");
+	msgb->l2h = &msgb->data[0];
+	it = (struct sccp_data_it *) msgb_put(msgb, sizeof(*it));
+	it->type = SCCP_MSG_TYPE_IT;
+	memcpy(&it->destination_local_reference, &conn->destination_local_reference,
+		sizeof(struct sccp_source_reference));
+	memcpy(&it->source_local_reference, &conn->source_local_reference,
+		sizeof(struct sccp_source_reference));
+
+	it->proto_class = 0x2;
+	it->sequencing[0] = it->sequencing[1] = 0;
+	it->credit = 0;
+
+	ret = _send_msg(msgb);
+	msgb_free(msgb);
+	return ret;
+}
+
 static int _sccp_send_connection_released(struct sccp_connection *conn, int cause)
 {
 	struct msgb *msg;
@@ -1025,6 +1050,23 @@
 	return _sccp_send_connection_data(connection, data);
 }
 
+/*
+ * Send a Inactivity Test message. The owner of the connection
+ * should start a timer and call this method regularily. Calling
+ * this every 60 seconds should be good enough.
+ */
+int sccp_connection_send_it(struct sccp_connection *connection)
+{
+	if (connection->connection_state < SCCP_CONNECTION_STATE_CONFIRM
+	    || connection->connection_state > SCCP_CONNECTION_STATE_ESTABLISHED) {
+		DEBUGP(DSCCP, "sccp_connection_write: Wrong connection state: %p %d\n",
+		       connection, connection->connection_state);
+		return -1;
+	}
+
+	return _sccp_send_connection_it(connection);
+}
+
 /* send a connection release and wait for the connection released */
 int sccp_connection_close(struct sccp_connection *connection, int cause)
 {
diff --git a/openbsc/tests/sccp/sccp_test.c b/openbsc/tests/sccp/sccp_test.c
index d3b334f..bd28ed1 100644
--- a/openbsc/tests/sccp/sccp_test.c
+++ b/openbsc/tests/sccp/sccp_test.c
@@ -622,6 +622,7 @@
 
 		printf("\tWriting test data2\n");
 		sccp_connection_write(outgoing_con, test_data2);
+		sccp_connection_send_it(outgoing_con);
 
 		/* closing connection */
 		if (test->close_side == 0)