Exemplo n.º 1
0
static
  int
s1ap_mme_compare_plmn (
  S1ap_PLMNidentity_t * plmn)
{
  int                                     i;
  uint16_t                                mcc;
  uint16_t                                mnc;
  uint16_t                                mnc_len;

  DevAssert (plmn != NULL);
  TBCD_TO_MCC_MNC (plmn, mcc, mnc, mnc_len);
  config_read_lock (&mme_config);

  for (i = 0; i < mme_config.gummei.nb_mme_gid; i++) {
    S1AP_DEBUG ("Comparing plmn_mcc %d/%d, plmn_mnc %d/%d plmn_mnc_len %d/%d\n", mme_config.gummei.plmn_mcc[i], mcc, mme_config.gummei.plmn_mnc[i], mnc, mme_config.gummei.plmn_mnc_len[i], mnc_len);

    if ((mme_config.gummei.plmn_mcc[i] == mcc) && (mme_config.gummei.plmn_mnc[i] == mnc) && (mme_config.gummei.plmn_mnc_len[i] == mnc_len))
      /*
       * There is a matching plmn
       */
      return TA_LIST_AT_LEAST_ONE_MATCH;
  }

  config_unlock (&mme_config);
  return TA_LIST_NO_MATCH;
}
Exemplo n.º 2
0
int s1ap_mme_decode_pdu(s1ap_message *message, uint8_t *buffer, uint32_t len) {
    S1AP_PDU_t  pdu;
    S1AP_PDU_t *pdu_p = &pdu;
    asn_dec_rval_t dec_ret;

    assert(buffer != NULL);

    memset((void *)pdu_p, 0, sizeof(S1AP_PDU_t));

    dec_ret = aper_decode(NULL,
                          &asn_DEF_S1AP_PDU,
                          (void**)&pdu_p,
                          buffer,
                          len,
                          0,
                          0);

    if (dec_ret.code != RC_OK)
        return -1;

    message->direction = pdu_p->present;

    switch(pdu_p->present) {
        case S1AP_PDU_PR_initiatingMessage:
            return s1ap_mme_decode_initiating(message, &pdu_p->choice.initiatingMessage);
        case S1AP_PDU_PR_successfulOutcome:
            return s1ap_mme_decode_successfull_outcome(message, &pdu_p->choice.successfulOutcome);
        case S1AP_PDU_PR_unsuccessfulOutcome:
            return s1ap_mme_decode_unsuccessfull_outcome(message, &pdu_p->choice.unsuccessfulOutcome);
        default:
            S1AP_DEBUG("Unknown message outcome (%d) or not implemented", (int)pdu_p->present);
            break;
    }
    return -1;
}
static inline
int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p,
    uint8_t **buffer, uint32_t *len)
{
    int ret = -1;
    MessageDef *message_p;
    char       *message_string = NULL;
    size_t      message_string_size;
    MessagesIds message_id;

    DevAssert(s1ap_message_p != NULL);

    message_string = calloc(10000, sizeof(char));

    s1ap_string_total_size = 0;
    message_string_size = strlen(message_string);


    switch(s1ap_message_p->procedureCode) {
    case S1ap_ProcedureCode_id_InitialContextSetup:
        ret = s1ap_eNB_encode_initial_context_setup_response(
            &s1ap_message_p->msg.s1ap_InitialContextSetupResponseIEs, buffer, len);

        s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, s1ap_message_p);
        message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG;
        message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
        message_p->ittiMsg.s1ap_initial_context_setup_log.size = message_string_size;
        memcpy(&message_p->ittiMsg.s1ap_initial_context_setup_log.text, message_string, message_string_size);
        itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
        free(message_string);
        break;

    case S1ap_ProcedureCode_id_UEContextRelease:
        ret = s1ap_eNB_encode_ue_context_release_complete(
            &s1ap_message_p->msg.s1ap_UEContextReleaseCompleteIEs, buffer, len);
        s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, s1ap_message_p);
        message_id = S1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG;
        message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
        message_p->ittiMsg.s1ap_ue_context_release_complete_log.size = message_string_size;
        memcpy(&message_p->ittiMsg.s1ap_ue_context_release_complete_log.text, message_string, message_string_size);
        itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
        free(message_string);
        break;

        default:
            S1AP_DEBUG("Unknown procedure ID (%d) for successfull outcome message\n",
                       (int)s1ap_message_p->procedureCode);
            return ret;
            break;
    }


    return ret;
}
Exemplo n.º 4
0
static int s1ap_mme_decode_unsuccessfull_outcome(s1ap_message *message, UnsuccessfulOutcome_t *unSuccessfulOutcome_p) {

    assert(unSuccessfulOutcome_p != NULL);
    message->procedureCode = unSuccessfulOutcome_p->procedureCode;
    switch(unSuccessfulOutcome_p->procedureCode) {
        case ProcedureCode_id_InitialContextSetup:
            return s1ap_decode_initialcontextsetupfailureies(&message->msg.initialContextSetupFailureIEs, &unSuccessfulOutcome_p->value);
        default:
            S1AP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message", (int)unSuccessfulOutcome_p->procedureCode);
            break;
    }
    return -1;
}
Exemplo n.º 5
0
int s1ap_eNB_init(const char *mme_ip_address, const uint8_t eNB_id) {
    uint8_t args = eNB_id;
    if (sctp_connect_to_remote_host(
        mme_ip_address, 36412, &args,
        s1ap_sctp_connected_callback,
        s1ap_sctp_recv_callback) < 0)
    {
        S1AP_ERROR("[eNB %02d] Failed to setup SCTP\n", eNB_id);
        return -1;
    }

    S1AP_DEBUG("[eNB %02d] successfully connected to MME\n", eNB_id);
    return 0;
}
Exemplo n.º 6
0
static int s1ap_mme_decode_successfull_outcome(s1ap_message *message, SuccessfulOutcome_t *successfullOutcome_p) {

    assert(successfullOutcome_p != NULL);
    message->procedureCode = successfullOutcome_p->procedureCode;
    switch(successfullOutcome_p->procedureCode) {
        case ProcedureCode_id_InitialContextSetup:
            return s1ap_decode_initialcontextsetupresponseies(&message->msg.initialContextSetupResponseIEs, &successfullOutcome_p->value);
        case ProcedureCode_id_UEContextRelease:
            return s1ap_decode_uecontextreleasecompleteies(&message->msg.ueContextReleaseCompleteIEs, &successfullOutcome_p->value);
        default:
            S1AP_DEBUG("Unknown procedure ID (%d) for successfull outcome message", (int)successfullOutcome_p->procedureCode);
            break;
    }
    return -1;
}
static inline
int s1ap_mme_encode_unsuccessfull_outcome(s1ap_message *message_p,
    uint8_t **buffer, uint32_t *length)
{
  switch(message_p->procedureCode) {
  case S1ap_ProcedureCode_id_S1Setup:
    return s1ap_mme_encode_s1setupfailure(message_p, buffer, length);

  default:
    S1AP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
               (int)message_p->procedureCode);
    break;
  }

  return -1;
}
Exemplo n.º 8
0
static int s1ap_mme_decode_initiating(s1ap_message *message, InitiatingMessage_t *initiating_p) {

    assert(initiating_p != NULL);
    message->procedureCode = initiating_p->procedureCode;
    switch(initiating_p->procedureCode) {
        case ProcedureCode_id_uplinkNASTransport:
            return s1ap_decode_uplinknastransporties(&message->msg.uplinkNASTransportIEs, &initiating_p->value);
        case ProcedureCode_id_S1Setup:
            return s1ap_decode_s1setuprequesties(&message->msg.s1SetupRequestIEs, &initiating_p->value);
        case ProcedureCode_id_initialUEMessage:
            return s1ap_decode_initialuemessageies(&message->msg.initialUEMessageIEs, &initiating_p->value);
        case ProcedureCode_id_UEContextReleaseRequest:
            return s1ap_decode_uecontextreleaserequesties(&message->msg.ueContextReleaseRequestIEs, &initiating_p->value);
        default:
            S1AP_DEBUG("Unknown procedure ID (%d) for initiating message", (int)initiating_p->procedureCode);
            break;
    }
    return -1;
}
Exemplo n.º 9
0
int s1ap_eNB_decode_pdu(s1ap_message *message, const uint8_t * const buffer,
                        const uint32_t length)
{
    S1AP_PDU_t  pdu;
    S1AP_PDU_t *pdu_p = &pdu;
    asn_dec_rval_t dec_ret;

    DevAssert(buffer != NULL);

    memset((void *)pdu_p, 0, sizeof(S1AP_PDU_t));

    dec_ret = aper_decode(NULL,
                          &asn_DEF_S1AP_PDU,
                          (void **)&pdu_p,
                          buffer,
                          length,
                          0,
                          0);

    if (dec_ret.code != RC_OK) {
        S1AP_ERROR("Failed to decode pdu\n");
        return -1;
    }

    message->direction = pdu_p->present;

    switch(pdu_p->present) {
        case S1AP_PDU_PR_initiatingMessage:
            return s1ap_eNB_decode_initiating_message(message,
                    &pdu_p->choice.initiatingMessage);
        case S1AP_PDU_PR_successfulOutcome:
            return s1ap_eNB_decode_successful_outcome(message,
                    &pdu_p->choice.successfulOutcome);
        case S1AP_PDU_PR_unsuccessfulOutcome:
            return s1ap_eNB_decode_unsuccessful_outcome(message,
                    &pdu_p->choice.unsuccessfulOutcome);
        default:
            S1AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu_p->present);
            break;
    }
    return -1;
}
int s1ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len)
{
    DevAssert(message != NULL);
    DevAssert(buffer != NULL);
    DevAssert(len != NULL);

    switch(message->direction) {
        case S1AP_PDU_PR_initiatingMessage:
            return s1ap_eNB_encode_initiating(message, buffer, len);
        case S1AP_PDU_PR_successfulOutcome:
            return s1ap_eNB_encode_successfull_outcome(message, buffer, len);
        case S1AP_PDU_PR_unsuccessfulOutcome:
            return s1ap_eNB_encode_unsuccessfull_outcome(message, buffer, len);
        default:
            S1AP_DEBUG("Unknown message outcome (%d) or not implemented",
                       (int)message->direction);
            break;
    }
    return -1;
}
Exemplo n.º 11
0
/* @brief compare a TAC
*/
static
  int
