From 7ad066c5c380a93aa525356ff588c1f8776ad4a2 Mon Sep 17 00:00:00 2001 From: Jonathan Santos Date: Fri, 10 Jun 2011 17:25:48 -0400 Subject: gprs: Suspend user data transmission during Routing Area Updating TS 24.008 version 9.5.0 Release 9 sec 4.7.5: In A/Gb mode, user data transmission in the MS shall be suspended during the routing area updating procedure, except if the routing area updating procedure is triggered by a PS handover procedure as described in 3GPP TS 43.129 [113]; user data reception shall be possible. User data transmission in the network may be suspended during the routing area updating procedure. --- include/openbsc/gprs_llc.h | 4 ++++ src/gprs/gprs_gmm.c | 5 +++++ src/gprs/gprs_llc.c | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/include/openbsc/gprs_llc.h b/include/openbsc/gprs_llc.h index 02945e164..5949ac3b8 100644 --- a/include/openbsc/gprs_llc.h +++ b/include/openbsc/gprs_llc.h @@ -140,6 +140,8 @@ struct gprs_llc_llme { uint16_t bvci; uint16_t nsei; struct gprs_llc_lle lle[NUM_SAPIS]; + + int suspended; }; extern struct llist_head gprs_llc_llmes; @@ -156,6 +158,8 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme, uint32_t old_tlli, uint32_t new_tlli, enum gprs_ciph_algo alg, const uint8_t *kc); +int gprs_llgmm_suspend(struct gprs_llc_llme *llme); +int gprs_llgmm_resume(struct gprs_llc_llme *llme); int gprs_llc_init(const char *cipher_plugin_path); int gprs_llc_vty_init(void); diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c index b722f1212..d6cd4125c 100644 --- a/src/gprs/gprs_gmm.c +++ b/src/gprs/gprs_gmm.c @@ -937,6 +937,8 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_MS_ID_NOT_DERIVED); } + gprs_llgmm_suspend(mmctx->llme); + /* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */ msgid2mmctx(mmctx, msg); /* Bump the statistics of received signalling msgs for this MM context */ @@ -1027,6 +1029,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, gprs_llgmm_assign(mmctx->llme, mmctx->tlli, mmctx->tlli_new, GPRS_ALGO_GEA0, NULL); mmctx->tlli = mmctx->tlli_new; + gprs_llgmm_resume(mmctx->llme); break; case GSM48_MT_GMM_RA_UPD_COMPL: /* only in case SGSN offered new P-TMSI */ @@ -1037,6 +1040,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, gprs_llgmm_assign(mmctx->llme, mmctx->tlli, mmctx->tlli_new, GPRS_ALGO_GEA0, NULL); mmctx->tlli = mmctx->tlli_new; + gprs_llgmm_resume(mmctx->llme); break; case GSM48_MT_GMM_PTMSI_REALL_COMPL: DEBUGP(DMM, "-> PTMSI REALLLICATION COMPLETE\n"); @@ -1070,6 +1074,7 @@ static void mmctx_timer_cb(void *_mm) case 3350: /* waiting for ATTACH COMPLETE */ if (mm->num_T_exp >= 5) { LOGP(DMM, LOGL_NOTICE, "T3350 expired >= 5 times\n"); + gprs_llgmm_resume(mm->llme); break; } /* re-transmit the respective msg and re-start timer */ diff --git a/src/gprs/gprs_llc.c b/src/gprs/gprs_llc.c index 37bd8804f..0b4a5de94 100644 --- a/src/gprs/gprs_llc.c +++ b/src/gprs/gprs_llc.c @@ -350,6 +350,12 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, return -EFBIG; } + if ((sapi != GPRS_SAPI_GMM) && lle->llme->suspended) { + LOGP(DLLC, LOGL_DEBUG, "LLC TX: suspended TLLI 0x08x, " + "dropping UI frame\n", msgb_tlli(msg)); + return 0; + } + /* Update LLE's (BVCI, NSEI) tuple */ lle->llme->bvci = msgb_bvci(msg); lle->llme->nsei = msgb_nsei(msg); @@ -846,6 +852,18 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme, return 0; } +int gprs_llgmm_suspend(struct gprs_llc_llme* llme) +{ + llme->suspended = 1; + return 0; +} + +int gprs_llgmm_resume(struct gprs_llc_llme* llme) +{ + llme->suspended = 0; + return 0; +} + int gprs_llc_init(const char *cipher_plugin_path) { return gprs_cipher_load(cipher_plugin_path); -- cgit v1.2.3