#ifndef __SPLIT_HEADERS_H #define __SPLIT_HEADERS_H #include <stdint.h> #include <stdbool.h> #include <openair1/PHY/defs_eNB.h> #define CU_PORT "7878" #define DU_PORT "8787" #define SPLIT73_CU 1 #define SPLIT73_DU 2 extern int split73; #define MTU 65536 #define UDP_TIMEOUT 900000L // in micro second (struct timeval, NOT struct timespec) // linux may timeout for a much longer time (up to 10ms) #define blockAlign 32 //bytes to align memory for SIMD copy (256 bits vectors) // FS6 transport configuration and handler typedef struct { char *sourceIP; char *sourcePort; char *destIP; char *destPort; struct addrinfo *destAddr; int sockHandler; } UDPsock_t; #define CTsentCUv0 0xA500 #define CTsentDUv0 0x5A00 // Main FS6 transport layer header // All packets starts with this header typedef struct commonUDP_s { uint64_t timestamp; // id of the group (subframe for LTE) uint16_t nbBlocks; // total number of blocks for this timestamp uint16_t blockID; // id: 0..nbBocks-1 uint16_t contentType; // defines the content format uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes uint64_t senderClock; } commonUDP_t; // FS6 UL common header (DU to CU) // gives the RACH detection data and is always sent to inform the CU that a subframe arrived typedef struct { uint16_t max_preamble[4]; uint16_t max_preamble_energy[4]; uint16_t max_preamble_delay[4]; uint16_t avg_preamble_energy[4]; } fs6_ul_t; // FS6 DL common header (CU to DU) // gives the DCI configuration from each subframe typedef struct { uint8_t pbch_pdu[4]; int num_pdcch_symbols; int num_dci; DCI_ALLOC_t dci_alloc[8]; int num_mdci; int amp; LTE_eNB_PHICH phich_vars; uint64_t DuClock; uint64_t CuSpentMicroSec; } fs6_dl_t; // a value to type all sub packets, // to detect errors, and to be able to extend to other versions // the first byte of each sub structure should match one of these values enum pckType { fs6UlConfig=25, fs6DlConfig=26, fs6ULConfigCCH=27, fs6ULsch=28, fs6ULcch=29, fs6ULindicationHarq=40, fs6ULindicationSr=41, }; // CU to DU definition of a future UL subframe decode // defines a UE future data plane typedef struct { enum pckType type:8; uint16_t UE_id; int8_t harq_pid; UE_type_t ue_type; uint8_t dci_alloc; uint8_t rar_alloc; SCH_status_t status; uint8_t Msg3_flag; uint8_t subframe; uint32_t frame; uint8_t handled; uint8_t phich_active; uint8_t phich_ACK; uint16_t previous_first_rb; uint32_t B; uint32_t G; UCI_format_t uci_format; uint8_t Or2; uint8_t o_RI[2]; uint8_t o_ACK[4]; uint8_t O_ACK; uint8_t o_RCC; int16_t q_ACK[MAX_ACK_PAYLOAD]; int16_t q_RI[MAX_RI_PAYLOAD]; uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS]; uint8_t ndi; uint8_t round; uint8_t rvidx; uint8_t Nl; uint8_t n_DMRS; uint8_t previous_n_DMRS; uint8_t n_DMRS2; int32_t delta_TF; uint32_t repetition_number ; uint32_t total_number_of_repetitions; uint16_t harq_mask; uint16_t nb_rb; uint8_t Qm; uint16_t first_rb; uint8_t O_RI; uint8_t Or1; uint16_t Msc_initial; uint8_t Nsymb_initial; uint8_t V_UL_DAI; uint8_t srs_active; uint32_t TBS; uint8_t Nsymb_pusch; uint8_t Mlimit; uint8_t max_turbo_iterations; uint8_t bundling; uint16_t beta_offset_cqi_times8; uint16_t beta_offset_ri_times8; uint16_t beta_offset_harqack_times8; uint8_t Msg3_active; uint16_t rnti; uint8_t cyclicShift; uint8_t cooperation_flag; uint8_t num_active_cba_groups; uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; } fs6_dl_ulsched_t; // CU to DU defintion of a DL packet for a given UE // The data itself is padded at the end of this structure typedef struct { enum pckType type:8; int UE_id; int8_t harq_pid; uint16_t rnti; int16_t sqrt_rho_a; int16_t sqrt_rho_b; CEmode_t CEmode:8; uint16_t nb_rb; uint8_t Qm; int8_t Nl; uint8_t pdsch_start; uint8_t sib1_br_flag; uint16_t i0; uint32_t rb_alloc[4]; int dataLen; } fs6_dl_uespec_t; // CU to DU definition of CCH channel typedef struct { int16_t UE_id; LTE_eNB_UCI cch_vars; } fs6_dl_uespec_ulcch_element_t; // header to group all UE CCH channels definitions in one UDP packet typedef struct { enum pckType type:8; int16_t nb_active_ue; } fs6_dl_uespec_ulcch_t; // code internal, not transmitted as this typedef struct { int ta; } ul_propagation_t; // One UE UL data, data plane, UE data appended after the header typedef struct { enum pckType type:8; short UE_id; uint8_t harq_id; uint8_t segment; int segLen; int r_offset; int G; int ulsch_power[2]; uint8_t o_ACK[4]; uint8_t O_ACK; int ta; uint8_t o[MAX_CQI_BYTES]; uint8_t cqi_crc_status; } fs6_ul_uespec_t; // UL UCI (control plane), per UE typedef struct { enum pckType type:8; int UEid; int frame; int subframe; LTE_eNB_UCI uci; uint8_t harq_ack[4]; uint8_t tdd_mapping_mode; uint16_t tdd_multiplexing_mask; unsigned short n0_subband_power_dB; uint16_t rnti; int32_t stat; } fs6_ul_uespec_uci_element_t; // all segments UCI grouped in one UDP packet typedef struct { enum pckType type:8; int16_t nb_active_ue; } fs6_ul_uespec_uci_t; bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result); int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType); int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType); #define initBufferZone(xBuf) \ uint8_t xBuf[FS6_BUF_SIZE]; \ ((commonUDP_t *)xBuf)->nbBlocks=0; #define hUDP(xBuf) ((commonUDP_t *)xBuf) #define hDL(xBuf) ((fs6_dl_t*)(((commonUDP_t *)xBuf)+1)) #define hUL(xBuf) ((fs6_ul_t*)(((commonUDP_t *)xBuf)+1)) #define hDLUE(xBuf) ((fs6_dl_uespec_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) #define hTxULUE(xBuf) ((fs6_dl_ulsched_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) #define hTxULcch(xBuf) ((fs6_dl_uespec_ulcch_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) #define hULUE(xBuf) ((fs6_ul_uespec_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1)) #define hULUEuci(xBuf) ((fs6_ul_uespec_uci_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1)) static inline size_t alignedSize(uint8_t *ptr) { commonUDP_t *header=(commonUDP_t *) ptr; return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign; } static inline void *commonUDPdata(uint8_t *ptr) { return (void *) (((commonUDP_t *)ptr)+1); } void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc); void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat); void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset); void *cu_fs6(void *arg); void *du_fs6(void *arg); void fill_rf_config(RU_t *ru, char *rf_config_file); int init_rf(RU_t *ru); void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc); void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc); void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe); void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); bool dlsch_procedures(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int harq_pid, LTE_eNB_DLSCH_t *dlsch, LTE_eNB_UE_stats *ue_stats) ; void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req); void pdsch_procedures(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int harq_pid, LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1); void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); void uci_procedures(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc); void ocp_rx_prach(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, RU_t *ru, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, uint16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag); void rx_prach0(PHY_VARS_eNB *eNB, RU_t *ru, int frame_prach, int subframe, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, uint16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag, uint8_t ce_level ); void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc); // mistakes in main OAI void phy_init_RU(RU_t *); void fep_full(RU_t *ru, int subframe); void feptx_prec(RU_t *ru,int frame,int subframe); void feptx_ofdm(RU_t *ru, int frame, int subframe); void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern uint16_t sf_ahead; #endif