示例#1
0
/****************************************************************************
 **                                                                        **
 ** Name:    esm_pt_stop_timer()                                       **
 **                                                                        **
 ** Description: Stop the timer previously started for the given procedure **
 **      transaction                                               **
 **                                                                        **
 ** Inputs:  pti:       The identity of the procedure transaction  **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    _esm_pt_data                               **
 **                                                                        **
 ***************************************************************************/
int esm_pt_stop_timer(int pti)
{
  LOG_FUNC_IN;

  if ( (pti < ESM_PTI_MIN) || (pti > ESM_PTI_MAX) ) {
    LOG_FUNC_RETURN (RETURNerror);
  }

  /* Get procedure transaction data */
  esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN];

  if ( (ctx == NULL) || (ctx->pti != pti) ) {
    /* Procedure transaction not assigned */
    LOG_FUNC_RETURN (RETURNerror);
  }

  /* Stop the retransmission timer if still running */
  if (ctx->timer.id != NAS_TIMER_INACTIVE_ID) {
    LOG_TRACE(INFO, "ESM-FSM   - Stop retransmission timer %d",
              ctx->timer.id);
    ctx->timer.id = nas_timer_stop(ctx->timer.id);
  }

  /* Release the retransmisison timer parameters */
  if (ctx->args) {
    if (ctx->args->msg.length > 0) {
      free(ctx->args->msg.value);
    }

    free(ctx->args);
    ctx->args = NULL;
  }

  LOG_FUNC_RETURN (RETURNok);
}
/****************************************************************************
 **                                                                        **
 ** Name:    _authentication_abort()                                   **
 **                                                                        **
 ** Description: Aborts the authentication procedure currently in progress **
 **                                                                        **
 ** Inputs:  args:      Authentication data to be released         **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    T3460                                      **
 **                                                                        **
 ***************************************************************************/
static int
_authentication_abort (
  void *args)
{
  LOG_FUNC_IN;
  int                                     rc = RETURNerror;
  struct emm_data_context_s              *emm_ctx;
  authentication_data_t                  *data = (authentication_data_t *) (args);

  if (data) {
    unsigned int                            ueid = data->ueid;
    int                                     notify_failure = data->notify_failure;

    LOG_TRACE (WARNING, "EMM-PROC  - Abort authentication procedure " "(ueid=" NAS_UE_ID_FMT ")", ueid);
#if NAS_BUILT_IN_EPC
    emm_ctx = emm_data_context_get (&_emm_data, ueid);
#else
    emm_ctx = _emm_data.ctx[ueid];
#endif

    if (emm_ctx) {
      /*
       * Stop timer T3460
       */
      if (emm_ctx->T3460.id != NAS_TIMER_INACTIVE_ID) {
        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);
      }
    }

    /*
     * Release retransmission timer paramaters
     */
    if (data->rand.length > 0) {
      free (data->rand.value);
    }

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

    free (data);

    /*
     * Notify EMM that the authentication procedure failed
     */
    if (notify_failure) {
      emm_sap_t                               emm_sap;

      emm_sap.primitive = EMMREG_COMMON_PROC_REJ;
      emm_sap.u.emm_reg.ueid = ueid;
      rc = emm_sap_send (&emm_sap);
    } else {
      rc = RETURNok;
    }
  }

  LOG_FUNC_RETURN (rc);
}
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_detach_accept()                                  **
 **                                                                        **
 ** Description: Performs the UE initiated detach procedure for EPS servi- **
 **      ces only When the DETACH ACCEPT message is received from  **
 **      the network.                                              **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.2.2.2                         **
 **              Upon receiving the DETACH ACCEPT message, the UE shall    **
 **      stop timer T3421, locally deactivate all EPS bearer con-  **
 **      texts without peer-to-peer signalling and enter state EMM-**
 **      DEREGISTERED.                                             **
 **                                                                        **
 ** Inputs:  None                                                      **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    T3421                                      **
 **                                                                        **
 ***************************************************************************/
int emm_proc_detach_accept(void)
{
  LOG_FUNC_IN;

  int rc;

  LOG_TRACE(INFO, "EMM-PROC  - UE initiated detach procedure completion");

  /* Reset EMM procedure handler */
  (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL);

  /* Stop timer T3421 */
  T3421.id = nas_timer_stop(T3421.id);

  /*
   * Notify ESM that all EPS bearer contexts have to be locally deactivated
   */
  esm_sap_t esm_sap;
  esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ;
  esm_sap.data.eps_bearer_context_deactivate.ebi = ESM_SAP_ALL_EBI;
  rc = esm_sap_send(&esm_sap);

  /*
   * XXX - Upon receiving notification from ESM that all EPS bearer
   * contexts are locally deactivated, the UE is considered as
   * detached from the network and is entered state EMM-DEREGISTERED
   */
  LOG_FUNC_RETURN(rc);
}
示例#4
0
/****************************************************************************
 **                                                                        **
 ** Name:    _emm_attach_abnormal_cases_bcd()                          **
 **                                                                        **
 ** Description: Performs the abnormal case attach procedure.              **
 **                                                                        **
 **      3GPP TS 24.301, section 5.5.1.2.6, cases b, c and d       **
 **      The Timer T3410 shall be stopped if still running, the    **
 **      attach attempt counter shall be incremented and the UE    **
 **      shall proceed depending on whether the attach attempt     **
 **      counter reached its maximum value or not.                 **
 **                                                                        **
 ** Inputs:  None                                                      **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     emm_sap:   EMM service access point                   **
 **      Return:    None                                       **
 **      Others:    _emm_data, _emm_attach_data, T3402, T3410, **
 **             T3411                                      **
 **                                                                        **
 ***************************************************************************/
