Merge remote-tracking branch 'origin/f1-interop-fixes' into integration_2022_wk46
This commit is contained in:
@@ -37,6 +37,8 @@
|
|||||||
#include "f1ap_du_interface_management.h"
|
#include "f1ap_du_interface_management.h"
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
|
|
||||||
|
#include "GNB_APP/gnb_paramdef.h"
|
||||||
|
|
||||||
int to_NRNRB(int nrb) {
|
int to_NRNRB(int nrb) {
|
||||||
for (int i=0; i<sizeofArray(nrb_lut); i++)
|
for (int i=0; i<sizeofArray(nrb_lut); i++)
|
||||||
if (nrb_lut[i] == nrb)
|
if (nrb_lut[i] == nrb)
|
||||||
@@ -180,12 +182,30 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
|
|||||||
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
|
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
|
||||||
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
|
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
|
||||||
|
|
||||||
asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, SliceSupport_item);
|
/* get list of sst/sd from configuration file */
|
||||||
INT8_TO_OCTET_STRING(1,&SliceSupport_item->sNSSAI.sST);
|
paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC;
|
||||||
asn1cCalloc(SliceSupport_item->sNSSAI.sD, tmp);
|
paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0};
|
||||||
INT24_TO_OCTET_STRING(10203,tmp);
|
char sstr[100];
|
||||||
//INT24_TO_OCTET_STRING(1,tmp);
|
/* 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
|
if (f1ap_req(false, instance)->fdd_flag) { // FDD
|
||||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
||||||
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
||||||
|
|||||||
@@ -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);
|
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) {
|
void *F1AP_DU_task(void *arg) {
|
||||||
//sctp_cu_init();
|
//sctp_cu_init();
|
||||||
LOG_I(F1AP, "Starting F1AP at DU\n");
|
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");
|
LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n");
|
||||||
f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg);
|
f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg);
|
||||||
createF1inst(false, myInstance, msgSetup);
|
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);
|
du_task_send_sctp_association_req(myInstance,msgSetup);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -1078,6 +1078,17 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
|||||||
f1ap_remove_ue(DUtype, instance, cplt->rnti);
|
f1ap_remove_ue(DUtype, instance, cplt->rnti);
|
||||||
return 0;
|
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,
|
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
||||||
uint32_t assoc_id,
|
uint32_t assoc_id,
|
||||||
uint32_t stream,
|
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
|
// 3GPP assumes GTP-U is on port 2152, but OAI is configurable
|
||||||
drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport;
|
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) {
|
switch (drbs_tobesetupmod_item_p->rLCMode) {
|
||||||
case F1AP_RLCMode_rlc_am:
|
case F1AP_RLCMode_rlc_am:
|
||||||
drb_p->rlc_mode = RLC_MODE_AM;
|
drb_p->rlc_mode = RLC_MODE_AM;
|
||||||
|
|||||||
@@ -3407,6 +3407,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co
|
|||||||
/* Configure DRB */
|
/* Configure DRB */
|
||||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||||
NR_DRB_ToAddModList_t *DRB_configList = NULL;
|
NR_DRB_ToAddModList_t *DRB_configList = NULL;
|
||||||
|
int drb_id_to_setup_start = 0;
|
||||||
if(req->drbs_to_be_setup_length>0){
|
if(req->drbs_to_be_setup_length>0){
|
||||||
if(ue_context_p->ue_context.DRB_configList == NULL){
|
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));
|
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));
|
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;
|
addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8;
|
||||||
extern instance_t DUuniqInstance;
|
extern instance_t DUuniqInstance;
|
||||||
|
if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id;
|
||||||
incoming_teid = newGtpuCreateTunnel(DUuniqInstance,
|
incoming_teid = newGtpuCreateTunnel(DUuniqInstance,
|
||||||
req->rnti,
|
req->rnti,
|
||||||
drb_p.drb_id,
|
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){
|
if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){
|
||||||
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
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)
|
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,
|
fill_mastercellGroupConfig(cellGroupConfig,
|
||||||
ue_context_p->ue_context.masterCellGroup,
|
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");
|
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;
|
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;
|
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);
|
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,
|
MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ,
|
||||||
sizeof(gtpv1u_gnb_tunnel_data_req_t));
|
sizeof(gtpv1u_gnb_tunnel_data_req_t));
|
||||||
|
|||||||
@@ -1115,7 +1115,7 @@ static int Gtpv1uHandleGpdu(int h,
|
|||||||
|
|
||||||
if(NR_PDCP_PDU_SN > 0 && NR_PDCP_PDU_SN %5 ==0){
|
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);
|
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);
|
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
|
/*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
|
* size of mandatory part + 3 octets for highest transmitted/delivered PDCP SN
|
||||||
|
|||||||
Reference in New Issue
Block a user