int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out)
{
  uint8_t *data = NULL;

  uint32_t byte_length;

  DevAssert(stream_cipher != NULL);
  DevAssert(out != NULL);

  LOG_D(OSA, "Entering stream_encrypt_eea0, bits length %u, bearer %u, "
        "count %u, direction %s\n", stream_cipher->blength,
        stream_cipher->bearer, stream_cipher->count, stream_cipher->direction == SECU_DIRECTION_DOWNLINK ?
        "Downlink" : "Uplink");

  byte_length = (stream_cipher->blength + 7) >> 3;

  if (*out == NULL) {
    /* User did not provide output buffer */
    data = malloc(byte_length);
    *out = data;
  } else {
    data = *out;
  }

  memcpy (data, stream_cipher->message, byte_length);

  return 0;
}
Beispiel #2
0
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp)
{
  s1ap_eNB_instance_t *instance_p;
  s1ap_eNB_mme_data_t *s1ap_mme_data_p;

  DevAssert(sctp_new_association_resp != NULL);

  instance_p = s1ap_eNB_get_instance(instance);
  DevAssert(instance_p != NULL);

  s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1,
                                     sctp_new_association_resp->ulp_cnx_id);
  DevAssert(s1ap_mme_data_p != NULL);

  if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
    S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
              sctp_new_association_resp->sctp_state,
              instance,
              sctp_new_association_resp->ulp_cnx_id);

    s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);

    return;
  }

  /* Update parameters */
  s1ap_mme_data_p->assoc_id    = sctp_new_association_resp->assoc_id;
  s1ap_mme_data_p->in_streams  = sctp_new_association_resp->in_streams;
  s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;

  /* Prepare new S1 Setup Request */
  s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p);
}
/* @brief compare a given ta list against the one provided by mme configuration.
   @param ta_list
   @return - TA_LIST_UNKNOWN_PLMN if at least one TAC match and no PLMN match
           - TA_LIST_UNKNOWN_TAC if at least one PLMN match and no TAC match
           - TA_LIST_RET_OK if both tac and plmn match at least one element
*/
int
s1ap_mme_compare_ta_lists (
  S1ap_SupportedTAs_t * ta_list)
{
  int                                     i;
  int                                     tac_ret,
                                          bplmn_ret;

  DevAssert (ta_list != NULL);

  /*
   * Parse every item in the list and try to find matching parameters
   */
  for (i = 0; i < ta_list->list.count; i++) {
    S1ap_SupportedTAs_Item_t               *ta;

    ta = ta_list->list.array[i];
    DevAssert (ta != NULL);
    tac_ret = s1ap_mme_compare_tac (&ta->tAC);
    bplmn_ret = s1ap_mme_compare_plmns (&ta->broadcastPLMNs);

    if (tac_ret == TA_LIST_NO_MATCH && bplmn_ret == TA_LIST_NO_MATCH) {
      return TA_LIST_UNKNOWN_PLMN + TA_LIST_UNKNOWN_TAC;
    } else {
      if (tac_ret > TA_LIST_NO_MATCH && bplmn_ret == TA_LIST_NO_MATCH) {
        return TA_LIST_UNKNOWN_PLMN;
      } else if (tac_ret == TA_LIST_NO_MATCH && bplmn_ret > TA_LIST_NO_MATCH) {
        return TA_LIST_UNKNOWN_TAC;
      }
    }
  }

  return TA_LIST_RET_OK;
}
Beispiel #4
0
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB)
{
  s1ap_eNB_instance_t *new_instance;
  uint8_t index;
  
  DevAssert(s1ap_register_eNB != NULL);

  /* Look if the provided instance already exists */
  new_instance = s1ap_eNB_get_instance(instance);
  
 
  if (new_instance != NULL) { 
    /* Checks if it is a retry on the same eNB */
    DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0);
    DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0);
    DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0);
    DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0);
    DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0);
    DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0);
    DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0);
  } else {
    new_instance = calloc(1, sizeof(s1ap_eNB_instance_t));
    DevAssert(new_instance != NULL);

    RB_INIT(&new_instance->s1ap_ue_head);
    RB_INIT(&new_instance->s1ap_mme_head);

    /* Copy usefull parameters */
    new_instance->instance         = instance;
    new_instance->eNB_name         = s1ap_register_eNB->eNB_name;
    new_instance->eNB_id           = s1ap_register_eNB->eNB_id;
    new_instance->cell_type        = s1ap_register_eNB->cell_type;
    new_instance->tac              = s1ap_register_eNB->tac;
    new_instance->mcc              = s1ap_register_eNB->mcc;
    new_instance->mnc              = s1ap_register_eNB->mnc;
    new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length;
    new_instance->default_drx      = s1ap_register_eNB->default_drx;

    /* Add the new instance to the list of eNB (meaningfull in virtual mode) */
    s1ap_eNB_insert_new_instance(new_instance);

    S1AP_INFO("Registered new eNB[%d] and %s eNB id %u\n",
               instance,
               s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
               s1ap_register_eNB->eNB_id);
  }

  DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS,
           S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0);

  /* Trying to connect to provided list of MME ip address */
  for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
    s1ap_eNB_register_mme(new_instance,
    		          &s1ap_register_eNB->mme_ip_address[index],
                          &s1ap_register_eNB->enb_ip_address,
                          s1ap_register_eNB->sctp_in_streams,
                          s1ap_register_eNB->sctp_out_streams);
  }
}
Beispiel #5
0
void *s6a_thread(void *args)
{
    itti_mark_task_ready(TASK_S6A);

    while(1) {
        MessageDef *received_message_p = NULL;
        /* Trying to fetch a message from the message queue.
         * If the queue is empty, this function will block till a
         * message is sent to the task.
         */
        itti_receive_msg(TASK_S6A, &received_message_p);
        DevAssert(received_message_p != NULL);

        switch (ITTI_MSG_ID(received_message_p))
        {
            case S6A_UPDATE_LOCATION_REQ: {
                s6a_generate_update_location(&received_message_p->ittiMsg.s6a_update_location_req);
            } break;
            case S6A_AUTH_INFO_REQ: {
                s6a_generate_authentication_info_req(&received_message_p->ittiMsg.s6a_auth_info_req);
            } break;
            case TERMINATE_MESSAGE: {
                itti_exit_task();
            } break;
            default: {
                S6A_DEBUG("Unkwnon message ID %d:%s\n",
                          ITTI_MSG_ID(received_message_p), ITTI_MSG_NAME(received_message_p));
            } break;
        }
        itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
        received_message_p = NULL;
    }
    return NULL;
}
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;
}
int s1ap_eNB_handle_overload_stop(uint32_t               assoc_id,
                                  uint32_t               stream,
                                  struct s1ap_message_s *message_p)
{
  /* We received Overload stop message, meaning that the MME is no more
   * overloaded. This is an empty message, with only message header and no
   * Information Element.
   */