s1ap_mme_compare_tac (
  S1ap_TAC_t * tac)
{
  int                                     i;
  uint16_t                                tac_value;

  DevAssert (tac != NULL);
  OCTET_STRING_TO_TAC (tac, tac_value);
  config_read_lock (&mme_config);

  for (i = 0; i < mme_config.gummei.nb_plmns; i++) {
    S1AP_DEBUG ("Comparing config tac %d, received tac = %d\n", mme_config.gummei.plmn_tac[i], tac_value);

    if (mme_config.gummei.plmn_tac[i] == tac_value)
      return TA_LIST_AT_LEAST_ONE_MATCH;
  }

  config_unlock (&mme_config);
  return TA_LIST_NO_MATCH;
}
static inline
int s1ap_mme_encode_initiating(s1ap_message *message_p,
                               uint8_t **buffer,
                               uint32_t *length)
{
  switch(message_p->procedureCode) {
  case S1ap_ProcedureCode_id_downlinkNASTransport:
    return s1ap_mme_encode_downlink_nas_transport(message_p, buffer, length);

  case S1ap_ProcedureCode_id_InitialContextSetup:
    return s1ap_mme_encode_initial_context_setup_request(message_p, buffer, length);

  case S1ap_ProcedureCode_id_UEContextRelease:
    return s1ap_mme_encode_ue_context_release_command(message_p, buffer, length);

  default:
    S1AP_DEBUG("Unknown procedure ID (%d) for initiating message_p\n",
               (int)message_p->procedureCode);
    break;
  }

  return -1;
}
//------------------------------------------------------------------------------
int s1ap_eNB_handle_nas_first_req(
  instance_t instance, s1ap_nas_first_req_t *s1ap_nas_first_req_p)