static void _emm_attach_abnormal_cases_bcd(emm_sap_t *emm_sap)
{
  LOG_FUNC_IN;

  LOG_TRACE(WARNING, "EMM-PROC  - Abnormal case, attach counter = %d",
            _emm_attach_data.attempt_count);

  /* Stop timer T3410 */
  if (T3410.id != NAS_TIMER_INACTIVE_ID) {
    LOG_TRACE(INFO, "EMM-PROC  - Stop timer T3410 (%d)", T3410.id);
    T3410.id = nas_timer_stop(T3410.id);
  }

  if (_emm_attach_data.attempt_count < EMM_ATTACH_COUNTER_MAX) {
    /* Increment the attach attempt counter */
    _emm_attach_data.attempt_count += 1;
    /* Start T3411 timer */
    T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL);
    LOG_TRACE(INFO, "EMM-PROC  - Timer T3411 (%d) expires in %ld seconds",
              T3411.id, T3411.sec);
    /*
     * Notify EMM that the attempt to attach for EPS services failed and
     * the attach attempt counter didn't reach its maximum value; network
     * attach procedure shall be restarted when timer T3411 expires.
     */
    emm_sap->primitive = EMMREG_ATTACH_FAILED;
  } else {
    /* Delete the GUTI */
    _emm_data.guti = NULL;
    /* Delete the TAI list */
    _emm_data.ltai.n_tais = 0;
    /* Delete the last visited registered TAI */
    _emm_data.tai = NULL;
    /* Delete the list of equivalent PLMNs */
    _emm_data.nvdata.eplmn.n_plmns = 0;

    /* Delete the eKSI */
    if (_emm_data.security) {
      _emm_data.security->type = EMM_KSI_NOT_AVAILABLE;
    }

    /* Set the EPS update status to EU2 NOT UPDATED */
    _emm_data.status = EU2_NOT_UPDATED;

    /* Start T3402 timer */
    T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, NULL);
    LOG_TRACE(INFO, "EMM-PROC  - Timer T3402 (%d) expires in %ld seconds",
              T3402.id, T3402.sec);
    /*
     * Notify EMM that the attempt to attach for EPS services failed and
     * the attach attempt counter reached its maximum value.
     */
    emm_sap->primitive = EMMREG_ATTACH_EXCEEDED;
  }

  LOG_FUNC_OUT;
}
/****************************************************************************
 **                                                                        **
 ** Name:    _identification_abort()                                   **
 **                                                                        **
 ** Description: Aborts the identification procedure currently in progress **
 **                                                                        **
 ** Inputs:  args:      Identification data to be released         **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    None                                       **
 **      Others:    T3470                                      **
 **                                                                        **
 ***************************************************************************/
static int _identification_abort(void *args)
{
  LOG_FUNC_IN;

  int rc = RETURNerror;

  identification_data_t *data = (identification_data_t *)(args);

  if (data) {
    unsigned int ueid = data->ueid;
    int notify_failure = data->notify_failure;
    struct emm_data_context_s *emm_ctx = NULL;
    /* Get the UE context */
  #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
    LOG_TRACE(WARNING, "EMM-PROC  - Abort identification procedure "
              "(ueid="NAS_UE_ID_FMT")", ueid);

    /* Stop timer T3470 */
    if (emm_ctx->T3470.id != NAS_TIMER_INACTIVE_ID) {
      LOG_TRACE(INFO, "EMM-PROC  - Stop timer T3470 (%d)", emm_ctx->T3470.id);
      emm_ctx->T3470.id = nas_timer_stop(emm_ctx->T3470.id);
      MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 stopped UE "NAS_UE_ID_FMT" ", data->ueid);
    }

    /* Release retransmission timer paramaters */
    free(data);

    /*
     * Notify EMM that the identification procedure failed
     */
    if (notify_failure) {
      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_t emm_sap;
      emm_sap.primitive = EMMREG_COMMON_PROC_REJ;
      emm_sap.u.emm_reg.ueid = ueid;
      rc = emm_sap_send(&emm_sap);
    } else {
      rc = RETURNok;
    }
  }

  LOG_FUNC_RETURN(rc);
}
/****************************************************************************
 **                                                                        **
 ** Name:    _emm_detach_t3421_handler()                               **
 **                                                                        **
 ** Description: T3421 timeout handler                                     **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.2.2.4 case c                  **
 **      On the first four expiries of the timer, the UE shall re- **
 **      transmit the DETACH REQUEST message and shall reset and   **
 **      restart timer T3421. On the fifth expiry of timer T3421,  **
 **      the detach procedure shall be aborted.                    **
 **                                                                        **
 ** Inputs:  args:      handler parameters                         **
 **      Others:    _emm_detach_data                           **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    None                                       **
 **      Others:    None                                       **
 **                                                                        **
 ***************************************************************************/
