Commit 86592e70 authored by Vaibhav Shrivastava's avatar Vaibhav Shrivastava

Rebased changes of RAN/targets directory

parent 91e97133
/* ********** ********** ********** ********** ********** ********** ********** */
Requirements:
-------------
- Previous kernel module/libraries shall be uninstalled !!!
- cf. command line below "SYRTEM_IQ_uninstall_previous_SW.sh"
./SYRTEM_IQ_unload_previous_SW.sh
- You shall have SYRIQ1.4.6nr.tar.gz
- Ubuntu kernel version is restricted to:
- Kernel 4.15.0-20-lowlatency (Ubuntu 18.04)
- Kernel 4.10.0-42-lowlatency (Ubuntu 17.04)
- Kernel 3.19.0-61-lowlatency (Ubuntu 14.04)
- ADRV9371+ZC706 PCIe board shall be switched on
- PC shall be reboot once ADRV9371+ZC706 PCIe board is switched on
mkdir eur_oai_develop-nr
cd eur_oai_develop-nr
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
cd openairinterface5g
git checkout 375-syrtem-sdr-platform
or
git checkout develop-nr (after merge request accepted)
./targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh
-> Reading package lists... Done
-> Building dependency tree
-> Reading state information... Done
-> linux-headers-4.15.0-20-lowlatency is already the newest version (4.15.0-20.21).
-> 0 upgraded, 0 newly installed, 0 to remove and 327 not upgraded.
-> Previous SYRIQ is loaded!
-> previous SYRIQ is unloaded!
-> previous SYRIQ is uninstall!
-> Previous SYRIQ uninstallation is done
/* ********** ********** ********** ********** ********** ********** ********** */
UE:
---
configuration:
--------------
sudo apt update
sudo apt-get update
tar -xvzf SYRIQ1.4.6nr.tar.gz
./SYRIQplatformR1.4.6nr_install.sh
sudo reboot
sudo lspci -vv | grep Xilinx
sudo lspci -vv -s 02:00.0 | grep LnkSta
sudo lspci -vv -s 03:00.0 | grep LnkSta
sudo lspci -vv -s 02:00.0 | grep Interr
sudo lspci -vv -s 03:00.0 | grep Interr
sudo gedit /usr/local/etc/syriq/cpu-irq.sh
echo '1' > /proc/irq/49/smp_affinity_list
echo '5' > /proc/irq/48/smp_affinity_list
gedit oaienv
export IIOD_REMOTE=192.168.1.11
compilation:
------------
sudo cset shield --reset
cd eur_oai_develop-nr/openairinterface5g/
source oaienv
sudo -E ./cmake_targets/build_oai -c --nrUE -w ADRV9371_ZC706 -I
sudo -E ./cmake_targets/build_oai -c --nrUE -w ADRV9371_ZC706
run:
----
source oaienv
sudo -E /usr/local/etc/syriq/cpu-irq.sh
sudo -E cset shield -e ./targets/bin/nr-uesoftmodem.Rel15 -- --numerology 1 -r 106 -C 3510000000 --loop-memory --rf-config-file /usr/local/etc/syriq/ue.band22.tm1.PRB100.NR40.dat
/* ********** ********** ********** ********** ********** ********** ********** */
gNB:
----
configuration:
--------------
sudo apt update
sudo apt-get update
tar -xvzf SYRIQ1.4.6nr.tar.gz
./SYRIQplatformR1.4.6nr_install.sh
sudo reboot
sudo lspci -vv | grep Xilinx
sudo lspci -vv -s 02:00.0 | grep LnkSta
sudo lspci -vv -s 02:00.0 | grep Interr
sudo gedit /usr/local/etc/syriq/cpu-irq.sh
echo '1' > /proc/irq/46/smp_affinity_list
gedit oaienv
export IIOD_REMOTE=192.168.1.21
compilation:
------------
sudo cset shield --reset
cd eur_oai_develop-nr/openairinterface5g/
source oaienv
sudo -E ./cmake_targets/build_oai -c --gNB -w ADRV9371_ZC706 -I --enable-cpu-affinity
/* CPU available shall be mapped on CPU2 to get_nprocs() number with hyperthreading disabled */
/* because : */
/* - cset shield leave CPU0 for system */
/* - CPU1 is reserved for HwRxTx thread for I/Q acquisition ! */
/* Note: "/usr/local/etc/syriq/cpu-irq.sh" shall be changed if more than 8 cores are used */
/* ie. "cset shield --force --kthread on -c 1-7" where "-c 1-7" reserves CPU1 to CPU7 for application (CPU0 is for system) */
sudo -E ./cmake_targets/build_oai -c --gNB -w ADRV9371_ZC706 --enable-cpu-affinity
run:
----
source oaienv
sudo -E /usr/local/etc/syriq/cpu-irq.sh
sudo -E cset shield -e ./targets/bin/nr-softmodem.Rel15 -- -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf --rf-config-file /usr/local/etc/syriq/gnb.band22.tm1.PRB100.NR40_hwgain15.dat
# Previous SYRIQ uninstall
#!/bin/sh
MODULE="riffa"
KERNEL_VERSION=$(uname -r)
RHR=/etc/redhat-release
sudo apt-get install -y linux-headers-`uname -r`
if lsmod | grep "$MODULE" &> /dev/null ; then
echo "Previous SYRIQ is loaded!"
sudo rmmod $MODULE
echo " -> previous SYRIQ is unloaded!"
sudo rm -f /usr/local/lib/libriffa.so*
sudo rm -f /usr/local/include/riffa.h
sudo rm -f /usr/local/include/riffa_driver.h
sudo rm -f /etc/ld.so.conf.d/riffa.conf
sudo rm -rf /lib/modules/$KERNEL_VERSION/kernel/drivers/riffa
sudo rm -f /etc/udev/rules.d/99-riffa.rules
sudo sed -i '/riffa/d' /etc/modules
sudo ldconfig
sudo depmod
echo " -> previous SYRIQ is uninstall!"
echo "Previous SYRIQ uninstallation is done"
exit 0
else
echo "Previous SYRIQ is not loaded!"
exit 1
fi
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
BladeRF documentation
=====================
As of 2018-11-06, the bladeRF support is not fully automatic and requires
some manual settings before use. This documentation is the ultimate source
of information. If something described in this file does not work or does
not correspond to the reality, then contact us so we can fix the problems
and update this documentation.
1. Install bladeRF 2.0 libraries.
As of now, it's better to install from source.
So, do not run: ./build_oai -I -w BLADERF
(That is: do not include '-w BLADERF'.)
Instead, follow the instructions at: https://github.com/Nuand/bladeRF
If you already had some bladeRF software installed using automatic
methods, first remove it by hand ('apt-get purge bladeRF' or something
similar, you can get the list of installed bladeRF packages by running
'dpkg -l|grep -i blade', remove them all).
2. Update the device.
Download the latest FX3 firmware and FPGA images from Nuand's website.
As of writing, this is:
https://github.com/Nuand/bladeRF/wiki
That points to the following pages.
For FX3:
http://www.nuand.com/fx3_images/
For FPGA:
http://www.nuand.com/fpga_images/
Install FX3 firmware:
sudo bladeRF-cli -f bladeRF_fw_latest.img
Install FPGA image (this is for BladeRF x40):
sudo bladeRF-cli -L hostedx40-latest.rbf
Retrieve calibration information:
sudo bladeRF-cli -i
info
That outputs the serial number of your device.
Go to:
https://www.nuand.com/calibration
And enter your serial number.
The website tells you to run something like:
sudo bladeRF-cli -i
flash_init_cal 40 0x9271
Actual values depend on your device and serial number.
3. Calibrate the bladeRF device.
We will work with band 7 on 2.68GHz with a bandwidth of 5 MHz (25 RBs).
Plug the bladeRF device, then run:
sudo bladeRF-cli -i
set frequency tx 2680000000
set frequency rx 2560000000
set gain rx 60
set gain tx 60
set bandwidth 5000000
set samplerate 7680000
cal lms
cal lms
cal lms
cal dc rxtx
cal dc rxtx
cal dc rxtx
4. Tune the RX gain using the enb tracer.
Run the softmodem and the 'enb' tracer. For instructions, see:
https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/basic
In the enb window, check the 'input signal'. You should see some blue
signal as seen at:
https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/enb
(the 'Time signal power' plot).
The level should be around 30.
If it's not around 30 then edit your configuration file and modify
the value 'max_rxgain' in the section 'RUs'.
The configuration file to use is:
configuration/bladeRF/enb-band7-5mhz.conf
In the configuration file, you also need to set the correct values for:
- tracking_area_code
- plmn_list: mcc, mnc, mnc_length
- mme_ip_address: this is the IP address used by the computer running
the softmodem to connect to the EPC
- NETWORK_INTERFACES: all the ENB*ADDRESS* variables have to point
to the IP address of the EPC machine
5. You're good to go.
You can now connect a UE and pass some traffic. If everything is well
configured you can expect more than 16 Mb/s of throughput in the downlink
using iperf and more than 8 Mb/s in the uplink. Looking at the logs, you
should find lines containing 'PHR 40' and 'CQI 15'. If your values are
lower then your setup may need some adjustments.
6. In case of problems.
If the performance of the softmodem is very bad, you can stop it and
run the calibration again, without setting the parameters (frequencies,
gains, etc.). Just run:
sudo bladeRF-cli -i
cal lms
cal dc rxtx
That may help.
Be sure to use proper radio equipment (duplexer, antennas, clean
environment without interferences).
This diff is collapsed.
/*
* 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
*/
/** bladerf_lib.h
*
* Author: navid nikaein
*/
#include <libbladeRF.h>
#include "common_lib.h"
#include "LOG/log.h"
/** @addtogroup _BLADERF_PHY_RF_INTERFACE_
* @{
*/
/*! \brief BladeRF specific data structure */
typedef struct {
//! opaque BladeRF device struct. An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
struct bladerf *dev;
//! Number of buffers
unsigned int num_buffers;
//! Buffer size
unsigned int buffer_size;
//! Number of transfers
unsigned int num_transfers;
//! RX timeout
unsigned int rx_timeout_ms;
//! TX timeout
unsigned int tx_timeout_ms;
//! Metadata for RX
struct bladerf_metadata meta_rx;
//!Metadata for TX
struct bladerf_metadata meta_tx;
//! Sample rate
unsigned int sample_rate;
//! time offset between transmiter timestamp and receiver timestamp;
double tdiff;
//! TX number of forward samples use brf_time_offset to get this value
int tx_forward_nsamps; //166 for 20Mhz
// --------------------------------
// Debug and output control
// --------------------------------
//! Number of underflows
int num_underflows;
//! Number of overflows
int num_overflows;
//! number of sequential errors
int num_seq_errors;
//! number of RX errors
int num_rx_errors;
//! Number of TX errors
int num_tx_errors;
//! timestamp of current TX
uint64_t tx_current_ts;
//! timestamp of current RX
uint64_t rx_current_ts;
//! number of actual samples transmitted
uint64_t tx_actual_nsamps;
//! number of actual samples received
uint64_t rx_actual_nsamps;
//! number of TX samples
uint64_t tx_nsamps;
//! number of RX samples
uint64_t rx_nsamps;
//! number of TX count
uint64_t tx_count;
//! number of RX count
uint64_t rx_count;
//! timestamp of RX packet
openair0_timestamp rx_timestamp;
} brf_state_t;
/*
* func prototypes
*/
/*! \brief BladeRF Init function (not used at the moment)
* \param device RF frontend parameters set by application
*/
int trx_brf_init(openair0_device *device);
/*! \brief get current timestamp
*\param device the hardware to use
*\param module the bladeRf module
*/
openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module);
/*! \brief Get BladeRF log level
* \param log_level log level
* \returns log level of BLADERF device
*/
int get_brf_log_level(int log_level);
/*! \brief bladeRF error report
* \param status
* \returns 0 on success
*/
int brf_error(int status);
/*@}*/
/*
* 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 common_lib.c
* \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <strings.h>
#include <dlfcn.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "common_lib.h"
#include "assertions.h"
#include "common/utils/load_module_shlib.h"
#include "common/utils/LOG/log.h"
//#include "targets/RT/USER/lte-softmodem.h"
#include "executables/softmodem-common.h"
char *get_devname(int devtype) {
char *devnames[MAX_RF_DEV_TYPE]=DEVTYPE_NAMES;
if (devtype < MAX_RF_DEV_TYPE && devtype !=MIN_RF_DEV_TYPE )
return devnames[devtype];
return "none";
}
int set_device(openair0_device *device)
{
char *devname = get_devname(device->type);
if (strcmp(devname,"none") != 0) {
LOG_I(HW,"[%s] has loaded %s device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),devname);
} else {
LOG_E(HW,"[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return -1;
}
return 0;
}
int set_transport(openair0_device *device)
{
switch (device->transp_type) {
case ETHERNET_TP:
LOG_I(HW,"[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0;
break;
case NONE_TP:
LOG_I(HW,"[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0;
break;
default:
LOG_E(HW,"[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return -1;
break;
}
}
typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *);
/* look for the interface library and load it */
int load_lib(openair0_device *device,
openair0_config_t *openair0_cfg,
eth_params_t *cfg,
uint8_t flag)
{
loader_shlibfunc_t shlib_fdesc[1];
int ret=0;
char *deflibname=OAI_RF_LIBNAME;
openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state));
if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) {
deflibname=OAI_IQPLAYER_LIBNAME;
shlib_fdesc[0].fname="device_init";
set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms
} else if ( IS_SOFTMODEM_BASICSIM ) {
deflibname=OAI_BASICSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
deflibname=OAI_RFSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_LOCAL_RADIO_HEAD) {
if (IS_SOFTMODEM_RFSIM)
deflibname="rfsimulator";
else
deflibname=OAI_RF_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_REMOTE_THIRDPARTY_RADIO_HEAD) {
deflibname=OAI_THIRDPARTY_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
} else {
deflibname=OAI_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
}
char *devname=NULL;
paramdef_t device_params[]=DEVICE_PARAMS_DESC ;
int numparams = sizeof(device_params)/sizeof(paramdef_t);
int devname_pidx = config_paramidx_fromname(device_params,numparams, CONFIG_DEVICEOPT_NAME);
device_params[devname_pidx].defstrval=deflibname;
config_get(device_params,numparams,DEVICE_SECTION);
ret=load_module_shlib(devname,shlib_fdesc,1,NULL);
AssertFatal( (ret >= 0),
"Library %s couldn't be loaded\n",devname);
return ((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
}
int openair0_device_load(openair0_device *device,
openair0_config_t *openair0_cfg)
{
int rc=0;
rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD );
if ( rc >= 0) {
if ( set_device(device) < 0) {
LOG_E(HW, "%s %d:Unsupported radio head\n", __FILE__, __LINE__);
return -1;
}
} else
AssertFatal(false, "can't open the radio device: %s\n", get_devname(device->type));
return rc;
}
int openair0_transport_load(openair0_device *device,
openair0_config_t *openair0_cfg,
eth_params_t *eth_params)
{
int rc;
rc=load_lib(device, openair0_cfg, eth_params, RAU_REMOTE_RADIO_HEAD);
if ( rc >= 0) {
if ( set_transport(device) < 0) {
LOG_E(HW, "%s %d:Unsupported transport protocol\n", __FILE__, __LINE__);
return -1;
}
}
return rc;
}
This diff is collapsed.
/*
* 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
*/
/** record_player.c
*
* \author: Nokia bellLabs B. Mongazon F. Taburet
*
*/
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/sysinfo.h>
#include <sys/resource.h>
#include "common/utils/LOG/log.h"
#include "assertions.h"
#include "common_lib.h"
#include "record_player.h"
/*! \brief read the oai recorder or player configuration, called from common device code
* \param recplay_conf: store parameters
* recplay_state: store recorder or player data while the device runs
*/
int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {
unsigned int u_sf_record = 0; // record mode
unsigned int u_sf_replay = 0; // replay mode
*recplay_conf = calloc(sizeof(recplay_conf_t),1);
paramdef_t device_recplay_params[]=DEVICE_RECPLAY_PARAMS_DESC ;
config_get(device_recplay_params,sizeof(device_recplay_params)/sizeof(paramdef_t),DEVICE_RECPLAY_SECTION);
if (u_sf_record || u_sf_replay ) {
struct sysinfo systeminfo;
*recplay_state = calloc(sizeof(recplay_state_t),1);
if ( *recplay_state == NULL) {
LOG_E(HW,"calloc error in %s\n", __FILE__);
return -1;
}
// Use mmap for IQ files for systems with less than 6GB total RAM
sysinfo(&systeminfo);
if (systeminfo.totalram < 6144000000 && ((*recplay_conf)->use_mmap == 1)) {
LOG_W(HW,"System with %f GB of mem (<6GB), mmap usage disabled\n",systeminfo.totalram/10E9);
(*recplay_conf)->use_mmap = 0;
}
} else { /* record player enabled */
free(*recplay_conf);
*recplay_conf=NULL;
}
if (u_sf_replay == 1)
return RECPLAY_REPLAYMODE;
else if (u_sf_record == 1)
return RECPLAY_RECORDMODE;
return 0;
}
/*! \brief Terminate operation of the oai iq recorder. to be called by any device
* used in record mode
* \param device, the hardware used
*/
void iqrecorder_end(openair0_device *device) {
if (device->recplay_state != NULL) { // subframes store
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
recplay_state_t *rs = device->recplay_state;
recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf;
rs->pFile = fopen (rc->u_sf_filename,"wb+");
if (rs->pFile == NULL) {
LOG_E(HW,"Cannot open %s\n", rc->u_sf_filename);
} else {
unsigned int i = 0;
unsigned int modu = 0;
if ((modu = rs->nbSamplesBlocks % 10) != 0) {
rs->nbSamplesBlocks -= modu; // store entire number of frames
}
fh.nbSamplesBlocks=rs->nbSamplesBlocks;
LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename );
fwrite(&fh, sizeof(fh), 1, rs->pFile);
LOG_UI(HW,"Writing %u subframes to %s \n",rs->nbSamplesBlocks, rc->u_sf_filename );
uint8_t *ptr=(uint8_t *)rs->ms_sample;
for (i = 0; i < rs->nbSamplesBlocks; i++) {
int blockBytes=sizeof(iqrec_t)+((iqrec_t *)ptr)->nbBytes;
fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile);
ptr+=blockBytes;
}
fclose (rs->pFile);
LOG_UI(HW,"File %s closed\n",rc->u_sf_filename );
}
if (rs->ms_sample != NULL) {
free((void *)rs->ms_sample);
rs->ms_sample = NULL;
}
}
}
#ifndef __RECORD_PLAYER_H
#define __RECORD_PLAYER_H
/*
* 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
*/
/** targets/ARCH/COMMON/record-player.h
*
* \author: bruno.mongazon-cazavet@nokia-bell-labs.com
*/
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "common/config/config_paramdesc.h"
#include "common/config/config_userapi.h"
#ifdef __cplusplus
extern "C"
{
#endif
/* inclusions for record player */
#define RECPLAY_DISABLED 0
#define RECPLAY_RECORDMODE 1
#define RECPLAY_REPLAYMODE 2
#define BELL_LABS_IQ_HEADER 0xabababababababab
#define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
#define MAX_BELL_LABS_IQ_BYTES_PER_SF BELL_LABS_IQ_BYTES_PER_SF*10
#define OAIIQFILE_ID {'O', 'I','Q','F'}
typedef struct {
uint64_t devtype;
uint64_t tx_sample_advance;
double bw;
unsigned int nbSamplesBlocks;
char oaiid[4];
} iqfile_header_t;
typedef struct {
int64_t header;
int64_t ts;
int64_t nbBytes;
int64_t rfu2; // pad for 256 bits alignement required by AVX2
} iqrec_t;
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name
#define DEF_SF_DELAY_READ 700 // default read delay µs (860=real)
#define DEF_SF_DELAY_WRITE 15 // default write delay µs (15=real)
#define DEF_SF_NB_LOOP 5 // default nb loops
/* help strings definition for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_SF_FILE "Path of the file used for subframes record or replay"
#define CONFIG_HLP_SF_REC "Record subframes from device driver into a file for later replay"
#define CONFIG_HLP_SF_REP "Replay subframes from a file using the oai replay driver"
#define CONFIG_HLP_SF_MAX "Maximum count of subframes to be recorded in subframe file"
#define CONFIG_HLP_SF_LOOPS "Number of loops to replay of the entire subframes file"
#define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode"
#define CONFIG_HLP_SF_WDELAY "Delay in microseconds to write a subframe in replay mode"
#define CONFIG_HLP_USE_MMAP "In replay mode, map iq file in memory before replaying"
/* keyword strings for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_OPT_SF_FILE "subframes-file"
#define CONFIG_OPT_SF_REC "subframes-record"
#define CONFIG_OPT_SF_REP "subframes-replay"
#define CONFIG_OPT_SF_MAX "subframes-max"
#define CONFIG_OPT_SF_LOOPS "subframes-loops"
#define CONFIG_OPT_SF_RDELAY "subframes-read-delay"
#define CONFIG_OPT_SF_WDELAY "subframes-write-delay"
#define CONFIG_OPT_USE_MMAP "use-mmap"
#define DEVICE_RECPLAY_SECTION "device.recplay"
/* For information only - the macro is not usable in C++ */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for USRP record/playback */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define DEVICE_RECPLAY_PARAMS_DESC { \
{CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:(char **)((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 1024}, \
{CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \
{CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \
{CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \
{CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
{CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
{CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
{CONFIG_OPT_USE_MMAP, CONFIG_HLP_USE_MMAP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->use_mmap), defuintval:1, TYPE_UINT, 0}, \
}/*! \brief Record Player Configuration and state */
typedef struct {
char u_sf_filename[1024]; // subframes file path
unsigned int u_sf_max ; // max number of recorded subframes
unsigned int u_sf_loops ; // number of loops in replay mode
unsigned int u_sf_read_delay; // read delay in replay mode
unsigned int u_sf_write_delay ; // write delay in replay mode
unsigned int use_mmap; // default is to use mmap
} recplay_conf_t;
typedef struct {
size_t mapsize;
FILE *pFile;
int fd;
iqrec_t *ms_sample; // memory for all subframes
unsigned int nbSamplesBlocks;
uint8_t *currentPtr;
uint64_t currentTs;
unsigned int curSamplesBlock;
int64_t wrap_count;
size_t maxSizeBytes;
} recplay_state_t;
#ifdef __cplusplus
}
#endif
#endif // __RECORD_PLAYER_H
ETHERNET_OBJ += $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.o
ETHERNET_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
ETHERNET_CFLAGS += -O2 -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* 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 ethernet_lib.h
* \brief API to stream I/Q samples over standard ethernet
* \author Katerina Trilyraki, Navid Nikaein
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#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>
#define MAX_INST 4
#define DEFAULT_IF "lo"
#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))
#define ECPRIREV 1 // ECPRI Version 1, C=0 - single ECPRI message per OAI TX packet
/*!\brief opaque ethernet data structure */
typedef struct {
/*!\brief socket file desc (control)*/
int sockfdc;
/*!\brief socket file desc (user)*/
int sockfdd;
/*!\brief interface name */
char *if_name;
/*!\brief buffer size */
unsigned int buffer_size;
/*!\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 destination address (control) for RAW socket*/
struct sockaddr_ll dest_addrc_ll;
/*!\brief local address (control) for RAW socket*/
struct sockaddr_ll local_addrc_ll;
/*!\brief destination address (user) for RAW socket*/
struct sockaddr_ll dest_addrd_ll;
/*!\brief local address (user) for RAW socket*/
struct sockaddr_ll local_addrd_ll;
/*!\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;
/*!\compression enalbe */
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 current TX timestamp */
openair0_timestamp tx_current_ts;
/*!\brief socket file desc */
openair0_timestamp 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;
} 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 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 ;
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 *device);
/*void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_flag,int nsamps);
void inline dump_rxcounters(openair0_device *device);
void inline dump_txcounters(openair0_device *device);
*/
void dump_iqs(char * buff, int iq_cnt);
/*! \fn int ethernet_tune (openair0_device *device, unsigned int option, int value);
* \brief this function allows you to configure certain ethernet parameters in socket or device level
* \param[in] openair0 device which bears the socket
* \param[in] name of parameter to configure
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int ethernet_tune(openair0_device *device, unsigned int option, int value);
/*! \fn int eth_socket_init_udp(openair0_device *device)
* \brief initialization of UDP Socket to communicate with one destination
* \param[in] *device openair device for which the socket will be created
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int eth_socket_init_udp(openair0_device *device);
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags);
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc);
int eth_socket_init_raw(openair0_device *device);
int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_ctlsend_udp(openair0_device *device, void *msg, ssize_t msg_len);
int trx_eth_ctlrecv_udp(openair0_device *device, void *msg, ssize_t msg_len);
int eth_get_dev_conf_raw(openair0_device *device);
int eth_set_dev_conf_raw(openair0_device *device);
int eth_get_dev_conf_raw_IF4p5(openair0_device *device);
int eth_set_dev_conf_raw_IF4p5(openair0_device *device);
#endif
/*
* 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 targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
* \brief
* \author S. Sandeep Kumar, Raymond Knopp
* \date 2016
* \version 0.1
* \company Eurecom
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr
* \note
* \warning
*/
#ifndef __ETHERNET_USERSPACE_LIB_IF_DEFS__H__
#define __ETHERNET_USERSPACE_LIB_IF_DEFS__H__
#include <netinet/ether.h>
#include <stdint.h>
#ifndef LITE_COMPILATION
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#endif
// ETH transport preference modes
#define ETH_UDP_MODE 0
#define ETH_RAW_MODE 1
#define ETH_UDP_IF4p5_MODE 2
#define ETH_RAW_IF4p5_MODE 3
#define ETH_UDP_IF5_ECPRI_MODE 4
// COMMOM HEADER LENGTHS
#define NO_COMPRESS 0
#define ALAW_COMPRESS 1
#define UDP_HEADER_SIZE_BYTES 8
#define IPV4_HEADER_SIZE_BYTES 60 // This is the maximum IPv4 header length
// Time domain RRH packet sizes
#define MAC_HEADER_SIZE_BYTES (sizeof(struct ether_header))
#define MAX_PACKET_SEQ_NUM(spp,spf) (spf/spp)
#define PAYLOAD_SIZE_BYTES(nsamps) (nsamps<<2)
#define UDP_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
#define RAW_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
#define PAYLOAD_SIZE_BYTES_ALAW(nsamps) (nsamps<<1)
#define UDP_PACKET_SIZE_BYTES_ALAW(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES_ALAW(nsamps))
#define RAW_PACKET_SIZE_BYTES_ALAW(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES_ALAW(nsamps))
// Packet sizes for IF4p5 interface format
#define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(uint16_t)*scaled_nblocks)
#define PRACH_NUM_SAMPLES (839*2)
#define PRACH_BLOCK_SIZE_BYTES (sizeof(int16_t)*PRACH_NUM_SAMPLES)
#define RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4p5_PULTICK_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t)
#define RAW_IF4p5_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
#define UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks) (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define UDP_IF4p5_PULTICK_SIZE_BYTES (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t)
#define UDP_IF4p5_PRACH_SIZE_BYTES (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
// Mobipass packet sizes
#define RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES 1280
#define RAW_IF5_MOBIPASS_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES)
#define PAYLOAD_MOBIPASS_NUM_SAMPLES 640
#endif
This diff is collapsed.
This diff is collapsed.
/*
* 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
*/
#include "low.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void store_ul(benetel_t *bs, ul_packet_t *ul)
{
int a = ul->antenna;
if (ul->subframe != bs->next_subframe[a] ||
ul->symbol != bs->next_symbol[a]) {
printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n",
__FUNCTION__,
a,
bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a],
ul->frame, ul->subframe, ul->symbol);
exit(1);
}
lock_ul_buffer(bs->buffers, bs->next_subframe[a]);
if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) {
printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__,
bs->next_subframe[a], bs->next_symbol[a]);
}
memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4,
ul->iq, 1200*4);
bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]);
signal_ul_buffer(bs->buffers, bs->next_subframe[a]);
unlock_ul_buffer(bs->buffers, bs->next_subframe[a]);
bs->next_symbol[a]++;
if (bs->next_symbol[a] == 14) {
bs->next_symbol[a] = 0;
bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10;
if (bs->next_subframe[a] == 0) {
bs->expected_benetel_frame[a]++;
bs->expected_benetel_frame[a] &= 255;
}
}
}
void store_prach(benetel_t *bs, int frame, int subframe, void *data)
{
static int last_frame = -1;
static int last_subframe = -1;
/* hack: antenna number is always 0, discard second packet with same f/sf */
if (frame == last_frame && subframe == last_subframe) return;
last_frame = frame;
last_subframe = subframe;
lock_ul_buffer(bs->buffers, subframe);
if (bs->buffers->prach_busy[subframe]) {
printf("store_prach: fatal: previous prach buffer not processed\n");
unlock_ul_buffer(bs->buffers, subframe);
return;
}
bs->buffers->prach_busy[subframe] = 1;
memcpy(bs->buffers->prach[subframe], data, 849*4);
signal_ul_buffer(bs->buffers, subframe);
unlock_ul_buffer(bs->buffers, subframe);
}
void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line);
void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line)
{
if (!strcmp(ifname, "dpdk"))
return benetel_start_dpdk(ifname, buffers, dpdk_main_command_line);
printf("benetel: fatal: interface %s not supported, only dpdpk is supported\n", ifname);
exit(1);
}
/*
* 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
*/
#ifndef _BENETEL_4G_LOW_H_
#define _BENETEL_4G_LOW_H_
#include "shared_buffers.h"
typedef struct {
shared_buffers *buffers;
/* [2] is for two antennas */
int next_subframe[2];
int next_symbol[2];
int expected_benetel_frame[2];
char *dpdk_main_command_line;
} benetel_t;
typedef struct {
int frame;
int subframe;
int slot;
int symbol;
int antenna;
unsigned char iq[4800];
} ul_packet_t;
void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line);
void store_ul(benetel_t *bs, ul_packet_t *ul);
void store_prach(benetel_t *bs, int frame, int subframe, void *data);
#endif /* _BENETEL_4G_LOW_H_ */
This diff is collapsed.
This diff is collapsed.
/*
* 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
*/
#ifndef _BENETEL_4G_SHARED_BUFFERS_H_
#define _BENETEL_4G_SHARED_BUFFERS_H_
#include <pthread.h>
#include <stdint.h>
typedef struct {
/* [2] is for two antennas */
unsigned char dl[2][10][14*1200*4];
unsigned char ul[2][10][14*1200*4];
uint16_t dl_busy[2][10];
uint16_t ul_busy[2][10];
pthread_mutex_t m_ul[10];
pthread_cond_t c_ul[10];
pthread_mutex_t m_dl[10];
pthread_cond_t c_dl[10];
unsigned char prach[10][849*4];
unsigned char prach_busy[10];
/* statistics/error counting */
int ul_overflow;
int dl_underflow;
} shared_buffers;
void init_buffers(shared_buffers *s);
void lock_dl_buffer(shared_buffers *s, int subframe);
void unlock_dl_buffer(shared_buffers *s, int subframe);
void wait_dl_buffer(shared_buffers *s, int subframe);
void signal_dl_buffer(shared_buffers *s, int subframe);
void lock_ul_buffer(shared_buffers *s, int subframe);
void unlock_ul_buffer(shared_buffers *s, int subframe);
void wait_ul_buffer(shared_buffers *s, int subframe);
void signal_ul_buffer(shared_buffers *s, int subframe);
#endif /* _BENETEL_4G_SHARED_BUFFERS_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment