Merge remote-tracking branch 'origin/develop' into NR_pdcch_improvements
This commit is contained in:
@@ -219,6 +219,10 @@ typedef struct kenb_refresh_req_s {
|
||||
Byte_t kenb[32];
|
||||
} kenb_refresh_req_t;
|
||||
|
||||
typedef struct nsa_oai_tun_nsa_s {
|
||||
uint8_t buffer[500];
|
||||
} nas_oai_tun_nsa_t;
|
||||
|
||||
/*
|
||||
* NAS->AS - Cell Information request
|
||||
* NAS request AS to search for a suitable cell belonging to the selected
|
||||
|
||||
@@ -44,7 +44,8 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_r
|
||||
/* RRC -> F1AP messages */
|
||||
MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message )
|
||||
//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_req_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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#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_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_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_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
|
||||
@@ -71,6 +72,29 @@ typedef struct f1ap_cu_setup_req_s {
|
||||
//
|
||||
} f1ap_cu_setup_req_t;
|
||||
|
||||
typedef struct cellIDs_s {
|
||||
|
||||
// Served Cell Information
|
||||
/* Tracking area code */
|
||||
uint32_t tac;
|
||||
|
||||
/* Mobile Country Codes
|
||||
* Mobile Network Codes
|
||||
*/
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_digit_length;
|
||||
|
||||
// NR Global Cell Id
|
||||
uint64_t nr_cellid;
|
||||
// NR Physical Cell Ids
|
||||
uint16_t nr_pci;
|
||||
// Number of slide support items (max 16, could be increased to as much as 1024)
|
||||
uint16_t num_ssi;
|
||||
uint8_t sst;
|
||||
uint8_t sd;
|
||||
} cellIDs_t;
|
||||
|
||||
typedef struct f1ap_setup_req_s {
|
||||
|
||||
// Midhaul networking parameters
|
||||
@@ -84,6 +108,8 @@ typedef struct f1ap_setup_req_s {
|
||||
/* The eNB IP address to bind */
|
||||
f1ap_net_ip_address_t CU_f1_ip_address;
|
||||
f1ap_net_ip_address_t DU_f1_ip_address;
|
||||
uint16_t CUport;
|
||||
uint16_t DUport;
|
||||
|
||||
/* Number of SCTP streams used for a mme association */
|
||||
uint16_t sctp_in_streams;
|
||||
@@ -100,31 +126,12 @@ typedef struct f1ap_setup_req_s {
|
||||
|
||||
/// number of DU cells available
|
||||
uint16_t num_cells_available; //0< num_cells_available <= 512;
|
||||
|
||||
// Served Cell Information
|
||||
/* Tracking area code */
|
||||
uint32_t tac[F1AP_MAX_NB_CELLS];
|
||||
|
||||
/* Mobile Country Codes
|
||||
* Mobile Network Codes
|
||||
*/
|
||||
uint16_t mcc[F1AP_MAX_NB_CELLS];//[6];
|
||||
uint16_t mnc[F1AP_MAX_NB_CELLS];//[6];
|
||||
uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS];//[6];
|
||||
|
||||
// NR Global Cell Id
|
||||
uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
|
||||
// NR Physical Cell Ids
|
||||
uint16_t nr_pci[F1AP_MAX_NB_CELLS];
|
||||
// Number of slide support items (max 16, could be increased to as much as 1024)
|
||||
uint16_t num_ssi[F1AP_MAX_NB_CELLS];//[6];
|
||||
uint8_t sst[F1AP_MAX_NB_CELLS];//[16][6];
|
||||
uint8_t sd[F1AP_MAX_NB_CELLS];//[16][6];
|
||||
cellIDs_t cell[F1AP_MAX_NB_CELLS];
|
||||
// fdd_flag = 1 means FDD, 0 means TDD
|
||||
int fdd_flag;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct fdd_s {
|
||||
uint32_t ul_nr_arfcn;
|
||||
uint8_t ul_scs;
|
||||
uint8_t ul_nrb;
|
||||
@@ -148,7 +155,7 @@ typedef struct f1ap_setup_req_s {
|
||||
uint8_t dl_num_sul_frequency_bands;
|
||||
uint16_t dl_nr_sul_band[32];
|
||||
} fdd;
|
||||
struct {
|
||||
struct tdd_s {
|
||||
|
||||
uint32_t nr_arfcn;
|
||||
uint8_t scs;
|
||||
@@ -195,6 +202,7 @@ typedef struct served_cells_to_activate_s {
|
||||
/// SI message containers (up to 21 messages per cell)
|
||||
uint8_t *SI_container[21];
|
||||
int SI_container_length[21];
|
||||
int SI_type[21];
|
||||
} served_cells_to_activate_t;
|
||||
|
||||
typedef struct f1ap_setup_resp_s {
|
||||
@@ -299,7 +307,7 @@ typedef struct f1ap_initial_ul_rrc_message_s {
|
||||
uint16_t crnti;
|
||||
uint8_t *rrc_container;
|
||||
int rrc_container_length;
|
||||
int8_t *du2cu_rrc_container;
|
||||
char du2cu_rrc_container[200];
|
||||
int du2cu_rrc_container_length;
|
||||
} f1ap_initial_ul_rrc_message_t;
|
||||
|
||||
@@ -312,19 +320,32 @@ typedef struct f1ap_ul_rrc_message_s {
|
||||
|
||||
typedef struct f1ap_up_tnl_s {
|
||||
in_addr_t tl_address; // currently only IPv4 supported
|
||||
uint32_t gtp_teid;
|
||||
teid_t teid;
|
||||
uint16_t port;
|
||||
} f1ap_up_tnl_t;
|
||||
|
||||
typedef struct f1ap_drb_to_be_setup_s {
|
||||
uint8_t drb_id;
|
||||
long drb_id;
|
||||
f1ap_up_tnl_t up_ul_tnl[2];
|
||||
uint8_t up_ul_tnl_length;
|
||||
f1ap_up_tnl_t up_dl_tnl[2];
|
||||
uint8_t up_dl_tnl_length;
|
||||
rlc_mode_t rlc_mode;
|
||||
} f1ap_drb_to_be_setup_t;
|
||||
|
||||
typedef struct f1ap_ue_context_setup_req_s {
|
||||
typedef struct f1ap_srb_to_be_setup_s {
|
||||
long srb_id;
|
||||
rlc_mode_t rlc_mode;
|
||||
uint8_t lcid;
|
||||
} f1ap_srb_to_be_setup_t;
|
||||
|
||||
typedef struct f1ap_rb_failed_to_be_setup_s {
|
||||
long rb_id;
|
||||
} f1ap_rb_failed_to_be_setup_t;
|
||||
|
||||
typedef struct f1ap_ue_context_setup_s {
|
||||
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;
|
||||
uint16_t rnti;
|
||||
// SpCell Info
|
||||
uint16_t mcc;
|
||||
@@ -336,13 +357,37 @@ typedef struct f1ap_ue_context_setup_req_s {
|
||||
uint32_t servCellId;
|
||||
uint8_t *cu_to_du_rrc_information;
|
||||
uint8_t cu_to_du_rrc_information_length;
|
||||
uint8_t *du_to_cu_rrc_information;
|
||||
uint8_t du_to_cu_rrc_information_length;
|
||||
f1ap_drb_to_be_setup_t *drbs_to_be_setup; // BK: need to replace by s1ap_initial_context_setup_req
|
||||
uint8_t drbs_to_be_setup_length; // BK: need to replace by s1ap_initial_context_setup_req
|
||||
uint8_t drbs_failed_to_be_setup_length;
|
||||
f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup;
|
||||
f1ap_srb_to_be_setup_t *srbs_to_be_setup;
|
||||
uint8_t srbs_to_be_setup_length;
|
||||
uint8_t srbs_failed_to_be_setup_length;
|
||||
f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup;
|
||||
s1ap_initial_context_setup_req_t *s1ap_initial_context_setup_req;
|
||||
// coniatner for the rrc_eNB_generate_SecurityModeCommand message
|
||||
uint8_t *rrc_container;
|
||||
int rrc_container_length;
|
||||
} f1ap_ue_context_setup_req_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 {
|
||||
F1AP_CAUSE_NOTHING, /* No components present */
|
||||
|
||||
@@ -29,9 +29,8 @@ MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_dat
|
||||
MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_ind_t,Gtpv1uDataForwardingInd)
|
||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq)
|
||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
|
||||
MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req)
|
||||
MESSAGE_DEF(GTPV1U_REQ, MESSAGE_PRIORITY_MED, Gtpv1uReq, gtpv1uReq)
|
||||
|
||||
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t, NRGtpv1uDeleteTunnelReq)
|
||||
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp)
|
||||
MESSAGE_DEF(GTPV1U_GNB_NG_REQ, MESSAGE_PRIORITY_MED, Gtpv1uNGReq, gtpv1uNGReq)
|
||||
MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq)
|
||||
|
||||
@@ -39,11 +39,10 @@
|
||||
#define GTPV1U_ENB_END_MARKER_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerReq
|
||||
#define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd
|
||||
|
||||
#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req
|
||||
#define GTPV1U_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uReq
|
||||
|
||||
#define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq
|
||||
#define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp
|
||||
#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq
|
||||
#define GTPV1U_GNB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uTunnelDataReq
|
||||
|
||||
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
|
||||
@@ -174,25 +173,23 @@ typedef struct gtpv1u_enb_end_marker_ind_s {
|
||||
} gtpv1u_enb_end_marker_ind_t;
|
||||
|
||||
typedef struct {
|
||||
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
|
||||
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
|
||||
char addrStr[256];
|
||||
char portStr[256];
|
||||
} Gtpv1uS1Req;
|
||||
in_addr_t localAddr;
|
||||
tcp_udp_port_t localPort;
|
||||
char localAddrStr[256];
|
||||
char localPortStr[256];
|
||||
} Gtpv1uReq;
|
||||
|
||||
|
||||
typedef struct {
|
||||
in_addr_t gnb_ip_address_for_NGu_up;
|
||||
tcp_udp_port_t gnb_port_for_NGu_up;
|
||||
char addrStr[256];
|
||||
char portStr[256];
|
||||
} Gtpv1uNGReq;
|
||||
typedef struct gtpv1u_gnb_create_tunnel_req_s {
|
||||
rnti_t rnti;
|
||||
int num_tunnels;
|
||||
teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
//teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
//ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
//transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t dst_addr[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
} gtpv1u_gnb_create_tunnel_req_t;
|
||||
|
||||
typedef struct gtpv1u_gnb_create_tunnel_resp_s {
|
||||
|
||||
@@ -147,6 +147,7 @@ typedef struct NRRrcMacCcchDataInd_s {
|
||||
OCTET_STRING_t *du_to_cu_rrc_container;
|
||||
uint8_t gnb_index;
|
||||
int CC_id;
|
||||
uint64_t nr_cellid;
|
||||
} NRRrcMacCcchDataInd;
|
||||
|
||||
typedef struct RrcMacMcchDataReq_s {
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
MESSAGE_DEF(RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq, rrc_dcch_data_req)
|
||||
MESSAGE_DEF(RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_ind)
|
||||
MESSAGE_DEF(RRC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq, rrc_pcch_data_req)
|
||||
MESSAGE_DEF(RRC_NRUE_CAP_INFO_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_nrue_cap_info_ind)
|
||||
MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_copy_ind)
|
||||
|
||||
// gNB
|
||||
MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq, nr_rrc_dcch_data_req)
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_req
|
||||
#define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_ind
|
||||
#define RRC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_pcch_data_req
|
||||
#define RRC_NRUE_CAP_INFO_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_nrue_cap_info_ind
|
||||
#define RRC_DCCH_DATA_COPY_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_copy_ind
|
||||
|
||||
// gNB
|
||||
#define NR_RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_req
|
||||
@@ -65,6 +67,13 @@ typedef struct RrcDcchDataInd_s {
|
||||
uint8_t eNB_index; // LG: needed in UE
|
||||
} RrcDcchDataInd;
|
||||
|
||||
typedef struct RrcDcchDataCopyInd_s {
|
||||
uint8_t dcch_index;
|
||||
uint32_t sdu_size;
|
||||
uint8_t *sdu_p;
|
||||
uint8_t eNB_index;
|
||||
} RrcDcchDataCopyInd;
|
||||
|
||||
typedef struct NRRrcDcchDataReq_s {
|
||||
uint32_t frame;
|
||||
uint8_t gnb_flag;
|
||||
|
||||
@@ -75,9 +75,9 @@
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#else
|
||||
#define MAX_MOBILES_PER_ENB 4
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 4
|
||||
#define MAX_MOBILES_PER_GNB 4//16
|
||||
#define MAX_MOBILES_PER_ENB 40
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 40
|
||||
#define MAX_MOBILES_PER_GNB 16
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#endif
|
||||
|
||||
@@ -212,6 +212,14 @@ typedef enum config_action_e {
|
||||
CONFIG_ACTION_MBMS_MODIFY = 11
|
||||
} config_action_t;
|
||||
|
||||
/* Maximum size of any message we might send or receive (e.g., via a socket) */
|
||||
#define MAX_MESSAGE_SIZE 8192
|
||||
|
||||
typedef struct nsa_msg_t {
|
||||
uint8_t msg_type;
|
||||
uint8_t msg_buffer[MAX_MESSAGE_SIZE];
|
||||
} nsa_msg_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GTPV1U TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -233,7 +241,6 @@ typedef struct protocol_ctxt_s {
|
||||
frame_t frame; /*!< \brief LTE frame number.*/
|
||||
sub_frame_t subframe; /*!< \brief LTE sub frame number.*/
|
||||
eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */
|
||||
boolean_t configured; /*!< \brief flag indicating whether the instance is configured or not */
|
||||
boolean_t brOption;
|
||||
} protocol_ctxt_t;
|
||||
// warning time hardcoded
|
||||
|
||||
@@ -65,6 +65,8 @@ MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq
|
||||
|
||||
MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, NasRabEstRsp, nas_rab_est_rsp)
|
||||
|
||||
MESSAGE_DEF(NAS_OAI_TUN_NSA, MESSAGE_PRIORITY_MED, NasOaiTunNsa, nas_oai_tun_nsa)
|
||||
|
||||
// UE: RRC -> NAS messages
|
||||
MESSAGE_DEF(NAS_CELL_SELECTION_CNF, MESSAGE_PRIORITY_MED, NasCellSelectionCnf, nas_cell_selection_cnf)
|
||||
MESSAGE_DEF(NAS_CELL_SELECTION_IND, MESSAGE_PRIORITY_MED, NasCellSelectionInd, nas_cell_selection_ind)
|
||||
@@ -79,3 +81,5 @@ MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeP
|
||||
|
||||
// eNB: RLC -> RRC messages
|
||||
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
|
||||
|
||||
MESSAGE_DEF(NR_DU_RRC_DL_INDICATION, MESSAGE_PRIORITY_MED, NRDuDlReq_t, nr_du_dl_req)
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process
|
||||
|
||||
#define RLC_SDU_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.rlc_sdu_indication
|
||||
#define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req
|
||||
|
||||
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
typedef struct RrcStateInd_s {
|
||||
@@ -418,6 +421,11 @@ typedef struct NRRrcConfigurationReq_s {
|
||||
int pucch_TargetSNRx10;
|
||||
} gNB_RrcConfigurationReq;
|
||||
|
||||
typedef struct NRDuDlReq_s {
|
||||
rnti_t rnti;
|
||||
mem_block_t * buf;
|
||||
uint64_t srb_id;
|
||||
} NRDuDlReq_t;
|
||||
|
||||
// UE: NAS -> RRC messages
|
||||
typedef kenb_refresh_req_t NasKenbRefreshReq;
|
||||
@@ -427,6 +435,8 @@ typedef ul_info_transfer_req_t NasUlDataReq;
|
||||
|
||||
typedef rab_establish_rsp_t NasRabEstRsp;
|
||||
|
||||
typedef nas_oai_tun_nsa_t NasOaiTunNsa;
|
||||
|
||||
// UE: RRC -> NAS messages
|
||||
typedef cell_info_cnf_t NasCellSelectionCnf;
|
||||
typedef cell_info_ind_t NasCellSelectionInd;
|
||||
|
||||
@@ -1925,6 +1925,7 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
AssertFatal(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr != NULL,
|
||||
"eNB id %u is not defined in configuration file\n",i);
|
||||
F1AP_SETUP_REQ (msg_p).num_cells_available = 0;
|
||||
F1AP_SETUP_REQ (msg_p).cell_type = CELL_MACRO_ENB;
|
||||
|
||||
for (k=0; k <num_enbs ; k++) {
|
||||
if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) {
|
||||
@@ -1945,20 +1946,20 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
LOG_I(ENB_APP,"F1AP: gNB_DU_id[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_id);
|
||||
F1AP_SETUP_REQ (msg_p).gNB_DU_name = strdup(*(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr));
|
||||
LOG_I(ENB_APP,"F1AP: gNB_DU_name[%d] %s\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_name);
|
||||
F1AP_SETUP_REQ (msg_p).tac[k] = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
LOG_I(ENB_APP,"F1AP: tac[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).tac[k]);
|
||||
F1AP_SETUP_REQ (msg_p).mcc[k] = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
LOG_I(ENB_APP,"F1AP: mcc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mcc[k]);
|
||||
F1AP_SETUP_REQ (msg_p).mnc[k] = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
LOG_I(ENB_APP,"F1AP: mnc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc[k]);
|
||||
F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
LOG_I(ENB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
|
||||
AssertFatal((F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 2) ||
|
||||
(F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 3),
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
LOG_I(ENB_APP,"F1AP: tac[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).cell[k].tac);
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
LOG_I(ENB_APP,"F1AP: mcc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).cell[k].mcc);
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
LOG_I(ENB_APP,"F1AP: mnc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).cell[k].mnc);
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
LOG_I(ENB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).cell[k].mnc_digit_length);
|
||||
AssertFatal((F1AP_SETUP_REQ (msg_p).cell[k].mnc_digit_length == 2) ||
|
||||
(F1AP_SETUP_REQ (msg_p).cell[k].mnc_digit_length == 3),
|
||||
"BAD MNC DIGIT LENGTH %d",
|
||||
F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
|
||||
F1AP_SETUP_REQ (msg_p).nr_cellid[k] = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
|
||||
LOG_I(ENB_APP,"F1AP: nr_cellid[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).nr_cellid[k]);
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].mnc_digit_length);
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].nr_cellid = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
|
||||
LOG_I(ENB_APP,"F1AP: nr_cellid[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).cell[k].nr_cellid);
|
||||
LOG_I(ENB_APP,"F1AP: CU_ip4_address in DU %s\n",RC.mac[k]->eth_params_n.remote_addr);
|
||||
LOG_I(ENB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.remote_addr));
|
||||
F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6 = 0;
|
||||
@@ -1969,8 +1970,11 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
LOG_I(ENB_APP,"FIAP: DU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.my_addr));
|
||||
F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6 = 0;
|
||||
F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4 = 1;
|
||||
|
||||
//strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6_address, "");
|
||||
strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address, RC.mac[k]->eth_params_n.my_addr);
|
||||
F1AP_SETUP_REQ (msg_p).DUport= RC.mac[k]->eth_params_n.my_portd;
|
||||
F1AP_SETUP_REQ (msg_p).CUport= RC.mac[k]->eth_params_n.remote_portd;
|
||||
//strcpy(F1AP_SETUP_REQ (msg_p).CU_ip_address[l].ipv6_address,*(F1ParamList.paramarray[l][ENB_CU_IPV6_ADDRESS_IDX].strptr));
|
||||
//F1AP_SETUP_REQ (msg_p).CU_port = RC.mac[k]->eth_params_n.remote_portc; // maybe we dont need it
|
||||
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
|
||||
@@ -1989,12 +1993,12 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
pthread_mutex_unlock(&rrc->cell_info_mutex);
|
||||
} while (cell_info_configured ==0);
|
||||
|
||||
rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k];
|
||||
rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k];
|
||||
rrc->configuration.tac = F1AP_SETUP_REQ (msg_p).tac[k];
|
||||
rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).nr_cellid[k];
|
||||
F1AP_SETUP_REQ (msg_p).nr_pci[k] = rrc->carrier[0].physCellId;
|
||||
F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0;
|
||||
rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).cell[k].mcc;
|
||||
rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).cell[k].mnc;
|
||||
rrc->configuration.tac = F1AP_SETUP_REQ (msg_p).cell[k].tac;
|
||||
rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).cell[k].nr_cellid;
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].nr_pci = rrc->carrier[0].physCellId;
|
||||
F1AP_SETUP_REQ (msg_p).cell[k].num_ssi = 0;
|
||||
|
||||
if (rrc->carrier[0].sib1->tdd_Config) {
|
||||
LOG_I(ENB_APP,"ngran_DU: Configuring Cell %d for TDD\n",k);
|
||||
@@ -2070,12 +2074,12 @@ int RCconfig_gtpu(void ) {
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,"");
|
||||
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
|
||||
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U;
|
||||
strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
|
||||
sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", enb_port_for_S1U);
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, 0, GTPV1U_REQ))!=NULL,"");
|
||||
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_REQ(message).localAddr, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_REQ(message).localAddr);
|
||||
GTPV1U_REQ(message).localPort = enb_port_for_S1U;
|
||||
strcpy(GTPV1U_REQ(message).localAddrStr,address);
|
||||
sprintf(GTPV1U_REQ(message).localPortStr,"%d", enb_port_for_S1U);
|
||||
itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
|
||||
} else
|
||||
LOG_E(GTPU,"invalid address for S1U\n");
|
||||
@@ -3167,7 +3171,7 @@ void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
|
||||
(check_plmn_identity(carrier, resp->cells_to_activate[j].mcc, resp->cells_to_activate[j].mnc, resp->cells_to_activate[j].mnc_digit_length)>0 &&
|
||||
resp->cells_to_activate[j].nrpci == carrier->physCellId)) {
|
||||
// copy system information and decode it
|
||||
for (si_ind=2; si_ind<resp->cells_to_activate[j].num_SI + 2; si_ind++) {
|
||||
for (si_ind=0; si_ind<resp->cells_to_activate[j].num_SI; si_ind++) {
|
||||
//printf("SI %d size %d: ", si_ind, resp->cells_to_activate[j].SI_container_length[si_ind]);
|
||||
//for (int n=0;n<resp->cells_to_activate[j].SI_container_length[si_ind];n++)
|
||||
// printf("%02x ",resp->cells_to_activate[j].SI_container[si_ind][n]);
|
||||
@@ -3175,7 +3179,7 @@ void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
|
||||
if (si_ind==6) si_ind=9;
|
||||
if (resp->cells_to_activate[j].SI_container[si_ind] != NULL) {
|
||||
extract_and_decode_SI(i,
|
||||
si_ind,
|
||||
resp->cells_to_activate[j].SI_type[si_ind],
|
||||
resp->cells_to_activate[j].SI_container[si_ind],
|
||||
resp->cells_to_activate[j].SI_container_length[si_ind]);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,19 @@
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
abort();
|
||||
abort();
|
||||
}
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
) {
|
||||
abort();
|
||||
}
|
||||
|
||||
+79
-61
@@ -32,19 +32,22 @@
|
||||
|
||||
#include "f1ap_common.h"
|
||||
|
||||
static f1ap_cudu_inst_t *f1_du_inst[NUMBER_OF_eNB_MAX]= {0};
|
||||
static f1ap_cudu_inst_t *f1_cu_inst[NUMBER_OF_eNB_MAX]= {0};
|
||||
|
||||
#if defined(EMIT_ASN_DEBUG_EXTERN)
|
||||
int asn_debug = 0;
|
||||
int asn1_xer_print = 0;
|
||||
|
||||
inline void ASN_DEBUG(const char *fmt, ...)
|
||||
{
|
||||
inline void ASN_DEBUG(const char *fmt, ...) {
|
||||
if (asn_debug) {
|
||||
int adi = asn_debug_indent;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "[ASN1]");
|
||||
|
||||
while(adi--) fprintf(stderr, " ");
|
||||
while(adi--)
|
||||
fprintf(stderr, " ");
|
||||
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
@@ -53,142 +56,157 @@ inline void ASN_DEBUG(const char *fmt, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_t cu_mod_idP)
|
||||
{
|
||||
uint8_t F1AP_get_next_transaction_identifier(instance_t enb_mod_idP, instance_t cu_mod_idP) {
|
||||
static uint8_t transaction_identifier[NUMBER_OF_eNB_MAX];
|
||||
transaction_identifier[enb_mod_idP+cu_mod_idP] =
|
||||
(transaction_identifier[enb_mod_idP+cu_mod_idP] + 1) % F1AP_TRANSACTION_IDENTIFIER_NUMBER;
|
||||
(transaction_identifier[enb_mod_idP+cu_mod_idP] + 1) % F1AP_TRANSACTION_IDENTIFIER_NUMBER;
|
||||
//LOG_T(F1AP,"generated xid is %d\n",transaction_identifier[enb_mod_idP+cu_mod_idP]);
|
||||
return transaction_identifier[enb_mod_idP+cu_mod_idP];
|
||||
}
|
||||
|
||||
int f1ap_add_ue(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t module_idP,
|
||||
int CC_idP,
|
||||
int UE_id,
|
||||
f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP) {
|
||||
//Fixme: 4G F1 has race condtions, someone may debug it, using this test
|
||||
/*
|
||||
static pid_t t=-1;
|
||||
pid_t tNew=gettid();
|
||||
AssertFatal ( t==-1 || t==tNew, "This is not thread safe\n");
|
||||
t=tNew;
|
||||
*/
|
||||
AssertFatal( instanceP < sizeofArray(f1_cu_inst), "");
|
||||
return isCU == CUtype ? f1_cu_inst[ instanceP]: f1_du_inst[ instanceP];
|
||||
}
|
||||
|
||||
void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req) {
|
||||
if (isCU == CUtype) {
|
||||
AssertFatal(f1_cu_inst[instanceP] == NULL, "Double call to F1 CU init\n");
|
||||
f1_cu_inst[instanceP]=( f1ap_cudu_inst_t *) calloc(1, sizeof( f1ap_cudu_inst_t));
|
||||
//memcpy(f1_cu_inst[instanceP]->setupReq, req, sizeof(f1ap_setup_req_t) );
|
||||
} else {
|
||||
AssertFatal(f1_du_inst[instanceP] == NULL, "Double call to F1 DU init\n");
|
||||
f1_du_inst[instanceP]=( f1ap_cudu_inst_t *) calloc(1, sizeof(f1ap_cudu_inst_t));
|
||||
memcpy(&f1_du_inst[instanceP]->setupReq, req, sizeof(f1ap_setup_req_t) );
|
||||
}
|
||||
}
|
||||
|
||||
int f1ap_add_ue(F1_t isCu,
|
||||
instance_t instanceP,
|
||||
rnti_t rntiP) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].rnti == rntiP) {
|
||||
f1_inst->f1ap_ue[i].f1ap_uid = i;
|
||||
f1_inst->f1ap_ue[i].mac_uid = UE_id;
|
||||
LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %d\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
|
||||
LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find the rnti
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].rnti == 0 ) {
|
||||
f1_inst->f1ap_ue[i].rnti = rntiP;
|
||||
f1_inst->f1ap_ue[i].f1ap_uid = i;
|
||||
f1_inst->f1ap_ue[i].mac_uid = UE_id;
|
||||
f1_inst->f1ap_ue[i].du_ue_f1ap_id = rntiP;
|
||||
f1_inst->f1ap_ue[i].cu_ue_f1ap_id = rntiP;
|
||||
f1_inst->num_ues++;
|
||||
LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %d\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
|
||||
LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int f1ap_remove_ue(f1ap_cudu_inst_t *f1_inst,
|
||||
int f1ap_remove_ue(F1_t isCu, instance_t instanceP,
|
||||
rnti_t rntiP) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].rnti == rntiP) {
|
||||
f1_inst->f1ap_ue[i].rnti = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f1_inst->num_ues--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int f1ap_get_du_ue_f1ap_id(f1ap_cudu_inst_t *f1_inst,
|
||||
rnti_t rntiP) {
|
||||
int f1ap_get_du_ue_f1ap_id(F1_t isCu, instance_t instanceP,
|
||||
rnti_t rntiP) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].rnti == rntiP) {
|
||||
return f1_inst->f1ap_ue[i].du_ue_f1ap_id;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1ap_get_cu_ue_f1ap_id(f1ap_cudu_inst_t *f1_inst,
|
||||
rnti_t rntiP) {
|
||||
int f1ap_get_cu_ue_f1ap_id(F1_t isCu, instance_t instanceP,
|
||||
rnti_t rntiP) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].rnti == rntiP) {
|
||||
return f1_inst->f1ap_ue[i].cu_ue_f1ap_id;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1ap_get_rnti_by_du_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t du_ue_f1ap_id ) {
|
||||
int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP,
|
||||
instance_t du_ue_f1ap_id ) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) {
|
||||
return f1_inst->f1ap_ue[i].rnti;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1ap_get_rnti_by_cu_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t cu_ue_f1ap_id ) {
|
||||
int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP,
|
||||
instance_t cu_ue_f1ap_id ) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP);
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) {
|
||||
return f1_inst->f1ap_ue[i].rnti;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1ap_get_du_uid(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t du_ue_f1ap_id ) {
|
||||
int f1ap_du_add_cu_ue_id(instance_t instanceP,
|
||||
instance_t du_ue_f1ap_id,
|
||||
instance_t cu_ue_f1ap_id) {
|
||||
f1ap_cudu_inst_t *f1_inst=getCxt(DUtype, instanceP);
|
||||
instance_t f1ap_uid=-1;
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) {
|
||||
return i;
|
||||
f1ap_uid=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1ap_get_cu_uid(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t cu_ue_f1ap_id ) {
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (f1ap_uid < 0 || f1ap_uid >= MAX_MOBILES_PER_ENB)
|
||||
return -1;
|
||||
|
||||
int f1ap_get_uid_by_rnti(f1ap_cudu_inst_t *f1_inst,
|
||||
rnti_t rntiP ) {
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
if (f1_inst->f1ap_ue[i].rnti == rntiP) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1ap_du_add_cu_ue_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t du_ue_f1ap_id,
|
||||
module_id_t cu_ue_f1ap_id) {
|
||||
module_id_t f1ap_uid = f1ap_get_du_uid(f1_inst,du_ue_f1ap_id);
|
||||
if (f1ap_uid < 0 || f1ap_uid >= MAX_MOBILES_PER_ENB) return -1;
|
||||
f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id;
|
||||
LOG_I(F1AP, "Adding cu_ue_f1ap_id %d for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti);
|
||||
LOG_I(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int f1ap_cu_add_du_ue_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t cu_ue_f1ap_id,
|
||||
module_id_t du_ue_f1ap_id) {
|
||||
module_id_t f1ap_uid = f1ap_get_cu_uid(f1_inst,cu_ue_f1ap_id);
|
||||
if (f1ap_uid < 0 || f1ap_uid >= MAX_MOBILES_PER_ENB) return -1;
|
||||
f1_inst->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
|
||||
LOG_I(F1AP, "Adding du_ue_f1ap_id %d for UE with RNTI %x\n", du_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti);
|
||||
return 0;
|
||||
int f1ap_assoc_id(F1_t isCu, instance_t instanceP) {
|
||||
f1ap_setup_req_t *f1_inst=f1ap_req(isCu, instanceP);
|
||||
return f1_inst->assoc_id;
|
||||
}
|
||||
|
||||
+63
-49
@@ -31,19 +31,20 @@
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H_
|
||||
# include "config.h"
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef F1AP_COMMON_H_
|
||||
#define F1AP_COMMON_H_
|
||||
|
||||
#include "openairinterface5g_limits.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
|
||||
#define F1AP_UE_IDENTIFIER_NUMBER 3
|
||||
#define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3
|
||||
|
||||
#if defined(EMIT_ASN_DEBUG_EXTERN)
|
||||
inline void ASN_DEBUG(const char *fmt, ...);
|
||||
inline void ASN_DEBUG(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#include "F1AP_RAT-FrequencyPriorityInformation.h"
|
||||
@@ -360,14 +361,14 @@ inline void ASN_DEBUG(const char *fmt, ...);
|
||||
|
||||
/* Checking version of ASN1C compiler */
|
||||
#if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION)
|
||||
# error "You are compiling f1ap with the wrong version of ASN1C"
|
||||
# error "You are compiling f1ap with the wrong version of ASN1C"
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE (0)
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
# define TRUE (!FALSE)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#define F1AP_UE_ID_FMT "0x%06"PRIX32
|
||||
@@ -375,20 +376,20 @@ inline void ASN_DEBUG(const char *fmt, ...);
|
||||
#include "assertions.h"
|
||||
|
||||
#if defined(ENB_MODE)
|
||||
# include "common/utils/LOG/log.h"
|
||||
# include "f1ap_default_values.h"
|
||||
# define F1AP_ERROR(x, args...) LOG_E(F1AP, x, ##args)
|
||||
# define F1AP_WARN(x, args...) LOG_W(F1AP, x, ##args)
|
||||
# define F1AP_TRAF(x, args...) LOG_I(F1AP, x, ##args)
|
||||
# define F1AP_INFO(x, args...) LOG_I(F1AP, x, ##args)
|
||||
# define F1AP_DEBUG(x, args...) LOG_I(F1AP, x, ##args)
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "f1ap_default_values.h"
|
||||
#define F1AP_ERROR(x, args...) LOG_E(F1AP, x, ##args)
|
||||
#define F1AP_WARN(x, args...) LOG_W(F1AP, x, ##args)
|
||||
#define F1AP_TRAF(x, args...) LOG_I(F1AP, x, ##args)
|
||||
#define F1AP_INFO(x, args...) LOG_I(F1AP, x, ##args)
|
||||
#define F1AP_DEBUG(x, args...) LOG_I(F1AP, x, ##args)
|
||||
#else
|
||||
//# include "mme_default_values.h"
|
||||
# define F1AP_ERROR(x, args...) do { fprintf(stdout, "[F1AP][E]"x, ##args); } while(0)
|
||||
# define F1AP_WARN(x, args...) do { fprintf(stdout, "[F1AP][W]"x, ##args); } while(0)
|
||||
# define F1AP_TRAF(x, args...) do { fprintf(stdout, "[F1AP][T]"x, ##args); } while(0)
|
||||
# define F1AP_INFO(x, args...) do { fprintf(stdout, "[F1AP][I]"x, ##args); } while(0)
|
||||
# define F1AP_DEBUG(x, args...) do { fprintf(stdout, "[F1AP][D]"x, ##args); } while(0)
|
||||
//# include "mme_default_values.h"
|
||||
#define F1AP_ERROR(x, args...) do { fprintf(stdout, "[F1AP][E]"x, ##args); } while(0)
|
||||
#define F1AP_WARN(x, args...) do { fprintf(stdout, "[F1AP][W]"x, ##args); } while(0)
|
||||
#define F1AP_TRAF(x, args...) do { fprintf(stdout, "[F1AP][T]"x, ##args); } while(0)
|
||||
#define F1AP_INFO(x, args...) do { fprintf(stdout, "[F1AP][I]"x, ##args); } while(0)
|
||||
#define F1AP_DEBUG(x, args...) do { fprintf(stdout, "[F1AP][D]"x, ##args); } while(0)
|
||||
#endif
|
||||
|
||||
//Forward declaration
|
||||
@@ -407,73 +408,86 @@ inline void ASN_DEBUG(const char *fmt, ...);
|
||||
if (mandatory) DevAssert(ie != NULL); \
|
||||
} while(0)
|
||||
|
||||
/** \brief Function callback prototype.
|
||||
/** \brief Function array prototype.
|
||||
**/
|
||||
typedef int (*f1ap_message_decoded_callback)(
|
||||
typedef int (*f1ap_message_processing_t)(
|
||||
instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *message_p
|
||||
);
|
||||
int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t *const data, const uint32_t data_length);
|
||||
|
||||
typedef struct f1ap_cudu_ue_inst_s {
|
||||
// used for eNB stats generation
|
||||
rnti_t rnti;
|
||||
module_id_t f1ap_uid;
|
||||
module_id_t mac_uid;
|
||||
module_id_t du_ue_f1ap_id;
|
||||
module_id_t cu_ue_f1ap_id;
|
||||
instance_t f1ap_uid;
|
||||
instance_t du_ue_f1ap_id;
|
||||
instance_t cu_ue_f1ap_id;
|
||||
} f1ap_cudu_ue_t;
|
||||
|
||||
typedef struct f1ap_cudu_inst_s {
|
||||
f1ap_setup_req_t setupReq;
|
||||
uint16_t sctp_in_streams;
|
||||
uint16_t sctp_out_streams;
|
||||
uint16_t default_sctp_stream_id;
|
||||
instance_t gtpInst;
|
||||
uint64_t gNB_DU_id;
|
||||
uint16_t num_ues;
|
||||
f1ap_cudu_ue_t f1ap_ue[MAX_MOBILES_PER_ENB];
|
||||
} f1ap_cudu_inst_t;
|
||||
|
||||
typedef enum {
|
||||
DUtype=0,
|
||||
CUtype
|
||||
} F1_t;
|
||||
|
||||
static const int nrb_lut[29] = {11, 18, 24, 25, 31, 32, 38, 51, 52, 65, 66, 78, 79, 93, 106, 107, 121, 132, 133, 135, 160, 162, 189, 216, 217, 245, 264, 270, 273};
|
||||
|
||||
uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_t cu_mod_idP);
|
||||
uint8_t F1AP_get_next_transaction_identifier(instance_t enb_mod_idP, instance_t cu_mod_idP);
|
||||
|
||||
f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP);
|
||||
|
||||
int f1ap_add_ue(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t module_idP,
|
||||
int CC_idP,
|
||||
int UE_id,
|
||||
void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req);
|
||||
int f1ap_add_ue(F1_t isCu,
|
||||
instance_t instanceP,
|
||||
rnti_t rntiP);
|
||||
|
||||
int f1ap_remove_ue(f1ap_cudu_inst_t *f1_inst,
|
||||
int f1ap_remove_ue(F1_t isCu, instance_t instanceP,
|
||||
rnti_t rntiP);
|
||||
|
||||
int f1ap_get_du_ue_f1ap_id (f1ap_cudu_inst_t *f1_inst,
|
||||
int f1ap_get_du_ue_f1ap_id (F1_t isCu, instance_t instanceP,
|
||||
rnti_t rntiP);
|
||||
|
||||
int f1ap_get_cu_ue_f1ap_id (f1ap_cudu_inst_t *f1_inst,
|
||||
int f1ap_get_cu_ue_f1ap_id (F1_t isCu, instance_t instanceP,
|
||||
rnti_t rntiP);
|
||||
|
||||
|
||||
int f1ap_get_rnti_by_du_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t du_ue_f1ap_id );
|
||||
int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP,
|
||||
instance_t du_ue_f1ap_id );
|
||||
|
||||
|
||||
int f1ap_get_rnti_by_cu_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t cu_ue_f1ap_id );
|
||||
int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP,
|
||||
instance_t cu_ue_f1ap_id );
|
||||
|
||||
int f1ap_du_add_cu_ue_id(instance_t instanceP,
|
||||
instance_t du_ue_f1ap_id,
|
||||
instance_t cu_ue_f1ap_id);
|
||||
|
||||
int f1ap_get_du_uid(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t du_ue_f1ap_id );
|
||||
int f1ap_assoc_id(F1_t isCu, instance_t instanceP);
|
||||
|
||||
int f1ap_get_cu_uid(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t cu_ue_f1ap_id );
|
||||
static inline f1ap_setup_req_t *f1ap_req(F1_t isCu, instance_t instanceP) {
|
||||
return &getCxt(isCu, instanceP)->setupReq;
|
||||
}
|
||||
|
||||
int f1ap_get_uid_by_rnti(f1ap_cudu_inst_t *f1_inst,
|
||||
rnti_t rntiP );
|
||||
#define TASK_F1APP f1ap_req(false, instance)->cell_type==CELL_MACRO_GNB?TASK_GNB_APP:TASK_ENB_APP
|
||||
|
||||
int f1ap_du_add_cu_ue_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t du_ue_f1ap_id,
|
||||
module_id_t cu_ue_f1ap_id);
|
||||
|
||||
int f1ap_cu_add_du_ue_id(f1ap_cudu_inst_t *f1_inst,
|
||||
module_id_t cu_ue_f1ap_id,
|
||||
module_id_t du_ue_f1ap_id);
|
||||
//lts: C struct type is not homogeneous, so we need macros instead of functions
|
||||
#define addnRCGI(nRCGi, servedCelL) \
|
||||
MCC_MNC_TO_PLMNID((servedCelL)->mcc,(servedCelL)-> mnc,(servedCelL)->mnc_digit_length, \
|
||||
&((nRCGi).pLMN_Identity)); \
|
||||
NR_CELL_ID_TO_BIT_STRING((servedCelL)->nr_cellid, &((nRCGi).nRCellIdentity));
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
#endif /* F1AP_COMMON_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,39 +72,39 @@ int CU_send_F1_SETUP_FAILURE(instance_t instance);
|
||||
* gNB-DU Configuration Update
|
||||
*/
|
||||
int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
|
||||
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure);
|
||||
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure);
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge);
|
||||
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge);
|
||||
|
||||
/*
|
||||
* gNB-CU Configuration Update
|
||||
*/
|
||||
int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update);
|
||||
int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* gNB-DU Resource Coordination
|
||||
*/
|
||||
int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
|
||||
F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse);
|
||||
F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse);
|
||||
|
||||
#endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */
|
||||
|
||||
@@ -38,78 +38,54 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
|
||||
// Bing Kai: create CU and DU context, and put all the information there.
|
||||
uint64_t du_ue_f1ap_id = 0;
|
||||
uint32_t f1ap_assoc_id = 0;
|
||||
uint32_t f1ap_stream = 0;
|
||||
|
||||
|
||||
extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
|
||||
|
||||
/*
|
||||
Initial UL RRC Message Transfer
|
||||
*/
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
LOG_D(F1AP, "CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER\n");
|
||||
// decode the F1 message
|
||||
// get the rrc message from the contauiner
|
||||
// get the rrc message from the contauiner
|
||||
// call func rrc_eNB_decode_ccch: <-- needs some update here
|
||||
MessageDef *message_p;
|
||||
F1AP_InitialULRRCMessageTransfer_t *container;
|
||||
F1AP_InitialULRRCMessageTransferIEs_t *ie;
|
||||
|
||||
rnti_t rnti;
|
||||
sdu_size_t ccch_sdu_len;
|
||||
int CC_id =0;
|
||||
|
||||
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
|
||||
if (stream != 0) {
|
||||
LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
// TODO: use context
|
||||
f1ap_stream = stream;
|
||||
f1ap_assoc_id = assoc_id;
|
||||
|
||||
container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer;
|
||||
|
||||
/* GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
LOG_D(F1AP, "du_ue_f1ap_id %lu \n", du_ue_f1ap_id);
|
||||
|
||||
/* NRCGI
|
||||
* TODO: process NRCGI
|
||||
/* NRCGI
|
||||
* Fixme: process NRCGI
|
||||
*/
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_NRCGI, true);
|
||||
|
||||
|
||||
uint64_t nr_cellid;
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid);
|
||||
|
||||
/* RNTI */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_C_RNTI, true);
|
||||
rnti = ie->value.choice.C_RNTI;
|
||||
|
||||
/* RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
AssertFatal(ie!=NULL,"RRCContainer is missing\n");
|
||||
|
||||
// create an ITTI message and copy SDU
|
||||
if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
|
||||
if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) {
|
||||
message_p = itti_alloc_new_message (TASK_CU_F1, 0, NR_RRC_MAC_CCCH_DATA_IND);
|
||||
memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
|
||||
ccch_sdu_len = ie->value.choice.RRCContainer.size;
|
||||
@@ -123,310 +99,212 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
ccch_sdu_len);
|
||||
}
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
|
||||
LOG_I(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__, ie->value.choice.RRCContainer.size);
|
||||
/* DUtoCURRCContainer */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false);
|
||||
|
||||
LOG_D(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__, ie->value.choice.RRCContainer.size);
|
||||
//for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
|
||||
// printf("%02x ", RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]);
|
||||
//printf("\n");
|
||||
|
||||
/* DUtoCURRCContainer */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, true);
|
||||
if (ie) {
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t));
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = ie->value.choice.DUtoCURRCContainer.size;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(
|
||||
ie->value.choice.DUtoCURRCContainer.size);
|
||||
memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf,
|
||||
ie->value.choice.DUtoCURRCContainer.buf,
|
||||
ie->value.choice.DUtoCURRCContainer.size);
|
||||
}
|
||||
if (ie) {
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t));
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = ie->value.choice.DUtoCURRCContainer.size;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(ie->value.choice.DUtoCURRCContainer.size);
|
||||
memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf,
|
||||
ie->value.choice.DUtoCURRCContainer.buf,
|
||||
ie->value.choice.DUtoCURRCContainer.size);
|
||||
}
|
||||
|
||||
// Find instance from nr_cellid
|
||||
int rrc_inst = -1;
|
||||
if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
|
||||
for (int i=0;i<RC.nb_nr_inst;i++) {
|
||||
// first get RRC instance (note, no the ITTI instance)
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[i];
|
||||
if (rrc->nr_cellid == nr_cellid) {
|
||||
rrc_inst = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i=0;i<RC.nb_inst;i++) {
|
||||
// first get RRC instance (note, no the ITTI instance)
|
||||
eNB_RRC_INST *rrc = RC.rrc[i];
|
||||
if (rrc->nr_cellid == nr_cellid) {
|
||||
rrc_inst = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
AssertFatal(rrc_inst>=0,"couldn't find an RRC instance for nr_cell %llu\n",(unsigned long long int)nr_cellid);
|
||||
int f1ap_uid = f1ap_add_ue(CUtype, instance, rnti);
|
||||
|
||||
int f1ap_uid = f1ap_add_ue(&f1ap_cu_inst[rrc_inst], rrc_inst, CC_id, 0, rnti);
|
||||
if (f1ap_uid < 0 ) {
|
||||
LOG_E(F1AP, "Failed to add UE \n");
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
return -1;
|
||||
}
|
||||
f1ap_cu_inst[rrc_inst].f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = rrc_inst; // CU instance
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
|
||||
itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p);
|
||||
} else {
|
||||
RRC_MAC_CCCH_DATA_IND (message_p).frame = 0;
|
||||
RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
|
||||
RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len;
|
||||
RRC_MAC_CCCH_DATA_IND (message_p).enb_index = rrc_inst; // CU instance
|
||||
RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti;
|
||||
RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
|
||||
itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);
|
||||
}
|
||||
|
||||
//getCxt(true,ITTI_MSG_DESTINATION_ID(message_p))->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti;
|
||||
NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
|
||||
itti_send_msg_to_task (f1ap_req(true,ITTI_MSG_DESTINATION_ID(message_p))->cell_type==CELL_MACRO_GNB?TASK_RRC_GNB:TASK_RRC_ENB, instance, message_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
DL RRC Message Transfer.
|
||||
*/
|
||||
|
||||
//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) {
|
||||
int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
f1ap_dl_rrc_message_t *f1ap_dl_rrc)
|
||||
{
|
||||
|
||||
f1ap_dl_rrc_message_t *f1ap_dl_rrc) {
|
||||
LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n");
|
||||
F1AP_F1AP_PDU_t pdu;
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
F1AP_DLRRCMessageTransfer_t *out;
|
||||
F1AP_DLRRCMessageTransferIEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
|
||||
uint8_t *buffer=NULL;
|
||||
uint32_t len=0;
|
||||
/* Create */
|
||||
/* 0. Message Type */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
/* 0. Message Type */
|
||||
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
|
||||
pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer;
|
||||
pdu.choice.initiatingMessage->criticality = F1AP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer;
|
||||
out = &pdu.choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
|
||||
|
||||
asn1cCalloc(pdu.choice.initiatingMessage, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer;
|
||||
tmp->criticality = F1AP_Criticality_ignore;
|
||||
tmp->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer;
|
||||
out = &tmp->value.choice.DLRRCMessageTransfer;
|
||||
/* mandatory */
|
||||
/* c1. GNB_CU_UE_F1AP_ID */
|
||||
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
|
||||
ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti);
|
||||
LOG_I(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %ld)\n",
|
||||
(unsigned long long int)ie->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance);
|
||||
|
||||
|
||||
(unsigned long long int)ie1->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance);
|
||||
/* mandatory */
|
||||
/* c2. GNB_DU_UE_F1AP_ID */
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
LOG_I(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti);
|
||||
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti);
|
||||
LOG_I(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie2->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti);
|
||||
/* optional */
|
||||
/* c3. oldgNB_DU_UE_F1AP_ID */
|
||||
/* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) {
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING;
|
||||
ie->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}*/
|
||||
|
||||
/* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING;
|
||||
ie3->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id;
|
||||
}*/
|
||||
/* mandatory */
|
||||
/* c4. SRBID */
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_SRBID;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID;
|
||||
ie->value.choice.SRBID = f1ap_dl_rrc->srb_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_SRBID;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID;
|
||||
ie4->value.choice.SRBID = f1ap_dl_rrc->srb_id;
|
||||
|
||||
/* optional */
|
||||
/* c5. ExecuteDuplication */
|
||||
if (f1ap_dl_rrc->execute_duplication) {
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_ExecuteDuplication;
|
||||
ie->criticality = F1AP_Criticality_ignore;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication;
|
||||
ie->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie5);
|
||||
ie5->id = F1AP_ProtocolIE_ID_id_ExecuteDuplication;
|
||||
ie5->criticality = F1AP_Criticality_ignore;
|
||||
ie5->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication;
|
||||
ie5->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true;
|
||||
}
|
||||
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* c6. RRCContainer */
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char*)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
|
||||
LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, f1ap_dl_rrc->rrc_container_length);
|
||||
for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
|
||||
printf("%02x ", f1ap_dl_rrc->rrc_container[i]);
|
||||
printf("\n");
|
||||
}
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie6);
|
||||
ie6->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie6->criticality = F1AP_Criticality_reject;
|
||||
ie6->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie6->value.choice.RRCContainer,
|
||||
(const char *)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length);
|
||||
|
||||
/* optional */
|
||||
/* c7. RAT_FrequencyPriorityInformation */
|
||||
/* TODO */
|
||||
int endc=1;
|
||||
ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
|
||||
ie->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;
|
||||
if (endc==1) {
|
||||
ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC;
|
||||
ie->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 123L;
|
||||
}
|
||||
else {
|
||||
ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN;
|
||||
ie->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L;
|
||||
}
|
||||
/* TODO */
|
||||
if (0) {
|
||||
int endc=1;
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie7);
|
||||
ie7->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
|
||||
ie7->criticality = F1AP_Criticality_reject;
|
||||
ie7->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;
|
||||
|
||||
if (endc==1) {
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC;
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 123L;
|
||||
} else {
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN;
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L;
|
||||
}
|
||||
|
||||
//ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
|
||||
//ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
}
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cu_f1ap_itti_send_sctp_data_req(instance, f1ap_assoc_id /* BK: fix me*/ , buffer, len, 0 /* BK: fix me*/);
|
||||
|
||||
f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0 /* BK: fix me*/);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
UL RRC Message Transfer
|
||||
*/
|
||||
|
||||
int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
|
||||
LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n");
|
||||
|
||||
F1AP_ULRRCMessageTransfer_t *container;
|
||||
F1AP_ULRRCMessageTransferIEs_t *ie;
|
||||
|
||||
uint64_t cu_ue_f1ap_id;
|
||||
uint64_t du_ue_f1ap_id;
|
||||
uint64_t srb_id;
|
||||
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
|
||||
if (stream != 0) {
|
||||
LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
|
||||
assoc_id, stream);
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer;
|
||||
|
||||
|
||||
/* GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n", cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id));
|
||||
|
||||
|
||||
LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n",
|
||||
cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id));
|
||||
/* GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n", du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], du_ue_f1ap_id));
|
||||
|
||||
|
||||
LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n",
|
||||
du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, du_ue_f1ap_id));
|
||||
/* mandatory */
|
||||
/* SRBID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_SRBID, true);
|
||||
srb_id = ie->value.choice.SRBID;
|
||||
if (srb_id < 1 )
|
||||
LOG_E(F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id);
|
||||
else
|
||||
LOG_D(F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id);
|
||||
|
||||
if (srb_id < 1 )
|
||||
LOG_E(F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id);
|
||||
else
|
||||
LOG_D(F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id);
|
||||
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
// print message in debug mode
|
||||
|
||||
// create an ITTI message and copy SDU
|
||||
|
||||
/*
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_DCCH_DATA_IND);
|
||||
|
||||
RRC_DCCH_DATA_IND (message_p).sdu_p = malloc(ie->value.choice.RRCContainer.size);
|
||||
|
||||
RRC_DCCH_DATA_IND (message_p).sdu_size = ie->value.choice.RRCContainer.size;
|
||||
memcpy(RRC_DCCH_DATA_IND (message_p).sdu_p, ie->value.choice.RRCContainer.buf,
|
||||
ie->value.choice.RRCContainer.size);
|
||||
|
||||
RRC_DCCH_DATA_IND (message_p).dcch_index = srb_id;
|
||||
RRC_DCCH_DATA_IND (message_p).rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id);
|
||||
RRC_DCCH_DATA_IND (message_p).module_id = instance;
|
||||
RRC_DCCH_DATA_IND (message_p).eNB_index = instance; // not needed for CU
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance, message_p);
|
||||
*/
|
||||
protocol_ctxt_t ctxt;
|
||||
ctxt.module_id = instance;
|
||||
protocol_ctxt_t ctxt={0};
|
||||
ctxt.instance = instance;
|
||||
ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id);
|
||||
ctxt.module_id = instance;
|
||||
ctxt.rnti = f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id);
|
||||
ctxt.enb_flag = 1;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__);
|
||||
memcpy((void*)mb->data,(void*)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size);
|
||||
memcpy((void *)mb->data,(void *)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size);
|
||||
LOG_I(F1AP, "Calling pdcp_data_ind for UE RNTI %x srb_id %lu with size %ld (DCCH) \n", ctxt.rnti, srb_id, ie->value.choice.RRCContainer.size);
|
||||
|
||||
//LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size);
|
||||
//for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
|
||||
// printf("%02x ", mb->data[i]);
|
||||
//printf("\n");
|
||||
|
||||
pdcp_data_ind (&ctxt,
|
||||
1, // srb_flag
|
||||
0, // embms_flag
|
||||
srb_id,
|
||||
ie->value.choice.RRCContainer.size,
|
||||
mb);
|
||||
1, // srb_flag
|
||||
0, // embms_flag
|
||||
srb_id,
|
||||
ie->value.choice.RRCContainer.size,
|
||||
mb, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
#define F1AP_CU_RRC_MESSAGE_TRANSFER_H_
|
||||
|
||||
int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
f1ap_dl_rrc_message_t *f1ap_dl_rrc);
|
||||
|
||||
@@ -31,150 +31,134 @@
|
||||
*/
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_handlers.h"
|
||||
#include "f1ap_cu_interface_management.h"
|
||||
#include "f1ap_cu_rrc_message_transfer.h"
|
||||
#include "f1ap_cu_ue_context_management.h"
|
||||
#include "f1ap_cu_task.h"
|
||||
#include "proto_agent.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern uint8_t proto_agent_flag;
|
||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||
instance_t CUuniqInstance=0;
|
||||
|
||||
f1ap_setup_req_t *f1ap_du_data_from_du;
|
||||
f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
|
||||
|
||||
void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
|
||||
// Nothing
|
||||
static instance_t cu_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) {
|
||||
openAddr_t tmp= {0};
|
||||
strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost)-1);
|
||||
strncpy(tmp.destinationHost, IPaddrs->remote_addr, sizeof(tmp.destinationHost)-1);
|
||||
sprintf(tmp.originService, "%d", IPaddrs->my_portd);
|
||||
sprintf(tmp.destinationService, "%d", IPaddrs->remote_portd);
|
||||
return ocp_gtpv1Init(tmp);
|
||||
}
|
||||
|
||||
void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
|
||||
static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind,
|
||||
eth_params_t *IPaddrs) {
|
||||
createF1inst(true, instance, NULL);
|
||||
// save the assoc id
|
||||
f1ap_setup_req_t *f1ap_cu_data=f1ap_req(true, instance);
|
||||
f1ap_cu_data->assoc_id = sctp_new_association_ind->assoc_id;
|
||||
f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams;
|
||||
f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams;
|
||||
f1ap_cu_data->default_sctp_stream_id = 0;
|
||||
getCxt(CUtype, instance)->gtpInst=cu_task_create_gtpu_instance_to_du(IPaddrs);
|
||||
AssertFatal(getCxt(CUtype, instance)->gtpInst>0,"Failed to create CU F1-U UDP listener");
|
||||
// Fixme: fully inconsistent instances management
|
||||
// dirty global var is a bad fix
|
||||
CUuniqInstance=getCxt(CUtype, instance)->gtpInst;
|
||||
}
|
||||
|
||||
static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN)
|
||||
proto_agent_stop(instance);
|
||||
//f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return; // exit -1 for debugging
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
//if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN)
|
||||
//proto_agent_stop(instance);
|
||||
//f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return; // exit -1 for debugging
|
||||
}
|
||||
|
||||
// go to an init func
|
||||
f1ap_du_data_from_du = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t));
|
||||
// save the assoc id
|
||||
f1ap_du_data_from_du->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
f1ap_du_data_from_du->sctp_in_streams = sctp_new_association_resp->in_streams;
|
||||
f1ap_du_data_from_du->sctp_out_streams = sctp_new_association_resp->out_streams;
|
||||
|
||||
/* setup parameters for F1U and start the server */
|
||||
const cudu_params_t params = (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_CU) ? (cudu_params_t){
|
||||
.local_ipv4_address = RC.nrrrc[instance]->eth_params_s.my_addr,
|
||||
.local_port = RC.nrrrc[instance]->eth_params_s.my_portd,
|
||||
.remote_ipv4_address = RC.nrrrc[instance]->eth_params_s.remote_addr,
|
||||
.remote_port = RC.nrrrc[instance]->eth_params_s.remote_portd
|
||||
} : (cudu_params_t){
|
||||
.local_ipv4_address = RC.rrc[instance]->eth_params_s.my_addr,
|
||||
.local_port = RC.rrc[instance]->eth_params_s.my_portd,
|
||||
.remote_ipv4_address = RC.rrc[instance]->eth_params_s.remote_addr,
|
||||
.remote_port = RC.rrc[instance]->eth_params_s.remote_portd
|
||||
};
|
||||
AssertFatal(proto_agent_start(instance, ¶ms) == 0,
|
||||
"could not start PROTO_AGENT for F1U on instance %ld!\n", instance);
|
||||
proto_agent_flag = 1;
|
||||
}
|
||||
|
||||
void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
|
||||
static void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
|
||||
int result;
|
||||
|
||||
DevAssert(sctp_data_ind != NULL);
|
||||
|
||||
f1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
void cu_task_send_sctp_init_req(instance_t enb_id) {
|
||||
static void cu_task_send_sctp_init_req(instance_t instance, char *my_addr) {
|
||||
// 1. get the itti msg, and retrive the enb_id from the message
|
||||
// 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
|
||||
// 3. creat an itti message to init
|
||||
|
||||
LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket)\n");
|
||||
MessageDef *message_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_CU_F1, 0, SCTP_INIT_MSG);
|
||||
message_p->ittiMsg.sctp_init.port = F1AP_PORT_NUMBER;
|
||||
message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID;
|
||||
message_p->ittiMsg.sctp_init.ipv4 = 1;
|
||||
message_p->ittiMsg.sctp_init.ipv6 = 0;
|
||||
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
|
||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU) {
|
||||
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.nrrrc[enb_id]->eth_params_s.my_addr);
|
||||
} else{
|
||||
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
|
||||
}
|
||||
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr);
|
||||
/*
|
||||
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
|
||||
* * * * Disable it for now.
|
||||
*/
|
||||
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
|
||||
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
|
||||
void *F1AP_CU_task(void *arg) {
|
||||
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
|
||||
LOG_I(F1AP, "Starting F1AP at CU\n");
|
||||
|
||||
// no RLC in CU, initialize mem pool for PDCP
|
||||
pool_buffer_init();
|
||||
|
||||
itti_mark_task_ready(TASK_CU_F1);
|
||||
eth_params_t *IPaddrs;
|
||||
|
||||
cu_task_send_sctp_init_req(0);
|
||||
// Hardcoded instance id!
|
||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU)
|
||||
IPaddrs=&RC.nrrrc[0]->eth_params_s;
|
||||
else
|
||||
IPaddrs=&RC.rrc[0]->eth_params_s;
|
||||
|
||||
cu_task_send_sctp_init_req(0, IPaddrs->my_addr);
|
||||
|
||||
while (1) {
|
||||
itti_receive_msg(TASK_CU_F1, &received_msg);
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case SCTP_NEW_ASSOCIATION_IND:
|
||||
LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %ld\n",
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
cu_task_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_ind);
|
||||
cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_ind,
|
||||
IPaddrs);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n",
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
cu_task_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %ld\n",
|
||||
ITTI_MSG_DESTINATION_INSTANCE(received_msg));
|
||||
cu_task_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
case F1AP_SETUP_RESP: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_SETUP_RESP\n");
|
||||
// CU_send_f1setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &F1AP_SETUP_RESP(received_msg));
|
||||
CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_SETUP_RESP(received_msg));
|
||||
&F1AP_SETUP_RESP(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc
|
||||
@@ -182,19 +166,19 @@ void *F1AP_CU_task(void *arg) {
|
||||
// CU_send_f1setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
// &F1AP_SETUP_RESP(received_msg));
|
||||
CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_DL_RRC_MESSAGE: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n");
|
||||
CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_DL_RRC_MESSAGE(received_msg));
|
||||
&F1AP_DL_RRC_MESSAGE(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc
|
||||
LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_SETUP_REQ\n");
|
||||
CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
||||
@@ -203,13 +187,13 @@ void *F1AP_CU_task(void *arg) {
|
||||
&F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
|
||||
break;
|
||||
|
||||
// case F1AP_SETUP_RESPONSE: // This is from RRC
|
||||
// CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp)
|
||||
// break;
|
||||
|
||||
// case F1AP_SETUP_FAILURE: // This is from RRC
|
||||
// CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure)
|
||||
// break;
|
||||
// case F1AP_SETUP_RESPONSE: // This is from RRC
|
||||
// CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp)
|
||||
// break;
|
||||
|
||||
// case F1AP_SETUP_FAILURE: // This is from RRC
|
||||
// CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure)
|
||||
// break;
|
||||
|
||||
case TERMINATE_MESSAGE:
|
||||
LOG_W(F1AP, " *** Exiting F1AP thread\n");
|
||||
@@ -221,9 +205,9 @@ void *F1AP_CU_task(void *arg) {
|
||||
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
break;
|
||||
} // switch
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
|
||||
received_msg = NULL;
|
||||
} // while
|
||||
|
||||
|
||||
@@ -22,11 +22,6 @@
|
||||
#ifndef F1AP_CU_TASK_H_
|
||||
#define F1AP_CU_TASK_H_
|
||||
|
||||
void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
|
||||
void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
|
||||
void cu_task_send_sctp_init_req(instance_t enb_id);
|
||||
|
||||
void *F1AP_CU_task(void *arg);
|
||||
|
||||
#endif /* F1AP_CU_TASK_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@
|
||||
* UE Context Setup
|
||||
*/
|
||||
int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req);
|
||||
f1ap_ue_context_setup_t *f1ap_ue_context_setup_req);
|
||||
|
||||
int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
@@ -54,9 +54,9 @@ int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance,
|
||||
* UE Context Release Request (gNB-DU initiated)
|
||||
*/
|
||||
int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* UE Context Release (gNB-CU initiated)
|
||||
@@ -65,32 +65,32 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
f1ap_ue_context_release_cmd_t *cmd);
|
||||
|
||||
int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* UE Context Modification (gNB-CU initiated)
|
||||
*/
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance);
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* UE Context Modification Required (gNB-DU initiated)
|
||||
*/
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t);
|
||||
F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t);
|
||||
|
||||
/*
|
||||
* UE Inactivity Notification
|
||||
|
||||
@@ -35,15 +35,13 @@
|
||||
|
||||
int asn1_decoder_xer_print = 0;
|
||||
|
||||
static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) {
|
||||
//MessageDef *message_p;
|
||||
//MessagesIds message_id;
|
||||
//asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.initiatingMessage->procedureCode) {
|
||||
|
||||
case F1AP_ProcedureCode_id_F1Setup:
|
||||
//res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
|
||||
@@ -68,15 +66,19 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
|
||||
//res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_ULRRCMessageTransfer\n", __func__);
|
||||
break;
|
||||
|
||||
case F1AP_ProcedureCode_id_UEContextRelease:
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__);
|
||||
break;
|
||||
|
||||
case F1AP_ProcedureCode_id_UEContextReleaseRequest:
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextReleaseRequest\n", __func__);
|
||||
break;
|
||||
|
||||
case F1AP_ProcedureCode_id_UEContextSetup:
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
|
||||
break;
|
||||
|
||||
// case F1AP_ProcedureCode_id_InitialContextSetup:
|
||||
// res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
// message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG;
|
||||
@@ -92,7 +94,7 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
|
||||
// F1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
|
||||
// (int)pdu->choice.initiatingMessage->procedureCode);
|
||||
LOG_E(F1AP, "Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
return -1;
|
||||
@@ -101,8 +103,7 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu) {
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.successfulOutcome->procedureCode) {
|
||||
@@ -118,41 +119,41 @@ static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu)
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__);
|
||||
break;
|
||||
|
||||
case F1AP_ProcedureCode_id_UEContextSetup:
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f1ap_decode_unsuccessful_outcome(F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
static int f1ap_decode_unsuccessful_outcome(F1AP_F1AP_PDU_t *pdu) {
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.unsuccessfulOutcome->procedureCode) {
|
||||
case F1AP_ProcedureCode_id_F1Setup:
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
|
||||
break;
|
||||
LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
|
||||
break;
|
||||
|
||||
default:
|
||||
// F1AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
|
||||
// (int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
LOG_E(F1AP, "Unknown procedure ID (%d) for unsuccessfull outcome message\n",
|
||||
(int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
(int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
|
||||
{
|
||||
int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) {
|
||||
asn_dec_rval_t dec_ret;
|
||||
|
||||
DevAssert(buffer != NULL);
|
||||
|
||||
dec_ret = aper_decode(NULL,
|
||||
&asn_DEF_F1AP_F1AP_PDU,
|
||||
(void **)&pdu,
|
||||
@@ -166,6 +167,7 @@ int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t
|
||||
xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
LOG_E(F1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n");
|
||||
}
|
||||
|
||||
//LOG_I(F1AP, "f1ap_decode_pdu.dec_ret.code = %d\n", dec_ret.code);
|
||||
|
||||
if (dec_ret.code != RC_OK) {
|
||||
@@ -188,6 +190,5 @@ int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -76,43 +76,44 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance,
|
||||
* gNB-DU Configuration Update
|
||||
*/
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
|
||||
instance_t du_mod_idP,
|
||||
f1ap_setup_req_t *f1ap_du_data);
|
||||
instance_t du_mod_idP,
|
||||
f1ap_setup_req_t *f1ap_du_data);
|
||||
|
||||
int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* gNB-CU Configuration Update
|
||||
*/
|
||||
int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
|
||||
f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure);
|
||||
f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure);
|
||||
|
||||
int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge);
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* gNB-DU Resource Coordination
|
||||
*/
|
||||
int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
|
||||
F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
|
||||
F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
|
||||
|
||||
int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
#endif /* F1AP_DU_INTERFACE_MANAGEMENT_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,13 +44,13 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg);
|
||||
int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg);
|
||||
|
||||
int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP,
|
||||
int CC_idP,
|
||||
int UE_id,
|
||||
rnti_t rntiP,
|
||||
const uint8_t *sduP,
|
||||
sdu_size_t sdu_lenP,
|
||||
const int8_t *sdu2P,
|
||||
sdu_size_t sdu2_lenP);
|
||||
int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP,
|
||||
int CC_idP,
|
||||
int UE_id,
|
||||
rnti_t rntiP,
|
||||
const uint8_t *sduP,
|
||||
sdu_size_t sdu_lenP,
|
||||
const char *sdu2P,
|
||||
sdu_size_t sdu2_lenP);
|
||||
|
||||
#endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */
|
||||
|
||||
@@ -31,189 +31,171 @@
|
||||
*/
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_handlers.h"
|
||||
#include "f1ap_du_interface_management.h"
|
||||
#include "f1ap_du_ue_context_management.h"
|
||||
#include "f1ap_du_rrc_message_transfer.h"
|
||||
#include "f1ap_du_task.h"
|
||||
#include "proto_agent.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
f1ap_setup_req_t *f1ap_du_data;
|
||||
f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
|
||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||
instance_t DUuniqInstance=0;
|
||||
|
||||
void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1ap_setup_req) {
|
||||
|
||||
DevAssert(f1ap_setup_req != NULL);
|
||||
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_DU_F1, 0, SCTP_NEW_ASSOCIATION_REQ);
|
||||
|
||||
sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
|
||||
sctp_new_association_req_p->ulp_cnx_id = instance;
|
||||
sctp_new_association_req_p->port = F1AP_PORT_NUMBER;
|
||||
sctp_new_association_req_p->ppid = F1AP_SCTP_PPID;
|
||||
|
||||
sctp_new_association_req_p->in_streams = f1ap_setup_req->sctp_in_streams;
|
||||
sctp_new_association_req_p->out_streams = f1ap_setup_req->sctp_out_streams;
|
||||
|
||||
// remote
|
||||
memcpy(&sctp_new_association_req_p->remote_address,
|
||||
&f1ap_setup_req->CU_f1_ip_address,
|
||||
sizeof(f1ap_setup_req->CU_f1_ip_address));
|
||||
|
||||
// local
|
||||
memcpy(&sctp_new_association_req_p->local_address,
|
||||
&f1ap_setup_req->DU_f1_ip_address,
|
||||
sizeof(f1ap_setup_req->DU_f1_ip_address));
|
||||
|
||||
// store data
|
||||
f1ap_du_data = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t));
|
||||
*f1ap_du_data = *f1ap_setup_req;
|
||||
//printf("sib itti message %s\n", f1ap_setup_req_t->sib1[0]);
|
||||
|
||||
//printf("nr_cellid : %llx (%lld)",f1ap_setup_req->nr_cellid[0],f1ap_setup_req->nr_cellid[0]);
|
||||
|
||||
//du_f1ap_register_to_sctp
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
|
||||
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
LOG_E(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
(int)instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
//f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return; // exit -1 for debugging
|
||||
}
|
||||
|
||||
//f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return; // exit -1 for debugging
|
||||
}
|
||||
|
||||
// save the assoc id
|
||||
// save the assoc id
|
||||
f1ap_setup_req_t *f1ap_du_data=f1ap_req(false, instance);
|
||||
f1ap_du_data->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams;
|
||||
f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams;
|
||||
f1ap_du_data->default_sctp_stream_id = 0;
|
||||
|
||||
/* setup parameters for F1U and start the server */
|
||||
const cudu_params_t params = (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) ? (cudu_params_t){
|
||||
.local_ipv4_address = RC.nrmac[instance]->eth_params_n.my_addr,
|
||||
.local_port = RC.nrmac[instance]->eth_params_n.my_portd,
|
||||
.remote_ipv4_address = RC.nrmac[instance]->eth_params_n.remote_addr,
|
||||
.remote_port = RC.nrmac[instance]->eth_params_n.remote_portd
|
||||
} : (cudu_params_t){
|
||||
.local_ipv4_address = RC.mac[instance]->eth_params_n.my_addr,
|
||||
.local_port = RC.mac[instance]->eth_params_n.my_portd,
|
||||
.remote_ipv4_address = RC.mac[instance]->eth_params_n.remote_addr,
|
||||
.remote_port = RC.mac[instance]->eth_params_n.remote_portd
|
||||
};
|
||||
AssertFatal(proto_agent_start(instance, ¶ms) == 0,
|
||||
"could not start PROTO_AGENT for F1U on instance %ld!\n", instance);
|
||||
|
||||
DU_send_F1_SETUP_REQUEST(instance);
|
||||
}
|
||||
|
||||
void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind)
|
||||
{
|
||||
void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
|
||||
int result;
|
||||
|
||||
DevAssert(sctp_data_ind != NULL);
|
||||
|
||||
f1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) {
|
||||
openAddr_t tmp= {0};
|
||||
strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1);
|
||||
strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1);
|
||||
sprintf(tmp.originService, "%d", DUport);
|
||||
sprintf(tmp.destinationService, "%d", CUport);
|
||||
return ocp_gtpv1Init(tmp);
|
||||
}
|
||||
|
||||
void *F1AP_DU_task(void *arg) {
|
||||
|
||||
//sctp_cu_init();
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
|
||||
LOG_I(F1AP, "Starting F1AP at DU\n");
|
||||
|
||||
//f1ap_eNB_prepare_internal_data();
|
||||
|
||||
itti_mark_task_ready(TASK_DU_F1);
|
||||
|
||||
// SCTP
|
||||
while (1) {
|
||||
itti_receive_msg(TASK_DU_F1, &received_msg);
|
||||
MessageDef *msg = NULL;
|
||||
itti_receive_msg(TASK_DU_F1, &msg);
|
||||
instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
|
||||
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
|
||||
// case TERMINATE_MESSAGE:
|
||||
// //F1AP_WARN(" *** Exiting F1AP DU thread\n");
|
||||
// itti_exit_task();
|
||||
// break;
|
||||
|
||||
case F1AP_SETUP_REQ: // this is not a true F1 message, but rather an ITTI message sent by enb_app
|
||||
// 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message,
|
||||
switch (ITTI_MSG_ID(msg)) {
|
||||
case F1AP_SETUP_REQ:
|
||||
// this is not a true F1 message, but rather an ITTI message sent by enb_app
|
||||
// 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message,
|
||||
// 2. store the message in f1ap context, that is also stored in RC
|
||||
// 2. send a sctp_association req
|
||||
LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n");
|
||||
du_task_send_sctp_association_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_SETUP_REQ(received_msg));
|
||||
f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg);
|
||||
createF1inst(false, myInstance, msgSetup);
|
||||
getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address,
|
||||
msgSetup->CUport,
|
||||
msgSetup->DU_f1_ip_address.ipv4_address,
|
||||
msgSetup->DUport);
|
||||
AssertFatal(getCxt(DUtype, myInstance)->gtpInst>0,"Failed to create CU F1-U UDP listener");
|
||||
// Fixme: fully inconsistent instances management
|
||||
// dirty global var is a bad fix
|
||||
extern instance_t legacyInstanceMapping;
|
||||
legacyInstanceMapping = DUuniqInstance = getCxt(DUtype, myInstance)->gtpInst;
|
||||
du_task_send_sctp_association_req(myInstance,msgSetup);
|
||||
break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(received_msg));
|
||||
break;
|
||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg),
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg));
|
||||
break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE:
|
||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(received_msg));
|
||||
break;
|
||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(myInstance,
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(msg));
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
// 1. store the respon
|
||||
// 2. send the f1setup_req
|
||||
LOG_I(F1AP, "DU Task Received SCTP_NEW_ASSOCIATION_RESP\n");
|
||||
du_task_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
du_task_handle_sctp_association_resp(myInstance,
|
||||
&msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
case SCTP_DATA_IND:
|
||||
// ex: any F1 incoming message for DU ends here
|
||||
LOG_I(F1AP, "DU Task Received SCTP_DATA_IND\n");
|
||||
du_task_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
du_task_handle_sctp_data_ind(myInstance,
|
||||
&msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
case F1AP_INITIAL_UL_RRC_MESSAGE: // to rrc
|
||||
case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc
|
||||
LOG_I(F1AP, "DU Task Received F1AP_INITIAL_UL_RRC_MESSAGE\n");
|
||||
|
||||
f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(received_msg);
|
||||
DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0,0,0,msg->crnti,
|
||||
msg->rrc_container,
|
||||
msg->rrc_container_length,
|
||||
(const int8_t*)msg->du2cu_rrc_container,
|
||||
msg->du2cu_rrc_container_length);
|
||||
f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg);
|
||||
DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0,0,0,msgRrc->crnti,
|
||||
msgRrc->rrc_container,
|
||||
msgRrc->rrc_container_length,
|
||||
msgRrc->du2cu_rrc_container,
|
||||
msgRrc->du2cu_rrc_container_length
|
||||
);
|
||||
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");
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
|
||||
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UL_RRC_MESSAGE(received_msg));
|
||||
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance,
|
||||
&F1AP_UL_RRC_MESSAGE(msg));
|
||||
} else {
|
||||
DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UL_RRC_MESSAGE(received_msg));
|
||||
DU_send_UL_RRC_MESSAGE_TRANSFER(myInstance,
|
||||
&F1AP_UL_RRC_MESSAGE(msg));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_SETUP_RESP:
|
||||
DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
|
||||
LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n");
|
||||
DU_send_UE_CONTEXT_RELEASE_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_RELEASE_REQ(received_msg));
|
||||
DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance,
|
||||
&F1AP_UE_CONTEXT_RELEASE_REQ(msg));
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE:
|
||||
@@ -223,13 +205,12 @@ void *F1AP_DU_task(void *arg) {
|
||||
|
||||
default:
|
||||
LOG_E(F1AP, "DU Received unhandled message: %d:%s\n",
|
||||
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
ITTI_MSG_ID(msg), ITTI_MSG_NAME(msg));
|
||||
break;
|
||||
} // switch
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
|
||||
received_msg = NULL;
|
||||
int result = itti_free (ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
} // while
|
||||
|
||||
return NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,11 +36,12 @@
|
||||
/*
|
||||
* UE Context Setup
|
||||
*/
|
||||
int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req);
|
||||
|
||||
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance);
|
||||
int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance);
|
||||
|
||||
|
||||
@@ -55,9 +56,9 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
|
||||
* UE Context Release Command (gNB-CU initiated)
|
||||
*/
|
||||
int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* UE Context Release Complete (gNB-DU initiated)
|
||||
@@ -70,9 +71,9 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
* UE Context Modification (gNB-CU initiated)
|
||||
*/
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance);
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
||||
|
||||
@@ -82,9 +83,11 @@ int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
||||
*/
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance);
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req);
|
||||
|
||||
/*
|
||||
* UE Inactivity Notification
|
||||
|
||||
@@ -33,46 +33,9 @@
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_encoder.h"
|
||||
|
||||
int asn1_encoder_xer_print = 0;
|
||||
int asn1_encoder_xer_print = 1;
|
||||
|
||||
/*
|
||||
static inline int f1ap_encode_initiating(f1ap_message *message,
|
||||
uint8_t **buffer,
|
||||
uint32_t *len);
|
||||
|
||||
static inline int f1ap_encode_successfull_outcome(f1ap_message *message,
|
||||
uint8_t **buffer, uint32_t *len);
|
||||
|
||||
static inline int f1ap_encode_unsuccessfull_outcome(f1ap_message *message,
|
||||
uint8_t **buffer, uint32_t *len);
|
||||
|
||||
static inline int f1ap_encode_f1_setup_request(
|
||||
F1ap_F1SetupRequestIEs_t *f1SetupRequestIEs, uint8_t **buffer, uint32_t *length);
|
||||
|
||||
static inline int f1ap_encode_trace_failure(F1ap_TraceFailureIndicationIEs_t
|
||||
*trace_failure_ies_p, uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
static inline int f1ap_encode_initial_context_setup_response(
|
||||
F1ap_InitialContextSetupResponseIEs_t *initialContextSetupResponseIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
static inline
|
||||
int f1ap_encode_ue_context_release_complete(
|
||||
F1ap_UEContextReleaseCompleteIEs_t *f1ap_UEContextReleaseCompleteIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
static inline
|
||||
int f1ap_encode_ue_context_release_request(
|
||||
F1ap_UEContextReleaseRequestIEs_t *f1ap_UEContextReleaseRequestIEs,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
*/
|
||||
|
||||
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;
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
@@ -84,11 +47,23 @@ int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length)
|
||||
LOG_E(F1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n");
|
||||
}
|
||||
|
||||
AssertFatal((encoded = aper_encode_to_new_buffer(&asn_DEF_F1AP_F1AP_PDU, 0, pdu, (void **)buffer))>0,
|
||||
"Failed to encode F1AP message\n");
|
||||
char errbuf[128]; /* Buffer for error message */
|
||||
size_t errlen = sizeof(errbuf); /* Size of the buffer */
|
||||
int ret = asn_check_constraints(&asn_DEF_F1AP_F1AP_PDU, pdu, errbuf, &errlen);
|
||||
|
||||
/* assert(errlen < sizeof(errbuf)); // Guaranteed: you may rely on that */
|
||||
if(ret) {
|
||||
fprintf(stderr, "Constraint validation failed: %s\n", errbuf);
|
||||
}
|
||||
|
||||
encoded = aper_encode_to_new_buffer(&asn_DEF_F1AP_F1AP_PDU, 0, pdu, (void **)buffer);
|
||||
|
||||
if (encoded < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1AP message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*length = encoded;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
*/
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_handlers.h"
|
||||
#include "f1ap_decoder.h"
|
||||
#include "f1ap_cu_interface_management.h"
|
||||
#include "f1ap_du_interface_management.h"
|
||||
@@ -40,11 +39,9 @@
|
||||
#include "f1ap_cu_ue_context_management.h"
|
||||
#include "f1ap_du_ue_context_management.h"
|
||||
|
||||
extern f1ap_setup_req_t *f1ap_du_data_from_du;
|
||||
|
||||
/* Handlers matrix. Only f1 related procedure present here */
|
||||
f1ap_message_decoded_callback f1ap_messages_callback[][3] = {
|
||||
|
||||
f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
||||
|
||||
|
||||
{ 0, 0, 0 }, /* Reset */
|
||||
{ CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE }, /* F1Setup */
|
||||
@@ -73,55 +70,50 @@ f1ap_message_decoded_callback f1ap_messages_callback[][3] = {
|
||||
};
|
||||
|
||||
const char *f1ap_direction2String(int f1ap_dir) {
|
||||
static const char *f1ap_direction_String[] = {
|
||||
"", /* Nothing */
|
||||
"Initiating message", /* initiating message */
|
||||
"Successfull outcome", /* successfull outcome */
|
||||
"UnSuccessfull outcome", /* successfull outcome */
|
||||
};
|
||||
return(f1ap_direction_String[f1ap_dir]);
|
||||
static const char *f1ap_direction_String[] = {
|
||||
"", /* Nothing */
|
||||
"Initiating message", /* initiating message */
|
||||
"Successfull outcome", /* successfull outcome */
|
||||
"UnSuccessfull outcome", /* successfull outcome */
|
||||
};
|
||||
return(f1ap_direction_String[f1ap_dir]);
|
||||
}
|
||||
|
||||
int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t * const data, const uint32_t data_length)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu;
|
||||
const uint8_t *const data, const uint32_t data_length) {
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
int ret;
|
||||
|
||||
DevAssert(data != NULL);
|
||||
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
|
||||
if (f1ap_decode_pdu(&pdu, data, data_length) < 0) {
|
||||
LOG_E(F1AP, "Failed to decode PDU\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Checking procedure Code and direction of message */
|
||||
if (pdu.choice.initiatingMessage->procedureCode >= sizeof(f1ap_messages_callback) / (3 * sizeof(
|
||||
f1ap_message_decoded_callback))
|
||||
if (pdu.choice.initiatingMessage->procedureCode >=
|
||||
sizeof(f1ap_messages_processing) /
|
||||
(3 * sizeof(f1ap_message_processing_t))
|
||||
|| (pdu.present > F1AP_F1AP_PDU_PR_unsuccessfulOutcome)) {
|
||||
LOG_E(F1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
|
||||
assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present);
|
||||
assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* No handler present.
|
||||
* This can mean not implemented or no procedure for eNB (wrong direction).
|
||||
*/
|
||||
if (f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
|
||||
if (f1ap_messages_processing[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
|
||||
// No handler present. This can mean not implemented or no procedure for eNB (wrong direction).
|
||||
LOG_E(F1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
|
||||
assoc_id, pdu.choice.initiatingMessage->procedureCode,
|
||||
f1ap_direction2String(pdu.present - 1));
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
return -1;
|
||||
assoc_id, pdu.choice.initiatingMessage->procedureCode,
|
||||
f1ap_direction2String(pdu.present - 1));
|
||||
ret=-1;
|
||||
} else {
|
||||
/* Calling the right handler */
|
||||
LOG_I(F1AP, "Calling handler with instance %ld\n",instance);
|
||||
ret = (*f1ap_messages_processing[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
|
||||
(instance, assoc_id, stream, &pdu);
|
||||
}
|
||||
|
||||
/* Calling the right handler */
|
||||
LOG_I(F1AP, "Calling handler with instance %ld\n",instance);
|
||||
ret = (*f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
|
||||
(instance, assoc_id, stream, &pdu);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_handlers.h
|
||||
* \brief f1ap messages handlers
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef F1AP_HANDLERS_H_
|
||||
#define F1AP_HANDLERS_H_
|
||||
|
||||
int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t * const data, const uint32_t data_length);
|
||||
|
||||
#endif /* F1AP_HANDLERS_H_ */
|
||||
@@ -22,52 +22,26 @@
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_itti_messaging.h"
|
||||
|
||||
void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream)
|
||||
{
|
||||
void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream) {
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_CU_F1, 0, SCTP_DATA_REQ);
|
||||
|
||||
message_p = itti_alloc_new_message(isCu?TASK_CU_F1:TASK_DU_F1, 0, SCTP_DATA_REQ);
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->assoc_id = f1ap_assoc_id(isCu,instance);
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_DU_F1, 0, SCTP_DATA_REQ);
|
||||
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
|
||||
LOG_I(F1AP, "Sending ITTI message to SCTP Task\n");
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
void f1ap_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
|
||||
{
|
||||
void f1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) {
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_close_association_t *sctp_close_association_p = NULL;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION);
|
||||
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
|
||||
sctp_close_association_p->assoc_id = assoc_id;
|
||||
|
||||
sctp_close_association_p->assoc_id = f1ap_assoc_id(isCu,instance);
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,10 @@
|
||||
#ifndef F1AP_ITTI_MESSAGING_H_
|
||||
#define F1AP_ITTI_MESSAGING_H_
|
||||
|
||||
void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
void f1ap_itti_send_sctp_data_req(bool isCu,instance_t instance, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
void f1ap_eNB_itti_send_sctp_close_association(instance_t instance,
|
||||
int32_t assoc_id);
|
||||
void f1ap_eNB_itti_send_sctp_close_association(bool isCu,instance_t instance);
|
||||
|
||||
|
||||
#endif /* F1AP_ITTI_MESSAGING_H_ */
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_messaging.c
|
||||
* \brief f1ap procedures
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_messaging.h"
|
||||
|
||||
// void f1ap_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
// uint32_t buffer_length, uint16_t stream)
|
||||
// {
|
||||
// MessageDef *message_p;
|
||||
// sctp_data_req_t *sctp_data_req;
|
||||
|
||||
// message_p = itti_alloc_new_message(TASK_F1AP, SCTP_DATA_REQ);
|
||||
|
||||
// sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
// sctp_data_req->assoc_id = assoc_id;
|
||||
// sctp_data_req->buffer = buffer;
|
||||
// sctp_data_req->buffer_length = buffer_length;
|
||||
// sctp_data_req->stream = stream;
|
||||
|
||||
// itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
// }
|
||||
|
||||
// void f1ap_send_sctp_close_association(instance_t instance, int32_t assoc_id)
|
||||
// {
|
||||
// MessageDef *message_p = NULL;
|
||||
// sctp_close_association_t *sctp_close_association_p = NULL;
|
||||
|
||||
// message_p = itti_alloc_new_message(TASK_F1AP, SCTP_CLOSE_ASSOCIATION);
|
||||
// sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
|
||||
// sctp_close_association_p->assoc_id = assoc_id;
|
||||
|
||||
// itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
// }
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
#define F1AP_MESSAGING_H_
|
||||
|
||||
void f1ap_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
void f1ap_send_sctp_close_association(instance_t instance,
|
||||
int32_t assoc_id);
|
||||
int32_t assoc_id);
|
||||
|
||||
|
||||
#endif /* F1AP_MESSAGING_H_ */
|
||||
|
||||
+11
-10
@@ -51,6 +51,7 @@
|
||||
#include "f1ap_du_task.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h>
|
||||
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
extern unsigned char NB_gNB_INST;
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -144,19 +145,19 @@ static void init_pdcp(void) {
|
||||
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT;
|
||||
}
|
||||
|
||||
pdcp_module_init(pdcp_initmask);
|
||||
nr_pdcp_module_init(pdcp_initmask, 0);
|
||||
|
||||
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n");
|
||||
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
|
||||
pdcp_set_rlc_data_req_func(proto_agent_send_rlc_data_req);
|
||||
} else {
|
||||
LOG_I(PDCP, "node is gNB \n");
|
||||
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
|
||||
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
|
||||
pdcp_set_rlc_data_req_func(rlc_data_req);
|
||||
pdcp_set_pdcp_data_ind_func(pdcp_data_ind);
|
||||
}
|
||||
} else {
|
||||
LOG_I(PDCP, "node is DU, rlc send pdcp_data_ind by proto_agent \n");
|
||||
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
|
||||
pdcp_set_pdcp_data_ind_func(proto_agent_send_pdcp_data_ind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +182,8 @@ void *gNB_app_task(void *args_p)
|
||||
|
||||
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
|
||||
|
||||
RCconfig_NR_L1();
|
||||
|
||||
if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc();
|
||||
|
||||
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
|
||||
@@ -195,15 +198,13 @@ void *gNB_app_task(void *args_p)
|
||||
|
||||
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
|
||||
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
|
||||
|
||||
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
|
||||
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)malloc(sizeof(gNB_RRC_INST));
|
||||
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
|
||||
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
|
||||
memset((void *)RC.nrrrc[gnb_id],0,sizeof(gNB_RRC_INST));
|
||||
configure_nr_rrc(gnb_id);
|
||||
}
|
||||
|
||||
if (RC.nb_nr_inst > 0) {
|
||||
if (RC.nb_nr_inst > 0 && !get_softmodem_params()->nsa) {
|
||||
init_pdcp();
|
||||
}
|
||||
|
||||
@@ -214,7 +215,7 @@ void *gNB_app_task(void *args_p)
|
||||
|
||||
/* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
|
||||
* can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
|
||||
if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) && !NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
/* Try to register each gNB */
|
||||
//registered_gnb = 0;
|
||||
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
|
||||
|
||||
+108
-120
@@ -957,9 +957,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t));
|
||||
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc));
|
||||
uint64_t ssb_bitmap=0xff;
|
||||
memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t));
|
||||
prepare_scc(scc);
|
||||
paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
|
||||
paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
|
||||
@@ -1182,23 +1181,14 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
int RCconfig_nr_gtpu(void ) {
|
||||
|
||||
int num_gnbs = 0;
|
||||
|
||||
|
||||
|
||||
char* gnb_interface_name_for_NGU = NULL;
|
||||
char* gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char* gnb_interface_name_for_S1U = NULL;
|
||||
char* gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
|
||||
uint8_t gnb_mode = 0;
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
paramdef_t GTPUParams[] = GNBGTPUPARAMS_DESC;
|
||||
LOG_I(GTPU,"Configuring GTPu\n");
|
||||
|
||||
/* get number of active eNodeBs */
|
||||
@@ -1208,49 +1198,32 @@ int RCconfig_nr_gtpu(void ) {
|
||||
"Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS);
|
||||
|
||||
sprintf(gtpupath,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
config_get(GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath);
|
||||
|
||||
config_get(NETParams,sizeof(NETParams)/sizeof(paramdef_t),gtpupath);
|
||||
|
||||
if (NETParams[0].strptr != NULL) { // SA
|
||||
char *cidr=NULL, *address = NULL;
|
||||
int port;
|
||||
if (NETParams[1].strptr != NULL) {
|
||||
LOG_I(GTPU, "SA mode \n");
|
||||
cidr = gnb_ipv4_address_for_NGU;
|
||||
gnb_mode = 0;
|
||||
} else {// NSA
|
||||
address = strtok_r(gnb_ipv4_address_for_NGU, "/", &cidr);
|
||||
port=gnb_port_for_NGU;
|
||||
} else {
|
||||
LOG_I(GTPU, "NSA mode \n");
|
||||
cidr = gnb_ipv4_address_for_S1U;
|
||||
gnb_mode = 1;
|
||||
address = strtok_r(gnb_ipv4_address_for_S1U, "/", &cidr);
|
||||
port=gnb_port_for_S1U;
|
||||
}
|
||||
|
||||
address = strtok(cidr, "/");
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
|
||||
if (gnb_mode == 1) { // NSA
|
||||
message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ);
|
||||
AssertFatal(message!=NULL,"");
|
||||
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
// LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
|
||||
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
|
||||
strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
|
||||
sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU);
|
||||
} else {// TODO SA
|
||||
message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ);
|
||||
AssertFatal(message!=NULL,"");
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up);
|
||||
GTPV1U_GNB_NG_REQ(message).gnb_port_for_NGu_up = gnb_port_for_NGU;
|
||||
strcpy(GTPV1U_GNB_NG_REQ(message).addrStr,address);
|
||||
sprintf(GTPV1U_GNB_NG_REQ(message).portStr,"%d", gnb_port_for_NGU);
|
||||
}
|
||||
itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
|
||||
} else
|
||||
LOG_E(GTPU,"invalid address for NGU\n");
|
||||
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_REQ);
|
||||
AssertFatal(message!=NULL,"");
|
||||
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_REQ(message).localAddr, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_REQ(message).localAddr);
|
||||
GTPV1U_REQ(message).localPort = port;
|
||||
strcpy(GTPV1U_REQ(message).localAddrStr,address);
|
||||
sprintf(GTPV1U_REQ(message).localPortStr,"%d", port);
|
||||
itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
|
||||
} else
|
||||
LOG_E(GTPU,"invalid address for NGU or S1U\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1268,6 +1241,10 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
|
||||
(void) my_int;
|
||||
|
||||
memset((char*)active_gnb,0,MAX_GNB* sizeof(char*));
|
||||
char* gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char* gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
@@ -1609,6 +1586,11 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
paramdef_t X2Params[] = X2PARAMS_DESC;
|
||||
paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0};
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
char* gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char* gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
/* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */
|
||||
/* this is most probably a problem with the config module */
|
||||
@@ -1769,7 +1751,9 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
|
||||
AssertFatal(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr != NULL,
|
||||
"gNB id %u is not defined in configuration file\n",i);
|
||||
F1AP_SETUP_REQ (msg_p).num_cells_available = 0;
|
||||
f1ap_setup_req_t * f1Setup=&F1AP_SETUP_REQ(msg_p);
|
||||
f1Setup->num_cells_available = 0;
|
||||
f1Setup->cell_type=CELL_MACRO_GNB;
|
||||
|
||||
for (k=0; k <num_gnbs ; k++) {
|
||||
if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[k], *(GNBParamList.paramarray[i][GNB_GNB_NAME_IDX].strptr)) == 0) {
|
||||
@@ -1785,42 +1769,46 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
|
||||
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
|
||||
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
|
||||
F1AP_SETUP_REQ (msg_p).num_cells_available++;
|
||||
F1AP_SETUP_REQ (msg_p).gNB_DU_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
|
||||
LOG_I(GNB_APP,"F1AP: gNB_DU_id[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_id);
|
||||
F1AP_SETUP_REQ (msg_p).gNB_DU_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
LOG_I(GNB_APP,"F1AP: gNB_DU_name[%d] %s\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_name);
|
||||
F1AP_SETUP_REQ (msg_p).tac[k] = *GNBParamList.paramarray[i][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
LOG_I(GNB_APP,"F1AP: tac[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).tac[k]);
|
||||
F1AP_SETUP_REQ (msg_p).mcc[k] = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
LOG_I(GNB_APP,"F1AP: mcc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mcc[k]);
|
||||
F1AP_SETUP_REQ (msg_p).mnc[k] = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
LOG_I(GNB_APP,"F1AP: mnc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc[k]);
|
||||
F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
LOG_I(GNB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
|
||||
AssertFatal((F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 2) ||
|
||||
(F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 3),
|
||||
f1Setup->num_cells_available++;
|
||||
f1Setup->gNB_DU_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
|
||||
LOG_I(GNB_APP,"F1AP: gNB_DU_id[%d] %ld\n",k,f1Setup->gNB_DU_id);
|
||||
f1Setup->gNB_DU_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
LOG_I(GNB_APP,"F1AP: gNB_DU_name[%d] %s\n",k,f1Setup->gNB_DU_name);
|
||||
f1Setup->cell[k].tac = *GNBParamList.paramarray[i][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
LOG_I(GNB_APP,"F1AP: tac[%d] %d\n",k,f1Setup->cell[k].tac);
|
||||
f1Setup->cell[k].mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
LOG_I(GNB_APP,"F1AP: mcc[%d] %d\n",k,f1Setup->cell[k].mcc);
|
||||
f1Setup->cell[k].mnc = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
LOG_I(GNB_APP,"F1AP: mnc[%d] %d\n",k,f1Setup->cell[k].mnc);
|
||||
f1Setup->cell[k].mnc_digit_length = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
LOG_I(GNB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,f1Setup->cell[k].mnc_digit_length);
|
||||
AssertFatal((f1Setup->cell[k].mnc_digit_length == 2) ||
|
||||
(f1Setup->cell[k].mnc_digit_length == 3),
|
||||
"BAD MNC DIGIT LENGTH %d",
|
||||
F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
|
||||
F1AP_SETUP_REQ (msg_p).nr_cellid[k] = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
|
||||
LOG_I(GNB_APP,"F1AP: nr_cellid[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).nr_cellid[k]);
|
||||
f1Setup->cell[k].mnc_digit_length);
|
||||
f1Setup->cell[k].nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
|
||||
LOG_I(GNB_APP,"F1AP: nr_cellid[%d] %ld\n",k,f1Setup->cell[k].nr_cellid);
|
||||
LOG_I(GNB_APP,"F1AP: CU_ip4_address in DU %s\n",RC.nrmac[k]->eth_params_n.remote_addr);
|
||||
LOG_I(GNB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address,(int)strlen(RC.nrmac[k]->eth_params_n.remote_addr));
|
||||
F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6 = 0;
|
||||
F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4 = 1;
|
||||
//strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6_address, "");
|
||||
strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address, RC.nrmac[k]->eth_params_n.remote_addr);
|
||||
LOG_I(GNB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",f1Setup->CU_f1_ip_address.ipv4_address,(int)strlen(RC.nrmac[k]->eth_params_n.remote_addr));
|
||||
f1Setup->CU_f1_ip_address.ipv6 = 0;
|
||||
f1Setup->CU_f1_ip_address.ipv4 = 1;
|
||||
//strcpy(f1Setup->CU_f1_ip_address.ipv6_address, "");
|
||||
strcpy(f1Setup->CU_f1_ip_address.ipv4_address, RC.nrmac[k]->eth_params_n.remote_addr);
|
||||
LOG_I(GNB_APP,"F1AP: DU_ip4_address in DU %s\n",RC.nrmac[k]->eth_params_n.my_addr);
|
||||
LOG_I(GNB_APP,"FIAP: DU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address,(int)strlen(RC.nrmac[k]->eth_params_n.my_addr));
|
||||
F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6 = 0;
|
||||
F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4 = 1;
|
||||
//strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6_address, "");
|
||||
strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address, RC.nrmac[k]->eth_params_n.my_addr);
|
||||
//strcpy(F1AP_SETUP_REQ (msg_p).CU_ip_address[l].ipv6_address,*(F1ParamList.paramarray[l][ENB_CU_IPV6_ADDRESS_IDX].strptr));
|
||||
LOG_I(GNB_APP,"FIAP: DU_ip4_address in DU %p, strlen %ld\n",
|
||||
f1Setup->DU_f1_ip_address.ipv4_address,
|
||||
strlen(RC.nrmac[k]->eth_params_n.my_addr));
|
||||
f1Setup->DU_f1_ip_address.ipv6 = 0;
|
||||
f1Setup->DU_f1_ip_address.ipv4 = 1;
|
||||
//strcpy(f1Setup->DU_f1_ip_address.ipv6_address, "");
|
||||
strcpy(f1Setup->DU_f1_ip_address.ipv4_address, RC.nrmac[k]->eth_params_n.my_addr);
|
||||
f1Setup->DUport= RC.nrmac[k]->eth_params_n.my_portd;
|
||||
f1Setup->CUport= RC.nrmac[k]->eth_params_n.remote_portd;
|
||||
//strcpy(f1Setup->CU_ip_address[l].ipv6_address,*(F1ParamList.paramarray[l][ENB_CU_IPV6_ADDRESS_IDX].strptr));
|
||||
sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG);
|
||||
config_get(SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
|
||||
F1AP_SETUP_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
|
||||
F1AP_SETUP_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
f1Setup->sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
|
||||
f1Setup->sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[k];
|
||||
// wait until RRC cell information is configured
|
||||
int cell_info_configured = 0;
|
||||
@@ -1833,53 +1821,53 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
|
||||
pthread_mutex_unlock(&rrc->cell_info_mutex);
|
||||
} while (cell_info_configured == 0);
|
||||
|
||||
rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k];
|
||||
rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k];
|
||||
rrc->configuration.tac = F1AP_SETUP_REQ (msg_p).tac[k];
|
||||
rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).nr_cellid[k];
|
||||
F1AP_SETUP_REQ (msg_p).nr_pci[k] = *rrc->configuration.scc->physCellId;
|
||||
F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0;
|
||||
rrc->configuration.mcc[0] = f1Setup->cell[k].mcc;
|
||||
rrc->configuration.mnc[0] = f1Setup->cell[k].mnc;
|
||||
rrc->configuration.tac = f1Setup->cell[k].tac;
|
||||
rrc->nr_cellid = f1Setup->cell[k].nr_cellid;
|
||||
f1Setup->cell[k].nr_pci = *rrc->configuration.scc->physCellId;
|
||||
f1Setup->cell[k].num_ssi = 0;
|
||||
|
||||
if (rrc->configuration.scc->tdd_UL_DL_ConfigurationCommon) {
|
||||
LOG_I(GNB_APP,"ngran_DU: Configuring Cell %d for TDD\n",k);
|
||||
F1AP_SETUP_REQ (msg_p).fdd_flag = 0;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_arfcn = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.scs = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.num_frequency_bands = 1;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_band[0] = *rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.sul_active = 0;
|
||||
f1Setup->fdd_flag = 0;
|
||||
f1Setup->nr_mode_info[k].tdd.nr_arfcn = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
f1Setup->nr_mode_info[k].tdd.scs = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
f1Setup->nr_mode_info[k].tdd.nrb = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
f1Setup->nr_mode_info[k].tdd.num_frequency_bands = 1;
|
||||
f1Setup->nr_mode_info[k].tdd.nr_band[0] = *rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
f1Setup->nr_mode_info[k].tdd.sul_active = 0;
|
||||
} else {
|
||||
/***************** for test *****************/
|
||||
LOG_I(GNB_APP,"ngran_DU: Configuring Cell %d for FDD\n",k);
|
||||
F1AP_SETUP_REQ (msg_p).fdd_flag = 1;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn = 26200UL;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_arfcn = 26200UL;
|
||||
f1Setup->fdd_flag = 1;
|
||||
f1Setup->nr_mode_info[k].fdd.dl_nr_arfcn = 26200UL;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_nr_arfcn = 26200UL;
|
||||
// For LTE use scs field to carry prefix type and number of antennas
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_scs = 0;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_scs = 0;
|
||||
f1Setup->nr_mode_info[k].fdd.dl_scs = 0;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_scs = 0;
|
||||
// use nrb field to hold LTE N_RB_DL (0...5)
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb = 3;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb = 3;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_nrb = 3;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_nrb = 3;
|
||||
// RK: we need to check there value for FDD's frequency_bands DL/UL
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_frequency_bands = 1;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_band[0] = 7;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_frequency_bands = 1;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_band[0] = 7;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_sul_frequency_bands = 0;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_sul_band[0] = 7;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_sul_frequency_bands = 0;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_sul_band[0] = 7;
|
||||
F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active = 0;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_num_frequency_bands = 1;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_nr_band[0] = 7;
|
||||
f1Setup->nr_mode_info[k].fdd.dl_num_frequency_bands = 1;
|
||||
f1Setup->nr_mode_info[k].fdd.dl_nr_band[0] = 7;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_num_sul_frequency_bands = 0;
|
||||
f1Setup->nr_mode_info[k].fdd.ul_nr_sul_band[0] = 7;
|
||||
f1Setup->nr_mode_info[k].fdd.dl_num_sul_frequency_bands = 0;
|
||||
f1Setup->nr_mode_info[k].fdd.dl_nr_sul_band[0] = 7;
|
||||
f1Setup->nr_mode_info[k].fdd.sul_active = 0;
|
||||
/***************** for test *****************/
|
||||
}
|
||||
|
||||
F1AP_SETUP_REQ (msg_p).measurement_timing_information[k] = "0";
|
||||
F1AP_SETUP_REQ (msg_p).ranac[k] = 0;
|
||||
F1AP_SETUP_REQ (msg_p).mib[k] = rrc->carrier.MIB;
|
||||
F1AP_SETUP_REQ (msg_p).sib1[k] = rrc->carrier.SIB1;
|
||||
F1AP_SETUP_REQ (msg_p).mib_length[k] = rrc->carrier.sizeof_MIB;
|
||||
F1AP_SETUP_REQ (msg_p).sib1_length[k] = rrc->carrier.sizeof_SIB1;
|
||||
f1Setup->measurement_timing_information[k] = "0";
|
||||
f1Setup->ranac[k] = 0;
|
||||
f1Setup->mib[k] = rrc->carrier.MIB;
|
||||
f1Setup->sib1[k] = rrc->carrier.SIB1;
|
||||
f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB;
|
||||
f1Setup->sib1_length[k] = rrc->carrier.sizeof_SIB1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2075,8 +2063,8 @@ int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
|
||||
|
||||
du_extract_and_decode_SI(i,
|
||||
si_ind,
|
||||
resp->cells_to_activate[j].SI_container[2+si_ind],
|
||||
resp->cells_to_activate[j].SI_container_length[2+si_ind]);
|
||||
resp->cells_to_activate[j].SI_container[si_ind],
|
||||
resp->cells_to_activate[j].SI_container_length[si_ind]);
|
||||
}
|
||||
|
||||
// perform MAC/L1 common configuration
|
||||
@@ -2110,8 +2098,8 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
|
||||
|
||||
du_extract_and_decode_SI(i,
|
||||
si_ind,
|
||||
gnb_cu_cfg_update->cells_to_activate[j].SI_container[2+si_ind],
|
||||
gnb_cu_cfg_update->cells_to_activate[j].SI_container_length[2+si_ind]);
|
||||
gnb_cu_cfg_update->cells_to_activate[j].SI_container[si_ind],
|
||||
gnb_cu_cfg_update->cells_to_activate[j].SI_container_length[si_ind]);
|
||||
}
|
||||
|
||||
// perform MAC/L1 common configuration
|
||||
|
||||
@@ -334,29 +334,17 @@ typedef enum {
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define GNBNETPARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* GTPU configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define GNBGTPUPARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:&gnb_interface_name_for_NGU, defstrval:"lo", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:&gnb_ipv4_address_for_NGU, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:&gnb_port_for_NGU, defintval:2152, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:&gnb_interface_name_for_S1U, defstrval:"lo", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U, NULL, 0, strptr:&gnb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:&gnb_port_for_S1U, defintval:2152, TYPE_UINT, 0} \
|
||||
}
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:&gnb_ipv4_address_for_NGU, defstrval:"127.0.0.1",TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:&gnb_port_for_NGU, defintval:2152L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U, NULL, 0, strptr:&gnb_ipv4_address_for_S1U, defstrval:"127.0.0.1",TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:&gnb_port_for_S1U, defintval:2152L, TYPE_UINT, 0} \
|
||||
}
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -799,7 +799,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
|
||||
RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp;
|
||||
RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band;
|
||||
RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq;
|
||||
LOG_I(MAC,
|
||||
LOG_A(MAC,
|
||||
"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n",
|
||||
Mod_idP,
|
||||
CC_idP,
|
||||
@@ -1067,7 +1067,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
|
||||
while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) {
|
||||
// DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
|
||||
usleep(100 * 1000);
|
||||
printf("Waiting for PHY_config_req\n");
|
||||
LOG_I(MAC, "Waiting for PHY_config_req\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
|
||||
LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
|
||||
}
|
||||
|
||||
if(NFAPI_MODE != NFAPI_UE_STUB_PNF)
|
||||
if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF)
|
||||
phy_config_harq_ue(Mod_idP, 0, eNB_index, UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx);
|
||||
|
||||
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
|
||||
@@ -308,7 +308,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
|
||||
}
|
||||
|
||||
if (physicalConfigDedicated != NULL) {
|
||||
if(NFAPI_MODE != NFAPI_UE_STUB_PNF)
|
||||
if(NFAPI_MODE != NFAPI_UE_STUB_PNF && NFAPI_MODE != NFAPI_MODE_STANDALONE_PNF)
|
||||
phy_config_dedicated_ue(Mod_idP, 0, eNB_index,
|
||||
physicalConfigDedicated);
|
||||
|
||||
|
||||
@@ -313,6 +313,7 @@ schedule_SR (module_id_t module_idP,
|
||||
nfapi_ul_config_request_body_t *ul_req_body = NULL;
|
||||
LTE_SchedulingRequestConfig_t *SRconfig = NULL;
|
||||
nfapi_ul_config_sr_information sr;
|
||||
memset(&sr, 0, sizeof(sr));
|
||||
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
|
||||
@@ -573,6 +574,27 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
start_meas(&(eNB->eNB_scheduler));
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_IN);
|
||||
// TODO: Better solution needed this is the first
|
||||
// 3 indications of this function on startup
|
||||
// 1303275.278188 [MAC] XXX 0.0 -> 0.4 = 4
|
||||
// 1303275.279443 [MAC] XXX 0.4 -> 639.5 = 6391
|
||||
// 1303275.348686 [MAC] XXX 646.3 -> 646.3 = 0
|
||||
int delta = (frameP * 10 + subframeP) - (eNB->frame * 10 + eNB->subframe);
|
||||
if (delta < 0)
|
||||
{
|
||||
delta += 10240; // sfn_sf decimal values range from 0 to 10239
|
||||
}
|
||||
// If we ever see a difference this big something is very wrong
|
||||
// This threshold is arbitrary
|
||||
if (delta > 8500 || delta == 0) // 850 frames
|
||||
{
|
||||
LOG_I(MAC, "scheduler ignoring outerspace %d.%d -> %d.%d = %d\n",
|
||||
eNB->frame, eNB->subframe, frameP, subframeP, delta);
|
||||
return;
|
||||
}
|
||||
LOG_D(MAC, "Entering dlsch_ulsch scheduler %d.%d -> %d.%d = %d\n",
|
||||
eNB->frame, eNB->subframe, frameP, subframeP, delta);
|
||||
|
||||
eNB->frame = frameP;
|
||||
eNB->subframe = subframeP;
|
||||
|
||||
|
||||
@@ -918,7 +918,7 @@ generate_Msg4(module_id_t module_idP,
|
||||
module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);
|
||||
// AssertFatal(rrc_sdu_length > 0,
|
||||
// "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);
|
||||
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
|
||||
LOG_A(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
|
||||
module_idP, CC_idP, frameP, subframeP, ra->rnti);
|
||||
/// Choose first 4 RBs for Msg4, should really check that these are free!
|
||||
first_rb = 0;
|
||||
|
||||
@@ -560,7 +560,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
|
||||
return;
|
||||
}
|
||||
|
||||
void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
static void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP,
|
||||
@@ -729,7 +729,7 @@ void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
}
|
||||
|
||||
// This function returns the estimated number of RBs required by each UE for downlink scheduling
|
||||
void assign_rbs_required_fairRR(
|
||||
static void assign_rbs_required_fairRR(
|
||||
module_id_t Mod_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
@@ -1018,8 +1018,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
|
||||
UE_id,
|
||||
CC_id,
|
||||
N_RBG[CC_id],
|
||||
(uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required,
|
||||
(uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining,
|
||||
nb_rbs_required,
|
||||
nb_rbs_required_remaining,
|
||||
rballoc_sub);
|
||||
temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id];
|
||||
temp_total_ue_count--;
|
||||
@@ -1925,7 +1925,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
|
||||
}
|
||||
|
||||
trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
|
||||
TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id),
|
||||
TBS, module_idP, WS_C_RNTI, UE_RNTI(module_idP, UE_id),
|
||||
eNB->frame, eNB->subframe,0,0);
|
||||
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
|
||||
T_INT(harq_pid), T_BUFFER(UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
|
||||
|
||||
@@ -85,21 +85,6 @@ void dlsch_scheduler_pre_ue_select_fairRR(
|
||||
uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB],
|
||||
DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]);
|
||||
|
||||
void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP,
|
||||
int min_rb_unit[NFAPI_CC_MAX],
|
||||
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
|
||||
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
|
||||
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
|
||||
|
||||
void assign_rbs_required_fairRR(
|
||||
module_id_t Mod_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]);
|
||||
|
||||
void dlsch_scheduler_pre_processor_allocate_fairRR(
|
||||
module_id_t Mod_id,
|
||||
int UE_id,
|
||||
|
||||
@@ -41,10 +41,12 @@
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
|
||||
|
||||
#include "PHY_INTERFACE/phy_stub_UE.h"
|
||||
#include "common/ran_context.h"
|
||||
#include <openair2/RRC/LTE/rrc_proto.h>
|
||||
|
||||
extern void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
|
||||
|
||||
void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) { //init as MR
|
||||
LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n",
|
||||
module_idP, frameP, eNB_index);
|
||||
@@ -88,6 +90,16 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer,
|
||||
UE_mac_inst = NULL;
|
||||
}
|
||||
|
||||
// mutex below are used for multiple UE's L2 FAPI simulation.
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL);
|
||||
}
|
||||
|
||||
LOG_I(MAC, "[MAIN] calling RRC\n");
|
||||
openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,
|
||||
HO_active);
|
||||
|
||||
@@ -287,9 +287,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
|
||||
sub_frame_t subframeP) {
|
||||
uint8_t Size = 0;
|
||||
UE_MODE_t UE_mode;
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO,
|
||||
UE_mac_inst[module_idP].crnti, frameP,
|
||||
subframeP, eNB_indexP);
|
||||
// Modification for phy_stub_ue operation
|
||||
if(NFAPI_MODE == NFAPI_UE_STUB_PNF) { // phy_stub_ue mode
|
||||
if(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { // phy_stub_ue mode
|
||||
UE_mode = UE_mac_inst[module_idP].UE_mode[0];
|
||||
LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode);
|
||||
} else { // Full stack mode
|
||||
@@ -320,6 +323,18 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
|
||||
|
||||
if (UE_mac_inst[module_idP].RA_active == 0) {
|
||||
LOG_I(MAC, "RA not active\n");
|
||||
if (UE_rrc_inst[module_idP].Info[eNB_indexP].T300_cnt
|
||||
!= T300[UE_rrc_inst[module_idP].sib2[eNB_indexP]->ue_TimersAndConstants.t300]) {
|
||||
/* Calling rrc_ue_generate_RRCConnectionRequest here to ensure that
|
||||
every time we fill the UE_mac_inst context we generate new random
|
||||
values in msg3. When the T300 timer has expired, rrc_common.c will
|
||||
call rrc_ue_generate_RRCConnectionRequest, so we do not want to call
|
||||
when UE_rrc_inst[module_idP].Info[eNB_indexP].T300_cnt ==
|
||||
T300[UE_rrc_inst[module_idP].sib2[eNB_indexP]->ue_TimersAndConstants.t300. */
|
||||
UE_rrc_inst[module_idP].Srb0[eNB_indexP].Tx_buffer.payload_size = 0;
|
||||
rrc_ue_generate_RRCConnectionRequest(&ctxt, eNB_indexP);
|
||||
}
|
||||
|
||||
// check if RRC is ready to initiate the RA procedure
|
||||
Size = mac_rrc_data_req_ue(module_idP,
|
||||
CC_id,
|
||||
|
||||
@@ -67,6 +67,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
|
||||
rarh->RAPID);
|
||||
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
|
||||
UE_mac_inst[module_idP].UE_mode[0] = RA_RESPONSE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,9 +78,10 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
}
|
||||
|
||||
if (rarh->E == 0) {
|
||||
LOG_I(PHY,
|
||||
LOG_I(MAC,
|
||||
"No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n",
|
||||
best_rx_rapid);
|
||||
UE_mac_inst[module_idP].UE_mode[0] = PRACH;
|
||||
break;
|
||||
} else {
|
||||
rarh++;
|
||||
@@ -94,7 +96,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
return (0xffff);
|
||||
}
|
||||
|
||||
LOG_I(MAC,
|
||||
LOG_A(MAC,
|
||||
"[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
|
||||
module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2],
|
||||
rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
|
||||
@@ -130,7 +132,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
}
|
||||
|
||||
// move the selected RAR to the front of the RA_PDSCH buffer
|
||||
memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
|
||||
memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
|
||||
memmove(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
|
||||
memmove(selected_rar_buffer + 1, (uint8_t *) rar, 6);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -149,15 +149,13 @@ void ue_init_mac(module_id_t module_idP) {
|
||||
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0;
|
||||
}
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) {
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) {
|
||||
pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL);
|
||||
UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH;
|
||||
UE_mac_inst[module_idP].UE_mode[0] = PRACH; //NOT_SYNCHED;
|
||||
UE_mac_inst[module_idP].first_ULSCH_Tx =0;
|
||||
UE_mac_inst[module_idP].SI_Decoded = 0;
|
||||
next_ra_frame = 0;
|
||||
next_Mod_id = 0;
|
||||
tx_request_pdu_list = NULL;
|
||||
tx_req_num_elems = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +409,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
|
||||
if (payload_ptr != NULL) {
|
||||
for (i = 0; i < num_ce; i++) {
|
||||
// printf("ce %d : %d\n",i,rx_ces[i]);
|
||||
LOG_I(MAC, "ce %d : %d\n",i,rx_ces[i]);
|
||||
switch (rx_ces[i]) {
|
||||
case UE_CONT_RES:
|
||||
LOG_I(MAC,
|
||||
@@ -436,7 +434,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
"[UE %d][RAPROC] Contention detected, RA failed\n",
|
||||
module_idP);
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode
|
||||
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
|
||||
// PRACH state.
|
||||
LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n");
|
||||
@@ -462,7 +460,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
[module_idP].
|
||||
RA_contention_resolution_timer_active = 0;
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode
|
||||
// Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH
|
||||
UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH;
|
||||
} else { // Full stack mode
|
||||
@@ -480,7 +478,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
#endif
|
||||
|
||||
// Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct?
|
||||
if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
|
||||
if (NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) {
|
||||
process_timing_advance(module_idP,CC_id,payload_ptr[0]);
|
||||
}
|
||||
|
||||
@@ -2508,6 +2506,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||
scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
|
||||
scheduling_info.LCGID
|
||||
[lcid]]);
|
||||
AssertFatal(num_sdus < sizeof(sdu_lengths) / sizeof(sdu_lengths[0]), "num_sdus %d > num sdu_length elements\n", num_sdus);
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
|
||||
UE_mac_inst
|
||||
[module_idP].
|
||||
@@ -2639,7 +2638,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||
|
||||
// build PHR and update the timers
|
||||
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) {
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) {
|
||||
//Substitute with a static value for the MAC layer abstraction (phy_stub mode)
|
||||
phr_p->PH = 60;
|
||||
} else {
|
||||
@@ -3090,7 +3089,7 @@ ue_scheduler(const module_id_t module_idP,
|
||||
"Module id %u Contention resolution timer expired, RA failed\n",
|
||||
module_idP);
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode
|
||||
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
|
||||
// PRACH state.
|
||||
LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n");
|
||||
|
||||
@@ -264,6 +264,16 @@ typedef struct {
|
||||
uint8_t nbits;
|
||||
} dci_field_t;
|
||||
|
||||
typedef struct {
|
||||
bool expected_sib;
|
||||
bool index_has_sib[16];
|
||||
bool expected_rar;
|
||||
bool index_has_rar[16];
|
||||
bool expected_dci;
|
||||
bool index_has_dci[16];
|
||||
int active_harq_sfn_slot;
|
||||
} nr_emulated_l1_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint8_t format_indicator; //1 bit
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
|
||||
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
|
||||
|
||||
@@ -627,7 +627,8 @@ int nr_rrc_mac_config_req_ue(
|
||||
pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
if (!get_softmodem_params()->emulate_l1)
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
mac->common_configuration_complete = 1;
|
||||
}
|
||||
if(scell_group_config != NULL ){
|
||||
@@ -654,7 +655,16 @@ int nr_rrc_mac_config_req_ue(
|
||||
else if (cell_group_config != NULL ){
|
||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||
mac->cg = cell_group_config;
|
||||
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
|
||||
if (cell_group_config->spCellConfig) {
|
||||
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
|
||||
mac->DL_BWP_Id=mac->cg->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id ? *mac->cg->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id : 0;
|
||||
mac->UL_BWP_Id=mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id ? *mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
||||
}
|
||||
else {
|
||||
mac->servCellIndex = 0;
|
||||
mac->DL_BWP_Id = 0;
|
||||
mac->UL_BWP_Id = 0;
|
||||
}
|
||||
|
||||
mac->scheduling_info.periodicBSR_SF =
|
||||
MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
@@ -667,7 +677,26 @@ int nr_rrc_mac_config_req_ue(
|
||||
mac->scheduling_info.retxBSR_SF);
|
||||
|
||||
config_control_ue(mac);
|
||||
//config_common_ue(mac,module_id,cc_idP);
|
||||
if (get_softmodem_params()->nsa) {
|
||||
if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) {
|
||||
if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
|
||||
ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
|
||||
}
|
||||
mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
|
||||
int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
|
||||
if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) {
|
||||
num_slots++;
|
||||
}
|
||||
mac->ul_config_request = calloc(num_slots, sizeof(*mac->ul_config_request));
|
||||
config_common_ue(mac,module_id,cc_idP);
|
||||
mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
|
||||
}
|
||||
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac);
|
||||
}
|
||||
|
||||
/*
|
||||
if(mac_cell_group_configP != NULL){
|
||||
if(mac_cell_group_configP->drx_Config != NULL ){
|
||||
|
||||
@@ -430,8 +430,14 @@ typedef struct {
|
||||
|
||||
dci_pdu_rel15_t def_dci_pdu_rel15[8];
|
||||
|
||||
// Defined for abstracted mode
|
||||
nr_downlink_indication_t dl_info;
|
||||
NR_UE_HARQ_STATUS_t dl_harq_info[16];
|
||||
|
||||
nr_emulated_l1_t nr_ue_emul_l1;
|
||||
|
||||
pthread_mutex_t mutex_dl_info;
|
||||
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
typedef enum seach_space_mask_e {
|
||||
|
||||
@@ -68,8 +68,6 @@ extern const uint16_t table_7_2_1[16];
|
||||
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
|
||||
extern void mac_rlc_data_ind(const module_id_t module_idP,
|
||||
const rnti_t rntiP,
|
||||
const eNB_index_t eNB_index,
|
||||
|
||||
@@ -595,7 +595,9 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, prach_resources->ra_PreambleIndex, cfra_ssb_resource_idx);
|
||||
}
|
||||
} else {
|
||||
int16_t dl_pathloss = get_nr_PL(mod_id, CC_id, gNB_id);
|
||||
/* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we
|
||||
can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */
|
||||
int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? get_nr_PL(mod_id, CC_id, gNB_id) : 0;
|
||||
ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu);
|
||||
ra_preambles_config(prach_resources, mac, dl_pathloss);
|
||||
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
|
||||
@@ -674,7 +676,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
|
||||
if (!prach_resources->init_msg1) {
|
||||
if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){
|
||||
if ((mac->common_configuration_complete > 0 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) &&
|
||||
((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150) {
|
||||
prach_resources->init_msg1 = 1;
|
||||
} else {
|
||||
LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame);
|
||||
@@ -738,6 +741,30 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
pdu -= sh_size;
|
||||
}
|
||||
|
||||
} else if (get_softmodem_params()->nsa) {
|
||||
|
||||
uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
|
||||
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
||||
int TBS_bytes = 848;
|
||||
int mac_ce_len = 0;
|
||||
int header_length_total=0;
|
||||
unsigned short post_padding = 1;
|
||||
|
||||
// fill ulsch_buffer with random data
|
||||
for (int i = 0; i < TBS_bytes; i++){
|
||||
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
|
||||
}
|
||||
//Sending SDUs with size 1
|
||||
//Initialize elements of sdu_lengths
|
||||
sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
|
||||
header_length_total += 2 + (sdu_lengths[0] >= 128);
|
||||
size_sdu += sdu_lengths[0];
|
||||
|
||||
if (size_sdu > 0) {
|
||||
memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);
|
||||
ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
|
||||
@@ -746,19 +773,20 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
}
|
||||
|
||||
if (size_sdu > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) {
|
||||
if (size_sdu > 0 && (ra->generate_nr_prach == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx);
|
||||
AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__);
|
||||
|
||||
// Init RA procedure
|
||||
init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated);
|
||||
nr_get_RA_window(mac);
|
||||
// Fill in preamble and PRACH resources
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
if (ra->generate_nr_prach == GENERATE_PREAMBLE)
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
|
||||
// Padding: fill remainder with 0
|
||||
if (TBS_max - ra->Msg3_size > 0) {
|
||||
AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__);
|
||||
LOG_D(NR_MAC, "In %s: remaining %d bytes, filling with padding\n", __FUNCTION__, TBS_max - ra->Msg3_size);
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING;
|
||||
@@ -777,8 +805,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
// Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after
|
||||
// receiving Msg2 (which contains the Msg3 resource reserve).
|
||||
// Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s.
|
||||
mac->ulsch_pdu.Pdu_size = TBS_max;
|
||||
memcpy(mac->ulsch_pdu.payload, payload, TBS_max);
|
||||
if (!get_softmodem_params()->nsa) {
|
||||
mac->ulsch_pdu.Pdu_size = TBS_max;
|
||||
memcpy(mac->ulsch_pdu.payload, payload, TBS_max);
|
||||
}
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
@@ -936,7 +966,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
|
||||
|
||||
} else {
|
||||
|
||||
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
|
||||
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
|
||||
|
||||
ra->RA_contention_resolution_timer_active = 0;
|
||||
mac->crnti = ra->t_crnti;
|
||||
|
||||
@@ -428,7 +428,8 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
|
||||
|
||||
if (pdcch_ConfigCommon &&
|
||||
pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
|
||||
pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 &&
|
||||
!get_softmodem_params()->nsa) {
|
||||
|
||||
NR_SearchSpace_t *ss0 = mac->search_space_zero;
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
|
||||
@@ -442,7 +443,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // use coreset0/ss0
|
||||
else if (!get_softmodem_params()->nsa) { // use coreset0/ss0
|
||||
NR_SearchSpace_t *ss0 = mac->search_space_zero;
|
||||
if(ss0) {
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15;
|
||||
|
||||
@@ -608,7 +608,6 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
|
||||
def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
|
||||
}
|
||||
int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci);
|
||||
memset(def_dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t));
|
||||
return ret_proc;
|
||||
}
|
||||
|
||||
@@ -728,6 +727,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot);
|
||||
return -1;
|
||||
}
|
||||
ul_config->number_pdus = 0;
|
||||
|
||||
pthread_mutex_lock(&ul_config->mutex_ul_config);
|
||||
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
|
||||
@@ -868,7 +868,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
|
||||
/* dmrs symbol positions*/
|
||||
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
|
||||
mac->mib->dmrs_TypeA_Position,
|
||||
(get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
|
||||
dlsch_config_pdu_1_0->number_symbols,
|
||||
dlsch_config_pdu_1_0->start_symbol,
|
||||
mappingtype);
|
||||
@@ -1255,6 +1255,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
/* TODO same calculation for MCS table as done in UL */
|
||||
dlsch_config_pdu_1_1->mcs_table = (pdsch_Config->mcs_Table) ? (*pdsch_Config->mcs_Table + 1) : 0;
|
||||
/*PTRS configuration */
|
||||
dlsch_config_pdu_1_1->pduBitmap = 0;
|
||||
if(pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) {
|
||||
valid_ptrs_setup = set_dl_ptrs_values(pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup,
|
||||
dlsch_config_pdu_1_1->number_rbs, dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table,
|
||||
@@ -1333,8 +1334,10 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||
// FIXME k0 != 0 currently not taken into consideration
|
||||
current_harq->dl_frame = frame;
|
||||
current_harq->dl_slot = slot;
|
||||
mac->nr_ue_emul_l1.active_harq_sfn_slot = NFAPI_SFNSLOT2HEX(frame, (slot + data_toul_fb));
|
||||
|
||||
LOG_D(PHY,"Setting harq_status for harq_id %d, dl %d.%d\n",harq_id,frame,slot);
|
||||
LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n",
|
||||
harq_id, frame, slot, frame, (slot + data_toul_fb));
|
||||
}
|
||||
|
||||
|
||||
@@ -2837,7 +2840,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
// check BWP id
|
||||
if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
else N_RB=mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
;
|
||||
|
||||
|
||||
// indicating a DL DCI format 1bit
|
||||
pos++;
|
||||
@@ -3331,6 +3334,9 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
|
||||
AssertFatal(pdu_len > mac_sdu_len, "The mac_sdu_len (%d) has an invalid size. PDU len = %d! \n",
|
||||
mac_sdu_len, pdu_len);
|
||||
|
||||
// Check if it is a valid CCCH message, we get all 00's messages very often
|
||||
int i = 0;
|
||||
for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
|
||||
@@ -3496,47 +3502,56 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
case DL_SCH_LCID_DCCH1:
|
||||
// check if LCID is valid at current time.
|
||||
default:
|
||||
// check if LCID is valid at current time.
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
|
||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
|
||||
{
|
||||
// check if LCID is valid at current time.
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return;
|
||||
NR_MAC_SUBHEADER_SHORT *shs = (NR_MAC_SUBHEADER_SHORT *)pduP;
|
||||
if (shs->F) {
|
||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return;
|
||||
NR_MAC_SUBHEADER_LONG *shl = (NR_MAC_SUBHEADER_LONG *)pduP;
|
||||
mac_sdu_len = ((uint16_t)(shl->L1 & 0x7f) << 8) | (uint16_t)(shl->L2 & 0xff);
|
||||
} else {
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return;
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
|
||||
|
||||
LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||
for (i = 0; i < 32; i++)
|
||||
LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]);
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) {
|
||||
|
||||
if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) {
|
||||
mac_rlc_data_ind(module_idP,
|
||||
mac->crnti,
|
||||
gNB_index,
|
||||
frameP,
|
||||
ENB_FLAG_NO,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *) (pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index);
|
||||
}
|
||||
|
||||
mac_rlc_data_ind(module_idP,
|
||||
mac->crnti,
|
||||
gNB_index,
|
||||
frameP,
|
||||
ENB_FLAG_NO,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *) (pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
@@ -3791,7 +3806,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
|
||||
}
|
||||
}
|
||||
if (rarh->RAPID == preamble_index) {
|
||||
LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
|
||||
LOG_A(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
|
||||
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
|
||||
ra->RA_RAPID_found = 1;
|
||||
break;
|
||||
@@ -3908,6 +3923,8 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
|
||||
LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot);
|
||||
return -1;
|
||||
}
|
||||
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
|
||||
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
|
||||
|
||||
// Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles
|
||||
if (!ra->cfra) {
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "assertions.h"
|
||||
#include "asn1_conversions.h"
|
||||
#include "SIMULATION/TOOLS/sim.h" // for taus
|
||||
#include "utils.h"
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
@@ -60,8 +61,13 @@ static prach_association_pattern_t prach_assoc_pattern;
|
||||
static ssb_list_info_t ssb_list;
|
||||
|
||||
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){
|
||||
|
||||
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
|
||||
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
|
||||
// clear ul_config for new frame/slot
|
||||
if ((ul_config->slot != slot_tx || ul_config->sfn != frame_tx) && ul_config->number_pdus != 0) {
|
||||
if ((ul_config->slot != slot_tx || ul_config->sfn != frame_tx) &&
|
||||
ul_config->number_pdus != 0 &&
|
||||
!get_softmodem_params()->emulate_l1) {
|
||||
LOG_D(MAC, "%d.%d %d.%d f clear ul_config %p t %d pdu %d\n", frame_tx, slot_tx, ul_config->sfn, ul_config->slot, ul_config, pdu_type, ul_config->number_pdus);
|
||||
ul_config->number_pdus = 0;
|
||||
memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list));
|
||||
@@ -166,6 +172,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
|
||||
num_slots_ul,
|
||||
index);
|
||||
|
||||
if(!mac->ul_config_request)
|
||||
return NULL;
|
||||
return &mac->ul_config_request[index];
|
||||
}
|
||||
|
||||
@@ -912,6 +920,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
dcireq.slot = rx_slot;
|
||||
dcireq.dl_config_req.number_pdus = 0;
|
||||
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
|
||||
mac->dl_config_request = dcireq.dl_config_req;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
@@ -948,7 +957,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
RA_config_t *ra = &mac->ra;
|
||||
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx);
|
||||
|
||||
if (!ul_config) {
|
||||
LOG_E(NR_MAC, "mac->ul_config is null!\n");
|
||||
}
|
||||
// Schedule ULSCH only if the current frame and slot match those in ul_config_req
|
||||
// AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus)
|
||||
if (ul_config){
|
||||
@@ -1019,7 +1030,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
|
||||
}
|
||||
if (ra->ra_state == WAIT_RAR && !ra->cfra){
|
||||
LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
|
||||
LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
|
||||
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
|
||||
}
|
||||
}
|
||||
@@ -2197,9 +2208,12 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
RA_config_t *ra = &mac->ra;
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
|
||||
if (!ul_config) {
|
||||
LOG_E(NR_MAC, "mac->ul_config is null! \n");
|
||||
return;
|
||||
}
|
||||
|
||||
//fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
|
||||
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
|
||||
fapi_nr_ul_config_prach_pdu *prach_config_pdu;
|
||||
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
||||
fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
|
||||
@@ -2236,11 +2250,13 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
format = prach_occasion_info_p->format;
|
||||
format0 = format & 0xff; // single PRACH format
|
||||
format1 = (format >> 8) & 0xff; // dual PRACH format
|
||||
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
|
||||
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
|
||||
|
||||
pthread_mutex_lock(&ul_config->mutex_ul_config);
|
||||
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
|
||||
prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
|
||||
|
||||
memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
|
||||
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
|
||||
pthread_mutex_unlock(&ul_config->mutex_ul_config);
|
||||
LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus);
|
||||
|
||||
@@ -519,10 +519,16 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &cc->ra[i];
|
||||
pr_found = 0;
|
||||
const int UE_id = find_nr_UE_id(module_idP, ra->rnti);
|
||||
if (UE_id != -1) {
|
||||
continue;
|
||||
}
|
||||
if (ra->state == RA_IDLE) {
|
||||
for(int j = 0; j < ra->preambles.num_preambles; j++) {
|
||||
//check if the preamble received correspond to one of the listed or configured preambles
|
||||
if (preamble_index == ra->preambles.preamble_list[j]) {
|
||||
if (ra->rnti == 0 && get_softmodem_params()->nsa)
|
||||
continue;
|
||||
pr_found=1;
|
||||
break;
|
||||
}
|
||||
@@ -647,16 +653,17 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
ra->preamble_index = preamble_index;
|
||||
ra->beam_id = beam_index;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
LOG_I(NR_MAC,
|
||||
"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
|
||||
"index %u\n",
|
||||
"index %u RA index %d\n",
|
||||
module_idP,
|
||||
CC_id,
|
||||
frameP,
|
||||
ra->Msg2_frame,
|
||||
ra->Msg2_slot,
|
||||
ra->RA_rnti,
|
||||
cc->ssb_index[beam_index]);
|
||||
cc->ssb_index[beam_index],
|
||||
i);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1261,7 +1268,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_req->nPDUs+=1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%04x, state %d, CoreSetType %d\n",
|
||||
LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n",
|
||||
module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType);
|
||||
|
||||
// SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
|
||||
@@ -1669,7 +1676,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_req->nPDUs+=1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
|
||||
LOG_A(NR_MAC, "[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
|
||||
|
||||
// SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
|
||||
// information to data and is reset every slot.
|
||||
@@ -1859,7 +1866,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
|
||||
if (harq->is_waiting == 0) {
|
||||
if (harq->round == 0) {
|
||||
if (stats->dlsch_errors == 0) {
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
UE_info->active[UE_id] = true;
|
||||
UE_info->Msg4_ACKed[UE_id] = true;
|
||||
}
|
||||
|
||||
@@ -768,6 +768,11 @@ void pf_dl(module_id_t module_id,
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
if (sched_ctrl->available_dl_harq.head < 0) {
|
||||
LOG_D(MAC, "UE %d RNTI %04x has no free HARQ process, skipping\n", UE_id, UE_info->rnti[UE_id]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = RC.nrmac[module_id]->UE_info.Y[UE_id][cid%3][slot];
|
||||
@@ -919,7 +924,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
frame,
|
||||
slot,
|
||||
&UE_info->list,
|
||||
2,
|
||||
MAX_MOBILES_PER_GNB,
|
||||
n_rb_sched,
|
||||
rballoc_mask);
|
||||
}
|
||||
@@ -1065,6 +1070,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu) {
|
||||
LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
|
||||
@@ -292,7 +292,7 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
}
|
||||
return max_ri;
|
||||
}
|
||||
else
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -563,6 +563,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static void handle_dl_harq(module_id_t mod_id,
|
||||
int UE_id,
|
||||
int8_t harq_pid,
|
||||
@@ -1094,8 +1095,10 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
|
||||
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
||||
NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
|
||||
if (!harq)
|
||||
if (!harq) {
|
||||
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
DevAssert(harq->is_waiting);
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
@@ -1416,6 +1419,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
/* verify that at that slot and symbol, resources are free. We only do this
|
||||
* for initialCyclicShift 0 (we assume it always has that one), so other
|
||||
* initialCyclicShifts can overlap with ICS 0!*/
|
||||
|
||||
if (pucch_Config) {
|
||||
const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
|
||||
DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
|
||||
@@ -1464,8 +1468,11 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||
pucch_Config = RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
}
|
||||
|
||||
else continue;
|
||||
if (!pucch_Config->schedulingRequestResourceToAddModList) continue;
|
||||
if (!pucch_Config->schedulingRequestResourceToAddModList)
|
||||
continue;
|
||||
|
||||
AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available");
|
||||
|
||||
for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "utils.h"
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
@@ -565,6 +566,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
|
||||
LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid);
|
||||
while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
|
||||
LOG_W(NR_MAC,
|
||||
"Unexpected ULSCH HARQ PID %d (have %d) for RNTI 0x%04x (ignore this warning for RA)\n",
|
||||
@@ -800,14 +802,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
if(ra->cfra) {
|
||||
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
UE_info->active[UE_id] = true;
|
||||
|
||||
} else {
|
||||
|
||||
LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
|
||||
LOG_A(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
|
||||
LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
|
||||
for (int k = 0; k < sdu_lenP; k++) {
|
||||
LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
|
||||
@@ -1564,6 +1566,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
||||
|
||||
/* Statistics */
|
||||
AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) {
|
||||
UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
@@ -1697,6 +1700,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
|
||||
|
||||
/* PUSCH PDU */
|
||||
AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round);
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||
|
||||
@@ -140,6 +140,36 @@ extern volatile int oai_exit;
|
||||
|
||||
pthread_t pdcp_stats_thread_desc;
|
||||
|
||||
// will be called when 4G F1 implementation will use GTP-U instead of protobuf
|
||||
boolean_t cu_f1u_data_req(
|
||||
protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t mode,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
) {
|
||||
mem_block_t *memblock = get_free_mem_block(sdu_buffer_size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data,sdu_buffer, sdu_buffer_size);
|
||||
// weird rb id management in 4G, not fully understand (looks bad design)
|
||||
// overcomplex: if i understand, on the interface DRB start at 4 because there can be SRB 0..3
|
||||
// but it would be much simpler to use absolute numbering
|
||||
// instead of this "srb flag" associated to these +/-4
|
||||
int ret=pdcp_data_ind(ctxt_pP,srb_flagP, false, rb_id-4, sdu_buffer_size, memblock, NULL, NULL);
|
||||
if (!ret) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
/* what to do in case of failure? for the moment: nothing */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void *pdcp_stats_thread(void *param) {
|
||||
|
||||
FILE *fd;
|
||||
@@ -176,6 +206,33 @@ void *pdcp_stats_thread(void *param) {
|
||||
uint64_t get_pdcp_optmask(void) {
|
||||
return pdcp_params.optmask;
|
||||
}
|
||||
|
||||
rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt,
|
||||
const srb_flag_t srb_flag, const MBMS_flag_t MBMS_flag,
|
||||
const rb_id_t rb_id, const mui_t mui,
|
||||
confirm_t confirm, sdu_size_t size, mem_block_t *sdu,
|
||||
const uint32_t *const sourceID, const uint32_t *const destID) {
|
||||
uint8_t *gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
|
||||
size + GTPU_HEADER_OVERHEAD_MAX);
|
||||
AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
|
||||
memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX,
|
||||
sdu->data,
|
||||
size );
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
gtpv1u_enb_tunnel_data_req_t *req=>PV1U_ENB_TUNNEL_DATA_REQ(message_p);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ctxt->rnti;
|
||||
req->rab_id = rb_id+4;
|
||||
LOG_D(PDCP, "%s() (drb %ld) sending message to gtp size %d\n",
|
||||
__func__, rb_id, size);
|
||||
extern instance_t CUuniqInstance;
|
||||
itti_send_msg_to_task(TASK_VARIABLE, CUuniqInstance, message_p);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken
|
||||
@@ -249,12 +306,8 @@ boolean_t pdcp_data_req(
|
||||
LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %ld Ignoring SDU...\n",
|
||||
PROTOCOL_CTXT_ARGS(ctxt_pP),
|
||||
rb_idP);
|
||||
ctxt_pP->configured=FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
// instance for a given RB is configured
|
||||
ctxt_pP->configured=TRUE;
|
||||
}
|
||||
|
||||
if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
|
||||
@@ -575,7 +628,9 @@ pdcp_data_ind(
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP
|
||||
mem_block_t *const sdu_buffer_pP,
|
||||
const uint32_t *const srcID,
|
||||
const uint32_t *const dstID
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
@@ -1072,7 +1127,7 @@ pdcp_data_ind(
|
||||
* for the UE compiled in noS1 mode, we need 0
|
||||
* TODO: be sure of this
|
||||
*/
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) {
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
pdcpHead->inst = ctxt_pP->module_id;
|
||||
} else { // nfapi_mode
|
||||
if (UE_NAS_USE_TUN) {
|
||||
@@ -1288,7 +1343,7 @@ pdcp_run (
|
||||
|
||||
// IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
|
||||
// if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) {
|
||||
if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) {
|
||||
if (!get_softmodem_params()->emulate_l1 && (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO)) {
|
||||
pdcp_fifo_read_input_sdus(ctxt_pP);
|
||||
}
|
||||
|
||||
@@ -1298,8 +1353,9 @@ pdcp_run (
|
||||
} else {
|
||||
start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
|
||||
}
|
||||
|
||||
pdcp_fifo_flush_sdus(ctxt_pP);
|
||||
if (!get_softmodem_params()->emulate_l1) {
|
||||
pdcp_fifo_flush_sdus(ctxt_pP);
|
||||
}
|
||||
|
||||
if (ctxt_pP->enb_flag) {
|
||||
stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
|
||||
@@ -1491,7 +1547,7 @@ void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP) {
|
||||
pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti;
|
||||
pdcp_enb[ctxt_pP->module_id].uid[i]=i;
|
||||
pdcp_enb[ctxt_pP->module_id].num_ues++;
|
||||
printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti);
|
||||
LOG_I(PDCP,"add new uid is %d %x\n", i, ctxt_pP->rnti);
|
||||
pdcp_init_stats_UE(ctxt_pP->module_id, i);
|
||||
// ret=1;
|
||||
break;
|
||||
@@ -2342,7 +2398,7 @@ void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind) {
|
||||
pdcp_params.pdcp_data_ind_func = pdcp_data_ind;
|
||||
}
|
||||
|
||||
uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) {
|
||||
/* temporary enforce netlink when UE_NAS_USE_TUN is set,
|
||||
this is while switching from noS1 as build option
|
||||
to noS1 as config option */
|
||||
@@ -2359,18 +2415,18 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
nas_getparams();
|
||||
|
||||
if(UE_NAS_USE_TUN) {
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if);
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if, id);
|
||||
if (IS_SOFTMODEM_NOS1)
|
||||
nas_config(1, 1, 2, "ue");
|
||||
netlink_init_mbms_tun("uem");
|
||||
nas_config(1, 1, 2, "ue");
|
||||
netlink_init_mbms_tun("uem", id);
|
||||
nas_config_mbms(1, 2, 2, "uem");
|
||||
LOG_I(PDCP, "UE pdcp will use tun interface\n");
|
||||
} else if(ENB_NAS_USE_TUN) {
|
||||
netlink_init_tun("enb",1);
|
||||
netlink_init_tun("enb", 1, 0);
|
||||
nas_config(1, 1, 1, "enb");
|
||||
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
|
||||
netlink_init_mbms_tun("enm");
|
||||
netlink_init_mbms_tun("enm", 0);
|
||||
nas_config_mbms(1, 2, 1, "enm");
|
||||
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
|
||||
}
|
||||
@@ -2382,8 +2438,8 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
}else{
|
||||
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
|
||||
LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n");
|
||||
netlink_init_mbms_tun("enm");
|
||||
nas_config_mbms_s1(1, 2, 1, "enm");
|
||||
netlink_init_mbms_tun("enm", 0);
|
||||
nas_config_mbms_s1(1, 2, 1, "enm");
|
||||
}else
|
||||
LOG_E(PDCP, "ENB pdcp will not use tun interface\n");
|
||||
}
|
||||
@@ -2425,6 +2481,7 @@ pdcp_free (
|
||||
void pdcp_module_cleanup (void)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
netlink_cleanup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -47,13 +47,16 @@
|
||||
|
||||
|
||||
typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *const,
|
||||
const srb_flag_t, const MBMS_flag_t,
|
||||
const rb_id_t, const mui_t,
|
||||
const srb_flag_t, const MBMS_flag_t,
|
||||
const rb_id_t, const mui_t,
|
||||
confirm_t, sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_flag_t,
|
||||
const MBMS_flag_t, const rb_id_t, const sdu_size_t,
|
||||
mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
|
||||
typedef boolean_t (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t,
|
||||
const MBMS_flag_t, const rb_id_t, const sdu_size_t,
|
||||
mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
typedef pdcp_data_ind_t* pdcp_data_ind_func_t;
|
||||
|
||||
#define MAX_NUMBER_NETIF 1 //16
|
||||
#define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10)
|
||||
#define PDCP_USE_NETLINK_BIT (1<< 11)
|
||||
#define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13)
|
||||
@@ -254,6 +257,19 @@ boolean_t pdcp_data_req(
|
||||
const uint32_t * destinationL2Id
|
||||
);
|
||||
|
||||
boolean_t cu_f1u_data_req(
|
||||
protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t mode,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
);
|
||||
|
||||
/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t)
|
||||
* \brief This functions handles data transfer indications coming from RLC
|
||||
* \param[in] ctxt_pP Running context.
|
||||
@@ -267,13 +283,7 @@ boolean_t pdcp_data_req(
|
||||
* \note None
|
||||
* @ingroup _pdcp
|
||||
*/
|
||||
boolean_t pdcp_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
mem_block_t *const sdu_buffer);
|
||||
pdcp_data_ind_t pdcp_data_ind;
|
||||
|
||||
/*! \fn void rrc_pdcp_config_req(const protocol_ctxt_t* const ,uint32_t,rb_id_t,uint8_t)
|
||||
* \brief This functions initializes relevant PDCP entity
|
||||
@@ -401,7 +411,8 @@ void pdcp_mbms_run (
|
||||
*/
|
||||
void pdcp_run (
|
||||
const protocol_ctxt_t *const ctxt_pP);
|
||||
uint64_t pdcp_module_init (uint64_t pdcp_optmask);
|
||||
uint64_t pdcp_module_init (uint64_t pdcp_optmask, int ue_id);
|
||||
uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id);
|
||||
void pdcp_module_cleanup (void);
|
||||
void nr_ip_over_LTE_DRB_preconfiguration (void);
|
||||
void pdcp_layer_init (void);
|
||||
@@ -419,7 +430,10 @@ pdcp_data_ind_func_t get_pdcp_data_ind_func(void);
|
||||
//-----------------------------------------------------------------------------
|
||||
int pdcp_fifo_flush_mbms_sdus ( const protocol_ctxt_t *const ctxt_pP);
|
||||
int pdcp_fifo_read_input_mbms_sdus_fromtun ( const protocol_ctxt_t *const ctxt_pP);
|
||||
|
||||
rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP, const mui_t muiP,
|
||||
confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP, const uint32_t *const, const uint32_t *const);
|
||||
|
||||
/*
|
||||
* Following two types are utilized between NAS driver and PDCP
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
pdcp_control_primitives.c
|
||||
-------------------
|
||||
begin : Mon Dec 10 2001
|
||||
email : Lionel.Gauthier@eurecom.fr
|
||||
-------------------
|
||||
description
|
||||
This file contains the functions used for configuration of pdcp
|
||||
|
||||
***************************************************************************/
|
||||
#include "rtos_header.h"
|
||||
#include "platform.h"
|
||||
#include "protocol_vars_extern.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "rlc.h"
|
||||
#include "pdcp.h"
|
||||
#include "debug_l2.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
configure_pdcp_req (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block *mb;
|
||||
|
||||
mb = get_free_mem_block (sizeof (struct cpdcp_primitive), __func__);
|
||||
if(mb==NULL) return;
|
||||
((struct cpdcp_primitive *) mb->data)->type = CPDCP_CONFIG_REQ;
|
||||
((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_sap = rlcP;
|
||||
((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_type_sap = rlc_sap_typeP;
|
||||
((struct cpdcp_primitive *) mb->data)->primitive.config_req.header_compression_type = header_compression_typeP;
|
||||
send_pdcp_control_primitive (pdcpP, mb);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
pdcp_control_primitives_proto_extern.h
|
||||
-------------------
|
||||
begin : Mon Dec 10 2001
|
||||
email : Lionel.Gauthier@eurecom.fr
|
||||
-------------------
|
||||
description
|
||||
This file contains the prototypes of functions used for configuration of pdcp
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef PDCP_CONTROL_PRIMITIVES_PROTO_EXTERN_H
|
||||
# define PDCP_CONTROL_PRIMITIVES_PROTO_EXTERN_H
|
||||
# include "pdcp.h"
|
||||
void rrc_configure_pdcp (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP);
|
||||
#endif
|
||||
@@ -89,7 +89,7 @@ extern struct msghdr nas_msg_rx;
|
||||
|
||||
|
||||
extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP);
|
||||
|
||||
uint16_t ue_id_g; // Global variable to identify the ID for each UE. It is updated in main() of lte-uesoftmodem.c
|
||||
|
||||
void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) {
|
||||
LOG_I(PDCP,"%s: \nPC5S message, header traffic_type: %d)\n", title, sl_pc5s_msg->pc5s_header.traffic_type);
|
||||
@@ -210,14 +210,46 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
int len;
|
||||
rb_id_t rab_id = DEFAULT_RAB_ID;
|
||||
int sockd;
|
||||
|
||||
do {
|
||||
if (UE_NAS_USE_TUN) {
|
||||
if (ue_id_g == 0) {
|
||||
sockd = nas_sock_fd[ctxt_pP->module_id];
|
||||
}
|
||||
else {
|
||||
sockd = nas_sock_fd[ue_id_g];
|
||||
}
|
||||
}
|
||||
else {
|
||||
sockd = nas_sock_fd[0];
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
|
||||
len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
|
||||
len = read(sockd, &nl_rx_buf, NL_MAX_PAYLOAD);
|
||||
|
||||
if (len<=0) continue;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
|
||||
if (len == -1) {
|
||||
if (errno == EAGAIN) {
|
||||
LOG_D(PDCP, "Error reading NAS socket: %s\n", strerror(errno));
|
||||
}
|
||||
else {
|
||||
LOG_E(PDCP, "Error reading NAS socket: %s\n", strerror(errno));
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Check for message truncation. Strictly speaking if the packet is exactly sizeof(nl_rx_buf) bytes
|
||||
that would not be an error. But we cannot distinguish that from a packet > sizeof(nl_rx_buf) */
|
||||
if (len == sizeof(nl_rx_buf))
|
||||
{
|
||||
LOG_E(PDCP, "%s(%d). Message truncated %d\n", __FUNCTION__, __LINE__, len);
|
||||
break;
|
||||
}
|
||||
if (len == 0) {
|
||||
LOG_E(PDCP, "EOF Reading NAS socket\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (UE_NAS_USE_TUN) {
|
||||
key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
|
||||
@@ -263,7 +295,7 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
|
||||
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
|
||||
ctxt.rnti, rab_id, key);
|
||||
}
|
||||
} while (len > 0);
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
|
||||
return len;
|
||||
@@ -474,8 +506,12 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
// never finished code, dropped
|
||||
}
|
||||
} else { // ctxt.enb_flag => UE
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
#ifdef UESIM_EXPANSION
|
||||
ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
|
||||
#else
|
||||
ctxt.module_id = pdcp_read_header_g.inst;
|
||||
#endif
|
||||
} else {
|
||||
ctxt.module_id = 0;
|
||||
}
|
||||
@@ -526,8 +562,8 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
pdcp_read_header_g.data_size,
|
||||
(unsigned char *)NLMSG_DATA(nas_nlh_rx),
|
||||
PDCP_TRANSMISSION_MODE_DATA,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.destinationL2Id
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.destinationL2Id
|
||||
);
|
||||
} else { /* else of h_rc == HASH_TABLE_OK */
|
||||
MSC_LOG_RX_DISCARDED_MESSAGE(
|
||||
@@ -571,8 +607,8 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
pdcp_read_header_g.data_size,
|
||||
(unsigned char *)NLMSG_DATA(nas_nlh_rx),
|
||||
PDCP_TRANSMISSION_MODE_DATA,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.destinationL2Id
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF|| NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF|| NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.destinationL2Id
|
||||
);
|
||||
} /* rab_id == 0 */
|
||||
} /*pdcp_read_state_g != 0 */
|
||||
@@ -597,35 +633,45 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
|
||||
/* avoid gcc warnings */
|
||||
(void)data_p;
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
//TTN for D2D (PC5S)
|
||||
int prose_addr_len = sizeof(prose_pdcp_addr);
|
||||
char send_buf[BUFSIZE], receive_buf[BUFSIZE];
|
||||
//int optval;
|
||||
int bytes_received;
|
||||
sidelink_pc5s_element *sl_pc5s_msg_send = NULL;
|
||||
pc5s_header_t *pc5s_header = NULL;
|
||||
rb_id_t rab_id = 0;
|
||||
//TTN for D2D (PC5S)
|
||||
// receive a message from ProSe App
|
||||
memset(receive_buf, 0, BUFSIZE);
|
||||
bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0,
|
||||
(struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len);
|
||||
|
||||
char receive_buf[MAX_MESSAGE_SIZE];
|
||||
memset(receive_buf, 0, sizeof(receive_buf));
|
||||
socklen_t prose_addr_len = sizeof(prose_pdcp_addr);
|
||||
bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, sizeof(receive_buf), MSG_TRUNC,
|
||||
(struct sockaddr *) &prose_pdcp_addr, &prose_addr_len);
|
||||
if (bytes_received == -1) {
|
||||
LOG_E(PDCP, "%s(%d). recvfrom failed. %s\n", __FUNCTION__, __LINE__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (bytes_received == 0) {
|
||||
LOG_E(PDCP, "%s(%d). EOF pdcp_pc5_sockfd.\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (bytes_received > sizeof(receive_buf)) {
|
||||
LOG_E(PDCP, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, bytes_received);
|
||||
return;
|
||||
}
|
||||
if (bytes_received > 0) {
|
||||
pc5s_header = calloc(1, sizeof(pc5s_header_t));
|
||||
memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t));
|
||||
|
||||
char send_buf[MAX_MESSAGE_SIZE];
|
||||
switch(pc5s_header->traffic_type) {
|
||||
case TRAFFIC_PC5S_SESSION_INIT :
|
||||
//send reply to ProSe app
|
||||
LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n");
|
||||
memset(send_buf, 0, BUFSIZE);
|
||||
memset(send_buf, 0, sizeof(send_buf));
|
||||
sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element));
|
||||
sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT;
|
||||
sl_pc5s_msg_send->pc5sPrimitive.status = 1;
|
||||
memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
|
||||
memcpy(send_buf, sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
|
||||
int prose_addr_len = sizeof(prose_pdcp_addr);
|
||||
int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len);
|
||||
int bytes_sent = sendto(pdcp_pc5_sockfd, send_buf, sizeof(sidelink_pc5s_element), 0,
|
||||
(struct sockaddr *) &prose_pdcp_addr, prose_addr_len);
|
||||
free (sl_pc5s_msg_send);
|
||||
|
||||
if (bytes_sent < 0) {
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file pdcp_thread.c
|
||||
* \brief
|
||||
* \author F. Kaltenberger
|
||||
* \date 2013
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: florian.kaltenberger@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#include <pthread.h>
|
||||
//#include <inttypes.h>
|
||||
|
||||
#include "pdcp.h"
|
||||
#include "PHY/extern.h" //for PHY_vars
|
||||
#include "UTIL/LOG/log.h"
|
||||
#include "UTIL/LOG/vcd_signal_dumper.h"
|
||||
#include "msc.h"
|
||||
|
||||
#define OPENAIR_THREAD_STACK_SIZE 8192
|
||||
#define OPENAIR_THREAD_PRIORITY 255
|
||||
|
||||
extern int oai_exit;
|
||||
extern char UE_flag;
|
||||
|
||||
pthread_t pdcp_thread;
|
||||
pthread_mutex_t pdcp_mutex;
|
||||
pthread_cond_t pdcp_cond;
|
||||
int pdcp_instance_cnt;
|
||||
|
||||
static void *pdcp_thread_main(void* param);
|
||||
|
||||
static void *pdcp_thread_main(void* param)
|
||||
{
|
||||
uint8_t eNB_flag = !UE_flag;
|
||||
|
||||
LOG_I(PDCP,"This is pdcp_thread eNB_flag = %d\n",eNB_flag);
|
||||
MSC_START_USE();
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error locking mutex.\n");
|
||||
} else {
|
||||
while (pdcp_instance_cnt < 0) {
|
||||
pthread_cond_wait(&pdcp_cond,&pdcp_mutex);
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error unlocking mutex.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
if (eNB_flag) {
|
||||
pdcp_run(PHY_vars_eNB_g[0]->frame, eNB_flag, PHY_vars_eNB_g[0]->Mod_id, 0);
|
||||
LOG_D(PDCP,"Calling pdcp_run (eNB) for frame %d\n",PHY_vars_eNB_g[0]->frame);
|
||||
} else {
|
||||
pdcp_run(PHY_vars_UE_g[0]->frame, eNB_flag, 0, PHY_vars_UE_g[0]->Mod_id);
|
||||
LOG_D(PDCP,"Calling pdcp_run (UE) for frame %d\n",PHY_vars_UE_g[0]->frame);
|
||||
}
|
||||
|
||||
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error locking mutex.\n");
|
||||
} else {
|
||||
pdcp_instance_cnt--;
|
||||
|
||||
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error unlocking mutex.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
int init_pdcp_thread(void)
|
||||
{
|
||||
|
||||
pthread_mutex_init(&pdcp_mutex,NULL);
|
||||
pthread_cond_init(&pdcp_cond,NULL);
|
||||
|
||||
pdcp_instance_cnt = -1;
|
||||
LOG_I(PDCP,"Allocating PDCP thread\n");
|
||||
threadCreate(&pdcp_thread, pdcp_thread_main, (void*)NULL, "PDCP", -1, OAI_PRIORITY_RT);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void cleanup_pdcp_thread(void)
|
||||
{
|
||||
void *status_p = NULL;
|
||||
|
||||
LOG_I(PDCP,"Scheduling PDCP thread to exit\n");
|
||||
|
||||
pdcp_instance_cnt = 0;
|
||||
|
||||
if (pthread_cond_signal(&pdcp_cond) != 0) {
|
||||
LOG_I(PDCP,"ERROR pthread_cond_signal\n");
|
||||
} else {
|
||||
LOG_I(PDCP,"Signalled PDCP thread to exit\n");
|
||||
}
|
||||
|
||||
pthread_join(pdcp_thread,&status_p);
|
||||
LOG_I(PDCP,"PDCP thread exited\n");
|
||||
pthread_cond_destroy(&pdcp_cond);
|
||||
pthread_mutex_destroy(&pdcp_mutex);
|
||||
}
|
||||
@@ -157,7 +157,7 @@ void proto_agent_stop(mod_id_t mod_id) {
|
||||
rlc_op_status_t proto_agent_send_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP, const mui_t muiP,
|
||||
confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) {
|
||||
confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP,const uint32_t *const SrcID, const uint32_t *const DstID) {
|
||||
uint8_t *msg = NULL;
|
||||
Protocol__FlexsplitMessage *init_msg=NULL;
|
||||
int msg_flag = 0;
|
||||
@@ -191,9 +191,10 @@ error:
|
||||
}
|
||||
|
||||
|
||||
boolean_t
|
||||
proto_agent_send_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) {
|
||||
boolean_t proto_agent_send_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP,
|
||||
sdu_size_t sdu_sizeP, mem_block_t *sdu_pP,
|
||||
const uint32_t *const SrcID, const uint32_t *const DstID) {
|
||||
uint8_t *msg = NULL;
|
||||
Protocol__FlexsplitMessage *init_msg = NULL;
|
||||
int msg_flag = 0;
|
||||
|
||||
@@ -42,10 +42,8 @@ void proto_agent_stop(mod_id_t mod_id);
|
||||
rlc_op_status_t proto_agent_send_rlc_data_req( const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP, const mui_t muiP, confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP, mem_block_t *sdu_pP);
|
||||
sdu_size_t sdu_sizeP, mem_block_t *sdu_pP,const uint32_t *const SrcID, const uint32_t *const DstID);
|
||||
|
||||
boolean_t proto_agent_send_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP);
|
||||
pdcp_data_ind_t proto_agent_send_pdcp_data_ind;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -496,14 +496,6 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
boolean_t pdcp_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
mem_block_t *const sdu_buffer);
|
||||
|
||||
int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
|
||||
boolean_t result = 0;
|
||||
Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
|
||||
@@ -525,7 +517,6 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto
|
||||
ctxt_pP.rnti = ctxt->fsp_rnti;
|
||||
ctxt_pP.frame = ctxt->fsp_frame;
|
||||
ctxt_pP.subframe = ctxt->fsp_subframe;
|
||||
ctxt_pP.configured = 1;
|
||||
ctxt_pP.brOption = 0;
|
||||
ctxt_pP.eNB_index = ctxt->fsp_enb_index;
|
||||
srb_flagP = rlc_data->fsp_srb_flag;
|
||||
@@ -546,7 +537,7 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto
|
||||
flag_MBMS,
|
||||
rb_idP,
|
||||
pdcp_pdu_size,
|
||||
pdcp_pdu_p);
|
||||
pdcp_pdu_p, NULL, NULL);
|
||||
return result;
|
||||
error:
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
|
||||
if (rcvd_count < entity->rx_deliv
|
||||
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
|
||||
LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
|
||||
LOG_W(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ hash_table_t *pdcp_coll_p;
|
||||
static uint64_t pdcp_optmask;
|
||||
|
||||
ngran_node_t node_type = ngran_gNB;
|
||||
uint8_t first_dcch = 0;
|
||||
uint8_t proto_agent_flag = 0;
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -160,8 +161,7 @@ static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
const mui_t muiP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP,
|
||||
void *_unused1, void *_unused2)
|
||||
mem_block_t *sdu_pP)
|
||||
{
|
||||
int i;
|
||||
int logged = 0;
|
||||
@@ -206,9 +206,7 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
rb_idP, muiP,
|
||||
confirmP,
|
||||
sdu_sizeP,
|
||||
sdu_pP,
|
||||
NULL,
|
||||
NULL);
|
||||
sdu_pP);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -256,7 +254,6 @@ static void do_pdcp_data_ind(
|
||||
//ctxt_pP->enb_flag != 1 ||
|
||||
ctxt_pP->instance != 0 ||
|
||||
ctxt_pP->eNB_index != 0 ||
|
||||
ctxt_pP->configured != 1 ||
|
||||
ctxt_pP->brOption != 0) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
@@ -376,7 +373,9 @@ boolean_t pdcp_data_ind(
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
mem_block_t *const sdu_buffer)
|
||||
mem_block_t *const sdu_buffer,
|
||||
const uint32_t *const srcID,
|
||||
const uint32_t *const dstID)
|
||||
{
|
||||
enqueue_pdcp_data_ind(ctxt_pP,
|
||||
srb_flagP,
|
||||
@@ -442,7 +441,6 @@ static void *enb_tun_read_thread(void *_)
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rnti = rnti;
|
||||
@@ -486,7 +484,6 @@ static void *ue_tun_read_thread(void *_)
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rnti = rnti;
|
||||
@@ -559,7 +556,7 @@ void pdcp_layer_init(void)
|
||||
#include "targets/RT/USER/lte-softmodem.h"
|
||||
#include "openair2/RRC/NAS/nas_config.h"
|
||||
|
||||
uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
|
||||
uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
|
||||
{
|
||||
/* hack: be sure to initialize only once */
|
||||
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -591,16 +588,18 @@ uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
|
||||
nas_getparams();
|
||||
|
||||
if(UE_NAS_USE_TUN) {
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if);
|
||||
char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue";
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun(ifsuffix_ue, num_if, id);
|
||||
//Add --nr-ip-over-lte option check for next line
|
||||
if (IS_SOFTMODEM_NOS1)
|
||||
nas_config(1, 1, 2, "ue");
|
||||
nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue);
|
||||
LOG_I(PDCP, "UE pdcp will use tun interface\n");
|
||||
start_pdcp_tun_ue();
|
||||
} else if(ENB_NAS_USE_TUN) {
|
||||
netlink_init_tun("enb",1);
|
||||
nas_config(1, 1, 1, "enb");
|
||||
char *ifsuffix_base_s = get_softmodem_params()->nsa ? "gnb" : "enb";
|
||||
netlink_init_tun(ifsuffix_base_s, 1, id);
|
||||
nas_config(1, 1, 1, ifsuffix_base_s);
|
||||
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
|
||||
start_pdcp_tun_enb();
|
||||
} else {
|
||||
@@ -623,7 +622,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
int rb_id;
|
||||
int i;
|
||||
|
||||
if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){
|
||||
if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) {
|
||||
LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
|
||||
|
||||
if(entity->has_sdapDLheader){
|
||||
@@ -634,7 +633,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
}
|
||||
|
||||
if (len != size) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal error %d: %s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -653,19 +652,23 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
rb_found:
|
||||
{
|
||||
int offset=0;
|
||||
if (entity->has_sdap == 1 && entity->has_sdapULheader == 1) offset = 1; // this is the offset of the SDAP header in bytes
|
||||
if (entity->has_sdap == 1 && entity->has_sdapULheader == 1)
|
||||
offset = 1; // this is the offset of the SDAP header in bytes
|
||||
|
||||
gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
|
||||
size + GTPU_HEADER_OVERHEAD_MAX - offset);
|
||||
AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
|
||||
memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf+offset, size-offset);
|
||||
message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_GNB_TUNNEL_DATA_REQ);
|
||||
message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t) + size
|
||||
+ GTPU_HEADER_OVERHEAD_MAX - offset);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).length = size-offset;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id;
|
||||
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(message_p);
|
||||
gtpu_buffer_p = (uint8_t*)(req+1);
|
||||
memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX, buf+offset, size-offset);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size-offset;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ue->rnti;
|
||||
req->pdusession_id = entity->pdusession_id;
|
||||
if (offset==1) {
|
||||
LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
|
||||
@@ -703,18 +706,39 @@ rb_found:
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rnti = ue->rnti;
|
||||
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
|
||||
//printf("\n");
|
||||
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL);
|
||||
if (RC.nrrrc != NULL && NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t)
|
||||
+ size
|
||||
+ GTPU_HEADER_OVERHEAD_MAX);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(message_p);
|
||||
uint8_t *gtpu_buffer_p = (uint8_t*)(req+1);
|
||||
memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX,
|
||||
buf, size);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ue->rnti;
|
||||
req->pdusession_id = rb_id;
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n",
|
||||
__func__, rb_id, size);
|
||||
extern instance_t CUuniqInstance;
|
||||
itti_send_msg_to_task(TASK_VARIABLE, CUuniqInstance, message_p);
|
||||
} else {
|
||||
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
|
||||
//printf("\n");
|
||||
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock);
|
||||
}
|
||||
}
|
||||
|
||||
static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
@@ -791,18 +815,19 @@ srb_found:
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rnti = ue->rnti;
|
||||
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock, NULL, NULL);
|
||||
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock);
|
||||
}
|
||||
else {
|
||||
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
|
||||
F1AP_DL_RRC_MESSAGE (message_p).rrc_container = (uint8_t*)buf;
|
||||
uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size);
|
||||
memcpy (message_buffer, buf, size);
|
||||
F1AP_DL_RRC_MESSAGE (message_p).rrc_container = message_buffer;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = size;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0;
|
||||
@@ -827,7 +852,6 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
|
||||
.frame=-1,
|
||||
.subframe=-1,
|
||||
.eNB_index=0,
|
||||
.configured=true,
|
||||
.brOption=false
|
||||
};
|
||||
|
||||
@@ -1164,7 +1188,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
|
||||
|
||||
NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
|
||||
nr_rlc_bearer_init(RLC_BearerConfig,NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity);
|
||||
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional);
|
||||
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am);
|
||||
nr_rlc_bearer_init_ul_spec(RLC_BearerConfig->mac_LogicalChannelConfig);
|
||||
|
||||
Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list));
|
||||
@@ -1356,6 +1380,35 @@ static boolean_t pdcp_data_req_drb(
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean_t cu_f1u_data_req(
|
||||
protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t mode
|
||||
,const uint32_t *const sourceL2Id
|
||||
,const uint32_t *const destinationL2Id
|
||||
) {
|
||||
|
||||
//Force instance id to 0, OAI incoherent instance management
|
||||
ctxt_pP->instance=0;
|
||||
mem_block_t *memblock = get_free_mem_block(sdu_buffer_size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data,sdu_buffer, sdu_buffer_size);
|
||||
int ret=pdcp_data_ind(ctxt_pP,srb_flagP, false, rb_id, sdu_buffer_size, memblock, NULL, NULL);
|
||||
if (!ret) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
/* what to do in case of failure? for the moment: nothing */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean_t pdcp_data_req(
|
||||
protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "nr_pdcp_timer_thread.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -33,6 +34,7 @@ static volatile uint64_t timer_thread_curtime = 0;
|
||||
|
||||
static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager)
|
||||
{
|
||||
pthread_setname_np(pthread_self(),"pdcp_timer");
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager;
|
||||
nr_pdcp_ue_t **ue_list;
|
||||
int ue_count;
|
||||
|
||||
@@ -596,20 +596,20 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
/* dicard PDU if no data */
|
||||
if (data_size <= 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* dicard PDU if rx buffer is full */
|
||||
if (entity->rx_size + data_size > entity->rx_maxsize) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
if (!sn_in_recv_window(entity, sn)) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
sn, entity->rx_next);
|
||||
goto discard;
|
||||
@@ -617,7 +617,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
/* discard segment if all the bytes of the segment are already there */
|
||||
if (segment_already_received(entity, sn, so, data_size)) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
@@ -653,7 +653,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
control:
|
||||
cpt = nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder);
|
||||
if (cpt != 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, cpt);
|
||||
goto discard;
|
||||
}
|
||||
@@ -1660,7 +1660,7 @@ static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity)
|
||||
*/
|
||||
entity->force_poll = 1;
|
||||
|
||||
LOG_D(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
/* do we meet conditions of 38.322 5.3.3.4? */
|
||||
|
||||
@@ -313,21 +313,21 @@ void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
/* dicard PDU if no data */
|
||||
if (data_size <= 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* dicard PDU if rx buffer is full */
|
||||
if (entity->rx_size + data_size > entity->rx_maxsize) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* discard PDU if sn < rx_next_reassembly */
|
||||
if (sn_compare_rx(entity, sn, entity->rx_next_reassembly) < 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, SN (%d) < rx_next_reassembly (%d)\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, SN (%d) < rx_next_reassembly (%d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
sn, entity->rx_next_reassembly);
|
||||
goto discard;
|
||||
@@ -534,7 +534,7 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
|
||||
}
|
||||
|
||||
if (entity->tx_size + size > entity->tx_maxsize) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,16 +346,16 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
|
||||
|
||||
|
||||
rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
)
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
)
|
||||
{
|
||||
int rnti = ctxt_pP->rnti;
|
||||
nr_rlc_ue_t *ue;
|
||||
@@ -465,19 +465,11 @@ rb_found:
|
||||
LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size);
|
||||
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
/* unused fields? */
|
||||
ctx.instance = 0;
|
||||
ctx.frame = 0;
|
||||
ctx.subframe = 0;
|
||||
ctx.eNB_index = 0;
|
||||
ctx.configured = 1;
|
||||
ctx.brOption = 0;
|
||||
|
||||
/* used fields? */
|
||||
@@ -502,19 +494,44 @@ rb_found:
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (NODE_IS_DU(type) && is_srb == 1) {
|
||||
MessageDef *msg;
|
||||
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
if (NODE_IS_DU(type)) {
|
||||
if(is_srb) {
|
||||
MessageDef *msg;
|
||||
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
|
||||
uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size);
|
||||
memcpy (message_buffer, buf, size);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
} else {
|
||||
MessageDef *msg = itti_alloc_new_message_sized(TASK_RLC_ENB, 0, GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t) + size);
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(msg);
|
||||
req->buffer=(uint8_t*)(req+1);
|
||||
memcpy(req->buffer,buf,size);
|
||||
req->length=size;
|
||||
req->offset=0;
|
||||
req->rnti=ue->rnti;
|
||||
req->pdusession_id=rb_id;
|
||||
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
|
||||
extern instance_t DUuniqInstance;
|
||||
itti_send_msg_to_task(OCP_GTPV1_U, DUuniqInstance, msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) {
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
LOG_D(PDCP, "Calling PDCP layer from RLC in %s\n", __FUNCTION__);
|
||||
if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock, NULL, NULL)) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
/* what to do in case of failure? for the moment: nothing */
|
||||
}
|
||||
@@ -721,7 +738,7 @@ static void add_rlc_srb(int rnti, struct NR_SRB_ToAddMod *s, NR_RLC_BearerConfig
|
||||
sn_field_length);
|
||||
nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am);
|
||||
|
||||
LOG_D(RLC, "%s:%d:%s: added srb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
||||
LOG_I(RLC, "%s:%d:%s: added srb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
||||
}
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
@@ -803,7 +820,7 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
|
||||
sn_field_length);
|
||||
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am);
|
||||
|
||||
LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
LOG_I(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
}
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
@@ -918,10 +935,10 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
|
||||
if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*||
|
||||
ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 ||
|
||||
ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance,
|
||||
ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption);
|
||||
ctxt_pP->eNB_index, ctxt_pP->brOption);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -394,19 +394,12 @@ rb_found:
|
||||
LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d",
|
||||
__FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size);
|
||||
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
/* unused fields? */
|
||||
ctx.instance = ue->module_id;
|
||||
ctx.frame = 0;
|
||||
ctx.subframe = 0;
|
||||
ctx.eNB_index = 0;
|
||||
ctx.configured = 1;
|
||||
ctx.brOption = 0;
|
||||
|
||||
/* used fields? */
|
||||
@@ -425,17 +418,40 @@ rb_found:
|
||||
AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU,
|
||||
"Can't be CU, bad node type %d\n", type);
|
||||
|
||||
if (NODE_IS_DU(type) && is_srb == 1) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
if (NODE_IS_DU(type)) {
|
||||
if (is_srb == 1) {
|
||||
MessageDef *msg = itti_alloc_new_message_sized(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE, sizeof(*msg) + size);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (uint8_t*)(msg+1);
|
||||
memcpy(F1AP_UL_RRC_MESSAGE(msg).rrc_container, buf, size);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
} else {
|
||||
// Fixme: very dirty workaround of incomplete F1-U implementation
|
||||
instance_t DUuniqInstance=0;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ);
|
||||
gtpv1u_enb_tunnel_data_req_t *req=>PV1U_ENB_TUNNEL_DATA_REQ(msg);
|
||||
req->buffer=malloc(size);
|
||||
memcpy(req->buffer,buf,size);
|
||||
req->length=size;
|
||||
req->offset=0;
|
||||
req->rnti=ue->rnti;
|
||||
req->rab_id=rb_id+4;
|
||||
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
|
||||
itti_send_msg_to_task(OCP_GTPV1_U, DUuniqInstance, msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
if (!get_pdcp_data_ind_func()(&ctx, is_srb, is_mbms, rb_id, size, memblock, NULL, NULL)) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed (is_srb %d rb_id %d rnti %d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
@@ -832,10 +848,10 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
|
||||
|
||||
if (0 /*||
|
||||
ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 ||
|
||||
ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance,
|
||||
ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption);
|
||||
ctxt_pP->eNB_index, ctxt_pP->brOption);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1040,5 +1056,12 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP){
|
||||
|
||||
}
|
||||
rlc_data_req (ctxt_pP,
|
||||
srb_flagP,
|
||||
MBMS_flagP,
|
||||
rb_idP,
|
||||
muiP,
|
||||
confirmP,
|
||||
sdu_sizeP,
|
||||
sdu_pP, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "nfapi/oai_integration/gnb_ind_vars.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
|
||||
#define MAX_IF_MODULES 100
|
||||
//#define UL_HARQ_PRINT
|
||||
@@ -58,150 +60,372 @@ extern uint8_t nfapi_mode;
|
||||
extern uint16_t sf_ahead;
|
||||
extern uint16_t sl_ahead;
|
||||
|
||||
void handle_nr_rach(NR_UL_IND_t *UL_info) {
|
||||
|
||||
void handle_nr_rach(NR_UL_IND_t *UL_info)
|
||||
{
|
||||
if(NFAPI_MODE == NFAPI_MODE_PNF) {
|
||||
if (UL_info->rach_ind.number_of_pdus>0) {
|
||||
if (UL_info->rach_ind.number_of_pdus > 0) {
|
||||
LOG_D(PHY,"UL_info->UL_info->rach_ind.number_of_pdus:%d SFN/Slot:%d.%d \n", UL_info->rach_ind.number_of_pdus, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
|
||||
oai_nfapi_nr_rach_indication(&UL_info->rach_ind);
|
||||
UL_info->rach_ind.number_of_pdus = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else{
|
||||
if (UL_info->rach_ind.number_of_pdus>0) {
|
||||
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
|
||||
int npdus = UL_info->rach_ind.number_of_pdus;
|
||||
for(int i = 0; i < npdus; i++) {
|
||||
UL_info->rach_ind.number_of_pdus--;
|
||||
if (UL_info->rach_ind.pdu_list[i].num_preamble>0)
|
||||
AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1,
|
||||
"More than 1 preamble not supported\n");
|
||||
|
||||
nr_initiate_ra_proc(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
UL_info->rach_ind.sfn,
|
||||
UL_info->rach_ind.slot,
|
||||
UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index,
|
||||
UL_info->rach_ind.pdu_list[i].freq_index,
|
||||
UL_info->rach_ind.pdu_list[i].symbol_index,
|
||||
UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance);
|
||||
}
|
||||
NR_UL_IND_t UL_INFO;
|
||||
nfapi_nr_rach_indication_t *rach_ind = NULL;
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
if (gnb_rach_ind_queue.num_items == 0)
|
||||
return;
|
||||
LOG_I(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items);
|
||||
rach_ind = get_queue(&gnb_rach_ind_queue);
|
||||
|
||||
UL_INFO.rach_ind = *rach_ind;
|
||||
UL_INFO.module_id = UL_info->module_id;
|
||||
UL_INFO.CC_id = UL_info->CC_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
UL_INFO.rach_ind = UL_info->rach_ind;
|
||||
UL_INFO.module_id = UL_info->module_id;
|
||||
UL_INFO.CC_id = UL_info->CC_id;
|
||||
}
|
||||
|
||||
int frame_diff = UL_info->frame - UL_INFO.rach_ind.sfn;
|
||||
if (frame_diff < 0)
|
||||
{
|
||||
frame_diff += 1024;
|
||||
}
|
||||
bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7);
|
||||
|
||||
if (UL_INFO.rach_ind.number_of_pdus>0 && in_timewindow) {
|
||||
LOG_A(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",
|
||||
UL_info->frame, UL_info->slot, UL_INFO.rach_ind.sfn, UL_INFO.rach_ind.slot);
|
||||
int npdus = UL_INFO.rach_ind.number_of_pdus;
|
||||
for(int i = 0; i < npdus; i++) {
|
||||
UL_INFO.rach_ind.number_of_pdus--;
|
||||
UL_info->rach_ind.number_of_pdus--;
|
||||
if (UL_INFO.rach_ind.pdu_list[i].num_preamble>0)
|
||||
AssertFatal(UL_INFO.rach_ind.pdu_list[i].num_preamble==1,
|
||||
"More than 1 preamble not supported\n");
|
||||
|
||||
nr_initiate_ra_proc(UL_INFO.module_id,
|
||||
UL_INFO.CC_id,
|
||||
UL_INFO.rach_ind.sfn,
|
||||
UL_INFO.rach_ind.slot,
|
||||
UL_INFO.rach_ind.pdu_list[i].preamble_list[0].preamble_index,
|
||||
UL_INFO.rach_ind.pdu_list[i].freq_index,
|
||||
UL_INFO.rach_ind.pdu_list[i].symbol_index,
|
||||
UL_INFO.rach_ind.pdu_list[i].preamble_list[0].timing_advance);
|
||||
}
|
||||
}
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
if (rach_ind && rach_ind->number_of_pdus > 0)
|
||||
{
|
||||
for(int i = 0; i < rach_ind->number_of_pdus; i++)
|
||||
{
|
||||
free(rach_ind->pdu_list[i].preamble_list);
|
||||
rach_ind->pdu_list[i].preamble_list = NULL;
|
||||
}
|
||||
free(rach_ind->pdu_list);
|
||||
rach_ind->pdu_list = NULL;
|
||||
}
|
||||
free(rach_ind);
|
||||
rach_ind = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handle_nr_uci(NR_UL_IND_t *UL_info)
|
||||
{
|
||||
{
|
||||
if(NFAPI_MODE == NFAPI_MODE_PNF) {
|
||||
if (UL_info->uci_ind.num_ucis>0) {
|
||||
if (UL_info->uci_ind.num_ucis > 0) {
|
||||
LOG_D(PHY,"PNF Sending UL_info->num_ucis:%d PDU_type: %d, SFN/SF:%d.%d \n", UL_info->uci_ind.num_ucis, UL_info->uci_ind.uci_list[0].pdu_type ,UL_info->frame, UL_info->slot);
|
||||
oai_nfapi_nr_uci_indication(&UL_info->uci_ind);
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else{
|
||||
const module_id_t mod_id = UL_info->module_id;
|
||||
const frame_t frame = UL_info->frame;
|
||||
const sub_frame_t slot = UL_info->slot;
|
||||
int num_ucis = UL_info->uci_ind.num_ucis;
|
||||
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
|
||||
LOG_D(MAC,"handling UCI SFN/slot: %d.%d, num_ucis: %d \n", frame,slot, num_ucis);
|
||||
for (int i = 0; i < num_ucis; i++) {
|
||||
switch (uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
|
||||
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
|
||||
handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
|
||||
break;
|
||||
}
|
||||
NR_UL_IND_t UL_INFO;
|
||||
nfapi_nr_uci_indication_t *uci_ind = NULL;
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
if (gnb_uci_ind_queue.num_items == 0)
|
||||
return;
|
||||
LOG_I(NR_MAC, "gnb_uci_ind_queue size = %zu\n", gnb_uci_ind_queue.num_items);
|
||||
uci_ind = get_queue(&gnb_uci_ind_queue);
|
||||
UL_INFO.uci_ind = *uci_ind;
|
||||
}
|
||||
else
|
||||
{
|
||||
UL_INFO.uci_ind = UL_info->uci_ind;
|
||||
}
|
||||
|
||||
const module_id_t mod_id = UL_info->module_id;
|
||||
const frame_t frame = UL_INFO.uci_ind.sfn;
|
||||
const sub_frame_t slot = UL_INFO.uci_ind.slot;
|
||||
int num_ucis = UL_INFO.uci_ind.num_ucis;
|
||||
nfapi_nr_uci_t *uci_list = UL_INFO.uci_ind.uci_list;
|
||||
|
||||
for (int i = 0; i < num_ucis; i++) {
|
||||
switch (uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
|
||||
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
|
||||
LOG_D(NR_MAC, "The received uci has sfn slot %d %d, num_ucis %d and pdu_size %d\n",
|
||||
UL_INFO.uci_ind.sfn, UL_INFO.uci_ind.slot, num_ucis, uci_list[i].pdu_size);
|
||||
handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
|
||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
|
||||
handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LOG_D(MAC, "UCI handled \n");
|
||||
}
|
||||
}
|
||||
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
for (int i = 0; i < num_ucis; i++) {
|
||||
switch (uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
|
||||
if (uci_list[i].pucch_pdu_format_0_1.harq) {
|
||||
free(uci_list[i].pucch_pdu_format_0_1.harq->harq_list);
|
||||
uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL;
|
||||
}
|
||||
free(uci_list[i].pucch_pdu_format_0_1.harq);
|
||||
uci_list[i].pucch_pdu_format_0_1.harq = NULL;
|
||||
free(uci_list[i].pucch_pdu_format_0_1.sr);
|
||||
uci_list[i].pucch_pdu_format_0_1.sr = NULL;
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
|
||||
free(uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload);
|
||||
free(uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload);
|
||||
free(uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uci_ind && num_ucis > 0) {
|
||||
free(uci_list);
|
||||
uci_list = NULL;
|
||||
}
|
||||
free(uci_ind);
|
||||
uci_ind = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool crc_sfn_slot_matcher(void *wanted, void *candidate)
|
||||
{
|
||||
nfapi_p7_message_header_t *msg = candidate;
|
||||
int sfn_sf = *(int*)wanted;
|
||||
|
||||
switch (msg->message_id)
|
||||
{
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
{
|
||||
nfapi_nr_crc_indication_t *ind = candidate;
|
||||
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handle_nr_ulsch(NR_UL_IND_t *UL_info)
|
||||
{
|
||||
if(NFAPI_MODE == NFAPI_MODE_PNF) {
|
||||
if (UL_info->crc_ind.number_crcs>0) {
|
||||
if (UL_info->crc_ind.number_crcs > 0) {
|
||||
LOG_D(PHY,"UL_info->UL_info->crc_ind.number_crcs:%d CRC_IND:SFN/Slot:%d.%d\n", UL_info->crc_ind.number_crcs, UL_info->crc_ind.sfn, UL_info->crc_ind.slot);
|
||||
oai_nfapi_nr_crc_indication(&UL_info->crc_ind);
|
||||
UL_info->crc_ind.number_crcs = 0;
|
||||
}
|
||||
|
||||
if (UL_info->rx_ind.number_of_pdus>0) {
|
||||
if (UL_info->rx_ind.number_of_pdus > 0) {
|
||||
LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/Slot:%d.%d \n", UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot);
|
||||
oai_nfapi_nr_rx_data_indication(&UL_info->rx_ind);
|
||||
UL_info->rx_ind.number_of_pdus = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else{
|
||||
if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
|
||||
for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) {
|
||||
for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) {
|
||||
// find crc_indication j corresponding rx_indication i
|
||||
const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i];
|
||||
const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j];
|
||||
LOG_D(PHY,
|
||||
"UL_info->crc_ind.pdu_list[%d].rnti:%04x "
|
||||
"UL_info->rx_ind.pdu_list[%d].rnti:%04x\n",
|
||||
j,
|
||||
crc->rnti,
|
||||
i,
|
||||
rx->rnti);
|
||||
|
||||
if (crc->rnti != rx->rnti)
|
||||
continue;
|
||||
NR_UL_IND_t UL_INFO;
|
||||
nfapi_nr_rx_data_indication_t *rx_ind = NULL;
|
||||
nfapi_nr_crc_indication_t *crc_ind = NULL;
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
rx_ind = get_queue(&gnb_rx_ind_queue);
|
||||
if (!rx_ind)
|
||||
{
|
||||
LOG_D(NR_PHY, "No rx data indication (empty gnb_rx_ind_queue)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
|
||||
UL_info->frame,
|
||||
UL_info->slot,
|
||||
crc->tb_crc_status ? "error" : "ok",
|
||||
crc->tb_crc_status);
|
||||
int sfn_slot = NFAPI_SFNSLOT2HEX(rx_ind->sfn, rx_ind->slot);
|
||||
|
||||
crc_ind = unqueue_matching(&gnb_crc_ind_queue,
|
||||
MAX_QUEUE_SIZE,
|
||||
crc_sfn_slot_matcher,
|
||||
&sfn_slot);
|
||||
if (!crc_ind)
|
||||
{
|
||||
LOG_D(NR_PHY, "No crc indication with the same SFN SLOT of rx indication %u %u\n", rx_ind->sfn, rx_ind->slot);
|
||||
put_queue(&gnb_rx_ind_queue, rx_ind);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if CRC passes, pass PDU, otherwise pass NULL as error indication */
|
||||
nr_rx_sdu(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot,
|
||||
rx->rnti,
|
||||
crc->tb_crc_status ? NULL : rx->pdu,
|
||||
rx->pdu_length,
|
||||
rx->timing_advance,
|
||||
rx->ul_cqi,
|
||||
rx->rssi);
|
||||
handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc);
|
||||
break;
|
||||
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
|
||||
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
|
||||
UL_INFO.rx_ind = *rx_ind;
|
||||
UL_INFO.crc_ind = *crc_ind;
|
||||
UL_INFO.module_id = UL_info->module_id;
|
||||
UL_INFO.CC_id = UL_info->CC_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
UL_INFO.rx_ind = UL_info->rx_ind;
|
||||
UL_INFO.crc_ind = UL_info->crc_ind;
|
||||
UL_INFO.module_id = UL_info->module_id;
|
||||
UL_INFO.CC_id = UL_info->CC_id;
|
||||
}
|
||||
|
||||
UL_INFO.frame = UL_INFO.rx_ind.sfn;
|
||||
UL_INFO.slot = UL_INFO.rx_ind.slot;
|
||||
UL_INFO.module_id = UL_info->module_id;
|
||||
UL_INFO.CC_id = UL_info->CC_id;
|
||||
LOG_D(NR_MAC, " UL_info frame slot vs rx_ind frame slot vs crc_ind slot frame slot = %u %u vs %u %u vs %u %u\n",
|
||||
UL_info->frame, UL_info->slot,
|
||||
UL_INFO.rx_ind.sfn, UL_INFO.rx_ind.slot,
|
||||
UL_INFO.crc_ind.sfn, UL_INFO.crc_ind.slot
|
||||
);
|
||||
|
||||
if (UL_INFO.rx_ind.number_of_pdus > 0 && UL_INFO.crc_ind.number_crcs > 0) {
|
||||
for (int i = 0; i < UL_INFO.rx_ind.number_of_pdus; i++) {
|
||||
int j;
|
||||
for (j = 0; j < UL_INFO.crc_ind.number_crcs; j++) {
|
||||
// find crc_indication j corresponding rx_indication i
|
||||
const nfapi_nr_rx_data_pdu_t *rx = &UL_INFO.rx_ind.pdu_list[i];
|
||||
const nfapi_nr_crc_t *crc = &UL_INFO.crc_ind.crc_list[j];
|
||||
LOG_D(NR_PHY,
|
||||
"UL_INFO.crc_ind.pdu_list[%d].rnti:%04x "
|
||||
"UL_INFO.rx_ind.pdu_list[%d].rnti:%04x\n",
|
||||
j,
|
||||
crc->rnti,
|
||||
i,
|
||||
rx->rnti);
|
||||
|
||||
if (crc->rnti != rx->rnti)
|
||||
{
|
||||
LOG_D(NR_MAC, "mis-match between CRC rnti %04x and RX rnit %04x\n", crc->rnti, rx->rnti);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
|
||||
UL_INFO.frame,
|
||||
UL_INFO.slot,
|
||||
crc->tb_crc_status ? "error" : "ok",
|
||||
crc->tb_crc_status);
|
||||
|
||||
/* if CRC passes, pass PDU, otherwise pass NULL as error indication */
|
||||
nr_rx_sdu(UL_INFO.module_id,
|
||||
UL_INFO.CC_id,
|
||||
UL_INFO.rx_ind.sfn,
|
||||
UL_INFO.rx_ind.slot,
|
||||
rx->rnti,
|
||||
crc->tb_crc_status ? NULL : rx->pdu,
|
||||
rx->pdu_length,
|
||||
rx->timing_advance,
|
||||
rx->ul_cqi,
|
||||
rx->rssi);
|
||||
handle_nr_ul_harq(UL_INFO.CC_id, UL_INFO.module_id, UL_INFO.frame, UL_INFO.slot, crc);
|
||||
break;
|
||||
} // for (j=0;j<UL_INFO.crc_ind.number_crcs;j++)
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
int last = UL_INFO.crc_ind.number_crcs - 1;
|
||||
if (j < last)
|
||||
{
|
||||
crc_ind->crc_list[j] = crc_ind->crc_list[last];
|
||||
UL_INFO.crc_ind.number_crcs--;
|
||||
}
|
||||
else if (j == last)
|
||||
{
|
||||
UL_INFO.crc_ind.number_crcs--;
|
||||
}
|
||||
|
||||
last = UL_INFO.rx_ind.number_of_pdus - 1;
|
||||
if (i < last)
|
||||
{
|
||||
rx_ind->pdu_list[i] = rx_ind->pdu_list[last];
|
||||
UL_INFO.rx_ind.number_of_pdus--;
|
||||
i--;
|
||||
}
|
||||
else if (i == last)
|
||||
{
|
||||
UL_INFO.rx_ind.number_of_pdus--;
|
||||
}
|
||||
}
|
||||
} // for (i=0;i<UL_INFO.rx_ind.number_of_pdus;i++)
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
{
|
||||
if (UL_INFO.crc_ind.number_crcs > 0)
|
||||
{
|
||||
crc_ind->number_crcs = UL_INFO.crc_ind.number_crcs;
|
||||
requeue(&gnb_crc_ind_queue, crc_ind);
|
||||
}
|
||||
|
||||
if (UL_INFO.rx_ind.number_of_pdus > 0)
|
||||
{
|
||||
rx_ind->number_of_pdus = UL_INFO.rx_ind.number_of_pdus;
|
||||
requeue(&gnb_rx_ind_queue, rx_ind);
|
||||
}
|
||||
|
||||
if (UL_INFO.crc_ind.number_crcs == 0)
|
||||
{
|
||||
free(crc_ind->crc_list);
|
||||
crc_ind->crc_list = NULL;
|
||||
free(crc_ind);
|
||||
crc_ind = NULL;
|
||||
}
|
||||
if (UL_INFO.rx_ind.number_of_pdus == 0)
|
||||
{
|
||||
free(rx_ind->pdu_list);
|
||||
rx_ind->pdu_list = NULL;
|
||||
free(rx_ind);
|
||||
rx_ind = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UL_info->crc_ind.number_crcs = 0;
|
||||
UL_info->rx_ind.number_of_pdus = 0;
|
||||
} else if (UL_info->rx_ind.number_of_pdus != 0
|
||||
|| UL_info->crc_ind.number_crcs != 0) {
|
||||
LOG_E(PHY,
|
||||
"hoping not to have mis-match between CRC ind and RX ind - "
|
||||
"hopefully the missing message is coming shortly "
|
||||
"rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
|
||||
UL_info->rx_ind.number_of_pdus,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot,
|
||||
UL_info->crc_ind.number_crcs,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot);
|
||||
}
|
||||
} else if ((UL_INFO.rx_ind.number_of_pdus != 0)
|
||||
|| (UL_INFO.crc_ind.number_crcs != 0)) {
|
||||
LOG_E(NR_PHY,
|
||||
"hoping not to have mis-match between CRC ind and RX ind - "
|
||||
"hopefully the missing message is coming shortly "
|
||||
"rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
|
||||
UL_INFO.rx_ind.number_of_pdus,
|
||||
UL_INFO.rx_ind.sfn,
|
||||
UL_INFO.rx_ind.slot,
|
||||
UL_INFO.crc_ind.number_crcs,
|
||||
UL_INFO.crc_ind.sfn,
|
||||
UL_INFO.crc_ind.slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,10 +439,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id];
|
||||
NR_IF_Module_t *ifi = nr_if_inst[module_id];
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n",
|
||||
LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n",
|
||||
UL_info->frame,UL_info->slot,
|
||||
module_id,CC_id, UL_info->rach_ind.number_of_pdus,
|
||||
UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
|
||||
module_id,CC_id, gnb_rach_ind_queue.num_items,
|
||||
gnb_rx_ind_queue.num_items, gnb_crc_ind_queue.num_items);
|
||||
|
||||
handle_nr_rach(UL_info);
|
||||
|
||||
@@ -250,7 +474,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
gNB_dlsch_ulsch_scheduler(module_id,
|
||||
(UL_info->frame+((UL_info->slot>(spf-1-sl_ahead))?1:0)) % 1024,
|
||||
(UL_info->slot+sl_ahead)%spf);
|
||||
|
||||
|
||||
ifi->CC_mask = 0;
|
||||
sched_info->module_id = module_id;
|
||||
sched_info->CC_id = CC_id;
|
||||
@@ -274,7 +498,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
ifi->NR_Schedule_response(sched_info);
|
||||
}
|
||||
|
||||
LOG_D(PHY,"NR_Schedule_response: SFN_SF:%d%d dl_pdus:%d\n",
|
||||
LOG_D(NR_PHY,"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
|
||||
sched_info->frame,
|
||||
sched_info->slot,
|
||||
sched_info->DL_req->dl_tti_request_body.nPDUs);
|
||||
|
||||
@@ -124,6 +124,8 @@ void NR_IF_Module_kill(int Mod_id);
|
||||
|
||||
void NR_UL_indication(NR_UL_IND_t *UL_INFO);
|
||||
|
||||
void RCconfig_nr_ue_L1(void);
|
||||
|
||||
/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
|
||||
void NR_Schedule_Response(NR_Sched_Rsp_t *Sched_INFO);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,10 +35,21 @@
|
||||
|
||||
#include "platform_types.h"
|
||||
#include <openair1/PHY/thread_NR_UE.h>
|
||||
#include <semaphore.h>
|
||||
#include "fapi_nr_ue_interface.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
|
||||
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
|
||||
|
||||
typedef struct nr_phy_channel_params_t
|
||||
{
|
||||
uint16_t sfn_slot;
|
||||
float sinr;
|
||||
// Incomplete, need all channel parameters
|
||||
} nr_phy_channel_params_t;
|
||||
|
||||
typedef enum {
|
||||
ONLY_PUSCH,
|
||||
NOT_PUSCH,
|
||||
@@ -209,6 +220,25 @@ typedef struct nr_ue_if_module_s {
|
||||
\param module_id module id*/
|
||||
nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id);
|
||||
|
||||
void nrue_init_standalone_socket(int tx_port, int rx_port);
|
||||
|
||||
void *nrue_standalone_pnf_task(void *context);
|
||||
extern sem_t sfn_slot_semaphore;
|
||||
|
||||
typedef struct nfapi_dl_tti_config_req_tx_data_req_t
|
||||
{
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_itti_config_req;
|
||||
nfapi_nr_tx_data_request_t *tx_data_req_pdu_list;
|
||||
} nfapi_dl_tti_config_req_tx_data_req_t;
|
||||
|
||||
void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id);
|
||||
|
||||
void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request);
|
||||
|
||||
void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
|
||||
nfapi_nr_tx_data_request_t *tx_data_request,
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_request,
|
||||
nfapi_nr_ul_tti_request_t *ul_tti_request);
|
||||
|
||||
/**\brief done free of memory allocation by module_id and release to pointer pool.
|
||||
\param module_id module id*/
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/queue_test
|
||||
@@ -24,25 +24,31 @@ extern RAN_CONTEXT_t RC;
|
||||
uint16_t frame_cnt=0;
|
||||
void handle_rach(UL_IND_t *UL_info) {
|
||||
int i;
|
||||
|
||||
if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) {
|
||||
if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles>0) {
|
||||
AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n");
|
||||
LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_RCC_INFO.rach_ind[j].sfn_sf));
|
||||
initiate_ra_proc(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf),
|
||||
NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf),
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble,
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti,
|
||||
0
|
||||
);
|
||||
free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list);
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0;
|
||||
UL_RCC_INFO.rach_ind[j].header.message_id = 0;
|
||||
int j = UL_info->subframe;
|
||||
AssertFatal(j < sizeof(UL_RCC_INFO.rach_ind) / sizeof(UL_RCC_INFO.rach_ind[0]), "j index out of range of index of rach_ind\n");
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF)
|
||||
{
|
||||
if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 0)
|
||||
{
|
||||
if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 1)
|
||||
{
|
||||
LOG_D(MAC, "handle_rach j: %d UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles: %d\n",
|
||||
j, UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles);
|
||||
LOG_D(MAC, "UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:Frame: %d Subframe: %d\n",
|
||||
UL_info->frame, UL_info->subframe, NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf));
|
||||
}
|
||||
AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles == 1, "More than 1 preamble not supported\n"); // dump frame/sf and all things in UL_RCC_INFO
|
||||
initiate_ra_proc(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf),
|
||||
NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf),
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble,
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti,
|
||||
0);
|
||||
free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list);
|
||||
UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0;
|
||||
UL_RCC_INFO.rach_ind[j].header.message_id = 0;
|
||||
}
|
||||
} else {
|
||||
if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) {
|
||||
@@ -92,8 +98,9 @@ void handle_sr(UL_IND_t *UL_info) {
|
||||
oai_nfapi_sr_indication(&UL_info->sr_ind);
|
||||
}
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) {
|
||||
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
|
||||
if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0) {
|
||||
assert(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
|
||||
for (i=0; i<UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs; i++) {
|
||||
SR_indication(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
@@ -109,6 +116,7 @@ void handle_sr(UL_IND_t *UL_info) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(UL_info->sr_ind.sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
|
||||
for (i=0; i<UL_info->sr_ind.sr_indication_body.number_of_srs; i++)
|
||||
SR_indication(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
@@ -133,8 +141,9 @@ void handle_cqi(UL_IND_t *UL_info) {
|
||||
UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0;
|
||||
}
|
||||
} else if (NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) {
|
||||
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
|
||||
if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0) {
|
||||
assert(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
for (i=0; i<UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis; i++) {
|
||||
cqi_indication(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
@@ -153,6 +162,7 @@ void handle_cqi(UL_IND_t *UL_info) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(UL_info->cqi_ind.cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
for (i=0; i<UL_info->cqi_ind.cqi_indication_body.number_of_cqis; i++)
|
||||
cqi_indication(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
@@ -178,8 +188,9 @@ void handle_harq(UL_IND_t *UL_info) {
|
||||
|
||||
UL_info->harq_ind.harq_indication_body.number_of_harqs = 0;
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) {
|
||||
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
|
||||
if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0) {
|
||||
assert(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU);
|
||||
for (int i=0; i<UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs; i++) {
|
||||
harq_indication(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
@@ -194,6 +205,7 @@ void handle_harq(UL_IND_t *UL_info) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(UL_info->harq_ind.harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU);
|
||||
for (int i=0; i < UL_info->harq_ind.harq_indication_body.number_of_harqs; i++)
|
||||
harq_indication(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
@@ -221,9 +233,11 @@ void handle_ulsch(UL_IND_t *UL_info) {
|
||||
UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
|
||||
}
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
for(uint8_t k = 0; k < NUM_NFPAI_SUBFRAME; k++) {
|
||||
for(uint8_t k = 0; k < NUM_NFAPI_SUBFRAME; k++) {
|
||||
if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) {
|
||||
assert(UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU);
|
||||
for (i=0; i<UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus; i++) {
|
||||
assert(UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU);
|
||||
for (j=0; j<UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs; j++) {
|
||||
// find crc_indication j corresponding rx_indication i
|
||||
LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n",
|
||||
@@ -251,16 +265,12 @@ void handle_ulsch(UL_IND_t *UL_info) {
|
||||
NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame,
|
||||
NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe,
|
||||
UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
|
||||
UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data,
|
||||
UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ind_data,
|
||||
UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
|
||||
UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance,
|
||||
UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
|
||||
}
|
||||
|
||||
if(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data != NULL) {
|
||||
free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data);
|
||||
}
|
||||
|
||||
break;
|
||||
} //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti)
|
||||
} // for (j=0;j<UL_info->crc_ind.crc_indication_body.number_of_crcs;j++)
|
||||
@@ -276,7 +286,9 @@ void handle_ulsch(UL_IND_t *UL_info) {
|
||||
}
|
||||
} else {
|
||||
if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) {
|
||||
assert(UL_info->rx_ind.rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU);
|
||||
for (i=0; i<UL_info->rx_ind.rx_indication_body.number_of_pdus; i++) {
|
||||
assert(UL_info->crc_ind.crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU);
|
||||
for (j=0; j<UL_info->crc_ind.crc_indication_body.number_of_crcs; j++) {
|
||||
// find crc_indication j corresponding rx_indication i
|
||||
LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j,
|
||||
@@ -304,7 +316,7 @@ void handle_ulsch(UL_IND_t *UL_info) {
|
||||
NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame,
|
||||
NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe,
|
||||
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
|
||||
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data,
|
||||
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ind_data,
|
||||
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
|
||||
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance,
|
||||
UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
|
||||
@@ -790,6 +802,7 @@ IF_Module_t *IF_Module_init(int Mod_id) {
|
||||
"allocation of if_inst[%d]->if_mutex fails\n",Mod_id);
|
||||
}
|
||||
|
||||
memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_INFO));
|
||||
return if_inst[Mod_id];
|
||||
}
|
||||
|
||||
|
||||
@@ -87,25 +87,25 @@ typedef struct {
|
||||
} UL_IND_t;
|
||||
|
||||
// Downlink subframe P7
|
||||
#define NUM_NFPAI_SUBFRAME 5
|
||||
#define NUM_NFAPI_SUBFRAME 10
|
||||
typedef struct {
|
||||
/// harq indication list
|
||||
nfapi_harq_indication_t harq_ind[NUM_NFPAI_SUBFRAME];
|
||||
nfapi_harq_indication_t harq_ind[NUM_NFAPI_SUBFRAME];
|
||||
|
||||
/// crc indication list
|
||||
nfapi_crc_indication_t crc_ind[NUM_NFPAI_SUBFRAME];
|
||||
nfapi_crc_indication_t crc_ind[NUM_NFAPI_SUBFRAME];
|
||||
|
||||
/// SR indication list
|
||||
nfapi_sr_indication_t sr_ind[NUM_NFPAI_SUBFRAME];
|
||||
nfapi_sr_indication_t sr_ind[NUM_NFAPI_SUBFRAME];
|
||||
|
||||
/// CQI indication list
|
||||
nfapi_cqi_indication_t cqi_ind[NUM_NFPAI_SUBFRAME];
|
||||
nfapi_cqi_indication_t cqi_ind[NUM_NFAPI_SUBFRAME];
|
||||
|
||||
/// RACH indication list
|
||||
nfapi_rach_indication_t rach_ind[NUM_NFPAI_SUBFRAME];
|
||||
nfapi_rach_indication_t rach_ind[NUM_NFAPI_SUBFRAME];
|
||||
|
||||
/// RX indication
|
||||
nfapi_rx_indication_t rx_ind[NUM_NFPAI_SUBFRAME];
|
||||
nfapi_rx_indication_t rx_ind[NUM_NFAPI_SUBFRAME];
|
||||
|
||||
} UL_RCC_IND_t;
|
||||
|
||||
@@ -151,6 +151,17 @@ typedef struct IF_Module_s{
|
||||
pthread_mutex_t if_mutex;
|
||||
} IF_Module_t;
|
||||
|
||||
// These mutex is used for multiple UEs L2 FAPI simulator.
|
||||
// Each UEs set these value in UL and UL_INFO is shared in all UE's thread.
|
||||
typedef struct {
|
||||
pthread_mutex_t rx_mutex;
|
||||
pthread_mutex_t crc_mutex;
|
||||
pthread_mutex_t sr_mutex;
|
||||
pthread_mutex_t harq_mutex;
|
||||
pthread_mutex_t cqi_mutex;
|
||||
pthread_mutex_t rach_mutex;
|
||||
} FILL_UL_INFO_MUTEX_t;
|
||||
|
||||
/*Initial */
|
||||
IF_Module_t *IF_Module_init(int Mod_id);
|
||||
void IF_Module_kill(int Mod_id);
|
||||
|
||||
+1207
-208
File diff suppressed because it is too large
Load Diff
@@ -13,16 +13,51 @@
|
||||
#include "openair2/PHY_INTERFACE/IF_Module.h"
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi_pnf_interface.h"
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
|
||||
//#include "openair1/PHY/defs.h"
|
||||
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
|
||||
#include "queue_t.h"
|
||||
|
||||
#define NUM_MCS 28
|
||||
#define NUM_SINR 100
|
||||
#define NUM_BLER_COL 13
|
||||
|
||||
// this mutex is used to set multiple UE's UL value in L2 FAPI simulator.
|
||||
extern FILL_UL_INFO_MUTEX_t fill_ul_mutex;
|
||||
//below 2 difinitions move to phy_stub_UE.c to add initialization when difinition.
|
||||
extern UL_IND_t *UL_INFO;
|
||||
extern nfapi_tx_request_pdu_t* tx_request_pdu_list;
|
||||
// New
|
||||
/// Pointers to config_request types. Used from nfapi callback functions.
|
||||
//below 3 difinitions move to phy_stub_UE.c to add initialization when difinition.
|
||||
|
||||
//below 2 difinitions move to lte-ue.c to add initialization when difinition.
|
||||
//int next_ra_frame;
|
||||
//module_id_t next_Mod_id;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t sf;
|
||||
uint16_t rnti[256];
|
||||
uint8_t mcs[256];
|
||||
float sinr;
|
||||
uint16_t pdu_size;
|
||||
bool drop_flag[256];
|
||||
bool latest;
|
||||
|
||||
} sf_rnti_mcs_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t length;
|
||||
float bler_table[NUM_SINR][NUM_BLER_COL];
|
||||
} bler_struct;
|
||||
|
||||
extern bler_struct bler_data[NUM_MCS];
|
||||
|
||||
|
||||
extern nfapi_dl_config_request_t* dl_config_req;
|
||||
extern nfapi_ul_config_request_t* ul_config_req;
|
||||
extern nfapi_hi_dci0_request_t* hi_dci0_req;
|
||||
@@ -52,16 +87,19 @@ void send_nfapi_UL_indications(UL_IND_t UL_INFO);
|
||||
|
||||
//void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe);
|
||||
|
||||
void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index);
|
||||
void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index,
|
||||
nfapi_ul_config_request_t *ul_config_req);
|
||||
|
||||
|
||||
// This function should be indicating directly to the eNB when there is a planned scheduling request at the MAC layer
|
||||
// of the UE. It should get called from ue_get_SR()
|
||||
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti);
|
||||
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti,
|
||||
nfapi_ul_config_request_t *ul_config_req);
|
||||
|
||||
// In our case the this function will be always indicating ACK to the MAC of the eNB (i.e. always assuming)
|
||||
// successful decoding.
|
||||
void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti);
|
||||
void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti,
|
||||
nfapi_ul_config_request_t *ul_config_req);
|
||||
|
||||
|
||||
void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI);
|
||||
@@ -70,9 +108,11 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
|
||||
void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti);
|
||||
|
||||
|
||||
void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti);
|
||||
void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti,
|
||||
nfapi_ul_config_request_t *ul_config_req);
|
||||
|
||||
void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO,nfapi_ul_config_harq_information *harq_information, uint16_t rnti
|
||||
void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO,nfapi_ul_config_harq_information *harq_information, uint16_t rnti,
|
||||
nfapi_ul_config_request_t *ul_config_req
|
||||
/*uint8_t tdd_mapping_mode,
|
||||
uint16_t tdd_multiplexing_mask*/);
|
||||
|
||||
@@ -80,13 +120,36 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int frame, int subframe
|
||||
|
||||
void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
|
||||
nfapi_ul_config_request_pdu_t *ul_config_pdu,
|
||||
uint16_t frame,uint8_t subframe,uint8_t srs_present, int index);
|
||||
uint16_t frame,uint8_t subframe,uint8_t srs_present, int index,
|
||||
nfapi_ul_config_request_t *ul_config_req);
|
||||
|
||||
typedef struct phy_channel_params_t
|
||||
{
|
||||
uint16_t sfn_sf;
|
||||
float sinr;
|
||||
// Incomplete, need all channel parameters
|
||||
} phy_channel_params_t;
|
||||
|
||||
typedef struct nfapi_tx_req_pdu_list_t
|
||||
{
|
||||
int num_pdus; /* number .pdus[] objects */
|
||||
nfapi_tx_request_pdu_t pdus[]; /* see "struct hack" */
|
||||
} nfapi_tx_req_pdu_list_t;
|
||||
|
||||
typedef struct nfapi_dl_config_req_tx_req_t
|
||||
{
|
||||
nfapi_dl_config_request_t *dl_config_req;
|
||||
nfapi_tx_req_pdu_list_t *tx_req_pdu_list;
|
||||
} nfapi_dl_config_req_tx_req_t;
|
||||
|
||||
void nfapi_free_tx_req_pdu_list(nfapi_tx_req_pdu_list_t *);
|
||||
|
||||
void dl_config_req_UE_MAC_dci(int sfn,
|
||||
int sf,
|
||||
nfapi_dl_config_request_pdu_t *dci,
|
||||
nfapi_dl_config_request_pdu_t *dlsch,
|
||||
int num_ue);
|
||||
int num_ue,
|
||||
nfapi_tx_req_pdu_list_t *);
|
||||
void dl_config_req_UE_MAC_bch(int sfn,
|
||||
int sf,
|
||||
nfapi_dl_config_request_pdu_t *bch,
|
||||
@@ -94,7 +157,8 @@ void dl_config_req_UE_MAC_bch(int sfn,
|
||||
void dl_config_req_UE_MAC_mch(int sfn,
|
||||
int sf,
|
||||
nfapi_dl_config_request_pdu_t *bch,
|
||||
int num_ue);
|
||||
int num_ue,
|
||||
nfapi_tx_req_pdu_list_t *);
|
||||
|
||||
int tx_req_UE_MAC(nfapi_tx_request_t* req);
|
||||
|
||||
@@ -107,19 +171,44 @@ void hi_dci0_req_UE_MAC(int sfn,
|
||||
// The following set of memcpy functions should be getting called as callback functions from
|
||||
// pnf_p7_subframe_ind.
|
||||
|
||||
int memcpy_dl_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req);
|
||||
|
||||
|
||||
int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req);
|
||||
|
||||
|
||||
int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req);
|
||||
|
||||
|
||||
int memcpy_hi_dci0_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req);
|
||||
|
||||
void UE_config_stub_pnf(void);
|
||||
|
||||
void *memcpy_tx_req_standalone(nfapi_tx_request_t *tx_req);
|
||||
|
||||
void *memcpy_dl_config_req_standalone(nfapi_dl_config_request_t *dl_config_req);
|
||||
|
||||
// open an SCTP socket with a standalone PNF module
|
||||
void ue_init_standalone_socket(int tx_port, int rx_port);
|
||||
|
||||
// read from standalone pnf socket call corresponding memcpy functions
|
||||
void *ue_standalone_pnf_task(void *context);
|
||||
void send_standalone_msg(UL_IND_t *UL, nfapi_message_id_e msg_type);
|
||||
void send_standalone_dummy(void);
|
||||
void enqueue_dl_config_req_tx_req(nfapi_dl_config_request_t *dl_config_req, nfapi_tx_request_t *tx_req);
|
||||
|
||||
// Convert downlink nfapi messages to a string.
|
||||
// Returned memory is malloc'ed, caller is responsible for freeing.
|
||||
char *nfapi_dl_config_req_to_string(nfapi_dl_config_request_t *req);
|
||||
char *nfapi_ul_config_req_to_string(nfapi_ul_config_request_t *req);
|
||||
|
||||
// Convert downlink nfapi messages to a string.
|
||||
// Returned memory is statically allocated.
|
||||
const char *dl_pdu_type_to_string(uint8_t pdu_type);
|
||||
const char *ul_pdu_type_to_string(uint8_t pdu_type);
|
||||
|
||||
extern queue_t dl_config_req_tx_req_queue;
|
||||
extern queue_t ul_config_req_queue;
|
||||
extern queue_t hi_dci0_req_queue;
|
||||
|
||||
extern nfapi_ul_config_request_t* ul_config_req;
|
||||
extern nfapi_hi_dci0_request_t* hi_dci0_req;
|
||||
|
||||
extern int current_sfn_sf;
|
||||
|
||||
extern sem_t sfn_semaphore;
|
||||
|
||||
#endif /* PHY_STUB_UE_H_ */
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
#include "queue_t.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef UNITTEST
|
||||
#include <stdio.h>
|
||||
#define LOG_ERROR(MSG) printf(MSG "\n")
|
||||
#else
|
||||
#include "common/utils/LOG/log.h"
|
||||
#define LOG_ERROR(MSG) LOG_E(PHY, MSG "\n")
|
||||
#endif
|
||||
|
||||
void init_queue(queue_t *q)
|
||||
{
|
||||
memset(q, 0, sizeof(*q));
|
||||
pthread_mutex_init(&q->mutex, NULL);
|
||||
}
|
||||
|
||||
void reset_queue(queue_t *q)
|
||||
{
|
||||
void *p;
|
||||
while ((p = get_queue(q)) != NULL)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void *put_queue_replace(queue_t *q, void *item)
|
||||
{
|
||||
assert(item != NULL);
|
||||
if (pthread_mutex_lock(&q->mutex) != 0)
|
||||
{
|
||||
LOG_ERROR("put_queue: mutex_lock failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
void *evicted = NULL;
|
||||
if (q->num_items >= MAX_QUEUE_SIZE)
|
||||
{
|
||||
evicted = q->items[q->read_index];
|
||||
assert(evicted != NULL);
|
||||
q->items[q->read_index] = NULL;
|
||||
q->read_index = (q->read_index + 1) % MAX_QUEUE_SIZE;
|
||||
q->num_items--;
|
||||
}
|
||||
assert(q->items[q->write_index] == NULL);
|
||||
q->items[q->write_index] = item;
|
||||
q->write_index = (q->write_index + 1) % MAX_QUEUE_SIZE;
|
||||
q->num_items++;
|
||||
|
||||
pthread_mutex_unlock(&q->mutex);
|
||||
return evicted;
|
||||
}
|
||||
|
||||
|
||||
bool put_queue(queue_t *q, void *item)
|
||||
{
|
||||
assert(item != NULL);
|
||||
if (pthread_mutex_lock(&q->mutex) != 0)
|
||||
{
|
||||
LOG_ERROR("put_queue: mutex_lock failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool queued;
|
||||
if (q->num_items >= MAX_QUEUE_SIZE)
|
||||
{
|
||||
LOG_ERROR("put_queue: queue is full");
|
||||
queued = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(q->items[q->write_index] == NULL);
|
||||
q->items[q->write_index] = item;
|
||||
q->write_index = (q->write_index + 1) % MAX_QUEUE_SIZE;
|
||||
q->num_items++;
|
||||
queued = true;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&q->mutex);
|
||||
return queued;
|
||||
}
|
||||
|
||||
void *get_queue(queue_t *q)
|
||||
{
|
||||
void *item = NULL;
|
||||
if (pthread_mutex_lock(&q->mutex) != 0)
|
||||
{
|
||||
LOG_ERROR("get_queue: mutex_lock failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (q->num_items > 0)
|
||||
{
|
||||
item = q->items[q->read_index];
|
||||
assert(item != NULL);
|
||||
q->items[q->read_index] = NULL;
|
||||
q->read_index = (q->read_index + 1) % MAX_QUEUE_SIZE;
|
||||
q->num_items--;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&q->mutex);
|
||||
return item;
|
||||
}
|
||||
|
||||
bool requeue(queue_t *q, void *item)
|
||||
{
|
||||
assert(item != NULL);
|
||||
if (pthread_mutex_lock(&q->mutex) != 0)
|
||||
{
|
||||
LOG_ERROR("requeue: mutex_lock failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool queued;
|
||||
if (q->num_items >= MAX_QUEUE_SIZE)
|
||||
{
|
||||
LOG_ERROR("requeue: queue is full");
|
||||
queued = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->read_index = (q->read_index + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE;
|
||||
assert(q->items[q->read_index] == NULL);
|
||||
q->items[q->read_index] = item;
|
||||
q->num_items++;
|
||||
queued = true;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&q->mutex);
|
||||
return queued;
|
||||
}
|
||||
|
||||
void *unqueue(queue_t *q)
|
||||
{
|
||||
void *item = NULL;
|
||||
if (pthread_mutex_lock(&q->mutex) != 0) {
|
||||
LOG_ERROR("unqueue: mutex_lock failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (q->num_items > 0) {
|
||||
q->write_index = (q->write_index + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE;
|
||||
item = q->items[q->write_index];
|
||||
q->items[q->write_index] = NULL;
|
||||
q->num_items--;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&q->mutex);
|
||||
return item;
|
||||
}
|
||||
|
||||
void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted)
|
||||
{
|
||||
if (pthread_mutex_lock(&q->mutex) != 0)
|
||||
{
|
||||
LOG_ERROR("unqueue_matching: mutex_lock failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *item = NULL;
|
||||
size_t endi = q->write_index;
|
||||
for (size_t i = 0; i < q->num_items; i++)
|
||||
{
|
||||
if (max_depth == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
--max_depth;
|
||||
|
||||
endi = (endi + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE;
|
||||
void *candidate = q->items[endi];
|
||||
if (matcher(wanted, candidate))
|
||||
{
|
||||
item = candidate;
|
||||
// delete item from the queue and move other items down
|
||||
for (;;)
|
||||
{
|
||||
size_t j = (endi + 1) % MAX_QUEUE_SIZE;
|
||||
if (j == q->write_index)
|
||||
{
|
||||
q->items[endi] = NULL;
|
||||
q->write_index = endi;
|
||||
q->num_items--;
|
||||
break;
|
||||
}
|
||||
q->items[endi] = q->items[j];
|
||||
endi = j;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&q->mutex);
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
queue_t is a basic thread-safe non-blocking fixed-size queue.
|
||||
|
||||
put_queue returns false if the queue is full.
|
||||
get_queue returns NULL if the queue is empty.
|
||||
|
||||
Example usage:
|
||||
|
||||
// Initialization:
|
||||
queue_t fooq;
|
||||
init_queue(&fooq);
|
||||
|
||||
// Producer:
|
||||
foo_t *item = new_foo();
|
||||
if (!put_queue(&fooq, item))
|
||||
delete_foo(item);
|
||||
|
||||
// Consumer:
|
||||
foo_t *item = get_queue(&fooq);
|
||||
if (item)
|
||||
{
|
||||
do_something_with_foo(item);
|
||||
delete_foo(item);
|
||||
}
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MAX_QUEUE_SIZE 512
|
||||
|
||||
typedef struct queue_t
|
||||
{
|
||||
void *items[MAX_QUEUE_SIZE];
|
||||
size_t read_index, write_index;
|
||||
size_t num_items;
|
||||
pthread_mutex_t mutex;
|
||||
} queue_t;
|
||||
|
||||
void init_queue(queue_t *q);
|
||||
void reset_queue(queue_t *q);
|
||||
void *put_queue_replace(queue_t *q, void *item);
|
||||
bool put_queue(queue_t *q, void *item);
|
||||
void *get_queue(queue_t *q);
|
||||
|
||||
/* Put the given item back onto this queue at the head.
|
||||
(The next call to put_queue would return this item.)
|
||||
Return true if successful, false if the queue was full */
|
||||
bool requeue(queue_t *q, void *item);
|
||||
|
||||
/* Remove the last item queued.
|
||||
Return the item or NULL if the queue was empty */
|
||||
void *unqueue(queue_t *q);
|
||||
|
||||
typedef bool queue_matcher_t(void *wanted, void *candidate);
|
||||
|
||||
/* Unqueue the most recently queued item for which `matcher(wanted, candidate)`
|
||||
returns true where `candidate` is an item currently on the queue.
|
||||
Look only at the last `max_depth` items on the queue, at most.
|
||||
Returns the candidate item, or NULL if none matches */
|
||||
void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted);
|
||||
@@ -0,0 +1,226 @@
|
||||
#include "queue_t.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FAIL do { \
|
||||
printf("\n*** FAILED at %s line %d\n", __FILE__, __LINE__); \
|
||||
pass = false; \
|
||||
} while (0)
|
||||
|
||||
#define EQUAL(A, B) do { \
|
||||
if ((A) != (B)) \
|
||||
FAIL; \
|
||||
} while (0)
|
||||
|
||||
typedef uint32_t Thing_t; /* actual type doesn't matter */
|
||||
|
||||
static Thing_t things[MAX_QUEUE_SIZE];
|
||||
static Thing_t thing1, thing2;
|
||||
|
||||
static bool matcher(void *wanted, void *candidate)
|
||||
{
|
||||
return wanted == candidate;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bool pass = true;
|
||||
queue_t queue;
|
||||
init_queue(&queue);
|
||||
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
{
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* queue is full */
|
||||
if (put_queue(&queue, &thing1))
|
||||
FAIL;
|
||||
|
||||
Thing_t *p;
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[i]);
|
||||
}
|
||||
|
||||
/* queue is empty */
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, NULL);
|
||||
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
{
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[0]);
|
||||
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[1]);
|
||||
|
||||
if (!requeue(&queue, &thing1))
|
||||
FAIL;
|
||||
if (!requeue(&queue, &thing2))
|
||||
FAIL;
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &thing2);
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &thing1);
|
||||
|
||||
if (!requeue(&queue, &things[1]))
|
||||
FAIL;
|
||||
if (!requeue(&queue, &things[0]))
|
||||
FAIL;
|
||||
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE / 2; ++i)
|
||||
{
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[i]);
|
||||
}
|
||||
|
||||
for (int i = MAX_QUEUE_SIZE / 2; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
FAIL;
|
||||
}
|
||||
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[MAX_QUEUE_SIZE / 2]);
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[MAX_QUEUE_SIZE / 2 + 1]);
|
||||
|
||||
// ---- unqueue ----
|
||||
|
||||
init_queue(&queue);
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
{
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
for (int i = MAX_QUEUE_SIZE; --i >= 0;)
|
||||
{
|
||||
p = unqueue(&queue);
|
||||
EQUAL(p, &things[i]);
|
||||
EQUAL(queue.num_items, i);
|
||||
}
|
||||
EQUAL(queue.num_items, 0);
|
||||
if (!put_queue(&queue, &thing1))
|
||||
FAIL;
|
||||
if (!put_queue(&queue, &thing2))
|
||||
FAIL;
|
||||
EQUAL(queue.num_items, 2);
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &thing1);
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &thing2);
|
||||
|
||||
// ---- unqueue_matching ----
|
||||
|
||||
init_queue(&queue);
|
||||
|
||||
// empty queue
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
|
||||
EQUAL(p, NULL);
|
||||
EQUAL(queue.num_items, 0);
|
||||
|
||||
// one item in queue
|
||||
if (!put_queue(&queue, &thing1))
|
||||
FAIL;
|
||||
EQUAL(queue.num_items, 1);
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing2);
|
||||
EQUAL(p, NULL);
|
||||
EQUAL(queue.num_items, 1);
|
||||
|
||||
p = unqueue_matching(&queue, /*max_queue=*/ 0, matcher, &thing1);
|
||||
EQUAL(p, NULL);
|
||||
EQUAL(queue.num_items, 1);
|
||||
|
||||
p = unqueue_matching(&queue, /*max_queue=*/ 1, matcher, &thing1);
|
||||
EQUAL(p, &thing1);
|
||||
EQUAL(queue.num_items, 0);
|
||||
|
||||
// more max_queue values
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
{
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
p = unqueue_matching(&queue, /*max_queue=*/ 0, matcher, &things[MAX_QUEUE_SIZE - 1]);
|
||||
EQUAL(p, NULL);
|
||||
p = unqueue_matching(&queue, /*max_queue=*/ 1, matcher, &things[MAX_QUEUE_SIZE - 1]);
|
||||
EQUAL(p, &things[MAX_QUEUE_SIZE - 1]);
|
||||
EQUAL(queue.num_items, MAX_QUEUE_SIZE - 1);
|
||||
p = unqueue_matching(&queue, /*max_queue=*/ MAX_QUEUE_SIZE - 2, matcher, &things[0]);
|
||||
EQUAL(p, NULL);
|
||||
p = unqueue_matching(&queue, /*max_queue=*/ MAX_QUEUE_SIZE - 1, matcher, &things[0]);
|
||||
EQUAL(p, &things[0]);
|
||||
EQUAL(queue.num_items, MAX_QUEUE_SIZE - 2);
|
||||
|
||||
// fill the queue then remove every other item
|
||||
init_queue(&queue);
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
{
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
|
||||
EQUAL(p, NULL);
|
||||
for (int i = MAX_QUEUE_SIZE - 1; i >= 0; i -= 2)
|
||||
{
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &things[i]);
|
||||
EQUAL(p, &things[i]);
|
||||
}
|
||||
EQUAL(queue.num_items, MAX_QUEUE_SIZE / 2);
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
|
||||
EQUAL(p, NULL);
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; i += 2)
|
||||
{
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[i]);
|
||||
}
|
||||
EQUAL(queue.num_items, 0);
|
||||
|
||||
// fill the queue then remove every third item
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (!put_queue(&queue, &things[i]))
|
||||
{
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
|
||||
EQUAL(p, NULL);
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; i += 3)
|
||||
{
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &things[i]);
|
||||
EQUAL(p, &things[i]);
|
||||
}
|
||||
EQUAL(queue.num_items, MAX_QUEUE_SIZE * 2 / 3);
|
||||
p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1);
|
||||
EQUAL(p, NULL);
|
||||
for (int i = 0; i < MAX_QUEUE_SIZE; ++i)
|
||||
{
|
||||
if (i % 3 == 0)
|
||||
continue;
|
||||
p = get_queue(&queue);
|
||||
EQUAL(p, &things[i]);
|
||||
}
|
||||
EQUAL(queue.num_items, 0);
|
||||
|
||||
if (!pass)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
opts=(
|
||||
-Wall -Werror
|
||||
-Wno-error=int-to-pointer-cast
|
||||
-Wno-int-to-pointer-cast
|
||||
-DUNITTEST
|
||||
)
|
||||
|
||||
set -x
|
||||
|
||||
gcc "${opts[@]}" -fsanitize=address -o queue_test queue_test.c queue.c || exit
|
||||
./queue_test || exit
|
||||
|
||||
gcc "${opts[@]}" -o queue_test queue_test.c queue.c || exit
|
||||
valgrind ./queue_test || exit
|
||||
|
||||
: PASS
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file l2_interface.c
|
||||
* \brief layer 2 interface
|
||||
* \author Navid Nikaein and Raymond Knopp
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform_types.h"
|
||||
#include "openair_defs.h"
|
||||
|
||||
#ifdef CELLULAR
|
||||
#include "rrc_L2_proto.h"
|
||||
#else
|
||||
#include "RRC/LTE/defs.h"
|
||||
#endif //CELLULAR
|
||||
#include "COMMON/mac_rrc_primitives.h"
|
||||
#include "openair_rrc_L2_interface.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int8_t
|
||||
mac_rrc_data_req(
|
||||
const module_id_t module_idP,
|
||||
const int CC_idP,
|
||||
const frame_t frameP,
|
||||
const rb_id_t srb_idP,
|
||||
const uint8_t nb_tbP,
|
||||
uint8_t* const buffer_pP,
|
||||
const eNB_flag_t eNB_flagP,
|
||||
const uint8_t eNB_indexP,
|
||||
const uint8_t mbsfn_sync_areaP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return(mac_rrc_lite_data_req(
|
||||
module_idP,
|
||||
CC_idP,
|
||||
frameP,
|
||||
srb_idP,
|
||||
nb_tbP,
|
||||
buffer_pP,
|
||||
eNB_flagP,
|
||||
eNB_indexP,
|
||||
mbsfn_sync_areaP)
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*int8_t
|
||||
mac_rrc_data_ind(
|
||||
const module_id_t module_idP,
|
||||
const int CC_idP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t subframeP,
|
||||
const rnti_t rntiP,
|
||||
const rb_id_t srb_idP,
|
||||
const uint8_t *sduP,
|
||||
const sdu_size_t sdu_lenP,
|
||||
const eNB_flag_t eNB_flagP,
|
||||
const mac_enb_index_t eNB_indexP,
|
||||
const uint8_t mbsfn_sync_area
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return(mac_rrc_lite_data_ind(
|
||||
module_idP,
|
||||
CC_idP,
|
||||
frameP,subframeP,
|
||||
rntiP,
|
||||
srb_idP,
|
||||
sduP,
|
||||
sdu_lenP,
|
||||
eNB_flagP,
|
||||
eNB_indexP,
|
||||
mbsfn_sync_area)
|
||||
);
|
||||
}*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
rlcrrc_data_ind(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
const rb_id_t srb_idP,
|
||||
const sdu_size_t sdu_lenP,
|
||||
const uint8_t * const buffer_pP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
rrc_data_ind(ctxt_pP,
|
||||
srb_idP,
|
||||
sdu_lenP,
|
||||
buffer_pP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
pdcp_rrc_data_req(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
uint8_t* const sdu_buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return rrc_lite_data_req (
|
||||
ctxt_pP,
|
||||
rb_idP,
|
||||
muiP,
|
||||
confirmP,
|
||||
sdu_buffer_sizeP,
|
||||
sdu_buffer_pP,
|
||||
modeP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
pdcp_rrc_data_ind(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
const rb_id_t srb_idP,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
uint8_t * const buffer_pP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
rrc_lite_data_ind(
|
||||
ctxt_pP,
|
||||
srb_idP,
|
||||
sdu_sizeP,
|
||||
buffer_pP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
mac_rrc_meas_ind(
|
||||
const module_id_t module_idP,
|
||||
MAC_MEAS_REQ_ENTRY * const Meas_entry_pP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
// mac_rrc_meas_ind(module_idP,Meas_entry_pP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
mac_sync_ind(
|
||||
const module_id_t module_idP,
|
||||
const uint8_t Status
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
mac_lite_sync_ind(module_idP,Status);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
mac_in_sync_ind(
|
||||
const module_id_t module_idP,
|
||||
const frame_t frameP,
|
||||
const uint16_t eNB_indexP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
rrc_lite_in_sync_ind(module_idP,frameP,eNB_indexP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
mac_out_of_sync_ind(
|
||||
const module_id_t module_idP,
|
||||
const frame_t frameP,
|
||||
const uint16_t eNB_indexP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
rrc_lite_out_of_sync_ind(module_idP,frameP,eNB_indexP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
mac_eNB_get_rrc_status(
|
||||
const module_id_t module_idP,
|
||||
const rnti_t rntiP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return mac_eNB_get_rrc_lite_status(module_idP, rntiP);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
mac_UE_get_rrc_status(
|
||||
const module_id_t module_idP,
|
||||
const uint8_t sig_indexP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return mac_UE_get_rrc_lite_status(module_idP, sig_indexP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
char
|
||||
openair_rrc_ue_init(
|
||||
const module_id_t module_idP,
|
||||
const unsigned char eNB_indexP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return openair_rrc_lite_ue_init(module_idP, eNB_indexP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
char
|
||||
openair_rrc_eNB_init(
|
||||
const module_id_t module_idP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
return openair_rrc_lite_eNB_init(module_idP);
|
||||
}
|
||||
@@ -317,6 +317,12 @@ mac_rrc_data_ind(
|
||||
sdu_lenP,
|
||||
NULL,
|
||||
0);
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[module_idP]);
|
||||
ue_context_p->ue_id_rnti = rntiP;
|
||||
ue_context_p->ue_context.rnti = rntiP;
|
||||
ue_context_p->ue_context.random_ue_identity = rntiP;
|
||||
ue_context_p->ue_context.Srb0.Active = 1;
|
||||
RB_INSERT(rrc_ue_tree_s, &RC.rrc[module_idP]->rrc_ue_head, ue_context_p);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2129,7 +2129,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) {
|
||||
uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
uint8_t buf[5],buf2=0;
|
||||
LTE_UL_CCCH_Message_t ul_ccch_msg;
|
||||
@@ -2178,7 +2178,7 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) {
|
||||
NULL,
|
||||
(void *)&ul_ccch_msg,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
LOG_D(RRC,"[UE] RRCConnectionRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
@@ -2378,12 +2378,39 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
static void assign_scg_ConfigResponseNR_r15(LTE_RRCConnectionReconfigurationComplete_t *rrc, OCTET_STRING_t *str)
|
||||
{
|
||||
LTE_RRCConnectionReconfigurationComplete_r8_IEs_t *rrc_r8 = &rrc->criticalExtensions.choice.
|
||||
rrcConnectionReconfigurationComplete_r8;
|
||||
typeof(rrc_r8->nonCriticalExtension) nce1;
|
||||
rrc_r8->nonCriticalExtension = nce1 = CALLOC(1, sizeof(*nce1));
|
||||
|
||||
typeof(nce1->nonCriticalExtension) nce2;
|
||||
nce1->nonCriticalExtension = nce2 = CALLOC(1, sizeof(*nce2));
|
||||
|
||||
typeof(nce2->nonCriticalExtension) nce3;
|
||||
nce2->nonCriticalExtension = nce3 = CALLOC(1, sizeof(*nce3));
|
||||
|
||||
typeof(nce3->nonCriticalExtension) nce4;
|
||||
nce3->nonCriticalExtension = nce4 = CALLOC(1, sizeof(*nce4));
|
||||
|
||||
typeof(nce4->nonCriticalExtension) nce5;
|
||||
nce4->nonCriticalExtension = nce5 = CALLOC(1, sizeof(*nce5));
|
||||
|
||||
typeof(nce5->nonCriticalExtension) nce6;
|
||||
nce5->nonCriticalExtension = nce6 = CALLOC(1, sizeof(*nce6));
|
||||
|
||||
nce6->scg_ConfigResponseNR_r15 = str;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
size_t
|
||||
do_RRCConnectionReconfigurationComplete(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
const uint8_t Transaction_id
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
OCTET_STRING_t *str
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -2397,7 +2424,13 @@ do_RRCConnectionReconfigurationComplete(
|
||||
rrcConnectionReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id;
|
||||
rrcConnectionReconfigurationComplete->criticalExtensions.present =
|
||||
LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8;
|
||||
rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL;
|
||||
if (str != NULL) {
|
||||
assign_scg_ConfigResponseNR_r15(rrcConnectionReconfigurationComplete, str);
|
||||
LOG_D(RRC, "Successfully assigned scg_ConfigResponseNR_r15\n");
|
||||
}
|
||||
else {
|
||||
rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL;
|
||||
}
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg);
|
||||
@@ -2407,7 +2440,7 @@ do_RRCConnectionReconfigurationComplete(
|
||||
NULL,
|
||||
(void *)&ul_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
LOG_D(RRC,"RRCConnectionReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||
@@ -3142,6 +3175,7 @@ uint8_t do_RRCConnectionSetup_BR(
|
||||
uint8_t do_SecurityModeCommand(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
const uint8_t integrityProtAlgorithm
|
||||
@@ -3171,7 +3205,7 @@ uint8_t do_SecurityModeCommand(
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -3200,6 +3234,7 @@ uint8_t do_SecurityModeCommand(
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band)
|
||||
@@ -3220,58 +3255,56 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0;
|
||||
ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list,
|
||||
&rat);
|
||||
|
||||
/* request NR configuration */
|
||||
LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8;
|
||||
LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0;
|
||||
LTE_UECapabilityEnquiry_v1180_IEs_t r11_80;
|
||||
LTE_UECapabilityEnquiry_v1310_IEs_t r13_10;
|
||||
LTE_UECapabilityEnquiry_v1430_IEs_t r14_30;
|
||||
LTE_UECapabilityEnquiry_v1510_IEs_t r15_10;
|
||||
OCTET_STRING_t req_freq;
|
||||
|
||||
if (nr_band>0) {
|
||||
memset(&r8_a0, 0, sizeof(r8_a0));
|
||||
memset(&r11_80, 0, sizeof(r11_80));
|
||||
memset(&r13_10, 0, sizeof(r13_10));
|
||||
memset(&r14_30, 0, sizeof(r14_30));
|
||||
memset(&r15_10, 0, sizeof(r15_10));
|
||||
|
||||
/* request NR configuration */
|
||||
r8->nonCriticalExtension = &r8_a0;
|
||||
r8_a0.nonCriticalExtension = &r11_80;
|
||||
r11_80.nonCriticalExtension = &r13_10;
|
||||
r13_10.nonCriticalExtension = &r14_30;
|
||||
r14_30.nonCriticalExtension = &r15_10;
|
||||
|
||||
memset(&r8_a0, 0, sizeof(r8_a0));
|
||||
memset(&r11_80, 0, sizeof(r11_80));
|
||||
memset(&r13_10, 0, sizeof(r13_10));
|
||||
memset(&r14_30, 0, sizeof(r14_30));
|
||||
memset(&r15_10, 0, sizeof(r15_10));
|
||||
/* TODO: no hardcoded values here */
|
||||
|
||||
r8->nonCriticalExtension = &r8_a0;
|
||||
r8_a0.nonCriticalExtension = &r11_80;
|
||||
r11_80.nonCriticalExtension = &r13_10;
|
||||
r13_10.nonCriticalExtension = &r14_30;
|
||||
r14_30.nonCriticalExtension = &r15_10;
|
||||
nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
|
||||
|
||||
/* TODO: no hardcoded values here */
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA;
|
||||
nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t));
|
||||
nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
|
||||
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA;
|
||||
nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t));
|
||||
nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR;
|
||||
nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t));
|
||||
//if(nr_band > 0)
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR;
|
||||
nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t));
|
||||
if(nr_band > 0)
|
||||
nsa_band->choice.bandInformationNR->bandNR = nr_band;
|
||||
//else
|
||||
// nsa_band->choice.bandInformationNR->bandNR = 78;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
else
|
||||
nsa_band->choice.bandInformationNR->bandNR = 78;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
OCTET_STRING_t req_freq;
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78
|
||||
unsigned char req_freq_buf[1024];
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList,
|
||||
NULL,
|
||||
(void *)nsa_band_list,
|
||||
req_freq_buf,
|
||||
1024);
|
||||
unsigned char req_freq_buf[1024];
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList,
|
||||
NULL,
|
||||
(void *)nsa_band_list,
|
||||
req_freq_buf,
|
||||
1024);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list);
|
||||
xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list);
|
||||
|
||||
|
||||
|
||||
@@ -3282,22 +3315,20 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
//0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a
|
||||
// };
|
||||
|
||||
req_freq.buf = req_freq_buf;
|
||||
req_freq.size = (enc_rval.encoded+7)/8;
|
||||
req_freq.buf = req_freq_buf;
|
||||
req_freq.size = (enc_rval.encoded+7)/8;
|
||||
// req_freq.size = 21;
|
||||
|
||||
r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
|
||||
// Add request for eutra-nr
|
||||
}
|
||||
// if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
// }
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -3324,6 +3355,7 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band)
|
||||
@@ -3417,7 +3449,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -3444,6 +3476,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id,
|
||||
LTE_SRB_ToAddModList_t *SRB_list,
|
||||
LTE_DRB_ToAddModList_t *DRB_list,
|
||||
@@ -3545,7 +3578,7 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
RRC_BUF_SIZE);
|
||||
buffer_size);
|
||||
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) ) {
|
||||
@@ -3562,6 +3595,7 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const
|
||||
*/
|
||||
uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id,
|
||||
LTE_SRB_ToAddModList_t *SRB_list,
|
||||
LTE_DRB_ToAddModList_t *DRB_list,
|
||||
@@ -3722,7 +3756,7 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
RRC_BUF_SIZE);
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -3977,6 +4011,7 @@ uint8_t do_RRCConnectionReject(uint8_t Mod_id,
|
||||
|
||||
uint8_t do_RRCConnectionRelease(uint8_t Mod_id,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
LTE_DL_DCCH_Message_t dl_dcch_msg;
|
||||
@@ -3998,7 +4033,7 @@ uint8_t do_RRCConnectionRelease(uint8_t Mod_id,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
RRC_BUF_SIZE);
|
||||
buffer_size);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -4008,6 +4043,7 @@ uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 1
|
||||
uint8_t do_MBSFNAreaConfig(uint8_t Mod_id,
|
||||
uint8_t sync_area,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
LTE_MCCH_Message_t *mcch_message,
|
||||
LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
@@ -4114,7 +4150,7 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id,
|
||||
NULL,
|
||||
(void *)mcch_message,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -4133,7 +4169,9 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id,
|
||||
}
|
||||
|
||||
|
||||
uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t) {
|
||||
uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
int measid, int phy_id, long rsrp_s, long rsrq_s,
|
||||
long rsrp_t, long rsrq_t) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
LTE_UL_DCCH_Message_t ul_dcch_msg;
|
||||
LTE_MeasurementReport_t *measurementReport;
|
||||
@@ -4205,7 +4243,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_
|
||||
NULL,
|
||||
(void *)&ul_dcch_msg,
|
||||
buffer,
|
||||
100);
|
||||
buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -4220,6 +4258,64 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
#define asn1cCallocOne(VaR, VaLue) \
|
||||
VaR = calloc(1,sizeof(*VaR)); *VaR=VaLue;
|
||||
#define asn1cCalloc(VaR, lOcPtr) \
|
||||
typeof(VaR) lOcPtr = VaR = calloc(1,sizeof(*VaR));
|
||||
#define asn1cSequenceAdd(VaR, TyPe, lOcPtr) \
|
||||
TyPe *lOcPtr= calloc(1,sizeof(TyPe)); \
|
||||
ASN_SEQUENCE_ADD(&VaR,lOcPtr);
|
||||
|
||||
ssize_t do_nrMeasurementReport(uint8_t *buffer,
|
||||
size_t bufsize,
|
||||
LTE_MeasId_t measid,
|
||||
LTE_PhysCellIdNR_r15_t phy_id,
|
||||
long rsrp_s,
|
||||
long rsrq_s,
|
||||
long rsrp_tar,
|
||||
long rsrq_tar) {
|
||||
|
||||
LTE_UL_DCCH_Message_t ul_dcch_msg={0};
|
||||
ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1;
|
||||
ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_measurementReport;
|
||||
|
||||
LTE_MeasurementReport_t *measurementReport = &ul_dcch_msg.message.choice.c1.choice.measurementReport;
|
||||
measurementReport->criticalExtensions.present = LTE_MeasurementReport__criticalExtensions_PR_c1;
|
||||
measurementReport->criticalExtensions.choice.c1.present = LTE_MeasurementReport__criticalExtensions__c1_PR_measurementReport_r8;
|
||||
measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension =
|
||||
calloc(1, sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension));
|
||||
measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measId = measid;
|
||||
measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrpResult = rsrp_s;
|
||||
measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrqResult = rsrq_s;
|
||||
asn1cCalloc(measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells,
|
||||
measResultNeighCells);
|
||||
measResultNeighCells->present = LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15;
|
||||
LTE_MeasResultListEUTRA_t *measResultListEUTRA2=&measResultNeighCells->choice.measResultListEUTRA;
|
||||
asn1cSequenceAdd(measResultListEUTRA2->list, struct LTE_MeasResultEUTRA, measresulteutra_list);
|
||||
measresulteutra_list->physCellId = phy_id;
|
||||
asn1cCalloc(measresulteutra_list->cgi_Info, measresult_cgi2);
|
||||
//measresult_cgi2->cellGlobalId= {0};
|
||||
//measresult_cgi2->trackingAreaCode= {0};
|
||||
struct LTE_MeasResultEUTRA__measResult* measResult= &measresulteutra_list->measResult;
|
||||
asn1cCallocOne(measResult->rsrpResult, rsrp_tar);
|
||||
asn1cCallocOne(measResult->rsrqResult, rsrq_tar);
|
||||
|
||||
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message,
|
||||
NULL,
|
||||
&ul_dcch_msg,
|
||||
buffer,
|
||||
bufsize);
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal] ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
SEQUENCE_free(&asn_DEF_LTE_UL_DCCH_Message, &ul_dcch_msg, ASFM_FREE_UNDERLYING_AND_RESET);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer) {
|
||||
ssize_t encoded;
|
||||
LTE_DL_DCCH_Message_t dl_dcch_msg;
|
||||
@@ -4237,7 +4333,8 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans
|
||||
return encoded;
|
||||
}
|
||||
|
||||
uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain) {
|
||||
uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain) {
|
||||
LOG_D(RRC, "[eNB %d] do_Paging start\n", Mod_id);
|
||||
asn_enc_rval_t enc_rval;
|
||||
LTE_PCCH_Message_t pcch_msg;
|
||||
@@ -4289,7 +4386,8 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin
|
||||
ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list, paging_record_p);
|
||||
LOG_D(RRC, "[eNB %d] do_Paging paging_record: cn_Domain %ld, ue_paging_identity.presenceMask %d, PagingRecordList.count %d\n",
|
||||
Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count);
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE);
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void *)&pcch_msg,
|
||||
buffer, buffer_size);
|
||||
|
||||
if(enc_rval.encoded == -1) {
|
||||
LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
|
||||
@@ -4378,7 +4476,161 @@ int do_HandoverCommand(char *ho_buf, int ho_size, char *rrc_buf, int rrc_size) {
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) {
|
||||
//-----------------------------------------------------------------------------
|
||||
int
|
||||
is_en_dc_supported(
|
||||
LTE_UE_EUTRA_Capability_t *c
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
LOG_D(RRC, "Entered %s \n", __FUNCTION__);
|
||||
/* to be refined - check that the bands supported by the UE include
|
||||
* the band of the gNB
|
||||
*/
|
||||
#define NCE nonCriticalExtension
|
||||
return c != NULL
|
||||
&& c->NCE != NULL
|
||||
&& c->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15 != NULL
|
||||
&& c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 != NULL
|
||||
&& *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 ==
|
||||
LTE_IRAT_ParametersNR_r15__en_DC_r15_supported;
|
||||
#undef NCE
|
||||
}
|
||||
|
||||
void allocate_en_DC_r15(LTE_UE_EUTRA_Capability_t *cap)
|
||||
{
|
||||
LOG_D(RRC, "Entered %s\n", __FUNCTION__);
|
||||
if (!cap->nonCriticalExtension)
|
||||
cap->nonCriticalExtension = CALLOC(1, sizeof(*cap->nonCriticalExtension));
|
||||
|
||||
typeof(cap->nonCriticalExtension) nce1 = cap->nonCriticalExtension;
|
||||
if (!nce1->nonCriticalExtension)
|
||||
nce1->nonCriticalExtension = CALLOC(1, sizeof(*nce1->nonCriticalExtension));
|
||||
|
||||
typeof(nce1->nonCriticalExtension) nce2 = nce1->nonCriticalExtension;
|
||||
if (!nce2->nonCriticalExtension)
|
||||
nce2->nonCriticalExtension = CALLOC(1, sizeof(*nce2->nonCriticalExtension));
|
||||
|
||||
typeof(nce2->nonCriticalExtension) nce3 = nce2->nonCriticalExtension;
|
||||
if (!nce3->nonCriticalExtension)
|
||||
nce3->nonCriticalExtension = CALLOC(1, sizeof(*nce3->nonCriticalExtension));
|
||||
|
||||
typeof(nce3->nonCriticalExtension) nce4 = nce3->nonCriticalExtension;
|
||||
if (!nce4->nonCriticalExtension)
|
||||
nce4->nonCriticalExtension = CALLOC(1, sizeof(*nce4->nonCriticalExtension));
|
||||
|
||||
typeof(nce4->nonCriticalExtension) nce5 = nce4->nonCriticalExtension;
|
||||
if (!nce5->nonCriticalExtension)
|
||||
nce5->nonCriticalExtension = CALLOC(1, sizeof(*nce5->nonCriticalExtension));
|
||||
|
||||
typeof(nce5->nonCriticalExtension) nce6 = nce5->nonCriticalExtension;
|
||||
if (!nce6->nonCriticalExtension)
|
||||
nce6->nonCriticalExtension = CALLOC(1, sizeof(*nce6->nonCriticalExtension));
|
||||
|
||||
typeof(nce6->nonCriticalExtension) nce7 = nce6->nonCriticalExtension;
|
||||
if (!nce7->nonCriticalExtension)
|
||||
nce7->nonCriticalExtension = CALLOC(1, sizeof(*nce7->nonCriticalExtension));
|
||||
|
||||
typeof(nce7->nonCriticalExtension) nce8 = nce7->nonCriticalExtension;
|
||||
if (!nce8->nonCriticalExtension)
|
||||
nce8->nonCriticalExtension = CALLOC(1, sizeof(*nce8->nonCriticalExtension));
|
||||
|
||||
typeof(nce8->nonCriticalExtension) nce9 = nce8->nonCriticalExtension;
|
||||
if (!nce9->nonCriticalExtension)
|
||||
nce9->nonCriticalExtension = CALLOC(1, sizeof(*nce9->nonCriticalExtension));
|
||||
|
||||
typeof(nce9->nonCriticalExtension) nce10 = nce9->nonCriticalExtension;
|
||||
if (!nce10->nonCriticalExtension)
|
||||
nce10->nonCriticalExtension = CALLOC(1, sizeof(*nce10->nonCriticalExtension));
|
||||
|
||||
typeof(nce10->nonCriticalExtension) nce11 = nce10->nonCriticalExtension;
|
||||
if (!nce11->nonCriticalExtension)
|
||||
nce11->nonCriticalExtension = CALLOC(1, sizeof(*nce11->nonCriticalExtension));
|
||||
|
||||
typeof(nce11->nonCriticalExtension) nce12 = nce11->nonCriticalExtension;
|
||||
if (!nce12->nonCriticalExtension)
|
||||
nce12->nonCriticalExtension = CALLOC(1, sizeof(*nce12->nonCriticalExtension));
|
||||
|
||||
typeof(nce12->nonCriticalExtension) nce13 = nce12->nonCriticalExtension;
|
||||
if (!nce13->nonCriticalExtension)
|
||||
nce13->nonCriticalExtension = CALLOC(1, sizeof(*nce13->nonCriticalExtension));
|
||||
|
||||
typeof(nce13->nonCriticalExtension) nce14 = nce13->nonCriticalExtension;
|
||||
if (!nce14->nonCriticalExtension)
|
||||
nce14->nonCriticalExtension = CALLOC(1, sizeof(*nce14->nonCriticalExtension));
|
||||
|
||||
typeof(nce14->nonCriticalExtension) nce15 = nce14->nonCriticalExtension;
|
||||
if (!nce15->nonCriticalExtension)
|
||||
nce15->nonCriticalExtension = CALLOC(1, sizeof(*nce15->nonCriticalExtension));
|
||||
|
||||
typeof(nce15->nonCriticalExtension) nce16 = nce15->nonCriticalExtension;
|
||||
if (!nce16->nonCriticalExtension)
|
||||
nce16->nonCriticalExtension = CALLOC(1, sizeof(*nce16->nonCriticalExtension));
|
||||
|
||||
typeof(nce16->nonCriticalExtension) nce17 = nce16->nonCriticalExtension;
|
||||
if (!nce17->nonCriticalExtension)
|
||||
nce17->nonCriticalExtension = CALLOC(1, sizeof(*nce17->nonCriticalExtension));
|
||||
|
||||
typeof(nce17->nonCriticalExtension) nce18 = nce17->nonCriticalExtension;
|
||||
if (!nce18->nonCriticalExtension)
|
||||
nce18->nonCriticalExtension = CALLOC(1, sizeof(*nce18->nonCriticalExtension));
|
||||
|
||||
typeof(nce18->nonCriticalExtension) nce19 = nce18->nonCriticalExtension;
|
||||
if (!nce19->nonCriticalExtension)
|
||||
nce19->nonCriticalExtension = CALLOC(1, sizeof(*nce19->nonCriticalExtension));
|
||||
|
||||
typeof(nce19->nonCriticalExtension) nce20 = nce19->nonCriticalExtension;
|
||||
if (!nce20->nonCriticalExtension)
|
||||
nce20->nonCriticalExtension = CALLOC(1, sizeof(*nce20->nonCriticalExtension));
|
||||
|
||||
typeof(nce20->nonCriticalExtension) nce21 = nce20->nonCriticalExtension;
|
||||
if (!nce21->nonCriticalExtension)
|
||||
nce21->nonCriticalExtension = CALLOC(1, sizeof(*nce21->nonCriticalExtension));
|
||||
|
||||
typeof(nce21->nonCriticalExtension) nce22 = nce21->nonCriticalExtension;
|
||||
if (!nce22->nonCriticalExtension)
|
||||
nce22->nonCriticalExtension = CALLOC(1, sizeof(*nce22->nonCriticalExtension));
|
||||
|
||||
typeof(nce22->nonCriticalExtension) nce23 = nce22->nonCriticalExtension;
|
||||
if (!nce23->nonCriticalExtension)
|
||||
nce23->nonCriticalExtension = CALLOC(1, sizeof(*nce23->nonCriticalExtension));
|
||||
|
||||
typeof(nce23->nonCriticalExtension) nce24 = nce23->nonCriticalExtension;
|
||||
if (!nce24->irat_ParametersNR_r15)
|
||||
nce24->irat_ParametersNR_r15 = CALLOC(1, sizeof(*nce24->irat_ParametersNR_r15));
|
||||
|
||||
typeof(nce24->irat_ParametersNR_r15) irat = nce24->irat_ParametersNR_r15;
|
||||
if (!irat->en_DC_r15)
|
||||
irat->en_DC_r15 = CALLOC(1, sizeof(*irat->en_DC_r15));
|
||||
|
||||
*irat->en_DC_r15 = LTE_IRAT_ParametersNR_r15__en_DC_r15_supported;
|
||||
|
||||
}
|
||||
|
||||
OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname, bool received_nr_msg) {
|
||||
static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */
|
||||
static LTE_SupportedBandEUTRA_t Bandlist[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it
|
||||
static LTE_InterFreqBandInfo_t InterFreqBandInfo[4][4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it
|
||||
@@ -4476,7 +4728,13 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) {
|
||||
UE_EUTRA_Capability->featureGroupIndicators = bit_string;
|
||||
}
|
||||
|
||||
// UE_EUTRA_Capability->interRAT_Parameters // null
|
||||
if (get_softmodem_params()->nsa && received_nr_msg)
|
||||
{
|
||||
allocate_en_DC_r15(UE_EUTRA_Capability);
|
||||
if (!is_en_dc_supported(UE_EUTRA_Capability)){
|
||||
LOG_E(RRC, "We did not properly allocate en_DC_r15 for UE_EUTRA_Capability\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FILE *f = fopen(UE_EUTRA_Capability_xer_fname, "r");
|
||||
assert(f);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "RRC/LTE/rrc_defs.h"
|
||||
#include "LTE_SL-DestinationInfoList-r12.h"
|
||||
#include "OctetString.h"
|
||||
|
||||
/*
|
||||
* The variant of the above function which dumps the BASIC-XER (XER_F_BASIC)
|
||||
@@ -52,6 +53,14 @@
|
||||
*/
|
||||
int xer_sprint(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr);
|
||||
|
||||
#define asn1cCallocOne(VaR, VaLue) \
|
||||
VaR = calloc(1,sizeof(*VaR)); *VaR=VaLue;
|
||||
#define asn1cCalloc(VaR, lOcPtr) \
|
||||
typeof(VaR) lOcPtr = VaR = calloc(1,sizeof(*VaR));
|
||||
#define asn1cSequenceAdd(VaR, TyPe, lOcPtr) \
|
||||
TyPe *lOcPtr= calloc(1,sizeof(TyPe)); \
|
||||
ASN_SEQUENCE_ADD(&VaR,lOcPtr);
|
||||
|
||||
uint16_t get_adjacent_cell_id(uint8_t Mod_id,uint8_t index);
|
||||
|
||||
uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId);
|
||||
@@ -129,7 +138,7 @@ routine only generates an mo-data establishment cause.
|
||||
@param rv 5 byte random string or S-TMSI
|
||||
@returns Size of encoded bit stream in bytes*/
|
||||
|
||||
uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv);
|
||||
uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv);
|
||||
|
||||
/**
|
||||
\brief Generate an SidelinkUEInformation UL-DCCH-Message (UE).
|
||||
@@ -156,7 +165,9 @@ uint8_t
|
||||
do_RRCConnectionReconfigurationComplete(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
const uint8_t Transaction_id
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
OCTET_STRING_t *str
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -204,6 +215,7 @@ uint16_t
|
||||
do_RRCConnectionReconfiguration_BR(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id,
|
||||
LTE_SRB_ToAddModList_t *SRB_list,
|
||||
LTE_DRB_ToAddModList_t *DRB_list,
|
||||
@@ -249,6 +261,7 @@ uint16_t
|
||||
do_RRCConnectionReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id,
|
||||
LTE_SRB_ToAddModList_t *SRB_list,
|
||||
LTE_DRB_ToAddModList_t *DRB_list,
|
||||
@@ -322,14 +335,8 @@ routine only generates an mo-data establishment cause.
|
||||
@param transaction_id Transaction index
|
||||
@returns Size of encoded bit stream in bytes*/
|
||||
|
||||
uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer,int Transaction_id);
|
||||
uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, int Transaction_id);
|
||||
|
||||
/***
|
||||
* \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data)
|
||||
* @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU
|
||||
* @returns Size of encoded bit stream in bytes
|
||||
*/
|
||||
uint8_t do_MCCHMessage(uint8_t *buffer);
|
||||
/***
|
||||
* \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data)
|
||||
* @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU
|
||||
@@ -338,14 +345,28 @@ uint8_t do_MCCHMessage(uint8_t *buffer);
|
||||
uint8_t do_MBSFNAreaConfig(uint8_t Mod_id,
|
||||
uint8_t sync_area,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
LTE_MCCH_Message_t *mcch_message,
|
||||
LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration);
|
||||
|
||||
uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t);
|
||||
ssize_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
int measid, int phy_id,
|
||||
long rsrp_s, long rsrq_s,
|
||||
long rsrp_t, long rsrq_t);
|
||||
|
||||
ssize_t do_nrMeasurementReport(uint8_t *buffer,
|
||||
size_t bufsize,
|
||||
LTE_MeasId_t measid,
|
||||
LTE_PhysCellIdNR_r15_t phy_id,
|
||||
long rsrp_s,
|
||||
long rsrq_s,
|
||||
long rsrp_tar,
|
||||
long rsrq_tar);
|
||||
|
||||
uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer);
|
||||
|
||||
uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain);
|
||||
uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain);
|
||||
|
||||
uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer);
|
||||
|
||||
@@ -353,12 +374,17 @@ int do_HandoverPreparation(char *ho_buf, int ho_size, LTE_UE_EUTRA_Capability_t
|
||||
|
||||
int do_HandoverCommand(char *ho_buf, int ho_size, char *rrc_buf, int rrc_size);
|
||||
|
||||
OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer);
|
||||
OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer, bool received_nr_msg);
|
||||
|
||||
int is_en_dc_supported(LTE_UE_EUTRA_Capability_t *c);
|
||||
|
||||
void allocate_en_DC_r15(LTE_UE_EUTRA_Capability_t *cap);
|
||||
|
||||
uint8_t
|
||||
do_UECapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band);
|
||||
@@ -367,6 +393,7 @@ uint8_t
|
||||
do_NR_UECapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band);
|
||||
@@ -374,6 +401,7 @@ do_NR_UECapabilityEnquiry(
|
||||
uint8_t do_SecurityModeCommand(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
const uint8_t integrityProtAlgorithm);
|
||||
|
||||
@@ -834,6 +834,7 @@ uint8_t do_UECapabilityEnquiry_NB_IoT(
|
||||
uint16_t do_RRCConnectionReconfiguration_NB_IoT(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id,
|
||||
LTE_SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1
|
||||
LTE_DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default)
|
||||
@@ -886,7 +887,7 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT(
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg_NB_IoT,
|
||||
buffer,
|
||||
RRC_BUF_SIZE);
|
||||
buffer_size);
|
||||
|
||||
if (enc_rval.encoded <= 0) {
|
||||
LOG_E(RRC, "ASN1 message encoding failed %s, %li\n",
|
||||
@@ -1020,7 +1021,8 @@ uint8_t do_DLInformationTransfer_NB_IoT(
|
||||
/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use?
|
||||
uint8_t do_RRCConnectionReestablishment_NB_IoT(
|
||||
uint8_t Mod_id,
|
||||
uint8_t *const buffer,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
const NB_IoT_DL_FRAME_PARMS *const frame_parms, //to be changed
|
||||
LTE_SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT) { //should contain SRB1 already configured?
|
||||
@@ -1046,7 +1048,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT(
|
||||
NULL,
|
||||
(void *)&dl_ccch_msg_NB_IoT,
|
||||
buffer,
|
||||
RRC_BUF_SIZE);
|
||||
buffer_size);
|
||||
|
||||
if (enc_rval.encoded <= 0) {
|
||||
LOG_E(RRC, "ASN1 message encoding failed (%s, %li)!\n",
|
||||
@@ -1065,6 +1067,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT(
|
||||
uint8_t do_RRCConnectionRelease_NB_IoT(
|
||||
uint8_t Mod_id,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
|
||||
@@ -1087,7 +1090,7 @@ uint8_t do_RRCConnectionRelease_NB_IoT(
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg_NB_IoT,
|
||||
buffer,
|
||||
RRC_BUF_SIZE);//check
|
||||
buffer_size);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
|
||||
@@ -125,10 +125,12 @@ uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, co
|
||||
@param Transaction_id
|
||||
@returns Size of encoded bit stream in bytes*/
|
||||
|
||||
uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT(
|
||||
size_t do_RRCConnectionReconfigurationComplete_NB_IoT(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
uint8_t* buffer,
|
||||
const uint8_t Transaction_id
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
OCTET_STRING_t *str
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -178,6 +180,7 @@ uint16_t
|
||||
do_RRCConnectionReconfiguration_NB_IoT(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
uint8_t Transaction_id,
|
||||
SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT,
|
||||
DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT,
|
||||
@@ -249,8 +252,8 @@ do_RRCConnectionReject_NB_IoT(
|
||||
@param transaction_id Transaction index
|
||||
@returns Size of encoded bit stream in bytes*/
|
||||
|
||||
uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id);
|
||||
|
||||
uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
|
||||
int Transaction_id);
|
||||
|
||||
uint8_t do_DLInformationTransfer_NB_IoT(
|
||||
uint8_t Mod_id,
|
||||
@@ -273,7 +276,8 @@ uint8_t do_DLInformationTransfer_NB_IoT(
|
||||
|
||||
uint8_t do_RRCConnectionReestablishment_NB_IoT(
|
||||
uint8_t Mod_id,
|
||||
uint8_t* const buffer,
|
||||
uint8_t* buffer,
|
||||
size_t buffer_size,
|
||||
const uint8_t Transaction_id,
|
||||
const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed
|
||||
SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user