void *_emm_detach_t3421_handler(void *args)
{
  LOG_FUNC_IN;

  int rc;

  /* Increment the retransmission counter */
  _emm_detach_data.count += 1;

  LOG_TRACE(WARNING, "EMM-PROC  - T3421 timer expired, "
            "retransmission counter = %d", _emm_detach_data.count);

  if (_emm_detach_data.count < EMM_DETACH_COUNTER_MAX) {
    /* Retransmit the Detach Request message */
    emm_sap_t emm_sap;
    emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data;

    /* Stop timer T3421 */
    T3421.id = nas_timer_stop(T3421.id);

    /* Setup NAS information message to transfer */
    emm_as->NASinfo = EMM_AS_NAS_INFO_DETACH;
    emm_as->NASmsg.length = 0;
    emm_as->NASmsg.value = NULL;
    /* Set the detach type */
    emm_as->type = _emm_detach_data.type;
    /* Set the switch-off indicator */
    emm_as->switch_off = _emm_detach_data.switch_off;
    /* Set the EPS mobile identity */
    emm_as->guti = _emm_data.guti;
    emm_as->ueid = 0;
    /* Setup EPS NAS security data */
    emm_as_set_security_data(&emm_as->sctx, _emm_data.security,
                             FALSE, TRUE);

    /*
     * Notify EMM-AS SAP that Detach Request message has to
     * be sent to the network
     */
    emm_sap.primitive = EMMAS_DATA_REQ;
    rc = emm_sap_send(&emm_sap);

    if (rc != RETURNerror) {
      /* Start T3421 timer */
      T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL);
      LOG_TRACE(INFO, "EMM-PROC  - Timer T3421 (%d) expires in %ld "
                "seconds", T3421.id, T3421.sec);
    }
  } else {
    /* Abort the detach procedure */
    rc = _emm_detach_abort(_emm_detach_data.type);
  }

  LOG_FUNC_RETURN(NULL);
}
/****************************************************************************
 **                                                                        **
 ** Name:        _emm_tau_t3430_handler()                                  **
 **                                                                        **
 ** Description: T3430 timeout handler                                     **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.3.2.6 case c                  **
 **                                                                        **
 ** Inputs:      args:          handler parameters                         **
 **              Others:        None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **              Return:        None                                       **
 **              Others:        None                                       **
 **                                                                        **
 ***************************************************************************/
void *_emm_tau_t3430_handler(void *args)
{
  LOG_FUNC_IN;

  LOG_TRACE(WARNING, "EMM-PROC  - T3430 timer expired");

  /* Stop timer T3430 */
  T3430.id = nas_timer_stop(T3430.id);

  LOG_FUNC_RETURN(NULL);
}
示例#8
0
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_attach_failure()                                 **
 **                                                                        **
 ** Description: Performs the attach procedure abnormal case upon receipt  **
 **      of transmission failure of Attach Request message or At-  **
 **      tach Complete message.                                    **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.1.2.6, cases h and i          **
 **      The  UE  shall restart the attach  procedure when timer   **
 **      T3411 expires.                                            **
 **                                                                        **
 ** Inputs:  is_initial:    TRUE if the NAS message that failed to be  **
 **             transfered is an initial NAS message (ESM  **
 **             message embedded within an Attach Request  **
 **             message)                                   **
 **          args:      Not used                                   **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    T3410, T3411                               **
 **                                                                        **
 ***************************************************************************/
int emm_proc_attach_failure(int is_initial, void *args)
{
  LOG_FUNC_IN;

  int rc = RETURNok;
  esm_sap_t esm_sap;

  LOG_TRACE(WARNING, "EMM-PROC  - EPS attach failure");

  /* Reset EMM procedure handler */
  (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL);

  /* Stop timer T3410 if still running */
  if (T3410.id != NAS_TIMER_INACTIVE_ID) {
    LOG_TRACE(INFO, "EMM-PROC  - Stop timer T3410 (%d)", T3410.id);
    T3410.id = nas_timer_stop(T3410.id);
  }

  if (is_initial) {
    /*
     * Notify ESM that the PDN CONNECTIVITY REQUEST message contained
     * in the ESM message container IE of the ATTACH REQUEST has failed
     * to be transmitted
     */
    esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ;
    esm_sap.is_standalone = FALSE;
    esm_sap.recv = NULL;
  } else {
    /*
     * Notify ESM that ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST message
     * contained in the ESM message container IE of the ATTACH COMPLETE
     * has failed to be transmitted
     */
    esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REJ;
    esm_sap.is_standalone = FALSE;
    esm_sap.recv = NULL;
  }

  rc = esm_sap_send(&esm_sap);

  if (rc != RETURNerror) {
    /* Start T3411 timer */
    T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL);
    LOG_TRACE(INFO, "EMM-PROC  - Timer T3411 (%d) expires in %ld seconds",
              T3411.id, T3411.sec);
  }

  LOG_FUNC_RETURN(rc);
}
示例#9
0
/****************************************************************************
 **                                                                        **
 ** Name:    _emm_attach_t3411_handler()                               **
 **                                                                        **
 ** Description: T3411 timeout handler                                     **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.1.2.6                         **
 **      Upon T3411 timer expiration, the attach procedure shall   **
 **      be restarted, if still required by ESM sublayer.          **
 **                                                                        **
 ** Inputs:  args:      handler parameters                         **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    None                                       **
 **      Others:    T3411                                      **
 **                                                                        **
 ***************************************************************************/