  DevAssert(message_p != NULL);

  s1ap_eNB_mme_data_t *mme_desc_p;

  /* Non UE-associated signalling -> stream 0 */
  DevCheck(stream == 0, stream, 0, 0);

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    /* No MME context associated */
    return -1;
  }

  mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
  mme_desc_p->overload_state = S1AP_NO_OVERLOAD;
  return 0;
}
int s1ap_eNB_handle_overload_start(uint32_t               assoc_id,
                                   uint32_t               stream,
                                   struct s1ap_message_s *message_p)
{
  S1ap_OverloadStartIEs_t *overload_start_p;
  s1ap_eNB_mme_data_t     *mme_desc_p;

  DevAssert(message_p != NULL);

  overload_start_p = &message_p->msg.s1ap_OverloadStartIEs;

  DevCheck(overload_start_p->overloadResponse.present ==
           S1ap_OverloadResponse_PR_overloadAction,
           S1ap_OverloadResponse_PR_overloadAction, 0, 0);

  /* Non UE-associated signalling -> stream 0 */
  DevCheck(stream == 0, stream, 0, 0);

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    /* No MME context associated */
    return -1;
  }

  /* Mark the MME as overloaded and set the overload state according to
   * the value received.
   */
  mme_desc_p->state = S1AP_ENB_OVERLOAD;
  mme_desc_p->overload_state =
    overload_start_p->overloadResponse.choice.overloadAction;

  return 0;
}
/* 
 * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller 
 * and can interact with other itti tasks
*/
void *flexran_agent_task(void *args){

  //flexran_agent_instance_t         *d = (flexran_agent_instance_t *) args;
  Protocol__FlexranMessage *msg;
  void *data;
  int size;
  err_code_t err_code;
  int                   priority = 0;

  MessageDef                     *msg_p           = NULL;
  const char                     *msg_name        = NULL;
  int                             result;
  struct flexran_agent_timer_element_s * elem = NULL;

  itti_mark_task_ready(TASK_FLEXRAN_AGENT);

  do {
    // Wait for a message
    itti_receive_msg (TASK_FLEXRAN_AGENT, &msg_p);
    DevAssert(msg_p != NULL);
    msg_name = ITTI_MSG_NAME (msg_p);

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

    case MESSAGE_TEST:
      LOG_I(FLEXRAN_AGENT, "Received %s\n", ITTI_MSG_NAME(msg_p));
      break;
    
    case TIMER_HAS_EXPIRED:
      msg = flexran_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, msg_p->ittiMsg.timer_has_expired.arg);
      if (msg != NULL){
	data=flexran_agent_pack_message(msg,&size);
	elem = get_timer_entry(msg_p->ittiMsg.timer_has_expired.timer_id);
	if (flexran_agent_msg_send(elem->agent_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) {
	  err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
	  goto error;
	}

	LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
      }
      break;

    default:
      LOG_E(FLEXRAN_AGENT, "Received unexpected message %s\n", msg_name);
      break;
    }

    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    continue;
  error:
    LOG_E(FLEXRAN_AGENT,"flexran_agent_task: error %d occured\n",err_code);
  } while (1);

  return NULL;
}
//compute average channel_level on each (TX,RX) antenna pair
int dl_channel_level(int16_t *dl_ch,
                     LTE_DL_FRAME_PARMS *frame_parms)
{

    int16_t rb;
#if defined(__x86_64__) || defined(__i386__)
    __m128i *dl_ch128;
#elif defined(__arm__)
    int16x4_t *dl_ch128;
#endif
    int avg;

    //clear average level
#if defined(__x86_64__) || defined(__i386__)
    avg128F = _mm_setzero_si128();
    dl_ch128=(__m128i *)dl_ch;

    for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

        avg128F = _mm_add_epi32(avg128F,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
        avg128F = _mm_add_epi32(avg128F,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
        avg128F = _mm_add_epi32(avg128F,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));

        dl_ch128+=3;

    }
#elif defined(__arm__)
    avg128F = vdupq_n_s32(0);
    dl_ch128=(int16x4_t *)dl_ch;

    for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

        avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[0],dl_ch128[0]));
        avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[1],dl_ch128[1]));
        avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[2],dl_ch128[2]));
        avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[3],dl_ch128[3]));
        avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[4],dl_ch128[4]));
        avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[5],dl_ch128[5]));
        dl_ch128+=6;


    }


