sgsn: Pass subscriber error causes to the GMM layer

This patch extends gsm0408_gprs_access_denied and
gsm0408_gprs_access_cancelled to accept GMM cause codes. These are
then passed to the MS, unless gsm0408_gprs_access_cancelled is called
with cause 0 (no error -> updateProcedure).

Since gsm0408_gprs_access_denied uses GMM_CAUSE_GPRS_NOTALLOWED if
the cause is not set, and the subscriber's error_cause is never set
(and thus always 0), the SGSN's behaviour does not change with this
patch.

Sponsored-by: On-Waves ehf

Conflicts:
	openbsc/include/openbsc/gprs_sgsn.h

[hfreyther: Conflict due the removal of the unused
authenticate flag]
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index d762ac4..8b7cc9f 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -652,57 +652,54 @@
 	}
 }
 
-void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx)
+void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx, int gmm_cause)
 {
+	if (gmm_cause == 0)
+		gmm_cause = GMM_CAUSE_GPRS_NOTALLOWED;
+
 	switch (ctx->mm_state) {
 	case GMM_COMMON_PROC_INIT:
-		LOGP(DMM, LOGL_NOTICE,
-		     "Not authorized, rejecting ATTACH REQUEST, IMSI=%s\n",
-		     ctx->imsi);
-		gsm48_tx_gmm_att_rej(ctx, GMM_CAUSE_GPRS_NOTALLOWED);
+		LOGMMCTXP(LOGL_NOTICE, ctx,
+			  "Not authorized, rejecting ATTACH REQUEST "
+			  "with cause '%s' (%d)\n",
+			  get_value_string(gsm48_gmm_cause_names, gmm_cause),
+			  gmm_cause);
+		gsm48_tx_gmm_att_rej(ctx, gmm_cause);
 		mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJECT");
 		break;
 	case GMM_REGISTERED_NORMAL:
 	case GMM_REGISTERED_SUSPENDED:
-		LOGP(DMM, LOGL_NOTICE,
-		     "Authorization lost, detaching, IMSI=%s\n",
-		     ctx->imsi);
+		LOGMMCTXP(LOGL_NOTICE, ctx,
+			  "Authorization lost, detaching "
+			  "with cause '%s' (%d)\n",
+			  get_value_string(gsm48_gmm_cause_names, gmm_cause),
+			  gmm_cause);
 		gsm48_tx_gmm_detach_req(
-			ctx, GPRS_DET_T_MT_REATT_NOTREQ, GMM_CAUSE_GPRS_NOTALLOWED);
+			ctx, GPRS_DET_T_MT_REATT_NOTREQ, gmm_cause);
 
 		mm_ctx_cleanup_free(ctx, "auth lost");
 		break;
 	default:
-		LOGP(DMM, LOGL_INFO,
-		     "Authorization lost, ignored, IMSI=%s\n",
-		     ctx->imsi);
+		LOGMMCTXP(LOGL_INFO, ctx,
+			  "Authorization lost, cause is '%s' (%d)\n",
+			  get_value_string(gsm48_gmm_cause_names, gmm_cause),
+			  gmm_cause);
+		mm_ctx_cleanup_free(ctx, "auth lost");
 	}
 }
 
-void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *ctx)
+void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *ctx, int gmm_cause)
 {
-	switch (ctx->mm_state) {
-#if 0
-	case GMM_COMMON_PROC_INIT:
-		LOGP(DMM, LOGL_NOTICE,
-		     "Cancelled, rejecting ATTACH REQUEST, IMSI=%s\n",
-		     ctx->imsi);
-		gsm48_tx_gmm_att_rej(ctx, GMM_CAUSE_IMPL_DETACHED);
-		break;
-	case GMM_REGISTERED_NORMAL:
-	case GMM_REGISTERED_SUSPENDED:
-		LOGP(DMM, LOGL_NOTICE,
-		     "Cancelled, detaching, IMSI=%s\n",
-		     ctx->imsi);
-		gsm48_tx_gmm_detach_req(
-			ctx, GPRS_DET_T_MT_REATT_NOTREQ, GMM_CAUSE_IMPL_DETACHED);
-		break;
-#endif
-	default:
-		LOGP(DMM, LOGL_INFO,
-		     "Cancelled, deleting context, IMSI=%s\n",
-		     ctx->imsi);
+	if (gmm_cause != 0) {
+		LOGMMCTXP(LOGL_INFO, ctx,
+			  "Cancelled with cause '%s' (%d), deleting context\n",
+			  get_value_string(gsm48_gmm_cause_names, gmm_cause),
+			  gmm_cause);
+		gsm0408_gprs_access_denied(ctx, gmm_cause);
+		return;
 	}
+
+	LOGMMCTXP(LOGL_INFO, ctx, "Cancelled, deleting context silently\n");
 	mm_ctx_cleanup_free(ctx, "access cancelled");
 }
 
diff --git a/openbsc/src/gprs/sgsn_auth.c b/openbsc/src/gprs/sgsn_auth.c
index 9cc67db..9f526dc 100644
--- a/openbsc/src/gprs/sgsn_auth.c
+++ b/openbsc/src/gprs/sgsn_auth.c
@@ -207,6 +207,7 @@
 	enum sgsn_auth_state auth_state;
 	struct gsm_subscriber *subscr = mmctx->subscr;
 	struct gsm_auth_tuple *at;
+	int gmm_cause;
 
 	auth_state = sgsn_auth_state(mmctx);
 
@@ -256,10 +257,12 @@
 		gsm0408_gprs_access_granted(mmctx);
 		break;
 	case SGSN_AUTH_REJECTED:
+		gmm_cause = subscr->sgsn_data->error_cause;
+
 		if (subscr && (subscr->flags & GPRS_SUBSCRIBER_CANCELLED) != 0)
-			gsm0408_gprs_access_cancelled(mmctx);
+			gsm0408_gprs_access_cancelled(mmctx, gmm_cause);
 		else
-			gsm0408_gprs_access_denied(mmctx);
+			gsm0408_gprs_access_denied(mmctx, gmm_cause);
 		break;
 	default:
 		break;