static void *_emm_attach_t3411_handler(void *args)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;

  LOG_TRACE(WARNING, "EMM-PROC  - T3411 timer expired");

  /* Stop T3411 timer */
  T3411.id = nas_timer_stop(T3411.id);
  /*
   * Notify EMM that timer T3411 expired and attach procedure has to be
   * restarted
   */
  emm_sap.primitive = EMMREG_ATTACH_INIT;
  emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency;

  (void) emm_sap_send(&emm_sap);

  LOG_FUNC_RETURN(NULL);
}
示例#10
0
/****************************************************************************
 **                                                                        **
 ** Name:    _identification_abort()                                   **
 **                                                                        **
 ** Description: Aborts the identification procedure currently in progress **
 **                                                                        **
 ** Inputs:  args:      Identification data to be released         **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    None                                       **
 **      Others:    T3470                                      **
 **                                                                        **
 ***************************************************************************/
static int _identification_abort(void *args)
{
    LOG_FUNC_IN;

    int rc = RETURNerror;

    identification_data_t *data = (identification_data_t *)(args);

    if (data) {
        unsigned int ueid = data->ueid;
        int notify_failure = data->notify_failure;

        LOG_TRACE(WARNING, "EMM-PROC  - Abort identification procedure "
                  "(ueid=%u)", ueid);

        /* Stop timer T3470 */
        if (T3470.id != NAS_TIMER_INACTIVE_ID) {
            LOG_TRACE(INFO, "EMM-PROC  - Stop timer T3470 (%d)", T3470.id);
            T3470.id = nas_timer_stop(T3470.id);
        }
        /* Release retransmission timer paramaters */
        free(data);

        /*
         * Notify EMM that the identification procedure failed
         */
        if (notify_failure) {
            emm_sap_t emm_sap;
            emm_sap.primitive = EMMREG_COMMON_PROC_REJ;
            emm_sap.u.emm_reg.ueid = ueid;
            rc = emm_sap_send(&emm_sap);
        } else {
            rc = RETURNok;
        }
    }

    LOG_FUNC_RETURN(rc);
}
示例#11
0
/****************************************************************************
 **                                                                        **
 ** Name:    _emm_attach_t3410_handler()                               **
 **                                                                        **
 ** Description: T3410 timeout handler                                     **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.1.2.6, case c                 **
 **      Upon T3410 timer expiration, the attach procedure shall   **
 **      be aborted and the UE shall execute abnormal case attach  **
 **      procedure.                                                **
 **      The NAS signalling connection shall be released locally.  **
 **                                                                        **
 ** Inputs:  args:      handler parameters                         **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    None                                       **
 **      Others:    T3410                                      **
 **                                                                        **
 ***************************************************************************/
void *_emm_attach_t3410_handler(void *args)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;
  int rc;

  LOG_TRACE(WARNING, "EMM-PROC  - T3410 timer expired");

  /* Stop T3410 timer */
  T3410.id = nas_timer_stop(T3410.id);
  /* Execute abnormal case attach procedure */
  _emm_attach_abnormal_cases_bcd(&emm_sap);

  rc = emm_sap_send(&emm_sap);

  if (rc != RETURNerror) {
    /* Locally release the NAS signalling connection */
    _emm_data.ecm_status = ECM_IDLE;
  }

  LOG_FUNC_RETURN(NULL);
}
/****************************************************************************
 **                                                                        **
 ** Name:    _emm_detach_abort()                                       **
 **                                                                        **
 ** Description: Aborts the detach procedure                               **
 **                                                                        **
 ** Inputs:  type:      not used                                   **
 **      Others:    _emm_detach_data                           **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    T3421                                      **
 **                                                                        **
 ***************************************************************************/
static int _emm_detach_abort(emm_proc_detach_type_t type)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;
  int rc ;

  LOG_TRACE(WARNING, "EMM-PROC  - Abort the detach procedure");

  /* Reset EMM procedure handler */
  (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL);

  /* Stop timer T3421 */
  T3421.id = nas_timer_stop(T3421.id);

  /*
   * Notify EMM that detach procedure failed
   */
  emm_sap.primitive = EMMREG_DETACH_FAILED;
  emm_sap.u.emm_reg.u.detach.type = type;
  rc = emm_sap_send(&emm_sap);

  LOG_FUNC_RETURN (rc);
}
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_detach_failure()                                 **
 **                                                                        **
 ** Description: Performs the detach procedure abnormal case upon receipt  **
 **          of transmission failure of Detach Request message.        **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.2.2.4, case h                 **
 **      The UE shall restart the detach procedure.                **
 **                                                                        **
 ** Inputs:  is_initial:    Not used                                   **
 **          args:      Not used                                   **
 **      Others:    _emm_detach_data                           **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    None                                       **
 **                                                                        **
 ***************************************************************************/