#endif
    DevAssert( frame_parms->N_RB_DL );
    avg = (((int*)&avg128F)[0] +
           ((int*)&avg128F)[1] +
           ((int*)&avg128F)[2] +
           ((int*)&avg128F)[3])/(frame_parms->N_RB_DL*12);


#if defined(__x86_64__) || defined(__i386__)
    _mm_empty();
    _m_empty();
#endif
    return(avg);
}
Beispiel #11
0
uint32_t s1ap_generate_eNB_id(void)
{
  char    *out;
  char     hostname[50];
  int      ret;
  uint32_t eNB_id;

  /* Retrieve the host name */
  ret = gethostname(hostname, sizeof(hostname));
  DevAssert(ret == 0);

  out = crypt(hostname, "eurecom");
  DevAssert(out != NULL);

  eNB_id = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | out[3]);

  return eNB_id;
}
int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor)
{

  uint32_t Nre,sumKr,MPR_x100,Kr,r;
  uint16_t beta_offset_pusch;

  DevAssert( UE_id < NUMBER_OF_UE_MAX+1 );
  DevAssert( harq_pid < 8 );

  Nre = phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->Nsymb_initial *
        phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb*12;

  sumKr = 0;

  for (r=0; r<phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->C; r++) {
    if (r<phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->Cminus)
      Kr = phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->Kminus;
    else
      Kr = phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->Kplus;

    sumKr += Kr;
  }

  if (Nre==0)
    return(0);

  MPR_x100 = 100*sumKr/Nre;
  // Note: MPR=is the effective spectral efficiency of the PUSCH
  // FK 20140908 sumKr is only set after the ulsch_encoding

  beta_offset_pusch = 8;
  //(phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->control_only == 1) ? phy_vars_eNB->ulsch_eNB[UE_id]->beta_offset_cqi_times8:8;

  DevAssert( UE_id < NUMBER_OF_UE_MAX );
#warning "This condition happens sometimes. Need more investigation" // navid
  //DevAssert( MPR_x100/6 < 100 );

  if (phy_vars_eNB->ul_power_control_dedicated[UE_id].deltaMCS_Enabled == 1) {
    // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch)
    if (bw_factor == 1) {
      uint8_t nb_rb = phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb;
      return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1];
    } else
      return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3));
