diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/gprs_sgsn.h | 6 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_gmm.c | 58 |
2 files changed, 48 insertions, 16 deletions
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 73731fe97..75797dba0 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -48,6 +48,7 @@ enum gprs_pdp_ctx { }; enum gprs_t3350_mode { + GMM_T3350_MODE_NONE, GMM_T3350_MODE_ATT, GMM_T3350_MODE_RAU, GMM_T3350_MODE_PTMSI_REALL, @@ -111,6 +112,11 @@ struct sgsn_mm_ctx { enum gprs_t3350_mode t3350_mode; uint8_t t3370_id_type; + uint8_t pending_req; /* the request's message type */ + /* TODO: There isn't much semantic difference between t3350_mode + * (refers to the timer) and pending_req (refers to the procedure), + * where mm->T == 3350 => mm->t3350_mode == f(mm->pending_req). Check + * whether one of them can be dropped. */ }; #define LOGMMCTXP(level, mm, fmt, args...) \ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index a5f9b782a..e661b4875 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -625,27 +625,15 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx, } /* Check if we can already authorize a subscriber */ -static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx, - enum gprs_t3350_mode t3350_mode) +static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { - if (strlen(ctx->imei) && strlen(ctx->imsi)) { -#ifdef PTMSI_ALLOC - ctx->t3370_id_type = GSM_MI_TYPE_NONE; - - /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */ - ctx->t3350_mode = t3350_mode; - mmctx_timer_start(ctx, 3350, GSM0408_T3350_SECS); -#endif - ctx->mm_state = GMM_REGISTERED_NORMAL; - return gsm48_tx_gmm_att_ack(ctx); - } + /* Request IMSI and IMEI from the MS if they are unknown */ if (!strlen(ctx->imei)) { ctx->mm_state = GMM_COMMON_PROC_INIT; ctx->t3370_id_type = GSM_MI_TYPE_IMEI; mmctx_timer_start(ctx, 3370, GSM0408_T3370_SECS); return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMEI); } - if (!strlen(ctx->imsi)) { ctx->mm_state = GMM_COMMON_PROC_INIT; ctx->t3370_id_type = GSM_MI_TYPE_IMSI; @@ -653,6 +641,31 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx, return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMSI); } + /* All information required for authentication is available */ + + ctx->t3370_id_type = GSM_MI_TYPE_NONE; + + switch (ctx->pending_req) { + case 0: + LOGMMCTXP(LOGL_INFO, ctx, + "no pending request, authorization completed\n"); + break; + case GSM48_MT_GMM_ATTACH_REQ: +#ifdef PTMSI_ALLOC + /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */ + mmctx_timer_start(ctx, 3350, GSM0408_T3350_SECS); + ctx->t3350_mode = GMM_T3350_MODE_ATT; +#endif + + ctx->mm_state = GMM_REGISTERED_NORMAL; + return gsm48_tx_gmm_att_ack(ctx); + default: + LOGMMCTXP(LOGL_ERROR, ctx, + "only Attach Request is supported yet, " + "got request type %u\n", ctx->pending_req); + break; + } + return 0; } @@ -715,7 +728,7 @@ static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg) } /* Check if we can let the mobile station enter */ - return gsm48_gmm_authorize(ctx, ctx->t3350_mode); + return gsm48_gmm_authorize(ctx); } /* Section 9.4.1 Attach request */ @@ -856,7 +869,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, gprs_llgmm_assign(ctx->llme, ctx->tlli, ctx->tlli_new, GPRS_ALGO_GEA0, NULL); - return gsm48_gmm_authorize(ctx, GMM_T3350_MODE_ATT); + ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ; + return gsm48_gmm_authorize(ctx); err_inval: LOGPC(DMM, LOGL_INFO, "\n"); @@ -1168,7 +1182,9 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, /* only in case SGSN offered new P-TMSI */ LOGMMCTXP(LOGL_INFO, mmctx, "-> ATTACH COMPLETE\n"); mmctx_timer_stop(mmctx, 3350); + mmctx->t3350_mode = GMM_T3350_MODE_NONE; mmctx->p_tmsi_old = 0; + mmctx->pending_req = 0; /* Unassign the old TLLI */ mmctx->tlli = mmctx->tlli_new; gprs_llgmm_assign(mmctx->llme, 0xffffffff, mmctx->tlli_new, @@ -1179,7 +1195,9 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, /* only in case SGSN offered new P-TMSI */ LOGMMCTXP(LOGL_INFO, mmctx, "-> ROUTEING AREA UPDATE COMPLETE\n"); mmctx_timer_stop(mmctx, 3350); + mmctx->t3350_mode = GMM_T3350_MODE_NONE; mmctx->p_tmsi_old = 0; + mmctx->pending_req = 0; /* Unassign the old TLLI */ mmctx->tlli = mmctx->tlli_new; gprs_llgmm_assign(mmctx->llme, 0xffffffff, mmctx->tlli_new, @@ -1189,7 +1207,9 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, case GSM48_MT_GMM_PTMSI_REALL_COMPL: LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLLICATION COMPLETE\n"); mmctx_timer_stop(mmctx, 3350); + mmctx->t3350_mode = GMM_T3350_MODE_NONE; mmctx->p_tmsi_old = 0; + mmctx->pending_req = 0; /* Unassign the old TLLI */ mmctx->tlli = mmctx->tlli_new; //gprs_llgmm_assign(mmctx->llme, 0xffffffff, mmctx->tlli_new, GPRS_ALGO_GEA0, NULL); @@ -1219,6 +1239,8 @@ static void mmctx_timer_cb(void *_mm) if (mm->num_T_exp >= 5) { LOGMMCTXP(LOGL_NOTICE, mm, "T3350 expired >= 5 times\n"); mm->mm_state = GMM_DEREGISTERED; + mm->t3350_mode = GMM_T3350_MODE_NONE; + mm->pending_req = 0; /* FIXME: should we return some error? */ break; } @@ -1233,6 +1255,10 @@ static void mmctx_timer_cb(void *_mm) case GMM_T3350_MODE_PTMSI_REALL: /* FIXME */ break; + case GMM_T3350_MODE_NONE: + LOGMMCTXP(LOGL_NOTICE, mm, + "T3350 mode wasn't set, ignoring timeout\n"); + break; } osmo_timer_schedule(&mm->timer, GSM0408_T3350_SECS, 0); break; |