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; }
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; }
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); } }
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); }
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; }
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; }
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; }