From 8c6732909bd8dc090c079755a4166e813bac826a Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Mon, 2 May 2016 16:46:43 +0200 Subject: gprs: Track PMM states For Iu mode it is important to know when the UE is in PMM-IDLE mode since the SGSN will need to page the UE if there is data for it. --- openbsc/include/openbsc/gprs_sgsn.h | 15 +++++++++++++-- openbsc/src/gprs/gprs_gmm.c | 10 ++++++++-- openbsc/src/gprs/gprs_sgsn.c | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 10c2d9a7f..7dadfd214 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -24,7 +24,7 @@ struct gsm_subscriber; enum gsm48_gsm_cause; /* TS 04.08 4.1.3.3 GMM mobility management states on the network side */ -enum gprs_mm_state { +enum gprs_gmm_state { GMM_DEREGISTERED, /* 4.1.3.3.1.1 */ GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */ GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */ @@ -32,6 +32,16 @@ enum gprs_mm_state { GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */ }; +/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */ +enum gprs_pmm_state { + PMM_DETACHED, + PMM_CONNECTED, + PMM_IDLE, + MM_IDLE = PMM_DETACHED, + MM_READY = PMM_CONNECTED, + MM_STANDBY = PMM_IDLE, +}; + enum gprs_mm_ctr { GMM_CTR_PKTS_SIG_IN, GMM_CTR_PKTS_SIG_OUT, @@ -117,7 +127,8 @@ struct sgsn_mm_ctx { enum sgsn_ran_type ran_type; char imsi[GSM_IMSI_LENGTH]; - enum gprs_mm_state mm_state; + enum gprs_gmm_state mm_state; + enum gprs_pmm_state pmm_state; uint32_t p_tmsi; uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ uint32_t p_tmsi_sig; diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index d734df014..f32854d74 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -120,7 +120,10 @@ int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void * /* fall thru */ case IU_EVENT_LINK_INVALIDATED: /* Clean up ue_conn_ctx here */ - LOGMMCTXP(LOGL_INFO, mm, "IU release\n"); + LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); + if (mm->pmm_state == PMM_CONNECTED) + mm->pmm_state = PMM_IDLE; + rc = 0; break; case IU_EVENT_SECURITY_MODE_COMPLETE: @@ -217,6 +220,7 @@ static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text) /* Mark MM state as deregistered */ ctx->mm_state = GMM_DEREGISTERED; + ctx->pmm_state = PMM_DETACHED; sgsn_mm_ctx_cleanup_free(ctx); } @@ -802,7 +806,7 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) case GSM48_MT_GMM_SERVICE_REQ: /* TODO: PMM State transition */ ctx->pending_req = 0; - + ctx->pmm_state = PMM_CONNECTED; rc = gsm48_tx_gmm_service_ack(ctx); if (ctx->iu.service.type == 1) { @@ -1714,6 +1718,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, GPRS_ALGO_GEA0, NULL); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; rc = 0; memset(&sig_data, 0, sizeof(sig_data)); @@ -1734,6 +1739,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, GPRS_ALGO_GEA0, NULL); } mmctx->mm_state = GMM_REGISTERED_NORMAL; + mmctx->pmm_state = PMM_CONNECTED; activate_pdp_rabs(mmctx); rc = 0; diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index c34620183..bfa2c4436 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -205,6 +205,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx) ctx->iu.ue_ctx = uectx; ctx->iu.new_key = 1; ctx->mm_state = GMM_DEREGISTERED; + ctx->pmm_state = PMM_DETACHED; ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0); INIT_LLIST_HEAD(&ctx->pdp_list); -- cgit v1.2.3