Commit dc14cdc6 authored by Javier Morgade's avatar Javier Morgade

*L2 procedures to enable mixed unicast/broadcast operation at ENB implemeted:

	-MBMS scheduler developed (oneFrame allocations implemented at this time)
	-UE DSLCH schedulers updated: if an eMBMS session running UE DTCH, DCCH will be only scheduled at non MBSFN sufbframes
	-eMBMS L2 procedures implemented
	-Dedicated MBMS PDCP pipes src/sink enabled (only for TUN)
	-BUGFIX eMBMS MAC procedures (wrong indexing at few loops)
	-ENB FAPI updated to enable dynamic MBSFN configurations through M2AP (RRC<->MCE)

	ACKNOWLEDGEMENT:
 	1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS"
 	2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu)
Signed-off-by: default avatarJavier Morgade <javier.morgade@ieee.org>
parent bcf42ca2
......@@ -53,6 +53,7 @@
#include "LTE_MBSFN-AreaInfoList-r9.h"
#include "LTE_MBSFN-AreaInfo-r9.h"
#include "LTE_MBSFN-SubframeConfigList.h"
#include "LTE_MBSFN-SubframeConfig.h"
#include "LTE_PMCH-InfoList-r9.h"
......@@ -633,6 +634,123 @@ config_sib2(int Mod_idP,
#endif
}
void
config_sib2_mbsfn_part( int Mod_idP,
int CC_idP,
struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) {
//LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_idP][CC_idP]->frame_parms;
//int i;
//if(mbsfn_SubframeConfigListP != NULL) {
// fp->num_MBSFN_config = mbsfn_SubframeConfigListP->list.count;
// for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) {
// fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod;
// fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset;
// if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
// fp->MBSFN_config[i].fourFrames_flag = 0;
// fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
// LOG_I (PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig);
// } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
// fp->MBSFN_config[i].fourFrames_flag = 1;
// fp->MBSFN_config[i].mbsfn_SubframeConfig =
// mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
// (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
// (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
// LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i,
// fp->MBSFN_config[i].mbsfn_SubframeConfig);
// }
// }
//} else
// fp->num_MBSFN_config = 0;
PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP;
phycfg.CC_id = CC_idP;
phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP];
int i;
if(mbsfn_SubframeConfigListP != NULL) {
phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = mbsfn_SubframeConfigListP->list.count;
for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) {
phycfg.cfg->embms_mbsfn_config.radioframe_allocation_period[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod;
phycfg.cfg->embms_mbsfn_config.radioframe_allocation_offset[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset;
if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 0;
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
} else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 1;
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] =
mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
(mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
(mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i,
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
}
}
phycfg.cfg->num_tlv++;
} else{
phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = 0;
phycfg.cfg->num_tlv++;
}
phycfg.cfg->embms_mbsfn_config.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_TAG;
if (RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req) RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req(&phycfg);
}
void
config_sib13( int Mod_id,
int CC_id,
int mbsfn_Area_idx,
long mbsfn_AreaId_r9){
//nfapi_config_request_t *cfg = &RC.mac[Mod_id]->config[CC_id];
//work around until PHY_config_re "update" mechanisms get defined
// LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
// LOG_I (MAC, "[eNB%d] Applying MBSFN_Area_id %ld for index %d\n", Mod_id, mbsfn_AreaId_r9, mbsfn_Area_idx);
//
// AssertFatal(mbsfn_Area_idx == 0, "Fix me: only called when mbsfn_Area_idx == 0\n");
// if (mbsfn_Area_idx == 0) {
// fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9;
// LOG_I(MAC,"Fix me: only called when mbsfn_Area_idx == 0)\n");
// }
// lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn);
//
//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
// lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn);
//#endif
//
PHY_Config_t phycfg;
phycfg.Mod_id = Mod_id;
phycfg.CC_id = CC_id;
phycfg.cfg = &RC.mac[Mod_id]->config[CC_id];
phycfg.cfg->embms_sib13_config.mbsfn_area_idx.value = (uint8_t)mbsfn_Area_idx;
phycfg.cfg->embms_sib13_config.mbsfn_area_idx.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG;
phycfg.cfg->num_tlv++;
phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.value = (uint32_t)mbsfn_AreaId_r9;
phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG;
phycfg.cfg->num_tlv++;
if (RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req) RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req(&phycfg);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
}
void
config_dedicated(int Mod_idP,
int CC_idP,
......@@ -878,6 +996,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag;
#endif
config_sib2_mbsfn_part(Mod_idP,0,mbsfn_SubframeConfigList);
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
......@@ -925,6 +1045,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_idP,i,
RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
// config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
}
......@@ -954,6 +1075,10 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i,
RC.mac[Mod_idP]->common_channels[0].
mbms_SessionList[i]->list.count);
for(int ii=0; ii < RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.count;ii++){
LOG_I(MAC, "PMCH[%d] MBMS Session[%d] is: %lu\n", i,ii,
RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.array[ii]->logicalChannelIdentity_r9);
}
}
}
......
......@@ -162,7 +162,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
phy_config_sib2_ue(Mod_idP, 0, eNB_index,
radioResourceConfigCommon, ul_CarrierFreq,
ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
NULL/*mbsfn_SubframeConfigList*/);
}
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
......@@ -513,6 +513,9 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
}
if (mbsfn_SubframeConfigList != NULL) {
phy_config_mbsfn_list_ue(Mod_idP, 0,
mbsfn_SubframeConfigList);
LOG_I(MAC,
"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
......
......@@ -327,7 +327,7 @@ typedef struct {
/*!\brief DTCH DRB1 logical channel */
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
#define MCCH 4
#define MCCH 11
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
......
......@@ -64,7 +64,8 @@
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
//#define MCCH 4
#define MCCH 62
//#define MCCH 62
#define MCCH 11
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
......
......@@ -931,6 +931,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP);
pdcp_run(&ctxt);
pdcp_mbms_run(&ctxt);
rrc_rx_tx(&ctxt, CC_id);
#endif
......
......@@ -506,6 +506,13 @@ schedule_ue_spec(module_id_t module_idP,
rrc_eNB_ue_context_t *ue_contextP = NULL;
int nb_mac_CC = RC.nb_mac_CC[module_idP];
long dl_Bandwidth;
if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){
//LOG_E(MAC,"Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP);
return ;
}
start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
VCD_FUNCTION_IN);
......
......@@ -855,6 +855,12 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
#ifdef DEBUG_eNB_SCHEDULER
int k;
#endif
if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){
//LOG_E(MAC,"fairRR Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP);
return;
}
start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
......
This diff is collapsed.
......@@ -424,8 +424,8 @@ typedef struct {
#define BCCH_SI_BR 7 // SI-BR
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/*!\brief Values of BCCH SIB1_BR logical channel (fake) */
#define BCCH_SIB1_MBMS 60 // SIB1_MBMS //TODO better armonize index
#define BCCH_SI_MBMS 61 // SIB_MBMS //TODO better armonize index
#define BCCH_SIB1_MBMS 12 // SIB1_MBMS //TODO better armonize index
#define BCCH_SI_MBMS 13 // SIB_MBMS //TODO better armonize index
#endif
/*!\brief Value of CCCH / SRB0 logical channel */
#define CCCH 0 // srb0
......@@ -437,7 +437,8 @@ typedef struct {
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
//#define MCCH 4
#define MCCH 62
//#define MCCH 62
#define MCCH 11
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
......
......@@ -73,6 +73,8 @@ extern UL_IND_t *UL_INFO;
extern int next_ra_frame;
extern module_id_t next_Mod_id;
int mbms_rab_id = 2047;
/*
*
#ifndef USER_MODE
......@@ -828,6 +830,9 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) {
LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j);
//This sucks I know ... workaround !
mbms_rab_id = rx_lcids[i];
//end sucks :-(
mac_rlc_data_ind(
module_idP,
UE_mac_inst[module_idP].crnti,
......@@ -1132,6 +1137,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i
int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) {
int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1;
int l =0;
int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
long mch_scheduling_period = -1;
uint8_t mch_lcid = 0;
......@@ -1383,28 +1389,39 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
// Acount for sf_allocable in CSA
int num_sf_alloc = 0;
for (i = 0; i < 8; i++) {
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL)
for (l = 0; l < 8; l++) {
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
continue;
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
continue;
uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0];
uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0];
for (j = 0; j < 6; j++)
num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j));
}
for (i = 0; i < 28; i++) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) {
if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL)
for (l = 0; l < 28; l++) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= num_sf_alloc) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[l] != 2047) {
if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL){
mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationPeriod;
long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
if(UE_mac_inst[module_idP].common_num_sf_alloc >= UE_mac_inst[module_idP].pmch_stop_mtch[l]){
//LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);
mtch_mcs = -1;
}
UE_mac_inst[module_idP].common_num_sf_alloc++;
UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);
}
else
mtch_mcs = -1;
mch_lcid = (uint8_t)i;
mch_lcid = (uint8_t)l;
break;
}
}
......@@ -1413,7 +1430,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
// sf allocation is non-overlapping
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag);
module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag);
*sync_area=i;
break;
}
......
......@@ -966,15 +966,15 @@ pdcp_data_ind(
#ifdef MBMS_MULTICAST_OUT
if ((MBMS_flagP != 0) && (mbms_socket != -1)) {
struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset];
struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)];
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = udp_header->dest;
dest_addr.sin_addr.s_addr = ip_header->daddr;
// struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset];
// struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)];
// struct sockaddr_in dest_addr;
// dest_addr.sin_family = AF_INET;
// dest_addr.sin_port = udp_header->dest;
// dest_addr.sin_addr.s_addr = ip_header->daddr;
sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
//packet_forwarded = TRUE;
// sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
// //packet_forwarded = TRUE;
}
......@@ -1250,6 +1250,131 @@ pdcp_run (
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT);
}
//-----------------------------------------------------------------------------
void
pdcp_mbms_run (
const protocol_ctxt_t *const ctxt_pP
)
//-----------------------------------------------------------------------------
{
// if (ctxt_pP->enb_flag) {
// start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// } else {
// start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// }
// pdcp_enb[ctxt_pP->module_id].sfn++; // range: 0 to 18,446,744,073,709,551,615
// pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023
// pdcp_enb[ctxt_pP->module_id].subframe= ctxt_pP->subframe;
// pdcp_update_stats(ctxt_pP);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN);
// MessageDef *msg_p;
//int result;
//protocol_ctxt_t ctxt;
// do {
// // Checks if a message has been sent to PDCP sub-task
// itti_poll_msg (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
//
// if (msg_p != NULL) {
// switch (ITTI_MSG_ID(msg_p)) {
// case RRC_DCCH_DATA_REQ:
// PROTOCOL_CTXT_SET_BY_MODULE_ID(
// &ctxt,
// RRC_DCCH_DATA_REQ (msg_p).module_id,
// RRC_DCCH_DATA_REQ (msg_p).enb_flag,
// RRC_DCCH_DATA_REQ (msg_p).rnti,
// RRC_DCCH_DATA_REQ (msg_p).frame,
// 0,
// RRC_DCCH_DATA_REQ (msg_p).eNB_index);
// LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
// PROTOCOL_CTXT_ARGS(&ctxt),
// ITTI_MSG_NAME (msg_p),
// ITTI_MSG_ORIGIN_NAME(msg_p),
// ITTI_MSG_INSTANCE (msg_p),
// RRC_DCCH_DATA_REQ (msg_p).rb_id,
// RRC_DCCH_DATA_REQ (msg_p).muip,
// RRC_DCCH_DATA_REQ (msg_p).confirmp,
// RRC_DCCH_DATA_REQ (msg_p).mode);
// LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id);
// result = pdcp_data_req (&ctxt,
// SRB_FLAG_YES,
// RRC_DCCH_DATA_REQ (msg_p).rb_id,
// RRC_DCCH_DATA_REQ (msg_p).muip,
// RRC_DCCH_DATA_REQ (msg_p).confirmp,
// RRC_DCCH_DATA_REQ (msg_p).sdu_size,
// RRC_DCCH_DATA_REQ (msg_p).sdu_p,
// RRC_DCCH_DATA_REQ (msg_p).mode,
// NULL, NULL
// );
//
// if (result != TRUE)
// LOG_E(PDCP, "PDCP data request failed!\n");
//
// // Message buffer has been processed, free it now.
// result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ (msg_p).sdu_p);
// AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
// break;
//
// case RRC_PCCH_DATA_REQ: {
// sdu_size_t sdu_buffer_sizeP;
// sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size;
// uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id;
// uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index;
// RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP;
//
// if (sdu_buffer_sizeP > 0) {
// memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP);
// }
//
// //paging pdcp log
// LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP);
// }
// break;
//
// default:
// LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
// break;
// }
//
// result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
// AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
// }
// } while(msg_p != NULL);
//
// IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
// if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) {
if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) {
pdcp_fifo_read_input_mbms_sdus_fromtun(ctxt_pP);
}
// PDCP -> NAS/IP traffic: RX
// if (ctxt_pP->enb_flag) {
// start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// } else {
// start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// }
//
//pdcp_fifo_flush_mbms_sdus(ctxt_pP);
// if (ctxt_pP->enb_flag) {
// stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// } else {
// stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// }
//
// if (ctxt_pP->enb_flag) {
// stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// } else {
// stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// }
//
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT);
}
void pdcp_init_stats_UE(module_id_t mod, uint16_t uid) {
Pdcp_stats_tx_window_ms[mod][uid] = 100;
Pdcp_stats_rx_window_ms[mod][uid] = 100;
......@@ -1694,7 +1819,7 @@ rrc_pdcp_config_asn1_req (
for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
if (MBMS_SessionInfo_p->sessionId_r9)
if (0/*MBMS_SessionInfo_p->sessionId_r9*/)
lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0];
else
lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9;
......@@ -1721,7 +1846,7 @@ rrc_pdcp_config_asn1_req (
}
}
LOG_D(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n",
LOG_I(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n",
lc_id,
MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0],
MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1],
......@@ -2169,10 +2294,14 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
if(UE_NAS_USE_TUN) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1;
netlink_init_tun("ue",num_if);
netlink_init_mbms_tun("uem",1);
nas_config_mbms(1, 2, 2, "uem");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if(ENB_NAS_USE_TUN) {
netlink_init_tun("enb",1);
nas_config(1, 1, 1, "enb");
netlink_init_mbms_tun("enm",1);
nas_config_mbms(1, 2, 1, "enm");
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
} else {
LOG_I(PDCP, "pdcp will use kernel modules\n");
......
......@@ -392,6 +392,17 @@ boolean_t pdcp_remove_UE(
*/
//void rrc_pdcp_config_release ( const protocol_ctxt_t* const ctxt_pP, rb_id_t);
/*! \fn void pdcp_mbms_run(const protocol_ctxt_t* const ctxt_pP)
* \brief Runs PDCP entity to let it handle incoming/outgoing SDUs
* \param[in] ctxt_pP Running context.
* \return none
* \note None
* @ingroup _pdcp
*/
void pdcp_mbms_run (
const protocol_ctxt_t *const ctxt_pP);
/*! \fn void pdcp_run(const protocol_ctxt_t* const ctxt_pP)
* \brief Runs PDCP entity to let it handle incoming/outgoing SDUs
* \param[in] ctxt_pP Running context.
......@@ -416,6 +427,9 @@ void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req);
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind);
pdcp_data_ind_func_t get_pdcp_data_ind_func(void);
//-----------------------------------------------------------------------------
int pdcp_fifo_flush_mbms_sdus ( const protocol_ctxt_t *const ctxt_pP);
int pdcp_fifo_read_input_mbms_sdus_fromtun ( const protocol_ctxt_t *const ctxt_pP);
/*
* Following two types are utilized between NAS driver and PDCP
......
......@@ -77,6 +77,11 @@ extern struct iovec nas_iov_rx;
extern int nas_sock_fd[MAX_MOBILES_PER_ENB];
extern int nas_sock_mbms_fd[8];
extern int mbms_rab_id;
extern struct msghdr nas_msg_tx;
extern struct msghdr nas_msg_rx;
......@@ -125,7 +130,16 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
} else if (UE_NAS_USE_TUN) {
ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
//ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
if(rb_id == mbms_rab_id){
ret = write(nas_sock_mbms_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
else
{
ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
} else if (ENB_NAS_USE_TUN) {
ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
} else if (PDCP_USE_NETLINK) {
......@@ -143,6 +157,47 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
return pdcp_nb_sdu_sent;
}
int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
mem_block_t *sdu_p;
int pdcp_nb_sdu_sent = 0;
//int ret=0;
while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
//int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
//int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
//((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
//if (rb_id == 10) { //hardcoded for PC5-Signaling
// if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
// debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
// "pdcp_fifo_flush_sdus sends a aPC5S message");
// }
// ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
// sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
//} else if (UE_NAS_USE_TUN) {
// ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
// LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
//} else if (ENB_NAS_USE_TUN) {
// ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
//} else if (PDCP_USE_NETLINK) {
// memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite);
// nas_nlh_tx->nlmsg_len = sizeToWrite;
// ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
//} // PDCP_USE_NETLINK
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu_p, __func__);
pdcp_nb_sdu_sent ++;
}
return pdcp_nb_sdu_sent;
}
int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
protocol_ctxt_t ctxt = *ctxt_pP;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
......@@ -210,6 +265,105 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
return len;
}
int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
protocol_ctxt_t ctxt = *ctxt_pP;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc = HASH_TABLE_OK;
//pdcp_t *pdcp_p = NULL;
int len;
rb_id_t rab_id = mbms_rab_id;//DEFAULT_RAB_ID;
//if(mbms_rab_id > 9 || mbms_rab_id < 4)
//h_rc = 2;
if(UE_NAS_USE_TUN)
return 0;
do {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 1 );
len = read(UE_NAS_USE_TUN?nas_sock_mbms_fd[0]:nas_sock_mbms_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 0 );
if (len<=0) continue;
if (UE_NAS_USE_TUN) {
//key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
//h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
} else { // => ENB_NAS_USE_TUN
//ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0];
// ctxt.enb_flag=ENB_FLAG_YES;
// ctxt.module_id=0;
// key = PDCP_COLL_KEY_VALUE(ctxt.module_id, /*ctxt.rnti*/0, ctxt.enb_flag, /*mbms_rab_id*/8, SRB_FLAG_YES);
// h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
// LOG_W(PDCP,"h_rc %d %d\n",h_rc,rab_id);
}
LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
if (h_rc == HASH_TABLE_OK) {
LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n",
ctxt.frame, ctxt.instance, len, rab_id);
LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
ctxt.rnti, rab_id);
MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
NULL, 0,
MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ctxt.instance, rab_id, rab_id, len);
pdcp_data_req(
&ctxt,
SRB_FLAG_NO,
//DEFAULT_RAB_ID,
rab_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
len,
(unsigned char *)nl_rx_buf,
PDCP_TRANSMISSION_MODE_TRANSPARENT
, NULL, NULL
);
//pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED,
// RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf,
// PDCP_TRANSMISSION_MODE_DATA
// , NULL, NULL
// );
} else {
MSC_LOG_RX_DISCARDED_MESSAGE(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
NULL,
0,
MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ctxt.instance, rab_id, rab_id, len);
LOG_D(PDCP,
"[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
ctxt.rnti, rab_id, key);
//if (!UE_NAS_USE_TUN) {
// pdcp_data_req(
// &ctxt,
// SRB_FLAG_NO,
// DEFAULT_RAB_ID,
// RLC_MUI_UNDEFINED,
// RLC_SDU_CONFIRM_NO,
// len,
// (unsigned char *)nl_rx_buf,
// PDCP_TRANSMISSION_MODE_TRANSPARENT
// , NULL, NULL
// );
//}
}
} while (len > 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 0 );
return len;
}
int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctxt_pP) {
int len = 1;
int rlc_data_req_flag = 3;
......
......@@ -414,7 +414,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
if (MBMS_SessionInfo_p->sessionId_r9)
if (0/*MBMS_SessionInfo_p->sessionId_r9*/)
mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0];
else
mbms_session_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9;
......@@ -454,7 +454,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
}
}
LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n",
LOG_I(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n",
PROTOCOL_CTXT_ARGS(ctxt_pP),
lc_id,
rb_id,
......@@ -710,7 +710,7 @@ rlc_union_t* rrc_rlc_add_rlc (
}
key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id);
}
}else
if ((sourceL2Id > 0) && (destinationL2Id > 0) ){
key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP);
key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, sourceL2Id, destinationL2Id, srb_flagP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment