/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_authentication_complete()                            **
 **                                                                        **
 ** Description: Performs the authentication completion procedure executed **
 **      by the network.                                                   **
 **                                                                        **
 **              3GPP TS 24.301, section 5.4.2.4                           **
 **      Upon receiving the AUTHENTICATION RESPONSE message, the           **
 **      MME shall stop timer T3460 and check the correctness of           **
 **      the RES parameter.                                                **
 **                                                                        **
 ** Inputs:  ueid:      UE lower layer identifier                          **
 **      emm_cause: Authentication failure EMM cause code                  **
 **      res:       Authentication response parameter. or auts             **
 **                 in case of sync failure                                **
 **      Others:    None                                                   **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                                  **
 **      Others:    _emm_data, T3460                                       **
 **                                                                        **
 ***************************************************************************/
int emm_proc_authentication_complete(unsigned int ueid, int emm_cause,
                                     const OctetString *res)
{
  int rc;
  emm_sap_t emm_sap;

  LOG_FUNC_IN;

  LOG_TRACE(INFO, "EMM-PROC  - Authentication complete (ueid="NAS_UE_ID_FMT", cause=%d)",
            ueid, emm_cause);


  /* Release retransmission timer paramaters */
  authentication_data_t *data =
    (authentication_data_t *)(emm_proc_common_get_args(ueid));

  if (data) {
    if (data->rand.length > 0) {
      free(data->rand.value);
    }

    if (data->autn.length > 0) {
      free(data->autn.value);
    }

    free(data);
  }

  /* Get the UE context */
  emm_data_context_t *emm_ctx = NULL;
#if defined(NAS_BUILT_IN_EPC)
  if (ueid > 0) {
    emm_ctx = emm_data_context_get(&_emm_data, ueid);
  }
#else
  if (ueid < EMM_DATA_NB_UE_MAX) {
    emm_ctx = _emm_data.ctx[ueid];
  }
#endif

  if (emm_ctx) {
	/* Stop timer T3460 */
	LOG_TRACE(INFO, "EMM-PROC  - Stop timer T3460 (%d)", emm_ctx->T3460.id);
	emm_ctx->T3460.id = nas_timer_stop(emm_ctx->T3460.id);
	MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3460 stopped UE "NAS_UE_ID_FMT" ", data->ueid);
  }
  if (emm_cause == EMM_CAUSE_SUCCESS) {
    /* Check the received RES parameter */
    if ( (emm_ctx == NULL) ||
         (memcmp(res->value, &emm_ctx->vector.xres, res->length) != 0) ) {
      /* RES does not match the XRES parameter */
      LOG_TRACE(WARNING, "EMM-PROC  - Failed to authentify the UE");
      emm_cause = EMM_CAUSE_ILLEGAL_UE;
    } else {
      LOG_TRACE(DEBUG, "EMM-PROC  - Success to authentify the UE  RESP XRES == XRES UE CONTEXT");
    }
  }

  if (emm_cause != EMM_CAUSE_SUCCESS) {
    switch (emm_cause) {

#if defined(NAS_BUILT_IN_EPC)

    case EMM_CAUSE_SYNCH_FAILURE:
      /* USIM has detected a mismatch in SQN.
       * Ask for a new vector.
       */
      MSC_LOG_EVENT(
      		MSC_NAS_EMM_MME,
      	  	"0 SQN SYNCH_FAILURE ue id "NAS_UE_ID_FMT" ", ueid);

      LOG_TRACE(DEBUG, "EMM-PROC  - USIM has detected a mismatch in SQN Ask for a new vector");
      nas_itti_auth_info_req(ueid, emm_ctx->imsi, 0, res->value);

      rc = RETURNok;
      LOG_FUNC_RETURN (rc);
      break;
#endif

    default:
      LOG_TRACE(DEBUG, "EMM-PROC  - The MME received an authentication failure message or the RES does not match the XRES parameter computed by the network");
      /* The MME received an authentication failure message or the RES
       * contained in the Authentication Response message received from
       * the UE does not match the XRES parameter computed by the network */
      (void) _authentication_reject(ueid);
      /*
       * Notify EMM that the authentication procedure failed
       */
      MSC_LOG_TX_MESSAGE(
    		MSC_NAS_EMM_MME,
    	  	MSC_NAS_EMM_MME,
    	  	NULL,0,
    	  	"0 EMMREG_COMMON_PROC_REJ ue id "NAS_UE_ID_FMT" ", ueid);


      emm_sap.primitive = EMMREG_COMMON_PROC_REJ;
      emm_sap.u.emm_reg.ueid = ueid;
      emm_sap.u.emm_reg.ctx  = emm_ctx;
      break;
    }
  } else {
    /*
     * Notify EMM that the authentication procedure successfully completed
     */
    MSC_LOG_TX_MESSAGE(
    		MSC_NAS_EMM_MME,
    	  	MSC_NAS_EMM_MME,
    	  	NULL,0,
    	  	"0 EMMREG_COMMON_PROC_CNF ue id "NAS_UE_ID_FMT" ", ueid);

    LOG_TRACE(DEBUG, "EMM-PROC  - Notify EMM that the authentication procedure successfully completed");
    emm_sap.primitive = EMMREG_COMMON_PROC_CNF;
    emm_sap.u.emm_reg.ueid = ueid;
    emm_sap.u.emm_reg.ctx  = emm_ctx;
    emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached;
  }

  rc = emm_sap_send(&emm_sap);

  LOG_FUNC_RETURN (rc);
}
Пример #2
0
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_identification_complete()                            **
 **                                                                        **
 ** Description: Performs the identification completion procedure executed **
 **      by the network.                                                   **
 **                                                                        **
 **              3GPP TS 24.301, section 5.4.4.4                           **
 **      Upon receiving the IDENTITY RESPONSE message, the MME             **
 **      shall stop timer T3470.                                           **
 **                                                                        **
 ** Inputs:  ueid:      UE lower layer identifier                          **
 **      imsi:      The IMSI received from the UE                          **
 **      imei:      The IMEI received from the UE                          **
 **      tmsi:      The TMSI received from the UE                          **
 **      Others:    None                                                   **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                                  **
 **      Others:    _emm_data, T3470                                       **
 **                                                                        **
 ***************************************************************************/
