bsc: Implement queuing of messages to the MSC before the con is established
This commit is contained in:
parent
16e958dc68
commit
b4e72f881c
|
@ -19,6 +19,9 @@ struct osmo_bsc_sccp_con {
|
|||
struct timer_list sccp_it_timeout;
|
||||
struct timer_list sccp_cc_timeout;
|
||||
|
||||
struct llist_head sccp_queue;
|
||||
unsigned int sccp_queue_size;
|
||||
|
||||
struct gsm_subscriber_connection *conn;
|
||||
uint8_t new_subscriber;
|
||||
};
|
||||
|
|
|
@ -39,6 +39,32 @@
|
|||
|
||||
static LLIST_HEAD(active_connections);
|
||||
|
||||
static void free_queued(struct osmo_bsc_sccp_con *conn)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
while (!llist_empty(&conn->sccp_queue)) {
|
||||
/* this is not allowed to fail */
|
||||
msg = msgb_dequeue(&conn->sccp_queue);
|
||||
msgb_free(msg);
|
||||
}
|
||||
|
||||
conn->sccp_queue_size = 0;
|
||||
}
|
||||
|
||||
static void send_queued(struct osmo_bsc_sccp_con *conn)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
while (!llist_empty(&conn->sccp_queue)) {
|
||||
/* this is not allowed to fail */
|
||||
msg = msgb_dequeue(&conn->sccp_queue);
|
||||
sccp_connection_write(conn->sccp, msg);
|
||||
msgb_free(msg);
|
||||
conn->sccp_queue_size -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void msc_outgoing_sccp_data(struct sccp_connection *conn,
|
||||
struct msgb *msg, unsigned int len)
|
||||
{
|
||||
|
@ -63,6 +89,7 @@ static void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
|
|||
}
|
||||
|
||||
con_data->sccp = NULL;
|
||||
free_queued(con_data);
|
||||
sccp_connection_free(conn);
|
||||
bsc_delete_connection(con_data);
|
||||
} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
|
||||
|
@ -71,6 +98,8 @@ static void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
|
|||
|
||||
bsc_del_timer(&con_data->sccp_cc_timeout);
|
||||
bsc_schedule_timer(&con_data->sccp_it_timeout, SCCP_IT_TIMER, 0);
|
||||
|
||||
send_queued(con_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +111,7 @@ static void bsc_sccp_force_free(struct osmo_bsc_sccp_con *data)
|
|||
data->conn = NULL;
|
||||
}
|
||||
|
||||
free_queued(data);
|
||||
sccp_connection_force_free(data->sccp);
|
||||
data->sccp = NULL;
|
||||
bsc_delete_connection(data);
|
||||
|
@ -130,14 +160,22 @@ int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
|
|||
{
|
||||
struct sccp_connection *sccp = conn->sccp;
|
||||
|
||||
if (sccp->connection_state != SCCP_CONNECTION_STATE_ESTABLISHED) {
|
||||
LOGP(DMSC, LOGL_ERROR, "The connection is not established.\n");
|
||||
if (sccp->connection_state > SCCP_CONNECTION_STATE_ESTABLISHED) {
|
||||
LOGP(DMSC, LOGL_ERROR, "Connection closing, dropping packet on: %p\n", sccp);
|
||||
msgb_free(msg);
|
||||
return -1;
|
||||
} else if (sccp->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED
|
||||
&& conn->sccp_queue_size == 0) {
|
||||
sccp_connection_write(sccp, msg);
|
||||
msgb_free(msg);
|
||||
} else if (conn->sccp_queue_size > 10) {
|
||||
LOGP(DMSC, LOGL_ERROR, "Connection closing, dropping packet on: %p\n", sccp);
|
||||
msgb_free(msg);
|
||||
} else {
|
||||
LOGP(DMSC, LOGL_DEBUG, "Queueing packet on %p. Queue size: %d\n", sccp, conn->sccp_queue_size);
|
||||
conn->sccp_queue_size += 1;
|
||||
msgb_enqueue(&conn->sccp_queue, msg);
|
||||
}
|
||||
|
||||
sccp_connection_write(sccp, msg);
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -182,6 +220,8 @@ int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
|
|||
bsc_con->sccp_cc_timeout.cb = sccp_cc_timeout;
|
||||
bsc_con->sccp_cc_timeout.data = bsc_con;
|
||||
|
||||
INIT_LLIST_HEAD(&bsc_con->sccp_queue);
|
||||
|
||||
bsc_con->sccp = sccp;
|
||||
bsc_con->msc_con = net->msc_data->msc_con;
|
||||
bsc_con->conn = conn;
|
||||
|
|
Loading…
Reference in New Issue