aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Santos <jrsantos@jonathanrsantos.com>2011-06-10 17:25:48 -0400
committerJonathan Santos <jrsantos@jonathanrsantos.com>2011-06-23 17:47:27 -0400
commit7ad066c5c380a93aa525356ff588c1f8776ad4a2 (patch)
tree98832d5989a324ebb78cf0c8762fa39fa56f4dc4
parenta0fb1bb84765bfe3148d55a6da57c007a5ffe895 (diff)
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.
-rw-r--r--include/openbsc/gprs_llc.h4
-rw-r--r--src/gprs/gprs_gmm.c5
-rw-r--r--src/gprs/gprs_llc.c18
3 files changed, 27 insertions, 0 deletions
diff --git a/include/openbsc/gprs_llc.h b/include/openbsc/gprs_llc.h
index 02945e16..5949ac3b 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 b722f121..d6cd4125 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 37bd8804..0b4a5de9 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);