Files
openairinterface5g/radio/ETHERNET/ethernet_lib.h
Robert Schmidt 6d75ca8e9c Move fhstate into eth structure
fhstate is only used in the ETHERNET library, so move it to a smaller
scope. In AW2S it is write-only, so we can remove it.

Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-07-02 08:46:09 +02:00

291 lines
9.0 KiB
C

/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
/*!
* \brief API to stream I/Q samples over standard ethernet
*/
#ifndef ETHERNET_LIB_H
#define ETHERNET_LIB_H
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include "common/utils/threadPool/notified_fifo.h"
#define MAX_INST 4
#define TX_FLAG 1
#define RX_FLAG 0
#include "if_defs.h"
#define ECPRICOMMON_BYTES 4
#define ECPRIPCID_BYTES 2
#define APP_HEADER_SIZE_BYTES (ECPRICOMMON_BYTES + ECPRIPCID_BYTES + sizeof(openair0_timestamp_t))
#define ECPRIREV 1 // ECPRI Version 1, C=0 - single ECPRI message per OAI TX packet
/*! \brief Structure used for initializing UDP read threads */
typedef struct {
openair0_device_t *device;
int thread_id;
pthread_t pthread;
notifiedFIFO_t *resp;
} udp_ctx_t;
typedef struct fhstate_s {
openair0_timestamp_t TS[8];
openair0_timestamp_t TS0;
openair0_timestamp_t olddeltaTS[8];
openair0_timestamp_t oldTS[8];
openair0_timestamp_t TS_read;
int first_read;
uint32_t *buff[8];
uint32_t buff_size;
int r[8];
int active;
} fhstate_t;
/*!\brief opaque ethernet data structure */
typedef struct {
/*!\brief socket file desc (control)*/
int sockfdc;
/*!\brief number of sockets for user-plane*/
int num_fd;
/*!\brief socket file desc (user)*/
int sockfdd[8];
/*!\brief interface name */
char *if_name;
/*!\brief buffer size */
unsigned int buffer_size;
/*!\brief Fronthaul state */
fhstate_t fhstate;
/*!\brief destination address (control) for UDP socket*/
struct sockaddr_in dest_addrc;
/*!\brief local address (control) for UDP socket*/
struct sockaddr_in local_addrc;
/*!\brief destination address (user) for UDP socket*/
struct sockaddr_in dest_addrd;
/*!\brief local address (user) for UDP socket*/
struct sockaddr_in local_addrd;
/*!\brief address length for both UDP and RAW socket*/
int addr_len;
/*!\brief inteface index for RAW socket*/
struct ifreq if_index;
/*!\brief timeout ms */
unsigned int rx_timeout_ms;
/*!\brief timeout ms */
unsigned int tx_timeout_ms;
/*!\brief runtime flags */
uint32_t flags;
/*!\brief compression enable */
uint32_t compression;
/*!\ time offset between transmiter timestamp and receiver timestamp */
double tdiff;
/*!\ calibration */
int tx_forward_nsamps;
// --------------------------------
// Debug and output control
// --------------------------------
/*!\brief number of I/Q samples to be printed */
int iqdumpcnt;
/*!\brief number of underflows in interface */
int num_underflows;
/*!\brief number of overflows in interface */
int num_overflows;
/*!\brief number of concesutive errors in interface */
int num_seq_errors;
/*!\brief number of errors in interface's receiver */
int num_rx_errors;
/*!\brief number of errors in interface's transmitter */
int num_tx_errors;
/*!brief numerator of sampling rate ratio*/
int sampling_rate_ratio_n;
/*!brief denominator of sampling rate ratio*/
int sampling_rate_ratio_d;
/*!brief the TX/RX timing offset*/
int txrx_offset;
/*!\brief current TX timestamp */
openair0_timestamp_t tx_current_ts;
/*!\brief socket file desc */
openair0_timestamp_t rx_current_ts;
/*!\brief actual number of samples transmitted */
uint64_t tx_actual_nsamps;
/*!\brief actual number of samples received */
uint64_t rx_actual_nsamps;
/*!\brief number of samples to be transmitted */
uint64_t tx_nsamps;
/*!\brief number of samples to be received */
uint64_t rx_nsamps;
/*!\brief number of packets transmitted */
uint64_t tx_count;
/*!\brief number of packets received */
uint64_t rx_count;
/*!\brief TX sequence number*/
uint16_t pck_seq_num;
/*!\brief Current RX sequence number*/
uint16_t pck_seq_num_cur;
/*!\brief Previous RX sequence number */
uint16_t pck_seq_num_prev;
/*!\brief precomputed ethernet header (control) */
struct ether_header ehc;
/*!\brief precomputed ethernet header (data) */
struct ether_header ehd;
/*!\brief local address (user) for RAW socket*/
struct sockaddr_ll local_addrd_ll;
/*!brief UDP TX thread context*/
udp_ctx_t **utx;
} eth_state_t;
/*!\brief packet header */
typedef struct {
/*!\brief packet sequence number max value=packets per frame*/
uint16_t seq_num ;
/*!\brief antenna port used to resynchronize */
uint16_t antenna_id;
/*!\brief packet's timestamp */
openair0_timestamp_t timestamp;
} header_t;
/*!\brief different options for ethernet tuning in socket and driver level */
typedef enum {
MIN_OPT = 0,
/*!\brief socket send buffer size in bytes */
SND_BUF_SIZE,
/*!\brief socket receive buffer size in bytes */
RCV_BUF_SIZE,
/*!\brief receiving timeout */
RCV_TIMEOUT,
/*!\brief sending timeout */
SND_TIMEOUT,
/*!\brief maximun transmission unit size in bytes */
MTU_SIZE,
/*!\brief TX queue length */
TX_Q_LEN,
/*!\brief RX/TX ring parameters of ethernet device */
RING_PAR,
/*!\brief interruptions coalesence mechanism of ethernet device */
COALESCE_PAR,
/*!\brief pause parameters of ethernet device */
PAUSE_PAR,
/*!\brief kernel network receive buffer maximun size */
KERNEL_RCV_BUF_MAX_SIZE,
/*!\brief kernel network send buffer maximun size */
KERNEL_SND_BUF_MAX_SIZE,
MAX_OPT
} eth_opt_t;
/*
#define SND_BUF_SIZE 1
#define RCV_BUF_SIZE 1<<1
#define SND_TIMEOUT 1<<2
#define RCV_TIMEOUT 1<<3
#define MTU_SIZE 1<<4
#define TX_Q_LEN 1<<5
#define RING_PAR 1<<5
#define COALESCE_PAR 1<<6
#define PAUSE_PAR 1<<7
*/
/*!\brief I/Q samples */
typedef struct {
/*!\brief phase */
short i;
/*!\brief quadrature */
short q;
} iqoai_t ;
typedef struct udpTXelem_s {
openair0_device_t *device;
openair0_timestamp_t timestamp;
void **buff;
int fd_ind;
int nant;
int nsamps;
int flags;
} udpTXelem_t;
struct udpTXReqId {
uint64_t TS;
int aid;
int length;
uint16_t spare;
} __attribute__((packed));
union udpTXReqUnion {
struct udpTXReqId s;
uint64_t p;
};
void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag);
unsigned short calc_csum (unsigned short *buf, int nwords);
void dump_dev(openair0_device_t *device);
/*void inline dump_buff(openair0_device_t *device, char *buff,unsigned int tx_rx_flag,int nsamps);
void inline dump_rxcounters(openair0_device_t *device);
void inline dump_txcounters(openair0_device_t *device);
*/
void dump_iqs(char * buff, int iq_cnt);
void *udp_read_thread(void *arg);
void *udp_write_thread(void *arg);
/*! \fn int ethernet_tune (openair0_device_t *device, unsigned int option, int value);
* \brief this function allows you to configure certain ethernet parameters in socket or device level
* \param[in] device device which bears the socket
* \param[in] option of parameter to configure
* \param[in] value of parameter to configure
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int ethernet_tune(openair0_device_t *device, unsigned int option, int value);
/*! \fn int eth_socket_init_udp(openair0_device_t *device)
* \brief initialization of UDP Socket to communicate with one destination
* \param[in] device openair device for which the socket will be created
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int eth_socket_init_udp(openair0_device_t *device);
int trx_eth_write_udp(openair0_device_t *device,
openair0_timestamp_t timestamp,
void **buf,
int fd_ind,
int nsamps,
int flags,
int nant);
int trx_eth_read_udp(openair0_device_t *device, openair0_timestamp_t *timestamp, uint32_t **buff, int nsamps);
int eth_socket_init_raw(openair0_device_t *device);
int trx_eth_write_raw(openair0_device_t *device, openair0_timestamp_t timestamp, void **buff, int nsamps, int cc, int flags);
int trx_eth_read_raw(openair0_device_t *device, openair0_timestamp_t *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_raw_IF4p5(openair0_device_t *device, openair0_timestamp_t timestamp, void **buff, int nsamps, int cc, int flags);
int trx_eth_read_raw_IF4p5(openair0_device_t *device, openair0_timestamp_t *timestamp, void **buff, int nsamps, int cc);
int trx_eth_read_raw_IF5_mobipass(openair0_device_t *device, openair0_timestamp_t *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_udp_IF4p5(openair0_device_t *device, openair0_timestamp_t timestamp, void **buff, int nsamps, int cc, int flags);
int trx_eth_read_udp_IF4p5(openair0_device_t *device, openair0_timestamp_t *timestamp, void **buff, int nsamps, int cc);
int trx_eth_ctlsend_udp(openair0_device_t *device, void *msg, ssize_t msg_len);
int trx_eth_ctlrecv_udp(openair0_device_t *device, void *msg, ssize_t msg_len);
int eth_get_dev_conf_raw(openair0_device_t *device);
int eth_set_dev_conf_raw(openair0_device_t *device);
int eth_get_dev_conf_raw_IF4p5(openair0_device_t *device);
int eth_set_dev_conf_raw_IF4p5(openair0_device_t *device);
#endif