//------------------------------------------------------------------------------
{
  s1ap_eNB_instance_t          *instance_p = NULL;
  struct s1ap_eNB_mme_data_s   *mme_desc_p = NULL;
  struct s1ap_eNB_ue_context_s *ue_desc_p  = NULL;

  s1ap_message message;

  S1ap_InitialUEMessageIEs_t *initial_ue_message_p = NULL;

  uint8_t  *buffer = NULL;
  uint32_t  length = 0;

  DevAssert(s1ap_nas_first_req_p != NULL);

  /* Retrieve the S1AP eNB instance associated with Mod_id */
  instance_p = s1ap_eNB_get_instance(instance);
  DevAssert(instance_p != NULL);

  memset(&message, 0, sizeof(s1ap_message));

  message.direction     = S1AP_PDU_PR_initiatingMessage;
  message.procedureCode = S1ap_ProcedureCode_id_initialUEMessage;

  initial_ue_message_p = &message.msg.s1ap_InitialUEMessageIEs;

  /* Select the MME corresponding to the provided GUMMEI. */
  if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) {
    mme_desc_p = s1ap_eNB_nnsf_select_mme_by_gummei(
                   instance_p,
                   s1ap_nas_first_req_p->establishment_cause,
                   s1ap_nas_first_req_p->ue_identity.gummei);
  }

  if (mme_desc_p == NULL) {
    /* Select the MME corresponding to the provided s-TMSI. */
    if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) {
      mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code(
                     instance_p,
                     s1ap_nas_first_req_p->establishment_cause,
                     s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code);
    }
  }

  if (mme_desc_p == NULL) {
    /*
     * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the
     * highest capacity.
     */
    mme_desc_p = s1ap_eNB_nnsf_select_mme(
                   instance_p,
                   s1ap_nas_first_req_p->establishment_cause);
  }

  if (mme_desc_p == NULL) {
    /*
     * In case eNB has no MME associated, the eNB should inform RRC and discard
     * this request.
     */

    S1AP_WARN("No MME is associated to the eNB\n");
    // TODO: Inform RRC
    return -1;
  }

  /* The eNB should allocate a unique eNB UE S1AP ID for this UE. The value
   * will be used for the duration of the connectivity.
   */
  ue_desc_p = s1ap_eNB_allocate_new_UE_context();
  DevAssert(ue_desc_p != NULL);

  /* Keep a reference to the selected MME */
  ue_desc_p->mme_ref       = mme_desc_p;
  ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id;
  ue_desc_p->eNB_instance  = instance_p;

  do {
    struct s1ap_eNB_ue_context_s *collision_p;

    /* Peek a random value for the eNB_ue_s1ap_id */
    ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff;

    if ((collision_p = RB_INSERT(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_desc_p))
        == NULL) {
      S1AP_DEBUG("Found usable eNB_ue_s1ap_id: 0x%06x %d(10)\n",
                 ue_desc_p->eNB_ue_s1ap_id,
                 ue_desc_p->eNB_ue_s1ap_id);
      /* Break the loop as the id is not already used by another UE */
      break;
    }
  } while(1);

  initial_ue_message_p->eNB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id;
  /* Prepare the NAS PDU */
  initial_ue_message_p->nas_pdu.buf  = s1ap_nas_first_req_p->nas_pdu.buffer;
  initial_ue_message_p->nas_pdu.size = s1ap_nas_first_req_p->nas_pdu.length;

  /* Set the establishment cause according to those provided by RRC */
  DevCheck(s1ap_nas_first_req_p->establishment_cause < RRC_CAUSE_LAST,
           s1ap_nas_first_req_p->establishment_cause, RRC_CAUSE_LAST, 0);
  initial_ue_message_p->rrC_Establishment_Cause = s1ap_nas_first_req_p->establishment_cause;

  if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) {
    S1AP_DEBUG("S_TMSI_PRESENT\n");
    initial_ue_message_p->presenceMask |= S1AP_INITIALUEMESSAGEIES_S_TMSI_PRESENT;

    MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code,
                             &initial_ue_message_p->s_tmsi.mMEC);
    M_TMSI_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi,
                           &initial_ue_message_p->s_tmsi.m_TMSI);
  }

  if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) {
    S1AP_DEBUG("GUMMEI_ID_PRESENT\n");
    initial_ue_message_p->presenceMask |= S1AP_INITIALUEMESSAGEIES_GUMMEI_ID_PRESENT;

    MCC_MNC_TO_PLMNID(
      s1ap_nas_first_req_p->ue_identity.gummei.mcc,
      s1ap_nas_first_req_p->ue_identity.gummei.mnc,
      s1ap_nas_first_req_p->ue_identity.gummei.mnc_len,
      &initial_ue_message_p->gummei_id.pLMN_Identity);

    MME_GID_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id,
                            &initial_ue_message_p->gummei_id.mME_Group_ID);
    MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_code,
                             &initial_ue_message_p->gummei_id.mME_Code);
  }

  /* Assuming TAI is the TAI from the cell */
  INT16_TO_OCTET_STRING(instance_p->tac, &initial_ue_message_p->tai.tAC);
  MCC_MNC_TO_PLMNID(instance_p->mcc,
                    instance_p->mnc,
                    instance_p->mnc_digit_length,
                    &initial_ue_message_p->tai.pLMNidentity);

  /* Set the EUTRAN CGI
   * The cell identity is defined on 28 bits but as we use macro enb id,
   * we have to pad.
   */
