diff --git a/openair-cn/S1AP/s1ap_eNB_nas_procedures.c b/openair-cn/S1AP/s1ap_eNB_nas_procedures.c index 647b0a1c0a..7495c706af 100644 --- a/openair-cn/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair-cn/S1AP/s1ap_eNB_nas_procedures.c @@ -76,24 +76,40 @@ int s1ap_eNB_handle_nas_first_req( initial_ue_message_p = &message.msg.s1ap_InitialUEMessageIEs; - /* Select the MME corresponding to the provided GUMMEI. - * If no MME corresponds to the GUMMEI, the function selects the MME with the - * highest capacity. - * In case eNB has no MME associated, the eNB should inform RRC and discard - * this request. - */ - if (s1ap_nas_first_req_p->ue_identity.present == IDENTITY_PR_gummei) { + /* Select the MME corresponding to the provided GUMMEI. */ + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) { mme_desc_p = s1ap_eNB_nnsf_select_mme_by_gummei( instance_p, s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->ue_identity.choice.gummei); - } else { - mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code( - instance_p, - s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->ue_identity.choice.s_tmsi.mme_code); + s1ap_nas_first_req_p->ue_identity.gummei); } + if (mme_desc_p == NULL) { + /* Select the MME corresponding to the provided s-TMSI. */ + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) { + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); + } + } + + if (mme_desc_p == NULL) { + /* + * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the + * highest capacity. + */ + mme_desc_p = s1ap_eNB_nnsf_select_mme( + instance_p, + s1ap_nas_first_req_p->establishment_cause); + } + + if (mme_desc_p == NULL) { + /* + * In case eNB has no MME associated, the eNB should inform RRC and discard + * this request. + */ + S1AP_WARN("No MME is associated to the eNB\n"); // TODO: Inform RRC return -1; @@ -133,22 +149,23 @@ int s1ap_eNB_handle_nas_first_req( s1ap_nas_first_req_p->establishment_cause, RRC_CAUSE_LAST, 0); initial_ue_message_p->rrC_Establishment_Cause = s1ap_nas_first_req_p->establishment_cause; - if (s1ap_nas_first_req_p->ue_identity.present == IDENTITY_PR_gummei) { + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) { initial_ue_message_p->presenceMask |= S1AP_INITIALUEMESSAGEIES_S_TMSI_PRESENT; - MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.choice.s_tmsi.mme_code, + MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, &initial_ue_message_p->s_tmsi.mMEC); - M_TMSI_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.choice.s_tmsi.m_tmsi, + M_TMSI_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, &initial_ue_message_p->s_tmsi.m_TMSI); - } else { + } + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) { initial_ue_message_p->presenceMask |= S1AP_INITIALUEMESSAGEIES_GUMMEI_ID_PRESENT; - MCC_MNC_TO_PLMNID(s1ap_nas_first_req_p->ue_identity.choice.gummei.mcc, - s1ap_nas_first_req_p->ue_identity.choice.gummei.mnc, + MCC_MNC_TO_PLMNID(s1ap_nas_first_req_p->ue_identity.gummei.mcc, + s1ap_nas_first_req_p->ue_identity.gummei.mnc, &initial_ue_message_p->gummei_id.pLMN_Identity); - MME_GID_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.choice.gummei.mme_group_id, + MME_GID_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, &initial_ue_message_p->gummei_id.mME_Group_ID); - MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.choice.gummei.mme_code, + MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_code, &initial_ue_message_p->gummei_id.mME_Code); } @@ -336,6 +353,9 @@ int s1ap_eNB_initial_ctxt_resp( 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); @@ -415,6 +435,9 @@ int s1ap_eNB_ue_capabilities(instance_t instance, 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); diff --git a/openair-cn/S1AP/s1ap_eNB_nnsf.c b/openair-cn/S1AP/s1ap_eNB_nnsf.c index f9a0cffa99..1ad7e95a3a 100644 --- a/openair-cn/S1AP/s1ap_eNB_nnsf.c +++ b/openair-cn/S1AP/s1ap_eNB_nnsf.c @@ -45,6 +45,57 @@ #include "s1ap_eNB_defs.h" #include "s1ap_eNB_nnsf.h" +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause) +{ + struct s1ap_eNB_mme_data_s *mme_data_p = NULL; + struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; + uint8_t current_capacity = 0; + + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + struct served_gummei_s *gummei_p = NULL; + + if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { + /* The association between MME and eNB is not ready for the moment, + * go to the next known MME. + */ + if (mme_data_p->state == S1AP_ENB_OVERLOAD) { + /* MME is overloaded. We have to check the RRC establishment + * cause and take decision to the select this MME depending on + * the overload state. + */ + if ((cause == RRC_CAUSE_MO_DATA) + && (mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + if ((mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) { + continue; + } + if ((mme_data_p->overload_state == S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA) + || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + /* At this point, the RRC establishment can be handled by the MME + * even if it is in overload state. + */ + } else { + /* The MME is not overloaded, association is simply not ready. */ + continue; + } + } + if (current_capacity < mme_data_p->relative_mme_capacity) { + /* We find a better MME, keep a reference to it */ + current_capacity = mme_data_p->relative_mme_capacity; + mme_highest_capacity_p = mme_data_p; + } + } + + return mme_highest_capacity_p; +} + struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, @@ -116,7 +167,7 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, - gummei_t gummei) + s1ap_gummei_t gummei) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; diff --git a/openair-cn/S1AP/s1ap_eNB_nnsf.h b/openair-cn/S1AP/s1ap_eNB_nnsf.h index 51d3835d93..46433ba046 100644 --- a/openair-cn/S1AP/s1ap_eNB_nnsf.h +++ b/openair-cn/S1AP/s1ap_eNB_nnsf.h @@ -31,6 +31,10 @@ #ifndef S1AP_ENB_NNSF_H_ #define S1AP_ENB_NNSF_H_ +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause); + struct s1ap_eNB_mme_data_s* s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, @@ -39,6 +43,6 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, struct s1ap_eNB_mme_data_s* s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, - gummei_t gummei); + s1ap_gummei_t gummei); #endif /* S1AP_ENB_NNSF_H_ */ diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h new file mode 100644 index 0000000000..27200babd5 --- /dev/null +++ b/openair2/COMMON/mac_messages_def.h @@ -0,0 +1,21 @@ +/* + * mac_messages_def.h + * + * Created on: Oct 24, 2013 + * Author: winckel + */ + +//-------------------------------------------------------------------------------------------// +// Messages between RRC and MAC layers +MESSAGE_DEF(RRC_MAC_IN_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacInSyncInd, rrc_mac_in_sync_ind) +MESSAGE_DEF(RRC_MAC_OUT_OF_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacOutOfSyncInd, rrc_mac_out_of_sync_ind) + +MESSAGE_DEF(RRC_MAC_BCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataReq, rrc_mac_bcch_data_req) +MESSAGE_DEF(RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataInd, rrc_mac_bcch_data_ind) + +MESSAGE_DEF(RRC_MAC_CCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataReq, rrc_mac_ccch_data_req) +MESSAGE_DEF(RRC_MAC_CCCH_DATA_CNF, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataCnf, rrc_mac_ccch_data_cnf) +MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataInd, rrc_mac_ccch_data_ind) + +MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataReq, rrc_mac_mcch_data_req) +MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind) diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h new file mode 100644 index 0000000000..02f3a1ca36 --- /dev/null +++ b/openair2/COMMON/mac_messages_types.h @@ -0,0 +1,88 @@ +/* + * mac_messages_types.h + * + * Created on: Oct 24, 2013 + * Author: winckel + */ + +#ifndef MAC_MESSAGES_TYPES_H_ +#define MAC_MESSAGES_TYPES_H_ + +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. +#define RRC_MAC_IN_SYNC_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_in_sync_ind +#define RRC_MAC_OUT_OF_SYNC_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_out_of_sync_ind + +#define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_mac_bcch_data_req +#define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_bcch_data_ind + +#define RRC_MAC_CCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_mac_ccch_data_req +#define RRC_MAC_CCCH_DATA_CNF(mSGpTR) (mSGpTR)->msg.rrc_mac_ccch_data_cnf +#define RRC_MAC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_ccch_data_ind + +#define RRC_MAC_MCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_mac_mcch_data_req +#define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_mcch_data_ind + +// Some constants from "LAYER2/MAC/defs.h" +#define BCCH_SDU_SIZE (128) +#define CCCH_SDU_SIZE (128) +#define MCCH_SDU_SIZE (128) + +//-------------------------------------------------------------------------------------------// +// Messages between RRC and MAC layers +typedef struct { + uint32_t frame; + uint16_t enb_index; +} RrcMacInSyncInd; + +typedef RrcMacInSyncInd RrcMacOutOfSyncInd; + +typedef struct { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[BCCH_SDU_SIZE]; + uint8_t enb_index; +} RrcMacBcchDataReq; + +typedef struct { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[BCCH_SDU_SIZE]; + uint8_t enb_index; +} RrcMacBcchDataInd; + +typedef struct { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[CCCH_SDU_SIZE]; + uint8_t enb_index; +} RrcMacCcchDataReq; + +typedef struct { + uint8_t enb_index; +} RrcMacCcchDataCnf; + +typedef struct { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[CCCH_SDU_SIZE]; + uint8_t enb_index; +} RrcMacCcchDataInd; + +typedef struct { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[MCCH_SDU_SIZE]; + uint8_t enb_index; + uint8_t mbsfn_sync_area; +} RrcMacMcchDataReq; + +typedef struct { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[MCCH_SDU_SIZE]; + uint8_t enb_index; + uint8_t mbsfn_sync_area; +} RrcMacMcchDataInd; + +#endif /* MAC_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h index 0257c92ad1..b3a338e603 100644 --- a/openair2/COMMON/messages_def.h +++ b/openair2/COMMON/messages_def.h @@ -3,7 +3,9 @@ #include "timer_messages_def.h" // Messages files used between tasks +#include "mac_messages_def.h" +#include "pdcp_messages_def.h" #include "rrc_messages_def.h" #include "s1ap_messages_def.h" #include "sctp_messages_def.h" -#include "x2ap_messages_def.h" \ No newline at end of file +#include "x2ap_messages_def.h" diff --git a/openair2/COMMON/messages_types.h b/openair2/COMMON/messages_types.h index 2916ff21a5..581bcab247 100644 --- a/openair2/COMMON/messages_types.h +++ b/openair2/COMMON/messages_types.h @@ -10,6 +10,8 @@ #include "timer_messages_types.h" +#include "mac_messages_types.h" +#include "pdcp_messages_types.h" #include "rrc_messages_types.h" #include "s1ap_messages_types.h" #include "sctp_messages_types.h" diff --git a/openair2/COMMON/pdcp_messages_def.h b/openair2/COMMON/pdcp_messages_def.h new file mode 100644 index 0000000000..10d4317b4f --- /dev/null +++ b/openair2/COMMON/pdcp_messages_def.h @@ -0,0 +1,11 @@ +/* + * pdcp_messages_def.h + * + * Created on: Oct 24, 2013 + * Author: winckel + */ + +//-------------------------------------------------------------------------------------------// +// Messages between RRC and PDCP layers +MESSAGE_DEF(RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq, rrc_dcch_data_req) +MESSAGE_DEF(RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_ind) diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h new file mode 100644 index 0000000000..f11fcc6616 --- /dev/null +++ b/openair2/COMMON/pdcp_messages_types.h @@ -0,0 +1,37 @@ +/* + * pdcp_messages_types.h + * + * Created on: Oct 24, 2013 + * Author: winckel + */ + +#ifndef PDCP_MESSAGES_TYPES_H_ +#define PDCP_MESSAGES_TYPES_H_ + +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. +#define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_dcch_data_req +#define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_dcch_data_ind + +//-------------------------------------------------------------------------------------------// +// Messages between RRC and PDCP layers +typedef struct { + uint32_t frame; + uint8_t enb_flag; + uint32_t rb_id; + uint32_t muip; + uint32_t confirmp; + uint32_t sdu_size; + uint8_t *sdu_p; + uint8_t mode; +} RrcDcchDataReq; + +typedef struct { + uint32_t frame; + uint8_t dcch_index; + uint32_t sdu_size; + uint8_t *sdu_p; + uint8_t ue_index; +} RrcDcchDataInd; + +#endif /* PDCP_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 8bea6659a3..6f66fb647f 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -5,29 +5,21 @@ * Author: winckel */ -MESSAGE_DEF(RRC_DL_BCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcDlBcchMessage, rrc_dl_bcch_message) -MESSAGE_DEF(RRC_DL_CCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcDlCcchMessage, rrc_dl_ccch_message) -MESSAGE_DEF(RRC_DL_DCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcDlDcchMessage, rrc_dl_dcch_message) -MESSAGE_DEF(RRC_UE_EUTRA_CAPABILITY, MESSAGE_PRIORITY_MED_PLUS, RrcUeEutraCapability, rrc_ue_eutra_capability) -MESSAGE_DEF(RRC_UL_CCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcUlCcchMessage, rrc_ul_ccch_message) -MESSAGE_DEF(RRC_UL_DCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcUlDcchMessage, rrc_ul_dcch_message) +//-------------------------------------------------------------------------------------------// +// Messages for RRC logging +MESSAGE_DEF(RRC_DL_BCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcDlBcchMessage, rrc_dl_bcch_message) +MESSAGE_DEF(RRC_DL_CCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcDlCcchMessage, rrc_dl_ccch_message) +MESSAGE_DEF(RRC_DL_DCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcDlDcchMessage, rrc_dl_dcch_message) + +MESSAGE_DEF(RRC_UE_EUTRA_CAPABILITY, MESSAGE_PRIORITY_MED_PLUS, RrcUeEutraCapability, rrc_ue_eutra_capability) + +MESSAGE_DEF(RRC_UL_CCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcUlCcchMessage, rrc_ul_ccch_message) +MESSAGE_DEF(RRC_UL_DCCH_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, RrcUlDcchMessage, rrc_ul_dcch_message) //-------------------------------------------------------------------------------------------// -// Messages from MAC layer -MESSAGE_DEF(RRC_MAC_IN_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacInSyncInd, rrc_mac_in_sync_ind) -MESSAGE_DEF(RRC_MAC_OUT_OF_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacOutOfSyncInd, rrc_mac_out_of_sync_ind) +// Messages between NAS and RRC layers +MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind) -MESSAGE_DEF(RRC_MAC_BCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataReq, rrc_mac_bcch_data_req) -MESSAGE_DEF(RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataInd, rrc_mac_bcch_data_ind) - -MESSAGE_DEF(RRC_MAC_CCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataReq, rrc_mac_ccch_data_req) -MESSAGE_DEF(RRC_MAC_CCCH_DATA_CNF, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataCnf, rrc_mac_ccch_data_cnf) -MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataInd, rrc_mac_ccch_data_ind) - -MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataReq, rrc_mac_mcch_data_req) -MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind) - -//-------------------------------------------------------------------------------------------// -// Messages from/to PDCP layer -MESSAGE_DEF(RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq, rrc_dcch_data_req) -MESSAGE_DEF(RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_ind) +MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq, nas_ul_data_req) +MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf) +MESSAGE_DEF(NAS_UPLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasUlDataInd, nas_ul_data_ind) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 75550b4036..d209fcee72 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -8,6 +8,10 @@ #ifndef RRC_MESSAGES_TYPES_H_ #define RRC_MESSAGES_TYPES_H_ +#include "as_message.h" + +//-------------------------------------------------------------------------------------------// +// Messages for RRC logging #include "BCCH-DL-SCH-Message.h" #include "DL-CCCH-Message.h" #include "DL-DCCH-Message.h" @@ -15,30 +19,6 @@ #include "UL-CCCH-Message.h" #include "UL-DCCH-Message.h" -//-------------------------------------------------------------------------------------------// -// Defines to access message fields. - -#define RRC_MAC_IN_SYNC_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_in_sync_ind -#define RRC_MAC_OUT_OF_SYNC_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_out_of_sync_ind - -#define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_mac_bcch_data_req -#define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_bcch_data_ind - -#define RRC_MAC_CCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_mac_ccch_data_req -#define RRC_MAC_CCCH_DATA_CNF(mSGpTR) (mSGpTR)->msg.rrc_mac_ccch_data_cnf -#define RRC_MAC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_ccch_data_ind - -#define RRC_MAC_MCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_mac_mcch_data_req -#define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_mac_mcch_data_ind - -#define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->msg.rrc_dcch_data_req -#define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->msg.rrc_dcch_data_ind - -// Some constants from "LAYER2/MAC/defs.h" -#define BCCH_SDU_SIZE (128) -#define CCCH_SDU_SIZE (128) -#define MCCH_SDU_SIZE (128) - typedef BCCH_DL_SCH_Message_t RrcDlBcchMessage; typedef DL_CCCH_Message_t RrcDlCcchMessage; typedef DL_DCCH_Message_t RrcDlDcchMessage; @@ -47,83 +27,19 @@ typedef UL_CCCH_Message_t RrcUlCcchMessage; typedef UL_DCCH_Message_t RrcUlDcchMessage; //-------------------------------------------------------------------------------------------// -// Messages from MAC layer +// Defines to access message fields. +#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->msg.nas_dl_data_ind -typedef struct { - uint32_t frame; - uint16_t enb_index; -} RrcMacInSyncInd; - -typedef RrcMacInSyncInd RrcMacOutOfSyncInd; - -typedef struct { - uint32_t frame; - uint32_t sdu_size; - uint8_t sdu[BCCH_SDU_SIZE]; - uint8_t enb_index; -} RrcMacBcchDataReq; - -typedef struct { - uint32_t frame; - uint32_t sdu_size; - uint8_t sdu[BCCH_SDU_SIZE]; - uint8_t enb_index; -} RrcMacBcchDataInd; - -typedef struct { - uint32_t frame; - uint32_t sdu_size; - uint8_t sdu[CCCH_SDU_SIZE]; - uint8_t enb_index; -} RrcMacCcchDataReq; - -typedef struct { - uint8_t enb_index; -} RrcMacCcchDataCnf; - -typedef struct { - uint32_t frame; - uint32_t sdu_size; - uint8_t sdu[CCCH_SDU_SIZE]; - uint8_t enb_index; -} RrcMacCcchDataInd; - -typedef struct { - uint32_t frame; - uint32_t sdu_size; - uint8_t sdu[MCCH_SDU_SIZE]; - uint8_t enb_index; - uint8_t mbsfn_sync_area; -} RrcMacMcchDataReq; - -typedef struct { - uint32_t frame; - uint32_t sdu_size; - uint8_t sdu[MCCH_SDU_SIZE]; - uint8_t enb_index; - uint8_t mbsfn_sync_area; -} RrcMacMcchDataInd; +#define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->msg.nas_ul_data_req +#define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->msg.nas_ul_data_cnf +#define NAS_UPLINK_DATA_IND(mSGpTR) (mSGpTR)->msg.nas_ul_data_ind //-------------------------------------------------------------------------------------------// -// Messages from/to PDCP layer +// Messages between NAS and RRC layers +typedef dl_info_transfer_ind_t NasDlDataInd; -typedef struct { - uint32_t frame; - uint8_t enb_flag; - uint32_t rb_id; - uint32_t muip; - uint32_t confirmp; - uint32_t sdu_size; - uint8_t *sdu_p; - uint8_t mode; -} RrcDcchDataReq; - -typedef struct { - uint32_t frame; - uint8_t dcch_index; - uint32_t sdu_size; - uint8_t *sdu_p; - uint8_t ue_index; -} RrcDcchDataInd; +typedef ul_info_transfer_req_t NasUlDataReq; +typedef ul_info_transfer_cnf_t NasUlDataCnf; +typedef ul_info_transfer_ind_t NasUlDataInd; #endif /* RRC_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index 099ced4951..f146ca0a0f 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -5,22 +5,28 @@ // Defines to access message fields. #define S1AP_NAS_FIRST_REQ(mSGpTR) (mSGpTR)->msg.s1ap_nas_first_req +#define S1AP_UPLINK_NAS(mSGpTR) (mSGpTR)->msg.s1ap_uplink_nas +#define S1AP_UE_CAPABILITIES_IND(mSGpTR) (mSGpTR)->msg.s1ap_ue_cap_info_ind +#define S1AP_INITIAL_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->msg.s1ap_initial_context_setup_resp + +#define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->msg.s1ap_downlink_nas +#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->msg.s1ap_initial_context_setup_req //-------------------------------------------------------------------------------------------// -enum cell_type_e { +typedef enum cell_type_e { CELL_MACRO_ENB, CELL_HOME_ENB -}; +} cell_type_t; -typedef enum { +typedef enum paging_drx_e { PAGING_DRX_32 = 0x0, PAGING_DRX_64 = 0x1, PAGING_DRX_128 = 0x2, PAGING_DRX_256 = 0x3, } paging_drx_t; -typedef struct { +typedef struct net_ip_address_s { unsigned ipv4:1; unsigned ipv6:1; char ipv4_address[16]; @@ -44,7 +50,7 @@ typedef struct { * concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for * 'Mobile Originating'. Defined in TS 36.331. */ -typedef enum { +typedef enum rrc_establishment_cause_e { RRC_CAUSE_EMERGENCY = 0x0, RRC_CAUSE_HIGH_PRIO_ACCESS = 0x1, RRC_CAUSE_MT_ACCESS = 0x2, @@ -53,40 +59,38 @@ typedef enum { RRC_CAUSE_LAST } rrc_establishment_cause_t; -typedef struct { +typedef struct s1ap_gummei_s { uint16_t mcc; uint16_t mnc; uint8_t mme_code; uint16_t mme_group_id; -} gummei_t; +} s1ap_gummei_t; -typedef struct { +typedef struct s_tmsi_s { uint8_t mme_code; uint32_t m_tmsi; } s_tmsi_t; -typedef enum { - IDENTITY_PR_NOTHING, - IDENTITY_PR_s_tmsi, - IDENTITY_PR_gummei, -} identity_t; +typedef enum ue_identities_presenceMask_e { + UE_IDENTITIES_NONE = 0, + UE_IDENTITIES_s_tmsi = 1 << 1, + UE_IDENTITIES_gummei = 1 << 2, +} ue_identities_presenceMask_t; -typedef struct { - identity_t present; - union { - s_tmsi_t s_tmsi; - gummei_t gummei; - } choice; +typedef struct ue_identity_s { + ue_identities_presenceMask_t presenceMask; + s_tmsi_t s_tmsi; + s1ap_gummei_t gummei; } ue_identity_t; -typedef struct { +typedef struct nas_pdu_s { /* Octet string data */ uint8_t *buffer; /* Length of the octet string */ uint32_t length; } nas_pdu_t, ue_radio_cap_t; -typedef struct { +typedef struct transport_layer_addr_s { /* Length of the transport layer address buffer. S1AP layer received a * bit string<1..160> containing one of the following addresses: ipv4, * ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but @@ -96,12 +100,12 @@ typedef struct { uint8_t buffer[20]; } transport_layer_addr_t; -typedef struct { +typedef struct e_rab_level_qos_parameter_s { uint8_t qci; } e_rab_level_qos_parameter_t; -typedef struct { +typedef struct e_rab_s { /* Unique e_rab_id for the UE. */ uint8_t e_rab_id; /* Quality of service for this e_rab */ @@ -114,7 +118,7 @@ typedef struct { uint32_t gtp_teid; } e_rab_t; -typedef struct { +typedef struct e_rab_setup_s { /* Unique e_rab_id for the UE. */ uint8_t e_rab_id; @@ -125,14 +129,14 @@ typedef struct { uint32_t gtp_teid; } e_rab_setup_t; -typedef struct { +typedef struct e_rab_failed_s { /* Unique e_rab_id for the UE. */ uint8_t e_rab_id; /* Cause of the failure */ // cause_t cause; } e_rab_failed_t; -typedef struct { +typedef struct s1ap_register_eNB_s { /* Unique eNB_id to identify the eNB within EPC. * For macro eNB ids this field should be 20 bits long. * For home eNB ids this field should be 28 bits long. @@ -173,7 +177,7 @@ typedef struct { * The rnti uniquely identifies an UE within a cell. Later the enb_ue_s1ap_id * will be the unique identifier used between RRC and S1AP. */ -typedef struct { +typedef struct s1ap_nas_first_req_s { /* RNTI of the mobile */ uint16_t rnti; @@ -189,7 +193,7 @@ typedef struct { ue_identity_t ue_identity; } s1ap_nas_first_req_t; -typedef struct { +typedef struct s1ap_uplink_nas_s { /* Unique UE identifier within an eNB */ unsigned eNB_ue_s1ap_id:24; @@ -199,7 +203,7 @@ typedef struct { typedef s1ap_uplink_nas_t s1ap_downlink_nas_t; -typedef struct { +typedef struct s1ap_initial_context_setup_req_s { unsigned eNB_ue_s1ap_id:24; /* Number of e_rab to be setup in the list */ @@ -208,7 +212,7 @@ typedef struct { e_rab_t e_rab_param[S1AP_MAX_E_RAB]; } s1ap_initial_context_setup_req_t; -typedef struct { +typedef struct s1ap_initial_context_setup_resp_s { unsigned eNB_ue_s1ap_id:24; /* Number of e_rab setup-ed in the list */ @@ -222,7 +226,7 @@ typedef struct { e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB]; } s1ap_initial_context_setup_resp_t; -typedef struct { +typedef struct s1ap_ue_cap_info_ind_s { unsigned eNB_ue_s1ap_id:24; ue_radio_cap_t ue_radio_cap; } s1ap_ue_cap_info_ind_t; diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 4a7879f54c..8254e1be4e 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -119,8 +119,9 @@ uint16_t get_adjacent_cell_id(uint8_t Mod_id,uint8_t index) { return(two_tier_hexagonal_adjacent_cellIds[Mod_id][index]); } /* This only works for the hexagonal topology...need a more general function for other topologies */ -u8 get_adjacent_cell_mod_id(uint16_t phyCellId) { - u8 i; + +uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) { + uint8_t i; for(i=0;i<7;i++) { if(two_tier_hexagonal_cellIds[i] == phyCellId) return i; @@ -128,6 +129,7 @@ u8 get_adjacent_cell_mod_id(uint16_t phyCellId) { LOG_E(RRC,"\nCannot get adjacent cell mod id! Fatal error!\n"); return 0xFF; //error! } + /* uint8_t do_SIB1(LTE_DL_FRAME_PARMS *frame_parms, uint8_t *buffer, SystemInformationBlockType1_t *sib1) { @@ -306,6 +308,7 @@ uint8_t do_MIB(LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t *buffer) ); */ } + uint8_t do_SIB1(LTE_DL_FRAME_PARMS *frame_parms, uint8_t *buffer, BCCH_DL_SCH_Message_t *bcch_message, SystemInformationBlockType1_t **sib1) { @@ -1390,6 +1393,7 @@ uint8_t do_RRCConnectionSetup(uint8_t *buffer, return((enc_rval.encoded+7)/8); } + uint8_t do_SecurityModeCommand(uint8_t Mod_id, uint8_t *buffer, uint8_t UE_id, @@ -1434,6 +1438,7 @@ uint8_t do_SecurityModeCommand(uint8_t Mod_id, // exit(-1); return((enc_rval.encoded+7)/8); } + uint8_t do_UECapabilityEnquiry(uint8_t Mod_id, uint8_t *buffer, uint8_t UE_id, @@ -1821,13 +1826,55 @@ uint8_t do_MeasurementReport(uint8_t *buffer,int measid,int phy_id,int rsrp_s,in return((enc_rval.encoded+7)/8); } -static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */ -SupportedBandEUTRA_t Bandlist[4]; -BandInfoEUTRA_t BandInfo_meas[4]; -InterFreqBandInfo_t InterFreqBandInfo[4][4]; -BandInfoEUTRA_t BandInfoEUTRA[4]; +uint8_t do_DLInformationTransfer(uint32_t length, uint8_t *buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer) +{ + asn_enc_rval_t enc_rval; + + DL_DCCH_Message_t dl_dcch_msg; + + memset(&dl_dcch_msg,0,sizeof(DL_DCCH_Message_t)); + + dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = DL_DCCH_MessageType__c1_PR_dlInformationTransfer; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.rrc_TransactionIdentifier = transaction_id; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.present = DLInformationTransfer__criticalExtensions_PR_c1; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.present = DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present = DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.size = pdu_length; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.buf = pdu_buffer; + + enc_rval = uper_encode_to_buffer (&asn_DEF_UL_CCCH_Message, (void*) &dl_dcch_msg, buffer, length); + + return((enc_rval.encoded+7)/8); +} + +uint8_t do_ULInformationTransfer(uint32_t length, uint8_t *buffer, uint32_t pdu_length, uint8_t *pdu_buffer) +{ + asn_enc_rval_t enc_rval; + + UL_DCCH_Message_t ul_dcch_msg; + + memset(&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); + + ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_ulInformationTransfer; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.present = ULInformationTransfer__criticalExtensions_PR_c1; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.present = DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present = ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.size = pdu_length; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.buf = pdu_buffer; + + enc_rval = uper_encode_to_buffer (&asn_DEF_UL_CCCH_Message, (void*) &ul_dcch_msg, buffer, length); + + return((enc_rval.encoded+7)/8); +} OAI_UECapability_t *fill_ue_capability() { + static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */ + SupportedBandEUTRA_t Bandlist[4]; + // BandInfoEUTRA_t BandInfo_meas[4]; + InterFreqBandInfo_t InterFreqBandInfo[4][4]; + BandInfoEUTRA_t BandInfoEUTRA[4]; UE_EUTRA_Capability_t *UE_EUTRA_Capability; asn_enc_rval_t enc_rval; diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h index 9b0ae67dc2..273b61c829 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h @@ -195,6 +195,10 @@ uint8_t do_MBSFNAreaConfig(LTE_DL_FRAME_PARMS *frame_parms, uint8_t do_MeasurementReport(uint8_t *buffer,int measid,int phy_id,int rsrp_s,int rsrq_s,long rsrp_t,long rsrq_t); +uint8_t do_DLInformationTransfer(uint32_t length, uint8_t *buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer); + +uint8_t do_ULInformationTransfer(uint32_t length, uint8_t *buffer, uint32_t pdu_length, uint8_t *pdu_buffer); + OAI_UECapability_t *fill_ue_capability(); uint8_t do_UECapabilityEnquiry(uint8_t Mod_id, diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 20b15c01db..ef57a25005 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -1356,11 +1356,39 @@ void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index) case DL_DCCH_MessageType__c1_PR_NOTHING : LOG_I(RRC,"[UE %d] Frame %d : Received PR_NOTHING on DL-DCCH-Message\n",Mod_id,frame); return; - break; + case DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000: break; case DL_DCCH_MessageType__c1_PR_dlInformationTransfer: - break; + { +#if defined(ENABLE_ITTI) + DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer; + + if ((dlInformationTransfer->criticalExtensions.present == DLInformationTransfer__criticalExtensions_PR_c1) + && (dlInformationTransfer->criticalExtensions.choice.c1.present == DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8) + && (dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present == DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) + { + /* This message hold a dedicated info NAS payload, forward it to NAS */ + struct DLInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = + &dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType; + uint32_t pdu_length; + uint8_t *pdu_buffer; + MessageDef *msg_p; + + pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size; + pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf; + + msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_DOWNLINK_DATA_IND); + NAS_DOWNLINK_DATA_IND (msg_p).UEid = Mod_id; // TODO set the UEid to something else ? + NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.length = pdu_length; + NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.data = pdu_buffer; + + itti_send_msg_to_task(TASK_NAS_UE, Mod_id + NB_eNB_INST, msg_p); + } +#endif + break; + } + case DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest: break; case DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand: @@ -2247,6 +2275,7 @@ void *rrc_ue_task(void *args_p) { LOG_D(RRC, "Received %s\n", msg_name); break; + /* MAC messages */ case RRC_MAC_IN_SYNC_IND: LOG_D(RRC, "Received %s: instance %d, frame %d, eNB %d\n", msg_name, instance, RRC_MAC_IN_SYNC_IND (msg_p).frame, RRC_MAC_IN_SYNC_IND (msg_p).enb_index); @@ -2304,6 +2333,7 @@ void *rrc_ue_task(void *args_p) { break; #endif + /* PDCP messages */ case RRC_DCCH_DATA_IND: LOG_D(RRC, "Received %s: instance %d, frame %d, DCCH %d, UE %d\n", msg_name, instance, RRC_DCCH_DATA_IND (msg_p).frame, RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).ue_index); @@ -2316,6 +2346,27 @@ void *rrc_ue_task(void *args_p) { free (RRC_DCCH_DATA_IND (msg_p).sdu_p); break; + /* NAS messages */ + case NAS_UPLINK_DATA_REQ: + { + uint32_t length; + uint8_t *buffer; + + LOG_D(RRC, "Received %s: instance %d, UEid %d\n", msg_name, instance, NAS_UPLINK_DATA_REQ (msg_p).UEid); + + /* Allocate a buffer for the NAS PDU payload plus some space for the encapsulation */ + length = NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length + 20; + buffer = malloc (length); + + /* Create message for PDCP (ULInformationTransfer_t) */ + length = do_ULInformationTransfer(length, buffer, + NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); + + /* Transfer data to PDCP */ + pdcp_rrc_data_req (instance, 0 /* TODO put frame number ! */, 0, DCCH, rrc_mui++, 0, length, buffer, 1); + break; + } + default: LOG_E(RRC, "Received unexpected message %s\n", msg_name); break; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 2aab30789c..d1704fdaa9 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -94,6 +94,10 @@ extern void *bigphys_malloc (int); extern uint16_t two_tier_hexagonal_cellIds[7]; extern inline unsigned int taus (void); + +/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ +static const uint8_t rrc_transaction_identifier_number = 4; + void init_SI (u8 Mod_id) { @@ -433,9 +437,17 @@ init_MBMS (u8 Mod_id, u32 frame) { } } - #endif +static uint8_t get_next_rrc_transaction_identifier(u8 Mod_id) +{ + static uint8_t rrc_transaction_identifier[NUMBER_OF_eNB_MAX]; + + rrc_transaction_identifier[Mod_id] = (rrc_transaction_identifier[Mod_id] + 1) % rrc_transaction_identifier_number; + + return rrc_transaction_identifier[Mod_id]; +} + static void rrc_lite_eNB_init_security(u8 Mod_id, u8 UE_index) { @@ -454,8 +466,7 @@ void rrc_lite_eNB_init_security(u8 Mod_id, u8 UE_index) } /*------------------------------------------------------------------------------*/ -char -openair_rrc_lite_eNB_init (u8 Mod_id) +char openair_rrc_lite_eNB_init (u8 Mod_id) { /*-----------------------------------------------------------------------------*/ @@ -567,9 +578,7 @@ openair_rrc_lite_eNB_init (u8 Mod_id) } - -u8 -get_next_UE_index (u8 Mod_id, u8 *UE_identity) +u8 get_next_UE_index (u8 Mod_id, u8 *UE_identity) { u8 i, first_index = 255, reg = 0; static const u8 null_identity[5] = @@ -599,8 +608,7 @@ get_next_UE_index (u8 Mod_id, u8 *UE_identity) } } -void -rrc_remove_UE (u8 Mod_id, u8 UE_id) +void rrc_remove_UE (u8 Mod_id, u8 UE_id) { DevCheck(Mod_id < NB_eNB_INST, Mod_id, UE_id, NB_eNB_INST); DevCheck(UE_id < NUMBER_OF_UE_MAX, Mod_id, UE_id, NUMBER_OF_UE_MAX); @@ -610,10 +618,8 @@ rrc_remove_UE (u8 Mod_id, u8 UE_id) memset(eNB_rrc_inst[Mod_id].Info.UE_list[UE_id], 0, sizeof(eNB_rrc_inst[0].Info.UE_list[0])); } - /*------------------------------------------------------------------------------*/ -int -rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, +int rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, u8 * Rx_sdu, u8 sdu_size) { /*------------------------------------------------------------------------------*/ @@ -666,11 +672,12 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, switch (ul_dcch_msg->message.choice.c1.present) { - case UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ break; + case UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000: break; + case UL_DCCH_MessageType__c1_PR_measurementReport: LOG_D (RRC, "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND " @@ -683,6 +690,7 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, choice.measurementReport_r8. measResults); break; + case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: LOG_D (RRC, "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes " @@ -709,12 +717,14 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, Mod_id, UE_index); } break; + case UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: LOG_D (RRC, "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes " "(rrcConnectionReestablishmentComplete) --->][RRC_eNB][MOD %02d][]\n", frame, Mod_id, DCCH, sdu_size, Mod_id); break; + case UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: LOG_D (RRC, "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND %d bytes " @@ -750,6 +760,7 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, } } break; + case UL_DCCH_MessageType__c1_PR_securityModeComplete: LOG_I (RRC, "[eNB %d] Frame %d received securityModeComplete on UL-DCCH %d from UE %d\n", @@ -779,6 +790,7 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, // followup with the remaining procedure rrc_eNB_generate_UECapabilityEnquiry (Mod_id, frame, UE_index); break; + case UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: LOG_I (RRC, "[eNB %d] Frame %d received ueCapabilityInformation on UL-DCCH %d from UE %d\n", @@ -812,61 +824,101 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, UE_index, NULL, 0, eNB_rrc_inst[Mod_id].HO_flag); break; + case UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: break; + case UL_DCCH_MessageType__c1_PR_ulInformationTransfer: -#if defined(ENABLE_USE_MME) && !defined(ENABLE_ITTI) +#if defined(ENABLE_USE_MME) { if (oai_emulation.info.mme_enabled == 1) +# if defined(ENABLE_ITTI) + { + ULInformationTransfer_t *ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice.ulInformationTransfer; + + if ((ulInformationTransfer->criticalExtensions.present == + ULInformationTransfer__criticalExtensions_PR_c1) + && (ulInformationTransfer->criticalExtensions.choice.c1.present == + ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) + && (ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present == + ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { - ULInformationTransfer_t *ulInformationTransfer; - ulInformationTransfer = - &ul_dcch_msg->message.choice.c1.choice. - ulInformationTransfer; + /* This message hold a dedicated info NAS payload, forward it to NAS */ + struct ULInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = + &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType; + uint32_t pdu_length; + uint8_t *pdu_buffer; + MessageDef *msg_p; - if (ulInformationTransfer->criticalExtensions.present == - ULInformationTransfer__criticalExtensions_PR_c1) - { - if (ulInformationTransfer->criticalExtensions.choice.c1. - present == - ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) - { + pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size; + pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf; - ULInformationTransfer_r8_IEs_t - *ulInformationTransferR8; - ulInformationTransferR8 = - &ulInformationTransfer->criticalExtensions.choice. - c1.choice.ulInformationTransfer_r8; - if (ulInformationTransferR8->dedicatedInfoType. - present == - ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) - s1ap_eNB_new_data_request (Mod_id, UE_index, - ulInformationTransferR8-> - dedicatedInfoType.choice. - dedicatedInfoNAS.buf, - ulInformationTransferR8-> - dedicatedInfoType.choice. - dedicatedInfoNAS.size); - } - } + msg_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UPLINK_NAS); + S1AP_UPLINK_NAS (msg_p).eNB_ue_s1ap_id = Mod_id; // TODO set the UEid to a something else ? + S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; + S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; + + itti_send_msg_to_task(TASK_S1AP, 0, msg_p); } + } +# else + { + ULInformationTransfer_t *ulInformationTransfer; + ulInformationTransfer = + &ul_dcch_msg->message.choice.c1.choice. + ulInformationTransfer; + + if (ulInformationTransfer->criticalExtensions.present == + ULInformationTransfer__criticalExtensions_PR_c1) + { + if (ulInformationTransfer->criticalExtensions.choice.c1. + present == + ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) + { + + ULInformationTransfer_r8_IEs_t + *ulInformationTransferR8; + ulInformationTransferR8 = + &ulInformationTransfer->criticalExtensions.choice. + c1.choice.ulInformationTransfer_r8; + if (ulInformationTransferR8->dedicatedInfoType. + present == + ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) + s1ap_eNB_new_data_request (Mod_id, UE_index, + ulInformationTransferR8-> + dedicatedInfoType.choice. + dedicatedInfoNAS.buf, + ulInformationTransferR8-> + dedicatedInfoType.choice. + dedicatedInfoNAS.size); + } + } + } +# endif } #endif break; + case UL_DCCH_MessageType__c1_PR_counterCheckResponse: break; + #ifdef Rel10 case UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: break; + case UL_DCCH_MessageType__c1_PR_proximityIndication_r9: break; + case UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: break; + case UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: break; + case UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: break; #endif + default: LOG_E (RRC, "[UE %d] Frame %d : Unknown message\n", Mod_id, frame); return -1; @@ -881,10 +933,8 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, } - /*------------------------------------------------------------------------------*/ -int -rrc_eNB_decode_ccch (u8 Mod_id, u32 frame, SRB_INFO * Srb_info) +int rrc_eNB_decode_ccch (u8 Mod_id, u32 frame, SRB_INFO * Srb_info) { /*------------------------------------------------------------------------------*/ @@ -1072,14 +1122,10 @@ for (i = 0; i < 8; i++) return rval; } - - -void -rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, - u32 frame, - u8 UE_index, - RRCConnectionSetupComplete_r8_IEs_t - * rrcConnectionSetupComplete) +void rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, + u32 frame, + u8 UE_index, + RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete) { LOG_I (RRC, "[eNB %d][RAPROC] Frame %d : Logical Channel UL-DCCH, ""processing RRCConnectionSetupComplete from UE %d\n", Mod_id, frame, UE_index); @@ -1094,33 +1140,44 @@ rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_FIRST_REQ); S1AP_NAS_FIRST_REQ (message_p).rnti = eNB_mac_inst[Mod_id].UE_template[UE_index].rnti; // TODO check if this is the correct id to use + /* Assume that cause is coded in the same way in RRC and S1ap, just check that the value is in S1ap range */ DevCheck(eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index] < RRC_CAUSE_LAST, eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index], RRC_CAUSE_LAST, Mod_id); S1AP_NAS_FIRST_REQ (message_p).establishment_cause = eNB_rrc_inst[Mod_id].Info.UE_establishment_cause[UE_index]; + /* Forward NAS message */ S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer = rrcConnectionSetupComplete->dedicatedInfoNAS.buf; S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size; - if (eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index].present == InitialUE_Identity_PR_s_TMSI) + /* Fill UE identities with available information */ { - S_TMSI_t s_TMSI = eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index].choice.s_TMSI; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask = UE_IDENTITIES_NONE; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.present = IDENTITY_PR_s_tmsi; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.choice.s_tmsi.mme_code = BIT_STRING_to_uint8(&s_TMSI.mmec); - S1AP_NAS_FIRST_REQ (message_p).ue_identity.choice.s_tmsi.m_tmsi = BIT_STRING_to_uint32(&s_TMSI.m_TMSI); - } - else - { - if (rrcConnectionSetupComplete->registeredMME != NULL) - { - S1AP_NAS_FIRST_REQ (message_p).ue_identity.present = IDENTITY_PR_gummei; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.choice.gummei.mcc = 0; // TODO decode BIT STREAM - S1AP_NAS_FIRST_REQ (message_p).ue_identity.choice.gummei.mnc = 0; // TODO decode BIT STREAM - S1AP_NAS_FIRST_REQ (message_p).ue_identity.choice.gummei.mme_code = 0; // TODO decode BIT STREAM - S1AP_NAS_FIRST_REQ (message_p).ue_identity.choice.gummei.mme_group_id = 0; // TODO decode BIT STREAM + if (eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index].present == InitialUE_Identity_PR_s_TMSI) { + /* Fill s-TMSI */ + S_TMSI_t s_TMSI = eNB_rrc_inst[Mod_id].Info.UE_Initialue_identity[UE_index].choice.s_TMSI; + + S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_s_tmsi; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code = BIT_STRING_to_uint8 (&s_TMSI.mmec); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi = BIT_STRING_to_uint32 (&s_TMSI.m_TMSI); } - else - { - S1AP_NAS_FIRST_REQ (message_p).ue_identity.present = IDENTITY_PR_NOTHING; + + if (rrcConnectionSetupComplete->registeredMME != NULL) { + /* Fill GUMMEI */ + struct RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME; + + S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; + if (r_mme->plmn_Identity != NULL) { + if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { + /* Use first indicated PLMN MCC if it is defined */ + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[0]; + } + if (r_mme->plmn_Identity->mnc.list.count > 0) { + /* Use first indicated PLMN MNC if it is defined */ + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[0]; + } + } + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi); } } @@ -1134,8 +1191,8 @@ rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, rrcConnectionSetupComplete->dedicatedInfoNAS. size); } - else # endif + else #endif { @@ -1146,8 +1203,7 @@ rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, mui_t rrc_eNB_mui = 0; -void -rrc_eNB_generate_SecurityModeCommand (u8 Mod_id, u32 frame, u16 UE_index) +void rrc_eNB_generate_SecurityModeCommand (u8 Mod_id, u32 frame, u16 UE_index) { uint8_t buffer[100]; @@ -1172,15 +1228,13 @@ rrc_eNB_generate_SecurityModeCommand (u8 Mod_id, u32 frame, u16 UE_index) } - -void -rrc_eNB_generate_UECapabilityEnquiry (u8 Mod_id, u32 frame, u16 UE_index) +void rrc_eNB_generate_UECapabilityEnquiry (u8 Mod_id, u32 frame, u16 UE_index) { uint8_t buffer[100]; uint8_t size; - size = do_UECapabilityEnquiry (Mod_id, buffer, UE_index, 0); + size = do_UECapabilityEnquiry (Mod_id, buffer, UE_index, get_next_rrc_transaction_identifier(Mod_id)); LOG_I (RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d, UE id %d)\n", @@ -1196,12 +1250,12 @@ rrc_eNB_generate_UECapabilityEnquiry (u8 Mod_id, u32 frame, u16 UE_index) rrc_eNB_mui++, 0, size, buffer, 1); } -void -rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, - u16 UE_index, - u8 * nas_pdu, - u32 nas_length, - u8 ho_state) + +void rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, + u16 UE_index, + u8 * nas_pdu, + u32 nas_length, + u8 ho_state) { u8 buffer[RRC_BUF_SIZE]; @@ -1646,7 +1700,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, memset (buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration (Mod_id, buffer, UE_index, 0, //Transaction_id, + size = do_RRCConnectionReconfiguration (Mod_id, buffer, UE_index, get_next_rrc_transaction_identifier(Mod_id), //Transaction_id, SRB_configList2, *DRB_configList, NULL, // DRB2_list, NULL, //*sps_Config, physicalConfigDedicated[UE_index], MeasObj_list, ReportConfig_list, @@ -1665,8 +1719,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, rrc_eNB_mui++, 0, size, buffer, 1); } -void -rrc_eNB_process_MeasurementReport (u8 Mod_id, u32 frame, u16 UE_index, + +void rrc_eNB_process_MeasurementReport (u8 Mod_id, u32 frame, u16 UE_index, MeasResults_t * measResults2) { @@ -1715,8 +1769,8 @@ rrc_eNB_process_MeasurementReport (u8 Mod_id, u32 frame, u16 UE_index, //send_handover_command(); } -void -rrc_eNB_generate_HandoverPreparationInformation (u8 Mod_id, u32 frame, u8 UE_index, PhysCellId_t targetPhyId) { + +void rrc_eNB_generate_HandoverPreparationInformation (u8 Mod_id, u32 frame, u8 UE_index, PhysCellId_t targetPhyId) { u8 UE_id_target; u8 mod_id_target = get_adjacent_cell_mod_id(targetPhyId); HANDOVER_INFO *handoverInfo = CALLOC(1,sizeof(*handoverInfo)); @@ -1826,8 +1880,7 @@ void check_handovers(u8 Mod_id, u32 frame) { } // 5.3.5.4 RRCConnectionReconfiguration including the mobilityControlInfo to prepare the UE handover -void -rrc_eNB_generate_RRCConnectionReconfiguration_handover (u8 Mod_id, u32 frame,u16 UE_index,u8 *nas_pdu,u32 nas_length) { +void rrc_eNB_generate_RRCConnectionReconfiguration_handover (u8 Mod_id, u32 frame,u16 UE_index,u8 *nas_pdu,u32 nas_length) { u8 buffer[RRC_BUF_SIZE]; u8 size; @@ -2577,7 +2630,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover (u8 Mod_id, u32 frame,u16 // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; memset (buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration (Mod_id, buffer, UE_index, 0, //Transaction_id, + size = do_RRCConnectionReconfiguration (Mod_id, buffer, UE_index, get_next_rrc_transaction_identifier(Mod_id), //Transaction_id, SRB_configList2, DRB_configList2, NULL, // DRB2_list, NULL, //*sps_Config, physicalConfigDedicated[UE_index], MeasObj_list, ReportConfig_list, @@ -2659,8 +2712,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover (u8 Mod_id, u32 frame,u16 } -void -rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, +void rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, u8 UE_index, RRCConnectionReconfigurationComplete_r8_IEs_t *rrcConnectionReconfigurationComplete) { @@ -2867,9 +2919,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, } } - -void -rrc_eNB_generate_RRCConnectionSetup (u8 Mod_id, u32 frame, u16 UE_index) { +void rrc_eNB_generate_RRCConnectionSetup (u8 Mod_id, u32 frame, u16 UE_index) { LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; SRB_ToAddModList_t **SRB_configList = &eNB_rrc_inst[Mod_id].SRB_configList[UE_index]; @@ -2978,6 +3028,9 @@ void *rrc_enb_task(void *args_p) { const char *msg_name; instance_t instance; SRB_INFO *srb_info_p; + uint8_t ue_index; + uint32_t length; + uint8_t *buffer; itti_mark_task_ready (TASK_RRC_ENB); @@ -2997,6 +3050,7 @@ void *rrc_enb_task(void *args_p) { LOG_D(RRC, "Received %s\n", msg_name); break; + /* MAC messages */ case RRC_MAC_CCCH_DATA_IND: LOG_D(RRC, "Received %s: instance %d, frame %d,\n", msg_name, instance, RRC_MAC_CCCH_DATA_IND (msg_p).frame); @@ -3009,6 +3063,7 @@ void *rrc_enb_task(void *args_p) { rrc_eNB_decode_ccch (instance, RRC_MAC_CCCH_DATA_IND (msg_p).frame, srb_info_p); break; + /* PDCP messages */ case RRC_DCCH_DATA_IND: LOG_D(RRC, "Received %s: instance %d, frame %d, DCCH %d, UE %d\n", msg_name, instance, RRC_DCCH_DATA_IND (msg_p).frame, RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).ue_index); @@ -3021,6 +3076,35 @@ void *rrc_enb_task(void *args_p) { free (RRC_DCCH_DATA_IND (msg_p).sdu_p); break; + /* S1AP Messages */ + case S1AP_DOWNLINK_NAS: + ue_index = S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id; // TOTO convert eNB_ue_s1ap_id into ue_index + + LOG_D(RRC, "Received %s: instance %d, eNB_ue_s1ap_id %d, ue_index %d\n", + msg_name, instance, S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id, ue_index); + + /* Allocate a buffer for the NAS PDU payload plus some space for the encapsulation */ + length = S1AP_DOWNLINK_NAS (msg_p).nas_pdu.length + 20; + buffer = malloc (length); + + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_DLInformationTransfer(length, buffer, get_next_rrc_transaction_identifier(instance), + S1AP_DOWNLINK_NAS (msg_p).nas_pdu.length, S1AP_DOWNLINK_NAS (msg_p).nas_pdu.buffer); + + /* Transfer data to PDCP */ + pdcp_rrc_data_req (instance, 0 /* TODO put frame number ! */, 1, (ue_index * NB_RB_MAX) + DCCH, rrc_eNB_mui++, 0, length, buffer, 1); + break; + + case S1AP_INITIAL_CONTEXT_SETUP_REQ: + ue_index = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; // TOTO convert eNB_ue_s1ap_id into ue_index + + LOG_D(RRC, "Received %s: instance %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", msg_name, instance, + S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id, S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs); + + rrc_eNB_generate_SecurityModeCommand (instance, 0 /* TODO put frame number ! */, ue_index); + // TODO process this message + break; + default: LOG_E(RRC, "Received unexpected message %s\n", msg_name); break;