Remove 4G F1
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "COMMON/platform_types.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "NR_ServingCellConfigCommon.h"
|
||||
#include "NR_MIB.h"
|
||||
|
||||
bool sdap_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const ue_id_t ue_id,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id,
|
||||
const uint8_t qfi,
|
||||
const bool rqi,
|
||||
const int pdusession_id) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int rrc_gNB_generate_pcch_msg(uint32_t tmsi,
|
||||
uint8_t paging_drx,
|
||||
instance_t instance,
|
||||
uint8_t CC_id) {
|
||||
abort();
|
||||
}
|
||||
@@ -142,15 +142,9 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance,
|
||||
req->cell[i].nr_pci = servedCellInformation->nRPCI;
|
||||
LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell[i].nr_pci);
|
||||
|
||||
// LTS: FIXME data model failure: we don't KNOW if we receive a 4G or a 5G cell
|
||||
// Furthermore, cell_type is not a attribute of a cell in the data structure !!!!!!!!!!
|
||||
if (RC.nrrrc &&
|
||||
( RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU ||
|
||||
RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CUCP) )
|
||||
f1ap_req(true, instance)->cell_type=CELL_MACRO_GNB;
|
||||
else
|
||||
f1ap_req(true, instance)->cell_type=CELL_MACRO_ENB;
|
||||
|
||||
// LTS: FIXME cell_type is not a attribute of a cell in the data structure !!!!!!!!!!
|
||||
f1ap_req(true, instance)->cell_type = CELL_MACRO_GNB;
|
||||
|
||||
// FDD Cells
|
||||
if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_fDD) {
|
||||
struct fdd_s *FDDs=&req->nr_mode_info[i].fdd;
|
||||
@@ -558,198 +552,6 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configu
|
||||
}
|
||||
}
|
||||
|
||||
// c3. Cells_to_be_Deactivated_List
|
||||
//
|
||||
/*
|
||||
if(!RC.nrrrc) {
|
||||
// mandatory
|
||||
// c3. Cells_to_be_Deactivated_List
|
||||
asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC3);
|
||||
ieC3->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Deactivated_List;
|
||||
ieC3->criticality = F1AP_Criticality_reject;
|
||||
ieC3->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Deactivated_List;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ieC3->value.choice.Cells_to_be_Deactivated_List.list,
|
||||
F1AP_Cells_to_be_Deactivated_List_ItemIEs_t, cells_to_be_deactivated);
|
||||
cells_to_be_deactivated->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
|
||||
cells_to_be_deactivated->criticality = F1AP_Criticality_reject;
|
||||
cells_to_be_deactivated->value.present = F1AP_Cells_to_be_Deactivated_List_ItemIEs__value_PR_Cells_to_be_Deactivated_List_Item;
|
||||
// 3.1 cells to be Deactivated list item
|
||||
F1AP_Cells_to_be_Deactivated_List_Item_t *cells_to_be_deactivated_list=
|
||||
cells_to_be_deactivated->value.choice.Cells_to_be_Deactivated_List_Item;
|
||||
addnRCGI(cells_to_be_deactivated_item->nRCGI, f1ap_setup_resp->cells_to_deactivate+i);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// c4. GNB_CU_TNL_Association_To_Add_List
|
||||
/*
|
||||
asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC4);
|
||||
ieC4->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_List;
|
||||
ieC4->criticality = F1AP_Criticality_reject;
|
||||
ieC4->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Add_List;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ieC4->value.choice.GNB_CU_TNL_Association_To_Add_List.list,
|
||||
F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t, gnb_cu_tnl_association_to_add;
|
||||
gnb_cu_tnl_association_to_add->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_Item;
|
||||
gnb_cu_tnl_association_to_add->criticality = F1AP_Criticality_reject;
|
||||
gnb_cu_tnl_association_to_add->value.present = F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Add_Item;
|
||||
|
||||
// 4.1 GNB_CU_TNL_Association_To_Add_Item
|
||||
F1AP_GNB_CU_TNL_Association_To_Add_Item_t *gnb_cu_tnl_association_to_add_item=
|
||||
&gnb_cu_tnl_association_to_add_item_ies->value.choice.GNB_CU_TNL_Association_To_Add_Item;
|
||||
|
||||
// 4.1.1 tNLAssociationTransportLayerAddress
|
||||
F1AP_CP_TransportLayerAddress_t *transportLayerAddress=;
|
||||
gnb_cu_tnl_association_to_add->value.choice.GNB_CU_TNL_Association_To_Add_Item;
|
||||
|
||||
transportLayerAddress->present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress->choice.endpoint_IP_address);
|
||||
|
||||
// memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
|
||||
// transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
|
||||
// transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
|
||||
// TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
|
||||
|
||||
// 4.1.2 tNLAssociationUsage
|
||||
gnb_cu_tnl_association_to_add_item->tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// c5. GNB_CU_TNL_Association_To_Remove_List
|
||||
asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC5);
|
||||
ieC5->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_List;
|
||||
ieC5->criticality = F1AP_Criticality_reject;
|
||||
ieC5->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Remove_List;
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ieC5->value.choice.GNB_CU_TNL_Association_To_Remove_List.list,
|
||||
F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t, gnb_cu_tnl_association_to_remove);
|
||||
gnb_cu_tnl_association_to_remove->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_Item;
|
||||
gnb_cu_tnl_association_to_remove->criticality = F1AP_Criticality_reject;
|
||||
gnb_cu_tnl_association_to_remove->value.present = F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Remove_Item;
|
||||
|
||||
// 4.1 GNB_CU_TNL_Association_To_Remove_Item
|
||||
F1AP_GNB_CU_TNL_Association_To_Remove_Item_t *gnb_cu_tnl_association_to_remove_item=
|
||||
&gnb_cu_tnl_association_to_remove->value.choice.GNB_CU_TNL_Association_To_Remove_Item;
|
||||
|
||||
// 4.1.1 tNLAssociationTransportLayerAddress
|
||||
F1AP_CP_TransportLayerAddress_t *transportLayerAddress=
|
||||
&gnb_cu_tnl_association_to_remove_item->tNLAssociationTransportLayerAddress;
|
||||
transportLayerAddress->present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress->choice.endpoint_IP_address);
|
||||
|
||||
// memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
|
||||
// transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
|
||||
// transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
|
||||
// TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
//mandatory
|
||||
// c6. GNB_CU_TNL_Association_To_Update_List
|
||||
asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC6);
|
||||
ieC6->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_List;
|
||||
ieC6->criticality = F1AP_Criticality_reject;
|
||||
ieC6->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Update_List;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ieC3->value.choice.GNB_CU_TNL_Association_To_Update_List.list,
|
||||
F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t, gnb_cu_tnl_association_to_update);
|
||||
gnb_cu_tnl_association_to_update->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_Item;
|
||||
gnb_cu_tnl_association_to_update->criticality = F1AP_Criticality_reject;
|
||||
gnb_cu_tnl_association_to_update->value.present = F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Update_Item;
|
||||
// 4.1 GNB_CU_TNL_Association_To_Update_Item
|
||||
F1AP_GNB_CU_TNL_Association_To_Update_Item_t *gnb_cu_tnl_association_to_update_item=
|
||||
&gnb_cu_tnl_association_to_update->value.choice.GNB_CU_TNL_Association_To_Update_Item;
|
||||
// 4.1.1 tNLAssociationTransportLayerAddress
|
||||
F1AP_CP_TransportLayerAddress_t *transportLayerAddress=
|
||||
&gnb_cu_tnl_association_to_update_item.tNLAssociationTransportLayerAddress;
|
||||
transportLayerAddress->present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress->choice.endpoint_IP_address);
|
||||
// memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
|
||||
// transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
|
||||
// transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
|
||||
// TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
|
||||
// 4.1.2 tNLAssociationUsage
|
||||
if (1) {
|
||||
gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = (F1AP_TNLAssociationUsage_t *)calloc(1, sizeof(F1AP_TNLAssociationUsage_t));
|
||||
*gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// c7. Cells_to_be_Barred_List
|
||||
asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC7);
|
||||
ieC7->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Barred_List;
|
||||
ieC7->criticality = F1AP_Criticality_reject;
|
||||
ieC7->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Barred_List;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ieC7->value.choice.Cells_to_be_Barred_List.list,
|
||||
F1AP_Cells_to_be_Barred_ItemIEs_t,cells_to_be_barred);
|
||||
cells_to_be_barred->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
|
||||
cells_to_be_barred->criticality = F1AP_Criticality_reject;
|
||||
cells_to_be_barred->value.present = F1AP_Cells_to_be_Barred_ItemIEs__value_PR_Cells_to_be_Barred_Item;
|
||||
// 7.1 cells to be Deactivated list item
|
||||
F1AP_Cells_to_be_Barred_Item_t *cells_to_be_barred_item=
|
||||
&cells_to_be_barred_item_ies->value.choice.Cells_to_be_Barred_Item;
|
||||
// - nRCGI
|
||||
addnRCGI(cells_to_be_barred_item->nRCGI, f1ap_gnb_cu_configuration_update->cells_to_activate+i);
|
||||
// 7.2 cellBarred
|
||||
cells_to_be_barred_item->cellBarred = F1AP_CellBarred_not_barred;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// c8. Protected_EUTRA_Resources_List
|
||||
asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC8);
|
||||
ieC8->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
|
||||
ieC8->criticality = F1AP_Criticality_reject;
|
||||
ieC8->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Protected_EUTRA_Resources_List;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
asn1cSequenceAdd(ieC8->value.choice.Protected_EUTRA_Resources_List.list,
|
||||
F1AP_Protected_EUTRA_Resources_ItemIEs_t, protected_eutra_resources);
|
||||
// 8.1 SpectrumSharingGroupID
|
||||
protected_eutra_resources->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
|
||||
protected_eutra_resources->criticality = F1AP_Criticality_reject;
|
||||
protected_eutra_resources->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_Protected_EUTRA_Resources_Item;
|
||||
((F1AP_Protected_EUTRA_Resources_Item_t *)&protected_eutra_resources->value.choice.Protected_EUTRA_Resources_Item)->spectrumSharingGroupID = 123L;
|
||||
memset(&protected_eutra_resources->value.choice.Protected_EUTRA_Resources_Item,0,
|
||||
sizeof(F1AP_Protected_EUTRA_Resources_Item_t));
|
||||
|
||||
asn1cSequenceAdd(protected_eutra_resources->value.choice.ListofEUTRACellsinGNBDUCoordination.list,
|
||||
F1AP_Served_EUTRA_Cells_Information_t, served_eutra_cells_information);
|
||||
memset((void *)&served_eutra_cells_information, 0, sizeof(F1AP_Served_EUTRA_Cells_Information_t));
|
||||
|
||||
F1AP_EUTRA_Mode_Info_t *eUTRA_Mode_Info=
|
||||
&served_eutra_cells_information.eUTRA_Mode_Info;
|
||||
|
||||
// eUTRAFDD
|
||||
eUTRA_Mode_Info->present = F1AP_EUTRA_Mode_Info_PR_eUTRAFDD;
|
||||
F1AP_EUTRA_FDD_Info_t *eutra_fdd_info = (F1AP_EUTRA_FDD_Info_t *)calloc(1, sizeof(F1AP_EUTRA_FDD_Info_t));
|
||||
eutra_fdd_info->uL_offsetToPointA = 123L;
|
||||
eutra_fdd_info->dL_offsetToPointA = 456L;
|
||||
eUTRA_Mode_Info.choice.eUTRAFDD = eutra_fdd_info;
|
||||
|
||||
// eUTRATDD
|
||||
// eUTRA_Mode_Info.present = F1AP_EUTRA_Mode_Info_PR_eUTRATDD;
|
||||
// F1AP_EUTRA_TDD_Info_t *eutra_tdd_info;
|
||||
// eutra_tdd_info = (F1AP_EUTRA_TDD_Info_t *)calloc(1, sizeof(F1AP_EUTRA_TDD_Info_t));
|
||||
// eutra_tdd_info->uL_offsetToPointA = 123L;
|
||||
// eutra_tdd_info->dL_offsetToPointA = 456L;
|
||||
// eUTRA_Mode_Info.choice.eUTRATDD = eutra_tdd_info;
|
||||
|
||||
OCTET_STRING_fromBuf(&served_eutra_cells_information.protectedEUTRAResourceIndication, "asdsa1d32sa1d31asd31as",
|
||||
strlen("asdsa1d32sa1d31asd31as"));
|
||||
}
|
||||
*/
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 gNB-CU CONFIGURATION UPDATE\n");
|
||||
|
||||
@@ -123,12 +123,7 @@ void *F1AP_CU_task(void *arg) {
|
||||
eth_params_t *IPaddrs;
|
||||
|
||||
// Hardcoded instance id!
|
||||
if (RC.nrrrc &&
|
||||
(RC.nrrrc[0]->node_type == ngran_gNB_CU ||
|
||||
RC.nrrrc[0]->node_type == ngran_gNB_CUCP ) )
|
||||
IPaddrs=&RC.nrrrc[0]->eth_params_s;
|
||||
else
|
||||
IPaddrs=&RC.rrc[0]->eth_params_s;
|
||||
IPaddrs = &RC.nrrrc[0]->eth_params_s;
|
||||
|
||||
cu_task_send_sctp_init_req(0, IPaddrs->my_addr);
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include "rrc_extern.h"
|
||||
#include "rrc_eNB_UE_context.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include "rrc_eNB_S1AP.h"
|
||||
#include "rrc_eNB_GTPV1U.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
|
||||
@@ -959,49 +958,15 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance);
|
||||
|
||||
if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p =
|
||||
rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
|
||||
|
||||
if (ue_context_p) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg);
|
||||
rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p);
|
||||
} else {
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
|
||||
|
||||
if (ue_context_p) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg);
|
||||
rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p);
|
||||
} else {
|
||||
struct rrc_eNB_ue_context_s *ue_context_p =
|
||||
rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
|
||||
|
||||
if (ue_context_p) {
|
||||
/* The following is normally done in the function rrc_rx_tx() */
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
|
||||
|
||||
// erase data of GTP tunnels in UE context
|
||||
for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
|
||||
0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
|
||||
rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
|
||||
if (rrc_ue_s1ap_ids)
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
|
||||
|
||||
/* trigger UE release in RRC */
|
||||
rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
|
||||
} else {
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
|
||||
pdcp_remove_UE(&ctxt);
|
||||
|
||||
@@ -58,38 +58,19 @@
|
||||
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||
|
||||
int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/* DL RRC Message Transfer */
|
||||
int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
LOG_I(F1AP, "node is gNB DU, call DU_handle_DL_NR_RRC_MESSAGE_TRANSFER \n");
|
||||
return DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance, assoc_id, stream, pdu);
|
||||
}
|
||||
|
||||
LOG_W(F1AP, "DU_handle_DL_RRC_MESSAGE_TRANSFER is a big race condition with rrc \n");
|
||||
F1AP_DLRRCMessageTransfer_t *container;
|
||||
F1AP_DLRRCMessageTransferIEs_t *ie;
|
||||
uint64_t cu_ue_f1ap_id;
|
||||
uint64_t du_ue_f1ap_id;
|
||||
int executeDuplication;
|
||||
sdu_size_t rrc_dl_sdu_len;
|
||||
//uint64_t subscriberProfileIDforRFP;
|
||||
//uint64_t rAT_FrequencySelectionPriority;
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if (stream != 0) {
|
||||
LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
|
||||
/* GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
@@ -102,8 +83,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n",
|
||||
du_ue_f1ap_id,
|
||||
f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id));
|
||||
// this should be the one transmitted via initial ul rrc message transfer
|
||||
f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer
|
||||
|
||||
if (f1ap_du_add_cu_ue_id(instance,du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) {
|
||||
LOG_E(F1AP, "Failed to find the F1AP UID \n");
|
||||
@@ -138,8 +118,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
/* RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
rrc_dl_sdu_len = ie->value.choice.RRCContainer.size;
|
||||
|
||||
/* optional */
|
||||
/* RAT_FrequencyPriorityInformation */
|
||||
if (0) {
|
||||
@@ -161,359 +139,25 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
}
|
||||
}
|
||||
|
||||
f1ap_dl_rrc_message_t dl_rrc = {
|
||||
.rrc_container_length = ie->value.choice.RRCContainer.size,
|
||||
.rrc_container = ie->value.choice.RRCContainer.buf,
|
||||
.rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id),
|
||||
.srb_id = srb_id
|
||||
};
|
||||
int rc = dl_rrc_message(instance, &dl_rrc);
|
||||
if (rc == 0)
|
||||
return 0; /* has been handled, otherwise continue below */
|
||||
|
||||
// decode RRC Container and act on the message type
|
||||
AssertFatal(srb_id<3,"illegal srb_id\n");
|
||||
protocol_ctxt_t ctxt;
|
||||
ctxt.rntiMaybeUEid = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id);
|
||||
ctxt.instance = instance;
|
||||
ctxt.module_id = instance;
|
||||
ctxt.enb_flag = 1;
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rntiMaybeUEid);
|
||||
|
||||
if (srb_id == 0) {
|
||||
LTE_DL_CCCH_Message_t *dl_ccch_msg=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_LTE_DL_CCCH_Message,
|
||||
(void **)&dl_ccch_msg,
|
||||
ie->value.choice.RRCContainer.buf,
|
||||
rrc_dl_sdu_len,0,0);
|
||||
AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n");
|
||||
|
||||
switch (dl_ccch_msg->message.choice.c1.present) {
|
||||
case LTE_DL_CCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(F1AP, "Received PR_NOTHING on DL-CCCH-Message\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment:
|
||||
LOG_I(F1AP,
|
||||
"Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject:
|
||||
LOG_I(F1AP,
|
||||
"Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject:
|
||||
LOG_I(F1AP,
|
||||
"Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n");
|
||||
break;
|
||||
|
||||
case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: {
|
||||
LOG_I(F1AP,
|
||||
"Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup DU_ID %lx/RNTI %x\n",
|
||||
du_ue_f1ap_id,
|
||||
f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id));
|
||||
// Get configuration
|
||||
LTE_RRCConnectionSetup_t *rrcConnectionSetup = &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup;
|
||||
AssertFatal(rrcConnectionSetup!=NULL,"rrcConnectionSetup is null\n");
|
||||
LTE_RadioResourceConfigDedicated_t *radioResourceConfigDedicated = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated;
|
||||
// get SRB logical channel information
|
||||
LTE_SRB_ToAddModList_t *SRB_configList = radioResourceConfigDedicated->srb_ToAddModList;
|
||||
AssertFatal(SRB_configList!=NULL,"SRB_configList is null\n");
|
||||
LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL;
|
||||
|
||||
for (int cnt = 0; cnt < (SRB_configList)->list.count; cnt++) {
|
||||
if ((SRB_configList)->list.array[cnt]->srb_Identity == 1) {
|
||||
LTE_SRB_ToAddMod_t * SRB1_config = (SRB_configList)->list.array[cnt];
|
||||
|
||||
if (SRB1_config->logicalChannelConfig) {
|
||||
if (SRB1_config->logicalChannelConfig->present ==
|
||||
LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
|
||||
SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
|
||||
} else {
|
||||
SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
|
||||
}
|
||||
} else {
|
||||
SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
||||
rrc_rlc_config_asn1_req(&ctxt,
|
||||
SRB_configList,
|
||||
(LTE_DRB_ToAddModList_t *) NULL,
|
||||
(LTE_DRB_ToReleaseList_t *) NULL
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL,
|
||||
0,0
|
||||
);
|
||||
// This should be somewhere in the f1ap_cudu_ue_inst_t
|
||||
/*int macrlc_instance = 0;
|
||||
|
||||
rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id);
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[macrlc_instance],rnti);
|
||||
*/
|
||||
eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
|
||||
AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
|
||||
memcpy((void *)ue_p->Srb0.Tx_buffer.Payload,
|
||||
(void *)ie->value.choice.RRCContainer.buf,
|
||||
rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
|
||||
ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
|
||||
LTE_MAC_MainConfig_t *mac_MainConfig = NULL;
|
||||
|
||||
if (radioResourceConfigDedicated->mac_MainConfig)
|
||||
mac_MainConfig = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue;
|
||||
rrc_mac_config_req_eNB_t tmp = {0};
|
||||
tmp.rnti = ctxt.rntiMaybeUEid;
|
||||
tmp.physicalConfigDedicated = radioResourceConfigDedicated->physicalConfigDedicated;
|
||||
tmp.mac_MainConfig = mac_MainConfig;
|
||||
tmp.logicalChannelIdentity = 1;
|
||||
tmp.logicalChannelConfig = SRB1_logicalChannelConfig;
|
||||
rrc_mac_config_req_eNB(ctxt.instance, &tmp);
|
||||
break;
|
||||
} // case
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,
|
||||
"Unknown message\n");
|
||||
break;
|
||||
}// switch case
|
||||
|
||||
return(0);
|
||||
} else if (srb_id == 1) {
|
||||
LTE_DL_DCCH_Message_t *dl_dcch_msg=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_LTE_DL_DCCH_Message,
|
||||
(void **)&dl_dcch_msg,
|
||||
&ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
|
||||
rrc_dl_sdu_len,0,0);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
|
||||
LOG_E(F1AP," Failed to decode DL-DCCH (%zu bytes)\n",dec_rval.consumed);
|
||||
else
|
||||
LOG_D(F1AP, "Received message: present %d and c1 present %d\n",
|
||||
dl_dcch_msg->message.present, dl_dcch_msg->message.choice.c1.present);
|
||||
|
||||
if (dl_dcch_msg->message.present == LTE_DL_DCCH_MessageType_PR_c1) {
|
||||
switch (dl_dcch_msg->message.choice.c1.present) {
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_NOTHING:
|
||||
LOG_I(F1AP, "Received PR_NOTHING on DL-DCCH-Message\n");
|
||||
return 0;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
|
||||
LOG_I(F1AP,"Received NAS DL Information Transfer\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000:
|
||||
LOG_I(F1AP,"Received NAS sfbParametersResponseCDMA2000\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest:
|
||||
LOG_I(F1AP,"Received NAS andoverFromEUTRAPreparationRequest\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand:
|
||||
LOG_I(F1AP,"Received NAS mobilityFromEUTRACommand\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration:
|
||||
// handle RRCConnectionReconfiguration
|
||||
LOG_I(F1AP,
|
||||
"Logical Channel DL-DCCH (SRB1), Received RRCConnectionReconfiguration DU_ID %lx/RNTI %x\n",
|
||||
du_ue_f1ap_id,
|
||||
f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id));
|
||||
LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration = &dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration;
|
||||
|
||||
if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) {
|
||||
if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present ==
|
||||
LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) {
|
||||
LTE_RRCConnectionReconfiguration_r8_IEs_t *rrcConnectionReconfiguration_r8 =
|
||||
&rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8;
|
||||
|
||||
if (rrcConnectionReconfiguration_r8->mobilityControlInfo) {
|
||||
LOG_I(F1AP, "Mobility Control Information is present\n");
|
||||
AssertFatal(1==0,"Can't handle this yet in DU\n");
|
||||
}
|
||||
|
||||
if (rrcConnectionReconfiguration_r8->measConfig != NULL) {
|
||||
LOG_I(F1AP, "Measurement Configuration is present\n");
|
||||
}
|
||||
|
||||
if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated) {
|
||||
LOG_I(F1AP, "Radio Resource Configuration is present\n");
|
||||
uint8_t DRB2LCHAN[8];
|
||||
long drb_id;
|
||||
int i;
|
||||
LTE_DRB_ToAddModList_t *DRB_configList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToAddModList;
|
||||
LTE_SRB_ToAddModList_t *SRB_configList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->srb_ToAddModList;
|
||||
LTE_DRB_ToReleaseList_t *DRB_ReleaseList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToReleaseList;
|
||||
LTE_MAC_MainConfig_t *mac_MainConfig = NULL;
|
||||
|
||||
for (i = 0; i< 8; i++) {
|
||||
DRB2LCHAN[i] = 0;
|
||||
}
|
||||
|
||||
if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) {
|
||||
LOG_D(F1AP, "MAC Main Configuration is present\n");
|
||||
mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue;
|
||||
|
||||
/* CDRX Configuration */
|
||||
if (mac_MainConfig->drx_Config == NULL) {
|
||||
LOG_W(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n");
|
||||
} else {
|
||||
rrc_mac_drx_config_req_t req = {.rnti = ctxt.rntiMaybeUEid, .drx_Configuration = mac_MainConfig->drx_Config};
|
||||
/* Send DRX configuration to MAC task to configure timers of local UE context */
|
||||
eNB_Config_Local_DRX(instance, &req);
|
||||
LOG_D(F1AP, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n");
|
||||
}
|
||||
|
||||
/* End of CDRX configuration */
|
||||
}
|
||||
|
||||
LTE_MeasGapConfig_t *measGapConfig = NULL;
|
||||
struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated;
|
||||
rrc_rlc_config_asn1_req(
|
||||
&ctxt,
|
||||
SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList,
|
||||
DRB_configList,
|
||||
DRB_ReleaseList, (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0
|
||||
);
|
||||
|
||||
if (SRB_configList != NULL) {
|
||||
for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) {
|
||||
if (SRB_configList->list.array[i]->srb_Identity == 1 ) {
|
||||
ue_context_p->ue_context.Srb1.Active=1;
|
||||
} else if (SRB_configList->list.array[i]->srb_Identity == 2 ) {
|
||||
ue_context_p->ue_context.Srb2.Active=1;
|
||||
ue_context_p->ue_context.Srb2.Srb_info.Srb_id=2;
|
||||
LOG_I(F1AP, "[DU %ld] SRB2 is now active\n",ctxt.instance);
|
||||
} else {
|
||||
LOG_W(F1AP, "[DU %ld] invalid SRB identity %ld\n",ctxt.instance,
|
||||
SRB_configList->list.array[i]->srb_Identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DRB_configList != NULL) {
|
||||
for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8)
|
||||
if (DRB_configList->list.array[i]) {
|
||||
drb_id = (int)DRB_configList->list.array[i]->drb_Identity;
|
||||
LOG_I(F1AP,
|
||||
"[DU %ld] Logical Channel UL-DCCH, Received RRCConnectionReconfiguration for UE rnti %lx, reconfiguring DRB %d/LCID %d\n",
|
||||
ctxt.instance,
|
||||
ctxt.rntiMaybeUEid,
|
||||
(int)DRB_configList->list.array[i]->drb_Identity,
|
||||
(int)*DRB_configList->list.array[i]->logicalChannelIdentity);
|
||||
|
||||
if (ue_context_p->ue_context.DRB_active[drb_id] == 0) {
|
||||
ue_context_p->ue_context.DRB_active[drb_id] = 1;
|
||||
|
||||
if (DRB_configList->list.array[i]->logicalChannelIdentity) {
|
||||
DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
|
||||
}
|
||||
rrc_mac_config_req_eNB_t tmp = {0};
|
||||
tmp.rnti = ue_context_p->ue_context.rnti;
|
||||
tmp.physicalConfigDedicated = physicalConfigDedicated;
|
||||
tmp.mac_MainConfig = mac_MainConfig;
|
||||
tmp.logicalChannelIdentity = DRB2LCHAN[i];
|
||||
tmp.logicalChannelConfig = DRB_configList->list.array[i]->logicalChannelConfig;
|
||||
tmp.measGapConfig = measGapConfig;
|
||||
rrc_mac_config_req_eNB(ctxt.instance, &tmp);
|
||||
}
|
||||
} else { // remove LCHAN from MAC/PHY
|
||||
AssertFatal(1==0,"Can't handle this yet in DU\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
|
||||
// handle RRCConnectionRelease
|
||||
LOG_I(F1AP, "Received RRCConnectionRelease\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand:
|
||||
LOG_I(F1AP, "Received securityModeCommand\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
|
||||
LOG_I(F1AP, "Received ueCapabilityEnquiry\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_counterCheck:
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10:
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10:
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_spare1:
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_spare2:
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_spare3:
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9:
|
||||
LOG_I(F1AP, "Received ueInformationRequest_r9\n");
|
||||
break;
|
||||
|
||||
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionResume_r13:
|
||||
LOG_I(F1AP, "Received rrcConnectionResume_r13\n");
|
||||
}
|
||||
}
|
||||
} else if (srb_id == 2) {
|
||||
}
|
||||
|
||||
LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", srb_id);
|
||||
rlc_op_status_t rlc_status;
|
||||
bool ret = true;
|
||||
mem_block_t *pdcp_pdu_p = NULL;
|
||||
pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__);
|
||||
|
||||
//LOG_I(F1AP, "PRRCContainer size %lu:", ie->value.choice.RRCContainer.size);
|
||||
//for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
|
||||
// printf("%02x ", ie->value.choice.RRCContainer.buf[i]);
|
||||
|
||||
//printf (", PDCP PDU size %d:", rrc_dl_sdu_len);
|
||||
//for (int i=0;i<rrc_dl_sdu_len;i++) printf("%2x ",pdcp_pdu_p->data[i]);
|
||||
//printf("\n");
|
||||
|
||||
if (pdcp_pdu_p != NULL) {
|
||||
memset(pdcp_pdu_p->data, 0, rrc_dl_sdu_len);
|
||||
memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, rrc_dl_sdu_len);
|
||||
rlc_status = rlc_data_req(&ctxt
|
||||
, 1
|
||||
, MBMS_FLAG_NO
|
||||
, srb_id
|
||||
, 0
|
||||
, 0
|
||||
, rrc_dl_sdu_len
|
||||
, pdcp_pdu_p
|
||||
,NULL
|
||||
,NULL
|
||||
);
|
||||
|
||||
switch (rlc_status) {
|
||||
case RLC_OP_STATUS_OK:
|
||||
//LOG_I(F1AP, "Data sending request over RLC succeeded!\n");
|
||||
ret=true;
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_BAD_PARAMETER:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
|
||||
ret= false;
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_INTERNAL_ERROR:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
|
||||
ret= false;
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_OUT_OF_RESSOURCES:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
|
||||
ret= false;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
|
||||
ret= false;
|
||||
break;
|
||||
} // switch case
|
||||
|
||||
return ret;
|
||||
} // if pdcp_pdu_p
|
||||
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_DU_F1, 0, NR_DU_RRC_DL_INDICATION);
|
||||
NRDuDlReq_t *req=&NRDuDlReq(msg);
|
||||
req->rnti=f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id);
|
||||
req->srb_id=srb_id;
|
||||
req->buf= get_free_mem_block( ie->value.choice.RRCContainer.size, __func__);
|
||||
memcpy(req->buf->data, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -839,119 +483,3 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
f1ap_itti_send_sctp_data_req(false, instance, buffer, len, getCxt(DUtype, instance)->default_sctp_stream_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DL NR RRC Message Transfer */
|
||||
int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
LOG_D(F1AP, "DU_handle_DL_NR_RRC_MESSAGE_TRANSFER \n");
|
||||
F1AP_DLRRCMessageTransfer_t *container;
|
||||
F1AP_DLRRCMessageTransferIEs_t *ie;
|
||||
uint64_t cu_ue_f1ap_id;
|
||||
uint64_t du_ue_f1ap_id;
|
||||
int executeDuplication;
|
||||
//uint64_t subscriberProfileIDforRFP;
|
||||
//uint64_t rAT_FrequencySelectionPriority;
|
||||
DevAssert(pdu != NULL);
|
||||
container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
|
||||
/* GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id);
|
||||
/* GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n",
|
||||
du_ue_f1ap_id,
|
||||
f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer
|
||||
|
||||
if (f1ap_du_add_cu_ue_id(instance,du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) {
|
||||
LOG_E(F1AP, "Failed to find the F1AP UID \n");
|
||||
//return -1;
|
||||
}
|
||||
|
||||
/* optional */
|
||||
/* oldgNB_DU_UE_F1AP_ID */
|
||||
if (0) {
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* SRBID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_SRBID, true);
|
||||
uint64_t srb_id = ie->value.choice.SRBID;
|
||||
LOG_D(F1AP, "srb_id %lu \n", srb_id);
|
||||
|
||||
/* optional */
|
||||
/* ExecuteDuplication */
|
||||
if (0) {
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_ExecuteDuplication, true);
|
||||
executeDuplication = ie->value.choice.ExecuteDuplication;
|
||||
LOG_D(F1AP, "ExecuteDuplication %d \n", executeDuplication);
|
||||
}
|
||||
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
// BK: need check
|
||||
// create an ITTI message and copy SDU
|
||||
// message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND);
|
||||
// memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
|
||||
// memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
|
||||
// ccch_sdu_len);
|
||||
|
||||
//LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size);
|
||||
//for (int i = 0;i < ie->value.choice.RRCContainer.size; i++)
|
||||
// printf("%02x ", ie->value.choice.RRCContainer.buf[i]);
|
||||
//printf("\n");
|
||||
|
||||
/* optional */
|
||||
/* RAT_FrequencyPriorityInformation */
|
||||
if (0) {
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true);
|
||||
|
||||
switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) {
|
||||
case F1AP_RAT_FrequencyPriorityInformation_PR_eNDC:
|
||||
//subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP;
|
||||
break;
|
||||
|
||||
case F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN:
|
||||
//rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_W(F1AP, "unhandled IE RAT_FrequencyPriorityInformation.present\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f1ap_dl_rrc_message_t dl_rrc = {
|
||||
.rrc_container_length = ie->value.choice.RRCContainer.size,
|
||||
.rrc_container = ie->value.choice.RRCContainer.buf,
|
||||
.rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id),
|
||||
.srb_id = srb_id
|
||||
};
|
||||
int rc = dl_rrc_message(instance, &dl_rrc);
|
||||
if (rc == 0)
|
||||
return 0; /* has been handled, otherwise continue below */
|
||||
|
||||
// decode RRC Container and act on the message type
|
||||
AssertFatal(srb_id<3,"illegal srb_id\n");
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_DU_F1, 0, NR_DU_RRC_DL_INDICATION);
|
||||
NRDuDlReq_t *req=&NRDuDlReq(msg);
|
||||
req->rnti=f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id);
|
||||
req->srb_id=srb_id;
|
||||
req->buf= get_free_mem_block( ie->value.choice.RRCContainer.size, __func__);
|
||||
memcpy(req->buf->data, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -150,14 +150,7 @@ void *F1AP_DU_task(void *arg) {
|
||||
} break;
|
||||
|
||||
case F1AP_UL_RRC_MESSAGE: // to rrc
|
||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
|
||||
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance,
|
||||
&F1AP_UL_RRC_MESSAGE(msg));
|
||||
} else {
|
||||
DU_send_UL_RRC_MESSAGE_TRANSFER(myInstance,
|
||||
&F1AP_UL_RRC_MESSAGE(msg));
|
||||
}
|
||||
|
||||
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, &F1AP_UL_RRC_MESSAGE(msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_SETUP_RESP:
|
||||
|
||||
@@ -182,23 +182,6 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
drb_p->rlc_mode = RLC_MODE_TM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU)) {
|
||||
transport_layer_addr_t addr;
|
||||
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;
|
||||
drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||
f1ap_ue_context_setup_req->rnti,
|
||||
drb_p->drb_id,
|
||||
drb_p->drb_id,
|
||||
drb_p->up_ul_tnl[0].teid,
|
||||
-1, // no qfi
|
||||
addr,
|
||||
drb_p->up_ul_tnl[0].port,
|
||||
lteDURecvCb,
|
||||
NULL);
|
||||
drb_p->up_dl_tnl_length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,11 +225,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
LOG_W(F1AP, "can't find RRCContainer in UEContextSetupRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
|
||||
}
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU)
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
|
||||
else
|
||||
// in 4G, race conditon is to fix
|
||||
DU_send_UE_CONTEXT_SETUP_RESPONSE(instance, f1ap_ue_context_setup_req);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -670,146 +649,6 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
|
||||
getCxt(false, instance)->default_sctp_stream_id);
|
||||
return 0;
|
||||
}
|
||||
/*int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
F1AP_UEContextReleaseCommand_t *container;
|
||||
F1AP_UEContextReleaseCommandIEs_t *ie;
|
||||
protocol_ctxt_t ctxt;
|
||||
DevAssert(pdu);
|
||||
container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand;
|
||||
// GNB_CU_UE_F1AP_ID
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
ctxt.rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID);
|
||||
ctxt.instance = instance;
|
||||
ctxt.module_id = instance;
|
||||
ctxt.enb_flag = 1;
|
||||
// GNB_DU_UE_F1AP_ID
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance,
|
||||
ie->value.choice.GNB_DU_UE_F1AP_ID);
|
||||
AssertFatal(ctxt.rnti == rnti,
|
||||
"RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
|
||||
rnti, ctxt.rnti);
|
||||
int UE_out_of_sync = 0;
|
||||
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
UE_iterator(RC.nrmac[instance]->UE_info.list, UE) {
|
||||
if (UE->rnti == rnti) {
|
||||
UE_out_of_sync = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!UE)
|
||||
LOG_E(F1AP,"Not found rnti: %x\n", rnti);
|
||||
} else {
|
||||
for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
|
||||
if (RC.mac[instance]->UE_info.active[n] == true
|
||||
&& rnti == UE_RNTI(instance, n)) {
|
||||
UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need the Cause
|
||||
// Optional RRC Container: if present, send to UE
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, false);
|
||||
|
||||
if (ie && !UE_out_of_sync) {
|
||||
// RRC message and UE is reachable, send message
|
||||
const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size;
|
||||
mem_block_t *pdu_p = NULL;
|
||||
pdu_p = get_free_mem_block(sdu_len, __func__);
|
||||
memcpy(&pdu_p->data[0], ie->value.choice.RRCContainer.buf, sdu_len);
|
||||
rlc_op_status_t rlc_status = rlc_data_req(&ctxt
|
||||
, 1
|
||||
, MBMS_FLAG_NO
|
||||
, 1 // SRB 1 correct?
|
||||
, 0
|
||||
, 0
|
||||
, sdu_len
|
||||
, pdu_p
|
||||
,NULL
|
||||
,NULL
|
||||
);
|
||||
|
||||
switch (rlc_status) {
|
||||
case RLC_OP_STATUS_OK:
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_BAD_PARAMETER:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_INTERNAL_ERROR:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_OUT_OF_RESSOURCES:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_W(F1AP, "RLC returned an unknown status code after F1AP placed "
|
||||
"the order to send some data (Status Code:%d)\n", rlc_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
// struct rrc_gNB_ue_context_s *ue_context_p;
|
||||
f1ap_ue_context_release_cplt_t cplt;
|
||||
cplt.rnti = ctxt.rnti;
|
||||
DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
|
||||
return 0;
|
||||
} else {
|
||||
struct rrc_eNB_ue_context_s *ue_context_p;
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rnti);
|
||||
|
||||
if (ue_context_p && !UE_out_of_sync) {
|
||||
// UE exists and is in sync so we start a timer before releasing the
|
||||
// connection
|
||||
pthread_mutex_lock(&rrc_release_freelist);
|
||||
|
||||
for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
|
||||
if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
|
||||
if (ue_context_p->ue_context.ue_release_timer_s1 > 0)
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
|
||||
else
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
|
||||
|
||||
rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt.rnti;
|
||||
LOG_D(F1AP, "add rrc_release_info RNTI %x\n", ctxt.rnti);
|
||||
// TODO: how to provide the correct MUI?
|
||||
rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = 0;
|
||||
rrc_release_info.num_UEs++;
|
||||
LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num,
|
||||
ctxt.rnti, 0, rrc_release_info.RRC_release_ctrl[release_num].flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&rrc_release_freelist);
|
||||
ue_context_p->ue_context.ue_release_timer_s1 = 0;
|
||||
} else if (ue_context_p && UE_out_of_sync) {
|
||||
// UE exists and is out of sync, drop the connection
|
||||
mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti);
|
||||
} else {
|
||||
LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti);
|
||||
}
|
||||
|
||||
// TODO send this once the connection has really been released
|
||||
f1ap_ue_context_release_cplt_t cplt;
|
||||
cplt.rnti = ctxt.rnti;
|
||||
DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
@@ -817,7 +656,6 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
F1AP_UEContextReleaseCommand_t *container;
|
||||
F1AP_UEContextReleaseCommandIEs_t *ie;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
/* ITTI message to NR-RRC for the case of gNB-DU */
|
||||
MessageDef *msg_p; // message to NR-RRC
|
||||
@@ -830,159 +668,48 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
// GNB_CU_UE_F1AP_ID
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
if(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU){
|
||||
f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID);
|
||||
}
|
||||
else{
|
||||
ctxt.rntiMaybeUEid = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID);
|
||||
ctxt.instance = instance;
|
||||
ctxt.module_id = instance;
|
||||
ctxt.enb_flag = 1;
|
||||
}
|
||||
f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID);
|
||||
// GNB_DU_UE_F1AP_ID
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance,
|
||||
ie->value.choice.GNB_DU_UE_F1AP_ID);
|
||||
if(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU){
|
||||
AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti,
|
||||
"RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
|
||||
rnti, f1ap_ue_context_release_cmd->rnti);
|
||||
}
|
||||
else{
|
||||
AssertFatal(ctxt.rntiMaybeUEid == rnti, "RNTI obtained through DU ID (%x) is different from CU ID (%lx)\n", rnti, ctxt.rntiMaybeUEid);
|
||||
}
|
||||
int UE_out_of_sync = 0;
|
||||
|
||||
if(RC.rrc && RC.rrc[instance]->node_type == ngran_eNB_DU){
|
||||
for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
|
||||
if (RC.mac[instance]->UE_info.active[n] == true
|
||||
&& rnti == UE_RNTI(instance, n)) {
|
||||
UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", rnti, f1ap_ue_context_release_cmd->rnti);
|
||||
|
||||
// We don't need the Cause
|
||||
// Optional RRC Container: if present, send to UE
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, false);
|
||||
|
||||
if (ie && !UE_out_of_sync && RC.rrc && RC.rrc[instance]->node_type == ngran_eNB_DU) {
|
||||
// RRC message and UE is reachable, send message
|
||||
const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size;
|
||||
mem_block_t *pdu_p = NULL;
|
||||
pdu_p = get_free_mem_block(sdu_len, __func__);
|
||||
memcpy(&pdu_p->data[0], ie->value.choice.RRCContainer.buf, sdu_len);
|
||||
rlc_op_status_t rlc_status = rlc_data_req(&ctxt
|
||||
, 1
|
||||
, MBMS_FLAG_NO
|
||||
, 1 // SRB 1 correct?
|
||||
, 0
|
||||
, 0
|
||||
, sdu_len
|
||||
, pdu_p
|
||||
,NULL
|
||||
,NULL
|
||||
);
|
||||
f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size);
|
||||
memcpy(f1ap_ue_context_release_cmd->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
|
||||
|
||||
switch (rlc_status) {
|
||||
case RLC_OP_STATUS_OK:
|
||||
break;
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_Cause, true);
|
||||
switch (ie->value.choice.Cause.present){
|
||||
case F1AP_Cause_PR_radioNetwork:
|
||||
LOG_W (F1AP, "UE context release command cause is due to radioNetwork with specific code: %ld\n",ie->value.choice.Cause.choice.radioNetwork);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||
break;
|
||||
case F1AP_Cause_PR_transport:
|
||||
LOG_W (F1AP, "UE context release command cause is due to transport with specific code: %ld\n",ie->value.choice.Cause.choice.transport);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT;
|
||||
break;
|
||||
case F1AP_Cause_PR_protocol:
|
||||
LOG_W (F1AP, "UE context release command cause is due to protocol with specific code: %ld\n",ie->value.choice.Cause.choice.protocol);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL;
|
||||
break;
|
||||
case F1AP_Cause_PR_misc:
|
||||
LOG_W (F1AP, "UE context release command cause is misc with specific code: %ld \n",ie->value.choice.Cause.choice.misc);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC;
|
||||
break;
|
||||
default:
|
||||
LOG_W(F1AP, "Unknown cause for UE context release command\n");
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_BAD_PARAMETER:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_INTERNAL_ERROR:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
|
||||
break;
|
||||
|
||||
case RLC_OP_STATUS_OUT_OF_RESSOURCES:
|
||||
LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_W(F1AP, "RLC returned an unknown status code after F1AP placed "
|
||||
"the order to send some data (Status Code:%d)\n", rlc_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(ie && RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size);
|
||||
memcpy(f1ap_ue_context_release_cmd->rrc_container,
|
||||
ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
|
||||
}
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_Cause, true);
|
||||
switch (ie->value.choice.Cause.present){
|
||||
case F1AP_Cause_PR_radioNetwork:
|
||||
LOG_W (F1AP, "UE context release command cause is due to radioNetwork with specific code: %ld\n",ie->value.choice.Cause.choice.radioNetwork);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||
break;
|
||||
case F1AP_Cause_PR_transport:
|
||||
LOG_W (F1AP, "UE context release command cause is due to transport with specific code: %ld\n",ie->value.choice.Cause.choice.transport);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT;
|
||||
break;
|
||||
case F1AP_Cause_PR_protocol:
|
||||
LOG_W (F1AP, "UE context release command cause is due to protocol with specific code: %ld\n",ie->value.choice.Cause.choice.protocol);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL;
|
||||
break;
|
||||
case F1AP_Cause_PR_misc:
|
||||
LOG_W (F1AP, "UE context release command cause is misc with specific code: %ld \n",ie->value.choice.Cause.choice.misc);
|
||||
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC;
|
||||
break;
|
||||
default:
|
||||
LOG_W(F1AP, "Unknown cause for UE context release command\n");
|
||||
break;
|
||||
|
||||
}
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
|
||||
return 0;
|
||||
} else {
|
||||
struct rrc_eNB_ue_context_s *ue_context_p;
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rntiMaybeUEid);
|
||||
|
||||
if (ue_context_p && !UE_out_of_sync) {
|
||||
// UE exists and is in sync so we start a timer before releasing the
|
||||
// connection
|
||||
pthread_mutex_lock(&rrc_release_freelist);
|
||||
|
||||
for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
|
||||
if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
|
||||
if (ue_context_p->ue_context.ue_release_timer_s1 > 0)
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
|
||||
else
|
||||
rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
|
||||
|
||||
rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt.rntiMaybeUEid;
|
||||
LOG_D(F1AP, "add rrc_release_info RNTI %lx\n", ctxt.rntiMaybeUEid);
|
||||
// TODO: how to provide the correct MUI?
|
||||
rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = 0;
|
||||
rrc_release_info.num_UEs++;
|
||||
LOG_D(RRC, "Generate DLSCH Release send: index %d rnti %lx mui %d flag %d \n", release_num, ctxt.rntiMaybeUEid, 0, rrc_release_info.RRC_release_ctrl[release_num].flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&rrc_release_freelist);
|
||||
ue_context_p->ue_context.ue_release_timer_s1 = 0;
|
||||
} else if (ue_context_p && UE_out_of_sync) {
|
||||
// UE exists and is out of sync, drop the connection
|
||||
mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti);
|
||||
} else {
|
||||
LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti);
|
||||
}
|
||||
|
||||
// TODO send this once the connection has really been released
|
||||
f1ap_ue_context_release_cplt_t cplt;
|
||||
cplt.rnti = ctxt.rntiMaybeUEid;
|
||||
DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
|
||||
return 0;
|
||||
}
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
@@ -1199,22 +926,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
||||
drb_p->rlc_mode = RLC_MODE_TM;
|
||||
break;
|
||||
}
|
||||
if (!(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU)) {
|
||||
transport_layer_addr_t addr;
|
||||
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;
|
||||
drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||
f1ap_ue_context_modification_req->rnti,
|
||||
drb_p->drb_id,
|
||||
drb_p->drb_id,
|
||||
drb_p->up_ul_tnl[0].teid,
|
||||
-1, // no qfi
|
||||
addr,
|
||||
drb_p->up_ul_tnl[0].port,
|
||||
lteDURecvCb,
|
||||
NULL);
|
||||
drb_p->up_dl_tnl_length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* RRC Reconfiguration Complete indicator */
|
||||
|
||||
Reference in New Issue
Block a user