gprs_ranap: release Iu UE Context when exiting PMM Connected

PMM Connected defines a Iu signaling connection. The 2 other
PMM states do not have an active Iu signaling connection.

Change-Id: Ie05d2bdf8dfb593b4c7e837107a3a06f22e90119
diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
index d2b3455..8f45650 100644
--- a/src/sgsn/gprs_ranap.c
+++ b/src/sgsn/gprs_ranap.c
@@ -119,6 +119,7 @@
 	mm = sgsn_mm_ctx_by_ue_ctx(ctx);
 	if (!mm) {
 		LOGIUP(ctx, LOGL_NOTICE, "Cannot find mm ctx for IU event %d\n", type);
+		ranap_iu_free_ue(ctx);
 		return rc;
 	}
 
@@ -131,7 +132,11 @@
 	case RANAP_IU_EVENT_LINK_INVALIDATED:
 		/* Clean up ranap_ue_conn_ctx here */
 		LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
-		osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_PS_CONN_RELEASE, NULL);
+		if (mm->iu.mm_state_fsm->state == ST_PMM_CONNECTED)
+			osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_PS_CONN_RELEASE, NULL);
+		else
+			sgsn_ranap_iu_free(mm);
+
 		rc = 0;
 		break;
 	case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
@@ -153,6 +158,35 @@
 	return rc;
 }
 
+/* TODO: use timers */
+#define TIMEOUT_RANAP_RELEASE_SEC 5
+void sgsn_ranap_iu_free(struct sgsn_mm_ctx *ctx)
+{
+	if (!ctx)
+		return;
+
+	if (!ctx->iu.ue_ctx)
+		return;
+
+	ranap_iu_free_ue(ctx->iu.ue_ctx);
+	ctx->iu.ue_ctx = NULL;
+}
+
+void sgsn_ranap_iu_release_free(struct sgsn_mm_ctx *ctx,
+				const struct RANAP_Cause *cause)
+{
+	if (!ctx)
+		return;
+
+	if (!ctx->iu.ue_ctx)
+		return;
+
+	ranap_iu_tx_release_free(ctx->iu.ue_ctx,
+				 cause,
+				 TIMEOUT_RANAP_RELEASE_SEC);
+	ctx->iu.ue_ctx = NULL;
+}
+
 int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp)
 {
 	struct msgb *msg;