Commit 91dd7ed4 authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'origin/develop_integration_2018_w03' into develop

Summary of changes:
- Implementation of paging (see issue #255 in gitlab)
- Implementation of RRC RE-ESTABLISHMENT (see issue #256 in gitlab)
- Implementation of RRC CONNECTION RELEASE (see issue #257 in gitlab)

Some modifications with timers have been done.
Expect (and report) problems, thanks.

What has been tested:
- monolithic eNB 5 and 10MHz with one commercial UE. UDP and TCP
  traffic, uplink and downlink, with iperf (with a third party
  EPC, not openair-cn). TCP downlink traffic is not stable.
  Reason yet unknown. Will be fixed later.
parents 8489e406 3a867ac7
......@@ -2005,6 +2005,7 @@ add_executable(oaisim_nos1
${OPENAIR_BIN_DIR}/messages_xml.h
${OPENAIR_TARGETS}/RT/USER/lte-ue.c
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
${OPENAIR_TARGETS}/RT/USER/lte-enb.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
......
......@@ -185,6 +185,10 @@ ID = ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST
DESC = RRC connection reestablishment request
GROUP = ALL:RRC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti
ID = ENB_RRC_CONNECTION_REESTABLISHMENT
DESC = RRC connection reestablishment
GROUP = ALL:RRC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti
ID = ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE
DESC = RRC connection reestablishment complete
GROUP = ALL:RRC:ENB
......
......@@ -6560,7 +6560,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
else
ul_subframe = ((n+4)%10);
if (subframe_select(frame_parms,ul_subframe) != SF_UL) return(255);
if ((subframe_select(frame_parms,ul_subframe) != SF_UL) && (frame_parms->frame_type == TDD)) return(255);
LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
return ul_subframe;
......
......@@ -178,9 +178,26 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch->harq_processes[i]->phich_ACK = 0;
ulsch->harq_processes[i]->round = 0;
ulsch->harq_processes[i]->rar_alloc = 0;
ulsch->harq_processes[i]->first_rb = 0;
ulsch->harq_processes[i]->nb_rb = 0;
ulsch->harq_processes[i]->TBS = 0;
ulsch->harq_processes[i]->Or1 = 0;
ulsch->harq_processes[i]->Or2 = 0;
for ( int j = 0; j < 2; j++ ) {
ulsch->harq_processes[i]->o_RI[j] = 0;
}
ulsch->harq_processes[i]->O_ACK = 0;
ulsch->harq_processes[i]->srs_active = 0;
ulsch->harq_processes[i]->rvidx = 0;
ulsch->harq_processes[i]->Msc_initial = 0;
ulsch->harq_processes[i]->Nsymb_initial = 0;
}
}
ulsch->beta_offset_cqi_times8 = 0;
ulsch->beta_offset_ri_times8 = 0;
ulsch->beta_offset_harqack_times8 = 0;
ulsch->Msg3_active = 0;
}
}
......@@ -2044,3 +2061,4 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
}
#endif
......@@ -989,6 +989,7 @@ typedef struct PHY_VARS_eNB_s {
LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
LTE_eNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
LTE_eNB_DLSCH_t *dlsch_MCH;
LTE_eNB_DLSCH_t *dlsch_PCH;
LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
......
......@@ -213,6 +213,13 @@ void prach_procedures(PHY_VARS_eNB *eNB,
int br_flag
#endif
);
/*! \brief Function to compute subframe Number(DL and S) as a function of Frame type and TDD Configuration
@param frame_parms Pointer to DL frame parameter descriptor
@returns Subframe Number (DL,S)
*/
int subframe_num(LTE_DL_FRAME_PARMS *frame_parms);
/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
@param frame_parms Pointer to DL frame parameter descriptor
@param subframe Subframe index
......
......@@ -709,6 +709,26 @@ uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1)
return(Np[0+plus1]);
}
int subframe_num(LTE_DL_FRAME_PARMS *frame_parms){
if (frame_parms->frame_type == FDD)
return 10;
switch (frame_parms->tdd_config) {
case 1:
return 6;
case 3:
return 7;
case 4:
return 8;
case 5:
return 9;
default:
LOG_E(PHY,"Unsupported TDD configuration %d\n",frame_parms->tdd_config);
AssertFatal(frame_parms->tdd_config==1 || frame_parms->tdd_config==3 || frame_parms->tdd_config==4 || frame_parms->tdd_config==5,"subframe x Unsupported TDD configuration");
return(255);
}
}
lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe)
{
......
......@@ -887,10 +887,10 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
if (uci->type == SR) {
if (SR_payload == 1) {
fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
return;
continue;
}
else {
return;
continue;
}
}
case HARQ:
......
......@@ -40,3 +40,5 @@ MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDat
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)
MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req)
......@@ -43,11 +43,13 @@
#define RRC_MAC_MCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_req
#define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind
#define RRC_MAC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req
// Some constants from "LAYER2/MAC/defs.h"
#define BCCH_SDU_SIZE (512)
#define CCCH_SDU_SIZE (512)
#define MCCH_SDU_SIZE (512)
#define PCCH_SDU_SIZE (512)
//-------------------------------------------------------------------------------------------//
// Messages between RRC and MAC layers
......@@ -114,4 +116,10 @@ typedef struct RrcMacMcchDataInd_s {
uint8_t mbsfn_sync_area;
} RrcMacMcchDataInd;
typedef struct RrcMacPcchDataReq_s {
uint32_t frame;
uint32_t sdu_size;
uint8_t sdu[PCCH_SDU_SIZE];
uint8_t enb_index;
} RrcMacPcchDataReq;
#endif /* MAC_MESSAGES_TYPES_H_ */
......@@ -30,3 +30,4 @@
// 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)
MESSAGE_DEF(RRC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq, rrc_pcch_data_req)
......@@ -33,6 +33,7 @@
// Defines to access message fields.
#define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_req
#define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_ind
#define RRC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_pcch_data_req
//-------------------------------------------------------------------------------------------//
// Messages between RRC and PDCP layers
......@@ -60,4 +61,13 @@ typedef struct RrcDcchDataInd_s {
uint8_t eNB_index; // LG: needed in UE
} RrcDcchDataInd;
typedef struct RrcPcchDataReq_s {
uint32_t sdu_size;
uint8_t *sdu_p;
uint8_t mode;
uint16_t rnti;
uint8_t ue_index;
uint8_t CC_id;
} RrcPcchDataReq;
#endif /* PDCP_MESSAGES_TYPES_H_ */
......@@ -33,6 +33,11 @@ MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG, MESSAGE_PRIORITY_MED, IttiMsgT
MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_ue_context_release_log)
MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_setup_request_log)
MESSAGE_DEF(S1AP_E_RAB_SETUP_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_setup_response_log)
MESSAGE_DEF(S1AP_E_RAB_MODIFY_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_modify_request_log)
MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_modify_response_log)
MESSAGE_DEF(S1AP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_paging_log)
MESSAGE_DEF(S1AP_E_RAB_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_request_log)
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_response_log)
/* eNB application layer -> S1AP messages */
MESSAGE_DEF(S1AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t , s1ap_register_enb_req)
......@@ -54,6 +59,8 @@ MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_
MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_fail_t , s1ap_ue_ctxt_modification_fail)
MESSAGE_DEF(S1AP_E_RAB_SETUP_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_resp_t , s1ap_e_rab_setup_resp)
MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_fail_t , s1ap_e_rab_setup_request_fail)
MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_resp_t , s1ap_e_rab_modify_resp)
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp)
/* S1AP -> RRC messages */
MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas )
......@@ -61,6 +68,8 @@ MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, s1ap_initial_
MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_req_t , s1ap_ue_ctxt_modification_req)
MESSAGE_DEF(S1AP_PAGING_IND , MESSAGE_PRIORITY_MED, s1ap_paging_ind_t , s1ap_paging_ind )
MESSAGE_DEF(S1AP_E_RAB_SETUP_REQ , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_t , s1ap_e_rab_setup_req )
MESSAGE_DEF(S1AP_E_RAB_MODIFY_REQ , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_req_t , s1ap_e_rab_modify_req )
MESSAGE_DEF(S1AP_E_RAB_RELEASE_COMMAND , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_command_t , s1ap_e_rab_release_command)
MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, s1ap_ue_release_command_t , s1ap_ue_release_command)
/* S1AP <-> RRC messages (can be initiated either by MME or eNB) */
......
......@@ -41,6 +41,7 @@
#define S1AP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_ctxt_modification_fail
#define S1AP_E_RAB_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_resp
#define S1AP_E_RAB_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req_fail
#define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp
#define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas
#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
......@@ -48,9 +49,12 @@
#define S1AP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_command
#define S1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_complete
#define S1AP_E_RAB_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req
#define S1AP_PAGIND_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_paging_ind
#define S1AP_E_RAB_MODIFY_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_req
#define S1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_paging_ind
#define S1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_req
#define S1AP_E_RAB_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_release_command
#define S1AP_E_RAB_RELEASE_RESPONSE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_release_resp
//-------------------------------------------------------------------------------------------//
/* Maximum number of e-rabs to be setup/deleted in a single message.
......@@ -175,6 +179,11 @@ typedef struct s1ap_gummei_s {
uint16_t mme_group_id;
} s1ap_gummei_t;
typedef struct s1ap_imsi_s {
uint8_t buffer[S1AP_IMSI_LENGTH];
uint8_t length;
} s1ap_imsi_t;
typedef struct s_tmsi_s {
uint8_t mme_code;
uint32_t m_tmsi;
......@@ -189,7 +198,7 @@ typedef enum ue_paging_identity_presenceMask_e {
typedef struct ue_paging_identity_s {
ue_paging_identity_presenceMask_t presenceMask;
union {
char imsi[S1AP_IMSI_LENGTH];
s1ap_imsi_t imsi;
s_tmsi_t s_tmsi;
} choice;
} ue_paging_identity_t;
......@@ -260,11 +269,29 @@ typedef struct e_rab_setup_s {
uint32_t gtp_teid;
} e_rab_setup_t;
typedef struct e_rab_modify_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
} e_rab_modify_t;
typedef enum S1ap_Cause_e {
S1AP_CAUSE_NOTHING, /* No components present */
S1AP_CAUSE_RADIO_NETWORK,
S1AP_CAUSE_TRANSPORT,
S1AP_CAUSE_NAS,
S1AP_CAUSE_PROTOCOL,
S1AP_CAUSE_MISC,
/* Extensions may appear below */
} s1ap_Cause_t;
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;
s1ap_Cause_t cause;
uint8_t cause_value;
} e_rab_failed_t;
typedef enum s1ap_ue_ctxt_modification_present_s {
......@@ -460,6 +487,12 @@ typedef struct s1ap_initial_context_setup_req_s {
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
} s1ap_initial_context_setup_req_t;
typedef struct tai_plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
} plmn_identity_t;
typedef struct s1ap_paging_ind_s {
/* UE identity index value.
* Specified in 3GPP TS 36.304
......@@ -472,6 +505,15 @@ typedef struct s1ap_paging_ind_s {
/* Indicates origin of paging */
cn_domain_t cn_domain;
/* PLMN_identity in TAI of Paging*/
plmn_identity_t plmn_identity[256];
/* TAC in TAIList of Paging*/
int16_t tac[256];
/* size of TAIList*/
int16_t tai_size;
/* Optional fields */
paging_drx_t paging_drx;
......@@ -520,16 +562,6 @@ typedef struct s1ap_ue_release_command_s {
//-------------------------------------------------------------------------------------------//
typedef enum S1ap_Cause_e {
S1AP_CAUSE_NOTHING, /* No components present */
S1AP_CAUSE_RADIO_NETWORK,
S1AP_CAUSE_TRANSPORT,
S1AP_CAUSE_NAS,
S1AP_CAUSE_PROTOCOL,
S1AP_CAUSE_MISC,
/* Extensions may appear below */
} s1ap_Cause_t;
// S1AP <-- RRC messages
typedef struct s1ap_ue_release_req_s {
unsigned eNB_ue_s1ap_id:24;
......@@ -537,4 +569,78 @@ typedef struct s1ap_ue_release_req_s {
long cause_value;
} s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
typedef struct s1ap_e_rab_modify_req_s {
/* UE id for initial connection to S1AP */
uint16_t ue_initial_id;
/* MME UE id */
uint16_t mme_ue_s1ap_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab to be modify in the list */
uint8_t nb_e_rabs_tomodify;
/* E RAB modify request */
e_rab_t e_rab_modify_params[S1AP_MAX_E_RAB];
} s1ap_e_rab_modify_req_t;
typedef struct s1ap_e_rab_modify_resp_s {
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab modify-ed in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab modify-ed by RRC layers */
e_rab_modify_t e_rabs[S1AP_MAX_E_RAB];
/* Number of e_rab failed to be modify in list */
uint8_t nb_of_e_rabs_failed;
/* list of e_rabs that failed to be modify */
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
} s1ap_e_rab_modify_resp_t;
typedef struct e_rab_release_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
} e_rab_release_t;
typedef struct s1ap_e_rab_release_command_s {
/* MME UE id */
uint16_t mme_ue_s1ap_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
nas_pdu_t nas_pdu;
/* Number of e_rab to be released in the list */
uint8_t nb_e_rabs_torelease;
/* E RAB release command */
e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB];
} s1ap_e_rab_release_command_t;
typedef struct s1ap_e_rab_release_resp_s {
/* MME UE id */
uint16_t mme_ue_s1ap_id;
/* eNB ue s1ap id as initialized by S1AP layer */
unsigned eNB_ue_s1ap_id:24;
/* Number of e_rab released in the list */
uint8_t nb_of_e_rabs_released;
/* list of e_rabs released */
e_rab_release_t e_rab_release[S1AP_MAX_E_RAB];
/* Number of e_rab failed to be released in list */
uint8_t nb_of_e_rabs_failed;
/* list of e_rabs that failed to be released */
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
} s1ap_e_rab_release_resp_t;
#endif /* S1AP_MESSAGES_TYPES_H_ */
......@@ -163,6 +163,8 @@
/*!\brief maximum number of slices / groups */
#define MAX_NUM_SLICES 4
#define U_PLANE_INACTIVITY_VALUE 6000
/*
* eNB part
*/
......@@ -472,6 +474,15 @@ typedef struct {
/// BCCH MCS
uint32_t ccch_mcs;
/// num PCCH PDU per CC
uint32_t total_num_pcch_pdu;
/// PCCH buffer size
uint32_t pcch_buffer;
/// total PCCH buffer size
uint32_t total_pcch_buffer;
/// BCCH MCS
uint32_t pcch_mcs;
/// num active users
uint16_t num_dlactive_UEs;
/// available number of PRBs for a give SF
......@@ -824,6 +835,8 @@ typedef struct {
int32_t cqi_req_timer;
int32_t ul_inactivity_timer;
int32_t ul_failure_timer;
uint32_t ue_reestablishment_reject_timer;
uint32_t ue_reestablishment_reject_timer_thres;
int32_t ul_scheduled;
int32_t ra_pdcch_order_sent;
int32_t ul_out_of_sync;
......@@ -855,6 +868,7 @@ typedef struct {
uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
uint8_t dl_cqi[NFAPI_CC_MAX];
int32_t uplane_inactivity_timer;
} UE_sched_ctrl;
/*! \brief eNB template for the Random access information */
typedef struct {
......@@ -982,6 +996,10 @@ typedef struct {
uint32_t BCCH_alloc_pdu;
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
/// Outgoing PCCH DCI allocation
uint32_t PCCH_alloc_pdu;
/// Outgoing PCCH pdu for PHY
PCCH_PDU PCCH_pdu;
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations
......@@ -1102,6 +1120,8 @@ typedef struct eNB_MAC_INST_s {
time_stats_t schedule_mch;
/// processing time of eNB ULSCH reception
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
/// processing time of eNB PCH scheduler
time_stats_t schedule_pch;
} eNB_MAC_INST;
/*
......
......@@ -164,7 +164,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
ul_config_pdu->srs_pdu.srs_pdu_rel8.size =
(uint8_t)
sizeof(nfapi_ul_config_srs_pdu);;
sizeof(nfapi_ul_config_srs_pdu);
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti =
UE_list->UE_template[CC_id][UE_id].
rnti;
......@@ -546,7 +546,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
// check threshold
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
// inform RRC of failure and clear timer
LOG_I(MAC,
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
......@@ -558,6 +558,12 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
}
} // ul_failure_timer>0
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){
LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
}// time > 60s
}
void
......@@ -702,6 +708,50 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
ul_inactivity_timer,
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
check_ul_failure(module_idP, CC_id, i, frameP, subframeP);
if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) {
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++;
if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >=
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) {
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0;
for (int ue_id_l = 0; ue_id_l < NUMBER_OF_UE_MAX; ue_id_l++) {
if (reestablish_rnti_map[ue_id_l][0] == rnti) {
// clear currentC-RNTI from map
reestablish_rnti_map[ue_id_l][0] = 0;
reestablish_rnti_map[ue_id_l][1] = 0;
break;
}
}
for (int ii=0; ii<NUMBER_OF_UE_MAX; ii++) {
LTE_eNB_ULSCH_t *ulsch = NULL;
ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii];
if((ulsch != NULL) && (ulsch->rnti == rnti)){
LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti);
clean_eNb_ulsch(ulsch);
break;
}
}
for(int j = 0; j < 10; j++){
nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
ul_req_tmp = &RC.mac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body;
if(ul_req_tmp){
int pdu_number = ul_req_tmp->number_of_pdus;
for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){
LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
if(pdu_index < pdu_number -1){
memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
}
ul_req_tmp->number_of_pdus--;
}
}
}
}
rrc_mac_remove_ue(module_idP,rnti);
}
}
}
......@@ -731,6 +781,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
schedule_mib(module_idP, frameP, subframeP);
// This schedules SI for legacy LTE and eMTC starting in subframeP
schedule_SI(module_idP, frameP, subframeP);
// This schedules Paging in subframeP
schedule_PCH(module_idP,frameP,subframeP);
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP
schedule_RA(module_idP, frameP, subframeP);
// copy previously scheduled UL resources (ULSCH + HARQ)
......
This diff is collapsed.
......@@ -2094,6 +2094,7 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP
sizeof(UE_sched_ctrl));
memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0,
sizeof(eNB_UE_STATS));
UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
......@@ -2124,47 +2125,68 @@ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP)
//------------------------------------------------------------------------------
{
int i;
int j;
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
int UE_id = find_UE_id(mod_idP, rntiP);
int UE_id = find_UE_id(mod_idP,rntiP);
int pCC_id;
if (UE_id == -1) {
LOG_W(MAC, "rrc_mac_remove_ue: UE %x not found\n", rntiP);
return 0;
LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
return 0;
}
pCC_id = UE_PCCID(mod_idP, UE_id);
pCC_id = UE_PCCID(mod_idP,UE_id);
LOG_I(MAC, "Removing UE %d from Primary CC_id %d (rnti %x)\n", UE_id,
pCC_id, rntiP);
dump_ue_list(UE_list, 0);
LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
dump_ue_list(UE_list,0);
UE_list->active[UE_id] = FALSE;
UE_list->num_UEs--;
if (UE_list->head == UE_id)
UE_list->head = UE_list->next[UE_id];
else
UE_list->next[prev(UE_list, UE_id, 0)] = UE_list->next[UE_id];
if (UE_list->head_ul == UE_id)
UE_list->head_ul = UE_list->next_ul[UE_id];
else
UE_list->next_ul[prev(UE_list, UE_id, 0)] =
UE_list->next_ul[UE_id];
if (UE_list->head == UE_id) UE_list->head=UE_list->next[UE_id];
else UE_list->next[prev(UE_list,UE_id,0)]=UE_list->next[UE_id];
if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id];
else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[UE_id];
// clear all remaining pending transmissions
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][UE_id].ul_SR = 0;
UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE;
/* UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0;
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][UE_id].ul_SR = 0;
UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE;
*/
memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE));
UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_retx = 0;
for ( j = 0; j < NB_RB_MAX; j++ ) {
UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_tx[j] = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_tx[j] = 0;
}
UE_list->eNB_UE_stats[pCC_id][UE_id].num_retransmission = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_sdu_bytes = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_rx = 0;
for ( j = 0; j < NB_RB_MAX; j++ ) {
UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_rx[j] = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_rx[j] = 0;
}
UE_list->eNB_UE_stats[pCC_id][UE_id].num_errors_rx = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes_rx = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus_rx = 0;
UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_errors_rx = 0;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE;
eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
// check if this has an RA process active
RA_t *ra;
......
......@@ -732,6 +732,8 @@ rx_sdu(const module_id_t enb_mod_idP,
num_pdu_rx[rx_lcids[i]] += 1;
UE_list->eNB_UE_stats[CC_idP][UE_id].
num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
//clear uplane_inactivity_timer
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
} else { /* rx_length[i] */
UE_list->eNB_UE_stats[CC_idP][UE_id].
num_errors_rx += 1;
......
......@@ -101,4 +101,4 @@ extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#endif //DEF_H
#endif //DEF_H
......@@ -426,6 +426,14 @@ void set_ue_dai(sub_frame_t subframeP,
int UE_id,
uint8_t CC_id, uint8_t tdd_config, UE_list_t * UE_list);
/** \brief First stage of PCH Scheduling. Gets a PCH SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe number on which to act
@param paging_ue_index
*/
void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP);
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP,
unsigned char group_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
......
......@@ -68,6 +68,8 @@
extern int otg_enabled;
#endif
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
//-----------------------------------------------------------------------------
/*
......@@ -948,6 +950,21 @@ pdcp_run (
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
case RRC_PCCH_DATA_REQ:
{
sdu_size_t sdu_buffer_sizeP;
sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size;
uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id;
uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index;
RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP;
if (sdu_buffer_sizeP > 0) {
memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP);
}
//paging pdcp log
LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP);
}
break;
default:
LOG_E(PDCP, "Received unexpected message %s\n", msg_name);
break;
......@@ -1037,6 +1054,13 @@ pdcp_remove_UE(
// check and remove SRBs first
for(int i = 0;i<NUMBER_OF_UE_MAX;i++){
if(pdcp_eNB_UE_instance_to_rnti[i] == ctxt_pP->rnti){
pdcp_eNB_UE_instance_to_rnti[i] = NOT_A_RNTI;
break;
}
}
for (srb_id=0; srb_id<2; srb_id++) {
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES);
h_rc = hashtable_remove(pdcp_coll_p, key);
......@@ -1344,7 +1368,7 @@ rrc_pdcp_config_asn1_req (
for (cnt=0; cnt<drb2release_list_pP->list.count; cnt++) {
pdrb_id_p = drb2release_list_pP->list.array[cnt];
drb_id = *pdrb_id_p;
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_NO);
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO);
h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
if (h_rc != HASH_TABLE_OK) {
......@@ -1472,7 +1496,17 @@ pdcp_config_req_asn1 (
if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
pdcp_pP->is_ue = FALSE;
//pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti;
pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
// pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
if( srb_flagP == SRB_FLAG_NO ) {
for(int i = 0;i<NUMBER_OF_UE_MAX;i++){
if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI){
break;
}
pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
}
pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
}
//pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
} else {
pdcp_pP->is_ue = TRUE;
......
......@@ -589,7 +589,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
if (ctxt_cpy.enb_flag) {
ctxt.module_id = 0;
rab_id = pdcp_read_header_g.rb_id % maxDRB;
ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index];
ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / maxDRB];
} else {
ctxt.module_id = 0;
rab_id = pdcp_read_header_g.rb_id % maxDRB;
......
......@@ -125,6 +125,7 @@ rlc_tm_cleanup (
// RX SIDE
if ((rlcP->output_sdu_in_construction)) {
free_mem_block (rlcP->output_sdu_in_construction, __func__);
rlcP->output_sdu_in_construction = NULL;
}
memset(rlcP, 0, sizeof(rlc_tm_entity_t));
......
......@@ -343,6 +343,7 @@ rlc_um_cleanup (
if ((rlc_pP->output_sdu_in_construction)) {
free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
rlc_pP->output_sdu_in_construction = NULL;
}
if (rlc_pP->dar_buffer) {
......
......@@ -131,6 +131,12 @@ int dump_eNB_l2_stats(char *buffer, int length)
eNB->eNB_stats[CC_id].bcch_buffer,
eNB->eNB_stats[CC_id].total_bcch_buffer,
eNB->eNB_stats[CC_id].bcch_mcs);
len += sprintf(&buffer[len],"PCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n",
eNB->eNB_stats[CC_id].total_num_pcch_pdu,
eNB->eNB_stats[CC_id].pcch_buffer,
eNB->eNB_stats[CC_id].total_pcch_buffer,
eNB->eNB_stats[CC_id].pcch_mcs);
eNB->eNB_stats[CC_id].dlsch_bitrate=((eNB->eNB_stats[CC_id].dlsch_bytes_tx*8)/((eNB->frame + 1)*10));
eNB->eNB_stats[CC_id].total_dlsch_pdus_tx+=eNB->eNB_stats[CC_id].dlsch_pdus_tx;
......
......@@ -249,6 +249,44 @@ mac_rrc_data_req(
return (Sdu_size);
}
if( (Srb_id & RAB_OFFSET ) == PCCH) {
LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
// check if data is there for MAC
if(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] > 0) { //Fill buffer
LOG_D(RRC,"[eNB %d] PCCH (%p) has %d bytes\n",Mod_idP,&RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area],
RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]);
#if 0 //defined(ENABLE_ITTI)
{
MessageDef *message_p;
int pcch_size = RC.rrc[Mod_idP]->arrier[CC_id].sizeof_paging[mbsfn_sync_area];
int sdu_size = sizeof(RRC_MAC_PCCH_DATA_REQ (message_p).sdu);
if (pcch_size > sdu_size) {
LOG_E(RRC, "SDU larger than PCCH SDU buffer size (%d, %d)", pcch_size, sdu_size);
pcch_size = sdu_size;
}
message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_MAC_PCCH_DATA_REQ);
RRC_MAC_PCCH_DATA_REQ (message_p).frame = frameP;
RRC_MAC_PCCH_DATA_REQ (message_p).sdu_size = pcch_size;
memset (RRC_MAC_PCCH_DATA_REQ (message_p).sdu, 0, PCCH_SDU_SIZE);
memcpy (RRC_MAC_PCCH_DATA_REQ (message_p).sdu, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], pcch_size);
RRC_MAC_PCCH_DATA_REQ (message_p).enb_index = eNB_index;
itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
}
#endif
memcpy(buffer_pP, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]);
Sdu_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area];
RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] = 0;
}
return (Sdu_size);
}
#if defined(Rel10) || defined(Rel14)
if((Srb_id & RAB_OFFSET) == MCCH) {
......@@ -770,12 +808,34 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
if (ue_context_p != NULL) {
LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
ue_context_p->ue_context.ul_failure_timer=1;
if(ue_context_p->ue_context.ul_failure_timer == 0)
ue_context_p->ue_context.ul_failure_timer=1;
}
else {
LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
}
rrc_mac_remove_ue(Mod_instP,rntiP);
// rrc_mac_remove_ue(Mod_instP,rntiP);
}
void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
const int CC_idP,
const frame_t frameP,
const sub_frame_t subframeP,
const rnti_t rntiP)
{
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
ue_context_p = rrc_eNB_get_ue_context(
RC.rrc[Mod_instP],
rntiP);
if (ue_context_p != NULL) {
LOG_I(RRC,"Frame %d, Subframe %d: UE %x U-Plane failure, activating timer\n",frameP,subframeP,rntiP);
if(ue_context_p->ue_context.ul_failure_timer == 0)
ue_context_p->ue_context.ul_failure_timer=19999;
}
else {
LOG_W(RRC,"Frame %d, Subframe %d: U-Plane failure: UE %x unknown \n",frameP,subframeP,rntiP);
}
}
void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP,
......
This diff is collapsed.
......@@ -195,6 +195,28 @@ do_RRCConnectionReconfiguration(
, SCellToAddMod_r10_t *SCell_config
#endif
);
/**
\brief Generate an RRCConnectionReestablishment DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB2) and
PhysicalConfigDedicated IEs. The latter does not enable periodic CQI reporting (PUCCH format 2/2a/2b) or SRS.
@param ctxt_pP Running context
@param ue_context_pP UE context
@param CC_id Component Carrier ID
@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
@param transmission_mode Transmission mode for UE (1-9)
@param Transaction_id Transaction_ID for this message
@param SRB_configList Pointer (returned) to SRB1_config/SRB2_config(later) IEs for this UE
@param physicalConfigDedicated Pointer (returned) to PhysicalConfigDedicated IE for this UE
@returns Size of encoded bit stream in bytes*/
uint8_t
do_RRCConnectionReestablishment(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_t* const ue_context_pP,
int CC_id,
uint8_t* const buffer,
const uint8_t transmission_mode,
const uint8_t Transaction_id,
SRB_ToAddModList_t **SRB_configList,
struct PhysicalConfigDedicated **physicalConfigDedicated);
/**
\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB).
......@@ -249,6 +271,8 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_
uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer);
uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain);
uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer);
OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer);
......
......@@ -296,12 +296,15 @@ typedef enum e_rab_satus_e {
E_RAB_STATUS_DONE, // from the eNB perspective
E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
E_RAB_STATUS_FAILED,
E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE
} e_rab_status_t;
typedef struct e_rab_param_s {
e_rab_t param;
uint8_t status;
uint8_t xid; // transaction_id
s1ap_Cause_t cause;
uint8_t cause_value;
} __attribute__ ((__packed__)) e_rab_param_t;
#endif
......@@ -379,6 +382,7 @@ typedef struct eNB_RRC_UE_s {
SRB_ToAddModList_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
DRB_ToAddModList_t* DRB_configList;
DRB_ToAddModList_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
DRB_ToReleaseList_t* DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
uint8_t DRB_active[8];
struct PhysicalConfigDedicated* physicalConfigDedicated;
struct SPS_Config* sps_Config;
......@@ -398,6 +402,9 @@ typedef struct eNB_RRC_UE_s {
#if defined(ENABLE_SECURITY)
/* KeNB as derived from KASME received from EPC */
uint8_t kenb[32];
int8_t kenb_ncc;
uint8_t nh[32];
int8_t nh_ncc;
#endif
/* Used integrity/ciphering algorithms */
CipheringAlgorithm_r12_t ciphering_algorithm;
......@@ -427,9 +434,15 @@ typedef struct eNB_RRC_UE_s {
uint8_t setup_e_rabs;
/* Number of e_rab to be setup in the list */
uint8_t nb_of_e_rabs;
/* Number of e_rab to be modified in the list */
uint8_t nb_of_modify_e_rabs;
uint8_t nb_of_failed_e_rabs;
e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
//release e_rabs
uint8_t nb_release_of_e_rabs;
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
// LG: For GTPV1 TUNNELS
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB];
......@@ -438,6 +451,13 @@ typedef struct eNB_RRC_UE_s {
uint32_t ul_failure_timer;
uint32_t ue_release_timer;
uint32_t ue_release_timer_thres;
uint32_t ue_release_timer_s1;
uint32_t ue_release_timer_thres_s1;
uint32_t ue_release_timer_rrc;
uint32_t ue_release_timer_thres_rrc;
uint32_t ue_reestablishment_timer;
uint32_t ue_reestablishment_timer_thres;
uint8_t e_rab_release_command_flag;
} eNB_RRC_UE_t;
typedef uid_t ue_uid_t;
......@@ -501,6 +521,8 @@ typedef struct {
#endif
SRB_INFO SI;
SRB_INFO Srb0;
uint8_t *paging[NUMBER_OF_UE_MAX];
uint32_t sizeof_paging[NUMBER_OF_UE_MAX];
} rrc_eNB_carrier_data_t;
typedef struct eNB_RRC_INST_s {
......@@ -628,6 +650,8 @@ typedef struct UE_RRC_INST_s {
#if defined(ENABLE_SECURITY)
/* KeNB as computed from parameters within USIM card */
uint8_t kenb[32];
uint8_t nh[32];
int8_t nh_ncc;
#endif
/* Used integrity/ciphering algorithms */
......@@ -635,6 +659,14 @@ typedef struct UE_RRC_INST_s {
e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
} UE_RRC_INST;
typedef struct UE_PF_PO_s {
boolean_t enable_flag; /* flag indicate whether current object is used */
uint16_t ue_index_value; /* UE index value */
uint8_t PF_min; /* minimal value of Paging Frame (PF) */
uint8_t PO; /* Paging Occasion (PO) */
uint32_t T; /* DRX cycle */
} UE_PF_PO_t;
#include "proto.h"
#endif
......
......@@ -77,6 +77,11 @@ extern uint32_t timeToTrigger_ms[16];
extern float RSRP_meas_mapping[100];
extern float RSRQ_meas_mapping[33];
extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
extern pthread_mutex_t ue_pf_po_mutex;
extern uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2];
#endif
......@@ -254,6 +254,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
const uint8_t ho_state
);
int freq_to_arfcn10(int band, unsigned long freq);
void
rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
const protocol_ctxt_t* const ctxt_pP,
......@@ -261,6 +263,18 @@ rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
const uint8_t ho_state
);
/**\brief release Data Radio Bearer between ENB and UE
\param ctxt_pP Running context
\param ue_context_pP UE context of UE receiving the message*/
void
rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_t* const ue_context_pP,
uint8_t xid,
uint32_t nas_length,
uint8_t* nas_buffer
);
void
rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_t* ue_context_pP);
......@@ -324,6 +338,12 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
const sub_frame_t subframeP,
const rnti_t rnti);
void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
const int CC_id,
const frame_t frameP,
const sub_frame_t subframeP,
const rnti_t rnti);
void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP,
const int CC_id,
const frame_t frameP,
......
......@@ -333,26 +333,58 @@ rrc_rx_tx(
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) {
if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/20000\n",
LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n",
ue_context_p->ue_context.rnti,
ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
ue_context_p->ue_context.ul_failure_timer);
}
else {
LOG_I(RRC,"UE rnti %x failure timer %d/20000\n",
LOG_I(RRC,"UE rnti %x failure timer %d/8\n",
ue_context_p->ue_context.rnti,
ue_context_p->ue_context.ul_failure_timer);
}
}
if (ue_context_p->ue_context.ul_failure_timer>0) {
ue_context_p->ue_context.ul_failure_timer++;
if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
if (ue_context_p->ue_context.ul_failure_timer >= 8) {
// remove UE after 20 seconds after MAC has indicated UL failure
LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
ue_to_be_removed = ue_context_p;
break;
}
}
if (ue_context_p->ue_context.ue_release_timer_s1>0) {
ue_context_p->ue_context.ue_release_timer_s1++;
if (ue_context_p->ue_context.ue_release_timer_s1 >=
ue_context_p->ue_context.ue_release_timer_thres_s1) {
LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1);
ue_to_be_removed = ue_context_p;
break;
}
}
if (ue_context_p->ue_context.ue_release_timer_rrc>0) {
ue_context_p->ue_context.ue_release_timer_rrc++;
if (ue_context_p->ue_context.ue_release_timer_rrc >=
ue_context_p->ue_context.ue_release_timer_thres_rrc) {
LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti);
ue_to_be_removed = ue_context_p;
break;
}
}
if (ue_context_p->ue_context.ue_reestablishment_timer>0) {
ue_context_p->ue_context.ue_reestablishment_timer++;
if (ue_context_p->ue_context.ue_reestablishment_timer >=
ue_context_p->ue_context.ue_reestablishment_timer_thres) {
LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti);
ue_context_p->ue_context.ul_failure_timer = 20000;
ue_to_be_removed = ue_context_p;
ue_context_p->ue_context.ue_reestablishment_timer = 0;
break;
}
}
if (ue_context_p->ue_context.ue_release_timer>0) {
ue_context_p->ue_context.ue_release_timer++;
if (ue_context_p->ue_context.ue_release_timer >=
......@@ -363,9 +395,18 @@ rrc_rx_tx(
}
}
}
if (ue_to_be_removed)
if (ue_to_be_removed) {
if(ue_to_be_removed->ue_context.ul_failure_timer >= 8) {
ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
ue_to_be_removed->ue_context.ue_release_timer = 0;
ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
}
rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed);
if(ue_to_be_removed->ue_context.ul_failure_timer >= 8){
ue_to_be_removed->ue_context.ul_failure_timer = 0;
}
}
#ifdef RRC_LOCALIZATION
/* for the localization, only primary CC_id might be relevant*/
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -47,7 +47,8 @@ extern RAN_CONTEXT_t RC;
int
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t* const ctxt_pP,
const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP
const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP,
uint8_t *inde_list
)
{
rnti_t rnti;
......@@ -66,15 +67,18 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_S1u_teid[i];
ue_context_p->ue_context.enb_gtp_addrs[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_addr;
ue_context_p->ue_context.enb_gtp_ebi[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->eps_bearer_id[i];
// ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_S1u_teid[i];
// ue_context_p->ue_context.enb_gtp_addrs[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_addr;
// ue_context_p->ue_context.enb_gtp_ebi[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->eps_bearer_id[i];
ue_context_p->ue_context.enb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
ue_context_p->ue_context.enb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
ue_context_p->ue_context.enb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
create_tunnel_resp_pP->enb_S1u_teid[i],
ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs],
i+ue_context_p->ue_context.setup_e_rabs,
ue_context_p->ue_context.enb_gtp_teid[inde_list[i]],
inde_list[i],
i,
create_tunnel_resp_pP->eps_bearer_id[i],
create_tunnel_resp_pP->enb_addr.length);
......
......@@ -43,7 +43,8 @@
int
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t* const ctxt_pP,
const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP
const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP,
uint8_t *inde_list
);
# endif
......
This diff is collapsed.
......@@ -79,6 +79,11 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
const uint8_t ho_state
);
int
rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_t* const ue_context_pP,
const uint8_t ho_state
);
/*! \fn void rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(uint8_t mod_id, uint8_t ue_index)
*\brief create a S1AP_INITIAL_CONTEXT_SETUP_RESP for S1AP.
......@@ -186,6 +191,24 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
*/
int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid );
/*! \fn rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
*\brief process a S1AP dedicated E_RAB modify request message received from S1AP.
*\param msg_p Message received by RRC.
*\param msg_name Message name.
*\param instance Message instance.
*\return 0 when successful, -1 if the UE index can not be retrieved.
*/
int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
/*! \fn rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid )
*\brief send a S1AP dedicated E_RAB modify response
*\param ctxt_pP contxt infirmation
*\param e_contxt_pP ue specific context at the eNB
*\param xid transaction identifier
*\return 0 when successful, -1 if the UE index can not be retrieved.
*/
int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid );
/*! \fn rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
*\brief process a S1AP_UE_CTXT_MODIFICATION_REQ message received from S1AP.
*\param msg_p Message received by RRC.
......@@ -213,6 +236,39 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char *
*/
int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const char *msg_name, instance_t instance);
/*! \fn rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance)
*\brief process a S1AP_PAGING_IND message received from S1AP.
*\param msg_p Message received by RRC.
*\param msg_name Message name.
*\param instance Message instance.
*\return 0 when successful, -1 if the UE index can not be retrieved.
*/
int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance);
void
rrc_pdcp_config_security(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_t* const ue_context_pP,
const uint8_t send_security_mode_command
);
/*! \fn rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance);
*\brief process a S1AP dedicated E_RAB release command message received from S1AP.
*\param msg_p Message received by RRC.
*\param msg_name Message name.
*\param instance Message instance.
*\return 0 when successful, -1 if the UE index can not be retrieved.
*/
int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance);
/*! \fn rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid )
*\brief send a S1AP dedicated E_RAB release response
*\param ctxt_pP contxt infirmation
*\param e_contxt_pP ue specific context at the eNB
*\param xid transaction identifier
*\return 0 when successful, -1 if the UE index can not be retrieved.
*/
int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid );
# endif
# endif /* defined(ENABLE_USE_MME) */
#endif /* RRC_ENB_S1AP_H_ */
......@@ -136,6 +136,10 @@ rrc_eNB_allocate_new_UE_context(
memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s));
new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP);
for(int i = 0; i < NB_RB_MAX; i++) {
new_p->ue_context.e_rab[i].xid = -1;
new_p->ue_context.modify_e_rab[i].xid = -1;
}
return new_p;
}
......@@ -151,7 +155,21 @@ rrc_eNB_get_ue_context(
memset(&temp, 0, sizeof(struct rrc_eNB_ue_context_s));
/* eNB ue rrc id = 24 bits wide */
temp.ue_id_rnti = rntiP;
#if 0
return RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
#endif
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
ue_context_p = RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
if ( ue_context_p != NULL) {
return ue_context_p;
} else {
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
if (ue_context_p->ue_context.rnti == rntiP) {
return ue_context_p;
}
}
return NULL;
}
}
......@@ -184,6 +202,7 @@ void rrc_eNB_remove_ue_context(
rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP);
uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid);
free(ue_context_pP);
rrc_instance_pP->Nb_ue --;
LOG_I(RRC,
PROTOCOL_RRC_CTXT_UE_FMT" Removed UE context\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
......
......@@ -36,6 +36,8 @@
#include "COMMON/mac_rrc_primitives.h"
#include "LAYER2/MAC/defs.h"
UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
pthread_mutex_t ue_pf_po_mutex;
UE_RRC_INST *UE_rrc_inst;
#include "LAYER2/MAC/extern.h"
#define MAX_U32 0xFFFFFFFF
......@@ -236,4 +238,10 @@ float RSRQ_meas_mapping[35] = {
-2
};
// only used for RRC connection re-establishment procedure TS36.331 5.3.7
// [0]: current C-RNTI, [1]: prior C-RNTI
// insert one when eNB received RRCConnectionReestablishmentRequest message
// delete one when eNB received RRCConnectionReestablishmentComplete message
uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2] = {{0}};
#endif
......@@ -767,6 +767,7 @@ gtpv1u_create_s1u_tunnel(
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB = s1u_teid;
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB_stack_session = stack_req.apiInfo.createTunnelEndPointInfo.hStackSession;
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw = create_tunnel_req_pP->sgw_S1u_teid[i];
gtpv1u_ue_data_p->num_bearers++;
create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid;
} else {
......@@ -808,7 +809,88 @@ gtpv1u_create_s1u_tunnel(
return 0;
}
int gtpv1u_update_s1u_tunnel(
const instance_t instanceP,
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
const rnti_t prior_rnti
)
{
/* Local tunnel end-point identifier */
teid_t s1u_teid = 0;
gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
gtpv1u_ue_data_t *gtpv1u_ue_data_new_p = NULL;
//MessageDef *message_p = NULL;
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
int i,j;
uint8_t bearers_num = 0,bearers_total = 0;
//-----------------------
// PDCP->GTPV1U mapping
//-----------------------
hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, prior_rnti, (void **)&gtpv1u_ue_data_p);
if(hash_rc != HASH_TABLE_OK){
LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
return -1;
}
gtpv1u_ue_data_new_p = calloc (1, sizeof(gtpv1u_ue_data_t));
memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(gtpv1u_ue_data_t));
gtpv1u_ue_data_new_p->ue_id = create_tunnel_req_pP->rnti;
hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p);
AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
create_tunnel_req_pP->rnti);
hash_rc = hashtable_remove(RC.gtpv1u_data_g->ue_mapping, prior_rnti);
LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n",
prior_rnti);
//-----------------------
// GTPV1U->PDCP mapping
//-----------------------
bearers_total =gtpv1u_ue_data_new_p->num_bearers;
for(j = 0;j<GTPV1U_MAX_BEARERS_ID;j++){
if(gtpv1u_ue_data_new_p->bearers[j].state != BEARER_IN_CONFIG)
continue;
bearers_num++;
for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
if(j == (create_tunnel_req_pP->eps_bearer_id[i]-GTPV1U_BEARER_OFFSET))
break;
}
if(i < create_tunnel_req_pP->num_tunnels){
s1u_teid = gtpv1u_ue_data_new_p->bearers[j].teid_eNB;
hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void**)&gtpv1u_teid_data_p);
if (hash_rc == HASH_TABLE_OK) {
gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti;
gtpv1u_teid_data_p->eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i];
LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n",
s1u_teid,prior_rnti,create_tunnel_req_pP->rnti);
}else{
LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", s1u_teid);
}
}else{
s1u_teid = gtpv1u_ue_data_new_p->bearers[j].teid_eNB;
hash_rc = hashtable_remove(RC.gtpv1u_data_g->teid_mapping, s1u_teid);
if (hash_rc != HASH_TABLE_OK) {
LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, s1u_teid);
}
gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN;
gtpv1u_ue_data_new_p->num_bearers--;
LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n",
s1u_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);;
}
if(bearers_num > bearers_total)
break;
}
return 0;
}
//-----------------------------------------------------------------------------
static int gtpv1u_delete_s1u_tunnel(
......
......@@ -49,5 +49,9 @@ gtpv1u_create_s1u_tunnel(
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP);
int
gtpv1u_update_s1u_tunnel(
const instance_t instanceP,
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
const rnti_t prior_rnti);
#endif /* GTPV1U_ENB_TASK_H_ */
......@@ -364,6 +364,12 @@ void *s1ap_eNB_task(void *arg)
&S1AP_E_RAB_SETUP_RESP(received_msg));
}
break;
case S1AP_E_RAB_MODIFY_RESP: {
s1ap_eNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&S1AP_E_RAB_MODIFY_RESP(received_msg));
}
break;
case S1AP_NAS_NON_DELIVERY_IND: {
s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
......@@ -397,6 +403,12 @@ void *s1ap_eNB_task(void *arg)
}
break;
case S1AP_E_RAB_RELEASE_RESPONSE: {
s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&S1AP_E_RAB_RELEASE_RESPONSE(received_msg));
}
break;
default:
S1AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
......
......@@ -108,7 +108,15 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
ret = s1ap_decode_s1ap_pagingies(
&message->msg.s1ap_PagingIEs, &initiating_p->value);
s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message);
S1AP_ERROR("TODO Paging initiating message\n");
message_id = S1AP_PAGING_LOG;
message_string_size = strlen(message_string);
message_p = itti_alloc_new_message_sized(TASK_S1AP,
message_id,
message_string_size + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_paging_log.size = message_string_size;
memcpy(&message_p->ittiMsg.s1ap_paging_log.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
S1AP_INFO("Paging initiating message\n");
free(message_string);
break;
......@@ -128,12 +136,36 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
free(message_string);
S1AP_INFO("E_RABSetup initiating message\n");
break;
case S1ap_ProcedureCode_id_E_RABModify:
ret = s1ap_decode_s1ap_e_rabmodifyrequesties(
&message->msg.s1ap_E_RABModifyRequestIEs, &initiating_p->value);
message_id = S1AP_E_RAB_MODIFY_REQUEST_LOG;
message_string_size = strlen(message_string);
message_p = itti_alloc_new_message_sized(TASK_S1AP,
message_id,
message_string_size + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_modify_request_log.size = message_string_size;
memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_request_log.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(message_string);
S1AP_INFO("E_RABModify initiating message\n");
break;
case S1ap_ProcedureCode_id_E_RABRelease:
ret = s1ap_decode_s1ap_e_rabreleasecommandies(&message->msg.s1ap_E_RABReleaseCommandIEs,
&initiating_p->value);
//s1ap_xer_print_s1ap_e_rabsetuprequest(s1ap_xer__print2sp, message_string, message);
S1AP_INFO("TODO E_RABRelease nitiating message\n");
ret = s1ap_decode_s1ap_e_rabreleasecommandies(
&message->msg.s1ap_E_RABReleaseCommandIEs, &initiating_p->value);
s1ap_xer_print_s1ap_e_rabreleasecommand(s1ap_xer__print2sp, message_string, message);
message_id = S1AP_E_RAB_RELEASE_REQUEST_LOG;
message_string_size = strlen(message_string);
message_p = itti_alloc_new_message_sized(TASK_S1AP,
message_id,
message_string_size + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_release_request_log.size = message_string_size;
memcpy(&message_p->ittiMsg.s1ap_e_rab_release_request_log.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(message_string);
S1AP_INFO("TODO E_RABRelease nitiating message\n");
break;
default:
......
......@@ -100,6 +100,16 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t *E_RABSet
uint8_t **buffer,
uint32_t *length);
static inline
int s1ap_eNB_encode_e_rab_modify_response(S1ap_E_RABModifyResponseIEs_t *E_RABModifyResponseIEs,
uint8_t **buffer,
uint32_t *length);
static inline
int s1ap_eNB_encode_e_rab_release_response(S1ap_E_RABReleaseResponseIEs_t *s1ap_E_RABReleaseResponseIEs,
uint8_t **buffer,
uint32_t *length);
int s1ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len)
{
DevAssert(message != NULL);
......@@ -264,6 +274,32 @@ int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p,
free(message_string);
S1AP_INFO("E_RABSetup successful message\n");
break;
case S1ap_ProcedureCode_id_E_RABModify:
ret = s1ap_eNB_encode_e_rab_modify_response (
&s1ap_message_p->msg.s1ap_E_RABModifyResponseIEs, buffer, len);
message_id = S1AP_E_RAB_MODIFY_RESPONSE_LOG ;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_modify_response_log.size = message_string_size;
memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_response_log.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(message_string);
S1AP_INFO("E_RABModify successful message\n");
break;
case S1ap_ProcedureCode_id_E_RABRelease:
ret = s1ap_eNB_encode_e_rab_release_response (
&s1ap_message_p->msg.s1ap_E_RABReleaseResponseIEs, buffer, len);
s1ap_xer_print_s1ap_e_rabreleaseresponse(s1ap_xer__print2sp, message_string, s1ap_message_p);
message_id = S1AP_E_RAB_RELEASE_RESPONSE_LOG ;
message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
message_p->ittiMsg.s1ap_e_rab_release_response_log.size = message_string_size;
memcpy(&message_p->ittiMsg.s1ap_e_rab_release_response_log.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
free(message_string);
S1AP_INFO("E_RAB Release successful message\n");
break;
default:
S1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
(int)s1ap_message_p->procedureCode);
......@@ -563,3 +599,48 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t *s1ap_E_R
&asn_DEF_S1ap_E_RABSetupResponse,
e_rab_setup_response_p);
}
static inline
int s1ap_eNB_encode_e_rab_modify_response(S1ap_E_RABModifyResponseIEs_t *s1ap_E_RABModifyResponseIEs,
uint8_t **buffer,
uint32_t *length)
{
S1ap_E_RABModifyResponse_t e_rab_modify_response;
S1ap_E_RABModifyResponse_t *e_rab_modify_response_p = &e_rab_modify_response;
memset((void *)e_rab_modify_response_p, 0,
sizeof(e_rab_modify_response));
if (s1ap_encode_s1ap_e_rabmodifyresponseies (e_rab_modify_response_p, s1ap_E_RABModifyResponseIEs) < 0) {
return -1;
}
return s1ap_generate_successfull_outcome(buffer,
length,
S1ap_ProcedureCode_id_E_RABModify,
S1ap_Criticality_reject,
&asn_DEF_S1ap_E_RABModifyResponse,
e_rab_modify_response_p);
}
static inline
int s1ap_eNB_encode_e_rab_release_response(S1ap_E_RABReleaseResponseIEs_t *s1ap_E_RABReleaseResponseIEs,
uint8_t **buffer,
uint32_t *length)
{
S1ap_E_RABReleaseResponse_t e_rab_release_response;
S1ap_E_RABReleaseResponse_t *e_rab_release_response_p = &e_rab_release_response;
memset((void *)e_rab_release_response_p, 0,
sizeof(e_rab_release_response));
if (s1ap_encode_s1ap_e_rabreleaseresponseies (e_rab_release_response_p, s1ap_E_RABReleaseResponseIEs) < 0) {
return -1;
}
return s1ap_generate_successfull_outcome(buffer,
length,
S1ap_ProcedureCode_id_E_RABRelease,
S1ap_Criticality_reject,
&asn_DEF_S1ap_E_RABReleaseResponse,
e_rab_release_response_p);
}
This diff is collapsed.
This diff is collapsed.
......@@ -44,4 +44,9 @@ int s1ap_eNB_ue_capabilities(instance_t instance,
int s1ap_eNB_e_rab_setup_resp(instance_t instance,
s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p);
int s1ap_eNB_e_rab_modify_resp(instance_t instance,
s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p);
int s1ap_eNB_e_rab_release_resp(instance_t instance,
s1ap_e_rab_release_resp_t *e_rab_release_resp_p);
#endif /* S1AP_ENB_NAS_PROCEDURES_H_ */
......@@ -63,3 +63,43 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB
}
#endif
int derive_keNB_star(
const uint8_t *kenb_32,
const uint16_t pci,
const uint32_t earfcn_dl,
const bool is_rel8_only,
uint8_t *kenb_star)
{
// see 33.401 section A.5 KeNB* derivation function
uint8_t s[10] = {0};
// FC = 0x13
s[0] = FC_KENB_STAR;
// P0 = PCI (target physical cell id)
s[1] = (pci & 0x0000ff00) >> 8;
s[2] = (pci & 0x000000ff);
// L0 = length of PCI (i.e. 0x00 0x02)
s[3] = 0x00;
s[4] = 0x02;
// P1 = EARFCN-DL (target physical cell downlink frequency)
if (is_rel8_only) {
s[5] = (earfcn_dl & 0x0000ff00) >> 8;
s[6] = (earfcn_dl & 0x000000ff);
s[7] = 0x00;
s[8] = 0x02;
kdf (kenb_32, 32, s, 9, kenb_star, 32);
} else {
s[5] = (earfcn_dl & 0x00ff0000) >> 16;
s[6] = (earfcn_dl & 0x0000ff00) >> 8;
s[7] = (earfcn_dl & 0x000000ff);
s[8] = 0x00;
s[9] = 0x03;
kdf (kenb_32, 32, s, 10, kenb_star, 32);
}
// L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143)
// NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
// entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
// would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
// EARFCN-DL.
return 0;
}
......@@ -23,6 +23,7 @@
#define SECU_DEFS_H_
#include "security_types.h"
#include <stdbool.h>
#define EIA0_ALG_ID 0x00
#define EIA1_128_ALG_ID 0x01
......@@ -44,6 +45,9 @@ void kdf(const uint8_t *key,
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl,
const bool is_rel8_only, uint8_t * kenb_star);
int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t kasme[32], uint8_t *knas);
......
......@@ -1188,6 +1188,10 @@ int main( int argc, char **argv )
RCconfig_L1();
}
#endif
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
mlockall(MCL_CURRENT | MCL_FUTURE);
......@@ -1457,7 +1461,7 @@ int main( int argc, char **argv )
pthread_cond_destroy(&nfapi_sync_cond);
pthread_mutex_destroy(&nfapi_sync_mutex);
pthread_mutex_destroy(&ue_pf_po_mutex);
// *** Handle per CC_id openair0
if (UE_flag==1) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment