diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 282739e31597782fd46a1e5e50f154d01c801708..6a70e1f10afae444929d0ec07807318ee9f8f261 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -702,6 +702,18 @@ typedef struct { #define NFAPI_PUCCH_CONFIG_N_AN_CS_TAG 0x003E #define NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG 0x003F +typedef struct { + nfapi_uint8_tlv_t radioframe_allocation_period; + nfapi_uint8_tlv_t radioframe_allocation_offset; + nfapi_uint8_tlv_t non_mbsfn_config_flag; + nfapi_uint16_tlv_t non_mbsfn_subframeconfig; +} nfapi_fembms_config_t; + +#define NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG 0x0042 +#define NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG 0x0043 +#define NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG 0x0044 +#define NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG 0x0045 + typedef struct { nfapi_uint16_tlv_t bandwidth_configuration; nfapi_uint16_tlv_t max_up_pts; @@ -1097,6 +1109,7 @@ typedef struct { nfapi_prach_config_t prach_config; nfapi_pusch_config_t pusch_config; nfapi_pucch_config_t pucch_config; + nfapi_fembms_config_t fembms_config; nfapi_srs_config_t srs_config; nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; nfapi_tdd_frame_structure_t tdd_frame_structure_config; @@ -1118,6 +1131,7 @@ typedef struct { nfapi_prach_config_t prach_config; nfapi_pusch_config_t pusch_config; nfapi_pucch_config_t pucch_config; + nfapi_fembms_config_t fembms_config; nfapi_srs_config_t srs_config; nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; nfapi_laa_config_t laa_config; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c index c78b8291358c2a611763649d024bb86acf2b9fba..54e27123d995ea1ec3088e0daa7a48c74574d64d 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -461,6 +461,12 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_subframeconfig), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 6a062abcaee94bf06cbb217259be716eb3107c65..34f0a2a87724c92f469bbd7730f56e289b2bd77a 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -310,6 +310,12 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->num_MBSFN_config = 0; + fp->NonMBSFN_config_flag =cfg->fembms_config.non_mbsfn_config_flag.value; + fp->NonMBSFN_config.non_mbsfn_SubframeConfig = cfg->fembms_config.non_mbsfn_subframeconfig.value; + fp->NonMBSFN_config.radioframeAllocationPeriod = cfg->fembms_config.radioframe_allocation_period.value; + fp->NonMBSFN_config.radioframeAllocationOffset = cfg->fembms_config.radioframe_allocation_offset.value; + LOG_D(PHY,"eNB %d/%d frame NonMBSFN configured: %d (%x) %d/%d\n",Mod_id,CC_id,fp->NonMBSFN_config_flag,fp->NonMBSFN_config.non_mbsfn_SubframeConfig,fp->NonMBSFN_config.radioframeAllocationPeriod,fp->NonMBSFN_config.radioframeAllocationOffset); + init_ncs_cell (fp, RC.eNB[Mod_id][CC_id]->ncs_cell); diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c index a4821a420ff27f87731c6b737d515598e5758343..e0184c204e2bb094ac8328c794ff469cb38fb954 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c @@ -22,6 +22,76 @@ #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int is_fembms_cas_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms){ + uint32_t period; + if(frame_parms->NonMBSFN_config_flag ) { + period = 4<<frame_parms->NonMBSFN_config.radioframeAllocationPeriod; + if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + switch (subframe) { + case 0: + return(1); //This should be CAS + break; + } + } + } + return (0); +} + +int is_fembms_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) +{ + uint32_t period; + + if(frame_parms->NonMBSFN_config_flag ) { + period = 4<<frame_parms->NonMBSFN_config.radioframeAllocationPeriod; + if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + switch (subframe) { + case 1: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x100) > 0) + return(1); + break; + case 2: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x80) > 0) + return(1); + break; + case 3: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x40) > 0) + return(1); + break; + case 4: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x20) > 0) + return(1); + break; + case 5: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x10) > 0) + return(1); + break; + case 6: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x8) > 0) + return(1); + break; + case 7: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x4) > 0) + return(1); + break; + case 8: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x2) > 0) + return(1); + break; + case 9: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x1) > 0) + return(1); + break; + } + } else { //Then regular MBSFN FeMBMS subframe + return(0); + } + } + return(0); +} +#endif + int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) { diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h index 0cc59360b612c57a7846abe5d4378a0517b791a7..a6cb0417adae40d61b4c8857af1b1bea0c7aec04 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h @@ -256,6 +256,27 @@ void init_prach_tables(int N_ZC); */ int is_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +/*! + \brief Return the status of CAS in this frame/subframe + @param frame Frame index + @param subframe Subframe index + @param frame_parms Pointer to frame parameters + @returns 1 if subframe is for CAS +*/ +int is_fembms_cas_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); + +/*! + \brief Return the status of MBSFN in this frame/subframe + @param frame Frame index + @param subframe Subframe index + @param frame_parms Pointer to frame parameters + @returns 1 if subframe is for MBSFN +*/ +int is_fembms_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); +#endif + + /** \brief This routine expands a single (wideband) PMI to subband PMI bitmap similar to the one used in the UCI and in the dlsch_modulation routine @param frame_parms Pointer to DL frame configuration parameters diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 64ca5afbb63f0c3ef62fe87f4368281c837c5b64..1ffd9ee2cf7e3ba9766a2be0cb7cd44347bfdae2 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -580,6 +580,15 @@ typedef struct { int mbsfn_SubframeConfig; } MBSFN_config_t; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +typedef struct { + int radioframeAllocationPeriod; + int radioframeAllocationOffset; + int non_mbsfn_SubframeConfig; +} NonMBSFN_config_t; +#endif + + typedef struct { /// Number of resource blocks (RB) in DL uint8_t N_RB_DL; @@ -665,6 +674,10 @@ typedef struct { int num_MBSFN_config; /// Array of MBSFN Configurations (max 8 (maxMBSFN-Allocations) elements as per 36.331) MBSFN_config_t MBSFN_config[8]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t NonMBSFN_config_flag; + NonMBSFN_config_t NonMBSFN_config; +#endif /// Maximum Number of Retransmissions of RRCConnectionRequest (from 36-331 RRC Spec) uint8_t maxHARQ_Msg3Tx; /// Size of SI windows used for repetition of one SI message (in frames) @@ -679,6 +692,9 @@ typedef struct { uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[MAX_MBSFN_AREA]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct NonMBSFN_SubframeConfig *non_mbsfn_SubframeConfig; +#endif /// for fair RR scheduler uint32_t ue_multiple_max; } LTE_DL_FRAME_PARMS; diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index bf079c216b9977e7dc923189945b52dfd87a5ef7..826b1445fd6aff1f2d0c418fbc036b6957004e64 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -967,6 +967,39 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag; #endif } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (nonMBSFN_SubframeConfig != NULL){ + LOG_D(MAC, + "[eNB %d][CONFIG] Received a non MBSFN subframe allocation pattern (%x,%x):%x for FeMBMS-CAS\n", + Mod_idP, nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0],nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1],nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7 ); + RC.mac[Mod_idP]->common_channels[0].non_mbsfn_SubframeConfig = (nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7); + + nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + cfg->fembms_config.non_mbsfn_config_flag.value = 1; + cfg->fembms_config.non_mbsfn_config_flag.tl.tag = NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG; + cfg->num_tlv++; + + cfg->fembms_config.non_mbsfn_subframeconfig.value = (nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7); + cfg->fembms_config.non_mbsfn_subframeconfig.tl.tag = NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG; + cfg->num_tlv++; + + cfg->fembms_config.radioframe_allocation_period.value = nonMBSFN_SubframeConfig->radioFrameAllocationPeriod_r14; + cfg->fembms_config.radioframe_allocation_period.tl.tag = NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG; + cfg->num_tlv++; + + cfg->fembms_config.radioframe_allocation_offset.value = nonMBSFN_SubframeConfig->radioFrameAllocationOffset_r14; + cfg->fembms_config.radioframe_allocation_offset.tl.tag = NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG; + cfg->num_tlv++; + + + + //We need to reuse current MCH scheduler + //TOCHECK whether we can simply reuse current mbsfn_SubframeConfig stuff + } +#endif + + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbsfn_AreaInfoList != NULL) { diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index ad16cf068f656f44da98e003cc09636b7b6344df..22b52cc6bb0f1a0c44d25a76b14d35760878d3f6 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1283,6 +1283,9 @@ typedef struct { uint8_t vrb_map_UL[100]; /// MBSFN SubframeConfig struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct LTE_NonMBSFN_SubframeConfig_r14 *non_mbsfn_SubframeConfig; +#endif /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -1628,6 +1631,9 @@ typedef struct { /// MBSFN_Subframe Configuration struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct LTE_NonMBSFN_SubframeConfig_r14 *non_mbsfn_SubframeConfig; +#endif /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 6276cdc0cc2b30955f80edab331a595ded964f53..479296fd12bb46c8c06b898e8c8b31cac88d7f7f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -588,10 +588,11 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14 = CALLOC(1,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14)); memset((*sib1_MBMS)->nonMBSFN_SubframeConfig_r14,0,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14)); (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14 = LTE_NonMBSFN_SubframeConfig_r14__radioFrameAllocationPeriod_r14_rf8; - (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationOffset_r14 = LTE_NonMBSFN_SubframeConfig_r14__radioFrameAllocationPeriod_r14_rf64; + (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationOffset_r14 = 0; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf = MALLOC(2); - (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[0] = 0x20<<0; - (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[1] = 0x20<<7; + //100000001 byte(0)=10000000 byte(1)=xxxxxxx1 + (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[0] = 0x80<<0; + (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[1] = 0x1<<7; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.size = 2; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.bits_unused = 7; }