int emm_proc_detach_failure(int is_initial, void *args)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;
  int rc;

  LOG_TRACE(WARNING, "EMM-PROC  - Network detach failure");

  /* Reset EMM procedure handler */
  (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL);

  /* Stop timer T3421 */
  T3421.id = nas_timer_stop(T3421.id);

  /*
   * Notify EMM that detach procedure has to be restarted
   */
  emm_sap.primitive = EMMREG_DETACH_INIT;
  emm_sap.u.emm_reg.u.detach.switch_off = _emm_detach_data.switch_off;
  rc = emm_sap_send(&emm_sap);

  LOG_FUNC_RETURN(rc);
}
示例#14
0
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_attach_reject()                                  **
 **                                                                        **
 ** Description: Performs the attach procedure rejected by the network.    **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.1.2.5                         **
 **      Upon receiving the ATTACH REJECT message, the UE shall    **
 **      stop timer T3410 and take actions depending on the EMM    **
 **      cause value received.                                     **
 **                                                                        **
 ** Inputs:  emm_cause: EMM cause indicating why the network re-   **
 **             jected the attach request                  **
 **      esm_msg_pP:   PDN connectivity reject ESM message        **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    _emm_data, _emm_attach_data, T3410         **
 **                                                                        **
 ***************************************************************************/
