Пример #1
0
int s1ap_eNB_new_data_request(uint8_t eNB_id, uint8_t ue_id, uint8_t *buffer, uint32_t length) {
    s1ap_message message;
    struct s1ap_eNB_UE_description_s *ue_ref;
    struct s1ap_eNB_description_s *eNB_ref;

    /* If we don't found the eNB as S1 associated, this may indicate that no S1 Setup Request has been sent,
     * or S1 Setup has failed.
     */
    if ((eNB_ref = s1ap_get_eNB_eNB_id(eNB_id)) == NULL) {
        S1AP_ERROR("This eNB (%d) has no known S1 association with any MME\n", eNB_id);
        return -1;
    }

    ///TODO: Check if eNB is associated to a MME

    /* Searching for UE in eNB.
     * If we failed founding it, request a new initial UE message to MME.
     */
    if ((ue_ref = s1ap_get_ue_id_pair(eNB_id, ue_id)) == NULL) {
        if ((ue_ref = s1ap_UE_add_new(eNB_ref)) == NULL) {
            /* We failed to allocate a new UE in list */
            S1AP_ERROR("Failed to allocate new UE description for UE %d attached to eNB %d\n",
                  ue_id, eNB_id);
            return -1;
        }
        ue_ref->eNB_UE_s1ap_id = ue_id;
        /* MME UE S1AP ID is allocated by MME, waiting for Initial Context Setup Request Message
         * before setting it.
         */
        ue_ref->mme_UE_s1ap_id = 0;
        ue_ref->eNB->nextstream++;
        /* Do we reached max number of output streams ?.
         * If so wrap to 1.
         */
        if (ue_ref->eNB->nextstream == ue_ref->eNB->outstreams)
            ue_ref->eNB->nextstream = 1;

        /* Set the output stream that will be used for this UE */
        ue_ref->stream_send = ue_ref->eNB->nextstream;

        S1AP_ERROR("Sending Initial UE message for UE %d on eNB %d\n",
              ue_id, eNB_id);

        return s1ap_eNB_generate_initial_ue_message(ue_ref, buffer, length);
    } else {
        /* UE is already associated to a valid Context.
         * Consider request as Uplink NAS transport.
         */
        S1AP_ERROR("Sending Uplink NAS transport message for UE %d on eNB %d\n",
              ue_id, eNB_id);
        return s1ap_eNB_generate_uplink_nas_transport(ue_ref, buffer, length);
    }
}
void s1ap_eNB_free_ue_context(struct s1ap_eNB_ue_context_s *ue_context_p)
{
  if (ue_context_p == NULL) {
    S1AP_ERROR("Trying to free a NULL context\n");
    return;
  }

  /* TODO: check that context is currently not in the tree of known
   * contexts.
   */

  free(ue_context_p);
}
Пример #3
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;
}
int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
                            const uint8_t * const data, const uint32_t data_length)
{
  struct s1ap_message_s message;

  DevAssert(data != NULL);

  memset(&message, 0, sizeof(struct s1ap_message_s));

  if (s1ap_eNB_decode_pdu(&message, data, data_length) < 0) {
    S1AP_ERROR("Failed to decode PDU\n");
    return -1;
  }

  /* Checking procedure Code and direction of message */
  if (message.procedureCode > sizeof(messages_callback) / (3 * sizeof(
        s1ap_message_decoded_callback))
      || (message.direction > S1AP_PDU_PR_unsuccessfulOutcome)) {
    S1AP_ERROR("[SCTP %d] Either procedureCode %d or direction %d exceed expected\n",
               assoc_id, message.procedureCode, message.direction);
    return -1;
  }

  /* No handler present.
   * This can mean not implemented or no procedure for eNB (wrong direction).
   */
  if (messages_callback[message.procedureCode][message.direction-1] == NULL) {
    S1AP_ERROR("[SCTP %d] No handler for procedureCode %d in %s\n",
               assoc_id, message.procedureCode,
               s1ap_direction2String[message.direction]);
    return -1;
  }

  /* Calling the right handler */
  return (*messages_callback[message.procedureCode][message.direction-1])
         (assoc_id, stream, &message);
}
static
int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
                                     uint32_t               stream,
                                     struct s1ap_message_s *message_p)
{
  S1ap_S1SetupFailureIEs_t   *s1_setup_failure_p;
  s1ap_eNB_mme_data_t        *mme_desc_p;

  DevAssert(message_p != NULL);

  s1_setup_failure_p = &message_p->msg.s1ap_S1SetupFailureIEs;

  /* S1 Setup Failure == Non UE-related procedure -> stream 0 */
  if (stream != 0) {
    S1AP_WARN("[SCTP %d] Received s1 setup failure on stream != 0 (%d)\n",
              assoc_id, stream);
  }

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing "
               "MME context\n", assoc_id);
    return -1;
  }

  if ((s1_setup_failure_p->cause.present == S1ap_Cause_PR_misc) &&
      (s1_setup_failure_p->cause.choice.misc == S1ap_CauseMisc_unspecified)) {
    S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n");
  } else {
    S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
  }

  mme_desc_p->state = S1AP_ENB_STATE_WAITING;
  s1ap_handle_s1_setup_message(mme_desc_p, 0);

  return 0;
}
struct s1ap_eNB_ue_context_s *s1ap_eNB_allocate_new_UE_context(void)
{
  struct s1ap_eNB_ue_context_s *new_p;

  new_p = malloc(sizeof(struct s1ap_eNB_ue_context_s));

  if (new_p == NULL) {
    S1AP_ERROR("Cannot allocate new ue context\n");
    return NULL;
  }

  memset(new_p, 0, sizeof(struct s1ap_eNB_ue_context_s));

