//------------------------------------------------------------------------------ static uint32_t eNB_app_register(const uint32_t enb_id_start, const uint32_t enb_id_end, const Enb_properties_array_t *enb_properties) //------------------------------------------------------------------------------ { uint32_t enb_id; uint32_t mme_id; MessageDef *msg_p; uint32_t register_enb_pending = 0; char *str = NULL; struct in_addr addr; // 1 eNB should be max. // 1 eNB should be max. for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { { s1ap_register_enb_req_t *s1ap_register_eNB; /* note: there is an implicit relationship between the data structure and the message name */ msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p); /* Some default/random parameters */ s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id; s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type; s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name; s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac; s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc; s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc; s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0]; s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme; AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme, S1AP_MAX_NB_MME_IP_ADDRESS); for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++) { s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4; s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6; strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address, enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address, sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address)); strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address, enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address, sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address)); } s1ap_register_eNB->enb_ip_address.ipv6 = 0; s1ap_register_eNB->enb_ip_address.ipv4 = 1; addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME; str = inet_ntoa(addr); strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str); itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); register_enb_pending++; } } return register_enb_pending; }
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; }