int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;
  int rc;

  LOG_TRACE(WARNING, "EMM-PROC  - EPS attach rejected by the network, "
            "EMM cause = %d", emm_cause);

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

  /* Update the EPS update status, the GUTI, the visited registered TAI and
   * the eKSI */
  switch (emm_cause) {
  case EMM_CAUSE_ILLEGAL_UE:
  case EMM_CAUSE_ILLEGAL_ME:
  case EMM_CAUSE_EPS_NOT_ALLOWED:
  case EMM_CAUSE_BOTH_NOT_ALLOWED:
  case EMM_CAUSE_PLMN_NOT_ALLOWED:
  case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN:
  case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN:
  case EMM_CAUSE_TA_NOT_ALLOWED:
  case EMM_CAUSE_ROAMING_NOT_ALLOWED:
  case EMM_CAUSE_NO_SUITABLE_CELLS:
    /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */
    _emm_data.status = EU3_ROAMING_NOT_ALLOWED;
    /* Delete the GUTI */
    _emm_data.guti = NULL;
    /* Delete the last visited registered TAI */
    _emm_data.tai = NULL;

    /* Delete the eKSI */
    if (_emm_data.security) {
      _emm_data.security->type = EMM_KSI_NOT_AVAILABLE;
    }

    break;

  default :
    break;
  }

  /* Update list of equivalents PLMNs and attach attempt counter */
  switch (emm_cause) {
  case EMM_CAUSE_ILLEGAL_UE:
  case EMM_CAUSE_ILLEGAL_ME:
  case EMM_CAUSE_EPS_NOT_ALLOWED:
  case EMM_CAUSE_BOTH_NOT_ALLOWED:
    /* Consider the USIM as invalid for EPS services */
    _emm_data.usim_is_valid = FALSE;
    /* Delete the list of equivalent PLMNs */
    _emm_data.nvdata.eplmn.n_plmns = 0;
    break;

  case EMM_CAUSE_PLMN_NOT_ALLOWED:
  case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN:
  case EMM_CAUSE_ROAMING_NOT_ALLOWED:
    /* Delete the list of equivalent PLMNs */
    _emm_data.nvdata.eplmn.n_plmns = 0;
    /* Reset the attach attempt counter */
    _emm_attach_data.attempt_count = 0;
    break;

  case EMM_CAUSE_TA_NOT_ALLOWED:
  case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN:
  case EMM_CAUSE_NO_SUITABLE_CELLS:
    /* Reset the attach attempt counter */
    _emm_attach_data.attempt_count = 0;
    break;

  case EMM_CAUSE_ESM_FAILURE:

    /* 3GPP TS 24.301, section 5.5.1.2.6, case d */
    if (_emm_data.NAS_SignallingPriority != 1) {
      /* The UE is not configured for NAS signalling low priority;
       * set the attach attempt counter to 5 */
      _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX;
    }

    break;

  case EMM_CAUSE_SEMANTICALLY_INCORRECT:
  case EMM_CAUSE_INVALID_MANDATORY_INFO:
  case EMM_CAUSE_MESSAGE_TYPE_NOT_IMPLEMENTED:
  case EMM_CAUSE_IE_NOT_IMPLEMENTED:
  case EMM_CAUSE_PROTOCOL_ERROR:
    /* 3GPP TS 24.301, section 5.5.1.2.6, case d
     * Set the attach attempt counter to 5 */
    _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX;
    break;

  default :
    break;
  }

  /* Update "forbidden lists" */
  switch (emm_cause) {
  case EMM_CAUSE_PLMN_NOT_ALLOWED:
  case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN:
    /* Store the PLMN identity in the "forbidden PLMN list" */
    _emm_data.fplmn.plmn[_emm_data.fplmn.n_plmns++] = _emm_data.splmn;
    break;

  case EMM_CAUSE_TA_NOT_ALLOWED:
    /* Store the current TAI in the list of "forbidden tracking
     * areas for regional provision of service" */
    _emm_data.ftai.tai[_emm_data.ftai.n_tais++] = *_emm_data.tai;
    break;

  case EMM_CAUSE_ROAMING_NOT_ALLOWED:
    /* Store the current TAI in the list of "forbidden tracking
     * areas for roaming" */
    _emm_data.ftai_roaming.tai[_emm_data.ftai_roaming.n_tais++] = *_emm_data.tai;
    break;

  case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN:
    /* Store the PLMN identity in the "forbidden PLMNs for GPRS
     * service" list */
    _emm_data.fplmn_gprs.plmn[_emm_data.fplmn_gprs.n_plmns++] = _emm_data.splmn;
    break;

  default :
    break;
  }

  /* Update state of EMM sublayer */
  switch (emm_cause) {
  case EMM_CAUSE_ILLEGAL_UE:
  case EMM_CAUSE_ILLEGAL_ME:
  case EMM_CAUSE_EPS_NOT_ALLOWED:
  case EMM_CAUSE_BOTH_NOT_ALLOWED:
    /*
     * Notify EMM that EPS attach is rejected
     */
    emm_sap.primitive = EMMREG_ATTACH_REJ;
    break;

  case EMM_CAUSE_PLMN_NOT_ALLOWED:
  case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN:
  case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN:
    /*
     * Notify EMM that the UE has to perform a PLMN selection because
     * it is not allowed to operate in the currently selected PLMN
     */
    emm_sap.primitive = EMMREG_REGISTER_REQ;
    break;

  case EMM_CAUSE_TA_NOT_ALLOWED:
  case EMM_CAUSE_ROAMING_NOT_ALLOWED:
  case EMM_CAUSE_NO_SUITABLE_CELLS:
    /*
     * Notify EMM that the UE failed to register to the network for
     * EPS services because it is not allowed to operate in the
     * requested tracking area
     */
    emm_sap.primitive = EMMREG_REGISTER_REJ;
    break;

  case EMM_CAUSE_IMEI_NOT_ACCEPTED:
    if (_emm_data.is_emergency) {
      /*
       * Notify EMM that the UE failed to register to the network
       * for emergency bearer services because "IMEI not accepted"
       */
      emm_sap.primitive = EMMREG_NO_IMSI;
      break;
    }

    /* break is volontary missing */

  default :
    /* Other values are considered as abnormal cases
     * 3GPP TS 24.301, section 5.5.1.2.6, case d */
    _emm_attach_abnormal_cases_bcd(&emm_sap);
    break;
  }

  rc = emm_sap_send(&emm_sap);

  /*
   * Notify ESM that the network rejected connectivity to the PDN
   */
  if (esm_msg_pP != NULL) {
    esm_sap_t esm_sap;
    esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ;
    esm_sap.is_standalone = FALSE;
    esm_sap.recv = esm_msg_pP;
    rc = esm_sap_send(&esm_sap);
  }

  LOG_FUNC_RETURN(rc);
}
示例#15
0
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_attach_accept()                                  **
 **                                                                        **
 ** Description: Performs the attach procedure accepted by the network.    **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.1.2.4                         **
 **      Upon receiving the ATTACH ACCEPT message, the UE shall    **
 **      stop timer T3410 and send an ATTACH COMPLETE message to   **
 **      the MME.                                                  **
 **                                                                        **
 ** Inputs:  t3412:     Value of the T3412 timer in seconds        **
 **      t3402:     Value of the T3402 timer in seconds        **
 **      t3423:     Value of the T3423 timer in seconds        **
 **      n_tais:    Number of tracking area identities contai- **
 **             ned in the TAI list                        **
 **      tai:       The TAI list that identifies the tracking  **
 **             areas the UE is registered to              **
 **      guti:      New UE's temporary identity assigned by    **
 **             the MME (GUTI reallocation)                **
 **      n_eplmns:  Number of equivalent PLMNs                 **
 **      eplmns:    List of equivalent PLMNs                   **
 **      esm_msg_pP:   Activate default EPS bearer context re-    **
 **             quest ESM message                          **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    _emm_data, T3412, T3402, T3423             **
 **                                                                        **
 ***************************************************************************/
