iu_client: introduce ranap_iu_tx_release_free()

ranap_iu_tx_release_free is a fire and forget function to release
gracefully if possible. It first sends a Iu Release Command. After
a certain timeout the connection will be released.

Change-Id: I349e2c61ba0131e233b7ab927dfced0bd461dd8f
diff --git a/src/iu_client.c b/src/iu_client.c
index 38c8a1d..e4eb83e 100644
--- a/src/iu_client.c
+++ b/src/iu_client.c
@@ -129,6 +129,9 @@
 	ctx->rnc = rnc;
 	ctx->conn_id = conn_id;
 	ctx->notification = true;
+	osmo_timer_setup(&ctx->release_timeout,
+			 (void *)(void *) ranap_iu_free_ue,
+			 ctx);
 	llist_add(&ctx->list, &ue_conn_ctx_list);
 
 	return ctx;
@@ -150,6 +153,7 @@
 	if (!ue_ctx)
 		return;
 
+	osmo_timer_del(&ue_ctx->release_timeout);
 	osmo_sccp_tx_disconn(g_scu, ue_ctx->conn_id, NULL, 0);
 	llist_del(&ue_ctx->list);
 	talloc_free(ue_ctx);
@@ -491,6 +495,20 @@
 	return osmo_sccp_user_sap_down(g_scu, &prim->oph);
 }
 
+void ranap_iu_tx_release_free(struct ranap_ue_conn_ctx *ctx,
+			     const struct RANAP_Cause *cause,
+			     int timeout)
+{
+	ctx->notification = false;
+	int ret = ranap_iu_tx_release(ctx, cause);
+	if (ret) {
+		ranap_iu_free_ue(ctx);
+		return;
+	}
+
+	osmo_timer_schedule(&ctx->release_timeout, timeout, 0);
+}
+
 static int ranap_handle_co_iu_rel_req(struct ranap_ue_conn_ctx *ctx, RANAP_Iu_ReleaseRequestIEs_t *ies)
 {
 	LOGPIU(LOGL_INFO, "Received Iu Release Request, Sending Release Command\n");