diff options
Diffstat (limited to 'openbsc/src/gprs/gprs_gmm.c')
-rw-r--r-- | openbsc/src/gprs/gprs_gmm.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index a966949a4..a2c30bee0 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -803,6 +803,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, char mi_string[GSM48_MI_SIZE]; struct gprs_ra_id ra_id; uint16_t cid; + enum gsm48_gmm_cause reject_cause; + int rc; LOGP(DMM, LOGL_INFO, "-> GMM ATTACH REQUEST "); @@ -863,8 +865,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN); #else ctx = sgsn_mm_ctx_alloc(0, &ra_id); - if (!ctx) - return gsm48_tx_gmm_att_rej_oldmsg(msg, GMM_CAUSE_NET_FAIL); + if (!ctx) { + reject_cause = GMM_CAUSE_NET_FAIL; + goto rejected; + } strncpy(ctx->imsi, mi_string, sizeof(ctx->imsi)); #endif } @@ -891,7 +895,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, default: LOGP(DMM, LOGL_NOTICE, "Rejecting ATTACH REQUEST with " "MI type %u\n", mi_type); - return gsm48_tx_gmm_att_rej_oldmsg(msg, GMM_CAUSE_MS_ID_NOT_DERIVED); + reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED; + goto rejected; } /* Update MM Context with currient RA and Cell ID */ ctx->ra = ra_id; @@ -923,7 +928,22 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, err_inval: LOGPC(DMM, LOGL_INFO, "\n"); - return gsm48_tx_gmm_att_rej_oldmsg(msg, GMM_CAUSE_SEM_INCORR_MSG); + reject_cause = GMM_CAUSE_SEM_INCORR_MSG; + +rejected: + /* Send ATTACH REJECT */ + LOGMMCTXP(LOGL_NOTICE, ctx, + "Rejecting Attach Request with cause '%s' (%d)\n", + get_value_string(gmm_cause_names, reject_cause), reject_cause); + rc = gsm48_tx_gmm_att_rej_oldmsg(msg, reject_cause); + if (ctx) + mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJ"); + else + /* TLLI unassignment */ + gprs_llgmm_assign(llme, llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL); + + return rc; + } /* Section 4.7.4.1 / 9.4.5.2 MO Detach request */ @@ -1061,6 +1081,8 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, struct gprs_ra_id old_ra_id; struct tlv_parsed tp; uint8_t upd_type; + enum gsm48_gmm_cause reject_cause; + int rc; /* Update Type 10.5.5.18 */ upd_type = *cur++ & 0x0f; @@ -1074,8 +1096,10 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, /* MS Radio Access Capability 10.5.5.12a */ ms_ra_acc_cap_len = *cur++; - if (ms_ra_acc_cap_len > 52) - return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_PROTO_ERR_UNSPEC); + if (ms_ra_acc_cap_len > 52) { + reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC; + goto rejected; + } cur += ms_ra_acc_cap_len; /* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status, @@ -1087,8 +1111,8 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, case GPRS_UPD_T_RA_LA: case GPRS_UPD_T_RA_LA_IMSI_ATT: LOGP(DMM, LOGL_NOTICE, "Update type %i unsupported in Mode III, is your SI13 corrupt?\n", upd_type); - return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_PROTO_ERR_UNSPEC); - break; + reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC; + goto rejected; case GPRS_UPD_T_RA: case GPRS_UPD_T_PERIODIC: break; @@ -1104,7 +1128,8 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, /* The MS has to perform GPRS attach */ /* Device is still IMSI attached for CS but initiate GPRS ATTACH, * see GSM 04.08, 4.7.5.1.4 and G.6 */ - return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_IMPL_DETACHED); + reject_cause = GMM_CAUSE_IMPL_DETACHED; + goto rejected; } /* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */ @@ -1150,6 +1175,21 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, /* Send RA UPDATE ACCEPT */ return gsm48_tx_gmm_ra_upd_ack(mmctx); + +rejected: + /* Send RA UPDATE REJECT */ + LOGMMCTXP(LOGL_NOTICE, mmctx, + "Rejecting RA Update Request with cause '%s' (%d)\n", + get_value_string(gmm_cause_names, reject_cause), reject_cause); + rc = gsm48_tx_gmm_ra_upd_rej(msg, reject_cause); + if (mmctx) + mm_ctx_cleanup_free(mmctx, "GPRS RA UPDATE REJ"); + else + /* TLLI unassignment */ + gprs_llgmm_assign(llme, llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, + NULL); + + return rc; } static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg) |