  return new_p;
}
Пример #7
0
static int s1ap_eNB_decode_successful_outcome(s1ap_message *message,
    S1ap_SuccessfulOutcome_t *successfullOutcome_p)
{
    int ret = -1;
    MessageDef *message_p;
    char       *message_string = NULL;
    size_t      message_string_size;
    MessagesIds message_id;

    DevAssert(successfullOutcome_p != NULL);

    message_string = malloc(sizeof(char) * 10000);

    s1ap_string_total_size = 0;

    message->procedureCode = successfullOutcome_p->procedureCode;
    message->criticality   = successfullOutcome_p->criticality;

    switch(successfullOutcome_p->procedureCode)
    {
        case S1ap_ProcedureCode_id_S1Setup:
            ret = s1ap_decode_s1ap_s1setupresponseies(
                &message->msg.s1ap_S1SetupResponseIEs, &successfullOutcome_p->value);
            s1ap_xer_print_s1ap_s1setupresponse(s1ap_xer__print2sp, message_string, message);
            message_id = S1AP_S1_SETUP_LOG;
            break;

        default:
            S1AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
                       (int)successfullOutcome_p->procedureCode);
            return -1;
    }

    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;
}
Пример #8
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;
}
Пример #9
0
static int s1ap_eNB_decode_unsuccessful_outcome(s1ap_message *message,
    S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p)
{
    int ret = -1;
    DevAssert(unSuccessfullOutcome_p != NULL);

    message->procedureCode = unSuccessfullOutcome_p->procedureCode;
    message->criticality   = unSuccessfullOutcome_p->criticality;

    switch(unSuccessfullOutcome_p->procedureCode) {
        case S1ap_ProcedureCode_id_S1Setup:
            return s1ap_decode_s1ap_s1setupfailureies(
                &message->msg.s1ap_S1SetupFailureIEs, &unSuccessfullOutcome_p->value);

        default:
            S1AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
                       (int)unSuccessfullOutcome_p->procedureCode);
            break;
    }
    return ret;
}
Пример #10
0
int s1ap_sctp_connected_callback(void *args, uint32_t assocId, uint32_t instreams, uint32_t outstreams) {

    struct s1ap_eNB_description_s* eNB_ref;

    if ((eNB_ref = s1ap_eNB_add_new()) == NULL)
        return;

    eNB_ref->eNB_id = *((uint8_t*)args);
    eNB_ref->assocId = assocId;
    eNB_ref->instreams = instreams;
    eNB_ref->outstreams = outstreams;
    eNB_ref->state = S1AP_ENB_STATE_DECONNECTED;
    /* First usable stream for UE associated signalling */
    eNB_ref->nextstream = 1;
    if (s1ap_eNB_generate_s1_setup_request(eNB_ref) < 0) {
        S1AP_ERROR("[eNB %02d] Failed to encode S1 Setup Request\n", eNB_ref->eNB_id);
        return -1;
    }
    /* Waiting for the response from MME */
    while ((volatile)(eNB_ref->state) & S1AP_ENB_STATE_WAITING) {
    }
    return 0;
}
//------------------------------------------------------------------------------
int s1ap_eNB_ue_capabilities(instance_t instance,
                             s1ap_ue_cap_info_ind_t *ue_cap_info_ind_p)
//------------------------------------------------------------------------------
{
  s1ap_eNB_instance_t          *s1ap_eNB_instance_p;
  struct s1ap_eNB_ue_context_s *ue_context_p;

  S1ap_UECapabilityInfoIndicationIEs_t *ue_cap_info_ind_ies_p;

  s1ap_message  message;

  uint8_t  *buffer;
  uint32_t length;
  int      ret = -1;

  /* Retrieve the S1AP eNB instance associated with Mod_id */
  s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);

  DevAssert(ue_cap_info_ind_p != NULL);
  DevAssert(s1ap_eNB_instance_p != NULL);

  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
                      ue_cap_info_ind_p->eNB_ue_s1ap_id)) == NULL) {
    /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
    S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n",
              ue_cap_info_ind_p->eNB_ue_s1ap_id);
    return -1;
  }

  /* UE capabilities message can occur either during an s1ap connected state
   * or during initial attach (for example: NAS authentication).
   */
  if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED ||
        ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) {
    S1AP_WARN("You are attempting to send NAS data over non-connected "
              "eNB ue s1ap id: %u, current state: %d\n",
              ue_cap_info_ind_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
    return -1;
  }

  /* Prepare the S1AP message to encode */
  memset(&message, 0, sizeof(s1ap_message));

  message.direction     = S1AP_PDU_PR_initiatingMessage;
  message.procedureCode = S1ap_ProcedureCode_id_UECapabilityInfoIndication;

  ue_cap_info_ind_ies_p = &message.msg.s1ap_UECapabilityInfoIndicationIEs;

  ue_cap_info_ind_ies_p->ueRadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer;
  ue_cap_info_ind_ies_p->ueRadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length;

  ue_cap_info_ind_ies_p->eNB_UE_S1AP_ID = ue_cap_info_ind_p->eNB_ue_s1ap_id;
  ue_cap_info_ind_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;

  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
    /* Encode procedure has failed... */
    S1AP_ERROR("Failed to encode UE capabilities indication\n");
    return -1;
  }

  MSC_LOG_TX_MESSAGE(
    MSC_S1AP_ENB,
    MSC_S1AP_MME,
    (const char *)buffer,
    length,
    MSC_AS_TIME_FMT" UECapabilityInfoIndication initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
    ue_cap_info_ind_ies_p->eNB_UE_S1AP_ID,
    ue_cap_info_ind_ies_p->mme_ue_s1ap_id);

  /* UE associated signalling -> use the allocated stream */
  s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
                                   ue_context_p->mme_ref->assoc_id, buffer,
                                   length, ue_context_p->tx_stream);

  return ret;
}
//------------------------------------------------------------------------------
int s1ap_eNB_initial_ctxt_resp(
  instance_t instance, s1ap_initial_context_setup_resp_t *initial_ctxt_resp_p)
