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.
This commit is contained in:
@@ -2005,6 +2005,7 @@ add_executable(oaisim_nos1
|
|||||||
${OPENAIR_BIN_DIR}/messages_xml.h
|
${OPENAIR_BIN_DIR}/messages_xml.h
|
||||||
${OPENAIR_TARGETS}/RT/USER/lte-ue.c
|
${OPENAIR_TARGETS}/RT/USER/lte-ue.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
|
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
|
||||||
|
${OPENAIR_TARGETS}/RT/USER/lte-enb.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||||
${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
|
${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
|
||||||
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
|
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
|
||||||
|
|||||||
@@ -185,6 +185,10 @@ ID = ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST
|
|||||||
DESC = RRC connection reestablishment request
|
DESC = RRC connection reestablishment request
|
||||||
GROUP = ALL:RRC:ENB
|
GROUP = ALL:RRC:ENB
|
||||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti
|
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
|
ID = ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE
|
||||||
DESC = RRC connection reestablishment complete
|
DESC = RRC connection reestablishment complete
|
||||||
GROUP = ALL:RRC:ENB
|
GROUP = ALL:RRC:ENB
|
||||||
|
|||||||
@@ -6560,7 +6560,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
|
|||||||
else
|
else
|
||||||
ul_subframe = ((n+4)%10);
|
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);
|
LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
|
||||||
return 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_active = 0; //this will be done later after transmission of PHICH
|
||||||
ulsch->harq_processes[i]->phich_ACK = 0;
|
ulsch->harq_processes[i]->phich_ACK = 0;
|
||||||
ulsch->harq_processes[i]->round = 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
|
#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_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_SI,*dlsch_ra,*dlsch_p;
|
||||||
LTE_eNB_DLSCH_t *dlsch_MCH;
|
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[NUMBER_OF_UE_MAX];
|
||||||
LTE_eNB_UE_stats *UE_stats_ptr[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
|
int br_flag
|
||||||
#endif
|
#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.
|
/*! \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 frame_parms Pointer to DL frame parameter descriptor
|
||||||
@param subframe Subframe index
|
@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]);
|
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)
|
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 (uci->type == SR) {
|
||||||
if (SR_payload == 1) {
|
if (SR_payload == 1) {
|
||||||
fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
|
fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case HARQ:
|
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_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_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_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_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"
|
// Some constants from "LAYER2/MAC/defs.h"
|
||||||
#define BCCH_SDU_SIZE (512)
|
#define BCCH_SDU_SIZE (512)
|
||||||
#define CCCH_SDU_SIZE (512)
|
#define CCCH_SDU_SIZE (512)
|
||||||
#define MCCH_SDU_SIZE (512)
|
#define MCCH_SDU_SIZE (512)
|
||||||
|
#define PCCH_SDU_SIZE (512)
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------------------------//
|
||||||
// Messages between RRC and MAC layers
|
// Messages between RRC and MAC layers
|
||||||
@@ -114,4 +116,10 @@ typedef struct RrcMacMcchDataInd_s {
|
|||||||
uint8_t mbsfn_sync_area;
|
uint8_t mbsfn_sync_area;
|
||||||
} RrcMacMcchDataInd;
|
} 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_ */
|
#endif /* MAC_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -30,3 +30,4 @@
|
|||||||
// Messages between RRC and PDCP layers
|
// 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_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_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.
|
// Defines to access message fields.
|
||||||
#define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_req
|
#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_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
|
// Messages between RRC and PDCP layers
|
||||||
@@ -60,4 +61,13 @@ typedef struct RrcDcchDataInd_s {
|
|||||||
uint8_t eNB_index; // LG: needed in UE
|
uint8_t eNB_index; // LG: needed in UE
|
||||||
} RrcDcchDataInd;
|
} 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_ */
|
#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_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_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_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 */
|
/* eNB application layer -> S1AP messages */
|
||||||
MESSAGE_DEF(S1AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t , s1ap_register_enb_req)
|
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_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_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_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 */
|
/* S1AP -> RRC messages */
|
||||||
MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas )
|
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_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_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_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)
|
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) */
|
/* 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_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_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_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_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas
|
||||||
#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
|
#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_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_command
|
||||||
#define S1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_complete
|
#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_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_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.
|
/* 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;
|
uint16_t mme_group_id;
|
||||||
} s1ap_gummei_t;
|
} 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 {
|
typedef struct s_tmsi_s {
|
||||||
uint8_t mme_code;
|
uint8_t mme_code;
|
||||||
uint32_t m_tmsi;
|
uint32_t m_tmsi;
|
||||||
@@ -189,7 +198,7 @@ typedef enum ue_paging_identity_presenceMask_e {
|
|||||||
typedef struct ue_paging_identity_s {
|
typedef struct ue_paging_identity_s {
|
||||||
ue_paging_identity_presenceMask_t presenceMask;
|
ue_paging_identity_presenceMask_t presenceMask;
|
||||||
union {
|
union {
|
||||||
char imsi[S1AP_IMSI_LENGTH];
|
s1ap_imsi_t imsi;
|
||||||
s_tmsi_t s_tmsi;
|
s_tmsi_t s_tmsi;
|
||||||
} choice;
|
} choice;
|
||||||
} ue_paging_identity_t;
|
} ue_paging_identity_t;
|
||||||
@@ -260,11 +269,29 @@ typedef struct e_rab_setup_s {
|
|||||||
uint32_t gtp_teid;
|
uint32_t gtp_teid;
|
||||||
} e_rab_setup_t;
|
} 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 {
|
typedef struct e_rab_failed_s {
|
||||||
/* Unique e_rab_id for the UE. */
|
/* Unique e_rab_id for the UE. */
|
||||||
uint8_t e_rab_id;
|
uint8_t e_rab_id;
|
||||||
/* Cause of the failure */
|
/* Cause of the failure */
|
||||||
// cause_t cause;
|
// cause_t cause;
|
||||||
|
s1ap_Cause_t cause;
|
||||||
|
uint8_t cause_value;
|
||||||
} e_rab_failed_t;
|
} e_rab_failed_t;
|
||||||
|
|
||||||
typedef enum s1ap_ue_ctxt_modification_present_s {
|
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];
|
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
|
||||||
} s1ap_initial_context_setup_req_t;
|
} 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 {
|
typedef struct s1ap_paging_ind_s {
|
||||||
/* UE identity index value.
|
/* UE identity index value.
|
||||||
* Specified in 3GPP TS 36.304
|
* Specified in 3GPP TS 36.304
|
||||||
@@ -472,6 +505,15 @@ typedef struct s1ap_paging_ind_s {
|
|||||||
/* Indicates origin of paging */
|
/* Indicates origin of paging */
|
||||||
cn_domain_t cn_domain;
|
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 */
|
/* Optional fields */
|
||||||
paging_drx_t paging_drx;
|
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
|
// S1AP <-- RRC messages
|
||||||
typedef struct s1ap_ue_release_req_s {
|
typedef struct s1ap_ue_release_req_s {
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
@@ -537,4 +569,78 @@ typedef struct s1ap_ue_release_req_s {
|
|||||||
long cause_value;
|
long cause_value;
|
||||||
} s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
|
} 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_ */
|
#endif /* S1AP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -163,6 +163,8 @@
|
|||||||
/*!\brief maximum number of slices / groups */
|
/*!\brief maximum number of slices / groups */
|
||||||
#define MAX_NUM_SLICES 4
|
#define MAX_NUM_SLICES 4
|
||||||
|
|
||||||
|
#define U_PLANE_INACTIVITY_VALUE 6000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* eNB part
|
* eNB part
|
||||||
*/
|
*/
|
||||||
@@ -472,6 +474,15 @@ typedef struct {
|
|||||||
/// BCCH MCS
|
/// BCCH MCS
|
||||||
uint32_t ccch_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
|
/// num active users
|
||||||
uint16_t num_dlactive_UEs;
|
uint16_t num_dlactive_UEs;
|
||||||
/// available number of PRBs for a give SF
|
/// available number of PRBs for a give SF
|
||||||
@@ -824,6 +835,8 @@ typedef struct {
|
|||||||
int32_t cqi_req_timer;
|
int32_t cqi_req_timer;
|
||||||
int32_t ul_inactivity_timer;
|
int32_t ul_inactivity_timer;
|
||||||
int32_t ul_failure_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 ul_scheduled;
|
||||||
int32_t ra_pdcch_order_sent;
|
int32_t ra_pdcch_order_sent;
|
||||||
int32_t ul_out_of_sync;
|
int32_t ul_out_of_sync;
|
||||||
@@ -855,6 +868,7 @@ typedef struct {
|
|||||||
uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
|
uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
|
||||||
uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
|
uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
|
||||||
uint8_t dl_cqi[NFAPI_CC_MAX];
|
uint8_t dl_cqi[NFAPI_CC_MAX];
|
||||||
|
int32_t uplane_inactivity_timer;
|
||||||
} UE_sched_ctrl;
|
} UE_sched_ctrl;
|
||||||
/*! \brief eNB template for the Random access information */
|
/*! \brief eNB template for the Random access information */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -982,6 +996,10 @@ typedef struct {
|
|||||||
uint32_t BCCH_alloc_pdu;
|
uint32_t BCCH_alloc_pdu;
|
||||||
/// Outgoing CCCH pdu for PHY
|
/// Outgoing CCCH pdu for PHY
|
||||||
CCCH_PDU CCCH_pdu;
|
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
|
/// Outgoing RAR pdu for PHY
|
||||||
RAR_PDU RAR_pdu;
|
RAR_PDU RAR_pdu;
|
||||||
/// Template for RA computations
|
/// Template for RA computations
|
||||||
@@ -1102,6 +1120,8 @@ typedef struct eNB_MAC_INST_s {
|
|||||||
time_stats_t schedule_mch;
|
time_stats_t schedule_mch;
|
||||||
/// processing time of eNB ULSCH reception
|
/// processing time of eNB ULSCH reception
|
||||||
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
|
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
|
||||||
|
/// processing time of eNB PCH scheduler
|
||||||
|
time_stats_t schedule_pch;
|
||||||
} eNB_MAC_INST;
|
} 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.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
|
||||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.size =
|
ul_config_pdu->srs_pdu.srs_pdu_rel8.size =
|
||||||
(uint8_t)
|
(uint8_t)
|
||||||
sizeof(nfapi_ul_config_srs_pdu);;
|
sizeof(nfapi_ul_config_srs_pdu);
|
||||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti =
|
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti =
|
||||||
UE_list->UE_template[CC_id][UE_id].
|
UE_list->UE_template[CC_id][UE_id].
|
||||||
rnti;
|
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++;
|
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
|
||||||
// check threshold
|
// 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
|
// inform RRC of failure and clear timer
|
||||||
LOG_I(MAC,
|
LOG_I(MAC,
|
||||||
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
|
"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
|
} // 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
|
void
|
||||||
@@ -702,6 +708,50 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
|
|||||||
ul_inactivity_timer,
|
ul_inactivity_timer,
|
||||||
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
|
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
|
||||||
check_ul_failure(module_idP, CC_id, i, frameP, subframeP);
|
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);
|
schedule_mib(module_idP, frameP, subframeP);
|
||||||
// This schedules SI for legacy LTE and eMTC starting in subframeP
|
// This schedules SI for legacy LTE and eMTC starting in subframeP
|
||||||
schedule_SI(module_idP, frameP, 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
|
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP
|
||||||
schedule_RA(module_idP, frameP, subframeP);
|
schedule_RA(module_idP, frameP, subframeP);
|
||||||
// copy previously scheduled UL resources (ULSCH + HARQ)
|
// copy previously scheduled UL resources (ULSCH + HARQ)
|
||||||
|
|||||||
@@ -1073,6 +1073,7 @@ schedule_ue_spec(module_id_t module_idP,
|
|||||||
header_len_dtch_last--;
|
header_len_dtch_last--;
|
||||||
}
|
}
|
||||||
num_sdus++;
|
num_sdus++;
|
||||||
|
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
|
||||||
} // no data for this LCID
|
} // no data for this LCID
|
||||||
else {
|
else {
|
||||||
header_len_dtch -= 3;
|
header_len_dtch -= 3;
|
||||||
@@ -1655,7 +1656,13 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
|
|||||||
BCCH_pdu.payload[0]);
|
BCCH_pdu.payload[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
UE_id = find_UE_id(module_idP, rntiP);
|
if (rntiP==P_RNTI) {
|
||||||
|
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP);
|
||||||
|
|
||||||
|
return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
UE_id = find_UE_id(module_idP,rntiP);
|
||||||
|
|
||||||
if (UE_id != -1) {
|
if (UE_id != -1) {
|
||||||
LOG_D(MAC,
|
LOG_D(MAC,
|
||||||
@@ -1770,3 +1777,351 @@ set_ue_dai(sub_frame_t subframeP,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
|
||||||
|
{
|
||||||
|
/* DCI:format 1A/1C P-RNTI:0xFFFE */
|
||||||
|
/* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */
|
||||||
|
uint16_t pcch_sdu_length;
|
||||||
|
int mcs = -1;
|
||||||
|
int CC_id;
|
||||||
|
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
||||||
|
COMMON_channels_t *cc;
|
||||||
|
uint8_t *vrb_map;
|
||||||
|
int n_rb_dl;
|
||||||
|
int first_rb = -1;
|
||||||
|
nfapi_dl_config_request_pdu_t *dl_config_pdu;
|
||||||
|
nfapi_tx_request_pdu_t *TX_req;
|
||||||
|
nfapi_dl_config_request_body_t *dl_req;
|
||||||
|
#ifdef FORMAT1C
|
||||||
|
int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */
|
||||||
|
const int GAP_MAP [9][2] = {
|
||||||
|
{-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/
|
||||||
|
{4, 0}, /* N_RB_DL [11] */
|
||||||
|
{8, 0}, /* N_RB_DL [12-19] */
|
||||||
|
{12, 0}, /* N_RB_DL [20-26] */
|
||||||
|
{18, 0}, /* N_RB_DL [27-44] */
|
||||||
|
{27, 0}, /* N_RB_DL [45-49] */
|
||||||
|
{27, 9}, /* N_RB_DL [50-63] */
|
||||||
|
{32, 16}, /* N_RB_DL [64-79] */
|
||||||
|
{48, 16} /* N_RB_DL [80-110] */
|
||||||
|
};
|
||||||
|
uint8_t n_rb_step = 0;
|
||||||
|
uint8_t n_gap = 0;
|
||||||
|
uint8_t n_vrb_dl = 0;
|
||||||
|
uint8_t Lcrbs = 0;
|
||||||
|
uint16_t rb_bit = 168; /* RB bit number value is unsure */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
start_meas(&eNB->schedule_pch);
|
||||||
|
|
||||||
|
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||||
|
cc = &eNB->common_channels[CC_id];
|
||||||
|
vrb_map = (void*)&cc->vrb_map;
|
||||||
|
n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth);
|
||||||
|
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
|
||||||
|
for (uint16_t i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||||
|
if (UE_PF_PO[CC_id][i].enable_flag != TRUE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) {
|
||||||
|
pcch_sdu_length = mac_rrc_data_req(module_idP,
|
||||||
|
CC_id,
|
||||||
|
frameP,
|
||||||
|
PCCH,1,
|
||||||
|
&cc->PCCH_pdu.payload[0],
|
||||||
|
1,
|
||||||
|
module_idP,
|
||||||
|
i); // used for ue index
|
||||||
|
if (pcch_sdu_length == 0) {
|
||||||
|
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length);
|
||||||
|
#ifdef FORMAT1C
|
||||||
|
//NO SIB
|
||||||
|
if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
|
||||||
|
(subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
|
||||||
|
switch (n_rb_dl) {
|
||||||
|
#if 0
|
||||||
|
case 6:
|
||||||
|
n_gap = n_rb_dl/2; /* expect: 3 */
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */
|
||||||
|
first_rb = 0;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
n_gap = GAP_MAP[2][0]; /* expect: 8 */
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */
|
||||||
|
first_rb = 6;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 25:
|
||||||
|
n_gap = GAP_MAP[3][0]; /* expect: 12 */
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */
|
||||||
|
first_rb = 10;
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */
|
||||||
|
if (gap_index > 0) {
|
||||||
|
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */
|
||||||
|
} else {
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */
|
||||||
|
}
|
||||||
|
first_rb = 24;
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */
|
||||||
|
if (gap_index > 0) {
|
||||||
|
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */
|
||||||
|
} else {
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */
|
||||||
|
}
|
||||||
|
first_rb = 48;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging
|
||||||
|
switch (n_rb_dl) {
|
||||||
|
#if 0
|
||||||
|
case 6:
|
||||||
|
n_gap = n_rb_dl/2; /* expect: 3 */
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */
|
||||||
|
first_rb = 0;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
n_gap = GAP_MAP[2][0]; /* expect: 8 */
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */
|
||||||
|
first_rb = 10;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 25:
|
||||||
|
n_gap = GAP_MAP[3][0]; /* expect: 12 */
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */
|
||||||
|
first_rb = 14;
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */
|
||||||
|
if (gap_index > 0) {
|
||||||
|
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */
|
||||||
|
} else {
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */
|
||||||
|
}
|
||||||
|
first_rb = 28;
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */
|
||||||
|
if (gap_index > 0) {
|
||||||
|
n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */
|
||||||
|
} else {
|
||||||
|
n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */
|
||||||
|
}
|
||||||
|
first_rb = 52;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Get MCS for length of PCH */
|
||||||
|
if (pcch_sdu_length <= TBStable1C[0]) {
|
||||||
|
mcs=0;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[1]) {
|
||||||
|
mcs=1;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[2]) {
|
||||||
|
mcs=2;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[3]) {
|
||||||
|
mcs=3;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[4]) {
|
||||||
|
mcs=4;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[5]) {
|
||||||
|
mcs=5;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[6]) {
|
||||||
|
mcs=6;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[7]) {
|
||||||
|
mcs=7;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[8]) {
|
||||||
|
mcs=8;
|
||||||
|
} else if (pcch_sdu_length <= TBStable1C[9]) {
|
||||||
|
mcs=9;
|
||||||
|
} else {
|
||||||
|
/* unexpected: pcch sdb size is over max value*/
|
||||||
|
LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n",
|
||||||
|
module_idP, frameP,CC_id, pcch_sdu_length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1;
|
||||||
|
/* calculate N_RB_STEP and Lcrbs */
|
||||||
|
if (n_rb_dl < 50) {
|
||||||
|
n_rb_step = 2;
|
||||||
|
Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2);
|
||||||
|
} else {
|
||||||
|
n_rb_step = 4;
|
||||||
|
Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4);
|
||||||
|
}
|
||||||
|
for(i = 0;i < Lcrbs ;i++){
|
||||||
|
vrb_map[first_rb+i] = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
//NO SIB
|
||||||
|
if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
|
||||||
|
(subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
|
||||||
|
switch (n_rb_dl) {
|
||||||
|
case 25:
|
||||||
|
first_rb = 10;
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
first_rb = 24;
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
first_rb = 48;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging
|
||||||
|
switch (n_rb_dl) {
|
||||||
|
case 25:
|
||||||
|
first_rb = 14;
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
first_rb = 28;
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
first_rb = 52;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vrb_map[first_rb] = 1;
|
||||||
|
vrb_map[first_rb+1] = 1;
|
||||||
|
vrb_map[first_rb+2] = 1;
|
||||||
|
vrb_map[first_rb+3] = 1;
|
||||||
|
/* Get MCS for length of PCH */
|
||||||
|
if (pcch_sdu_length <= get_TBS_DL(0,3)) {
|
||||||
|
mcs=0;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(1,3)) {
|
||||||
|
mcs=1;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(2,3)) {
|
||||||
|
mcs=2;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(3,3)) {
|
||||||
|
mcs=3;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(4,3)) {
|
||||||
|
mcs=4;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(5,3)) {
|
||||||
|
mcs=5;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(6,3)) {
|
||||||
|
mcs=6;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(7,3)) {
|
||||||
|
mcs=7;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(8,3)) {
|
||||||
|
mcs=8;
|
||||||
|
} else if (pcch_sdu_length <= get_TBS_DL(9,3)) {
|
||||||
|
mcs=9;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
|
||||||
|
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
|
||||||
|
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
|
||||||
|
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
|
||||||
|
#ifdef FORMAT1C
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C;
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap;
|
||||||
|
#else
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1;
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4);
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
|
||||||
|
#endif
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
|
||||||
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
|
||||||
|
|
||||||
|
// Rel10 fields
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3;
|
||||||
|
// Rel13 fields
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF;
|
||||||
|
|
||||||
|
if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) {
|
||||||
|
LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP);
|
||||||
|
dl_req->number_dci++;
|
||||||
|
dl_req->number_pdu++;
|
||||||
|
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
|
||||||
|
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
|
||||||
|
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
|
||||||
|
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE;
|
||||||
|
#ifdef FORMAT1C
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
|
||||||
|
#else
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4);
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
|
||||||
|
#endif
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
|
||||||
|
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
|
||||||
|
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
|
||||||
|
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
|
||||||
|
dl_req->number_pdu++;
|
||||||
|
|
||||||
|
eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
|
||||||
|
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
|
||||||
|
TX_req->pdu_length = pcch_sdu_length;
|
||||||
|
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
|
||||||
|
TX_req->num_segments = 1;
|
||||||
|
TX_req->segments[0].segment_length = pcch_sdu_length;
|
||||||
|
TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload;
|
||||||
|
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
|
||||||
|
} else {
|
||||||
|
LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_enabled == 1) {
|
||||||
|
trace_pdu(1,
|
||||||
|
&eNB->common_channels[CC_id].PCCH_pdu.payload[0],
|
||||||
|
pcch_sdu_length,
|
||||||
|
0xffff,
|
||||||
|
PCCH,
|
||||||
|
P_RNTI,
|
||||||
|
eNB->frame,
|
||||||
|
eNB->subframe,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
|
||||||
|
module_idP, frameP, CC_id, 0xffff, pcch_sdu_length);
|
||||||
|
}
|
||||||
|
eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1;
|
||||||
|
eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length;
|
||||||
|
eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length;
|
||||||
|
eNB->eNB_stats[CC_id].pcch_mcs=mcs;
|
||||||
|
//paging first_rb log
|
||||||
|
LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n",
|
||||||
|
module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ue_pf_po_mutex);
|
||||||
|
memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t));
|
||||||
|
pthread_mutex_unlock(&ue_pf_po_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* this might be misleading when pcch is inactive */
|
||||||
|
stop_meas(&eNB->schedule_pch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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));
|
sizeof(UE_sched_ctrl));
|
||||||
memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0,
|
memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0,
|
||||||
sizeof(eNB_UE_STATS));
|
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;
|
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 i;
|
||||||
|
int j;
|
||||||
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
|
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;
|
int pCC_id;
|
||||||
|
|
||||||
if (UE_id == -1) {
|
if (UE_id == -1) {
|
||||||
LOG_W(MAC, "rrc_mac_remove_ue: UE %x not found\n", rntiP);
|
LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
|
||||||
return 0;
|
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,
|
LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
|
||||||
pCC_id, rntiP);
|
dump_ue_list(UE_list,0);
|
||||||
dump_ue_list(UE_list, 0);
|
|
||||||
|
|
||||||
UE_list->active[UE_id] = FALSE;
|
UE_list->active[UE_id] = FALSE;
|
||||||
UE_list->num_UEs--;
|
UE_list->num_UEs--;
|
||||||
|
|
||||||
if (UE_list->head == UE_id)
|
if (UE_list->head == UE_id) UE_list->head=UE_list->next[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];
|
||||||
else
|
if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id];
|
||||||
UE_list->next[prev(UE_list, UE_id, 0)] = UE_list->next[UE_id];
|
else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[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
|
// 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[LCGID0] = 0;
|
||||||
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 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[LCGID2] = 0;
|
||||||
UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 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].ul_SR = 0;
|
||||||
UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
|
UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
|
||||||
UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE;
|
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;
|
memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE));
|
||||||
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->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
|
// check if this has an RA process active
|
||||||
RA_t *ra;
|
RA_t *ra;
|
||||||
|
|||||||
@@ -732,6 +732,8 @@ rx_sdu(const module_id_t enb_mod_idP,
|
|||||||
num_pdu_rx[rx_lcids[i]] += 1;
|
num_pdu_rx[rx_lcids[i]] += 1;
|
||||||
UE_list->eNB_UE_stats[CC_idP][UE_id].
|
UE_list->eNB_UE_stats[CC_idP][UE_id].
|
||||||
num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
|
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] */
|
} else { /* rx_length[i] */
|
||||||
UE_list->eNB_UE_stats[CC_idP][UE_id].
|
UE_list->eNB_UE_stats[CC_idP][UE_id].
|
||||||
num_errors_rx += 1;
|
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 DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
|
||||||
extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
|
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,
|
int UE_id,
|
||||||
uint8_t CC_id, uint8_t tdd_config, UE_list_t * UE_list);
|
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,
|
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP,
|
||||||
unsigned char group_id);
|
unsigned char group_id);
|
||||||
uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
|
uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
|
||||||
|
|||||||
@@ -68,6 +68,8 @@
|
|||||||
extern int otg_enabled;
|
extern int otg_enabled;
|
||||||
#endif
|
#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);
|
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||||
break;
|
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:
|
default:
|
||||||
LOG_E(PDCP, "Received unexpected message %s\n", msg_name);
|
LOG_E(PDCP, "Received unexpected message %s\n", msg_name);
|
||||||
break;
|
break;
|
||||||
@@ -1037,6 +1054,13 @@ pdcp_remove_UE(
|
|||||||
|
|
||||||
// check and remove SRBs first
|
// 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++) {
|
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);
|
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);
|
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++) {
|
for (cnt=0; cnt<drb2release_list_pP->list.count; cnt++) {
|
||||||
pdrb_id_p = drb2release_list_pP->list.array[cnt];
|
pdrb_id_p = drb2release_list_pP->list.array[cnt];
|
||||||
drb_id = *pdrb_id_p;
|
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);
|
h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
|
||||||
|
|
||||||
if (h_rc != HASH_TABLE_OK) {
|
if (h_rc != HASH_TABLE_OK) {
|
||||||
@@ -1472,7 +1496,17 @@ pdcp_config_req_asn1 (
|
|||||||
if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
|
if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
|
||||||
pdcp_pP->is_ue = FALSE;
|
pdcp_pP->is_ue = FALSE;
|
||||||
//pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti;
|
//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;
|
//pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
|
||||||
} else {
|
} else {
|
||||||
pdcp_pP->is_ue = TRUE;
|
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) {
|
if (ctxt_cpy.enb_flag) {
|
||||||
ctxt.module_id = 0;
|
ctxt.module_id = 0;
|
||||||
rab_id = pdcp_read_header_g.rb_id % maxDRB;
|
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 {
|
} else {
|
||||||
ctxt.module_id = 0;
|
ctxt.module_id = 0;
|
||||||
rab_id = pdcp_read_header_g.rb_id % maxDRB;
|
rab_id = pdcp_read_header_g.rb_id % maxDRB;
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ rlc_tm_cleanup (
|
|||||||
// RX SIDE
|
// RX SIDE
|
||||||
if ((rlcP->output_sdu_in_construction)) {
|
if ((rlcP->output_sdu_in_construction)) {
|
||||||
free_mem_block (rlcP->output_sdu_in_construction, __func__);
|
free_mem_block (rlcP->output_sdu_in_construction, __func__);
|
||||||
|
rlcP->output_sdu_in_construction = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(rlcP, 0, sizeof(rlc_tm_entity_t));
|
memset(rlcP, 0, sizeof(rlc_tm_entity_t));
|
||||||
|
|||||||
@@ -343,6 +343,7 @@ rlc_um_cleanup (
|
|||||||
|
|
||||||
if ((rlc_pP->output_sdu_in_construction)) {
|
if ((rlc_pP->output_sdu_in_construction)) {
|
||||||
free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
|
free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
|
||||||
|
rlc_pP->output_sdu_in_construction = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rlc_pP->dar_buffer) {
|
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].bcch_buffer,
|
||||||
eNB->eNB_stats[CC_id].total_bcch_buffer,
|
eNB->eNB_stats[CC_id].total_bcch_buffer,
|
||||||
eNB->eNB_stats[CC_id].bcch_mcs);
|
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].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;
|
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);
|
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 defined(Rel10) || defined(Rel14)
|
||||||
|
|
||||||
if((Srb_id & RAB_OFFSET) == MCCH) {
|
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) {
|
if (ue_context_p != NULL) {
|
||||||
LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
|
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 {
|
else {
|
||||||
LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
|
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,
|
void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP,
|
||||||
|
|||||||
@@ -54,6 +54,8 @@
|
|||||||
#include "UL-DCCH-Message.h"
|
#include "UL-DCCH-Message.h"
|
||||||
#include "DL-CCCH-Message.h"
|
#include "DL-CCCH-Message.h"
|
||||||
#include "DL-DCCH-Message.h"
|
#include "DL-DCCH-Message.h"
|
||||||
|
#include "PCCH-Message.h"
|
||||||
|
#include "openair3/UTILS/conversions.h"
|
||||||
#include "EstablishmentCause.h"
|
#include "EstablishmentCause.h"
|
||||||
#include "RRCConnectionSetup.h"
|
#include "RRCConnectionSetup.h"
|
||||||
#include "SRB-ToAddModList.h"
|
#include "SRB-ToAddModList.h"
|
||||||
@@ -89,6 +91,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/ran_context.h"
|
#include "common/ran_context.h"
|
||||||
|
#include "secu_defs.h"
|
||||||
|
|
||||||
//#include "PHY/defs.h"
|
//#include "PHY/defs.h"
|
||||||
#ifndef USER_MODE
|
#ifndef USER_MODE
|
||||||
@@ -230,7 +233,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich
|
|||||||
|
|
||||||
AssertFatal(phich_Resource <= PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n");
|
AssertFatal(phich_Resource <= PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n");
|
||||||
mib->message.phich_Config.phich_Resource = phich_Resource;
|
mib->message.phich_Config.phich_Resource = phich_Resource;
|
||||||
AssertFatal(phich_Resource <= PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n");
|
AssertFatal(phich_duration <= PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n");
|
||||||
mib->message.phich_Config.phich_Duration = phich_duration;
|
mib->message.phich_Config.phich_Duration = phich_duration;
|
||||||
LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x,sfn %x\n",
|
LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x,sfn %x\n",
|
||||||
(uint32_t)mib->message.dl_Bandwidth,
|
(uint32_t)mib->message.dl_Bandwidth,
|
||||||
@@ -1964,6 +1967,214 @@ do_RRCConnectionReconfiguration(
|
|||||||
return((enc_rval.encoded+7)/8);
|
return((enc_rval.encoded+7)/8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
asn_enc_rval_t enc_rval;
|
||||||
|
|
||||||
|
long* logicalchannelgroup = NULL;
|
||||||
|
struct SRB_ToAddMod* SRB1_config = NULL;
|
||||||
|
struct SRB_ToAddMod* SRB2_config = NULL;
|
||||||
|
struct SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL;
|
||||||
|
struct SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL;
|
||||||
|
struct LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL;
|
||||||
|
eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id];
|
||||||
|
|
||||||
|
#ifdef CBA
|
||||||
|
struct PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL;
|
||||||
|
long* betaOffset_CBA_Index = NULL;
|
||||||
|
long* cShift_CBA = NULL;
|
||||||
|
#endif
|
||||||
|
PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL;
|
||||||
|
|
||||||
|
DL_CCCH_Message_t dl_ccch_msg;
|
||||||
|
|
||||||
|
RRCConnectionReestablishment_t* rrcConnectionReestablishment = NULL;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||||
|
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
|
||||||
|
if (*SRB_configList2) {
|
||||||
|
free(*SRB_configList2);
|
||||||
|
}
|
||||||
|
*SRB_configList2 = CALLOC(1, sizeof(SRB_ToAddModList_t));
|
||||||
|
|
||||||
|
memset((void *)&dl_ccch_msg, 0, sizeof(DL_CCCH_Message_t));
|
||||||
|
dl_ccch_msg.message.present = DL_CCCH_MessageType_PR_c1;
|
||||||
|
dl_ccch_msg.message.choice.c1.present = DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment;
|
||||||
|
rrcConnectionReestablishment = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReestablishment;
|
||||||
|
|
||||||
|
// RRCConnectionReestablishment
|
||||||
|
// Configure SRB1
|
||||||
|
|
||||||
|
|
||||||
|
// get old configuration of SRB2
|
||||||
|
if (*SRB_configList != NULL) {
|
||||||
|
for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) {
|
||||||
|
LOG_D(RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n",
|
||||||
|
i, (*SRB_configList)->list.array[i]->srb_Identity);
|
||||||
|
if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ){
|
||||||
|
SRB2_config = (*SRB_configList)->list.array[i];
|
||||||
|
} else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ){
|
||||||
|
SRB1_config = (*SRB_configList)->list.array[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SRB1_config == NULL) {
|
||||||
|
// default SRB1 configuration
|
||||||
|
LOG_W(RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n");
|
||||||
|
/// SRB1
|
||||||
|
SRB1_config = CALLOC(1, sizeof(*SRB1_config));
|
||||||
|
|
||||||
|
SRB1_config->srb_Identity = 1;
|
||||||
|
SRB1_rlc_config = CALLOC(1, sizeof(*SRB1_rlc_config));
|
||||||
|
SRB1_config->rlc_Config = SRB1_rlc_config;
|
||||||
|
|
||||||
|
SRB1_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.present=RLC_Config_PR_am;
|
||||||
|
#if defined(ENABLE_ITTI)
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = rrc->srb1_poll_byte;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit;
|
||||||
|
#else
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms20;;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p4;;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35;
|
||||||
|
SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config));
|
||||||
|
SRB1_config->logicalChannelConfig = SRB1_lchan_config;
|
||||||
|
|
||||||
|
SRB1_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
|
||||||
|
SRB1_ul_SpecificParameters = CALLOC(1, sizeof(*SRB1_ul_SpecificParameters));
|
||||||
|
|
||||||
|
SRB1_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB1_ul_SpecificParameters;
|
||||||
|
SRB1_ul_SpecificParameters->priority = 1;
|
||||||
|
|
||||||
|
//assign_enum(&SRB1_ul_SpecificParameters->prioritisedBitRate,LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity);
|
||||||
|
SRB1_ul_SpecificParameters->prioritisedBitRate=LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
|
||||||
|
|
||||||
|
//assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50);
|
||||||
|
SRB1_ul_SpecificParameters->bucketSizeDuration=LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
|
||||||
|
|
||||||
|
logicalchannelgroup = CALLOC(1, sizeof(long));
|
||||||
|
*logicalchannelgroup = 0;
|
||||||
|
SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SRB2_config == NULL) {
|
||||||
|
LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n");
|
||||||
|
} else {
|
||||||
|
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*SRB_configList) {
|
||||||
|
free(*SRB_configList);
|
||||||
|
}
|
||||||
|
|
||||||
|
*SRB_configList = CALLOC(1, sizeof(SRB_ToAddModList_t));
|
||||||
|
|
||||||
|
ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config);
|
||||||
|
|
||||||
|
physicalConfigDedicated2 = *physicalConfigDedicated;
|
||||||
|
|
||||||
|
rrcConnectionReestablishment->rrc_TransactionIdentifier = Transaction_id;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.present = RRCConnectionReestablishment__criticalExtensions_PR_c1;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.present = RRCConnectionReestablishment__criticalExtensions__c1_PR_rrcConnectionReestablishment_r8;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.srb_ToAddModList = *SRB_configList;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.drb_ToAddModList = NULL;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.drb_ToReleaseList = NULL;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.sps_Config = NULL;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2;
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.mac_MainConfig = NULL;
|
||||||
|
|
||||||
|
uint8_t KeNB_star[32] = { 0 };
|
||||||
|
uint16_t pci = rrc->carrier[CC_id].physCellId;
|
||||||
|
uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
|
||||||
|
rrc->carrier[CC_id].dl_CarrierFreq);
|
||||||
|
bool is_rel8_only = true;
|
||||||
|
if (earfcn_dl > 65535) {
|
||||||
|
is_rel8_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D(RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n",
|
||||||
|
pci,
|
||||||
|
RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
|
||||||
|
rrc->carrier[CC_id].dl_CarrierFreq,
|
||||||
|
earfcn_dl,
|
||||||
|
is_rel8_only == true ? "true": "false");
|
||||||
|
#if defined(ENABLE_SECURITY)
|
||||||
|
if (ue_context_pP->ue_context.nh_ncc >= 0) {
|
||||||
|
derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KeNB_star);
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = ue_context_pP->ue_context.nh_ncc;
|
||||||
|
} else { // first HO
|
||||||
|
derive_keNB_star (ue_context_pP->ue_context.kenb, pci, earfcn_dl, is_rel8_only, KeNB_star);
|
||||||
|
// LG: really 1
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy KeNB_star to ue_context_pP->ue_context.kenb
|
||||||
|
memcpy (ue_context_pP->ue_context.kenb, KeNB_star, 32);
|
||||||
|
ue_context_pP->ue_context.kenb_ncc = 0;
|
||||||
|
#else
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nonCriticalExtension = NULL;
|
||||||
|
|
||||||
|
#ifdef XER_PRINT
|
||||||
|
xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg);
|
||||||
|
#endif
|
||||||
|
enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message,
|
||||||
|
(void*)&dl_ccch_msg,
|
||||||
|
buffer,
|
||||||
|
100);
|
||||||
|
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||||
|
enc_rval.failed_type->name, enc_rval.encoded);
|
||||||
|
|
||||||
|
#if defined(ENABLE_ITTI)
|
||||||
|
# if !defined(DISABLE_XER_SPRINT)
|
||||||
|
{
|
||||||
|
char message_string[20000];
|
||||||
|
size_t message_string_size;
|
||||||
|
|
||||||
|
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) {
|
||||||
|
MessageDef *msg_p;
|
||||||
|
|
||||||
|
msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText));
|
||||||
|
msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size;
|
||||||
|
memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size);
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USER_MODE
|
||||||
|
LOG_D(RRC,"RRCConnectionReestablishment Encoded %zd bits (%zd bytes)\n",
|
||||||
|
enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return((enc_rval.encoded+7)/8);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
uint8_t
|
uint8_t
|
||||||
do_RRCConnectionReestablishmentReject(
|
do_RRCConnectionReestablishmentReject(
|
||||||
@@ -2451,6 +2662,73 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans
|
|||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain)
|
||||||
|
{
|
||||||
|
LOG_D(RRC, "[eNB %d] do_Paging start\n", Mod_id);
|
||||||
|
asn_enc_rval_t enc_rval;
|
||||||
|
|
||||||
|
PCCH_Message_t pcch_msg;
|
||||||
|
PagingRecord_t *paging_record_p;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
pcch_msg.message.present = PCCH_MessageType_PR_c1;
|
||||||
|
pcch_msg.message.choice.c1.present = PCCH_MessageType__c1_PR_paging;
|
||||||
|
|
||||||
|
pcch_msg.message.choice.c1.choice.paging.pagingRecordList = CALLOC(1,sizeof(*pcch_msg.message.choice.c1.choice.paging.pagingRecordList));
|
||||||
|
|
||||||
|
pcch_msg.message.choice.c1.choice.paging.systemInfoModification = NULL;
|
||||||
|
pcch_msg.message.choice.c1.choice.paging.etws_Indication = NULL;
|
||||||
|
pcch_msg.message.choice.c1.choice.paging.nonCriticalExtension = NULL;
|
||||||
|
|
||||||
|
asn_set_empty(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list);
|
||||||
|
pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count = 0;
|
||||||
|
|
||||||
|
if ((paging_record_p = calloc(1, sizeof(PagingRecord_t))) == NULL) {
|
||||||
|
/* Possible error on calloc */
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(paging_record_p, 0, sizeof(PagingRecord_t));
|
||||||
|
|
||||||
|
/* convert ue_paging_identity_t to PagingUE_Identity_t */
|
||||||
|
if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_s_tmsi) {
|
||||||
|
paging_record_p->ue_Identity.present = PagingUE_Identity_PR_s_TMSI;
|
||||||
|
MME_CODE_TO_OCTET_STRING(ue_paging_identity.choice.s_tmsi.mme_code,
|
||||||
|
&paging_record_p->ue_Identity.choice.s_TMSI.mmec);
|
||||||
|
paging_record_p->ue_Identity.choice.s_TMSI.mmec.bits_unused = 0;
|
||||||
|
M_TMSI_TO_OCTET_STRING(ue_paging_identity.choice.s_tmsi.m_tmsi,
|
||||||
|
&paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI);
|
||||||
|
paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI.bits_unused = 0;
|
||||||
|
} else if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_imsi) {
|
||||||
|
IMSI_Digit_t imsi_digit[21];
|
||||||
|
for (j = 0; j< ue_paging_identity.choice.imsi.length; j++) { /* IMSI size */
|
||||||
|
imsi_digit[j] = (IMSI_Digit_t)ue_paging_identity.choice.imsi.buffer[j];
|
||||||
|
ASN_SEQUENCE_ADD(&paging_record_p->ue_Identity.choice.imsi.list, &imsi_digit[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set cn_domain */
|
||||||
|
if (cn_domain == CN_DOMAIN_PS) {
|
||||||
|
paging_record_p->cn_Domain = PagingRecord__cn_Domain_ps;
|
||||||
|
} else {
|
||||||
|
paging_record_p->cn_Domain = PagingRecord__cn_Domain_cs;
|
||||||
|
}
|
||||||
|
/* add to list */
|
||||||
|
ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list, paging_record_p);
|
||||||
|
LOG_D(RRC, "[eNB %d] do_Paging paging_record: cn_Domain %ld, ue_paging_identity.presenceMask %d, PagingRecordList.count %d\n",
|
||||||
|
Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count);
|
||||||
|
|
||||||
|
enc_rval = uper_encode_to_buffer(&asn_DEF_PCCH_Message, (void*)&pcch_msg, buffer, RRC_BUF_SIZE);
|
||||||
|
|
||||||
|
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||||
|
enc_rval.failed_type->name, enc_rval.encoded);
|
||||||
|
#ifdef XER_PRINT
|
||||||
|
xer_fprint(stdout, &asn_DEF_PCCH_Message, (void*)&pcch_msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return((enc_rval.encoded+7)/8);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer)
|
uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer)
|
||||||
{
|
{
|
||||||
ssize_t encoded;
|
ssize_t encoded;
|
||||||
|
|||||||
@@ -195,6 +195,28 @@ do_RRCConnectionReconfiguration(
|
|||||||
, SCellToAddMod_r10_t *SCell_config
|
, SCellToAddMod_r10_t *SCell_config
|
||||||
#endif
|
#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).
|
\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_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);
|
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);
|
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_DONE, // from the eNB perspective
|
||||||
E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
|
E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
|
||||||
E_RAB_STATUS_FAILED,
|
E_RAB_STATUS_FAILED,
|
||||||
|
E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE
|
||||||
} e_rab_status_t;
|
} e_rab_status_t;
|
||||||
|
|
||||||
typedef struct e_rab_param_s {
|
typedef struct e_rab_param_s {
|
||||||
e_rab_t param;
|
e_rab_t param;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
uint8_t xid; // transaction_id
|
uint8_t xid; // transaction_id
|
||||||
|
s1ap_Cause_t cause;
|
||||||
|
uint8_t cause_value;
|
||||||
} __attribute__ ((__packed__)) e_rab_param_t;
|
} __attribute__ ((__packed__)) e_rab_param_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -379,6 +382,7 @@ typedef struct eNB_RRC_UE_s {
|
|||||||
SRB_ToAddModList_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
SRB_ToAddModList_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||||
DRB_ToAddModList_t* DRB_configList;
|
DRB_ToAddModList_t* DRB_configList;
|
||||||
DRB_ToAddModList_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
DRB_ToAddModList_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||||
|
DRB_ToReleaseList_t* DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||||
uint8_t DRB_active[8];
|
uint8_t DRB_active[8];
|
||||||
struct PhysicalConfigDedicated* physicalConfigDedicated;
|
struct PhysicalConfigDedicated* physicalConfigDedicated;
|
||||||
struct SPS_Config* sps_Config;
|
struct SPS_Config* sps_Config;
|
||||||
@@ -398,6 +402,9 @@ typedef struct eNB_RRC_UE_s {
|
|||||||
#if defined(ENABLE_SECURITY)
|
#if defined(ENABLE_SECURITY)
|
||||||
/* KeNB as derived from KASME received from EPC */
|
/* KeNB as derived from KASME received from EPC */
|
||||||
uint8_t kenb[32];
|
uint8_t kenb[32];
|
||||||
|
int8_t kenb_ncc;
|
||||||
|
uint8_t nh[32];
|
||||||
|
int8_t nh_ncc;
|
||||||
#endif
|
#endif
|
||||||
/* Used integrity/ciphering algorithms */
|
/* Used integrity/ciphering algorithms */
|
||||||
CipheringAlgorithm_r12_t ciphering_algorithm;
|
CipheringAlgorithm_r12_t ciphering_algorithm;
|
||||||
@@ -427,9 +434,15 @@ typedef struct eNB_RRC_UE_s {
|
|||||||
uint8_t setup_e_rabs;
|
uint8_t setup_e_rabs;
|
||||||
/* Number of e_rab to be setup in the list */
|
/* Number of e_rab to be setup in the list */
|
||||||
uint8_t nb_of_e_rabs;
|
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 */
|
/* list of e_rab to be setup by RRC layers */
|
||||||
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
|
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
|
// LG: For GTPV1 TUNNELS
|
||||||
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
|
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
|
||||||
transport_layer_addr_t enb_gtp_addrs[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 ul_failure_timer;
|
||||||
uint32_t ue_release_timer;
|
uint32_t ue_release_timer;
|
||||||
uint32_t ue_release_timer_thres;
|
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;
|
} eNB_RRC_UE_t;
|
||||||
|
|
||||||
typedef uid_t ue_uid_t;
|
typedef uid_t ue_uid_t;
|
||||||
@@ -501,6 +521,8 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
SRB_INFO SI;
|
SRB_INFO SI;
|
||||||
SRB_INFO Srb0;
|
SRB_INFO Srb0;
|
||||||
|
uint8_t *paging[NUMBER_OF_UE_MAX];
|
||||||
|
uint32_t sizeof_paging[NUMBER_OF_UE_MAX];
|
||||||
} rrc_eNB_carrier_data_t;
|
} rrc_eNB_carrier_data_t;
|
||||||
|
|
||||||
typedef struct eNB_RRC_INST_s {
|
typedef struct eNB_RRC_INST_s {
|
||||||
@@ -628,6 +650,8 @@ typedef struct UE_RRC_INST_s {
|
|||||||
#if defined(ENABLE_SECURITY)
|
#if defined(ENABLE_SECURITY)
|
||||||
/* KeNB as computed from parameters within USIM card */
|
/* KeNB as computed from parameters within USIM card */
|
||||||
uint8_t kenb[32];
|
uint8_t kenb[32];
|
||||||
|
uint8_t nh[32];
|
||||||
|
int8_t nh_ncc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used integrity/ciphering algorithms */
|
/* Used integrity/ciphering algorithms */
|
||||||
@@ -635,6 +659,14 @@ typedef struct UE_RRC_INST_s {
|
|||||||
e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
|
e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
|
||||||
} UE_RRC_INST;
|
} 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"
|
#include "proto.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -77,6 +77,11 @@ extern uint32_t timeToTrigger_ms[16];
|
|||||||
extern float RSRP_meas_mapping[100];
|
extern float RSRP_meas_mapping[100];
|
||||||
extern float RSRQ_meas_mapping[33];
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
|
|||||||
const uint8_t ho_state
|
const uint8_t ho_state
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int freq_to_arfcn10(int band, unsigned long freq);
|
||||||
|
|
||||||
void
|
void
|
||||||
rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
|
rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
|
||||||
const protocol_ctxt_t* const ctxt_pP,
|
const protocol_ctxt_t* const ctxt_pP,
|
||||||
@@ -261,6 +263,18 @@ rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
|
|||||||
const uint8_t ho_state
|
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
|
void
|
||||||
rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP,
|
rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP,
|
||||||
rrc_eNB_ue_context_t* ue_context_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 sub_frame_t subframeP,
|
||||||
const rnti_t rnti);
|
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,
|
void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP,
|
||||||
const int CC_id,
|
const int CC_id,
|
||||||
const frame_t frameP,
|
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)) {
|
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 ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) {
|
||||||
if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
|
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.rnti,
|
||||||
ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
|
ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
|
||||||
ue_context_p->ue_context.ul_failure_timer);
|
ue_context_p->ue_context.ul_failure_timer);
|
||||||
}
|
}
|
||||||
else {
|
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.rnti,
|
||||||
ue_context_p->ue_context.ul_failure_timer);
|
ue_context_p->ue_context.ul_failure_timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ue_context_p->ue_context.ul_failure_timer>0) {
|
if (ue_context_p->ue_context.ul_failure_timer>0) {
|
||||||
ue_context_p->ue_context.ul_failure_timer++;
|
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
|
// 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);
|
LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
|
||||||
ue_to_be_removed = ue_context_p;
|
ue_to_be_removed = ue_context_p;
|
||||||
break;
|
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) {
|
if (ue_context_p->ue_context.ue_release_timer>0) {
|
||||||
ue_context_p->ue_context.ue_release_timer++;
|
ue_context_p->ue_context.ue_release_timer++;
|
||||||
if (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);
|
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
|
#ifdef RRC_LOCALIZATION
|
||||||
|
|
||||||
/* for the localization, only primary CC_id might be relevant*/
|
/* for the localization, only primary CC_id might be relevant*/
|
||||||
|
|||||||
+1634
-23
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,8 @@ extern RAN_CONTEXT_t RC;
|
|||||||
int
|
int
|
||||||
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||||
const protocol_ctxt_t* const ctxt_pP,
|
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;
|
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++) {
|
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_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_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_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",
|
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),
|
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||||
create_tunnel_resp_pP->enb_S1u_teid[i],
|
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],
|
ue_context_p->ue_context.enb_gtp_teid[inde_list[i]],
|
||||||
i+ue_context_p->ue_context.setup_e_rabs,
|
inde_list[i],
|
||||||
i,
|
i,
|
||||||
create_tunnel_resp_pP->eps_bearer_id[i],
|
create_tunnel_resp_pP->eps_bearer_id[i],
|
||||||
create_tunnel_resp_pP->enb_addr.length);
|
create_tunnel_resp_pP->enb_addr.length);
|
||||||
|
|||||||
@@ -43,7 +43,8 @@
|
|||||||
int
|
int
|
||||||
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||||
const protocol_ctxt_t* const ctxt_pP,
|
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
|
# endif
|
||||||
|
|||||||
@@ -342,6 +342,8 @@ static void process_eNB_security_key (
|
|||||||
|
|
||||||
/* Saves the security key */
|
/* Saves the security key */
|
||||||
memcpy (ue_context_pP->ue_context.kenb, security_key_pP, SECURITY_KEY_LENGTH);
|
memcpy (ue_context_pP->ue_context.kenb, security_key_pP, SECURITY_KEY_LENGTH);
|
||||||
|
memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH);
|
||||||
|
ue_context_pP->ue_context.nh_ncc = -1;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kenb[i]);
|
sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kenb[i]);
|
||||||
@@ -355,7 +357,7 @@ static void process_eNB_security_key (
|
|||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
static void
|
void
|
||||||
rrc_pdcp_config_security(
|
rrc_pdcp_config_security(
|
||||||
const protocol_ctxt_t* const ctxt_pP,
|
const protocol_ctxt_t* const ctxt_pP,
|
||||||
rrc_eNB_ue_context_t* const ue_context_pP,
|
rrc_eNB_ue_context_t* const ue_context_pP,
|
||||||
@@ -892,6 +894,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
|
|||||||
//MessageDef *message_gtpv1u_p = NULL;
|
//MessageDef *message_gtpv1u_p = NULL;
|
||||||
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
|
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
|
||||||
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
|
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
|
||||||
|
uint8_t inde_list[NB_RB_MAX - 3]={0};
|
||||||
|
|
||||||
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
||||||
protocol_ctxt_t ctxt;
|
protocol_ctxt_t ctxt;
|
||||||
@@ -937,10 +940,12 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
|
|||||||
memcpy(&create_tunnel_req.sgw_addr[i],
|
memcpy(&create_tunnel_req.sgw_addr[i],
|
||||||
&S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].sgw_addr,
|
&S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].sgw_addr,
|
||||||
sizeof(transport_layer_addr_t));
|
sizeof(transport_layer_addr_t));
|
||||||
|
inde_list[create_tunnel_req.num_tunnels]= i;
|
||||||
|
create_tunnel_req.num_tunnels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
|
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
|
||||||
create_tunnel_req.num_tunnels = i;
|
// create_tunnel_req.num_tunnels = i;
|
||||||
|
|
||||||
gtpv1u_create_s1u_tunnel(
|
gtpv1u_create_s1u_tunnel(
|
||||||
instance,
|
instance,
|
||||||
@@ -949,7 +954,8 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
|
|||||||
|
|
||||||
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||||
&ctxt,
|
&ctxt,
|
||||||
&create_tunnel_resp);
|
&create_tunnel_resp,
|
||||||
|
&inde_list[0]);
|
||||||
ue_context_p->ue_context.setup_e_rabs=ue_context_p->ue_context.nb_of_e_rabs;
|
ue_context_p->ue_context.setup_e_rabs=ue_context_p->ue_context.nb_of_e_rabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1191,6 +1197,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const ch
|
|||||||
}
|
}
|
||||||
return (-1);
|
return (-1);
|
||||||
} else {
|
} else {
|
||||||
|
ue_context_p->ue_context.ue_release_timer_s1 = 0;
|
||||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||||
rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p);
|
rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p);
|
||||||
/*
|
/*
|
||||||
@@ -1265,9 +1272,12 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
|
|||||||
uint32_t eNB_ue_s1ap_id;
|
uint32_t eNB_ue_s1ap_id;
|
||||||
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
|
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
|
||||||
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
|
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
|
||||||
|
uint8_t inde_list[NB_RB_MAX - 3]={0};
|
||||||
|
|
||||||
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
||||||
protocol_ctxt_t ctxt;
|
protocol_ctxt_t ctxt;
|
||||||
|
uint8_t e_rab_done;
|
||||||
|
|
||||||
ue_initial_id = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id;
|
ue_initial_id = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id;
|
||||||
eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id;
|
eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id;
|
||||||
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id);
|
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id);
|
||||||
@@ -1298,35 +1308,46 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
|
|||||||
|
|
||||||
memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
|
memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
|
||||||
uint8_t nb_e_rabs_tosetup = S1AP_E_RAB_SETUP_REQ (msg_p).nb_e_rabs_tosetup;
|
uint8_t nb_e_rabs_tosetup = S1AP_E_RAB_SETUP_REQ (msg_p).nb_e_rabs_tosetup;
|
||||||
|
e_rab_done = 0;
|
||||||
|
|
||||||
// keep the previous bearer
|
// keep the previous bearer
|
||||||
// the index for the rec
|
// the index for the rec
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
i < nb_e_rabs_tosetup;
|
// i < nb_e_rabs_tosetup;
|
||||||
|
i < NB_RB_MAX - 3; // loop all e-rabs in e_rab[]
|
||||||
i++) {
|
i++) {
|
||||||
if (ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status == E_RAB_STATUS_DONE)
|
//if (ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status == E_RAB_STATUS_DONE)
|
||||||
LOG_W(RRC,"E-RAB already configured, reconfiguring\n");
|
// LOG_W(RRC,"E-RAB already configured, reconfiguring\n");
|
||||||
ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status = E_RAB_STATUS_NEW;
|
// check e-rab status, if e rab status is greater than E_RAB_STATUS_DONE, don't not config this one
|
||||||
ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].param = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i];
|
if(ue_context_p->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE)
|
||||||
|
continue;
|
||||||
|
//ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status = E_RAB_STATUS_NEW;
|
||||||
|
//ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].param = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i];
|
||||||
|
ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
|
||||||
|
ue_context_p->ue_context.e_rab[i].param = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done];
|
||||||
|
|
||||||
|
create_tunnel_req.eps_bearer_id[e_rab_done] = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].e_rab_id;
|
||||||
|
create_tunnel_req.sgw_S1u_teid[e_rab_done] = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].gtp_teid;
|
||||||
|
|
||||||
create_tunnel_req.eps_bearer_id[i] = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i].e_rab_id;
|
memcpy(&create_tunnel_req.sgw_addr[e_rab_done],
|
||||||
create_tunnel_req.sgw_S1u_teid[i] = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i].gtp_teid;
|
& S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].sgw_addr,
|
||||||
|
|
||||||
memcpy(&create_tunnel_req.sgw_addr[i],
|
|
||||||
& S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i].sgw_addr,
|
|
||||||
sizeof(transport_layer_addr_t));
|
sizeof(transport_layer_addr_t));
|
||||||
|
|
||||||
LOG_I(RRC,"E_RAB setup REQ: local index %d teid %u, eps id %d \n",
|
LOG_I(RRC,"E_RAB setup REQ: local index %d teid %u, eps id %d \n",
|
||||||
i+ue_context_p->ue_context.setup_e_rabs,
|
i,
|
||||||
create_tunnel_req.sgw_S1u_teid[i],
|
create_tunnel_req.sgw_S1u_teid[e_rab_done],
|
||||||
create_tunnel_req.eps_bearer_id[i] );
|
create_tunnel_req.eps_bearer_id[i] );
|
||||||
|
inde_list[e_rab_done] = i;
|
||||||
|
e_rab_done++;
|
||||||
|
if(e_rab_done >= nb_e_rabs_tosetup){
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ue_context_p->ue_context.nb_of_e_rabs=nb_e_rabs_tosetup;
|
ue_context_p->ue_context.nb_of_e_rabs=nb_e_rabs_tosetup;
|
||||||
|
|
||||||
|
|
||||||
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
|
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
|
||||||
create_tunnel_req.num_tunnels = i;
|
create_tunnel_req.num_tunnels = e_rab_done;
|
||||||
|
|
||||||
// NN: not sure if we should create a new tunnel: need to check teid, etc.
|
// NN: not sure if we should create a new tunnel: need to check teid, etc.
|
||||||
gtpv1u_create_s1u_tunnel(
|
gtpv1u_create_s1u_tunnel(
|
||||||
@@ -1336,7 +1357,8 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
|
|||||||
|
|
||||||
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||||
&ctxt,
|
&ctxt,
|
||||||
&create_tunnel_resp);
|
&create_tunnel_resp,
|
||||||
|
&inde_list[0]);
|
||||||
|
|
||||||
ue_context_p->ue_context.setup_e_rabs+=nb_e_rabs_tosetup;
|
ue_context_p->ue_context.setup_e_rabs+=nb_e_rabs_tosetup;
|
||||||
|
|
||||||
@@ -1400,12 +1422,17 @@ int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
|
|||||||
S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
|
S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
|
||||||
e_rabs_failed++;
|
e_rabs_failed++;
|
||||||
// TODO add cause when it will be integrated
|
// TODO add cause when it will be integrated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
|
S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
|
||||||
S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
|
S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
|
||||||
// NN: add conditions for e_rabs_failed
|
// NN: add conditions for e_rabs_failed
|
||||||
|
} else {
|
||||||
|
/*debug info for the xid */
|
||||||
|
LOG_D(RRC,"xid does not corresponds (context e_rab index %d, status %d, xid %d/%d) \n ",
|
||||||
|
e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, ue_context_pP->ue_context.e_rab[e_rab].xid);
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((e_rabs_done > 0) ){
|
if ((e_rabs_done > 0) ){
|
||||||
|
|
||||||
LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: sending the message: nb_of_erabs %d, total e_rabs %d, index %d\n",
|
LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: sending the message: nb_of_erabs %d, total e_rabs %d, index %d\n",
|
||||||
@@ -1424,17 +1451,528 @@ int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
|
|||||||
|
|
||||||
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
|
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
|
||||||
}
|
}
|
||||||
|
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||||
} else {
|
ue_context_pP->ue_context.e_rab[i].xid = -1;
|
||||||
/*debug info for the xid */
|
|
||||||
LOG_D(RRC,"xid does not corresponds (context e_rab index %d, status %d, xid %d/%d) \n ",
|
|
||||||
e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, ue_context_pP->ue_context.e_rab[e_rab].xid);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t ue_initial_id;
|
||||||
|
uint32_t eNB_ue_s1ap_id;
|
||||||
|
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
||||||
|
protocol_ctxt_t ctxt;
|
||||||
|
|
||||||
|
ue_initial_id = S1AP_E_RAB_MODIFY_REQ (msg_p).ue_initial_id;
|
||||||
|
eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id;
|
||||||
|
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id);
|
||||||
|
LOG_D(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n",
|
||||||
|
instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify);
|
||||||
|
|
||||||
|
if (ue_context_p == NULL) {
|
||||||
|
/* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
|
||||||
|
LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_MODIFY_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id);
|
||||||
|
int nb_of_e_rabs_failed = 0;
|
||||||
|
MessageDef *msg_fail_p = NULL;
|
||||||
|
|
||||||
|
msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0;
|
||||||
|
|
||||||
|
for (nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; nb_of_e_rabs_failed++) {
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
|
||||||
|
S1AP_E_RAB_MODIFY_REQ (msg_p).e_rab_modify_params[nb_of_e_rabs_failed].e_rab_id;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances;
|
||||||
|
}
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_S1AP, instance, msg_fail_p);
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||||
|
ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||||
|
|
||||||
|
/* Save e RAB information for later */
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
boolean_t is_treated[S1AP_MAX_E_RAB] = {FALSE};
|
||||||
|
uint8_t nb_of_failed_e_rabs = 0;
|
||||||
|
|
||||||
|
// keep the previous bearer
|
||||||
|
// the index for the rec
|
||||||
|
for (i = 0; i < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; i++) {
|
||||||
|
if (is_treated[i] == TRUE) {
|
||||||
|
// already treated
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (j = i+1; j < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; j++) {
|
||||||
|
if (is_treated[j] == FALSE &&
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) {
|
||||||
|
// handle multiple E-RAB ID
|
||||||
|
ue_context_p->ue_context.modify_e_rab[j].status = E_RAB_STATUS_NEW;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[j].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[j].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[j].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances;
|
||||||
|
nb_of_failed_e_rabs++;
|
||||||
|
is_treated[i] = TRUE;
|
||||||
|
is_treated[j] = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_treated[i] == TRUE) {
|
||||||
|
// handle multiple E-RAB ID
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances;
|
||||||
|
nb_of_failed_e_rabs++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.length == 0) {
|
||||||
|
// nas_pdu.length == 0
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NAS;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause_value = 3;//S1ap_CauseNas_unspecified;
|
||||||
|
nb_of_failed_e_rabs++;
|
||||||
|
is_treated[i] = TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < NB_RB_MAX-3; j++) {
|
||||||
|
if (ue_context_p->ue_context.e_rab[j].param.e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) {
|
||||||
|
if(ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_TORELEASE || ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_DONE){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NOTHING;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.qos = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].qos;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.length = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.length;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.buffer = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.buffer;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.sgw_addr = ue_context_p->ue_context.e_rab[j].param.sgw_addr;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.gtp_teid = ue_context_p->ue_context.e_rab[j].param.gtp_teid;
|
||||||
|
|
||||||
|
is_treated[i] = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_treated[i] == FALSE) {
|
||||||
|
// handle Unknown E-RAB ID
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
ue_context_p->ue_context.modify_e_rab[i].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID;
|
||||||
|
nb_of_failed_e_rabs++;
|
||||||
|
is_treated[i] = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ue_context_p->ue_context.nb_of_modify_e_rabs = S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify;
|
||||||
|
ue_context_p->ue_context.nb_of_failed_e_rabs = nb_of_failed_e_rabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO parameters yet to process ... */
|
||||||
|
{
|
||||||
|
// S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ue_context_p->ue_context.nb_of_failed_e_rabs < ue_context_p->ue_context.nb_of_modify_e_rabs) {
|
||||||
|
if (0 == rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(&ctxt, ue_context_p, 0)) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int nb_of_e_rabs_failed = 0;
|
||||||
|
MessageDef *msg_fail_p = NULL;
|
||||||
|
|
||||||
|
msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id;
|
||||||
|
// S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB];
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0;
|
||||||
|
|
||||||
|
for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < ue_context_p->ue_context.nb_of_failed_e_rabs; nb_of_e_rabs_failed++) {
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
|
||||||
|
ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].param.e_rab_id;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause = ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].cause;
|
||||||
|
}
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
|
||||||
|
|
||||||
|
itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p);
|
||||||
|
|
||||||
|
ue_context_p->ue_context.nb_of_modify_e_rabs = 0;
|
||||||
|
ue_context_p->ue_context.nb_of_failed_e_rabs = 0;
|
||||||
|
memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
} // end of ue_context_p != NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
/*NN: careful about the typcast of xid (long -> uint8_t*/
|
||||||
|
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 ) {
|
||||||
|
|
||||||
|
MessageDef *msg_p = NULL;
|
||||||
|
int i;
|
||||||
|
int e_rab;
|
||||||
|
int e_rabs_done = 0;
|
||||||
|
int e_rabs_failed = 0;
|
||||||
|
msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
|
||||||
|
|
||||||
|
for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_modify_e_rabs; e_rab++) {
|
||||||
|
|
||||||
|
/* only respond to the corresponding transaction */
|
||||||
|
if (xid == ue_context_pP->ue_context.modify_e_rab[e_rab].xid) {
|
||||||
|
if (ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_DONE) {
|
||||||
|
for (i = 0; i < ue_context_pP->ue_context.setup_e_rabs; i++) {
|
||||||
|
if (ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id == ue_context_pP->ue_context.e_rab[i].param.e_rab_id) {
|
||||||
|
// Update ue_context_pP->ue_context.e_rab
|
||||||
|
ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_ESTABLISHED;
|
||||||
|
ue_context_pP->ue_context.e_rab[i].param.qos = ue_context_pP->ue_context.modify_e_rab[e_rab].param.qos;
|
||||||
|
ue_context_pP->ue_context.e_rab[i].cause = S1AP_CAUSE_NOTHING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < ue_context_pP->ue_context.setup_e_rabs) {
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id;
|
||||||
|
// TODO add other information from S1-U when it will be integrated
|
||||||
|
|
||||||
|
LOG_D (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d, xid %d): nb_of_modify_e_rabs %d, e_rab_id %d \n ",
|
||||||
|
e_rabs_done, e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid,
|
||||||
|
ue_context_pP->ue_context.nb_of_modify_e_rabs,
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id);
|
||||||
|
|
||||||
|
e_rabs_done++;
|
||||||
|
} else {
|
||||||
|
// unexpected
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id;
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID;
|
||||||
|
|
||||||
|
e_rabs_failed++;
|
||||||
|
}
|
||||||
|
} else if ((ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_NEW) ||
|
||||||
|
(ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)){
|
||||||
|
LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n");
|
||||||
|
} else { /* status == E_RAB_STATUS_FAILED; */
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id;
|
||||||
|
// add failure cause when defined
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause = ue_context_pP->ue_context.modify_e_rab[e_rab].cause;
|
||||||
|
|
||||||
|
e_rabs_failed++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*debug info for the xid */
|
||||||
|
LOG_D(RRC,"xid does not corresponds (context e_rab index %d, status %d, xid %d/%d) \n ",
|
||||||
|
e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid, ue_context_pP->ue_context.modify_e_rab[e_rab].xid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
|
||||||
|
// NN: add conditions for e_rabs_failed
|
||||||
|
if (e_rabs_done > 0 || e_rabs_failed > 0) {
|
||||||
|
LOG_D(RRC,"S1AP_E_RAB_MODIFY_RESP: sending the message: nb_of_modify_e_rabs %d, total e_rabs %d, index %d\n",
|
||||||
|
ue_context_pP->ue_context.nb_of_modify_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
|
||||||
|
MSC_LOG_TX_MESSAGE(
|
||||||
|
MSC_RRC_ENB,
|
||||||
|
MSC_S1AP_ENB,
|
||||||
|
(const char *)&S1AP_E_RAB_SETUP_RESP (msg_p),
|
||||||
|
sizeof(s1ap_e_rab_setup_resp_t),
|
||||||
|
MSC_AS_TIME_FMT" E_RAB_MODIFY_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail",
|
||||||
|
MSC_AS_TIME_ARGS(ctxt_pP),
|
||||||
|
ue_context_pP->ue_id_rnti,
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id,
|
||||||
|
e_rabs_done, e_rabs_failed);
|
||||||
|
|
||||||
|
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance){
|
||||||
|
uint16_t mme_ue_s1ap_id;
|
||||||
|
uint32_t eNB_ue_s1ap_id;
|
||||||
|
struct rrc_eNB_ue_context_s* ue_context_p = NULL;
|
||||||
|
protocol_ctxt_t ctxt;
|
||||||
|
e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB];
|
||||||
|
uint8_t nb_e_rabs_torelease;
|
||||||
|
int erab;
|
||||||
|
int i;
|
||||||
|
uint8_t b_existed,is_existed;
|
||||||
|
uint8_t xid;
|
||||||
|
uint8_t e_rab_release_drb;
|
||||||
|
MessageDef * msg_delete_tunnels_p = NULL;
|
||||||
|
e_rab_release_drb = 0;
|
||||||
|
memcpy(&e_rab_release_params[0], &(S1AP_E_RAB_RELEASE_COMMAND (msg_p).e_rab_release_params[0]), sizeof(e_rab_release_t)*S1AP_MAX_E_RAB);
|
||||||
|
|
||||||
|
mme_ue_s1ap_id = S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id;
|
||||||
|
eNB_ue_s1ap_id = S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id;
|
||||||
|
nb_e_rabs_torelease = S1AP_E_RAB_RELEASE_COMMAND (msg_p).nb_e_rabs_torelease;
|
||||||
|
ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id);
|
||||||
|
if(ue_context_p != NULL){
|
||||||
|
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||||
|
|
||||||
|
xid = rrc_eNB_get_next_transaction_identifier(ctxt.module_id);
|
||||||
|
|
||||||
|
LOG_D(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d ENB_UE_S1AP_ID %d release_e_rabs %d \n",
|
||||||
|
mme_ue_s1ap_id, eNB_ue_s1ap_id,nb_e_rabs_torelease);
|
||||||
|
for(erab = 0; erab < nb_e_rabs_torelease; erab++){
|
||||||
|
b_existed = 0;
|
||||||
|
is_existed = 0;
|
||||||
|
for ( i = erab-1; i>= 0; i--){
|
||||||
|
if (e_rab_release_params[erab].e_rab_id == e_rab_release_params[i].e_rab_id){
|
||||||
|
is_existed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(is_existed == 1){
|
||||||
|
//e_rab_id is existed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for ( i = 0; i < NB_RB_MAX; i++){
|
||||||
|
if (e_rab_release_params[erab].e_rab_id == ue_context_p->ue_context.e_rab[i].param.e_rab_id){
|
||||||
|
b_existed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(b_existed == 0) {
|
||||||
|
//no e_rab_id
|
||||||
|
ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id;
|
||||||
|
ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 30;
|
||||||
|
ue_context_p->ue_context.nb_release_of_e_rabs++;
|
||||||
|
} else {
|
||||||
|
if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_FAILED){
|
||||||
|
ue_context_p->ue_context.e_rab[i].xid = xid;
|
||||||
|
continue;
|
||||||
|
} else if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED){
|
||||||
|
ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE;
|
||||||
|
ue_context_p->ue_context.e_rab[i].xid = xid;
|
||||||
|
e_rab_release_drb++;
|
||||||
|
}else{
|
||||||
|
//e_rab_id status NG
|
||||||
|
ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id;
|
||||||
|
ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 0;
|
||||||
|
ue_context_p->ue_context.nb_release_of_e_rabs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(e_rab_release_drb > 0) {
|
||||||
|
//RRCConnectionReconfiguration To UE
|
||||||
|
rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(&ctxt, ue_context_p, xid, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.length, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.buffer);
|
||||||
|
} else {
|
||||||
|
//gtp tunnel delete
|
||||||
|
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||||
|
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||||
|
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||||
|
for(i = 0; i < NB_RB_MAX; i++){
|
||||||
|
if(xid == ue_context_p->ue_context.e_rab[i].xid){
|
||||||
|
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i];
|
||||||
|
ue_context_p->ue_context.enb_gtp_teid[i] = 0;
|
||||||
|
memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i]));
|
||||||
|
ue_context_p->ue_context.enb_gtp_ebi[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
|
||||||
|
|
||||||
|
//S1AP_E_RAB_RELEASE_RESPONSE
|
||||||
|
rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_E(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d ENB_UE_S1AP_ID %d Error ue_context_p NULL \n",
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id, S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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){
|
||||||
|
int e_rabs_released = 0;
|
||||||
|
MessageDef *msg_p;
|
||||||
|
|
||||||
|
msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_RELEASE_RESPONSE);
|
||||||
|
S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
|
||||||
|
|
||||||
|
for (int i = 0; i < NB_RB_MAX; i++){
|
||||||
|
if (xid == ue_context_pP->ue_context.e_rab[i].xid){
|
||||||
|
S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rab_release[e_rabs_released].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
|
||||||
|
e_rabs_released++;
|
||||||
|
//clear
|
||||||
|
memset(&ue_context_pP->ue_context.e_rab[i],0,sizeof(e_rab_param_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_released = e_rabs_released;
|
||||||
|
S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_failed = ue_context_pP->ue_context.nb_release_of_e_rabs;
|
||||||
|
memcpy(&(S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rabs_failed[0]),&ue_context_pP->ue_context.e_rabs_release_failed[0],sizeof(e_rab_failed_t)*ue_context_pP->ue_context.nb_release_of_e_rabs);
|
||||||
|
|
||||||
|
ue_context_pP->ue_context.setup_e_rabs -= e_rabs_released;
|
||||||
|
LOG_I(RRC,"S1AP-E-RAB RELEASE RESPONSE: ENB_UE_S1AP_ID %d release_e_rabs %d setup_e_rabs %d \n",
|
||||||
|
S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id,
|
||||||
|
e_rabs_released, ue_context_pP->ue_context.setup_e_rabs);
|
||||||
|
|
||||||
|
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
|
||||||
|
//clear xid
|
||||||
|
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||||
|
ue_context_pP->ue_context.e_rab[i].xid = -1;
|
||||||
|
}
|
||||||
|
//clear release e_rabs
|
||||||
|
ue_context_pP->ue_context.nb_release_of_e_rabs = 0;
|
||||||
|
memset(&ue_context_pP->ue_context.e_rabs_release_failed[0],0,sizeof(e_rab_failed_t)*S1AP_MAX_E_RAB);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------*/
|
||||||
|
int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance)
|
||||||
|
{
|
||||||
|
const unsigned int Ttab[4] = {32,64,128,256};
|
||||||
|
uint8_t Tc,Tue; /* DRX cycle of UE */
|
||||||
|
uint32_t pcch_nB; /* 4T, 2T, T, T/2, T/4, T/8, T/16, T/32 */
|
||||||
|
uint32_t N; /* N: min(T,nB). total count of PF in one DRX cycle */
|
||||||
|
uint32_t Ns = 0; /* Ns: max(1,nB/T) */
|
||||||
|
uint8_t i_s; /* i_s = floor(UE_ID/N) mod Ns */
|
||||||
|
uint32_t T; /* DRX cycle */
|
||||||
|
for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) {
|
||||||
|
LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc,
|
||||||
|
S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]);
|
||||||
|
if (RC.rrc[instance]->configuration.mcc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
|
||||||
|
&& RC.rrc[instance]->configuration.mnc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
|
||||||
|
&& RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
|
||||||
|
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||||
|
lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
|
||||||
|
/* get nB from configuration */
|
||||||
|
/* get default DRX cycle from configuration */
|
||||||
|
Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id];
|
||||||
|
if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx;
|
||||||
|
/* set T = min(Tc,Tue) */
|
||||||
|
T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
|
||||||
|
/* set pcch_nB = PCCH-Config->nB */
|
||||||
|
pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id];
|
||||||
|
switch (pcch_nB) {
|
||||||
|
case PCCH_Config__nB_fourT:
|
||||||
|
Ns = 4;
|
||||||
|
break;
|
||||||
|
case PCCH_Config__nB_twoT:
|
||||||
|
Ns = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Ns = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* set N = min(T,nB) */
|
||||||
|
if (pcch_nB > PCCH_Config__nB_oneT) {
|
||||||
|
switch (pcch_nB) {
|
||||||
|
case PCCH_Config__nB_halfT:
|
||||||
|
N = T/2;
|
||||||
|
break;
|
||||||
|
case PCCH_Config__nB_quarterT:
|
||||||
|
N = T/4;
|
||||||
|
break;
|
||||||
|
case PCCH_Config__nB_oneEighthT:
|
||||||
|
N = T/8;
|
||||||
|
break;
|
||||||
|
case PCCH_Config__nB_oneSixteenthT:
|
||||||
|
N = T/16;
|
||||||
|
break;
|
||||||
|
case PCCH_Config__nB_oneThirtySecondT:
|
||||||
|
N = T/32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* pcch_nB error */
|
||||||
|
LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n",
|
||||||
|
instance, pcch_nB);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
N = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert data to UE_PF_PO or update data in UE_PF_PO */
|
||||||
|
pthread_mutex_lock(&ue_pf_po_mutex);
|
||||||
|
uint8_t i = 0;
|
||||||
|
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||||
|
if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value))
|
||||||
|
|| (UE_PF_PO[CC_id][i].enable_flag != TRUE)) {
|
||||||
|
/* set T = min(Tc,Tue) */
|
||||||
|
UE_PF_PO[CC_id][i].T = T;
|
||||||
|
/* set UE_ID */
|
||||||
|
UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value;
|
||||||
|
/* calculate PF and PO */
|
||||||
|
/* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */
|
||||||
|
UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
|
||||||
|
/* set PO */
|
||||||
|
/* i_s = floor(UE_ID/N) mod Ns */
|
||||||
|
i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
|
||||||
|
if (Ns == 1) {
|
||||||
|
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0;
|
||||||
|
} else if (Ns==2) {
|
||||||
|
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s);
|
||||||
|
} else if (Ns==4) {
|
||||||
|
UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1)));
|
||||||
|
}
|
||||||
|
if (UE_PF_PO[CC_id][i].enable_flag == TRUE) {
|
||||||
|
//paging exist UE log
|
||||||
|
LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
|
||||||
|
} else {
|
||||||
|
/* set enable_flag */
|
||||||
|
UE_PF_PO[CC_id][i].enable_flag = TRUE;
|
||||||
|
//paging new UE log
|
||||||
|
LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&ue_pf_po_mutex);
|
||||||
|
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t buffer[RRC_BUF_SIZE];
|
||||||
|
uint8_t *message_buffer;
|
||||||
|
/* Transfer data to PDCP */
|
||||||
|
MessageDef *message_p;
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ);
|
||||||
|
/* Create message for PDCP (DLInformationTransfer_t) */
|
||||||
|
length = do_Paging (instance,
|
||||||
|
buffer,
|
||||||
|
S1AP_PAGING_IND(msg_p).ue_paging_identity,
|
||||||
|
S1AP_PAGING_IND(msg_p).cn_domain);
|
||||||
|
message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length);
|
||||||
|
/* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
|
||||||
|
memcpy (message_buffer, buffer, length);
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).sdu_size = length;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).ue_index = i;
|
||||||
|
RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id;
|
||||||
|
LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length);
|
||||||
|
itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
# endif /* defined(ENABLE_ITTI) */
|
# endif /* defined(ENABLE_ITTI) */
|
||||||
#endif /* defined(ENABLE_USE_MME) */
|
#endif /* defined(ENABLE_USE_MME) */
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
|
|||||||
const uint8_t ho_state
|
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)
|
/*! \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.
|
*\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 );
|
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)
|
/*! \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.
|
*\brief process a S1AP_UE_CTXT_MODIFICATION_REQ message received from S1AP.
|
||||||
*\param msg_p Message received by RRC.
|
*\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);
|
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
|
||||||
# endif /* defined(ENABLE_USE_MME) */
|
# endif /* defined(ENABLE_USE_MME) */
|
||||||
#endif /* RRC_ENB_S1AP_H_ */
|
#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));
|
memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s));
|
||||||
new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP);
|
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;
|
return new_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +155,21 @@ rrc_eNB_get_ue_context(
|
|||||||
memset(&temp, 0, sizeof(struct rrc_eNB_ue_context_s));
|
memset(&temp, 0, sizeof(struct rrc_eNB_ue_context_s));
|
||||||
/* eNB ue rrc id = 24 bits wide */
|
/* eNB ue rrc id = 24 bits wide */
|
||||||
temp.ue_id_rnti = rntiP;
|
temp.ue_id_rnti = rntiP;
|
||||||
|
#if 0
|
||||||
return RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
|
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);
|
rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP);
|
||||||
uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid);
|
uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid);
|
||||||
free(ue_context_pP);
|
free(ue_context_pP);
|
||||||
|
rrc_instance_pP->Nb_ue --;
|
||||||
LOG_I(RRC,
|
LOG_I(RRC,
|
||||||
PROTOCOL_RRC_CTXT_UE_FMT" Removed UE context\n",
|
PROTOCOL_RRC_CTXT_UE_FMT" Removed UE context\n",
|
||||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
|
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include "COMMON/mac_rrc_primitives.h"
|
#include "COMMON/mac_rrc_primitives.h"
|
||||||
#include "LAYER2/MAC/defs.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;
|
UE_RRC_INST *UE_rrc_inst;
|
||||||
#include "LAYER2/MAC/extern.h"
|
#include "LAYER2/MAC/extern.h"
|
||||||
#define MAX_U32 0xFFFFFFFF
|
#define MAX_U32 0xFFFFFFFF
|
||||||
@@ -236,4 +238,10 @@ float RSRQ_meas_mapping[35] = {
|
|||||||
-2
|
-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
|
#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 = 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_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->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;
|
create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -808,7 +809,88 @@ gtpv1u_create_s1u_tunnel(
|
|||||||
return 0;
|
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 **)>pv1u_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**)>pv1u_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(
|
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,
|
const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP,
|
||||||
gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_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_ */
|
#endif /* GTPV1U_ENB_TASK_H_ */
|
||||||
|
|||||||
@@ -364,6 +364,12 @@ void *s1ap_eNB_task(void *arg)
|
|||||||
&S1AP_E_RAB_SETUP_RESP(received_msg));
|
&S1AP_E_RAB_SETUP_RESP(received_msg));
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case S1AP_NAS_NON_DELIVERY_IND: {
|
||||||
s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||||
@@ -397,6 +403,12 @@ void *s1ap_eNB_task(void *arg)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
S1AP_ERROR("Received unhandled message: %d:%s\n",
|
S1AP_ERROR("Received unhandled message: %d:%s\n",
|
||||||
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
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(
|
ret = s1ap_decode_s1ap_pagingies(
|
||||||
&message->msg.s1ap_PagingIEs, &initiating_p->value);
|
&message->msg.s1ap_PagingIEs, &initiating_p->value);
|
||||||
s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message);
|
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);
|
free(message_string);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -128,12 +136,36 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
|
|||||||
free(message_string);
|
free(message_string);
|
||||||
S1AP_INFO("E_RABSetup initiating message\n");
|
S1AP_INFO("E_RABSetup initiating message\n");
|
||||||
break;
|
break;
|
||||||
case S1ap_ProcedureCode_id_E_RABRelease:
|
|
||||||
ret = s1ap_decode_s1ap_e_rabreleasecommandies(&message->msg.s1ap_E_RABReleaseCommandIEs,
|
case S1ap_ProcedureCode_id_E_RABModify:
|
||||||
&initiating_p->value);
|
ret = s1ap_decode_s1ap_e_rabmodifyrequesties(
|
||||||
//s1ap_xer_print_s1ap_e_rabsetuprequest(s1ap_xer__print2sp, message_string, message);
|
&message->msg.s1ap_E_RABModifyRequestIEs, &initiating_p->value);
|
||||||
S1AP_INFO("TODO E_RABRelease nitiating message\n");
|
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);
|
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_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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -100,6 +100,16 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t *E_RABSet
|
|||||||
uint8_t **buffer,
|
uint8_t **buffer,
|
||||||
uint32_t *length);
|
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)
|
int s1ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len)
|
||||||
{
|
{
|
||||||
DevAssert(message != NULL);
|
DevAssert(message != NULL);
|
||||||
@@ -264,6 +274,32 @@ int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p,
|
|||||||
free(message_string);
|
free(message_string);
|
||||||
S1AP_INFO("E_RABSetup successful message\n");
|
S1AP_INFO("E_RABSetup successful message\n");
|
||||||
break;
|
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:
|
default:
|
||||||
S1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
|
S1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||||
(int)s1ap_message_p->procedureCode);
|
(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,
|
&asn_DEF_S1ap_E_RABSetupResponse,
|
||||||
e_rab_setup_response_p);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -81,6 +81,20 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
|||||||
uint32_t stream,
|
uint32_t stream,
|
||||||
struct s1ap_message_s *s1ap_message_p);
|
struct s1ap_message_s *s1ap_message_p);
|
||||||
|
|
||||||
|
static
|
||||||
|
int s1ap_eNB_handle_paging(uint32_t assoc_id,
|
||||||
|
uint32_t stream,
|
||||||
|
struct s1ap_message_s *message_p);
|
||||||
|
|
||||||
|
static
|
||||||
|
int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
|
||||||
|
uint32_t stream,
|
||||||
|
struct s1ap_message_s *s1ap_message_p);
|
||||||
|
|
||||||
|
static
|
||||||
|
int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
|
||||||
|
uint32_t stream,
|
||||||
|
struct s1ap_message_s *s1ap_message_p);
|
||||||
|
|
||||||
/* Handlers matrix. Only eNB related procedure present here */
|
/* Handlers matrix. Only eNB related procedure present here */
|
||||||
s1ap_message_decoded_callback messages_callback[][3] = {
|
s1ap_message_decoded_callback messages_callback[][3] = {
|
||||||
@@ -90,11 +104,11 @@ s1ap_message_decoded_callback messages_callback[][3] = {
|
|||||||
{ 0, 0, 0 }, /* PathSwitchRequest */
|
{ 0, 0, 0 }, /* PathSwitchRequest */
|
||||||
{ 0, 0, 0 }, /* HandoverCancel */
|
{ 0, 0, 0 }, /* HandoverCancel */
|
||||||
{ s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */
|
{ s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */
|
||||||
{ 0, 0, 0 }, /* E_RABModify */
|
{ s1ap_eNB_handle_e_rab_modify_request, 0, 0 }, /* E_RABModify */
|
||||||
{ 0, 0, 0 }, /* E_RABRelease */
|
{ s1ap_eNB_handle_e_rab_release_command, 0, 0 }, /* E_RABRelease */
|
||||||
{ 0, 0, 0 }, /* E_RABReleaseIndication */
|
{ 0, 0, 0 }, /* E_RABReleaseIndication */
|
||||||
{ s1ap_eNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */
|
{ s1ap_eNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */
|
||||||
{ 0, 0, 0 }, /* Paging */
|
{ s1ap_eNB_handle_paging, 0, 0 }, /* Paging */
|
||||||
{ s1ap_eNB_handle_nas_downlink, 0, 0 }, /* downlinkNASTransport */
|
{ s1ap_eNB_handle_nas_downlink, 0, 0 }, /* downlinkNASTransport */
|
||||||
{ 0, 0, 0 }, /* initialUEMessage */
|
{ 0, 0, 0 }, /* initialUEMessage */
|
||||||
{ 0, 0, 0 }, /* uplinkNASTransport */
|
{ 0, 0, 0 }, /* uplinkNASTransport */
|
||||||
@@ -950,7 +964,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
|||||||
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL;
|
S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL;
|
||||||
|
|
||||||
S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n");
|
S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n");
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the transport layer address */
|
/* Set the transport layer address */
|
||||||
@@ -983,4 +997,382 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int s1ap_eNB_handle_paging(uint32_t assoc_id,
|
||||||
|
uint32_t stream,
|
||||||
|
struct s1ap_message_s *s1ap_message_p)
|
||||||
|
{
|
||||||
|
S1ap_PagingIEs_t *paging_p;
|
||||||
|
s1ap_eNB_mme_data_t *mme_desc_p = NULL;
|
||||||
|
s1ap_eNB_instance_t *s1ap_eNB_instance = NULL;
|
||||||
|
MessageDef *message_p = NULL;
|
||||||
|
|
||||||
|
DevAssert(s1ap_message_p != NULL);
|
||||||
|
// received Paging Message from MME
|
||||||
|
S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id);
|
||||||
|
|
||||||
|
paging_p = &s1ap_message_p->msg.s1ap_PagingIEs;
|
||||||
|
|
||||||
|
/* Paging procedure -> stream != 0 */
|
||||||
|
if (stream == 0) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging procedure on stream (%d)\n",
|
||||||
|
assoc_id, stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging for non "
|
||||||
|
"existing MME context\n", assoc_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance;
|
||||||
|
if (s1ap_eNB_instance == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging for non existing MME context : s1ap_eNB_instance is NULL\n",
|
||||||
|
assoc_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PAGING_IND);
|
||||||
|
|
||||||
|
/* convert S1ap_PagingIEs_t to s1ap_paging_ind_t */
|
||||||
|
/* convert UE Identity Index value */
|
||||||
|
S1AP_PAGING_IND(message_p).ue_index_value = BIT_STRING_to_uint32(&paging_p->ueIdentityIndexValue);
|
||||||
|
S1AP_DEBUG("[SCTP %d] Received Paging ue_index_value (%d)\n",
|
||||||
|
assoc_id,(uint32_t)S1AP_PAGING_IND(message_p).ue_index_value);
|
||||||
|
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0;
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0;
|
||||||
|
|
||||||
|
/* convert UE Paging Identity */
|
||||||
|
if (paging_p->uePagingID.present == S1ap_UEPagingID_PR_s_TMSI) {
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_s_tmsi;
|
||||||
|
OCTET_STRING_TO_INT8(&paging_p->uePagingID.choice.s_TMSI.mMEC, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code);
|
||||||
|
OCTET_STRING_TO_INT32(&paging_p->uePagingID.choice.s_TMSI.m_TMSI, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi);
|
||||||
|
} else if (paging_p->uePagingID.present == S1ap_UEPagingID_PR_iMSI) {
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_imsi;
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length = 0;
|
||||||
|
for (int i = 0; i < paging_p->uePagingID.choice.iMSI.size; i++) {
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i] = (uint8_t)(paging_p->uePagingID.choice.iMSI.buf[i] & 0x0F );
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++;
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] = (uint8_t)((paging_p->uePagingID.choice.iMSI.buf[i]>>4) & 0x0F);
|
||||||
|
LOG_D(S1AP,"paging : i %d %d imsi %d %d \n",2*i,2*i+1,S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1]);
|
||||||
|
if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] == 0x0F) {
|
||||||
|
if(i != paging_p->uePagingID.choice.iMSI.size - 1){
|
||||||
|
/* invalid paging_p->uePagingID.choise.iMSI.buffer */
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) {
|
||||||
|
/* invalid paging_p->uePagingID.choise.iMSI.size */
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* invalid paging_p->uePagingID.present */
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, paging_p->uePagingID.present);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* convert Paging DRX(optional) */
|
||||||
|
if (paging_p->presenceMask & S1AP_PAGINGIES_PAGINGDRX_PRESENT) {
|
||||||
|
switch(paging_p->pagingDRX) {
|
||||||
|
case S1ap_PagingDRX_v32:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_32;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingDRX_v64:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_64;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingDRX_v128:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_128;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingDRX_v256:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// when UE Paging DRX is no value
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
|
||||||
|
|
||||||
|
/* convert cnDomain */
|
||||||
|
if (paging_p->cnDomain == S1ap_CNDomain_ps) {
|
||||||
|
S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_PS;
|
||||||
|
} else if (paging_p->cnDomain == S1ap_CNDomain_cs) {
|
||||||
|
S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_CS;
|
||||||
|
} else {
|
||||||
|
/* invalid paging_p->cnDomain */
|
||||||
|
S1AP_ERROR("[SCTP %d] Received Paging : cnDomain(%ld) is unknown\n", assoc_id, paging_p->cnDomain);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&S1AP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256);
|
||||||
|
memset (&S1AP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256);
|
||||||
|
S1AP_PAGING_IND(message_p).tai_size = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < paging_p->taiList.s1ap_TAIItem.count; i++) {
|
||||||
|
S1AP_INFO("[SCTP %d] Received Paging taiList: i %d, count %d\n", assoc_id, i, paging_p->taiList.s1ap_TAIItem.count);
|
||||||
|
S1ap_TAIItem_t s1ap_TAIItem;
|
||||||
|
memset (&s1ap_TAIItem, 0, sizeof(S1ap_TAIItem_t));
|
||||||
|
|
||||||
|
memcpy(&s1ap_TAIItem, paging_p->taiList.s1ap_TAIItem.array[i], sizeof(S1ap_TAIItem_t));
|
||||||
|
|
||||||
|
TBCD_TO_MCC_MNC(&s1ap_TAIItem.tAI.pLMNidentity, S1AP_PAGING_IND(message_p).plmn_identity[i].mcc,
|
||||||
|
S1AP_PAGING_IND(message_p).plmn_identity[i].mnc,
|
||||||
|
S1AP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length);
|
||||||
|
OCTET_STRING_TO_INT16(&s1ap_TAIItem.tAI.tAC, S1AP_PAGING_IND(message_p).tac[i]);
|
||||||
|
S1AP_PAGING_IND(message_p).tai_size++;
|
||||||
|
S1AP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, S1AP_PAGING_IND(message_p).tac[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// CSG Id(optional) List is not used
|
||||||
|
if (paging_p->presenceMask & S1AP_PAGINGIES_CSG_IDLIST_PRESENT) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert pagingPriority (optional) if has value */
|
||||||
|
if (paging_p->presenceMask & S1AP_PAGINGIES_PAGINGPRIORITY_PRESENT) {
|
||||||
|
switch(paging_p->pagingPriority) {
|
||||||
|
case S1ap_PagingPriority_priolevel1:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL1;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel2:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL2;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel3:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL3;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel4:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL4;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel5:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL5;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel6:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL6;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel7:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL7;
|
||||||
|
break;
|
||||||
|
case S1ap_PagingPriority_priolevel8:
|
||||||
|
S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* invalid paging_p->pagingPriority */
|
||||||
|
S1AP_ERROR("[SCTP %d] Received paging : pagingPriority(%ld) is invalid\n", assoc_id, paging_p->pagingPriority);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//paging parameter values
|
||||||
|
S1AP_DEBUG("[SCTP %d] Received Paging parameters: ue_index_value %d cn_domain %d paging_drx %d paging_priority %d\n",assoc_id,
|
||||||
|
S1AP_PAGING_IND(message_p).ue_index_value, S1AP_PAGING_IND(message_p).cn_domain,
|
||||||
|
S1AP_PAGING_IND(message_p).paging_drx, S1AP_PAGING_IND(message_p).paging_priority);
|
||||||
|
S1AP_DEBUG("[SCTP %d] Received Paging parameters(ue): presenceMask %d s_tmsi.m_tmsi %d s_tmsi.mme_code %d IMSI length %d (0-5) %d%d%d%d%d%d\n",assoc_id,
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi,
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length,
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[0], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[1],
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[3],
|
||||||
|
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[4], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[5]);
|
||||||
|
|
||||||
|
/* send message to RRC */
|
||||||
|
itti_send_msg_to_task(TASK_RRC_ENB, s1ap_eNB_instance->instance, message_p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
|
||||||
|
uint32_t stream,
|
||||||
|
struct s1ap_message_s *s1ap_message_p) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
s1ap_eNB_mme_data_t *mme_desc_p = NULL;
|
||||||
|
s1ap_eNB_ue_context_t *ue_desc_p = NULL;
|
||||||
|
MessageDef *message_p = NULL;
|
||||||
|
int nb_of_e_rabs_failed = 0;
|
||||||
|
|
||||||
|
S1ap_E_RABModifyRequestIEs_t *s1ap_E_RABModifyRequest;
|
||||||
|
DevAssert(s1ap_message_p != NULL);
|
||||||
|
|
||||||
|
s1ap_E_RABModifyRequest = &s1ap_message_p->msg.s1ap_E_RABModifyRequestIEs;
|
||||||
|
|
||||||
|
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non "
|
||||||
|
"existing MME context\n", assoc_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
|
||||||
|
s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID)) == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non "
|
||||||
|
"existing UE context 0x%06lx\n", assoc_id,
|
||||||
|
s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* E-RAB modify request = UE-related procedure -> stream != 0 */
|
||||||
|
if (stream == 0) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||||
|
assoc_id, stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ue_desc_p->rx_stream = stream;
|
||||||
|
|
||||||
|
if ( ue_desc_p->mme_ue_s1ap_id != s1ap_E_RABModifyRequest->mme_ue_s1ap_id){
|
||||||
|
S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
|
||||||
|
ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABModifyRequest->mme_ue_s1ap_id);
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (message_p).eNB_ue_s1ap_id = s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID;
|
||||||
|
// S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB];
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (message_p).nb_of_e_rabs = 0;
|
||||||
|
|
||||||
|
for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count; nb_of_e_rabs_failed++) {
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
|
||||||
|
((S1ap_E_RABToBeModifiedItemBearerModReq_t *)s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.array[nb_of_e_rabs_failed])->e_RAB_ID;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = 13;//S1ap_CauseRadioNetwork_unknown_mme_ue_s1ap_id;
|
||||||
|
}
|
||||||
|
S1AP_E_RAB_MODIFY_RESP (message_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
|
||||||
|
|
||||||
|
s1ap_eNB_e_rab_modify_resp(mme_desc_p->s1ap_eNB_instance->instance,
|
||||||
|
&S1AP_E_RAB_MODIFY_RESP(message_p));
|
||||||
|
|
||||||
|
message_p = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_MODIFY_REQ);
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).mme_ue_s1ap_id = s1ap_E_RABModifyRequest->mme_ue_s1ap_id;
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).eNB_ue_s1ap_id = s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID;
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).nb_e_rabs_tomodify =
|
||||||
|
s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count;
|
||||||
|
|
||||||
|
for (i = 0; i < s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count; i++) {
|
||||||
|
S1ap_E_RABToBeModifiedItemBearerModReq_t *item_p;
|
||||||
|
|
||||||
|
item_p = (S1ap_E_RABToBeModifiedItemBearerModReq_t *)s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.array[i];
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].e_rab_id = item_p->e_RAB_ID;
|
||||||
|
|
||||||
|
// check for the NAS PDU
|
||||||
|
if (item_p->nAS_PDU.size > 0 ) {
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = item_p->nAS_PDU.size;
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size);
|
||||||
|
|
||||||
|
memcpy(S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer,
|
||||||
|
item_p->nAS_PDU.buf, item_p->nAS_PDU.size);
|
||||||
|
} else {
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = 0;
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the QOS informations */
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.qci = item_p->e_RABLevelQoSParameters.qCI;
|
||||||
|
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.priority_level =
|
||||||
|
item_p->e_RABLevelQoSParameters.allocationRetentionPriority.priorityLevel;
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_capability =
|
||||||
|
item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
|
||||||
|
S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_vulnerability =
|
||||||
|
item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// handle e-rab release command and send it to rrc_end
|
||||||
|
static
|
||||||
|
int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
|
||||||
|
uint32_t stream,
|
||||||
|
struct s1ap_message_s *s1ap_message_p) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
s1ap_eNB_mme_data_t *mme_desc_p = NULL;
|
||||||
|
s1ap_eNB_ue_context_t *ue_desc_p = NULL;
|
||||||
|
MessageDef *message_p = NULL;
|
||||||
|
|
||||||
|
S1ap_E_RABReleaseCommandIEs_t *s1ap_E_RABReleaseCommand;
|
||||||
|
DevAssert(s1ap_message_p != NULL);
|
||||||
|
s1ap_E_RABReleaseCommand = &s1ap_message_p->msg.s1ap_E_RABReleaseCommandIEs;
|
||||||
|
|
||||||
|
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing MME context\n", assoc_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
|
||||||
|
s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID)) == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing UE context 0x%06lx\n", assoc_id,
|
||||||
|
s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initial context request = UE-related procedure -> stream != 0 */
|
||||||
|
if (stream == 0) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
|
||||||
|
assoc_id, stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ue_desc_p->rx_stream = stream;
|
||||||
|
|
||||||
|
if ( ue_desc_p->mme_ue_s1ap_id != s1ap_E_RABReleaseCommand->mme_ue_s1ap_id){
|
||||||
|
S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
|
||||||
|
ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABReleaseCommand->mme_ue_s1ap_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
S1AP_DEBUG("[SCTP %d] Received E-RAB release command for eNB_UE_S1AP_ID %ld mme_ue_s1ap_id %ld\n",
|
||||||
|
assoc_id, s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID, s1ap_E_RABReleaseCommand->mme_ue_s1ap_id);
|
||||||
|
|
||||||
|
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND);
|
||||||
|
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID;
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = s1ap_E_RABReleaseCommand->mme_ue_s1ap_id;
|
||||||
|
if(s1ap_E_RABReleaseCommand->nas_pdu.size > 0 ){
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = s1ap_E_RABReleaseCommand->nas_pdu.size;
|
||||||
|
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer =
|
||||||
|
malloc(sizeof(uint8_t) * s1ap_E_RABReleaseCommand->nas_pdu.size);
|
||||||
|
|
||||||
|
memcpy(S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer,
|
||||||
|
s1ap_E_RABReleaseCommand->nas_pdu.buf,
|
||||||
|
s1ap_E_RABReleaseCommand->nas_pdu.size);
|
||||||
|
} else {
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.count;
|
||||||
|
for(i=0; i < s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.count; i++){
|
||||||
|
S1ap_E_RABItem_t *item_p;
|
||||||
|
item_p = (S1ap_E_RABItem_t*)s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.array[i];
|
||||||
|
S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID;
|
||||||
|
S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -837,3 +837,282 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int s1ap_eNB_e_rab_modify_resp(instance_t instance,
|
||||||
|
s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p)
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||||
|
struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
|
||||||
|
|
||||||
|
S1ap_E_RABModifyResponseIEs_t *initial_ies_p = NULL;
|
||||||
|
|
||||||
|
s1ap_message message;
|
||||||
|
|
||||||
|
uint8_t *buffer = NULL;
|
||||||
|
uint32_t length;
|
||||||
|
int ret = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Retrieve the S1AP eNB instance associated with Mod_id */
|
||||||
|
s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
|
||||||
|
|
||||||
|
DevAssert(e_rab_modify_resp_p != NULL);
|
||||||
|
DevAssert(s1ap_eNB_instance_p != NULL);
|
||||||
|
|
||||||
|
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||||
|
e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) {
|
||||||
|
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||||
|
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
|
||||||
|
e_rab_modify_resp_p->eNB_ue_s1ap_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Uplink NAS transport can occur either during an s1ap connected state
|
||||||
|
* or during initial attach (for example: NAS authentication).
|
||||||
|
*/
|
||||||
|
if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED ||
|
||||||
|
ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) {
|
||||||
|
S1AP_WARN("You are attempting to send NAS data over non-connected "
|
||||||
|
"eNB ue s1ap id: %06x, current state: %d\n",
|
||||||
|
e_rab_modify_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the S1AP message to encode */
|
||||||
|
memset(&message, 0, sizeof(s1ap_message));
|
||||||
|
|
||||||
|
message.direction = S1AP_PDU_PR_successfulOutcome;
|
||||||
|
message.procedureCode = S1ap_ProcedureCode_id_E_RABModify;
|
||||||
|
message.criticality = S1ap_Criticality_reject;
|
||||||
|
|
||||||
|
initial_ies_p = &message.msg.s1ap_E_RABModifyResponseIEs;
|
||||||
|
|
||||||
|
initial_ies_p->eNB_UE_S1AP_ID = e_rab_modify_resp_p->eNB_ue_s1ap_id;
|
||||||
|
initial_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
|
||||||
|
|
||||||
|
if ( e_rab_modify_resp_p->nb_of_e_rabs >= 1 )
|
||||||
|
initial_ies_p->presenceMask |= S1AP_E_RABMODIFYRESPONSEIES_E_RABMODIFYLISTBEARERMODRES_PRESENT;
|
||||||
|
|
||||||
|
for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs; i++) {
|
||||||
|
S1ap_E_RABModifyItemBearerModRes_t *modify_item;
|
||||||
|
|
||||||
|
modify_item = calloc(1, sizeof(S1ap_E_RABModifyItemBearerModRes_t));
|
||||||
|
|
||||||
|
modify_item->e_RAB_ID = e_rab_modify_resp_p->e_rabs[i].e_rab_id;
|
||||||
|
|
||||||
|
S1AP_DEBUG("e_rab_modify_resp: modified e_rab ID %ld\n",
|
||||||
|
modify_item->e_RAB_ID);
|
||||||
|
|
||||||
|
S1ap_IE_t *ie = s1ap_new_ie(S1ap_ProtocolIE_ID_id_E_RABModifyItemBearerModRes,
|
||||||
|
S1ap_Criticality_ignore,
|
||||||
|
&asn_DEF_S1ap_E_RABModifyItemBearerModRes,
|
||||||
|
modify_item);
|
||||||
|
|
||||||
|
ASN_SEQUENCE_ADD(&initial_ies_p->e_RABModifyListBearerModRes.s1ap_E_RABModifyItemBearerModRes,
|
||||||
|
ie);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( e_rab_modify_resp_p->nb_of_e_rabs_failed >= 1 )
|
||||||
|
initial_ies_p->presenceMask |= S1AP_E_RABMODIFYRESPONSEIES_E_RABFAILEDTOMODIFYLIST_PRESENT;
|
||||||
|
|
||||||
|
for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs_failed; i++) {
|
||||||
|
S1ap_E_RABItem_t *failed_item;
|
||||||
|
|
||||||
|
failed_item = calloc(1, sizeof(S1ap_E_RABItem_t));
|
||||||
|
|
||||||
|
failed_item->e_RAB_ID = e_rab_modify_resp_p->e_rabs_failed[i].e_rab_id;
|
||||||
|
switch(e_rab_modify_resp_p->e_rabs_failed[i].cause)
|
||||||
|
{
|
||||||
|
case S1AP_CAUSE_RADIO_NETWORK:
|
||||||
|
failed_item->cause.present = S1ap_Cause_PR_radioNetwork;
|
||||||
|
failed_item->cause.choice.radioNetwork = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
case S1AP_CAUSE_TRANSPORT:
|
||||||
|
failed_item->cause.present = S1ap_Cause_PR_transport;
|
||||||
|
failed_item->cause.choice.transport = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
case S1AP_CAUSE_NAS:
|
||||||
|
failed_item->cause.present = S1ap_Cause_PR_nas;
|
||||||
|
failed_item->cause.choice.nas = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
case S1AP_CAUSE_PROTOCOL:
|
||||||
|
failed_item->cause.present = S1ap_Cause_PR_protocol;
|
||||||
|
failed_item->cause.choice.protocol = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
case S1AP_CAUSE_MISC:
|
||||||
|
failed_item->cause.present = S1ap_Cause_PR_misc;
|
||||||
|
failed_item->cause.choice.misc = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n",
|
||||||
|
failed_item->e_RAB_ID);
|
||||||
|
|
||||||
|
S1ap_IE_t *ie = s1ap_new_ie(S1ap_ProtocolIE_ID_id_E_RABItem,
|
||||||
|
S1ap_Criticality_ignore,
|
||||||
|
&asn_DEF_S1ap_E_RABItem,
|
||||||
|
failed_item);
|
||||||
|
|
||||||
|
ASN_SEQUENCE_ADD(&initial_ies_p->e_RABFailedToModifyList.s1ap_E_RABItem,
|
||||||
|
ie);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "start encode\n");
|
||||||
|
if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
|
||||||
|
S1AP_ERROR("Failed to encode uplink transport\n");
|
||||||
|
/* Encode procedure has failed... */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSC_LOG_TX_MESSAGE(
|
||||||
|
MSC_S1AP_ENB,
|
||||||
|
MSC_S1AP_MME,
|
||||||
|
(const char *)buffer,
|
||||||
|
length,
|
||||||
|
MSC_AS_TIME_FMT" E_RAN Modify successful Outcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
|
||||||
|
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||||
|
initial_ies_p->eNB_UE_S1AP_ID,
|
||||||
|
initial_ies_p->mme_ue_s1ap_id);
|
||||||
|
|
||||||
|
/* UE associated signalling -> use the allocated stream */
|
||||||
|
s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
|
||||||
|
ue_context_p->mme_ref->assoc_id, buffer,
|
||||||
|
length, ue_context_p->tx_stream);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int s1ap_eNB_e_rab_release_resp(instance_t instance,
|
||||||
|
s1ap_e_rab_release_resp_t *e_rab_release_resp_p)
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||||
|
struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
|
||||||
|
|
||||||
|
S1ap_E_RABReleaseResponseIEs_t *release_response_ies_p = NULL;
|
||||||
|
|
||||||
|
s1ap_message message;
|
||||||
|
|
||||||
|
uint8_t *buffer = NULL;
|
||||||
|
uint32_t length;
|
||||||
|
int ret = -1;
|
||||||
|
int i;
|
||||||
|
/* Retrieve the S1AP eNB instance associated with Mod_id */
|
||||||
|
s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
|
||||||
|
DevAssert(e_rab_release_resp_p != NULL);
|
||||||
|
DevAssert(s1ap_eNB_instance_p != NULL);
|
||||||
|
|
||||||
|
/* Prepare the S1AP message to encode */
|
||||||
|
memset(&message, 0, sizeof(s1ap_message));
|
||||||
|
|
||||||
|
message.direction = S1AP_PDU_PR_successfulOutcome;
|
||||||
|
message.procedureCode = S1ap_ProcedureCode_id_E_RABRelease;
|
||||||
|
message.criticality = S1ap_Criticality_ignore;
|
||||||
|
|
||||||
|
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||||
|
e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) {
|
||||||
|
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||||
|
S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n",
|
||||||
|
e_rab_release_resp_p->eNB_ue_s1ap_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_response_ies_p = &message.msg.s1ap_E_RABReleaseResponseIEs;
|
||||||
|
release_response_ies_p->eNB_UE_S1AP_ID = e_rab_release_resp_p->eNB_ue_s1ap_id;
|
||||||
|
release_response_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
|
||||||
|
|
||||||
|
if ( e_rab_release_resp_p->nb_of_e_rabs_released > 0 )
|
||||||
|
release_response_ies_p->presenceMask |= S1AP_E_RABRELEASERESPONSEIES_E_RABRELEASELISTBEARERRELCOMP_PRESENT;
|
||||||
|
|
||||||
|
//release
|
||||||
|
for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_released; i++) {
|
||||||
|
|
||||||
|
S1ap_E_RABReleaseItemBearerRelComp_t *new_item;
|
||||||
|
|
||||||
|
new_item = calloc(1, sizeof(S1ap_E_RABReleaseItemBearerRelComp_t));
|
||||||
|
|
||||||
|
new_item->e_RAB_ID = e_rab_release_resp_p->e_rab_release[i].e_rab_id;
|
||||||
|
|
||||||
|
S1AP_DEBUG("e_rab_release_resp: e_rab ID %ld\n",new_item->e_RAB_ID);
|
||||||
|
|
||||||
|
ASN_SEQUENCE_ADD(&release_response_ies_p->e_RABReleaseListBearerRelComp.s1ap_E_RABReleaseItemBearerRelComp,
|
||||||
|
new_item);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( e_rab_release_resp_p->nb_of_e_rabs_failed > 0 )
|
||||||
|
release_response_ies_p->presenceMask |= S1AP_E_RABRELEASERESPONSEIES_E_RABFAILEDTORELEASELIST_PRESENT;
|
||||||
|
|
||||||
|
//release failed
|
||||||
|
for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_failed; i++) {
|
||||||
|
S1ap_E_RABItem_t *new_rabitem;
|
||||||
|
new_rabitem = calloc(1, sizeof(S1ap_E_RABItem_t));
|
||||||
|
//e_rab_id
|
||||||
|
new_rabitem->e_RAB_ID = e_rab_release_resp_p->e_rabs_failed[i].e_rab_id;
|
||||||
|
//cause
|
||||||
|
switch(e_rab_release_resp_p->e_rabs_failed[i].cause)
|
||||||
|
{
|
||||||
|
case S1AP_CAUSE_NOTHING:
|
||||||
|
new_rabitem->cause.present = S1ap_Cause_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S1AP_CAUSE_RADIO_NETWORK:
|
||||||
|
new_rabitem->cause.present = S1ap_Cause_PR_radioNetwork;
|
||||||
|
new_rabitem->cause.choice.radioNetwork = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S1AP_CAUSE_TRANSPORT:
|
||||||
|
new_rabitem->cause.present = S1ap_Cause_PR_transport;
|
||||||
|
new_rabitem->cause.choice.transport = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S1AP_CAUSE_NAS:
|
||||||
|
new_rabitem->cause.present = S1ap_Cause_PR_nas;
|
||||||
|
new_rabitem->cause.choice.nas = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S1AP_CAUSE_PROTOCOL:
|
||||||
|
new_rabitem->cause.present = S1ap_Cause_PR_protocol;
|
||||||
|
new_rabitem->cause.choice.protocol = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S1AP_CAUSE_MISC:
|
||||||
|
default:
|
||||||
|
new_rabitem->cause.present = S1ap_Cause_PR_misc;
|
||||||
|
new_rabitem->cause.choice.misc = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
S1AP_DEBUG("e_rab_release_resp: failed e_rab ID %ld\n",new_rabitem->e_RAB_ID);
|
||||||
|
ASN_SEQUENCE_ADD(&release_response_ies_p->e_RABFailedToReleaseList.s1ap_E_RABItem, new_rabitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "start encode\n");
|
||||||
|
if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
|
||||||
|
S1AP_ERROR("Failed to encode release response\n");
|
||||||
|
/* Encode procedure has failed... */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSC_LOG_TX_MESSAGE(
|
||||||
|
MSC_S1AP_ENB,
|
||||||
|
MSC_S1AP_MME,
|
||||||
|
(const char *)buffer,
|
||||||
|
length,
|
||||||
|
MSC_AS_TIME_FMT" E_RAN Release successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
|
||||||
|
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||||
|
e_rab_release_resp_p->eNB_ue_s1ap_id,
|
||||||
|
ue_context_p->mme_ue_s1ap_id);
|
||||||
|
|
||||||
|
/* UE associated signalling -> use the allocated stream */
|
||||||
|
s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
|
||||||
|
ue_context_p->mme_ref->assoc_id, buffer,
|
||||||
|
length, ue_context_p->tx_stream);
|
||||||
|
|
||||||
|
S1AP_INFO("e_rab_release_response sended eNB_UE_S1AP_ID %d mme_ue_s1ap_id %d nb_of_e_rabs_released %d nb_of_e_rabs_failed %d\n",
|
||||||
|
e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,e_rab_release_resp_p->nb_of_e_rabs_released,e_rab_release_resp_p->nb_of_e_rabs_failed);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,4 +44,9 @@ int s1ap_eNB_ue_capabilities(instance_t instance,
|
|||||||
int s1ap_eNB_e_rab_setup_resp(instance_t instance,
|
int s1ap_eNB_e_rab_setup_resp(instance_t instance,
|
||||||
s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p);
|
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_ */
|
#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
|
#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_
|
#define SECU_DEFS_H_
|
||||||
|
|
||||||
#include "security_types.h"
|
#include "security_types.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define EIA0_ALG_ID 0x00
|
#define EIA0_ALG_ID 0x00
|
||||||
#define EIA1_128_ALG_ID 0x01
|
#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(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,
|
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);
|
const uint8_t kasme[32], uint8_t *knas);
|
||||||
|
|
||||||
|
|||||||
@@ -1188,6 +1188,10 @@ int main( int argc, char **argv )
|
|||||||
RCconfig_L1();
|
RCconfig_L1();
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||||
@@ -1457,7 +1461,7 @@ int main( int argc, char **argv )
|
|||||||
pthread_cond_destroy(&nfapi_sync_cond);
|
pthread_cond_destroy(&nfapi_sync_cond);
|
||||||
pthread_mutex_destroy(&nfapi_sync_mutex);
|
pthread_mutex_destroy(&nfapi_sync_mutex);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&ue_pf_po_mutex);
|
||||||
|
|
||||||
// *** Handle per CC_id openair0
|
// *** Handle per CC_id openair0
|
||||||
if (UE_flag==1) {
|
if (UE_flag==1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user