int emm_proc_attach_accept(long t3412, long t3402, long t3423,
                           int n_tais, tai_t *tai, GUTI_t *guti,
                           int n_eplmns, plmn_t *eplmn,
                           const OctetString *esm_msg_pP)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;
  esm_sap_t esm_sap;
  int rc;
  int i;
  int j;

  LOG_TRACE(INFO, "EMM-PROC  - EPS attach accepted by the network");

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

  /* Delete old TAI list and store the received TAI list */
  _emm_data.ltai.n_tais = n_tais;

  for (i = 0; (i < n_tais) && (i < EMM_DATA_TAI_MAX); i++) {
    _emm_data.ltai.tai[i] = tai[i];
  }

  /* Update periodic tracking area update timer value */
  T3412.sec = t3412;

  /* Update attach failure timer value */
  if ( !(t3402 < 0) ) {
    T3402.sec = t3402;
  }

  /* Update E-UTRAN deactivate ISR timer value */
  if ( !(t3423 < 0) ) {
    T3423.sec = t3423;
  }

  /* Delete old GUTI and store the new assigned GUTI if provided */
  if (guti) {
    *_emm_data.guti = *guti;
  }

  /* Update the stored list of equivalent PLMNs */
  _emm_data.nvdata.eplmn.n_plmns = 0;

  if (n_eplmns > 0) {
    for (i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) {
      int is_forbidden = FALSE;

      if (!_emm_data.is_emergency) {
        /* If the attach procedure is not for emergency bearer
         * services, the UE shall remove from the list any PLMN
         * code that is already in the list of forbidden PLMNs */
        for (j = 0; j < _emm_data.fplmn.n_plmns; j++) {
          if (PLMNS_ARE_EQUAL(eplmn[i], _emm_data.fplmn.plmn[j])) {
            is_forbidden = TRUE;
            break;
          }
        }
      }

      if ( !is_forbidden ) {
        _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] =
          eplmn[i];
      }
    }

    /* Add the PLMN code of the registered PLMN that sent the list */
    if (_emm_data.nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) {
      _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] =
        _emm_data.splmn;
    }
  }

  /*
   * Notify ESM that a default EPS bearer has to be activated
   */
  esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ;
  esm_sap.is_standalone = FALSE;
  esm_sap.recv = esm_msg_pP;
  rc = esm_sap_send(&esm_sap);

  if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) {
    /* Setup EMM procedure handler to be executed upon receiving
     * lower layer notification */
    rc = emm_proc_lowerlayer_initialize(emm_proc_attach_complete,
                                        emm_proc_attach_failure,
                                        NULL, NULL);

    if (rc != RETURNok) {
      LOG_TRACE(WARNING,
                "EMM-PROC  - Failed to initialize EMM procedure handler");
      LOG_FUNC_RETURN (RETURNerror);
    }

    /*
     * Notify EMM-AS SAP that Attach Complete message together with
     * an Activate Default EPS Bearer Context Accept message has to
     * be sent to the network
     */
    emm_sap.primitive = EMMAS_DATA_REQ;
    emm_sap.u.emm_as.u.data.guti = _emm_data.guti;
    emm_sap.u.emm_as.u.data.ueid = 0;
    /* Setup EPS NAS security data */
    emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx,
                             _emm_data.security, FALSE, TRUE);
    /* Get the activate default EPS bearer context accept message
     * to be transfered within the ESM container of the attach
     * complete message */
    emm_sap.u.emm_as.u.data.NASinfo = EMM_AS_NAS_DATA_ATTACH;
    emm_sap.u.emm_as.u.data.NASmsg = esm_sap.send;
    rc = emm_sap_send(&emm_sap);
  } else if (esm_sap.err != ESM_SAP_DISCARDED) {
    /* 3GPP TS 24.301, section 5.5.1.2.6, case j
     * If the ACTIVATE DEFAULT BEARER CONTEXT REQUEST message combined
     * with the ATTACH ACCEPT is not accepted by the UE due to failure
     * in the UE ESM sublayer, then the UE shall initiate the detach
     * procedure by sending a DETACH REQUEST message to the network.
     */
    emm_sap.primitive = EMMREG_DETACH_INIT;
    rc = emm_sap_send(&emm_sap);
  } else {
    /*
     * ESM procedure failed and, received message has been discarded or
     * Status message has been returned; ignore ESM procedure failure
     */
    rc = RETURNok;
  }

  LOG_FUNC_RETURN(rc);
}
示例#16
0
/****************************************************************************
 **                                                                        **
 ** Name:    emm_proc_attach()                                         **
 **                                                                        **
 ** Description: Initiate EPS attach procedure to register a UE in PS mode **
 **      of operation for EPS services only, or register a UE for  **
 **      emergency bearer services.                                **
 **                                                                        **
 **              3GPP TS 24.301, section 5.5.1.2.2                         **
 **      In state EMM-DEREGISTERED, the UE initiates the attach    **
 **      procedure by sending an ATTACH REQUEST message to the MME,**
 **      starting timer T3410 and entering state EMM-REGISTERED-   **
 **      INITIATED.                                                **
 **                                                                        **
 ** Inputs:  type:      Type of the requested attach               **
 **      Others:    _emm_data                                  **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    T3402, T3410, T3411                        **
 **                                                                        **
 ***************************************************************************/