//------------------------------------------------------------------------------
{
  s1ap_eNB_instance_t          *s1ap_eNB_instance_p = NULL;
  struct s1ap_eNB_ue_context_s *ue_context_p        = NULL;

  S1ap_InitialContextSetupResponseIEs_t *initial_ies_p  = NULL;

  s1ap_message  message;

  uint8_t  *buffer  = NULL;
  uint32_t length;
  int      ret = -1;
  int      i;

  /* Retrieve the S1AP eNB instance associated with Mod_id */
  s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);

  DevAssert(initial_ctxt_resp_p != NULL);
  DevAssert(s1ap_eNB_instance_p != NULL);

  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
                      initial_ctxt_resp_p->eNB_ue_s1ap_id)) == NULL) {
    /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
    S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
              initial_ctxt_resp_p->eNB_ue_s1ap_id);
    return -1;
  }

  /* Uplink NAS transport can occur either during an s1ap connected state
   * or during initial attach (for example: NAS authentication).
   */
  if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED ||
        ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) {
    S1AP_WARN("You are attempting to send NAS data over non-connected "
              "eNB ue s1ap id: %06x, current state: %d\n",
              initial_ctxt_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
    return -1;
  }

  /* Prepare the S1AP message to encode */
  memset(&message, 0, sizeof(s1ap_message));

  message.direction     = S1AP_PDU_PR_successfulOutcome;
  message.procedureCode = S1ap_ProcedureCode_id_InitialContextSetup;

  initial_ies_p = &message.msg.s1ap_InitialContextSetupResponseIEs;

  initial_ies_p->eNB_UE_S1AP_ID = initial_ctxt_resp_p->eNB_ue_s1ap_id;
  initial_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;

  for (i = 0; i < initial_ctxt_resp_p->nb_of_e_rabs; i++) {
    S1ap_E_RABSetupItemCtxtSURes_t *new_item;

    new_item = calloc(1, sizeof(S1ap_E_RABSetupItemCtxtSURes_t));

    new_item->e_RAB_ID = initial_ctxt_resp_p->e_rabs[i].e_rab_id;
    GTP_TEID_TO_ASN1(initial_ctxt_resp_p->e_rabs[i].gtp_teid, &new_item->gTP_TEID);
    new_item->transportLayerAddress.buf = initial_ctxt_resp_p->e_rabs[i].eNB_addr.buffer;
    new_item->transportLayerAddress.size = initial_ctxt_resp_p->e_rabs[i].eNB_addr.length;
    new_item->transportLayerAddress.bits_unused = 0;

    ASN_SEQUENCE_ADD(&initial_ies_p->e_RABSetupListCtxtSURes.s1ap_E_RABSetupItemCtxtSURes,
                     new_item);
  }

  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
    S1AP_ERROR("Failed to encode uplink NAS transport\n");
    /* Encode procedure has failed... */
    return -1;
  }

  MSC_LOG_TX_MESSAGE(
    MSC_S1AP_ENB,
    MSC_S1AP_MME,
    (const char *)buffer,
    length,
    MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
    initial_ies_p->eNB_UE_S1AP_ID,
    initial_ies_p->mme_ue_s1ap_id);

  /* UE associated signalling -> use the allocated stream */
  s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
                                   ue_context_p->mme_ref->assoc_id, buffer,
                                   length, ue_context_p->tx_stream);

  return ret;
}
//------------------------------------------------------------------------------
void s1ap_eNB_nas_non_delivery_ind(instance_t instance,
                                   s1ap_nas_non_delivery_ind_t *s1ap_nas_non_delivery_ind)
//------------------------------------------------------------------------------
{
  struct s1ap_eNB_ue_context_s *ue_context_p;
  s1ap_eNB_instance_t          *s1ap_eNB_instance_p;

  S1ap_NASNonDeliveryIndication_IEs_t *nas_non_delivery_p;

  s1ap_message  message;

  uint8_t  *buffer;
  uint32_t length;

  DevAssert(s1ap_nas_non_delivery_ind != NULL);

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

  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id)) == NULL) {
    /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
    S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n",
              s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id);
    MSC_LOG_EVENT(
      MSC_S1AP_ENB,
      MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to MME failed, no context for eNB_ue_s1ap_id %06x",
      s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id);
    return;
  }

  /* Prepare the S1AP message to encode */
  memset(&message, 0, sizeof(s1ap_message));

  message.direction     = S1AP_PDU_PR_initiatingMessage;
  message.procedureCode = S1ap_ProcedureCode_id_NASNonDeliveryIndication;

  nas_non_delivery_p = &message.msg.s1ap_NASNonDeliveryIndication_IEs;
  nas_non_delivery_p->eNB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id;
  nas_non_delivery_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
  nas_non_delivery_p->nas_pdu.buf    = s1ap_nas_non_delivery_ind->nas_pdu.buffer;
  nas_non_delivery_p->nas_pdu.size   = s1ap_nas_non_delivery_ind->nas_pdu.length;

  /* Send a dummy cause */
  nas_non_delivery_p->cause.present = S1ap_Cause_PR_radioNetwork;
  nas_non_delivery_p->cause.choice.radioNetwork = S1ap_CauseRadioNetwork_radio_connection_with_ue_lost;

  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
    S1AP_ERROR("Failed to encode NAS NON delivery indication\n");
    /* Encode procedure has failed... */
    MSC_LOG_EVENT(
      MSC_S1AP_ENB,
      MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to MME failed (encoding)");
    return;
  }


  MSC_LOG_TX_MESSAGE(
    MSC_S1AP_ENB,
    MSC_S1AP_MME,
    (const char *)s1ap_nas_non_delivery_ind,
    sizeof(s1ap_nas_non_delivery_ind_t),
    MSC_AS_TIME_FMT" NASNonDeliveryIndication initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
    nas_non_delivery_p->eNB_UE_S1AP_ID,
    nas_non_delivery_p->mme_ue_s1ap_id);


  /* UE associated signalling -> use the allocated stream */
  s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
                                   ue_context_p->mme_ref->assoc_id, buffer,
                                   length, ue_context_p->tx_stream);
}
//------------------------------------------------------------------------------
int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_p)
//------------------------------------------------------------------------------
{
  struct s1ap_eNB_ue_context_s *ue_context_p;
  s1ap_eNB_instance_t          *s1ap_eNB_instance_p;
  S1ap_UplinkNASTransportIEs_t *uplink_NAS_transport_p;

  s1ap_message  message;

  uint8_t  *buffer;
  uint32_t length;

  DevAssert(s1ap_uplink_nas_p != NULL);

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

  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_uplink_nas_p->eNB_ue_s1ap_id)) == NULL) {
    /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
    S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n",
              s1ap_uplink_nas_p->eNB_ue_s1ap_id);
    return -1;
  }

  /* Uplink NAS transport can occur either during an s1ap connected state
   * or during initial attach (for example: NAS authentication).
   */
  if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED ||
        ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) {
    S1AP_WARN("You are attempting to send NAS data over non-connected "
              "eNB ue s1ap id: %u, current state: %d\n",
              s1ap_uplink_nas_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
    return -1;
  }

  /* Prepare the S1AP message to encode */
  memset(&message, 0, sizeof(s1ap_message));

  message.direction     = S1AP_PDU_PR_initiatingMessage;
  message.procedureCode = S1ap_ProcedureCode_id_uplinkNASTransport;

  uplink_NAS_transport_p = &message.msg.s1ap_UplinkNASTransportIEs;

  uplink_NAS_transport_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
  uplink_NAS_transport_p->eNB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id;

  uplink_NAS_transport_p->nas_pdu.buf  = s1ap_uplink_nas_p->nas_pdu.buffer;
  uplink_NAS_transport_p->nas_pdu.size = s1ap_uplink_nas_p->nas_pdu.length;

  MCC_MNC_TO_PLMNID(
    s1ap_eNB_instance_p->mcc,
    s1ap_eNB_instance_p->mnc,
    s1ap_eNB_instance_p->mnc_digit_length,
    &uplink_NAS_transport_p->eutran_cgi.pLMNidentity);

#warning "TODO get cell id from RRC"
  MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id,
          0,
          &uplink_NAS_transport_p->eutran_cgi.cell_ID);

  /* MCC/MNC should be repeated in TAI and EUTRAN CGI */
  MCC_MNC_TO_PLMNID(
    s1ap_eNB_instance_p->mcc,
    s1ap_eNB_instance_p->mnc,
    s1ap_eNB_instance_p->mnc_digit_length,
    &uplink_NAS_transport_p->tai.pLMNidentity);

  TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &uplink_NAS_transport_p->tai.tAC);

  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
    S1AP_ERROR("Failed to encode uplink NAS transport\n");
    /* Encode procedure has failed... */
    return -1;
  }

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


  /* UE associated signalling -> use the allocated stream */
  s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
                                   ue_context_p->mme_ref->assoc_id, buffer,
                                   length, ue_context_p->tx_stream);

  return 0;
}
//------------------------------------------------------------------------------
int s1ap_eNB_handle_nas_downlink(const uint32_t               assoc_id,
                                 const uint32_t               stream,
                                 struct s1ap_message_s* message_p)