double compute_sinr(channel_desc_t *desc,
                    channel_desc_t *desc_i1,
                    channel_desc_t *desc_i2,
                    double snr_dB,double snr_i1_dB,
                    double snr_i2_dB,
                    uint16_t nb_rb)
{

  double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB);
  uint16_t f;
  uint8_t aarx,aatx;
  double S;
  struct complex S_i1;
  struct complex S_i2;

  DevAssert( nb_rb > 0 );

  avg_sinr=0.0;

  //  printf("nb_rb %d\n",nb_rb);
  for (f=0; f<2*nb_rb; f++) {
    S = 0.0;
    S_i1.x =0.0;
    S_i1.y =0.0;
    S_i2.x =0.0;
    S_i2.y =0.0;

    for (aarx=0; aarx<desc->nb_rx; aarx++) {
      for (aatx=0; aatx<desc->nb_tx; aatx++) {
        S    += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x +
                 desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y);

        if (desc_i1) {
          S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x +
                     desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y);
          S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y -
                     desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x);
        }

        if (desc_i2) {
          S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x +
                     desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y);
          S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y -
                     desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x);
        }
      }
    }

    //        printf("f %d : S %f, S_i1 %f, S_i2 %f\n",f-nb_rb,snr*S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y));
    avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)));
  }

  //  printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2);
  return(10*log10(avg_sinr/(nb_rb*2)));
}
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;
}
int
mme_app_handle_s1ap_ue_capabilities_ind (
  const s1ap_ue_cap_ind_t const *s1ap_ue_cap_ind_pP)
{
  DevAssert (s1ap_ue_cap_ind_pP != NULL);
  //unsigned eNB_ue_s1ap_id:24;
  //uint32_t mme_ue_s1ap_id;
  //uint8_t  radio_capabilities[100];
  //uint32_t radio_capabilities_length;
  return 0;
}
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;
}
Beispiel #17
0
struct emm_data_context_s *emm_data_context_get(
    emm_data_t *emm_data, unsigned int _ueid)
{
    struct emm_data_context_s reference;

    DevAssert(emm_data != NULL);
    DevCheck(_ueid > 0, _ueid, 0, 0);

    memset(&reference, 0, sizeof(struct emm_data_context_s));
    reference.ueid = _ueid;
    return RB_FIND(emm_data_context_map, &emm_data->ctx_map, &reference);
}
static void *gtpv1u_thread(void *args)
{
  itti_mark_task_ready(TASK_GTPV1_U);
  MSC_START_USE();

  while(1) {
    /* Trying to fetch a message from the message queue.
     * If the queue is empty, this function will block till a
     * message is sent to the task.
     */
    MessageDef *received_message_p = NULL;
    itti_receive_msg(TASK_GTPV1_U, &received_message_p);
    DevAssert(received_message_p != NULL);


    switch (ITTI_MSG_ID(received_message_p)) {

    case TERMINATE_MESSAGE: {
      itti_exit_task();
    }
    break;

    // DATA COMING FROM UDP
    case UDP_DATA_IND: {
      udp_data_ind_t *udp_data_ind_p;
      udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind;
      nwGtpv1uProcessUdpReq(gtpv1u_sgw_data.gtpv1u_stack,
                             udp_data_ind_p->buffer,
                             udp_data_ind_p->buffer_length,
                             udp_data_ind_p->peer_port,
                             udp_data_ind_p->peer_address);
       //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer);
    }
    break;

    case TIMER_HAS_EXPIRED:
      nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg);
      break;

    default: {
      GTPU_ERROR("Unkwnon message ID %d:%s\n",
                 ITTI_MSG_ID(received_message_p),
                 ITTI_MSG_NAME(received_message_p));
    }
    break;
    }

    itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
    received_message_p = NULL;
  }

  return NULL;
}
int
s11_sgw_handle_delete_session_response (
  NwGtpv2cStackHandleT * stack_p,
  SgwDeleteSessionResponse * delete_session_response_p)
{
  NwRcT                                   rc;
  NwGtpv2cUlpApiT                         ulp_req;
  NwGtpv2cTrxnHandleT                     trxn;
  gtp_cause_t                             cause;

  DevAssert (delete_session_response_p != NULL);
  DevAssert (stack_p != NULL);
  trxn = (NwGtpv2cTrxnHandleT) delete_session_response_p->trxn;
  DevAssert (trxn != 0);
  /*
   * Prepare a create session response to send to MME.
   */
  memset (&ulp_req, 0, sizeof (NwGtpv2cUlpApiT));
  memset (&cause, 0, sizeof (gtp_cause_t));
  ulp_req.apiType = NW_GTPV2C_ULP_API_TRIGGERED_RSP;
  ulp_req.apiInfo.triggeredRspInfo.hTrxn = trxn;
  rc = nwGtpv2cMsgNew (*stack_p, NW_TRUE, NW_GTP_DELETE_SESSION_RSP, 0, 0, &(ulp_req.hMsg));
  DevAssert (NW_OK == rc);
  /*
   * Set the remote TEID
   */
  rc = nwGtpv2cMsgSetTeid (ulp_req.hMsg, delete_session_response_p->teid);
  DevAssert (NW_OK == rc);
  cause.cause_value = delete_session_response_p->cause;
  s11_cause_ie_set (&(ulp_req.hMsg), &cause);
  rc = nwGtpv2cProcessUlpReq (*stack_p, &ulp_req);
  DevAssert (NW_OK == rc);
  return 0;
}
struct emm_common_data_s               *
emm_common_data_context_get (
  struct emm_common_data_head_s *root,
  unsigned int _ueid)
{
  struct emm_common_data_s                reference;

  DevAssert (root != NULL);
  DevCheck (_ueid > 0, _ueid, 0, 0);
  memset (&reference, 0, sizeof (struct emm_common_data_s));
  reference.ueid = _ueid;
  return RB_FIND (emm_common_data_map, &root->emm_common_data_root, &reference);
}
int
s11_sgw_handle_create_session_response (
  NwGtpv2cStackHandleT * stack_p,
  SgwCreateSessionResponse * create_session_response_p)
{
  NwRcT                                   rc;
  NwGtpv2cUlpApiT                         ulp_req;
  NwGtpv2cTrxnHandleT                     trxn;
  gtp_cause_t                             cause;

  DevAssert (create_session_response_p != NULL);
  DevAssert (stack_p != NULL);
  trxn = (NwGtpv2cTrxnHandleT) create_session_response_p->trxn;
  DevAssert (trxn != 0);
  /*
   * Create a tunnel for the GTPv2-C stack
   */
  memset (&ulp_req, 0, sizeof (NwGtpv2cUlpApiT));
  ulp_req.apiType = NW_GTPV2C_ULP_CREATE_LOCAL_TUNNEL;
  ulp_req.apiInfo.createLocalTunnelInfo.teidLocal = create_session_response_p->s11_sgw_teid.teid;
  ulp_req.apiInfo.createLocalTunnelInfo.peerIp = create_session_response_p->peer_ip;
  rc = nwGtpv2cProcessUlpReq (*stack_p, &ulp_req);
  DevAssert (NW_OK == rc);
  /*
   * Prepare a create session response to send to MME.
   */
  memset (&ulp_req, 0, sizeof (NwGtpv2cUlpApiT));
  memset (&cause, 0, sizeof (gtp_cause_t));
  ulp_req.apiType = NW_GTPV2C_ULP_API_TRIGGERED_RSP;
  ulp_req.apiInfo.triggeredRspInfo.hTrxn = trxn;
  rc = nwGtpv2cMsgNew (*stack_p, NW_TRUE, NW_GTP_CREATE_SESSION_RSP, 0, 0, &(ulp_req.hMsg));
  DevAssert (NW_OK == rc);
  /*
   * Set the remote TEID
   */
  rc = nwGtpv2cMsgSetTeid (ulp_req.hMsg, create_session_response_p->teid);
  DevAssert (NW_OK == rc);
  cause.cause_value = (uint8_t) create_session_response_p->cause;
  s11_cause_ie_set (&(ulp_req.hMsg), &cause);
  rc = nwGtpv2cMsgAddIeFteid ((ulp_req.hMsg), NW_GTPV2C_IE_INSTANCE_ZERO, S1_U_SGW_GTP_U, create_session_response_p->s11_sgw_teid.teid, 0xC0A80EA2, NULL);
  s11_paa_ie_set (&(ulp_req.hMsg), &create_session_response_p->paa);
  /*
   * Put 0 for now i.e. no existing context or restriction
   */
  s11_apn_restriction_ie_set (&(ulp_req.hMsg), 0);
  s11_bearer_context_created_ie_set (&(ulp_req.hMsg), &create_session_response_p->bearer_context_created);
  rc = nwGtpv2cProcessUlpReq (*stack_p, &ulp_req);
  DevAssert (NW_OK == rc);
  return 0;
}
Beispiel #22
0
static
void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind)
{
  int result;

  DevAssert(sctp_data_ind != NULL);
#if defined(TEST_S1C_MME)
  mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
#else
  s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
#endif
  result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
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;
}
/* ULP callback for the GTPv2-C stack */
static
NwRcT s11_sgw_ulp_process_stack_req_cb(
  NwGtpv2cUlpHandleT hUlp, NwGtpv2cUlpApiT *pUlpApi)
{
  int ret = 0;

  DevAssert(pUlpApi != NULL);

  switch (pUlpApi->apiType) {
  case NW_GTPV2C_ULP_API_INITIAL_REQ_IND:
    S11_DEBUG("Received initial req indication\n");

    switch (pUlpApi->apiInfo.initialReqIndInfo.msgType) {
    case NW_GTP_CREATE_SESSION_REQ:
      ret = s11_sgw_handle_create_session_request(
              &s11_sgw_stack_handle, pUlpApi);
      break;

    case NW_GTP_MODIFY_BEARER_REQ:
      ret = s11_sgw_handle_modify_bearer_request(
              &s11_sgw_stack_handle, pUlpApi);
      break;

    case NW_GTP_DELETE_SESSION_REQ:
      ret = s11_sgw_handle_delete_session_request(
              &s11_sgw_stack_handle, pUlpApi);
      break;

    default:
      S11_WARN("Received unhandled message type %d\n",
               pUlpApi->apiInfo.initialReqIndInfo.msgType);
      break;
    }

    break;

  default:
    S11_ERROR("Received unknown stack req message %d\n",
              pUlpApi->apiType);
    break;
  }

  return ret == -1 ? NW_FAILURE : NW_OK;
}
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 s6a_parse_experimental_result(struct avp *avp, s6a_experimental_result_t *ptr)
{
  struct avp_hdr *hdr;
  struct avp *child_avp = NULL;

  if (!avp) {
    return EINVAL;
  }

  CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
  DevAssert(hdr->avp_code == AVP_CODE_EXPERIMENTAL_RESULT);
  CHECK_FCT(fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &child_avp, NULL));

  while(child_avp) {
    CHECK_FCT(fd_msg_avp_hdr(child_avp, &hdr));

    switch(hdr->avp_code) {
    case AVP_CODE_EXPERIMENTAL_RESULT_CODE:
      S6A_ERROR("Got experimental error %u:%s\n", hdr->avp_value->u32,
                experimental_retcode_2_string(hdr->avp_value->u32));

      if (ptr) {
        *ptr = (s6a_experimental_result_t)hdr->avp_value->u32;
      }

      break;

    case AVP_CODE_VENDOR_ID:
      DevCheck(hdr->avp_value->u32 == 10415, hdr->avp_value->u32,
               AVP_CODE_VENDOR_ID, 10415);
      break;

    default:
      return -1;
    }

    /* Go to next AVP in the grouped AVP */
    CHECK_FCT(fd_msg_browse(child_avp, MSG_BRW_NEXT, &child_avp, NULL));
  }

  return 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;
}
static int sctp_send_msg(int32_t sctp_assoc_id, uint16_t stream,
                         const uint8_t *buffer, const uint32_t length)
{
    struct sctp_association_s *assoc_desc = NULL;

    DevAssert(buffer != NULL);

    if ((assoc_desc = sctp_is_assoc_in_list(sctp_assoc_id)) == NULL) {
        SCTP_DEBUG("This assoc id has not been fount in list (%d)\n",
                   sctp_assoc_id);
        return -1;
    }

    if (assoc_desc->sd == -1) {
        /* The socket is invalid may be closed.
         */
        return -1;
    }

    SCTP_DEBUG("[%d][%d] Sending buffer %p of %d bytes on stream %d with ppid %d\n",
               assoc_desc->sd, sctp_assoc_id, buffer,
               length, stream, assoc_desc->ppid);

    /* Send message_p on specified stream of the sd association */
    if (sctp_sendmsg(assoc_desc->sd,
                     (const void *)buffer,
                     length,
                     NULL,
                     0,
                     assoc_desc->ppid, 0, stream, 0, 0) < 0) {
        SCTP_ERROR("send: %s:%d", strerror(errno), errno);
        return -1;
    }

    assoc_desc->messages_sent++;

    SCTP_DEBUG("Successfully sent %d bytes on stream %d\n", length, stream);

    return 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;
}
/* @brief compare a list of broadcasted plmns against the MME configured.
*/
static
  int
s1ap_mme_compare_plmns (
  S1ap_BPLMNs_t * b_plmns)
{
  int                                     i;
  int                                     matching_occurence = 0;

  DevAssert (b_plmns != NULL);

  for (i = 0; i < b_plmns->list.count; i++) {
    if (s1ap_mme_compare_plmn (b_plmns->list.array[i])
        == TA_LIST_AT_LEAST_ONE_MATCH)
      matching_occurence++;
  }

  if (matching_occurence == 0)
    return TA_LIST_NO_MATCH;
  else if (matching_occurence == b_plmns->list.count - 1)
    return TA_LIST_COMPLETE_MATCH;
  else
    return TA_LIST_AT_LEAST_ONE_MATCH;
}