#warning "TODO get cell id from RRC"
  MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,
		  0, // Cell ID
          &initial_ue_message_p->eutran_cgi.cell_ID);
  MCC_MNC_TO_TBCD(instance_p->mcc,
                  instance_p->mnc,
                  instance_p->mnc_digit_length,
                  &initial_ue_message_p->eutran_cgi.pLMNidentity);

  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
    /* Failed to encode message */
    DevMessage("Failed to encode initial UE message\n");
  }

  /* Update the current S1AP UE state */
  ue_desc_p->ue_state = S1AP_UE_WAITING_CSR;

  /* Assign a stream for this UE :
   * From 3GPP 36.412 7)Transport layers:
   *  Within the SCTP association established between one MME and eNB pair:
   *  - a single pair of stream identifiers shall be reserved for the sole use
   *      of S1AP elementary procedures that utilize non UE-associated signalling.
   *  - At least one pair of stream identifiers shall be reserved for the sole use
   *      of S1AP elementary procedures that utilize UE-associated signallings.
   *      However a few pairs (i.e. more than one) should be reserved.
   *  - A single UE-associated signalling shall use one SCTP stream and
   *      the stream should not be changed during the communication of the
   *      UE-associated signalling.
   */
  mme_desc_p->nextstream = (mme_desc_p->nextstream + 1) % mme_desc_p->out_streams;

  if ((mme_desc_p->nextstream == 0) && (mme_desc_p->out_streams > 1)) {
    mme_desc_p->nextstream += 1;
  }

  ue_desc_p->tx_stream = mme_desc_p->nextstream;

  MSC_LOG_TX_MESSAGE(
    MSC_S1AP_ENB,
    MSC_S1AP_MME,
    (const char *)NULL,
    0,
    MSC_AS_TIME_FMT" initialUEMessage initiatingMessage eNB_ue_s1ap_id %u",
    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
    initial_ue_message_p->eNB_UE_S1AP_ID);

  /* Send encoded message over sctp */
  s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, mme_desc_p->assoc_id,
                                   buffer, length, ue_desc_p->tx_stream);

  return 0;
}
Exemplo n.º 14
0
void *s1ap_eNB_task(void *arg)
{
  MessageDef *received_msg = NULL;
  int         result;

  S1AP_DEBUG("Starting S1AP layer\n");

  s1ap_eNB_prepare_internal_data();

  itti_mark_task_ready(TASK_S1AP);
  MSC_START_USE();

  while (1) {
    itti_receive_msg(TASK_S1AP, &received_msg);

    switch (ITTI_MSG_ID(received_msg)) {
    case TERMINATE_MESSAGE:
      itti_exit_task();
      break;

    case S1AP_REGISTER_ENB_REQ: {
      /* Register a new eNB.
       * in Virtual mode eNBs will be distinguished using the mod_id/
       * Each eNB has to send an S1AP_REGISTER_ENB message with its
       * own parameters.
       */
      s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                   &S1AP_REGISTER_ENB_REQ(received_msg));
    }
    break;

    case SCTP_NEW_ASSOCIATION_RESP: {
      s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                            &received_msg->ittiMsg.sctp_new_association_resp);
    }
    break;

    case SCTP_DATA_IND: {
      s1ap_eNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
    }
    break;

    case S1AP_NAS_FIRST_REQ: {
      s1ap_eNB_handle_nas_first_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                    &S1AP_NAS_FIRST_REQ(received_msg));
    }
    break;

    case S1AP_UPLINK_NAS: {
      s1ap_eNB_nas_uplink(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                          &S1AP_UPLINK_NAS(received_msg));
    }
    break;

    case S1AP_UE_CAPABILITIES_IND: {
      s1ap_eNB_ue_capabilities(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                               &S1AP_UE_CAPABILITIES_IND(received_msg));
    }
    break;

    case S1AP_INITIAL_CONTEXT_SETUP_RESP: {
      s1ap_eNB_initial_ctxt_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                 &S1AP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
    }
    break;

    case S1AP_E_RAB_SETUP_RESP: {
      s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
				&S1AP_E_RAB_SETUP_RESP(received_msg));
    }
    break;
      
    case S1AP_NAS_NON_DELIVERY_IND: {
      s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                    &S1AP_NAS_NON_DELIVERY_IND(received_msg));
    }
    break;

    case S1AP_UE_CONTEXT_RELEASE_COMPLETE: {
      s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                       &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
    }
    break;

    case S1AP_UE_CONTEXT_RELEASE_REQ: {
      s1ap_eNB_instance_t               *s1ap_eNB_instance_p           = NULL; // test
      struct s1ap_eNB_ue_context_s      *ue_context_p                  = NULL; // test

      s1ap_ue_context_release_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                  &S1AP_UE_CONTEXT_RELEASE_REQ(received_msg));


      s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MESSAGE_GET_INSTANCE(received_msg)); // test
      DevAssert(s1ap_eNB_instance_p != NULL); // test

      if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
                          S1AP_UE_CONTEXT_RELEASE_REQ(received_msg).eNB_ue_s1ap_id)) == NULL) { // test
        /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
        S1AP_ERROR("Failed to find ue context associated with eNB ue s1ap id: %u\n",
                   S1AP_UE_CONTEXT_RELEASE_REQ(received_msg).eNB_ue_s1ap_id); // test
      }  // test
    }
    break;

    default:
      S1AP_ERROR("Received unhandled message: %d:%s\n",
                 ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
      break;
    }

    result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);

    received_msg = NULL;
  }

  return NULL;
}
static inline
int s1ap_eNB_encode_initiating(s1ap_message *s1ap_message_p,
    uint8_t **buffer, uint32_t *len)
{
    int ret = -1;
    MessageDef *message_p;
    char       *message_string = NULL;
    size_t      message_string_size;
    MessagesIds message_id;

    DevAssert(s1ap_message_p != NULL);

    message_string = calloc(10000, sizeof(char));

    s1ap_string_total_size = 0;

    switch(s1ap_message_p->procedureCode) {
        case S1ap_ProcedureCode_id_S1Setup:
            ret = s1ap_eNB_encode_s1_setup_request(
                &s1ap_message_p->msg.s1ap_S1SetupRequestIEs, buffer, len);
            s1ap_xer_print_s1ap_s1setuprequest(s1ap_xer__print2sp, message_string, s1ap_message_p);
            message_id = S1AP_S1_SETUP_LOG;
            break;

        case S1ap_ProcedureCode_id_uplinkNASTransport:
            ret = s1ap_eNB_encode_uplink_nas_transport(
                &s1ap_message_p->msg.s1ap_UplinkNASTransportIEs, buffer, len);
            s1ap_xer_print_s1ap_uplinknastransport(s1ap_xer__print2sp, message_string, s1ap_message_p);
            message_id = S1AP_UPLINK_NAS_LOG;
            break;

        case S1ap_ProcedureCode_id_UECapabilityInfoIndication:
            ret = s1ap_eNB_encode_ue_capability_info_indication(
                &s1ap_message_p->msg.s1ap_UECapabilityInfoIndicationIEs, buffer, len);
            s1ap_xer_print_s1ap_uecapabilityinfoindication(s1ap_xer__print2sp, message_string, s1ap_message_p);
            message_id = S1AP_UE_CAPABILITY_IND_LOG;
            break;

        case S1ap_ProcedureCode_id_initialUEMessage:
            ret = s1ap_eNB_encode_initial_ue_message(
                &s1ap_message_p->msg.s1ap_InitialUEMessageIEs, buffer, len);
            s1ap_xer_print_s1ap_initialuemessage(s1ap_xer__print2sp, message_string, s1ap_message_p);
            message_id = S1AP_INITIAL_UE_MESSAGE_LOG;
            break;

        case S1ap_ProcedureCode_id_NASNonDeliveryIndication:
            ret = s1ap_eNB_encode_nas_non_delivery(
                &s1ap_message_p->msg.s1ap_NASNonDeliveryIndication_IEs, buffer, len);
            s1ap_xer_print_s1ap_nasnondeliveryindication_(s1ap_xer__print2sp,
                                                          message_string, s1ap_message_p);
            message_id = S1AP_NAS_NON_DELIVERY_IND_LOG;
            break;

        default:
            S1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n",
                       (int)s1ap_message_p->procedureCode);
            return ret;
            break;
    }

    message_string_size = strlen(message_string);

    message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
    message_p->ittiMsg.s1ap_s1_setup_log.size = message_string_size;
    memcpy(&message_p->ittiMsg.s1ap_s1_setup_log.text, message_string, message_string_size);

    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);

    free(message_string);

    return ret;
}