//------------------------------------------------------------------------------
{
  const S1ap_DownlinkNASTransportIEs_t *downlink_NAS_transport_p = NULL;

  s1ap_eNB_mme_data_t   *mme_desc_p                        = NULL;
  s1ap_eNB_ue_context_t *ue_desc_p                         = NULL;
  s1ap_eNB_instance_t   *s1ap_eNB_instance                 = NULL;

  DevAssert(message_p != NULL);

  downlink_NAS_transport_p = &message_p->msg.s1ap_DownlinkNASTransportIEs;

  /* UE-related procedure -> stream != 0 */
  if (stream == 0) {
    S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n",
               assoc_id);
    return -1;
  }

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR(
      "[SCTP %d] Received NAS downlink message for non existing MME context\n",
      assoc_id);
    return -1;
  }

  s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance;

  if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance,
                   downlink_NAS_transport_p->eNB_UE_S1AP_ID)) == NULL) {
    MSC_LOG_RX_DISCARDED_MESSAGE(
      MSC_S1AP_ENB,
      MSC_S1AP_MME,
      (const char *)downlink_NAS_transport_p,
      sizeof(S1ap_DownlinkNASTransportIEs_t),
      MSC_AS_TIME_FMT" downlinkNASTransport  eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
      0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
      downlink_NAS_transport_p->eNB_UE_S1AP_ID,
      downlink_NAS_transport_p->mme_ue_s1ap_id);

    S1AP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context eNB_UE_S1AP_ID: 0x%"PRIx32" %u\n",
               assoc_id,
               downlink_NAS_transport_p->eNB_UE_S1AP_ID,
               downlink_NAS_transport_p->eNB_UE_S1AP_ID);
    return -1;
  }

  if (0 == ue_desc_p->rx_stream) {
	ue_desc_p->rx_stream = stream;
  } else if (stream != ue_desc_p->rx_stream) {
    S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream %u, expecting %u\n",
               assoc_id, stream, ue_desc_p->rx_stream);
    return -1;
  }

  /* Is it the first outcome of the MME for this UE ? If so store the mme
   * UE s1ap id.
   */
  if (ue_desc_p->mme_ue_s1ap_id == 0) {
    ue_desc_p->mme_ue_s1ap_id = downlink_NAS_transport_p->mme_ue_s1ap_id;
  } else {
    /* We already have a mme ue s1ap id check the received is the same */
    if (ue_desc_p->mme_ue_s1ap_id != downlink_NAS_transport_p->mme_ue_s1ap_id) {
      S1AP_ERROR("[SCTP %d] Mismatch in MME UE S1AP ID (0x%"PRIx32" != 0x%"PRIx32")\n",
                 assoc_id,
                 downlink_NAS_transport_p->mme_ue_s1ap_id,
                 ue_desc_p->mme_ue_s1ap_id
                );
      return -1;
    }
  }

  MSC_LOG_RX_MESSAGE(
    MSC_S1AP_ENB,
    MSC_S1AP_MME,
    (const char *)downlink_NAS_transport_p,
    sizeof(S1ap_DownlinkNASTransportIEs_t),
    MSC_AS_TIME_FMT" downlinkNASTransport  eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
    downlink_NAS_transport_p->eNB_UE_S1AP_ID,
    downlink_NAS_transport_p->mme_ue_s1ap_id);

  /* Forward the NAS PDU to RRC */
  s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance,
                                      ue_desc_p->ue_initial_id,
                                      ue_desc_p->eNB_ue_s1ap_id,
                                      downlink_NAS_transport_p->nas_pdu.buf,
                                      downlink_NAS_transport_p->nas_pdu.size);

  // LG: Why set to 0 ??
  //ue_desc_p->ue_initial_id = 0;

  return 0;
}
Пример #16
0
static int s1ap_eNB_generate_s1_setup_request(
  s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p)
{
  s1ap_message               message;

  S1ap_S1SetupRequestIEs_t *s1SetupRequest_p;
  S1ap_PLMNidentity_t       plmnIdentity;
  S1ap_SupportedTAs_Item_t  ta;

  uint8_t  *buffer;
  uint32_t  len;
  int       ret = 0;

  DevAssert(instance_p != NULL);
  DevAssert(s1ap_mme_data_p != NULL);

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

  message.direction     = S1AP_PDU_PR_initiatingMessage;
  message.procedureCode = S1ap_ProcedureCode_id_S1Setup;
  message.criticality   = S1ap_Criticality_reject;

  s1SetupRequest_p = &message.msg.s1ap_S1SetupRequestIEs;
  memset((void *)&plmnIdentity, 0, sizeof(S1ap_PLMNidentity_t));

  memset((void *)&ta, 0, sizeof(S1ap_SupportedTAs_Item_t));

  s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;

  s1SetupRequest_p->global_ENB_ID.eNB_ID.present = S1ap_ENB_ID_PR_macroENB_ID;
  MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
                             &s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID);
  MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
                    &s1SetupRequest_p->global_ENB_ID.pLMNidentity);

  S1AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0], s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1],
            s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]);

  INT16_TO_OCTET_STRING(instance_p->tac, &ta.tAC);
  MCC_MNC_TO_TBCD(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, &plmnIdentity);

  ASN_SEQUENCE_ADD(&ta.broadcastPLMNs.list, &plmnIdentity);
  ASN_SEQUENCE_ADD(&s1SetupRequest_p->supportedTAs.list, &ta);

  s1SetupRequest_p->defaultPagingDRX = instance_p->default_drx;

  if (instance_p->eNB_name != NULL) {
    s1SetupRequest_p->presenceMask |= S1AP_S1SETUPREQUESTIES_ENBNAME_PRESENT;
    OCTET_STRING_fromBuf(&s1SetupRequest_p->eNBname, instance_p->eNB_name,
                         strlen(instance_p->eNB_name));
  }

  if (s1ap_eNB_encode_pdu(&message, &buffer, &len) < 0) {
    S1AP_ERROR("Failed to encode S1 setup request\n");
    return -1;
  }

  /* Non UE-Associated signalling -> stream = 0 */
  s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);

  return ret;
}
static
int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
                                      uint32_t               stream,
                                      struct s1ap_message_s *message_p)
{
  S1ap_S1SetupResponseIEs_t *s1SetupResponse_p;
  s1ap_eNB_mme_data_t       *mme_desc_p;
  int i;

