diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 367b71fed5..0a19c953f8 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -37,6 +37,8 @@ #include "f1ap_du_interface_management.h" #include "assertions.h" +#include "GNB_APP/gnb_paramdef.h" + int to_NRNRB(int nrb) { for (int i=0; iextensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList; F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList; - asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, SliceSupport_item); - INT8_TO_OCTET_STRING(1,&SliceSupport_item->sNSSAI.sST); - asn1cCalloc(SliceSupport_item->sNSSAI.sD, tmp); - INT24_TO_OCTET_STRING(10203,tmp); - //INT24_TO_OCTET_STRING(1,tmp); - + /* get list of sst/sd from configuration file */ + paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC; + paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0}; + char sstr[100]; + /* TODO: be sure that %d in the line below is at the right place */ + sprintf(sstr, "%s.[%d].%s.[0]", GNB_CONFIG_STRING_GNB_LIST, i, GNB_CONFIG_STRING_PLMN_LIST); + config_getlist(&SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams)/sizeof(paramdef_t), sstr); + AssertFatal(SNSSAIParamList.numelt > 0, "no slice configuration found (snssaiList in the configuration file)\n"); + AssertFatal(SNSSAIParamList.numelt <= 1024, "maximum size for slice support list is 1024, see F1AP 38.473 9.3.1.37\n"); + for (int s = 0; s < SNSSAIParamList.numelt; s++) { + uint32_t sst; + uint32_t sd; + bool has_sd; + sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + has_sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr != 0xffffff; + asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice); + INT8_TO_OCTET_STRING(sst, &slice->sNSSAI.sST); + if (has_sd) { + sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; + asn1cCalloc(slice->sNSSAI.sD, tmp); + INT24_TO_OCTET_STRING(sd, tmp); + } + } + if (f1ap_req(false, instance)->fdd_flag) { // FDD nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index f8cf216220..ac952e0498 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -96,15 +96,6 @@ void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_dat AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) { - openAddr_t tmp= {0}; - strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); - strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); - sprintf(tmp.originService, "%d", DUport); - sprintf(tmp.destinationService, "%d", CUport); - return gtpv1Init(tmp); -} - void *F1AP_DU_task(void *arg) { //sctp_cu_init(); LOG_I(F1AP, "Starting F1AP at DU\n"); @@ -126,15 +117,6 @@ void *F1AP_DU_task(void *arg) { LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg); createF1inst(false, myInstance, msgSetup); - getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address, //"172.21.6.9", //"172.21.10.9",//"172.21.9.5", //msgSetup->CU_f1_ip_address.ipv4_address, //"192.168.18.91" - msgSetup->CUport, - msgSetup->DU_f1_ip_address.ipv4_address, - msgSetup->DUport); - AssertFatal(getCxt(DUtype, myInstance)->gtpInst>0,"Failed to create CU F1-U UDP listener"); - // Fixme: fully inconsistent instances management - // dirty global var is a bad fix - extern instance_t legacyInstanceMapping; - legacyInstanceMapping = DUuniqInstance = getCxt(DUtype, myInstance)->gtpInst; du_task_send_sctp_association_req(myInstance,msgSetup); break; diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index cb15862921..c37e2cfdc6 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -1078,6 +1078,17 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_remove_ue(DUtype, instance, cplt->rnti); return 0; } + +static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) +{ + openAddr_t tmp; + strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); + strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); + sprintf(tmp.originService, "%d", DUport); + sprintf(tmp.destinationService, "%d", CUport); + return gtpv1Init(tmp); +} + int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, @@ -1160,6 +1171,26 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, // 3GPP assumes GTP-U is on port 2152, but OAI is configurable drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport; + extern instance_t DUuniqInstance; + if (DUuniqInstance == 0) { + char gtp_tunnel_ip_address[128]; + sprintf(gtp_tunnel_ip_address, "%d.%d.%d.%d", + drb_p->up_ul_tnl[0].tl_address & 0xff, + (drb_p->up_ul_tnl[0].tl_address >> 8) & 0xff, + (drb_p->up_ul_tnl[0].tl_address >> 16) & 0xff, + (drb_p->up_ul_tnl[0].tl_address >> 24) & 0xff); + getCxt(DUtype, instance)->gtpInst=du_create_gtpu_instance_to_cu( + gtp_tunnel_ip_address, + getCxt(false,instance)->setupReq.CUport, + getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + getCxt(false,instance)->setupReq.DUport); + AssertFatal(getCxt(DUtype, instance)->gtpInst>0,"Failed to create CU F1-U UDP listener"); + // Fixme: fully inconsistent instances management + // dirty global var is a bad fix + extern instance_t legacyInstanceMapping; + legacyInstanceMapping = DUuniqInstance = getCxt(DUtype, instance)->gtpInst; + } + switch (drbs_tobesetupmod_item_p->rLCMode) { case F1AP_RLCMode_rlc_am: drb_p->rlc_mode = RLC_MODE_AM; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index fdd6fb9544..02e1a09342 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3407,6 +3407,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co /* Configure DRB */ NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList = NULL; + int drb_id_to_setup_start = 0; if(req->drbs_to_be_setup_length>0){ if(ue_context_p->ue_context.DRB_configList == NULL){ ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); @@ -3421,6 +3422,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; extern instance_t DUuniqInstance; + if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; incoming_teid = newGtpuCreateTunnel(DUuniqInstance, req->rnti, drb_p.drb_id, @@ -3436,7 +3438,6 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - uint8_t drb_id_to_setup_start = 1; long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, @@ -3456,7 +3457,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); uint8_t drb_id = ue_context_p->ue_context.DRB_configList->list.array[0]->drb_Identity; rnti_t rnti = ue_context_p->ue_context.rnti; - int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id + 3); LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, sizeof(gtpv1u_gnb_tunnel_data_req_t)); diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index af2a0ee9e8..618cdef23b 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1115,7 +1115,7 @@ static int Gtpv1uHandleGpdu(int h, if(NR_PDCP_PDU_SN > 0 && NR_PDCP_PDU_SN %5 ==0){ LOG_D (GTPU, "Create and send DL DATA Delivery status for the previously received PDU, NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); - int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id + 3); LOG_D(GTPU, "Available buffer size in RLC for Tx: %d \n", rlc_tx_buffer_space); /*Total size of DDD_status PDU = 1 octet to report extension header length * size of mandatory part + 3 octets for highest transmitted/delivered PDCP SN