diff options
-rw-r--r-- | openbsc/include/sccp/sccp.h | 1 | ||||
-rw-r--r-- | openbsc/include/sccp/sccp_types.h | 11 | ||||
-rw-r--r-- | openbsc/src/sccp/sccp.c | 42 | ||||
-rw-r--r-- | openbsc/tests/sccp/sccp_test.c | 1 |
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) |