Example #1
0
/*
 *-----------------------------------------------------------------------------
 *                  Process EPS Mobility Management NAS message
 *-----------------------------------------------------------------------------
 */
static int
_nas_process_emm(
  char* buffer,
  int length,
  const EMM_msg* msg)
{
  int index = 0;
  const EsmMessageContainer* esm_container = NULL;

  printf("INFO\t: Process %s\n", emmMsgType(msg->header.message_type));
  index += snprintf(buffer + index, length - index, "%s (",
                    emmMsgType(msg->header.message_type));

  switch (msg->header.message_type) {
  case ATTACH_REQUEST:
    esm_container = &msg->attach_request.esmmessagecontainer;
    index += _attach_request(buffer + index, length - index,
                             &msg->attach_request);
    break;

  case ATTACH_ACCEPT:
    esm_container = &msg->attach_accept.esmmessagecontainer;
    index += _attach_accept(buffer + index, length - index,
                            &msg->attach_accept);
    break;

  case ATTACH_REJECT:
    esm_container = &msg->attach_reject.esmmessagecontainer;
    index += _attach_reject(buffer + index, length - index,
                            &msg->attach_reject);
    break;

  case ATTACH_COMPLETE:
    esm_container = &msg->attach_complete.esmmessagecontainer;
    index += _attach_complete(buffer + index, length - index,
                              &msg->attach_complete);
    break;

  case DETACH_REQUEST:
    index += _detach_request(buffer + index, length - index,
                             &msg->detach_request);
    break;

  case DETACH_ACCEPT:
    index += _detach_accept(buffer + index, length - index,
                            &msg->detach_accept);
    break;

  case IDENTITY_REQUEST:
    index += _identity_request(buffer + index, length - index,
                               &msg->identity_request);
    break;

  case IDENTITY_RESPONSE:
    index += _identity_response(buffer + index, length - index,
                                &msg->identity_response);
    break;

  case AUTHENTICATION_REQUEST:
    index += _authentication_request(buffer + index, length - index,
                                     &msg->authentication_request);
    break;

  case AUTHENTICATION_RESPONSE:
    index += _authentication_response(buffer + index, length - index,
                                      &msg->authentication_response);
    break;

  case AUTHENTICATION_FAILURE:
    index += _authentication_failure(buffer + index, length - index,
                                     &msg->authentication_failure);
    break;

  case AUTHENTICATION_REJECT:
    index += _authentication_reject(buffer + index, length - index,
                                    &msg->authentication_reject);
    break;

  case SECURITY_MODE_COMMAND:
    index += _security_mode_command(buffer + index, length - index,
                                    &msg->security_mode_command);
    break;

  case SECURITY_MODE_COMPLETE:
    index += _security_mode_complete(buffer + index, length - index,
                                     &msg->security_mode_complete);
    break;

  case SECURITY_MODE_REJECT:
    index += _security_mode_reject(buffer + index, length - index,
                                   &msg->security_mode_reject);
    break;

  case EMM_STATUS:
    index += _emm_status(buffer + index, length - index,
                         &msg->emm_status);
    break;

  default:
    printf("WARNING\t: %s - EMM NAS message is not valid (0x%x)\n",
           __FUNCTION__, msg->header.message_type);
    break;
  }

  index += snprintf(buffer + index, length - index, ")");

  /* Process ESM message container */
  if (esm_container) {
    index += _esm_message_container(buffer + index,
                                    length - index,
                                    esm_container);
  }

  return (index);
}
/****************************************************************************
 **                                                                        **
 ** 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);
}