  DevAssert(message_p != NULL);

  s1SetupResponse_p = &message_p->msg.s1ap_S1SetupResponseIEs;

  /* S1 Setup Response == Non UE-related procedure -> stream 0 */
  if (stream != 0) {
    S1AP_ERROR("[SCTP %d] Received s1 setup response on stream != 0 (%d)\n",
               assoc_id, stream);
    return -1;
  }

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing "
               "MME context\n", assoc_id);
    return -1;
  }

  /* The list of served gummei can contain at most 8 elements.
   * LTE related gummei is the first element in the list, i.e with an id of 0.
   */
  DevAssert(s1SetupResponse_p->servedGUMMEIs.list.count == 1);

  for (i = 0; i < s1SetupResponse_p->servedGUMMEIs.list.count; i++) {
    struct S1ap_ServedGUMMEIsItem *gummei_item_p;
    struct served_gummei_s        *new_gummei_p;
    int j;

    gummei_item_p = (struct S1ap_ServedGUMMEIsItem *)
                    s1SetupResponse_p->servedGUMMEIs.list.array[i];
    new_gummei_p = calloc(1, sizeof(struct served_gummei_s));

    STAILQ_INIT(&new_gummei_p->served_plmns);
    STAILQ_INIT(&new_gummei_p->served_group_ids);
    STAILQ_INIT(&new_gummei_p->mme_codes);

    for (j = 0; j < gummei_item_p->servedPLMNs.list.count; j++) {
      S1ap_PLMNidentity_t *plmn_identity_p;
      struct plmn_identity_s *new_plmn_identity_p;

      plmn_identity_p = gummei_item_p->servedPLMNs.list.array[i];
      new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s));
      TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc,
                      new_plmn_identity_p->mnc, new_plmn_identity_p->mnc_digit_length);
      STAILQ_INSERT_TAIL(&new_gummei_p->served_plmns, new_plmn_identity_p, next);
      new_gummei_p->nb_served_plmns++;
    }

    for (j = 0; j < gummei_item_p->servedGroupIDs.list.count; j++) {
      S1ap_MME_Group_ID_t           *mme_group_id_p;
      struct served_group_id_s *new_group_id_p;

      mme_group_id_p = gummei_item_p->servedGroupIDs.list.array[i];
      new_group_id_p = calloc(1, sizeof(struct served_group_id_s));
      OCTET_STRING_TO_INT16(mme_group_id_p, new_group_id_p->mme_group_id);
      STAILQ_INSERT_TAIL(&new_gummei_p->served_group_ids, new_group_id_p, next);
      new_gummei_p->nb_group_id++;
    }

    for (j = 0; j < gummei_item_p->servedMMECs.list.count; j++) {
      S1ap_MME_Code_t        *mme_code_p;
      struct mme_code_s *new_mme_code_p;

      mme_code_p = gummei_item_p->servedMMECs.list.array[i];
      new_mme_code_p = calloc(1, sizeof(struct mme_code_s));

      OCTET_STRING_TO_INT8(mme_code_p, new_mme_code_p->mme_code);
      STAILQ_INSERT_TAIL(&new_gummei_p->mme_codes, new_mme_code_p, next);
      new_gummei_p->nb_mme_code++;
    }

    STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
  }

  /* Free contents of the list */
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1ap_ServedGUMMEIs,
                                (void *)&s1SetupResponse_p->servedGUMMEIs);
  /* Set the capacity of this MME */
  mme_desc_p->relative_mme_capacity = s1SetupResponse_p->relativeMMECapacity;

  /* Optionaly set the mme name */
  if (s1SetupResponse_p->presenceMask & S1AP_S1SETUPRESPONSEIES_MMENAME_PRESENT) {
    mme_desc_p->mme_name = calloc(s1SetupResponse_p->mmEname.size + 1, sizeof(char));
    memcpy(mme_desc_p->mme_name, s1SetupResponse_p->mmEname.buf,
           s1SetupResponse_p->mmEname.size);
    /* Convert the mme name to a printable string */
    mme_desc_p->mme_name[s1SetupResponse_p->mmEname.size] = '\0';
  }

  /* The association is now ready as eNB and MME know parameters of each other.
   * Mark the association as UP to enable UE contexts creation.
   */
  mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
  mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++;
  s1ap_handle_s1_setup_message(mme_desc_p, 0);

#if 0
  /* We call back our self
   * -> generate a dummy initial UE message
   */
  {
    s1ap_nas_first_req_t s1ap_nas_first_req;

    memset(&s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t));

    s1ap_nas_first_req.rnti = 0xC03A;
    s1ap_nas_first_req.establishment_cause = RRC_CAUSE_MO_DATA;
    s1ap_nas_first_req.ue_identity.presenceMask = UE_IDENTITIES_gummei;

    s1ap_nas_first_req.ue_identity.gummei.mcc = 208;
    s1ap_nas_first_req.ue_identity.gummei.mnc = 34;
    s1ap_nas_first_req.ue_identity.gummei.mme_code = 0;
    s1ap_nas_first_req.ue_identity.gummei.mme_group_id = 0;

    /* NAS Attach request with IMSI */
    static uint8_t nas_attach_req_imsi[] = {
      0x07, 0x41,
      /* EPS Mobile identity = IMSI */
      0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87,
      0xF9,
      /* End of EPS Mobile Identity */
      0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
      0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
      0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
      0x01, 0x27, 0x11,
    };

    /* NAS Attach request with GUTI */
    static uint8_t nas_attach_req_guti[] = {
      0x07, 0x41,
      /* EPS Mobile identity = IMSI */
      0x71, 0x0B, 0xF6, 0x12, 0xF2, 0x01, 0x80, 0x00, 0x01, 0xE0, 0x00,
      0xDA, 0x1F,
      /* End of EPS Mobile Identity */
      0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
      0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
      0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
      0x01, 0x27, 0x11,
    };

    s1ap_nas_first_req.nas_pdu.buffer = nas_attach_req_guti;
    s1ap_nas_first_req.nas_pdu.length = sizeof(nas_attach_req_guti);

    s1ap_eNB_handle_nas_first_req(mme_desc_p->s1ap_eNB_instance->instance,
                                  &s1ap_nas_first_req);
  }
