mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
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>
291 lines
9.0 KiB
C
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
|