int emm_proc_attach(emm_proc_attach_type_t type)
{
  LOG_FUNC_IN;

  emm_sap_t emm_sap;
  emm_as_establish_t *emm_as = &emm_sap.u.emm_as.u.establish;
  esm_sap_t esm_sap;
  int rc;

  LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach type = %s (%d)",
            _emm_attach_type_str[type], type);

  /* Update the emergency bearer service indicator */
  if (type == EMM_ATTACH_TYPE_EMERGENCY) {
    _emm_data.is_emergency = TRUE;
  }

  /* Setup initial NAS information message to transfer */
  emm_as->NASinfo = EMM_AS_NAS_INFO_ATTACH;
  /* Set the attach type */
  emm_as->type = type;

  /* Set the RRC connection establishment cause */
  if (_emm_data.is_emergency) {
    emm_as->RRCcause = NET_ESTABLISH_CAUSE_EMERGENCY;
    emm_as->RRCtype = NET_ESTABLISH_TYPE_EMERGENCY_CALLS;
  } else {
    emm_as->RRCcause = NET_ESTABLISH_CAUSE_MO_SIGNAL;
    emm_as->RRCtype = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL;
  }

  /* Set the PLMN identifier of the selected PLMN */
  emm_as->plmnID = &_emm_data.splmn;
  /*
   * Process the EPS mobile identity
   */
  emm_as->UEid.guti = NULL;
  emm_as->UEid.tai  = NULL;
  emm_as->UEid.imsi = NULL;
  emm_as->UEid.imei = NULL;

  /* Check whether the UE is configured for "AttachWithIMSI" */
  if (_emm_data.AttachWithImsi) {
    /* Check whether the selected PLMN is neither the registered PLMN
     * nor in the list of equivalent PLMNs */
    if ( (!_emm_data.is_rplmn) && (!_emm_data.is_eplmn) ) {
      LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI");
      /* Include the IMSI */
      emm_as->UEid.imsi = _emm_data.imsi;
    } else {
      LOG_TRACE(INFO,
                "EMM-PROC  - Initiate EPS attach with NO IMSI, is registered PLMN %d, is equivalent PLMN %d",
                _emm_data.is_rplmn,
                _emm_data.is_eplmn);
    }
  } else if (_emm_data.guti) {
    LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with GUTI");
    /* Include a valid GUTI and the last visited registered TAI */
    emm_as->UEid.guti = _emm_data.guti;
    emm_as->UEid.tai = _emm_data.tai;
  } else if (!_emm_data.is_emergency) {
    LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI cause is no emergency and no GUTI");
    /* Include the IMSI if no valid GUTI is available */
    emm_as->UEid.imsi = _emm_data.imsi;
  } else {
    /* The UE is attaching for emergency bearer services and
     * does not hold a valid GUTI */
    if (_emm_data.imsi) {
      /* Include the IMSI if valid (USIM is present) */
      LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI cause is emergency and no GUTI");
      emm_as->UEid.imsi = _emm_data.imsi;
    } else {
      LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI cause is emergency and no GUTI and no IMSI");
      /* Include the IMEI if the IMSI is not valid */
      emm_as->UEid.imei = _emm_data.imei;
    }
  }

  /* Setup EPS NAS security data */
  emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, FALSE);
  emm_as->ksi = EMM_AS_NO_KEY_AVAILABLE;

  if (_emm_data.security) {
    if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) {
      emm_as->ksi = _emm_data.security->eksi;
    }

    LOG_TRACE(INFO, "EMM-PROC  - eps_encryption 0x%X", _emm_data.security->capability.eps_encryption);
    LOG_TRACE(INFO, "EMM-PROC  - eps_integrity  0x%X", _emm_data.security->capability.eps_integrity);
    emm_as->encryption = _emm_data.security->capability.eps_encryption;
    emm_as->integrity = _emm_data.security->capability.eps_integrity;
  }

  /*
   * Notify ESM that initiation of a PDN connectivity procedure
   * is requested to setup a default EPS bearer
   */
  esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ;
  esm_sap.is_standalone = FALSE;
  esm_sap.data.pdn_connect.is_defined = TRUE;
  esm_sap.data.pdn_connect.cid = 1;
  /* TODO: PDN type should be set according to the IP capability of the UE */
  esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4V6;
  esm_sap.data.pdn_connect.apn = NULL;
  esm_sap.data.pdn_connect.is_emergency = _emm_data.is_emergency;
  rc = esm_sap_send(&esm_sap);

  if (rc != RETURNerror) {
    /* Setup EMM procedure handler to be executed upon receiving
     * lower layer notification */
    rc = emm_proc_lowerlayer_initialize(emm_proc_attach_request,
                                        emm_proc_attach_failure,
                                        emm_proc_attach_release, NULL);

    if (rc != RETURNok) {
      LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler");
      LOG_FUNC_RETURN (RETURNerror);
    }

    /* Start T3410 timer */
    T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL);
    LOG_TRACE(INFO,"EMM-PROC  - Timer T3410 (%d) expires in %ld seconds",
              T3410.id, T3410.sec);
    /* Stop T3402 and T3411 timers if running */
    T3402.id = nas_timer_stop(T3402.id);
    T3411.id = nas_timer_stop(T3411.id);

    /*
     * Notify EMM-AS SAP that a RRC connection establishment procedure
     * is requested from the Access-Stratum to send initial NAS message
     * attach request to the network
     */
    emm_sap.primitive = EMMAS_ESTABLISH_REQ;
    /* Get the PDN connectivity request to transfer within the ESM
     * container of the initial attach request message */
    emm_sap.u.emm_as.u.establish.NASmsg = esm_sap.send;
    rc = emm_sap_send(&emm_sap);
  }

  LOG_FUNC_RETURN(rc);
}
/****************************************************************************
 **                                                                        **
 ** 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);
}
示例#18
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);
}