#endif

  return 0;
}
static
int s1ap_eNB_handle_error_indication(uint32_t               assoc_id,
                                     uint32_t               stream,
                                     struct s1ap_message_s *message_p)
{
  S1ap_ErrorIndicationIEs_t   *s1_error_indication_p;
  s1ap_eNB_mme_data_t        *mme_desc_p;

  DevAssert(message_p != NULL);

  s1_error_indication_p = &message_p->msg.s1ap_ErrorIndicationIEs;

  /* S1 Setup Failure == Non UE-related procedure -> stream 0 */
  if (stream != 0) {
    S1AP_WARN("[SCTP %d] Received s1 Error indication on stream != 0 (%d)\n",
              assoc_id, stream);
  }

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received S1 Error indication for non existing "
               "MME context\n", assoc_id);
    return -1;
  }
  if ( s1_error_indication_p->presenceMask & S1AP_ERRORINDICATIONIES_MME_UE_S1AP_ID_PRESENT) {
	  	S1AP_WARN("Received S1 Error indication MME UE S1AP ID 0x%x\n", s1_error_indication_p->mme_ue_s1ap_id);
  }
  if ( s1_error_indication_p->presenceMask & S1AP_ERRORINDICATIONIES_ENB_UE_S1AP_ID_PRESENT) {
  	S1AP_WARN("Received S1 Error indication eNB UE S1AP ID 0x%x\n", s1_error_indication_p->eNB_UE_S1AP_ID);
  }

  if ( s1_error_indication_p->presenceMask & S1AP_ERRORINDICATIONIES_CAUSE_PRESENT) {
    switch(s1_error_indication_p->cause.present) {
      case S1ap_Cause_PR_NOTHING:
    	S1AP_WARN("Received S1 Error indication cause NOTHING\n");
      break;
      case S1ap_Cause_PR_radioNetwork:
      	switch (s1_error_indication_p->cause.choice.radioNetwork) {
	      case S1ap_CauseRadioNetwork_unspecified:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_unspecified\n");
            break;
  	      case S1ap_CauseRadioNetwork_tx2relocoverall_expiry:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_tx2relocoverall_expiry\n");
            break;
  	      case S1ap_CauseRadioNetwork_successful_handover:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_successful_handover\n");
            break;
  	      case S1ap_CauseRadioNetwork_release_due_to_eutran_generated_reason:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_release_due_to_eutran_generated_reason\n");
            break;
  	      case S1ap_CauseRadioNetwork_handover_cancelled:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_handover_cancelled\n");
            break;
  	      case S1ap_CauseRadioNetwork_partial_handover:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_partial_handover\n");
            break;
  	      case S1ap_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system\n");
            break;
  	      case S1ap_CauseRadioNetwork_ho_target_not_allowed:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_ho_target_not_allowed\n");
            break;
  	      case S1ap_CauseRadioNetwork_tS1relocoverall_expiry:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_tS1relocoverall_expiry\n");
            break;
  	      case S1ap_CauseRadioNetwork_tS1relocprep_expiry:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_tS1relocprep_expiry\n");
            break;
  	      case S1ap_CauseRadioNetwork_cell_not_available:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_cell_not_available\n");
            break;
  	      case S1ap_CauseRadioNetwork_unknown_targetID:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_unknown_targetID\n");
            break;
  	      case S1ap_CauseRadioNetwork_no_radio_resources_available_in_target_cell:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_no_radio_resources_available_in_target_cell\n");
            break;
  	      case S1ap_CauseRadioNetwork_unknown_mme_ue_s1ap_id:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_unknown_mme_ue_s1ap_id\n");
            break;
  	      case S1ap_CauseRadioNetwork_unknown_enb_ue_s1ap_id:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_unknown_enb_ue_s1ap_id\n");
            break;
  	      case S1ap_CauseRadioNetwork_unknown_pair_ue_s1ap_id:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_unknown_pair_ue_s1ap_id\n");
            break;
  	      case S1ap_CauseRadioNetwork_handover_desirable_for_radio_reason:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_handover_desirable_for_radio_reason\n");
            break;
  	      case S1ap_CauseRadioNetwork_time_critical_handover:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_time_critical_handover\n");
            break;
  	      case S1ap_CauseRadioNetwork_resource_optimisation_handover:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_resource_optimisation_handover\n");
            break;
  	      case S1ap_CauseRadioNetwork_reduce_load_in_serving_cell:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_reduce_load_in_serving_cell\n");
            break;
  	      case S1ap_CauseRadioNetwork_user_inactivity:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_user_inactivity\n");
            break;
  	      case S1ap_CauseRadioNetwork_radio_connection_with_ue_lost:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_radio_connection_with_ue_lost\n");
            break;
  	      case S1ap_CauseRadioNetwork_load_balancing_tau_required:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_load_balancing_tau_required\n");
            break;
  	      case S1ap_CauseRadioNetwork_cs_fallback_triggered:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_cs_fallback_triggered\n");
            break;
  	      case S1ap_CauseRadioNetwork_ue_not_available_for_ps_service:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_ue_not_available_for_ps_service\n");
            break;
  	      case S1ap_CauseRadioNetwork_radio_resources_not_available:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_radio_resources_not_available\n");
            break;
  	      case S1ap_CauseRadioNetwork_failure_in_radio_interface_procedure:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_failure_in_radio_interface_procedure\n");
            break;
  	      case S1ap_CauseRadioNetwork_invals1ap_id_qos_combination:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_invals1ap_id_qos_combination\n");
            break;
  	      case S1ap_CauseRadioNetwork_interrat_redirection:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_interrat_redirection\n");
            break;
  	      case S1ap_CauseRadioNetwork_interaction_with_other_procedure:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_interaction_with_other_procedure\n");
            break;
  	      case S1ap_CauseRadioNetwork_unknown_E_RAB_ID:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_unknown_E_RAB_ID\n");
            break;
  	      case S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances\n");
            break;
  	      case S1ap_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported\n");
            break;
  	      case S1ap_CauseRadioNetwork_s1_intra_system_handover_triggered:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_s1_intra_system_handover_triggered\n");
            break;
  	      case S1ap_CauseRadioNetwork_s1_inter_system_handover_triggered:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_s1_inter_system_handover_triggered\n");
            break;
  	      case S1ap_CauseRadioNetwork_x2_handover_triggered:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_x2_handover_triggered\n");
            break;
  	      case S1ap_CauseRadioNetwork_redirection_towards_1xRTT:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_redirection_towards_1xRTT\n");
            break;
  	      case S1ap_CauseRadioNetwork_not_supported_QCI_value:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_not_supported_QCI_value\n");
            break;
  	      case S1ap_CauseRadioNetwork_invals1ap_id_CSG_Id:
            S1AP_WARN("Received S1 Error indication S1ap_CauseRadioNetwork_invals1ap_id_CSG_Id\n");
            break;
      	  default:
            S1AP_WARN("Received S1 Error indication cause radio network case not handled\n");
      	}
      break;

      case S1ap_Cause_PR_transport:
      	switch (s1_error_indication_p->cause.choice.transport) {
    	  case S1ap_CauseTransport_transport_resource_unavailable:
            S1AP_WARN("Received S1 Error indication S1ap_CauseTransport_transport_resource_unavailable\n");
            break;
    	  case S1ap_CauseTransport_unspecified:
            S1AP_WARN("Received S1 Error indication S1ap_CauseTransport_unspecified\n");
            break;
      	  default:
            S1AP_WARN("Received S1 Error indication cause transport case not handled\n");
      	}
      break;

      case S1ap_Cause_PR_nas:
      	switch (s1_error_indication_p->cause.choice.nas) {
    	  case S1ap_CauseNas_normal_release:
            S1AP_WARN("Received S1 Error indication S1ap_CauseNas_normal_release\n");
            break;
      	  case S1ap_CauseNas_authentication_failure:
            S1AP_WARN("Received S1 Error indication S1ap_CauseNas_authentication_failure\n");
            break;
      	  case S1ap_CauseNas_detach:
            S1AP_WARN("Received S1 Error indication S1ap_CauseNas_detach\n");
            break;
      	  case S1ap_CauseNas_unspecified:
            S1AP_WARN("Received S1 Error indication S1ap_CauseNas_unspecified\n");
            break;
      	  case S1ap_CauseNas_csg_subscription_expiry:
            S1AP_WARN("Received S1 Error indication S1ap_CauseNas_csg_subscription_expiry\n");
            break;
      	  default:
            S1AP_WARN("Received S1 Error indication cause nas case not handled\n");
      	}
      break;

      case S1ap_Cause_PR_protocol:
      	switch (s1_error_indication_p->cause.choice.protocol) {
      	  case S1ap_CauseProtocol_transfer_syntax_error:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_transfer_syntax_error\n");
            break;
      	  case S1ap_CauseProtocol_abstract_syntax_error_reject:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_abstract_syntax_error_reject\n");
            break;
      	  case S1ap_CauseProtocol_abstract_syntax_error_ignore_and_notify:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_abstract_syntax_error_ignore_and_notify\n");
            break;
      	  case S1ap_CauseProtocol_message_not_compatible_with_receiver_state:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_message_not_compatible_with_receiver_state\n");
            break;
      	  case S1ap_CauseProtocol_semantic_error:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_semantic_error\n");
            break;
      	  case S1ap_CauseProtocol_abstract_syntax_error_falsely_constructed_message:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_abstract_syntax_error_falsely_constructed_message\n");
            break;
      	  case S1ap_CauseProtocol_unspecified:
            S1AP_WARN("Received S1 Error indication S1ap_CauseProtocol_unspecified\n");
            break;
      	  default:
            S1AP_WARN("Received S1 Error indication cause protocol case not handled\n");
      	}
      break;

      case S1ap_Cause_PR_misc:
        switch (s1_error_indication_p->cause.choice.protocol) {
          case S1ap_CauseMisc_control_processing_overload:
            S1AP_WARN("Received S1 Error indication S1ap_CauseMisc_control_processing_overload\n");
            break;
          case S1ap_CauseMisc_not_enough_user_plane_processing_resources:
        	S1AP_WARN("Received S1 Error indication S1ap_CauseMisc_not_enough_user_plane_processing_resources\n");
        	break;
          case S1ap_CauseMisc_hardware_failure:
        	S1AP_WARN("Received S1 Error indication S1ap_CauseMisc_hardware_failure\n");
        	break;
          case S1ap_CauseMisc_om_intervention:
        	S1AP_WARN("Received S1 Error indication S1ap_CauseMisc_om_intervention\n");
        	break;
          case S1ap_CauseMisc_unspecified:
        	S1AP_WARN("Received S1 Error indication S1ap_CauseMisc_unspecified\n");
        	break;
          case S1ap_CauseMisc_unknown_PLMN:
        	S1AP_WARN("Received S1 Error indication S1ap_CauseMisc_unknown_PLMN\n");
        	break;
          default:
            S1AP_WARN("Received S1 Error indication cause misc case not handled\n");
        }
      break;
    }
  }
  if ( s1_error_indication_p->presenceMask & S1AP_ERRORINDICATIONIES_CRITICALITYDIAGNOSTICS_PRESENT) {
    // TODO continue
  }
  // TODO continue

  return 0;
}
static
int s1ap_eNB_handle_ue_context_release_command(uint32_t               assoc_id,
    uint32_t               stream,
    struct s1ap_message_s *s1ap_message_p)
{
  s1ap_eNB_mme_data_t   *mme_desc_p       = NULL;
  s1ap_eNB_ue_context_t *ue_desc_p        = NULL;
  MessageDef            *message_p        = NULL;

