Merge remote-tracking branch 'origin/F1_interop_ACC_n78' into integration_2022_wk25
This commit is contained in:
@@ -251,7 +251,6 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
|||||||
|
|
||||||
if (number_dl_pdu>0)
|
if (number_dl_pdu>0)
|
||||||
oai_nfapi_dl_tti_req(DL_req);
|
oai_nfapi_dl_tti_req(DL_req);
|
||||||
|
|
||||||
}
|
}
|
||||||
stop_meas(&gNB->schedule_response_stats);
|
stop_meas(&gNB->schedule_response_stats);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc
|
|||||||
//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
|
//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
|
||||||
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req)
|
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req)
|
||||||
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp)
|
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp)
|
||||||
|
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req)
|
||||||
|
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,15 +39,15 @@
|
|||||||
#define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message
|
#define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message
|
||||||
#define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message
|
#define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message
|
||||||
#define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req
|
#define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req
|
||||||
#define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp
|
#define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp
|
||||||
#define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp
|
#define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp
|
||||||
|
#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req
|
||||||
#define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp
|
#define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp
|
||||||
#define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail
|
#define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail
|
||||||
|
|
||||||
#define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message
|
#define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message
|
||||||
#define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
|
#define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
|
||||||
#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
|
#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
|
||||||
#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req
|
|
||||||
|
|
||||||
/* Length of the transport layer address string
|
/* Length of the transport layer address string
|
||||||
* 160 bits / 8 bits by char.
|
* 160 bits / 8 bits by char.
|
||||||
@@ -345,6 +345,35 @@ typedef struct f1ap_rb_failed_to_be_setup_s {
|
|||||||
long rb_id;
|
long rb_id;
|
||||||
} f1ap_rb_failed_to_be_setup_t;
|
} f1ap_rb_failed_to_be_setup_t;
|
||||||
|
|
||||||
|
typedef struct cu_to_du_rrc_information_s {
|
||||||
|
uint8_t * cG_ConfigInfo;
|
||||||
|
uint32_t cG_ConfigInfo_length;
|
||||||
|
uint8_t * uE_CapabilityRAT_ContainerList;
|
||||||
|
uint32_t uE_CapabilityRAT_ContainerList_length;
|
||||||
|
uint8_t * measConfig;
|
||||||
|
uint32_t measConfig_length;
|
||||||
|
}cu_to_du_rrc_information_t;
|
||||||
|
|
||||||
|
typedef struct du_to_du_rrc_information_s {
|
||||||
|
uint8_t * cellGroupConfig;
|
||||||
|
uint8_t cellGroupConfig_length;
|
||||||
|
uint8_t * measGapConfig;
|
||||||
|
uint8_t measGapConfig_length;
|
||||||
|
uint8_t * requestedP_MaxFR1;
|
||||||
|
uint8_t requestedP_MaxFR1_length;
|
||||||
|
}du_to_cu_rrc_information_t;
|
||||||
|
|
||||||
|
typedef enum QoS_information_e {
|
||||||
|
NG_RAN_QoS = 0,
|
||||||
|
EUTRAN_QoS = 1,
|
||||||
|
} QoS_information_t;
|
||||||
|
|
||||||
|
typedef enum ReconfigurationCompl_e {
|
||||||
|
RRCreconf_info_not_present = 0,
|
||||||
|
RRCreconf_failure = 1,
|
||||||
|
RRCreconf_success = 2,
|
||||||
|
} ReconfigurationCompl_t;
|
||||||
|
|
||||||
typedef struct f1ap_ue_context_setup_s {
|
typedef struct f1ap_ue_context_setup_s {
|
||||||
uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti
|
uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti
|
||||||
uint32_t gNB_DU_ue_id;
|
uint32_t gNB_DU_ue_id;
|
||||||
@@ -357,40 +386,27 @@ typedef struct f1ap_ue_context_setup_s {
|
|||||||
uint8_t servCellIndex;
|
uint8_t servCellIndex;
|
||||||
uint8_t *cellULConfigured;
|
uint8_t *cellULConfigured;
|
||||||
uint32_t servCellId;
|
uint32_t servCellId;
|
||||||
uint8_t *cu_to_du_rrc_information;
|
cu_to_du_rrc_information_t *cu_to_du_rrc_information;
|
||||||
uint8_t cu_to_du_rrc_information_length;
|
uint8_t cu_to_du_rrc_information_length;
|
||||||
uint8_t *du_to_cu_rrc_information;
|
//uint8_t *du_to_cu_rrc_information;
|
||||||
uint8_t du_to_cu_rrc_information_length;
|
du_to_cu_rrc_information_t *du_to_cu_rrc_information;
|
||||||
f1ap_drb_to_be_setup_t *drbs_to_be_setup; // BK: need to replace by s1ap_initial_context_setup_req
|
uint32_t du_to_cu_rrc_information_length;
|
||||||
uint8_t drbs_to_be_setup_length; // BK: need to replace by s1ap_initial_context_setup_req
|
f1ap_drb_to_be_setup_t *drbs_to_be_setup;
|
||||||
|
uint8_t drbs_to_be_setup_length;
|
||||||
|
f1ap_drb_to_be_setup_t *drbs_to_be_modified;
|
||||||
|
uint8_t drbs_to_be_modified_length;
|
||||||
|
QoS_information_t QoS_information_type;
|
||||||
uint8_t drbs_failed_to_be_setup_length;
|
uint8_t drbs_failed_to_be_setup_length;
|
||||||
f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup;
|
f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup;
|
||||||
f1ap_srb_to_be_setup_t *srbs_to_be_setup;
|
f1ap_srb_to_be_setup_t *srbs_to_be_setup;
|
||||||
uint8_t srbs_to_be_setup_length;
|
uint8_t srbs_to_be_setup_length;
|
||||||
uint8_t srbs_failed_to_be_setup_length;
|
uint8_t srbs_failed_to_be_setup_length;
|
||||||
f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup;
|
f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup;
|
||||||
s1ap_initial_context_setup_req_t *s1ap_initial_context_setup_req;
|
ReconfigurationCompl_t ReconfigComplOutcome;
|
||||||
// coniatner for the rrc_eNB_generate_SecurityModeCommand message
|
|
||||||
uint8_t *rrc_container;
|
uint8_t *rrc_container;
|
||||||
int rrc_container_length;
|
int rrc_container_length;
|
||||||
} f1ap_ue_context_setup_t;
|
} f1ap_ue_context_setup_t;
|
||||||
|
|
||||||
typedef struct f1ap_ue_context_setup_resp_s {
|
|
||||||
uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti
|
|
||||||
uint32_t gNB_DU_ue_id;
|
|
||||||
uint16_t rnti;
|
|
||||||
uint8_t du_to_cu_rrc_information[1024 /*Arbitrarily big enough*/];
|
|
||||||
uint32_t du_to_cu_rrc_information_length;
|
|
||||||
f1ap_drb_to_be_setup_t *drbs_setup; // BK: need to replace by s1ap_initial_context_setup_req
|
|
||||||
uint8_t drbs_setup_length; // BK: need to replace by s1ap_initial_context_setup_req
|
|
||||||
f1ap_srb_to_be_setup_t *srbs_setup;
|
|
||||||
uint8_t srbs_setup_length;
|
|
||||||
uint8_t srbs_failed_to_be_setup_length;
|
|
||||||
f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup;
|
|
||||||
uint8_t drbs_failed_to_be_setup_length;
|
|
||||||
f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup;
|
|
||||||
} f1ap_ue_context_setup_resp_t;
|
|
||||||
|
|
||||||
typedef enum F1ap_Cause_e {
|
typedef enum F1ap_Cause_e {
|
||||||
F1AP_CAUSE_NOTHING, /* No components present */
|
F1AP_CAUSE_NOTHING, /* No components present */
|
||||||
F1AP_CAUSE_RADIO_NETWORK,
|
F1AP_CAUSE_RADIO_NETWORK,
|
||||||
|
|||||||
@@ -27,4 +27,5 @@ MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end
|
|||||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
|
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
|
||||||
MESSAGE_DEF(GTPV1U_REQ, MESSAGE_PRIORITY_MED, Gtpv1uReq, gtpv1uReq)
|
MESSAGE_DEF(GTPV1U_REQ, MESSAGE_PRIORITY_MED, Gtpv1uReq, gtpv1uReq)
|
||||||
|
|
||||||
MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq)
|
MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq)
|
||||||
|
MESSAGE_DEF(GTPV1U_DU_BUFFER_REPORT_REQ, MESSAGE_PRIORITY_MED, gtpv1u_DU_buffer_report_req_t, NRGtpv1uBufferReportReq)
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#define GTPV1U_GNB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uTunnelDataReq
|
#define GTPV1U_GNB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uTunnelDataReq
|
||||||
|
|
||||||
|
#define GTPV1U_DU_BUFFER_REPORT_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uBufferReportReq
|
||||||
|
|
||||||
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
|
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
|
||||||
|
|
||||||
typedef struct gtpv1u_enb_create_x2u_tunnel_req_s {
|
typedef struct gtpv1u_enb_create_x2u_tunnel_req_s {
|
||||||
@@ -213,4 +215,10 @@ typedef struct gtpv1u_gnb_tunnel_data_req_s {
|
|||||||
pdusessionid_t pdusession_id;
|
pdusessionid_t pdusession_id;
|
||||||
} gtpv1u_gnb_tunnel_data_req_t;
|
} gtpv1u_gnb_tunnel_data_req_t;
|
||||||
|
|
||||||
|
typedef struct gtpv1u_DU_buffer_report_req_s {
|
||||||
|
uint32_t buffer_availability;
|
||||||
|
rnti_t rnti;
|
||||||
|
pdusessionid_t pdusession_id;
|
||||||
|
} gtpv1u_DU_buffer_report_req_t;
|
||||||
|
|
||||||
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
|
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -180,6 +180,12 @@ void *F1AP_CU_task(void *arg) {
|
|||||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
||||||
|
LOG_I(F1AP, "CU Task received F1AP_UE_CONTEXT_MODIFICATION_REQ\n");
|
||||||
|
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||||
|
&F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
|
||||||
|
break;
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
||||||
LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n");
|
LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n");
|
||||||
CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -72,7 +72,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
|||||||
/*
|
/*
|
||||||
* UE Context Modification (gNB-CU initiated)
|
* UE Context Modification (gNB-CU initiated)
|
||||||
*/
|
*/
|
||||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance);
|
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
||||||
|
f1ap_ue_context_setup_t *f1ap_ue_context_modification_req);
|
||||||
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
||||||
uint32_t assoc_id,
|
uint32_t assoc_id,
|
||||||
uint32_t stream,
|
uint32_t stream,
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) {
|
|||||||
case F1AP_ProcedureCode_id_UEContextSetup:
|
case F1AP_ProcedureCode_id_UEContextSetup:
|
||||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
|
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F1AP_ProcedureCode_id_UEContextModification:
|
||||||
|
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
// case F1AP_ProcedureCode_id_InitialContextSetup:
|
// case F1AP_ProcedureCode_id_InitialContextSetup:
|
||||||
// res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
// res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||||
@@ -123,6 +127,10 @@ static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu) {
|
|||||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
|
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F1AP_ProcedureCode_id_UEContextModification:
|
||||||
|
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n",
|
LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n",
|
||||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
#define ENB_NAME "Eurecom ENB"
|
#define ENB_NAME "Eurecom ENB"
|
||||||
#define ENB_NAME_FORMAT (ENB_NAME" %u")
|
#define ENB_NAME_FORMAT (ENB_NAME" %u")
|
||||||
|
|
||||||
#define F1AP_PORT_NUMBER (30923)
|
#define F1AP_PORT_NUMBER (38472)
|
||||||
#define F1AP_SCTP_PPID (62)
|
#define F1AP_SCTP_PPID (62)
|
||||||
|
|
||||||
#endif /* F1AP_DEFAULT_VALUES_H_ */
|
#endif /* F1AP_DEFAULT_VALUES_H_ */
|
||||||
|
|||||||
@@ -172,7 +172,20 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
|
|||||||
MCC_MNC_TO_PLMNID(cell->mcc, cell->mnc, cell->mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
MCC_MNC_TO_PLMNID(cell->mcc, cell->mnc, cell->mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||||
// // /* - CHOICE NR-MODE-Info */
|
// // /* - CHOICE NR-MODE-Info */
|
||||||
F1AP_NR_Mode_Info_t *nR_Mode_Info= &served_cell_information->nR_Mode_Info;
|
F1AP_NR_Mode_Info_t *nR_Mode_Info= &served_cell_information->nR_Mode_Info;
|
||||||
|
F1AP_ProtocolExtensionContainer_154P34_t *p_154P34=calloc(1,sizeof(* p_154P34));
|
||||||
|
servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p_154P34;
|
||||||
|
asn1cSequenceAdd(p_154P34->list, F1AP_ServedPLMNs_ItemExtIEs_t , served_plmns_itemExtIEs);
|
||||||
|
served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore;
|
||||||
|
served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList;
|
||||||
|
served_plmns_itemExtIEs->extensionValue.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);
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -810,6 +810,13 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
|
|||||||
sdu2P,
|
sdu2P,
|
||||||
sdu2_lenP);
|
sdu2_lenP);
|
||||||
}
|
}
|
||||||
|
/* mandatory */
|
||||||
|
/* c6. Transaction ID (integer value) */
|
||||||
|
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6);
|
||||||
|
ie6->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||||
|
ie6->criticality = F1AP_Criticality_ignore;
|
||||||
|
ie6->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID;
|
||||||
|
ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(f1ap_req(false, instanceP)->gNB_DU_id, f1ap_req(false, instanceP)->gNB_DU_id);
|
||||||
|
|
||||||
/* encode */
|
/* encode */
|
||||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ 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,
|
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->CUport,
|
||||||
msgSetup->DU_f1_ip_address.ipv4_address,
|
msgSetup->DU_f1_ip_address.ipv4_address,
|
||||||
msgSetup->DUport);
|
msgSetup->DUport);
|
||||||
@@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case F1AP_UL_RRC_MESSAGE: // to rrc
|
case F1AP_UL_RRC_MESSAGE: // to rrc
|
||||||
LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n");
|
LOG_D(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n");
|
||||||
|
|
||||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
|
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
|
||||||
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance,
|
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance,
|
||||||
@@ -191,6 +191,11 @@ void *F1AP_DU_task(void *arg) {
|
|||||||
DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg));
|
DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F1AP_UE_CONTEXT_MODIFICATION_RESP:
|
||||||
|
LOG_I(F1AP, "DU task received itti message from RRC for F1AP_UE_CONTEXT_MODIFICATION_RESP message generation \n");
|
||||||
|
DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg));
|
||||||
|
break;
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
|
case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
|
||||||
LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n");
|
LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n");
|
||||||
DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance,
|
DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -74,7 +74,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
|||||||
uint32_t assoc_id,
|
uint32_t assoc_id,
|
||||||
uint32_t stream,
|
uint32_t stream,
|
||||||
F1AP_F1AP_PDU_t *pdu);
|
F1AP_F1AP_PDU_t *pdu);
|
||||||
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance);
|
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp);
|
||||||
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include "f1ap_common.h"
|
#include "f1ap_common.h"
|
||||||
#include "f1ap_encoder.h"
|
#include "f1ap_encoder.h"
|
||||||
|
|
||||||
int asn1_encoder_xer_print = 1;
|
int asn1_encoder_xer_print = 0;
|
||||||
|
|
||||||
int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) {
|
int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) {
|
||||||
ssize_t encoded;
|
ssize_t encoded;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
|||||||
{ DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE }, /* gNBCUConfigurationUpdate */
|
{ DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE }, /* gNBCUConfigurationUpdate */
|
||||||
{ DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */
|
{ DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */
|
||||||
{ DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */
|
{ DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */
|
||||||
{ 0, 0, 0 }, /* UEContextModification */
|
{ DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0 }, /* UEContextModification */
|
||||||
{ 0, 0, 0 }, /* UEContextModificationRequired */
|
{ 0, 0, 0 }, /* UEContextModificationRequired */
|
||||||
{ 0, 0, 0 }, /* UEMobilityCommand */
|
{ 0, 0, 0 }, /* UEMobilityCommand */
|
||||||
{ CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0 }, /* UEContextReleaseRequest */
|
{ CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0 }, /* UEContextReleaseRequest */
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffe
|
|||||||
sctp_data_req->buffer = buffer;
|
sctp_data_req->buffer = buffer;
|
||||||
sctp_data_req->buffer_length = buffer_length;
|
sctp_data_req->buffer_length = buffer_length;
|
||||||
sctp_data_req->stream = stream;
|
sctp_data_req->stream = stream;
|
||||||
LOG_I(F1AP, "Sending ITTI message to SCTP Task\n");
|
LOG_D(F1AP, "Sending ITTI message to SCTP Task\n");
|
||||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1955,9 +1955,38 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
|
|||||||
f1Setup->measurement_timing_information[k] = "0";
|
f1Setup->measurement_timing_information[k] = "0";
|
||||||
f1Setup->ranac[k] = 0;
|
f1Setup->ranac[k] = 0;
|
||||||
f1Setup->mib[k] = rrc->carrier.MIB;
|
f1Setup->mib[k] = rrc->carrier.MIB;
|
||||||
f1Setup->sib1[k] = rrc->carrier.SIB1;
|
|
||||||
f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB;
|
f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB;
|
||||||
f1Setup->sib1_length[k] = rrc->carrier.sizeof_SIB1;
|
|
||||||
|
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
|
||||||
|
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||||
|
&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||||
|
(void **)&bcch_message,
|
||||||
|
(const void *)rrc->carrier.SIB1,
|
||||||
|
rrc->carrier.sizeof_SIB1);
|
||||||
|
|
||||||
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
LOG_E(RRC,"SIB1 decode error\n");
|
||||||
|
// free the memory
|
||||||
|
SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, bcch_message, 1 );
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NR_SIB1_t *bcch_SIB1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
|
||||||
|
f1Setup->sib1[k] = calloc(1,rrc->carrier.sizeof_SIB1);
|
||||||
|
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1,
|
||||||
|
NULL,
|
||||||
|
(void *)bcch_SIB1,
|
||||||
|
f1Setup->sib1[k],
|
||||||
|
NR_MAX_SIB_LENGTH/8);
|
||||||
|
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||||
|
enc_rval.failed_type->name, enc_rval.encoded);
|
||||||
|
|
||||||
|
//if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||||
|
LOG_I(NR_RRC, "SIB1 container to be integrated in F1 Setup request:\n");
|
||||||
|
xer_fprint(stdout, &asn_DEF_NR_SIB1,(void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1 );
|
||||||
|
//}
|
||||||
|
f1Setup->sib1_length[k] = (enc_rval.encoded+7)/8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+1
@@ -24,3 +24,4 @@
|
|||||||
*/
|
*/
|
||||||
long nr_get_Pcmax(module_id_t mod_id);
|
long nr_get_Pcmax(module_id_t mod_id);
|
||||||
/** @}*/
|
/** @}*/
|
||||||
|
|
||||||
|
|||||||
@@ -1530,6 +1530,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
|||||||
|
|
||||||
if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) {
|
if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) {
|
||||||
|
|
||||||
|
if (nr_mac_rrc_check_RRCSetup(module_idP, ra->rnti) <= 0){
|
||||||
|
ra->Msg4_frame++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t time_domain_assignment = 0;
|
uint8_t time_domain_assignment = 0;
|
||||||
uint8_t mcsIndex = 0;
|
uint8_t mcsIndex = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1915,7 +1915,6 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
|
|||||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||||
pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||||
}
|
}
|
||||||
|
|
||||||
else continue;
|
else continue;
|
||||||
if (!pucch_Config->schedulingRequestResourceToAddModList)
|
if (!pucch_Config->schedulingRequestResourceToAddModList)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <openair2/UTIL/OPT/opt.h>
|
#include <openair2/UTIL/OPT/opt.h>
|
||||||
|
|
||||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||||
|
extern void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||||
|
|
||||||
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
|
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||||
|
|
||||||
|
|||||||
@@ -274,9 +274,8 @@ static void do_pdcp_data_ind(
|
|||||||
if (rb != NULL) {
|
if (rb != NULL) {
|
||||||
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
|
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
|
||||||
} else {
|
} else {
|
||||||
LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n",
|
LOG_E(PDCP, "%s:%d:%s: no RB found (rb_id %ld, srb_flag %d)\n",
|
||||||
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
|
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||||
|
|||||||
@@ -77,14 +77,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
|
|||||||
ret->sn_modulus = 1 << ret->sn_field_length;
|
ret->sn_modulus = 1 << ret->sn_field_length;
|
||||||
ret->window_size = ret->sn_modulus / 2;
|
ret->window_size = ret->sn_modulus / 2;
|
||||||
|
|
||||||
ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu;
|
ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu;
|
||||||
ret->common.buffer_status = nr_rlc_entity_am_buffer_status;
|
ret->common.buffer_status = nr_rlc_entity_am_buffer_status;
|
||||||
ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu;
|
ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu;
|
||||||
ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu;
|
ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu;
|
||||||
ret->common.set_time = nr_rlc_entity_am_set_time;
|
ret->common.set_time = nr_rlc_entity_am_set_time;
|
||||||
ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu;
|
ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu;
|
||||||
ret->common.reestablishment = nr_rlc_entity_am_reestablishment;
|
ret->common.reestablishment = nr_rlc_entity_am_reestablishment;
|
||||||
ret->common.delete = nr_rlc_entity_am_delete;
|
ret->common.delete = nr_rlc_entity_am_delete;
|
||||||
|
ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space;
|
||||||
|
|
||||||
ret->common.deliver_sdu = deliver_sdu;
|
ret->common.deliver_sdu = deliver_sdu;
|
||||||
ret->common.deliver_sdu_data = deliver_sdu_data;
|
ret->common.deliver_sdu_data = deliver_sdu_data;
|
||||||
@@ -127,14 +128,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
|
|||||||
ret->sn_modulus = 1 << ret->sn_field_length;
|
ret->sn_modulus = 1 << ret->sn_field_length;
|
||||||
ret->window_size = ret->sn_modulus / 2;
|
ret->window_size = ret->sn_modulus / 2;
|
||||||
|
|
||||||
ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu;
|
ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu;
|
||||||
ret->common.buffer_status = nr_rlc_entity_um_buffer_status;
|
ret->common.buffer_status = nr_rlc_entity_um_buffer_status;
|
||||||
ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu;
|
ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu;
|
||||||
ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu;
|
ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu;
|
||||||
ret->common.set_time = nr_rlc_entity_um_set_time;
|
ret->common.set_time = nr_rlc_entity_um_set_time;
|
||||||
ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu;
|
ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu;
|
||||||
ret->common.reestablishment = nr_rlc_entity_um_reestablishment;
|
ret->common.reestablishment = nr_rlc_entity_um_reestablishment;
|
||||||
ret->common.delete = nr_rlc_entity_um_delete;
|
ret->common.delete = nr_rlc_entity_um_delete;
|
||||||
|
ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space;
|
||||||
|
|
||||||
ret->common.deliver_sdu = deliver_sdu;
|
ret->common.deliver_sdu = deliver_sdu;
|
||||||
ret->common.deliver_sdu_data = deliver_sdu_data;
|
ret->common.deliver_sdu_data = deliver_sdu_data;
|
||||||
@@ -158,14 +160,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
|
|||||||
|
|
||||||
ret->tx_maxsize = tx_maxsize;
|
ret->tx_maxsize = tx_maxsize;
|
||||||
|
|
||||||
ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu;
|
ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu;
|
||||||
ret->common.buffer_status = nr_rlc_entity_tm_buffer_status;
|
ret->common.buffer_status = nr_rlc_entity_tm_buffer_status;
|
||||||
ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu;
|
ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu;
|
||||||
ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu;
|
ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu;
|
||||||
ret->common.set_time = nr_rlc_entity_tm_set_time;
|
ret->common.set_time = nr_rlc_entity_tm_set_time;
|
||||||
ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu;
|
ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu;
|
||||||
ret->common.reestablishment = nr_rlc_entity_tm_reestablishment;
|
ret->common.reestablishment = nr_rlc_entity_tm_reestablishment;
|
||||||
ret->common.delete = nr_rlc_entity_tm_delete;
|
ret->common.delete = nr_rlc_entity_tm_delete;
|
||||||
|
ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space;
|
||||||
|
|
||||||
ret->common.deliver_sdu = deliver_sdu;
|
ret->common.deliver_sdu = deliver_sdu;
|
||||||
ret->common.deliver_sdu_data = deliver_sdu_data;
|
ret->common.deliver_sdu_data = deliver_sdu_data;
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ typedef struct nr_rlc_entity_t {
|
|||||||
|
|
||||||
void (*delete)(struct nr_rlc_entity_t *entity);
|
void (*delete)(struct nr_rlc_entity_t *entity);
|
||||||
|
|
||||||
|
int (*available_tx_space)(struct nr_rlc_entity_t *entity);
|
||||||
|
|
||||||
/* callbacks provided to the RLC module */
|
/* callbacks provided to the RLC module */
|
||||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
|
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
|
||||||
char *buf, int size);
|
char *buf, int size);
|
||||||
|
|||||||
@@ -1910,3 +1910,9 @@ void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity)
|
|||||||
clear_entity(entity);
|
clear_entity(entity);
|
||||||
free(entity);
|
free(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity)
|
||||||
|
{
|
||||||
|
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
|
||||||
|
return entity->tx_maxsize - entity->tx_size;
|
||||||
|
}
|
||||||
|
|||||||
@@ -99,5 +99,6 @@ void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now);
|
|||||||
void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
||||||
void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity);
|
void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity);
|
||||||
void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity);
|
void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity);
|
||||||
|
int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity);
|
||||||
|
|
||||||
#endif /* _NR_RLC_ENTITY_AM_H_ */
|
#endif /* _NR_RLC_ENTITY_AM_H_ */
|
||||||
|
|||||||
@@ -174,3 +174,9 @@ void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity)
|
|||||||
clear_entity(entity);
|
clear_entity(entity);
|
||||||
free(entity);
|
free(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity)
|
||||||
|
{
|
||||||
|
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
|
||||||
|
return entity->tx_maxsize - entity->tx_size;
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,5 +51,6 @@ void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now);
|
|||||||
void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
||||||
void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity);
|
void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity);
|
||||||
void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity);
|
void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity);
|
||||||
|
int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity);
|
||||||
|
|
||||||
#endif /* _NR_RLC_ENTITY_TM_H_ */
|
#endif /* _NR_RLC_ENTITY_TM_H_ */
|
||||||
|
|||||||
@@ -695,3 +695,9 @@ void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity)
|
|||||||
clear_entity(entity);
|
clear_entity(entity);
|
||||||
free(entity);
|
free(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity)
|
||||||
|
{
|
||||||
|
nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity;
|
||||||
|
return entity->tx_maxsize - entity->tx_size;
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,5 +75,6 @@ void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now);
|
|||||||
void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
|
||||||
void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity);
|
void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity);
|
||||||
void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity);
|
void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity);
|
||||||
|
int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity);
|
||||||
|
|
||||||
#endif /* _NR_RLC_ENTITY_UM_H_ */
|
#endif /* _NR_RLC_ENTITY_UM_H_ */
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config
|
|||||||
switch (rlc_config_pr){
|
switch (rlc_config_pr){
|
||||||
case NR_RLC_Config_PR_um_Bi_Directional:
|
case NR_RLC_Config_PR_um_Bi_Directional:
|
||||||
// RLC UM Bi-directional Bearer configuration
|
// RLC UM Bi-directional Bearer configuration
|
||||||
|
LOG_I(RLC, "RLC UM Bi-directional Bearer configuration selected \n");
|
||||||
rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional));
|
rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional));
|
||||||
rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
|
rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
|
||||||
*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
|
*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
|
||||||
@@ -213,10 +214,12 @@ tbs_size_t mac_rlc_data_req(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rb != NULL) {
|
if (rb != NULL) {
|
||||||
|
LOG_D(RLC, "MAC PDU to get created for channel_idP:%d \n", channel_idP);
|
||||||
rb->set_time(rb, nr_rlc_current_time);
|
rb->set_time(rb, nr_rlc_current_time);
|
||||||
maxsize = tb_sizeP;
|
maxsize = tb_sizeP;
|
||||||
ret = rb->generate_pdu(rb, buffer_pP, maxsize);
|
ret = rb->generate_pdu(rb, buffer_pP, maxsize);
|
||||||
} else {
|
} else {
|
||||||
|
LOG_D(RLC, "MAC PDU failed to get created for channel_idP:%d \n", channel_idP);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,6 +397,35 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
|
|||||||
return RLC_OP_STATUS_OK;
|
return RLC_OP_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_rlc_get_available_tx_space(
|
||||||
|
const rnti_t rntiP,
|
||||||
|
const logical_chan_id_t channel_idP)
|
||||||
|
{
|
||||||
|
nr_rlc_ue_t *ue;
|
||||||
|
nr_rlc_entity_t *rb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||||
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
|
||||||
|
|
||||||
|
switch (channel_idP) {
|
||||||
|
case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
|
||||||
|
case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
|
||||||
|
default: rb = NULL; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rb != NULL) {
|
||||||
|
ret = rb->available_tx_space(rb);
|
||||||
|
} else {
|
||||||
|
LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int rlc_module_init(int enb_flag)
|
int rlc_module_init(int enb_flag)
|
||||||
{
|
{
|
||||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|||||||
@@ -46,4 +46,8 @@ void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerCo
|
|||||||
|
|
||||||
void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr);
|
void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr);
|
||||||
|
|
||||||
void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig);
|
void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig);
|
||||||
|
|
||||||
|
int nr_rlc_get_available_tx_space(
|
||||||
|
const rnti_t rntiP,
|
||||||
|
const logical_chan_id_t channel_idP);
|
||||||
|
|||||||
@@ -1065,3 +1065,15 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
|||||||
sdu_sizeP,
|
sdu_sizeP,
|
||||||
sdu_pP, NULL, NULL);
|
sdu_pP, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HACK to be removed: nr_rlc_get_available_tx_space is needed by
|
||||||
|
* openair3/ocp-gtpu/gtp_itf.cpp which is compiled in lte-softmodem
|
||||||
|
* so let's put a dummy nr_rlc_get_available_tx_space here
|
||||||
|
*/
|
||||||
|
int nr_rlc_get_available_tx_space(
|
||||||
|
const rnti_t rntiP,
|
||||||
|
const logical_chan_id_t channel_idP)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -306,6 +306,14 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t nr_mac_rrc_check_RRCSetup(const module_id_t Mod_idP,
|
||||||
|
const rnti_t rnti) {
|
||||||
|
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_idP], rnti);
|
||||||
|
char payload_size = ue_context_p->ue_context.Srb0.Tx_buffer.payload_size;
|
||||||
|
return payload_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int8_t nr_mac_rrc_data_ind(const module_id_t module_idP,
|
int8_t nr_mac_rrc_data_ind(const module_id_t module_idP,
|
||||||
const int CC_id,
|
const int CC_id,
|
||||||
const frame_t frameP,
|
const frame_t frameP,
|
||||||
|
|||||||
@@ -1950,7 +1950,7 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR
|
|||||||
return rlc_BearerConfig;
|
return rlc_BearerConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority ) {
|
void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority) {
|
||||||
|
|
||||||
cellGroupConfig->cellGroupId = 0;
|
cellGroupConfig->cellGroupId = 0;
|
||||||
cellGroupConfig->rlc_BearerToReleaseList = NULL;
|
cellGroupConfig->rlc_BearerToReleaseList = NULL;
|
||||||
|
|||||||
@@ -447,7 +447,8 @@ typedef struct {
|
|||||||
|
|
||||||
NR_BCCH_BCH_Message_t mib;
|
NR_BCCH_BCH_Message_t mib;
|
||||||
NR_BCCH_BCH_Message_t *mib_DU;
|
NR_BCCH_BCH_Message_t *mib_DU;
|
||||||
NR_BCCH_DL_SCH_Message_t *siblock1_DU;
|
NR_SIB1_t *siblock1_DU;
|
||||||
|
//NR_BCCH_DL_SCH_Message_t *siblock1_DU;
|
||||||
NR_SIB1_t *sib1;
|
NR_SIB1_t *sib1;
|
||||||
NR_SIB2_t *sib2;
|
NR_SIB2_t *sib2;
|
||||||
NR_SIB3_t *sib3;
|
NR_SIB3_t *sib3;
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ rrc_gNB_generate_SecurityModeCommand(
|
|||||||
rrc_gNB_ue_context_t *const ue_context_pP
|
rrc_gNB_ue_context_t *const ue_context_pP
|
||||||
);
|
);
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
rrc_gNB_get_next_transaction_identifier(
|
rrc_gNB_get_next_transaction_identifier(
|
||||||
module_id_t gnb_mod_idP
|
module_id_t gnb_mod_idP
|
||||||
);
|
);
|
||||||
@@ -163,6 +163,12 @@ nr_rrc_data_req(
|
|||||||
const pdcp_transmission_mode_t modeP
|
const pdcp_transmission_mode_t modeP
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int8_t nr_mac_rrc_check_RRCSetup(
|
||||||
|
const module_id_t Mod_idP,
|
||||||
|
const rnti_t rnti
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
int
|
int
|
||||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||||
rnti_t rntiP);
|
rnti_t rntiP);
|
||||||
@@ -209,7 +215,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
|||||||
void
|
void
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||||
const protocol_ctxt_t *const ctxt_pP,
|
const protocol_ctxt_t *const ctxt_pP,
|
||||||
rrc_gNB_ue_context_t *ue_context_pP);
|
rrc_gNB_ue_context_t *ue_context_pP,
|
||||||
|
NR_CellGroupConfig_t *cell_groupConfig_from_DU);
|
||||||
|
|
||||||
rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
|
rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
|
||||||
const NR_SRB_ToAddModList_t * const srb2add_listP,
|
const NR_SRB_ToAddModList_t * const srb2add_listP,
|
||||||
|
|||||||
+479
-96
@@ -99,6 +99,7 @@
|
|||||||
#include <openair2/X2AP/x2ap_eNB.h>
|
#include <openair2/X2AP/x2ap_eNB.h>
|
||||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||||
|
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||||
|
|
||||||
#include "BIT_STRING.h"
|
#include "BIT_STRING.h"
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
@@ -164,7 +165,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
|
|||||||
|
|
||||||
LOG_I(NR_RRC,"Done init_NR_SI\n");
|
LOG_I(NR_RRC,"Done init_NR_SI\n");
|
||||||
|
|
||||||
if (NODE_IS_MONOLITHIC(rrc->node_type)){
|
if (NODE_IS_MONOLITHIC(rrc->node_type) || NODE_IS_DU(rrc->node_type)){
|
||||||
rrc_mac_config_req_gNB(rrc->module_id,
|
rrc_mac_config_req_gNB(rrc->module_id,
|
||||||
rrc->configuration.pdsch_AntennaPorts,
|
rrc->configuration.pdsch_AntennaPorts,
|
||||||
rrc->configuration.pusch_AntennaPorts,
|
rrc->configuration.pusch_AntennaPorts,
|
||||||
@@ -599,7 +600,8 @@ rrc_gNB_process_RRCSetupComplete(
|
|||||||
void
|
void
|
||||||
rrc_gNB_generate_defaultRRCReconfiguration(
|
rrc_gNB_generate_defaultRRCReconfiguration(
|
||||||
const protocol_ctxt_t *const ctxt_pP,
|
const protocol_ctxt_t *const ctxt_pP,
|
||||||
rrc_gNB_ue_context_t *ue_context_pP
|
rrc_gNB_ue_context_t *ue_context_pP,
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig
|
||||||
)
|
)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
@@ -714,7 +716,6 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
||||||
xid,
|
xid,
|
||||||
@@ -729,7 +730,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
|||||||
&rrc->carrier,
|
&rrc->carrier,
|
||||||
&rrc->configuration,
|
&rrc->configuration,
|
||||||
NULL,
|
NULL,
|
||||||
ue_p->masterCellGroup);
|
cellGroupConfig);
|
||||||
|
|
||||||
free(ue_context_pP->ue_context.nas_pdu.buffer);
|
free(ue_context_pP->ue_context.nas_pdu.buffer);
|
||||||
|
|
||||||
@@ -805,6 +806,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||||
|
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||||
rrc_mac_config_req_gNB(rrc->module_id,
|
rrc_mac_config_req_gNB(rrc->module_id,
|
||||||
rrc->configuration.pdsch_AntennaPorts,
|
rrc->configuration.pdsch_AntennaPorts,
|
||||||
rrc->configuration.pusch_AntennaPorts,
|
rrc->configuration.pusch_AntennaPorts,
|
||||||
@@ -834,7 +836,8 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
|||||||
void
|
void
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||||
const protocol_ctxt_t *const ctxt_pP,
|
const protocol_ctxt_t *const ctxt_pP,
|
||||||
rrc_gNB_ue_context_t *ue_context_pP
|
rrc_gNB_ue_context_t *ue_context_pP,
|
||||||
|
NR_CellGroupConfig_t *cell_groupConfig_from_DU
|
||||||
)
|
)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
@@ -857,7 +860,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
|||||||
uint8_t drb_id_to_setup_start = 1;
|
uint8_t drb_id_to_setup_start = 1;
|
||||||
uint8_t nb_drb_to_setup = 0;
|
uint8_t nb_drb_to_setup = 0;
|
||||||
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)
|
||||||
NR_CellGroupConfig_t *cellGroupConfig;
|
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||||
|
|
||||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||||
|
|
||||||
@@ -1013,9 +1016,17 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
if(cell_groupConfig_from_DU == NULL){
|
||||||
|
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||||
|
// FIXME: fill_mastercellGroupConfig() won't fill the right priorities or
|
||||||
|
// bearer IDs for the DRBs
|
||||||
|
fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_I(NR_RRC, "Master cell group originating from the DU \n");
|
||||||
|
cellGroupConfig = cell_groupConfig_from_DU;
|
||||||
|
}
|
||||||
|
|
||||||
fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
|
|
||||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
||||||
xid,
|
xid,
|
||||||
*SRB_configList2,
|
*SRB_configList2,
|
||||||
@@ -1454,7 +1465,6 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
|||||||
NULL,
|
NULL,
|
||||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||||
/* Refresh SRBs/DRBs */
|
/* Refresh SRBs/DRBs */
|
||||||
|
|
||||||
if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||||
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
|
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
|
||||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||||
@@ -1464,49 +1474,6 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
|||||||
NULL,
|
NULL,
|
||||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||||
}
|
}
|
||||||
else if(SRB_configList!=NULL || DRB_configList!=NULL){
|
|
||||||
MessageDef *message_p;
|
|
||||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
|
|
||||||
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p);
|
|
||||||
req->gNB_CU_ue_id = 0;
|
|
||||||
req->gNB_DU_ue_id = 0;
|
|
||||||
req->rnti = ue_context_pP->ue_context.rnti;
|
|
||||||
req->mcc = rrc->configuration.mcc[0];
|
|
||||||
req->mnc = rrc->configuration.mnc[0];
|
|
||||||
req->mnc_digit_length = rrc->configuration.mnc_digit_length[0];
|
|
||||||
req->nr_cellid = rrc->nr_cellid;
|
|
||||||
if(SRB_configList!=NULL){
|
|
||||||
req->srbs_to_be_setup = malloc(SRB_configList->list.count*sizeof(f1ap_srb_to_be_setup_t));
|
|
||||||
req->srbs_to_be_setup_length = SRB_configList->list.count;
|
|
||||||
f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
|
|
||||||
for (int i = 0; i < SRB_configList->list.count; i++){
|
|
||||||
if(SRB_configList->list.array[i]->srb_Identity > 1){
|
|
||||||
SRBs[i].srb_id = SRB_configList->list.array[i]->srb_Identity;
|
|
||||||
SRBs[i].lcid = SRB_configList->list.array[i]->srb_Identity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(DRB_configList!=NULL){
|
|
||||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
|
||||||
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
|
||||||
req->drbs_to_be_setup = malloc(DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t));
|
|
||||||
req->drbs_to_be_setup_length = DRB_configList->list.count;
|
|
||||||
f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
|
|
||||||
LOG_I(RRC, "Length of DRB list:%d, %d \n", DRB_configList->list.count, req->drbs_to_be_setup_length);
|
|
||||||
for (int i = 0; i < DRB_configList->list.count; i++){
|
|
||||||
DRBs[i].drb_id = DRB_configList->list.array[i]->drb_Identity;
|
|
||||||
DRBs[i].rlc_mode = RLC_MODE_AM;
|
|
||||||
DRBs[i].up_ul_tnl[0].tl_address = inet_addr(rrc->eth_params_s.my_addr);
|
|
||||||
DRBs[i].up_ul_tnl[0].port=rrc->eth_params_s.my_portd;
|
|
||||||
DRBs[i].up_ul_tnl_length = 1;
|
|
||||||
DRBs[i].up_dl_tnl[0].tl_address = inet_addr(rrc->eth_params_s.remote_addr);
|
|
||||||
DRBs[i].up_dl_tnl[0].port=rrc->eth_params_s.remote_portd;
|
|
||||||
DRBs[i].up_dl_tnl_length = 1;
|
|
||||||
}
|
|
||||||
LOG_I(RRC, "Send F1AP_UE_CONTEXT_SETUP_REQ with ITTI\n");
|
|
||||||
}
|
|
||||||
itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the SRB active in UE context */
|
/* Set the SRB active in UE context */
|
||||||
@@ -2808,11 +2775,76 @@ rrc_gNB_decode_dcch(
|
|||||||
ul_dcch_msg);
|
ul_dcch_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
|
if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)){
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p);
|
if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
|
||||||
} else {
|
rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p, NULL);
|
||||||
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
|
} else {
|
||||||
|
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
/*Generate a UE context setup request message towards the DU to provide the UE
|
||||||
|
*capability info and get the updates on master cell group config from the DU*/
|
||||||
|
MessageDef *message_p;
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
|
||||||
|
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p);
|
||||||
|
//UE_IDs will be extracted from F1AP layer
|
||||||
|
req->gNB_CU_ue_id = 0;
|
||||||
|
req->gNB_DU_ue_id = 0;
|
||||||
|
req->rnti = ue_context_p->ue_context.rnti;
|
||||||
|
req->mcc = RC.nrrrc[ctxt_pP->module_id]->configuration.mcc[0];
|
||||||
|
req->mnc = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc[0];
|
||||||
|
req->mnc_digit_length = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc_digit_length[0];
|
||||||
|
req->nr_cellid = RC.nrrrc[ctxt_pP->module_id]->nr_cellid;
|
||||||
|
|
||||||
|
if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
|
||||||
|
/*Instruction towards the DU for SRB2 configuration*/
|
||||||
|
req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
|
||||||
|
req->srbs_to_be_setup_length = 1;
|
||||||
|
f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
|
||||||
|
SRBs[0].srb_id = 2;
|
||||||
|
SRBs[0].lcid = 2;
|
||||||
|
|
||||||
|
/*Instruction towards the DU for DRB configuration and tunnel creation*/
|
||||||
|
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||||
|
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||||
|
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
|
||||||
|
req->drbs_to_be_setup_length = 1;
|
||||||
|
f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
|
||||||
|
LOG_I(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
|
||||||
|
DRBs[0].drb_id = 1;
|
||||||
|
DRBs[0].rlc_mode = RLC_MODE_AM;
|
||||||
|
DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_addr);
|
||||||
|
DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_portd;
|
||||||
|
DRBs[0].up_ul_tnl_length = 1;
|
||||||
|
DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_addr);
|
||||||
|
DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_portd;
|
||||||
|
DRBs[0].up_dl_tnl_length = 1;
|
||||||
|
}
|
||||||
|
if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present ==
|
||||||
|
NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) {
|
||||||
|
struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList =
|
||||||
|
ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList;
|
||||||
|
if(ue_CapabilityRAT_ContainerList!=NULL){
|
||||||
|
LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is present \n");
|
||||||
|
req->cu_to_du_rrc_information = calloc(1,sizeof(cu_to_du_rrc_information_t));
|
||||||
|
req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = calloc(1,4096);
|
||||||
|
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList,
|
||||||
|
NULL,
|
||||||
|
ue_CapabilityRAT_ContainerList,
|
||||||
|
req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList,
|
||||||
|
4096);
|
||||||
|
AssertFatal (enc_rval.encoded > 0, "ASN1 ue_CapabilityRAT_ContainerList encoding failed (%s, %jd)!\n",
|
||||||
|
enc_rval.failed_type->name, enc_rval.encoded);
|
||||||
|
req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = (enc_rval.encoded+7)>>3;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is not present \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2925,11 +2957,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
|
|||||||
memset(mib->message.choice.mib,0,sizeof(struct NR_MIB));
|
memset(mib->message.choice.mib,0,sizeof(struct NR_MIB));
|
||||||
memcpy(mib->message.choice.mib, mib_DU->message.choice.mib, sizeof(struct NR_MIB));
|
memcpy(mib->message.choice.mib, mib_DU->message.choice.mib, sizeof(struct NR_MIB));
|
||||||
|
|
||||||
rrc->carrier.SIB1 = malloc(f1_setup_req->sib1_length[i]);
|
|
||||||
rrc->carrier.sizeof_SIB1 = f1_setup_req->sib1_length[i];
|
|
||||||
memcpy((void *)rrc->carrier.SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]);
|
|
||||||
dec_rval = uper_decode_complete(NULL,
|
dec_rval = uper_decode_complete(NULL,
|
||||||
&asn_DEF_NR_BCCH_DL_SCH_Message,
|
&asn_DEF_NR_SIB1, //&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||||
(void **)&rrc->carrier.siblock1_DU,
|
(void **)&rrc->carrier.siblock1_DU,
|
||||||
f1_setup_req->sib1[i],
|
f1_setup_req->sib1[i],
|
||||||
f1_setup_req->sib1_length[i]);
|
f1_setup_req->sib1_length[i]);
|
||||||
@@ -2939,12 +2968,12 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
|
|||||||
dec_rval.consumed );
|
dec_rval.consumed );
|
||||||
|
|
||||||
// Parse message and extract SystemInformationBlockType1 field
|
// Parse message and extract SystemInformationBlockType1 field
|
||||||
NR_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier.siblock1_DU;
|
rrc->carrier.sib1 = rrc->carrier.siblock1_DU;
|
||||||
AssertFatal(bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1,
|
if ( LOG_DEBUGFLAG(DEBUG_ASN1)){
|
||||||
"bcch_message->message.present != NR_BCCH_DL_SCH_MessageType_PR_c1\n");
|
LOG_I(NR_RRC, "Printing received SIB1 container inside F1 setup request message:\n");
|
||||||
AssertFatal(bcch_message->message.choice.c1->present == NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1,
|
xer_fprint(stdout, &asn_DEF_NR_SIB1,(void *)rrc->carrier.sib1);
|
||||||
"bcch_message->message.choice.c1->present != NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n");
|
}
|
||||||
rrc->carrier.sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
|
|
||||||
rrc->carrier.physCellId = f1_setup_req->cell[i].nr_pci;
|
rrc->carrier.physCellId = f1_setup_req->cell[i].nr_pci;
|
||||||
|
|
||||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).gNB_CU_name = rrc->node_name;
|
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).gNB_CU_name = rrc->node_name;
|
||||||
@@ -3272,6 +3301,94 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
|
|||||||
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p);
|
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p);
|
||||||
uint32_t incoming_teid = 0;
|
uint32_t incoming_teid = 0;
|
||||||
|
|
||||||
|
if(req->cu_to_du_rrc_information!=NULL){
|
||||||
|
if(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){
|
||||||
|
LOG_I(NR_RRC, "Length of ue_CapabilityRAT_ContainerList is: %d \n", (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
|
||||||
|
struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = NULL;
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||||
|
&asn_DEF_NR_UE_CapabilityRAT_ContainerList,
|
||||||
|
(void **)&ue_CapabilityRAT_ContainerList,
|
||||||
|
(uint8_t *)req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList,
|
||||||
|
(int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
|
||||||
|
|
||||||
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
AssertFatal(1==0,"UE Capability RAT ContainerList decode error\n");
|
||||||
|
// free the memory
|
||||||
|
SEQUENCE_free( &asn_DEF_NR_UE_CapabilityRAT_ContainerList, ue_CapabilityRAT_ContainerList, 1 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//To fill ue_context.UE_Capability_MRDC, ue_context.UE_Capability_nr ...
|
||||||
|
int NR_index = -1;
|
||||||
|
for(int i = 0;i < ue_CapabilityRAT_ContainerList->list.count; i++){
|
||||||
|
if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
|
||||||
|
NR_RAT_Type_nr){
|
||||||
|
LOG_I(NR_RRC, "DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU \n");
|
||||||
|
if(ue_context_p->ue_context.UE_Capability_nr){
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr);
|
||||||
|
ue_context_p->ue_context.UE_Capability_nr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dec_rval = uper_decode(NULL,
|
||||||
|
&asn_DEF_NR_UE_NR_Capability,
|
||||||
|
(void**)&ue_context_p->ue_context.UE_Capability_nr,
|
||||||
|
ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf,
|
||||||
|
ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size,
|
||||||
|
0,0);
|
||||||
|
if(LOG_DEBUGFLAG(DEBUG_ASN1)){
|
||||||
|
xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){
|
||||||
|
LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n",
|
||||||
|
PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),dec_rval.consumed);
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr);
|
||||||
|
ue_context_p->ue_context.UE_Capability_nr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ue_context_p->ue_context.UE_Capability_size =
|
||||||
|
ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size;
|
||||||
|
if(NR_index != -1){
|
||||||
|
LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
NR_index = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
|
||||||
|
NR_RAT_Type_eutra_nr){
|
||||||
|
LOG_I(NR_RRC, "DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU \n");
|
||||||
|
if(ue_context_p->ue_context.UE_Capability_MRDC){
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC);
|
||||||
|
ue_context_p->ue_context.UE_Capability_MRDC = 0;
|
||||||
|
}
|
||||||
|
dec_rval = uper_decode(NULL,
|
||||||
|
&asn_DEF_NR_UE_MRDC_Capability,
|
||||||
|
(void**)&ue_context_p->ue_context.UE_Capability_MRDC,
|
||||||
|
ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf,
|
||||||
|
ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size,
|
||||||
|
0,0);
|
||||||
|
if(LOG_DEBUGFLAG(DEBUG_ASN1)){
|
||||||
|
xer_fprint(stdout,&asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){
|
||||||
|
LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n",
|
||||||
|
PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),dec_rval.consumed);
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC);
|
||||||
|
ue_context_p->ue_context.UE_Capability_MRDC = 0;
|
||||||
|
}
|
||||||
|
ue_context_p->ue_context.UE_MRDC_Capability_size =
|
||||||
|
ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
|
||||||
|
NR_RAT_Type_eutra){
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t drb_id_to_setup_start = 0;
|
uint8_t drb_id_to_setup_start = 0;
|
||||||
uint8_t nb_drb_to_setup = 0;
|
uint8_t nb_drb_to_setup = 0;
|
||||||
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)
|
||||||
@@ -3325,11 +3442,25 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_CellGroupConfig_t *cellGroupConfig;
|
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||||
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length>0)
|
||||||
fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
|
// FIXME: fill_mastercellGroupConfig() won't fill the right priorities or
|
||||||
|
// bearer IDs for the DRBs
|
||||||
|
fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
|
||||||
|
|
||||||
apply_macrlc_config(rrc, ue_context_p, &ctxt);
|
apply_macrlc_config(rrc, ue_context_p, &ctxt);
|
||||||
|
|
||||||
|
if(req->rrc_container_length > 0){
|
||||||
|
mem_block_t *pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__);
|
||||||
|
memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length);
|
||||||
|
du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length, pdcp_pdu_p);
|
||||||
|
LOG_I(F1AP, "Printing RRC Container of UE context setup request: \n");
|
||||||
|
for (int j=0; j<req->rrc_container_length; j++){
|
||||||
|
printf("%02x ", pdcp_pdu_p->data[j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill the UE context setup response ITTI message to send to F1AP */
|
/* Fill the UE context setup response ITTI message to send to F1AP */
|
||||||
resp->gNB_CU_ue_id = req->gNB_CU_ue_id;
|
resp->gNB_CU_ue_id = req->gNB_CU_ue_id;
|
||||||
resp->rnti = ctxt.rnti;
|
resp->rnti = ctxt.rnti;
|
||||||
@@ -3364,17 +3495,174 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
|
|||||||
else{
|
else{
|
||||||
LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n");
|
LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n");
|
||||||
}
|
}
|
||||||
resp->du_to_cu_rrc_information = calloc(1,1024*sizeof(uint8_t));
|
/* fixme:
|
||||||
|
* Here we should be encoding the updates on cellgroupconfig based on the content of UE capabilities
|
||||||
|
*/
|
||||||
|
resp->du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t));
|
||||||
|
resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024);
|
||||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||||
NULL,
|
NULL,
|
||||||
(void *)cellGroupConfig,
|
ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig,
|
||||||
resp->du_to_cu_rrc_information,
|
resp->du_to_cu_rrc_information->cellGroupConfig,
|
||||||
1024);
|
1024);
|
||||||
resp->du_to_cu_rrc_information_length = (enc_rval.encoded+7)>>3;
|
if (enc_rval.encoded == -1) {
|
||||||
|
LOG_E(F1AP,"Could not encode ue_context.masterCellGroup, failed element %s\n",enc_rval.failed_type->name);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3;
|
||||||
free(cellGroupConfig);
|
free(cellGroupConfig);
|
||||||
itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p);
|
itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, const char *msg_name, instance_t instance){
|
||||||
|
|
||||||
|
f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p);
|
||||||
|
protocol_ctxt_t ctxt;
|
||||||
|
ctxt.rnti = req->rnti;
|
||||||
|
ctxt.module_id = instance;
|
||||||
|
ctxt.instance = instance;
|
||||||
|
ctxt.enb_flag = 1;
|
||||||
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||||
|
gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id];
|
||||||
|
struct rrc_gNB_ue_context_s *ue_context_p =
|
||||||
|
rrc_gNB_get_ue_context(rrc, ctxt.rnti);
|
||||||
|
MessageDef *message_p;
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
|
||||||
|
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p);
|
||||||
|
uint32_t incoming_teid = 0;
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||||
|
|
||||||
|
/* Configure SRB2 */
|
||||||
|
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||||
|
NR_SRB_ToAddModList_t *SRB_configList = NULL;
|
||||||
|
uint8_t SRBs_before_new_addition = 0;
|
||||||
|
|
||||||
|
if(req->srbs_to_be_setup_length>0){
|
||||||
|
if(ue_context_p->ue_context.SRB_configList == NULL){
|
||||||
|
LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n");
|
||||||
|
ue_context_p->ue_context.SRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.SRB_configList));
|
||||||
|
}
|
||||||
|
SRB_configList = ue_context_p->ue_context.SRB_configList;
|
||||||
|
SRBs_before_new_addition = SRB_configList->list.count;
|
||||||
|
for (int i=0; i<req->srbs_to_be_setup_length; i++){
|
||||||
|
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||||
|
SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id;
|
||||||
|
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure DRB */
|
||||||
|
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||||
|
NR_DRB_ToAddModList_t *DRB_configList = NULL;
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
DRB_configList = ue_context_p->ue_context.DRB_configList;
|
||||||
|
for (int i=0; i<req->drbs_to_be_setup_length; i++){
|
||||||
|
DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||||
|
DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id;
|
||||||
|
ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
|
||||||
|
f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i];
|
||||||
|
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;
|
||||||
|
extern instance_t DUuniqInstance;
|
||||||
|
incoming_teid=newGtpuCreateTunnel(DUuniqInstance,
|
||||||
|
req->rnti,
|
||||||
|
drb_p.drb_id,
|
||||||
|
drb_p.drb_id,
|
||||||
|
drb_p.up_ul_tnl[0].teid,
|
||||||
|
addr,
|
||||||
|
drb_p.up_ul_tnl[0].port,
|
||||||
|
DURecvCb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
rrc->um_on_default_drb,
|
||||||
|
drb_id_to_setup_start < 2 ? 1 : 0,
|
||||||
|
drb_id_to_setup_start,
|
||||||
|
req->drbs_to_be_setup_length,
|
||||||
|
drb_priority);
|
||||||
|
apply_macrlc_config(rrc, ue_context_p, &ctxt);
|
||||||
|
}
|
||||||
|
if(req->ReconfigComplOutcome == RRCreconf_failure){
|
||||||
|
LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n");
|
||||||
|
}
|
||||||
|
else if(req->ReconfigComplOutcome == RRCreconf_success){
|
||||||
|
LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n");
|
||||||
|
if(ue_context_p->ue_context.DRB_configList!=NULL){
|
||||||
|
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);
|
||||||
|
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));
|
||||||
|
gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg);
|
||||||
|
req->pdusession_id = drb_id;
|
||||||
|
req->rnti = rnti;
|
||||||
|
req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead
|
||||||
|
extern instance_t DUuniqInstance;
|
||||||
|
itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill the UE context setup response ITTI message to send to F1AP */
|
||||||
|
resp->gNB_CU_ue_id = req->gNB_CU_ue_id;
|
||||||
|
resp->rnti = ctxt.rnti;
|
||||||
|
if(DRB_configList){
|
||||||
|
if(DRB_configList->list.count > 0){
|
||||||
|
resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t));
|
||||||
|
resp->drbs_to_be_setup_length = DRB_configList->list.count;
|
||||||
|
for (int i=0; i<DRB_configList->list.count; i++){
|
||||||
|
resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity;
|
||||||
|
resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM;
|
||||||
|
resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid;
|
||||||
|
resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr);
|
||||||
|
resp->drbs_to_be_setup[i].up_dl_tnl_length = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context modification request with a DRB to setup list\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(SRB_configList){
|
||||||
|
if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){
|
||||||
|
resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t));
|
||||||
|
resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length;
|
||||||
|
for (int i=SRBs_before_new_addition; i<SRB_configList->list.count; i++){
|
||||||
|
resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(cellGroupConfig != NULL) {
|
||||||
|
resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t));
|
||||||
|
resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024);
|
||||||
|
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||||
|
NULL,
|
||||||
|
ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig,
|
||||||
|
resp->du_to_cu_rrc_information->cellGroupConfig,
|
||||||
|
1024);
|
||||||
|
resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3;
|
||||||
|
//}
|
||||||
|
itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p);
|
||||||
|
}
|
||||||
|
|
||||||
static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const char *msg_name, instance_t instance){
|
static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const char *msg_name, instance_t instance){
|
||||||
|
|
||||||
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
||||||
@@ -3390,8 +3678,8 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
|
|||||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||||
&asn_DEF_NR_CellGroupConfig,
|
&asn_DEF_NR_CellGroupConfig,
|
||||||
(void **)&cellGroupConfig,
|
(void **)&cellGroupConfig,
|
||||||
(uint8_t *)resp->du_to_cu_rrc_information,
|
(uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig,
|
||||||
(int) resp->du_to_cu_rrc_information_length);
|
(int) resp->du_to_cu_rrc_information->cellGroupConfig_length);
|
||||||
|
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
AssertFatal(1==0,"Cell group config decode error\n");
|
AssertFatal(1==0,"Cell group config decode error\n");
|
||||||
@@ -3406,20 +3694,89 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
|
|||||||
}
|
}
|
||||||
if(cellGroupConfig->rlc_BearerToAddModList!=NULL){
|
if(cellGroupConfig->rlc_BearerToAddModList!=NULL){
|
||||||
if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){
|
if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){
|
||||||
LOG_I(NR_RRC, "rlc_BearerToAddModList not empty before filling it \n");
|
int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count;
|
||||||
free(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList);
|
for(int i=ue_ctxt_rlc_Bearers; i<ue_ctxt_rlc_Bearers + cellGroupConfig->rlc_BearerToAddModList->list.count; i++){
|
||||||
|
ASN_SEQUENCE_ADD(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list,
|
||||||
|
cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
else{
|
||||||
memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList,
|
LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n");
|
||||||
|
ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
||||||
|
memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList,
|
||||||
sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup);
|
xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup);
|
||||||
|
|
||||||
|
if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
|
||||||
|
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig);
|
||||||
|
} else {
|
||||||
|
rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
free(cellGroupConfig->rlc_BearerToAddModList);
|
free(cellGroupConfig->rlc_BearerToAddModList);
|
||||||
free(cellGroupConfig);
|
free(cellGroupConfig);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){
|
||||||
|
|
||||||
|
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
||||||
|
protocol_ctxt_t ctxt;
|
||||||
|
ctxt.rnti = resp->rnti;
|
||||||
|
ctxt.module_id = instance;
|
||||||
|
ctxt.instance = instance;
|
||||||
|
ctxt.enb_flag = 1;
|
||||||
|
ctxt.eNB_index = instance;
|
||||||
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||||
|
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti);
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||||
|
|
||||||
|
if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||||
|
&asn_DEF_NR_CellGroupConfig,
|
||||||
|
(void **)&cellGroupConfig,
|
||||||
|
(uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig,
|
||||||
|
(int) resp->du_to_cu_rrc_information->cellGroupConfig_length);
|
||||||
|
|
||||||
|
if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
AssertFatal(1==0,"Cell group config decode error\n");
|
||||||
|
// free the memory
|
||||||
|
SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
||||||
|
|
||||||
|
if(ue_context_p->ue_context.masterCellGroup == NULL){
|
||||||
|
ue_context_p->ue_context.masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cellGroupConfig->rlc_BearerToAddModList!=NULL){
|
||||||
|
if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){
|
||||||
|
int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count;
|
||||||
|
for(int i=ue_ctxt_rlc_Bearers; i<ue_ctxt_rlc_Bearers + cellGroupConfig->rlc_BearerToAddModList->list.count; i++){
|
||||||
|
ASN_SEQUENCE_ADD(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list,
|
||||||
|
cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n");
|
||||||
|
ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
||||||
|
memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList,
|
||||||
|
sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n");
|
||||||
|
xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup);
|
||||||
|
|
||||||
|
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig);
|
||||||
|
|
||||||
|
free(cellGroupConfig->rlc_BearerToAddModList);
|
||||||
|
free(cellGroupConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int mask_flip(unsigned int x) {
|
unsigned int mask_flip(unsigned int x) {
|
||||||
return((((x>>8) + (x<<8))&0xffff)>>6);
|
return((((x>>8) + (x<<8))&0xffff)>>6);
|
||||||
}
|
}
|
||||||
@@ -3621,15 +3978,27 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
|||||||
|
|
||||||
// Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G
|
// Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G
|
||||||
if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) {
|
if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) {
|
||||||
mac_remove_nr_ue(nrmac, ctxt_pP->rnti);
|
if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->instance]->node_type)){
|
||||||
rrc_rlc_remove_ue(ctxt_pP);
|
mac_remove_nr_ue(nrmac, ctxt_pP->rnti);
|
||||||
pdcp_remove_UE(ctxt_pP);
|
rrc_rlc_remove_ue(ctxt_pP);
|
||||||
|
pdcp_remove_UE(ctxt_pP);
|
||||||
|
|
||||||
/* remove RRC UE Context */
|
/* remove RRC UE Context */
|
||||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
|
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
|
||||||
if (ue_context_p) {
|
if (ue_context_p) {
|
||||||
rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
|
rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
|
||||||
LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
|
LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// In case of CU trigger UE context release command towards the DU
|
||||||
|
else{
|
||||||
|
MessageDef *message_p;
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
|
||||||
|
f1ap_ue_context_release_cmd_t *rel_cmd=&F1AP_UE_CONTEXT_RELEASE_CMD (message_p);
|
||||||
|
rel_cmd->rnti = ctxt_pP->rnti;
|
||||||
|
rel_cmd->cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
rel_cmd->cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
|
||||||
|
itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, message_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3815,17 +4184,30 @@ void *rrc_gnb_task(void *args_p) {
|
|||||||
rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
|
rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NR_DU_RRC_DL_INDICATION:
|
case NR_DU_RRC_DL_INDICATION:
|
||||||
rrc_process_DU_DL(msg_p, msg_name_p, instance);
|
rrc_process_DU_DL(msg_p, msg_name_p, instance);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_SETUP_REQ:
|
case F1AP_UE_CONTEXT_SETUP_REQ:
|
||||||
rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance);
|
rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_SETUP_RESP:
|
case F1AP_UE_CONTEXT_SETUP_RESP:
|
||||||
rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance);
|
rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F1AP_UE_CONTEXT_MODIFICATION_RESP:
|
||||||
|
rrc_CU_process_ue_context_modification_response(msg_p, msg_name_p, instance);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
||||||
|
rrc_DU_process_ue_context_modification_request(msg_p, msg_name_p, instance);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F1AP_UE_CONTEXT_RELEASE_CMD:
|
||||||
|
LOG_W(NR_RRC, "Received F1AP_UE_CONTEXT_RELEASE_CMD for processing at the RRC layer of the DU. Processing function "
|
||||||
|
"implementation is pending\n");
|
||||||
|
break;
|
||||||
|
|
||||||
/* Messages from X2AP */
|
/* Messages from X2AP */
|
||||||
case X2AP_ENDC_SGNB_ADDITION_REQ:
|
case X2AP_ENDC_SGNB_ADDITION_REQ:
|
||||||
@@ -4096,5 +4478,6 @@ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe)
|
|||||||
message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS);
|
message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS);
|
||||||
RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt;
|
RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt;
|
||||||
RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id;
|
RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id;
|
||||||
|
LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe);
|
||||||
itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p);
|
itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,7 +307,6 @@ nr_rrc_pdcp_config_security(
|
|||||||
//uint8_t *k_kdf = NULL;
|
//uint8_t *k_kdf = NULL;
|
||||||
static int print_keys= 1;
|
static int print_keys= 1;
|
||||||
|
|
||||||
|
|
||||||
/* Derive the keys from kgnb */
|
/* Derive the keys from kgnb */
|
||||||
if (SRB_configList != NULL) {
|
if (SRB_configList != NULL) {
|
||||||
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||||
@@ -1050,7 +1049,46 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
|||||||
// TEST
|
// TEST
|
||||||
// ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
|
// ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
|
||||||
// rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
|
// rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){
|
||||||
|
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/*Generate a UE context modification request message towards the DU to instruct the DU
|
||||||
|
*for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
|
||||||
|
MessageDef *message_p;
|
||||||
|
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
|
||||||
|
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p);
|
||||||
|
req->rnti = ue_context_p->ue_context.rnti;
|
||||||
|
req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
|
||||||
|
req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
|
||||||
|
req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
|
||||||
|
req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid;
|
||||||
|
|
||||||
|
/*Instruction towards the DU for SRB2 configuration*/
|
||||||
|
req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
|
||||||
|
req->srbs_to_be_setup_length = 1;
|
||||||
|
f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
|
||||||
|
SRBs[0].srb_id = 2;
|
||||||
|
SRBs[0].lcid = 2;
|
||||||
|
|
||||||
|
/*Instruction towards the DU for DRB configuration and tunnel creation*/
|
||||||
|
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||||
|
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||||
|
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
|
||||||
|
req->drbs_to_be_setup_length = 1;
|
||||||
|
f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
|
||||||
|
LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
|
||||||
|
DRBs[0].drb_id = 1;
|
||||||
|
DRBs[0].rlc_mode = RLC_MODE_AM;
|
||||||
|
DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
|
||||||
|
DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
|
||||||
|
DRBs[0].up_ul_tnl_length = 1;
|
||||||
|
DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
|
||||||
|
DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
|
||||||
|
DRBs[0].up_dl_tnl_length = 1;
|
||||||
|
|
||||||
|
itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
|
||||||
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ typedef struct {
|
|||||||
uint8_t kgnb[32];
|
uint8_t kgnb[32];
|
||||||
} ue_sa_security_key_t;
|
} ue_sa_security_key_t;
|
||||||
|
|
||||||
|
|
||||||
typedef enum fgs_protocol_discriminator_e {
|
typedef enum fgs_protocol_discriminator_e {
|
||||||
/* Protocol discriminator identifier for 5GS Mobility Management */
|
/* Protocol discriminator identifier for 5GS Mobility Management */
|
||||||
FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E,
|
FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E,
|
||||||
|
|||||||
@@ -70,8 +70,8 @@
|
|||||||
/* Convert an integer on 16 bits to the given bUFFER */
|
/* Convert an integer on 16 bits to the given bUFFER */
|
||||||
#define INT16_TO_BUFFER(x, buf) \
|
#define INT16_TO_BUFFER(x, buf) \
|
||||||
do { \
|
do { \
|
||||||
(buf)[0] = (x) >> 8; \
|
(buf)[0] = ((x) >> 8) & 0xff; \
|
||||||
(buf)[1] = (x); \
|
(buf)[1] = (x) & 0xff; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* Convert an array of char containing vALUE to x */
|
/* Convert an array of char containing vALUE to x */
|
||||||
@@ -84,9 +84,9 @@ do { \
|
|||||||
/* Convert an integer on 24 bits to the given bUFFER */
|
/* Convert an integer on 24 bits to the given bUFFER */
|
||||||
#define INT24_TO_BUFFER(x, buf) \
|
#define INT24_TO_BUFFER(x, buf) \
|
||||||
do { \
|
do { \
|
||||||
(buf)[0] = (x) >> 16; \
|
(buf)[0] = ((x) >> 16) & 0xff;\
|
||||||
(buf)[1] = (x) >> 8; \
|
(buf)[1] = ((x) >> 8) & 0xff; \
|
||||||
(buf)[2] = (x); \
|
(buf)[2] = (x) & 0xff; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* Convert an array of char containing vALUE to x */
|
/* Convert an array of char containing vALUE to x */
|
||||||
@@ -101,10 +101,10 @@ do { \
|
|||||||
/* Convert an integer on 32 bits to the given bUFFER */
|
/* Convert an integer on 32 bits to the given bUFFER */
|
||||||
#define INT32_TO_BUFFER(x, buf) \
|
#define INT32_TO_BUFFER(x, buf) \
|
||||||
do { \
|
do { \
|
||||||
(buf)[0] = (x) >> 24; \
|
(buf)[0] = ((x) >> 24) & 0xff;\
|
||||||
(buf)[1] = (x) >> 16; \
|
(buf)[1] = ((x) >> 16) & 0xff;\
|
||||||
(buf)[2] = (x) >> 8; \
|
(buf)[2] = ((x) >> 8) & 0xff; \
|
||||||
(buf)[3] = (x); \
|
(buf)[3] = (x) & 0xff; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* Convert an array of char containing vALUE to x */
|
/* Convert an array of char containing vALUE to x */
|
||||||
|
|||||||
+226
-31
@@ -17,6 +17,7 @@ extern "C" {
|
|||||||
#include <openair2/COMMON/gtpv1_u_messages_types.h>
|
#include <openair2/COMMON/gtpv1_u_messages_types.h>
|
||||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||||
|
#include <openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h>
|
||||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||||
//#include <openair1/PHY/phy_extern.h>
|
//#include <openair1/PHY/phy_extern.h>
|
||||||
|
|
||||||
@@ -36,6 +37,22 @@ typedef struct Gtpv1uMsgHeader {
|
|||||||
teid_t teid;
|
teid_t teid;
|
||||||
} __attribute__((packed)) Gtpv1uMsgHeaderT;
|
} __attribute__((packed)) Gtpv1uMsgHeaderT;
|
||||||
|
|
||||||
|
//TS 38.425, Figure 5.5.2.2-1
|
||||||
|
typedef struct DlDataDeliveryStatus_flags {
|
||||||
|
uint8_t LPR:1; //Lost packet report
|
||||||
|
uint8_t FFI:1; //Final Frame Ind
|
||||||
|
uint8_t deliveredPdcpSn:1; //Highest Delivered NR PDCP SN Ind
|
||||||
|
uint8_t transmittedPdcpSn:1; //Highest Transmitted NR PDCP SN Ind
|
||||||
|
uint8_t pduType:4; //PDU type
|
||||||
|
uint8_t CR:1; //Cause Report
|
||||||
|
uint8_t deliveredReTxPdcpSn:1; //Delivered retransmitted NR PDCP SN Ind
|
||||||
|
uint8_t reTxPdcpSn:1; //Retransmitted NR PDCP SN Ind
|
||||||
|
uint8_t DRI:1; //Data Rate Indication
|
||||||
|
uint8_t deliveredPdcpSnRange:1; //Delivered NR PDCP SN Range Ind
|
||||||
|
uint8_t spare:3;
|
||||||
|
uint32_t drbBufferSize; //Desired buffer size for the data radio bearer
|
||||||
|
} __attribute__((packed)) DlDataDeliveryStatus_flagsT;
|
||||||
|
|
||||||
typedef struct Gtpv1uMsgHeaderOptFields {
|
typedef struct Gtpv1uMsgHeaderOptFields {
|
||||||
uint8_t seqNum1Oct;
|
uint8_t seqNum1Oct;
|
||||||
uint8_t seqNum2Oct;
|
uint8_t seqNum2Oct;
|
||||||
@@ -61,6 +78,8 @@ typedef struct Gtpv1uExtHeader {
|
|||||||
|
|
||||||
// TS 29.281, fig 5.2.1-3
|
// TS 29.281, fig 5.2.1-3
|
||||||
#define PDU_SESSION_CONTAINER (0x85)
|
#define PDU_SESSION_CONTAINER (0x85)
|
||||||
|
#define NR_RAN_CONTAINER (0x84)
|
||||||
|
|
||||||
// TS 29.281, 5.2.1
|
// TS 29.281, 5.2.1
|
||||||
#define EXT_HDR_LNTH_OCTET_UNITS (4)
|
#define EXT_HDR_LNTH_OCTET_UNITS (4)
|
||||||
#define NO_MORE_EXT_HDRS (0)
|
#define NO_MORE_EXT_HDRS (0)
|
||||||
@@ -88,12 +107,14 @@ typedef struct gtpv1u_bearer_s {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
map<int, gtpv1u_bearer_t> bearers;
|
map<int, gtpv1u_bearer_t> bearers;
|
||||||
|
teid_t outgoing_teid;
|
||||||
} teidData_t;
|
} teidData_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rnti_t rnti;
|
rnti_t rnti;
|
||||||
ebi_t incoming_rb_id;
|
ebi_t incoming_rb_id;
|
||||||
gtpCallback callBack;
|
gtpCallback callBack;
|
||||||
|
teid_t outgoing_teid;
|
||||||
gtpCallbackSDAP callBackSDAP;
|
gtpCallbackSDAP callBackSDAP;
|
||||||
int pdusession_id;
|
int pdusession_id;
|
||||||
} rntiData_t;
|
} rntiData_t;
|
||||||
@@ -137,17 +158,18 @@ instance_t legacyInstanceMapping=0;
|
|||||||
#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a)
|
#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a)
|
||||||
|
|
||||||
#define GTPV1U_HEADER_SIZE (8)
|
#define GTPV1U_HEADER_SIZE (8)
|
||||||
|
|
||||||
|
|
||||||
static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, int msgType, teid_t teid, uint8_t *Msg,int msgLen,
|
static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, int msgType, teid_t teid, uint8_t *Msg,int msgLen,
|
||||||
bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) {
|
bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType,
|
||||||
AssertFatal(extHdrFlag==false,"Not developped");
|
uint8_t *extensionHeader_buffer, uint8_t extensionHeader_length) {
|
||||||
|
LOG_D(GTPU, "Peer IP:%u peer port:%u outgoing teid:%u \n", peerIp, peerPort, teid);
|
||||||
int headerAdditional=0;
|
int headerAdditional=0;
|
||||||
|
|
||||||
if ( seqNumFlag || npduNumFlag || extHdrFlag)
|
if ( seqNumFlag || npduNumFlag || extHdrFlag)
|
||||||
headerAdditional=4;
|
headerAdditional=4;
|
||||||
|
|
||||||
int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen;
|
int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen+extensionHeader_length;
|
||||||
uint8_t buffer[fullSize];
|
uint8_t buffer[fullSize];
|
||||||
Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *)buffer ;
|
Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *)buffer ;
|
||||||
// N should be 0 for us (it was used only in 2G and 3G)
|
// N should be 0 for us (it was used only in 2G and 3G)
|
||||||
@@ -159,20 +181,42 @@ static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, int
|
|||||||
msgHdr->PT=1;
|
msgHdr->PT=1;
|
||||||
msgHdr->version=1;
|
msgHdr->version=1;
|
||||||
msgHdr->msgType=msgType;
|
msgHdr->msgType=msgType;
|
||||||
msgHdr->msgLength=htons(msgLen);
|
msgHdr->msgLength=htons(msgLen+extensionHeader_length);
|
||||||
|
|
||||||
if ( seqNumFlag || extHdrFlag || npduNumFlag)
|
if ( seqNumFlag || extHdrFlag || npduNumFlag)
|
||||||
msgHdr->msgLength+=4;
|
msgHdr->msgLength+=htons(4);
|
||||||
|
|
||||||
msgHdr->teid=htonl(teid);
|
msgHdr->teid=htonl(teid);
|
||||||
|
|
||||||
if(seqNumFlag || extHdrFlag || npduNumFlag) {
|
if(seqNumFlag || extHdrFlag || npduNumFlag) {
|
||||||
*((uint16_t *) (buffer+8)) = seqNumFlag ? htons(seqNum) : 0x0000;
|
*((uint16_t *) (buffer+8)) = seqNumFlag ? seqNum : 0x0000;
|
||||||
*((uint8_t *) (buffer+10)) = npduNumFlag ? htons(npduNum) : 0x00;
|
*((uint8_t *) (buffer+10)) = npduNumFlag ? npduNum : 0x00;
|
||||||
*((uint8_t *) (buffer+11)) = extHdrFlag ? htons(extHdrType) : 0x00;
|
*((uint8_t *) (buffer+11)) = extHdrFlag ? extHdrType : 0x00;
|
||||||
|
|
||||||
|
/**(buffer+8) = seqNumFlag ? htons(seqNum) : 0x0000;
|
||||||
|
*(buffer+10) = npduNumFlag ? htons(npduNum) : 0x00;
|
||||||
|
*(buffer+11) = extHdrFlag ? htons(extHdrType) : 0x00;
|
||||||
|
*(buffer+11) = extHdrType;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if(extHdrFlag){
|
||||||
|
while (extHdrType){
|
||||||
|
if (extensionHeader_length > 0 && extHdrType == 0x84){
|
||||||
|
memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, extensionHeader_buffer, extensionHeader_length);
|
||||||
|
LOG_D(GTPU, "Extension Header for DDD added. The length is: %d, extension header type is: %x \n", extensionHeader_length, *((uint8_t *) (buffer+11)));
|
||||||
|
extHdrType = extensionHeader_buffer[extensionHeader_length -1];
|
||||||
|
LOG_D(GTPU, "Next extension header type is: %x \n", *((uint8_t *) (buffer+11)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_W(GTPU, "Extension header type not supported, returning... \n");
|
||||||
|
return GTPNOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Msg!= NULL){
|
||||||
|
memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional+extensionHeader_length, Msg, msgLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, Msg, msgLen);
|
|
||||||
// Fix me: add IPv6 support, using flag ipVersion
|
// Fix me: add IPv6 support, using flag ipVersion
|
||||||
static struct sockaddr_in to= {0};
|
static struct sockaddr_in to= {0};
|
||||||
to.sin_family = AF_INET;
|
to.sin_family = AF_INET;
|
||||||
@@ -230,7 +274,7 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b
|
|||||||
tmp.outgoing_port,
|
tmp.outgoing_port,
|
||||||
GTP_GPDU,
|
GTP_GPDU,
|
||||||
tmp.teid_outgoing,
|
tmp.teid_outgoing,
|
||||||
buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ;
|
buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0, NULL, 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) {
|
static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) {
|
||||||
@@ -273,7 +317,75 @@ static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req,
|
|||||||
tmp.outgoing_port,
|
tmp.outgoing_port,
|
||||||
GTP_GPDU,
|
GTP_GPDU,
|
||||||
tmp.teid_outgoing,
|
tmp.teid_outgoing,
|
||||||
buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ;
|
buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0, NULL, 0) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fillDlDeliveryStatusReport(extensionHeader_t *extensionHeader, uint32_t RLC_buffer_availability, uint32_t NR_PDCP_PDU_SN){
|
||||||
|
|
||||||
|
extensionHeader->buffer[0] = (1+sizeof(DlDataDeliveryStatus_flagsT)+(NR_PDCP_PDU_SN>0?3:0)+(NR_PDCP_PDU_SN>0?1:0)+1)/4;
|
||||||
|
DlDataDeliveryStatus_flagsT DlDataDeliveryStatus;
|
||||||
|
DlDataDeliveryStatus.deliveredPdcpSn = 0;
|
||||||
|
DlDataDeliveryStatus.transmittedPdcpSn= NR_PDCP_PDU_SN>0?1:0;
|
||||||
|
DlDataDeliveryStatus.pduType = 1;
|
||||||
|
DlDataDeliveryStatus.drbBufferSize = htonl(RLC_buffer_availability);
|
||||||
|
memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT));
|
||||||
|
uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1;
|
||||||
|
|
||||||
|
if(NR_PDCP_PDU_SN>0){
|
||||||
|
extensionHeader->buffer[offset] = (NR_PDCP_PDU_SN >> 16) & 0xff;
|
||||||
|
extensionHeader->buffer[offset+1] = (NR_PDCP_PDU_SN >> 8) & 0xff;
|
||||||
|
extensionHeader->buffer[offset+2] = NR_PDCP_PDU_SN & 0xff;
|
||||||
|
LOG_D(GTPU, "Octets reporting NR_PDCP_PDU_SN, extensionHeader->buffer[offset]: %u, extensionHeader->buffer[offset+1]:%u, extensionHeader->buffer[offset+2]:%u \n", extensionHeader->buffer[offset], extensionHeader->buffer[offset+1],extensionHeader->buffer[offset+2]);
|
||||||
|
extensionHeader->buffer[offset+3] = 0x00; //Padding octet
|
||||||
|
offset = offset+3;
|
||||||
|
}
|
||||||
|
extensionHeader->buffer[offset] = 0x00; //No more extension headers
|
||||||
|
/*Total size of DDD_status PDU = size of mandatory part +
|
||||||
|
* 3 octets for highest transmitted/delivered PDCP SN +
|
||||||
|
* 1 octet for padding + 1 octet for next extension header type,
|
||||||
|
* according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/
|
||||||
|
extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+
|
||||||
|
(NR_PDCP_PDU_SN>0?3:0)+
|
||||||
|
(NR_PDCP_PDU_SN>0?1:0)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gtpv1uSendDlDeliveryStatus(instance_t instance, gtpv1u_DU_buffer_report_req_t *req){
|
||||||
|
rnti_t rnti=req->rnti;
|
||||||
|
int rab_id=req->pdusession_id;
|
||||||
|
pthread_mutex_lock(&globGtp.gtp_lock);
|
||||||
|
auto inst=&globGtp.instances[compatInst(instance)];
|
||||||
|
auto ptrRnti=inst->ue2te_mapping.find(rnti);
|
||||||
|
|
||||||
|
if ( ptrRnti==inst->ue2te_mapping.end() ) {
|
||||||
|
LOG_E(GTPU, "[%ld] GTP-U gtpv1uSend failed: while getting ue rnti %x in hashtable ue_mapping\n", instance, rnti);
|
||||||
|
pthread_mutex_unlock(&globGtp.gtp_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<int, gtpv1u_bearer_t>::iterator ptr2=ptrRnti->second.bearers.find(rab_id);
|
||||||
|
|
||||||
|
if ( ptr2 == ptrRnti->second.bearers.end() ) {
|
||||||
|
LOG_D(GTPU,"GTP-U instance: %ld sending a packet to a non existant RNTI:RAB: %x/%x\n", instance, rnti, rab_id);
|
||||||
|
pthread_mutex_unlock(&globGtp.gtp_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionHeader_t *extensionHeader;
|
||||||
|
extensionHeader = (extensionHeader_t *) calloc(1, sizeof(extensionHeader_t));
|
||||||
|
fillDlDeliveryStatusReport(extensionHeader, req->buffer_availability,0);
|
||||||
|
|
||||||
|
LOG_I(GTPU,"[%ld] GTP-U sending DL Data Delivery status to RNTI:RAB:teid %x/%x/%x, oldseq %d, oldnum %d\n",
|
||||||
|
instance, rnti, rab_id,ptr2->second.teid_outgoing, ptr2->second.seqNum,ptr2->second.npduNum );
|
||||||
|
// copy to release the mutex
|
||||||
|
gtpv1u_bearer_t tmp=ptr2->second;
|
||||||
|
pthread_mutex_unlock(&globGtp.gtp_lock);
|
||||||
|
gtpv1uCreateAndSendMsg(compatInst(instance),
|
||||||
|
tmp.outgoing_ip_addr,
|
||||||
|
tmp.outgoing_port,
|
||||||
|
GTP_GPDU,
|
||||||
|
tmp.teid_outgoing,
|
||||||
|
NULL, 0, false, false, true, 0, 0, 0x84, extensionHeader->buffer, extensionHeader->length) ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) {
|
static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) {
|
||||||
@@ -478,6 +590,8 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer
|
|||||||
|
|
||||||
inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id;
|
inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id;
|
||||||
|
|
||||||
|
inst->te2ue_mapping[incoming_teid].outgoing_teid= outgoing_teid;
|
||||||
|
|
||||||
inst->te2ue_mapping[incoming_teid].callBack=callBack;
|
inst->te2ue_mapping[incoming_teid].callBack=callBack;
|
||||||
|
|
||||||
inst->te2ue_mapping[incoming_teid].callBackSDAP = sdap_data_req;
|
inst->te2ue_mapping[incoming_teid].callBackSDAP = sdap_data_req;
|
||||||
@@ -740,8 +854,8 @@ static int Gtpv1uHandleEchoReq(int h,
|
|||||||
LOG_D(GTPU, "[%d] Received a echo request, TEID: %d, seq: %hu\n", h, msgHdr->teid, seq);
|
LOG_D(GTPU, "[%d] Received a echo request, TEID: %d, seq: %hu\n", h, msgHdr->teid, seq);
|
||||||
uint8_t recovery[2]= {14,0};
|
uint8_t recovery[2]= {14,0};
|
||||||
return gtpv1uCreateAndSendMsg(h, peerIp, peerPort, GTP_ECHO_RSP, ntohl(msgHdr->teid),
|
return gtpv1uCreateAndSendMsg(h, peerIp, peerPort, GTP_ECHO_RSP, ntohl(msgHdr->teid),
|
||||||
recovery, sizeof recovery,
|
recovery, sizeof recovery,
|
||||||
1, 0, 0, seq, 0, 0);
|
1, 0, 0, seq, 0, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Gtpv1uHandleError(int h,
|
static int Gtpv1uHandleError(int h,
|
||||||
@@ -850,26 +964,63 @@ static int Gtpv1uHandleGpdu(int h,
|
|||||||
return GTPNOK;
|
return GTPNOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset=sizeof(Gtpv1uMsgHeaderT);
|
/* see TS 29.281 5.1 */
|
||||||
|
//Minimum length of GTP-U header if non of the optional fields are present
|
||||||
|
int offset = sizeof(Gtpv1uMsgHeaderT);
|
||||||
|
|
||||||
uint8_t qfi = 0;
|
uint8_t qfi = 0;
|
||||||
boolean_t rqi = FALSE;
|
boolean_t rqi = FALSE;
|
||||||
|
uint32_t NR_PDCP_PDU_SN = 0;
|
||||||
|
|
||||||
if( msgHdr->E || msgHdr->S || msgHdr->PN){
|
/* if E, S, or PN is set then there are 4 more bytes of header */
|
||||||
Gtpv1uMsgHeaderOptFieldsT *msgHdrOpt = (Gtpv1uMsgHeaderOptFieldsT *)(msgBuf+offset);
|
if( msgHdr->E || msgHdr->S ||msgHdr->PN)
|
||||||
offset+=sizeof(Gtpv1uMsgHeaderOptFieldsT);
|
offset += 4;
|
||||||
if( msgHdr->E && msgHdrOpt->NextExtHeaderType == PDU_SESSION_CONTAINER){
|
|
||||||
Gtpv1uExtHeaderT *msgHdrExt = (Gtpv1uExtHeaderT *)(msgBuf+offset);
|
|
||||||
offset+=msgHdrExt->ExtHeaderLen*EXT_HDR_LNTH_OCTET_UNITS;
|
|
||||||
qfi = msgHdrExt->pdusession_cntr.QFI;
|
|
||||||
rqi = msgHdrExt->pdusession_cntr.RQI;
|
|
||||||
|
|
||||||
/*
|
if (msgHdr->E) {
|
||||||
* Check if the next extension header type of GTP extension header is set to 0
|
int next_extension_header_type = msgBuf[offset - 1];
|
||||||
* We can not put it in the struct Gtpv1uExtHeaderT because the length is dynamic.
|
int extension_header_length;
|
||||||
*/
|
|
||||||
if(*(msgBuf+offset-1) != NO_MORE_EXT_HDRS)
|
while (next_extension_header_type != NO_MORE_EXT_HDRS) {
|
||||||
LOG_W(GTPU, "Warning - Next extension header is not zero, handle it \n");
|
extension_header_length = msgBuf[offset];
|
||||||
|
switch (next_extension_header_type) {
|
||||||
|
case PDU_SESSION_CONTAINER: {
|
||||||
|
PDUSessionContainerT *pdusession_cntr = (PDUSessionContainerT *)(msgBuf + offset + 1);
|
||||||
|
qfi = pdusession_cntr->QFI;
|
||||||
|
rqi = pdusession_cntr->RQI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NR_RAN_CONTAINER: {
|
||||||
|
uint8_t PDU_type = (msgBuf[offset+1]>>4) & 0x0f;
|
||||||
|
if (PDU_type == 0){ //DL USER Data Format
|
||||||
|
int additional_offset = 6; //Additional offset capturing the first non-mandatory octet (TS 38.425, Figure 5.5.2.1-1)
|
||||||
|
if(msgBuf[offset+1]>>2 & 0x1){ //DL Discard Blocks flag is present
|
||||||
|
LOG_I(GTPU, "DL User Data: DL Discard Blocks handling not enabled\n");
|
||||||
|
additional_offset = additional_offset + 9; //For the moment ignore
|
||||||
|
}
|
||||||
|
if(msgBuf[offset+1]>>1 & 0x1){ //DL Flush flag is present
|
||||||
|
LOG_I(GTPU, "DL User Data: DL Flush handling not enabled\n");
|
||||||
|
additional_offset = additional_offset + 3; //For the moment ignore
|
||||||
|
}
|
||||||
|
if((msgBuf[offset+2]>>3)& 0x1){ //"Report delivered" enabled (TS 38.425, 5.4)
|
||||||
|
/*Store the NR PDCP PDU SN for which a delivery status report shall be generated once the
|
||||||
|
*PDU gets forwarded to the lower layers*/
|
||||||
|
//NR_PDCP_PDU_SN = msgBuf[offset+6] << 16 | msgBuf[offset+7] << 8 | msgBuf[offset+8];
|
||||||
|
NR_PDCP_PDU_SN = msgBuf[offset+additional_offset] << 16 | msgBuf[offset+additional_offset+1] << 8 | msgBuf[offset+additional_offset+2];
|
||||||
|
LOG_D(GTPU, " NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
LOG_W(GTPU, "NR-RAN container type: %d not supported \n", PDU_type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOG_W(GTPU, "unhandled extension 0x%2.2x, skipping\n", next_extension_header_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += extension_header_length * EXT_HDR_LNTH_OCTET_UNITS;
|
||||||
|
next_extension_header_type = msgBuf[offset - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -925,6 +1076,44 @@ static int Gtpv1uHandleGpdu(int h,
|
|||||||
LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h);
|
LOG_E(GTPU,"[%d] down layer refused incoming packet\n", 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);
|
||||||
|
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
|
||||||
|
* 1 octet for padding + 1 octet for next extension header type,
|
||||||
|
* according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/
|
||||||
|
extensionHeader_t *extensionHeader;
|
||||||
|
extensionHeader = (extensionHeader_t *) calloc(1, sizeof(extensionHeader_t)) ;
|
||||||
|
extensionHeader->buffer[0] = (1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1)/4;
|
||||||
|
DlDataDeliveryStatus_flagsT DlDataDeliveryStatus;
|
||||||
|
DlDataDeliveryStatus.deliveredPdcpSn = 0;
|
||||||
|
DlDataDeliveryStatus.transmittedPdcpSn= 1;
|
||||||
|
DlDataDeliveryStatus.pduType = 1;
|
||||||
|
DlDataDeliveryStatus.drbBufferSize = htonl(rlc_tx_buffer_space); //htonl(10000000); //hardcoded for now but normally we should extract it from RLC
|
||||||
|
memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT));
|
||||||
|
uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1;
|
||||||
|
|
||||||
|
extensionHeader->buffer[offset] = (NR_PDCP_PDU_SN >> 16) & 0xff;
|
||||||
|
extensionHeader->buffer[offset+1] = (NR_PDCP_PDU_SN >> 8) & 0xff;
|
||||||
|
extensionHeader->buffer[offset+2] = NR_PDCP_PDU_SN & 0xff;
|
||||||
|
LOG_D(GTPU, "Octets reporting NR_PDCP_PDU_SN, extensionHeader->buffer[offset]: %u, extensionHeader->buffer[offset+1]:%u, extensionHeader->buffer[offset+2]:%u \n", extensionHeader->buffer[offset], extensionHeader->buffer[offset+1],extensionHeader->buffer[offset+2]);
|
||||||
|
extensionHeader->buffer[offset+3] = 0x00; //Padding octet
|
||||||
|
extensionHeader->buffer[offset+4] = 0x00; //No more extension headers
|
||||||
|
/*Total size of DDD_status PDU = size of mandatory part +
|
||||||
|
* 3 octets for highest transmitted/delivered PDCP SN +
|
||||||
|
* 1 octet for padding + 1 octet for next extension header type,
|
||||||
|
* according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/
|
||||||
|
extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1;
|
||||||
|
gtpv1uCreateAndSendMsg(h,
|
||||||
|
peerIp,
|
||||||
|
peerPort,
|
||||||
|
GTP_GPDU,
|
||||||
|
inst->te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid,
|
||||||
|
NULL, 0, false, false, true, 0, 0, 0x84, extensionHeader->buffer, extensionHeader->length) ;
|
||||||
|
}
|
||||||
|
|
||||||
LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h,
|
LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h,
|
||||||
msgBufLen-offset,
|
msgBufLen-offset,
|
||||||
ntohl(msgHdr->teid));
|
ntohl(msgHdr->teid));
|
||||||
@@ -1009,6 +1198,12 @@ void *gtpv1uTask(void *args) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GTPV1U_DU_BUFFER_REPORT_REQ:{
|
||||||
|
gtpv1uSendDlDeliveryStatus(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
|
||||||
|
>PV1U_DU_BUFFER_REPORT_REQ(message_p));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TERMINATE_MESSAGE:
|
case TERMINATE_MESSAGE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ typedef struct openAddr_s {
|
|||||||
instance_t originInstance;
|
instance_t originInstance;
|
||||||
} openAddr_t;
|
} openAddr_t;
|
||||||
|
|
||||||
|
typedef struct extensionHeader_s{
|
||||||
|
uint8_t buffer[500];
|
||||||
|
uint8_t length;
|
||||||
|
}extensionHeader_t;
|
||||||
|
|
||||||
// the init function create a gtp instance and return the gtp instance id
|
// the init function create a gtp instance and return the gtp instance id
|
||||||
// the parameter originInstance will be sent back in each message from gtp to the creator
|
// the parameter originInstance will be sent back in each message from gtp to the creator
|
||||||
void gtpv1uReceiver(int h);
|
void gtpv1uReceiver(int h);
|
||||||
|
|||||||
@@ -339,4 +339,7 @@ log_config :
|
|||||||
ngap_log_level ="debug";
|
ngap_log_level ="debug";
|
||||||
f1ap_log_level ="debug";
|
f1ap_log_level ="debug";
|
||||||
};
|
};
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
|
||||||
|
>>>>>>> origin/develop
|
||||||
|
|||||||
Reference in New Issue
Block a user