diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 708430b8b2..d64ad0a1b5 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -95,6 +95,8 @@ typedef struct x2ap_register_enb_req_s { lte_frame_type_t frame_type[MAX_NUM_CCs]; uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + uint32_t subframeAssignment[MAX_NUM_CCs]; + uint32_t specialSubframe[MAX_NUM_CCs]; int num_cc; /* To be considered for TDD */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 30130cf841..1aa8fa64c1 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2511,6 +2511,8 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = ccparams_lte.tdd_config; + X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s; } else { AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ba1c1832cd..4e23c1fe74 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -113,22 +113,22 @@ static const eutra_bandentry_t eutra_bandtable[] = { {30, 23050, 23250, 23500, 23600, 97700}, {31, 45250, 34900, 46250, 35900, 98700}, {32, 0, 0, 14520, 14960, 99200}, - {33, 19000, 19200, 19000, 19200, 36000}, - {34, 20100, 20250, 20100, 20250, 36200}, - {35, 18500, 19100, 18500, 19100, 36350}, - {36, 19300, 19900, 19300, 19900, 36950}, - {37, 19100, 19300, 19100, 19300, 37550}, - {38, 25700, 26200, 25700, 26300, 37750}, - {39, 18800, 19200, 18800, 19200, 38250}, - {40, 23000, 24000, 23000, 24000, 38650}, - {41, 24960, 26900, 24960, 26900, 39650}, - {42, 34000, 36000, 34000, 36000, 41590}, - {43, 36000, 38000, 36000, 38000, 43590}, - {44, 7030, 8030, 7030, 8030, 45590}, - {45, 14470, 14670, 14470, 14670, 46590}, - {46, 51500, 59250, 51500, 59250, 46790}, - {65, 19200, 20100, 21100, 22000, 65536}, - {66, 17100, 18000, 21100, 22000, 66436}, + {33, 19000, 19200, 19000, 19200, 360000}, + {34, 20100, 20250, 20100, 20250, 362000}, + {35, 18500, 19100, 18500, 19100, 363500}, + {36, 19300, 19900, 19300, 19900, 369500}, + {37, 19100, 19300, 19100, 19300, 375500}, + {38, 25700, 26200, 25700, 26300, 377500}, + {39, 18800, 19200, 18800, 19200, 382500}, + {40, 23000, 24000, 23000, 24000, 386500}, + {41, 24960, 26900, 24960, 26900, 396500}, + {42, 34000, 36000, 34000, 36000, 415900}, + {43, 36000, 38000, 36000, 38000, 435900}, + {44, 7030, 8030, 7030, 8030, 455900}, + {45, 14470, 14670, 14470, 14670, 465900}, + {46, 51500, 59250, 51500, 59250, 467900}, + {65, 19200, 20100, 21100, 22000, 655360}, + {66, 17100, 18000, 21100, 22000, 664360}, {67, 0, 0, 7380, 7580, 67336}, {68, 6980, 7280, 7530, 7830, 67536} }; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 230b9511f0..79a1484928 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3898,6 +3898,31 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB + if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) { + MeasObj->measObject.choice.measObjectEUTRA.ext1 = CALLOC(1, sizeof(struct LTE_MeasObjectEUTRA__ext1)); + MeasObj->measObject.choice.measObjectEUTRA.ext1->measCycleSCell_r10 = NULL; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10 = CALLOC(1, sizeof(struct LTE_MeasSubframePatternConfigNeigh_r10)); + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->present=LTE_MeasSubframePatternConfigNeigh_r10_PR_setup; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.present=LTE_MeasSubframePattern_r10_PR_subframePatternTDD_r10; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.present=LTE_MeasSubframePattern_r10__subframePatternTDD_r10_PR_subframeConfig1_5_r10; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf=CALLOC(3, sizeof(uint8_t)); + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.size=3; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.bits_unused=4; + switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) { + case 1: //subframe 0,4,5,9 + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x8C; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x63; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x10; + break; + + default: //subframe 0 , 5 + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x84; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x21; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x00; + break; + } + } + MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index e1a8b506bc..03d8216b56 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -173,6 +173,8 @@ typedef struct x2ap_eNB_instance_s { lte_frame_type_t frame_type[MAX_NUM_CCs]; uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + uint32_t subframeAssignment[MAX_NUM_CCs]; + uint32_t specialSubframe[MAX_NUM_CCs]; int num_cc; net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS]; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 53ec8574fd..7d84a7d498 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -144,7 +144,92 @@ int x2ap_eNB_generate_x2_setup_request( } } else { - AssertFatal(0,"X2Setuprequest not supported for TDD!"); + servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i]; + switch (instance_p->subframeAssignment[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + switch (instance_p->specialSubframe[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6; + break; + case 7: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7; + break; + case 8: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal; + + switch (instance_p->N_RB_DL[i]) { + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } } } ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); @@ -279,7 +364,92 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eN } } else { - AssertFatal(0,"X2Setupresponse not supported for TDD!"); + servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i]; + switch (instance_p->subframeAssignment[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + switch (instance_p->specialSubframe[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6; + break; + case 7: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7; + break; + case 8: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal; + + switch (instance_p->N_RB_DL[i]) { + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } } } ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);