diff options
author | Jonathan Santos <jrsantos@jonathanrsantos.com> | 2011-06-10 17:07:45 -0400 |
---|---|---|
committer | Jonathan Santos <jrsantos@jonathanrsantos.com> | 2011-06-23 17:45:19 -0400 |
commit | 8f3a5a2f0bbcd94e122639c45a9f7f0e73c46865 (patch) | |
tree | 3c5fa716efa0b7728b767536431368c641d3693c /src/gprs/gprs_gmm.c | |
parent | 749a666d849743353473813210cbf6899005c6c4 (diff) |
gprs: Delete GMM and PDP contexts if ATTACH_REQUEST received from already-attached MS
TS 24.008 version 9.5.0 Release 9 sec 4.7.3.1.6:
If an ATTACH REQUEST message is received in state GMM-REGISTERED
the network may initiate the GMM common procedures; if it turned
out that the ATTACH REQUEST message was send by an MS that has
already been attached, the GMM context, PDP contexts and MBMS
contexts, if any, are deleted and the new ATTACH REQUEST is
progressed.
Diffstat (limited to 'src/gprs/gprs_gmm.c')
-rw-r--r-- | src/gprs/gprs_gmm.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c index 467c7a0bd..942d93f47 100644 --- a/src/gprs/gprs_gmm.c +++ b/src/gprs/gprs_gmm.c @@ -635,6 +635,21 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, DEBUGP(DMM, "-> GMM ATTACH REQUEST "); + if (ctx && ((ctx->mm_state == GMM_REGISTERED_NORMAL) || + (ctx->mm_state == GMM_REGISTERED_SUSPENDED))) { + struct sgsn_pdp_ctx *pdp, *pdp2; + + LOGP(DMM, LOGL_NOTICE, "Attach requested by already-attached " + "mobile. Deleting existing contexts\n"); + + llist_for_each_entry_safe(pdp, pdp2, &ctx->pdp_list, list) { + sgsn_delete_pdp_ctx(pdp, 1); + } + + sgsn_mm_ctx_free(ctx); + ctx = NULL; + } + /* As per TS 04.08 Chapter 4.7.1.4, the attach request arrives either * with a foreign TLLI (P-TMSI that was allocated to the MS before), * or with random TLLI. */ @@ -772,7 +787,7 @@ static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) llist_for_each_entry_safe(pdp, pdp2, &ctx->pdp_list, list) { LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u " "due to GPRS DETACH REQUEST\n", pdp->nsapi); - sgsn_delete_pdp_ctx(pdp); + sgsn_delete_pdp_ctx(pdp, 0); /* FIXME: the callback wants to transmit a DEACT PDP CTX ACK, * which is quite stupid for a MS that has just detached.. */ } @@ -866,7 +881,7 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx, LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u " "due to PDP CTX STATUS IE= 0x%04x\n", pdp->nsapi, pdp_status); - sgsn_delete_pdp_ctx(pdp); + sgsn_delete_pdp_ctx(pdp, 0); } } } @@ -1393,7 +1408,7 @@ static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg) return _gsm48_tx_gsm_deact_pdp_acc(mm, transaction_id); } - return sgsn_delete_pdp_ctx(pdp); + return sgsn_delete_pdp_ctx(pdp, 0); } /* Section 9.5.9: Deactivate PDP Context Accept */ @@ -1413,7 +1428,7 @@ static int gsm48_rx_gsm_deact_pdp_ack(struct sgsn_mm_ctx *mm, struct msgb *msg) return 0; } - return sgsn_delete_pdp_ctx(pdp); + return sgsn_delete_pdp_ctx(pdp, 0); } static int gsm48_rx_gsm_status(struct sgsn_mm_ctx *ctx, struct msgb *msg) @@ -1437,7 +1452,7 @@ static void pdpctx_timer_cb(void *_pdp) if (pdp->num_T_exp >= 4) { LOGP(DMM, LOGL_NOTICE, "T3395 expired >= 5 times\n"); pdp->state = PDP_STATE_INACTIVE; - sgsn_delete_pdp_ctx(pdp); + sgsn_delete_pdp_ctx(pdp, 0); break; } gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL); |