aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/sccp/sccp.h1
-rw-r--r--openbsc/include/sccp/sccp_types.h11
-rw-r--r--openbsc/src/sccp/sccp.c42
-rw-r--r--openbsc/tests/sccp/sccp_test.c1
4 files changed, 55 insertions, 0 deletions
diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h
index 8ee4b680b..3ad568c0b 100644
--- a/openbsc/include/sccp/sccp.h
+++ b/openbsc/include/sccp/sccp.h
@@ -101,6 +101,7 @@ int sccp_system_incoming(struct msgb *data);
* 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 c6b11820c..9310a6bf0 100644
--- a/openbsc/include/sccp/sccp_types.h
+++ b/openbsc/include/sccp/sccp_types.h
@@ -380,4 +380,15 @@ struct sccp_data_unitdata {
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 8b111b2f5..522afcf7a 100644
--- a/openbsc/src/sccp/sccp.c
+++ b/openbsc/src/sccp/sccp.c
@@ -535,6 +535,31 @@ static int _sccp_send_connection_data(struct sccp_connection *conn, struct msgb
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 @@ int sccp_connection_write(struct sccp_connection *connection, struct msgb *data)
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 d3b334f3b..bd28ed179 100644
--- a/openbsc/tests/sccp/sccp_test.c
+++ b/openbsc/tests/sccp/sccp_test.c
@@ -622,6 +622,7 @@ static void do_test_sccp_connection(const struct connection_test *test)
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)