RRC:
- Reorganized ITTI messages definition by groups (MAC, PDCP and RRC). - Added support for some NAS / S1AP messages. S1AP: - Corrected MME selection in handle NAS first request. - Modified some messages definition. git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4429 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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)
|
||||
@@ -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_ */
|
||||
@@ -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"
|
||||
#include "x2ap_messages_def.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"
|
||||
|
||||
@@ -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)
|
||||
@@ -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_ */
|
||||
@@ -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)
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
+180
-96
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user