  S1ap_UEContextReleaseCommandIEs_t *ueContextReleaseCommand_p;
  DevAssert(s1ap_message_p != NULL);

  ueContextReleaseCommand_p = &s1ap_message_p->msg.s1ap_UEContextReleaseCommandIEs;

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received UE context release command for non "
               "existing MME context\n", assoc_id);
    return -1;
  }

  S1ap_MME_UE_S1AP_ID_t    mme_ue_s1ap_id;
  S1ap_ENB_UE_S1AP_ID_t    enb_ue_s1ap_id;

  switch (ueContextReleaseCommand_p->uE_S1AP_IDs.present) {
  case S1ap_UE_S1AP_IDs_PR_uE_S1AP_ID_pair:
    enb_ue_s1ap_id = ueContextReleaseCommand_p->uE_S1AP_IDs.choice.uE_S1AP_ID_pair.eNB_UE_S1AP_ID;
    mme_ue_s1ap_id = ueContextReleaseCommand_p->uE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID;

    MSC_LOG_RX_MESSAGE(
    		MSC_S1AP_ENB,
    		MSC_S1AP_MME,
    		NULL,0,
    		"0 UEContextRelease/%s eNB_ue_s1ap_id "S1AP_UE_ID_FMT" mme_ue_s1ap_id "S1AP_UE_ID_FMT" len %u",
  		s1ap_direction2String[s1ap_message_p->direction],
  		enb_ue_s1ap_id,
  		mme_ue_s1ap_id);

    if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
                     enb_ue_s1ap_id)) == NULL) {
      S1AP_ERROR("[SCTP %d] Received UE context release command for non "
                 "existing UE context 0x%06x\n",
                 assoc_id,
                 enb_ue_s1ap_id);
      /*MessageDef *msg_complete_p;
      msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
      S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
      itti_send_msg_to_task(TASK_S1AP, ue_desc_p->eNB_instance->instance <=> 0, msg_complete_p);
      */
      return -1;
    } else {
      MSC_LOG_TX_MESSAGE(
    		  MSC_S1AP_ENB,
    		  MSC_RRC_ENB,
    		  NULL,0,
    		  "0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ",
    		  enb_ue_s1ap_id);

      message_p        = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND);
      S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
      itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
      return 0;
    }

    break;

