diff --git a/openair-cn/S1AP/s1ap_eNB_handlers.c b/openair-cn/S1AP/s1ap_eNB_handlers.c index 571a96552f6eb61d881ac7ecc94b6b2b7942e26c..724d8133b0bb81605d49f00430c2240d82d5a446 100644 --- a/openair-cn/S1AP/s1ap_eNB_handlers.c +++ b/openair-cn/S1AP/s1ap_eNB_handlers.c @@ -218,7 +218,12 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, uint32_t stream, struct s1ap_message_s *message_p) { - s1ap_eNB_mme_data_t *mme_desc_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) { @@ -232,7 +237,12 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, return -1; } - S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n"); + 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); diff --git a/openair-cn/S1AP/s1ap_mme.c b/openair-cn/S1AP/s1ap_mme.c index 01d8b27e19e1f055fbe7157cdb9eb0d70bb1acce..975cdb5dcd3e1f68bdbd6b72e1b424e1bf8a68ba 100644 --- a/openair-cn/S1AP/s1ap_mme.c +++ b/openair-cn/S1AP/s1ap_mme.c @@ -62,9 +62,12 @@ #if !defined(MME_CLIENT_TEST) // static pthread_t s1ap_task_thread; -uint32_t nb_eNB_associated = 0; -STAILQ_HEAD(eNB_list_s, eNB_description_s) eNB_list_head; -static int indent = 0; +int hss_associated = 0; +uint32_t nb_eNB_associated = 0; +STAILQ_HEAD(eNB_list_s, eNB_description_s) + eNB_list_head; + +static int indent = 0; void *s1ap_mme_thread(void *args); @@ -103,6 +106,10 @@ void *s1ap_mme_thread(void *args) switch (ITTI_MSG_ID(received_message_p)) { + case ACTIVATE_MESSAGE: { + hss_associated = 1; + } break; + case SCTP_DATA_IND: { /* New message received from SCTP layer. * Decode and handle it. diff --git a/openair-cn/S1AP/s1ap_mme.h b/openair-cn/S1AP/s1ap_mme.h index c450c24fc71b2fc332e8f954ddd69a834846ec37..a86ea0ec4d3ee6accba3db154d84a1b3ba162794 100644 --- a/openair-cn/S1AP/s1ap_mme.h +++ b/openair-cn/S1AP/s1ap_mme.h @@ -111,8 +111,9 @@ typedef struct eNB_description_s { /*@}*/ } eNB_description_t; -extern uint32_t nb_eNB_associated; -extern mme_config_t *global_mme_config_p; +extern int hss_associated; +extern uint32_t nb_eNB_associated; +extern mme_config_t *global_mme_config_p; /** \brief S1AP layer top init * @returns -1 in case of failure diff --git a/openair-cn/S1AP/s1ap_mme_handlers.c b/openair-cn/S1AP/s1ap_mme_handlers.c index 599b26f301a52b770382092b55c17efbbf728ca1..33556d708358bf2105a4065327cf0c13d8c3a9cf 100644 --- a/openair-cn/S1AP/s1ap_mme_handlers.c +++ b/openair-cn/S1AP/s1ap_mme_handlers.c @@ -217,124 +217,131 @@ int s1ap_mme_generate_s1_setup_failure( int s1ap_mme_handle_s1_setup_request(uint32_t assoc_id, uint32_t stream, struct s1ap_message_s *message) { - S1ap_S1SetupRequestIEs_t *s1SetupRequest_p; - eNB_description_t *eNB_association; - uint32_t eNB_id = 0; - char *eNB_name = NULL; - int ta_ret; - uint16_t max_enb_connected; + if (hss_associated) + { + S1ap_S1SetupRequestIEs_t *s1SetupRequest_p; + eNB_description_t *eNB_association; + uint32_t eNB_id = 0; + char *eNB_name = NULL; + int ta_ret; + uint16_t max_enb_connected; - DevAssert(message != NULL); + DevAssert(message != NULL); - s1SetupRequest_p = &message->msg.s1ap_S1SetupRequestIEs; + s1SetupRequest_p = &message->msg.s1ap_S1SetupRequestIEs; - /* We received a new valid S1 Setup Request on a stream != 0. - * This should not happen -> reject eNB s1 setup request. - */ - if (stream != 0) { - S1AP_DEBUG("Received new s1 setup request on stream != 0\n"); - /* Send a s1 setup failure with protocol cause unspecified */ - return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_protocol, - S1ap_CauseProtocol_unspecified, -1); - } + /* We received a new valid S1 Setup Request on a stream != 0. + * This should not happen -> reject eNB s1 setup request. + */ + if (stream != 0) { + S1AP_DEBUG("Received new s1 setup request on stream != 0\n"); + /* Send a s1 setup failure with protocol cause unspecified */ + return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_protocol, + S1ap_CauseProtocol_unspecified, -1); + } - S1AP_DEBUG("New s1 setup request incoming from "); - if (s1SetupRequest_p->presenceMask & S1AP_S1SETUPREQUESTIES_ENBNAME_PRESENT) - { - S1AP_DEBUG("%*s ", s1SetupRequest_p->eNBname.size, s1SetupRequest_p->eNBname.buf); - eNB_name = (char *)s1SetupRequest_p->eNBname.buf; - } - if (s1SetupRequest_p->global_ENB_ID.eNB_ID.present == S1ap_ENB_ID_PR_homeENB_ID) { - // Home eNB ID = 28 bits - uint8_t *eNB_id_buf = - s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.homeENB_ID.buf; - if (s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.size != 28) { - //TODO: handle case were size != 28 -> notify ? reject ? + S1AP_DEBUG("New s1 setup request incoming from "); + if (s1SetupRequest_p->presenceMask & S1AP_S1SETUPREQUESTIES_ENBNAME_PRESENT) + { + S1AP_DEBUG("%*s ", s1SetupRequest_p->eNBname.size, s1SetupRequest_p->eNBname.buf); + eNB_name = (char *)s1SetupRequest_p->eNBname.buf; } - eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + - (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); - S1AP_DEBUG("home eNB id: %07x\n", eNB_id); - } else { - // Macro eNB = 20 bits - uint8_t *eNB_id_buf = - s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf; - if (s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.size != 20) { - //TODO: handle case were size != 20 -> notify ? reject ? + if (s1SetupRequest_p->global_ENB_ID.eNB_ID.present == S1ap_ENB_ID_PR_homeENB_ID) { + // Home eNB ID = 28 bits + uint8_t *eNB_id_buf = + s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.homeENB_ID.buf; + if (s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.size != 28) { + //TODO: handle case were size != 28 -> notify ? reject ? + } + eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); + S1AP_DEBUG("home eNB id: %07x\n", eNB_id); + } else { + // Macro eNB = 20 bits + uint8_t *eNB_id_buf = + s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf; + if (s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.size != 20) { + //TODO: handle case were size != 20 -> notify ? reject ? + } + eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + (( + eNB_id_buf[2] & 0xf0) >> 4); + S1AP_DEBUG("macro eNB id: %05x\n", eNB_id); } - eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + (( - eNB_id_buf[2] & 0xf0) >> 4); - S1AP_DEBUG("macro eNB id: %05x\n", eNB_id); - } - config_read_lock(&mme_config); - max_enb_connected = mme_config.max_eNBs; - config_unlock(&mme_config); + config_read_lock(&mme_config); + max_enb_connected = mme_config.max_eNBs; + config_unlock(&mme_config); - if (nb_eNB_associated == max_enb_connected) { - S1AP_DEBUG("There is too much eNB connected to MME, rejecting the association\n"); - S1AP_DEBUG("Connected = %d, maximum allowed = %d\n", nb_eNB_associated, - max_enb_connected); - - /* Send an overload cause... */ - return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_misc, - S1ap_CauseMisc_control_processing_overload, - S1ap_TimeToWait_v20s); - } + if (nb_eNB_associated == max_enb_connected) { + S1AP_DEBUG("There is too much eNB connected to MME, rejecting the association\n"); + S1AP_DEBUG("Connected = %d, maximum allowed = %d\n", nb_eNB_associated, + max_enb_connected); - /* If none of the provided PLMNs/TAC match the one configured in MME, - * the s1 setup should be rejected with a cause set to Unknown PLMN. - */ - ta_ret = s1ap_mme_compare_ta_lists(&s1SetupRequest_p->supportedTAs); + /* Send an overload cause... */ + return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_misc, + S1ap_CauseMisc_control_processing_overload, + S1ap_TimeToWait_v20s); + } - /* eNB and MME have no common PLMN */ - if (ta_ret != TA_LIST_RET_OK) { - return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_misc, - S1ap_CauseMisc_unknown_PLMN, - S1ap_TimeToWait_v20s); - } + /* If none of the provided PLMNs/TAC match the one configured in MME, + * the s1 setup should be rejected with a cause set to Unknown PLMN. + */ + ta_ret = s1ap_mme_compare_ta_lists(&s1SetupRequest_p->supportedTAs); - S1AP_DEBUG("Adding eNB to the list of served eNBs\n"); + /* eNB and MME have no common PLMN */ + if (ta_ret != TA_LIST_RET_OK) { + return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_misc, + S1ap_CauseMisc_unknown_PLMN, + S1ap_TimeToWait_v20s); + } - if ((eNB_association = s1ap_is_eNB_id_in_list(eNB_id)) == NULL) { - /* eNB has not been fount in list of associated eNB, - * Add it to the tail of list and initialize data */ - if ((eNB_association = s1ap_is_eNB_assoc_id_in_list(assoc_id)) == NULL) { - /* ?? */ - return -1; + S1AP_DEBUG("Adding eNB to the list of served eNBs\n"); + + if ((eNB_association = s1ap_is_eNB_id_in_list(eNB_id)) == NULL) { + /* eNB has not been fount in list of associated eNB, + * Add it to the tail of list and initialize data */ + if ((eNB_association = s1ap_is_eNB_assoc_id_in_list(assoc_id)) == NULL) { + /* ?? */ + return -1; + } else { + eNB_association->s1_state = S1AP_RESETING; + eNB_association->eNB_id = eNB_id; + eNB_association->default_paging_drx = s1SetupRequest_p->defaultPagingDRX; + + if (eNB_name != NULL) { + memcpy(eNB_association->eNB_name, s1SetupRequest_p->eNBname.buf, + s1SetupRequest_p->eNBname.size); + eNB_association->eNB_name[s1SetupRequest_p->eNBname.size] = '\0'; + } + } } else { eNB_association->s1_state = S1AP_RESETING; - eNB_association->eNB_id = eNB_id; - eNB_association->default_paging_drx = s1SetupRequest_p->defaultPagingDRX; - - if (eNB_name != NULL) { - memcpy(eNB_association->eNB_name, s1SetupRequest_p->eNBname.buf, - s1SetupRequest_p->eNBname.size); - eNB_association->eNB_name[s1SetupRequest_p->eNBname.size] = '\0'; + /* eNB has been fount in list, consider the s1 setup request as a reset connection, + * reseting any previous UE state if sctp association is != than the previous one */ + if (eNB_association->sctp_assoc_id != assoc_id) { + S1ap_S1SetupFailureIEs_t s1SetupFailure; + + memset(&s1SetupFailure, 0, sizeof(s1SetupFailure)); + + /* Send an overload cause... */ + s1SetupFailure.cause.present = S1ap_Cause_PR_misc; //TODO: send the right cause + s1SetupFailure.cause.choice.misc = S1ap_CauseMisc_control_processing_overload; + S1AP_DEBUG("Rejeting s1 setup request as eNB id %d is already associated to an active sctp association" + "Previous known: %d, new one: %d\n", + eNB_id, eNB_association->sctp_assoc_id, assoc_id); + // s1ap_mme_encode_s1setupfailure(&s1SetupFailure, + // receivedMessage->msg.s1ap_sctp_new_msg_ind.assocId); + return -1; } + /* TODO: call the reset procedure */ } + s1ap_dump_eNB(eNB_association); + return s1ap_generate_s1_setup_response(eNB_association); } else { - eNB_association->s1_state = S1AP_RESETING; - /* eNB has been fount in list, consider the s1 setup request as a reset connection, - * reseting any previous UE state if sctp association is != than the previous one */ - if (eNB_association->sctp_assoc_id != assoc_id) { - S1ap_S1SetupFailureIEs_t s1SetupFailure; - - memset(&s1SetupFailure, 0, sizeof(s1SetupFailure)); - - /* Send an overload cause... */ - s1SetupFailure.cause.present = S1ap_Cause_PR_misc; //TODO: send the right cause - s1SetupFailure.cause.choice.misc = S1ap_CauseMisc_control_processing_overload; - S1AP_DEBUG("Rejeting s1 setup request as eNB id %d is already associated to an active sctp association" - "Previous known: %d, new one: %d\n", - eNB_id, eNB_association->sctp_assoc_id, assoc_id); -// s1ap_mme_encode_s1setupfailure(&s1SetupFailure, -// receivedMessage->msg.s1ap_sctp_new_msg_ind.assocId); - return -1; - } - /* TODO: call the reset procedure */ + /* Can not process the request, MME is not connected to HSS */ + return s1ap_mme_generate_s1_setup_failure(assoc_id, S1ap_Cause_PR_misc, + S1ap_CauseMisc_unspecified, -1); } - s1ap_dump_eNB(eNB_association); - return s1ap_generate_s1_setup_response(eNB_association); } static diff --git a/openair-cn/S6A/s6a_peer.c b/openair-cn/S6A/s6a_peer.c index 52243ea3912e353457eedf4c7509c0091a07cb0a..64d82031c1106b4921f95c3883bf96d558a91624 100644 --- a/openair-cn/S6A/s6a_peer.c +++ b/openair-cn/S6A/s6a_peer.c @@ -50,8 +50,15 @@ void s6a_peer_connected_cb(struct peer_info *info, void *arg) if (info == NULL) { S6A_ERROR("Failed to connect to HSS entity\n"); } else { + MessageDef *message_p; + S6A_DEBUG("Peer %*s is now connected...\n", (int)info->pi_diamidlen, info->pi_diamid); + + /* Inform S1AP that connection to HSS is established */ + message_p = itti_alloc_new_message(TASK_S6A, ACTIVATE_MESSAGE); + + itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p); } /* For test */