From af3d5c508c9ca3ebae9388d3e09c5d7726db4f5c Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 5 Jan 2015 17:51:17 +0100 Subject: 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] --- openbsc/include/openbsc/gprs_gmm.h | 4 +-- openbsc/include/openbsc/gprs_sgsn.h | 1 + openbsc/src/gprs/gprs_gmm.c | 65 ++++++++++++++++++------------------- openbsc/src/gprs/sgsn_auth.c | 7 ++-- openbsc/tests/sgsn/sgsn_test.c | 2 +- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h index 6e0b67b7b..5b3321ffc 100644 --- a/openbsc/include/openbsc/gprs_gmm.h +++ b/openbsc/include/openbsc/gprs_gmm.h @@ -14,8 +14,8 @@ int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme); int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx); int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg); void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx); -void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx); -void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx); +void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause); +void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause); void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx); int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli); diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 48c9cc38c..7416e8cf7 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -275,6 +275,7 @@ struct sgsn_subscriber_data { struct sgsn_mm_ctx *mm; struct gsm_auth_tuple auth_triplets[5]; int auth_triplets_updated; + int error_cause; }; struct sgsn_config; diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index d762ac4aa..8b7cc9f17 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -652,57 +652,54 @@ void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *ctx) } } -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 9cc67db1c..9f526dcc1 100644 --- a/openbsc/src/gprs/sgsn_auth.c +++ b/openbsc/src/gprs/sgsn_auth.c @@ -207,6 +207,7 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx) 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 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx) 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; diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index d9cb84212..ef8661b12 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1278,7 +1278,7 @@ static void test_gmm_cancel(void) OSMO_ASSERT(sgsn_tx_counter == 0); /* cancel */ - gsm0408_gprs_access_cancelled(ctx); + gsm0408_gprs_access_cancelled(ctx, 0); /* verify that things are gone */ OSMO_ASSERT(count(gprs_llme_list()) == 0); -- cgit v1.2.3