#warning "TODO mapping mme_ue_s1ap_id  enb_ue_s1ap_id?"

  case S1ap_UE_S1AP_IDs_PR_mME_UE_S1AP_ID:
    mme_ue_s1ap_id = ueContextReleaseCommand_p->uE_S1AP_IDs.choice.mME_UE_S1AP_ID;
    S1AP_ERROR("TO DO mapping mme_ue_s1ap_id  enb_ue_s1ap_id");

  case S1ap_UE_S1AP_IDs_PR_NOTHING:
  default:
    S1AP_ERROR("S1AP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements");
    return -1;
  }
}
static
int s1ap_eNB_handle_initial_context_request(uint32_t               assoc_id,
    uint32_t               stream,
    struct s1ap_message_s *s1ap_message_p)
{
  int i;

  s1ap_eNB_mme_data_t   *mme_desc_p       = NULL;
  s1ap_eNB_ue_context_t *ue_desc_p        = NULL;
  MessageDef            *message_p        = NULL;

  S1ap_InitialContextSetupRequestIEs_t *initialContextSetupRequest_p;
  DevAssert(s1ap_message_p != NULL);

  initialContextSetupRequest_p = &s1ap_message_p->msg.s1ap_InitialContextSetupRequestIEs;

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
               "existing MME context\n", assoc_id);
    return -1;
  }

  if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
                   initialContextSetupRequest_p->eNB_UE_S1AP_ID)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
               "existing UE context 0x%06x\n", assoc_id,
               initialContextSetupRequest_p->eNB_UE_S1AP_ID);
    return -1;
  }

  /* Initial context request = UE-related procedure -> stream != 0 */
  if (stream == 0) {
    S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
               assoc_id, stream);
    return -1;
  }

  ue_desc_p->rx_stream = stream;

  ue_desc_p->mme_ue_s1ap_id = initialContextSetupRequest_p->mme_ue_s1ap_id;

  message_p        = itti_alloc_new_message(TASK_S1AP, S1AP_INITIAL_CONTEXT_SETUP_REQ);

  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id  = ue_desc_p->ue_initial_id;
  ue_desc_p->ue_initial_id = 0;

  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_e_rabs =
    initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.s1ap_E_RABToBeSetupItemCtxtSUReq.count;

  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul = 64;// TO DO(bitrate_t)(initialContextSetupRequest_p->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL);
  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl = 1024;//(bitrate_t)(initialContextSetupRequest_p->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL);

  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.encryption_algorithms =
    BIT_STRING_to_uint16(&initialContextSetupRequest_p->ueSecurityCapabilities.encryptionAlgorithms);
  S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
    BIT_STRING_to_uint16(&initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms);

  /* Copy the security key */
  memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
         initialContextSetupRequest_p->securityKey.buf, initialContextSetupRequest_p->securityKey.size);

  for (i = 0; i < initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.s1ap_E_RABToBeSetupItemCtxtSUReq.count; i++) {
    S1ap_E_RABToBeSetupItemCtxtSUReq_t *item_p;

    item_p = (S1ap_E_RABToBeSetupItemCtxtSUReq_t *)initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.s1ap_E_RABToBeSetupItemCtxtSUReq.array[i];

    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].e_rab_id = item_p->e_RAB_ID;

    if (item_p->nAS_PDU != NULL) {
      /* Only copy NAS pdu if present */
      S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = item_p->nAS_PDU->size;

      S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer =
        malloc(sizeof(uint8_t) * item_p->nAS_PDU->size);

      memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer,
             item_p->nAS_PDU->buf, item_p->nAS_PDU->size);
    } else {
      S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = 0;
      S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = NULL;
    }

    /* Set the transport layer address */
    memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.buffer,
           item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size);
    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.length =
      item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused;

    /* GTP tunnel endpoint ID */
    OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].gtp_teid);

    /* Set the QOS informations */
    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI;

    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.priority_level =
      item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel;
    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability =
      item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability =
      item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
  }

  itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);

  return 0;
}
Пример #21
0
static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
    S1ap_InitiatingMessage_t *initiating_p)
{
    int         ret = -1;
    MessageDef *message_p;
    char       *message_string = NULL;
    size_t      message_string_size;
    MessagesIds message_id;

    DevAssert(initiating_p != NULL);

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

    s1ap_string_total_size = 0;

    message->procedureCode = initiating_p->procedureCode;
    message->criticality   = initiating_p->criticality;

    switch(initiating_p->procedureCode)
    {
        case S1ap_ProcedureCode_id_downlinkNASTransport:
            ret = s1ap_decode_s1ap_downlinknastransporties(
                &message->msg.s1ap_DownlinkNASTransportIEs,
                &initiating_p->value);
            s1ap_xer_print_s1ap_downlinknastransport(s1ap_xer__print2sp,
                    message_string,
                    message);
            message_id          = S1AP_DOWNLINK_NAS_LOG;
            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_downlink_nas_log.size = message_string_size;
            memcpy(&message_p->ittiMsg.s1ap_downlink_nas_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_InitialContextSetup:
            ret = s1ap_decode_s1ap_initialcontextsetuprequesties(
                &message->msg.s1ap_InitialContextSetupRequestIEs, &initiating_p->value);
            s1ap_xer_print_s1ap_initialcontextsetuprequest(s1ap_xer__print2sp, message_string, message);
            message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG;
            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_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_decode_s1ap_uecontextreleasecommandies(
                &message->msg.s1ap_UEContextReleaseCommandIEs, &initiating_p->value);
            s1ap_xer_print_s1ap_uecontextreleasecommand(s1ap_xer__print2sp, message_string, message);
            message_id = S1AP_UE_CONTEXT_RELEASE_COMMAND_LOG;
            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_ue_context_release_command_log.size = message_string_size;
            memcpy(&message_p->ittiMsg.s1ap_ue_context_release_command_log.text, message_string, message_string_size);
            itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
            free(message_string);
            break;

        default:
            S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
                       (int)initiating_p->procedureCode);
            AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n",
                       (int)initiating_p->procedureCode);
            return -1;
    }



    return ret;
}
Пример #22
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;
}