int emm_proc_identification_complete(unsigned int ueid, const imsi_t *imsi,
                                     const imei_t *imei, UInt32_t *tmsi)
{
    int rc = RETURNerror;
    emm_sap_t emm_sap;

    emm_data_context_t *emm_ctx = NULL;

    LOG_FUNC_IN;

    LOG_TRACE(INFO, "EMM-PROC  - Identification complete (ueid=%u)", ueid);

    /* Stop timer T3470 */
    LOG_TRACE(INFO, "EMM-PROC  - Stop timer T3470 (%d)", T3470.id);
    T3470.id = nas_timer_stop(T3470.id);

    /* Release retransmission timer paramaters */
    identification_data_t *data =
        (identification_data_t *)(emm_proc_common_get_args(ueid));
    if (data) {
        free(data);
    }

    /* Get the UE context */
#if defined(EPC_BUILD)
    if (ueid > 0) {
        emm_ctx = emm_data_context_get(&_emm_data, ueid);
    }
#else
    if (ueid < EMM_DATA_NB_UE_MAX) {
        emm_ctx = _emm_data.ctx[ueid];
    }
#endif

    if (emm_ctx) {
        if (imsi) {
            /* Update the IMSI */
            if (emm_ctx->imsi == NULL) {
                emm_ctx->imsi = (imsi_t *)malloc(sizeof(imsi_t));
            }
            if (emm_ctx->imsi) {
                memcpy(emm_ctx->imsi, imsi, sizeof(imsi_t));
            }
        } else if (imei) {
            /* Update the IMEI */
            if (emm_ctx->imei == NULL) {
                emm_ctx->imei = (imei_t *)malloc(sizeof(imei_t));
            }
            if (emm_ctx->imei) {
                memcpy(emm_ctx->imei, imei, sizeof(imei_t));
            }
        } else if (tmsi) {
            /* Update the GUTI */
            if (emm_ctx->guti == NULL) {
                emm_ctx->guti = (GUTI_t *)malloc(sizeof(GUTI_t));
            }
            if (emm_ctx->guti) {
                memcpy(&emm_ctx->guti->gummei,
                       &_emm_data.conf.gummei, sizeof(gummei_t));
                emm_ctx->guti->m_tmsi = *tmsi;
            }
        }
        /*
         * Notify EMM that the identification procedure successfully completed
         */
        emm_sap.primitive = EMMREG_COMMON_PROC_CNF;
        emm_sap.u.emm_reg.ueid = ueid;
        emm_sap.u.emm_reg.ctx  = emm_ctx;
        emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached;
    } else {
        LOG_TRACE(ERROR, "EMM-PROC  - No EMM context exists");
        /*
         * Notify EMM that the identification procedure failed
         */
        emm_sap.primitive = EMMREG_COMMON_PROC_REJ;
        emm_sap.u.emm_reg.ueid = ueid;
        emm_sap.u.emm_reg.ctx  = emm_ctx;
    }

    rc = emm_sap_send(&emm_sap);

    LOG_FUNC_RETURN (rc);
}