Commit 761e7883 authored by Rahman's avatar Rahman

Initial commit

parents
cmake_minimum_required (VERSION 2.8)
project (Sounder)
set(CMAKE_C_FLAGS "-std=c99 -w ")
set(CMAKE_CXX_FLAGS "-std=c++11 -w -O3 -mavx2 -mavx")
find_package(nlohmann_json 3.2.0 REQUIRED)
########################################################################
# SoapySDR dependency
########################################################################
find_package(SoapySDR "0.6" CONFIG)
if (NOT SoapySDR_FOUND)
message(FATAL_ERROR "SoapySDR development files not found")
return()
endif ()
find_package(HDF5)
if (NOT HDF5_FOUND)
message(FATAL_ERROR "HDF5 development files not found")
return()
endif ()
set(directory "logs")
file(MAKE_DIRECTORY ${directory})
add_definitions(-DJSON)
message(STATUS "SoapySDR_INCLUDE_DIRS: ${SoapySDR_INCLUDE_DIRS}")
message(STATUS "SoapySDR_LIBRARIES: ${SoapySDR_LIBRARIES}")
message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}")
message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}")
include_directories(${SoapySDR_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS})
add_executable(sounder main.cc config.cc receiver.cc recorder.cc sdr-lib.cc comms-lib.cc utils.cc)
target_link_libraries(sounder -lpthread -lhdf5_cpp --enable-threadsafe ${SoapySDR_LIBRARIES} ${HDF5_LIBRARIES} ${CMAKE_SOURCE_DIR}/lib/libmuFFT.a ${CMAKE_SOURCE_DIR}/lib/libmuFFT-sse.a ${CMAKE_SOURCE_DIR}/lib/libmuFFT-sse3.a ${CMAKE_SOURCE_DIR}/lib/libmuFFT-avx.a)
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.12
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:
#=============================================================================
# Special targets provided by cmake.
# Disable implicit rules so canonical targets will work.
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
.SUFFIXES: .hpux_make_needs_suffix_list
# Suppress display of executed commands.
$(VERBOSE).SILENT:
# A target that is always out of date.
cmake_force:
.PHONY : cmake_force
#=============================================================================
# Set environment variables for the build.
# The shell in which to execute make rules.
SHELL = /bin/sh
# The CMake executable.
CMAKE_COMMAND = /opt/cmake-3.12.2-Linux-x86_64/bin/cmake
# The command to remove a file.
RM = /opt/cmake-3.12.2-Linux-x86_64/bin/cmake -E remove -f
# Escaping for special characters.
EQUALS = =
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /usr/git/renew/renew-software/CC/Sounder
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /usr/git/renew/renew-software/CC/Sounder
#=============================================================================
# Targets provided globally by CMake.
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
/opt/cmake-3.12.2-Linux-x86_64/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
/opt/cmake-3.12.2-Linux-x86_64/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache
# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast
# The main all target
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /usr/git/renew/renew-software/CC/Sounder/CMakeFiles /usr/git/renew/renew-software/CC/Sounder/CMakeFiles/progress.marks
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start /usr/git/renew/renew-software/CC/Sounder/CMakeFiles 0
.PHONY : all
# The main clean target
clean:
$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean
# The main clean target
clean/fast: clean
.PHONY : clean/fast
# Prepare targets for installation.
preinstall: all
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall
# Prepare targets for installation.
preinstall/fast:
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast
# clear depends
depend:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend
#=============================================================================
# Target rules for targets named sounder
# Build rule for target.
sounder: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 sounder
.PHONY : sounder
# fast build rule for target.
sounder/fast:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/build
.PHONY : sounder/fast
comms-lib.o: comms-lib.cc.o
.PHONY : comms-lib.o
# target to build an object file
comms-lib.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/comms-lib.cc.o
.PHONY : comms-lib.cc.o
comms-lib.i: comms-lib.cc.i
.PHONY : comms-lib.i
# target to preprocess a source file
comms-lib.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/comms-lib.cc.i
.PHONY : comms-lib.cc.i
comms-lib.s: comms-lib.cc.s
.PHONY : comms-lib.s
# target to generate assembly for a file
comms-lib.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/comms-lib.cc.s
.PHONY : comms-lib.cc.s
config.o: config.cc.o
.PHONY : config.o
# target to build an object file
config.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/config.cc.o
.PHONY : config.cc.o
config.i: config.cc.i
.PHONY : config.i
# target to preprocess a source file
config.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/config.cc.i
.PHONY : config.cc.i
config.s: config.cc.s
.PHONY : config.s
# target to generate assembly for a file
config.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/config.cc.s
.PHONY : config.cc.s
main.o: main.cc.o
.PHONY : main.o
# target to build an object file
main.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/main.cc.o
.PHONY : main.cc.o
main.i: main.cc.i
.PHONY : main.i
# target to preprocess a source file
main.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/main.cc.i
.PHONY : main.cc.i
main.s: main.cc.s
.PHONY : main.s
# target to generate assembly for a file
main.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/main.cc.s
.PHONY : main.cc.s
receiver.o: receiver.cc.o
.PHONY : receiver.o
# target to build an object file
receiver.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/receiver.cc.o
.PHONY : receiver.cc.o
receiver.i: receiver.cc.i
.PHONY : receiver.i
# target to preprocess a source file
receiver.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/receiver.cc.i
.PHONY : receiver.cc.i
receiver.s: receiver.cc.s
.PHONY : receiver.s
# target to generate assembly for a file
receiver.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/receiver.cc.s
.PHONY : receiver.cc.s
recorder.o: recorder.cc.o
.PHONY : recorder.o
# target to build an object file
recorder.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/recorder.cc.o
.PHONY : recorder.cc.o
recorder.i: recorder.cc.i
.PHONY : recorder.i
# target to preprocess a source file
recorder.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/recorder.cc.i
.PHONY : recorder.cc.i
recorder.s: recorder.cc.s
.PHONY : recorder.s
# target to generate assembly for a file
recorder.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/recorder.cc.s
.PHONY : recorder.cc.s
sdr-lib.o: sdr-lib.cc.o
.PHONY : sdr-lib.o
# target to build an object file
sdr-lib.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/sdr-lib.cc.o
.PHONY : sdr-lib.cc.o
sdr-lib.i: sdr-lib.cc.i
.PHONY : sdr-lib.i
# target to preprocess a source file
sdr-lib.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/sdr-lib.cc.i
.PHONY : sdr-lib.cc.i
sdr-lib.s: sdr-lib.cc.s
.PHONY : sdr-lib.s
# target to generate assembly for a file
sdr-lib.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/sdr-lib.cc.s
.PHONY : sdr-lib.cc.s
utils.o: utils.cc.o
.PHONY : utils.o
# target to build an object file
utils.cc.o:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/utils.cc.o
.PHONY : utils.cc.o
utils.i: utils.cc.i
.PHONY : utils.i
# target to preprocess a source file
utils.cc.i:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/utils.cc.i
.PHONY : utils.cc.i
utils.s: utils.cc.s
.PHONY : utils.s
# target to generate assembly for a file
utils.cc.s:
$(MAKE) -f CMakeFiles/sounder.dir/build.make CMakeFiles/sounder.dir/utils.cc.s
.PHONY : utils.cc.s
# Help Target
help:
@echo "The following are some of the valid targets for this Makefile:"
@echo "... all (the default if no target is provided)"
@echo "... clean"
@echo "... depend"
@echo "... rebuild_cache"
@echo "... edit_cache"
@echo "... sounder"
@echo "... comms-lib.o"
@echo "... comms-lib.i"
@echo "... comms-lib.s"
@echo "... config.o"
@echo "... config.i"
@echo "... config.s"
@echo "... main.o"
@echo "... main.i"
@echo "... main.s"
@echo "... receiver.o"
@echo "... receiver.i"
@echo "... receiver.s"
@echo "... recorder.o"
@echo "... recorder.i"
@echo "... recorder.s"
@echo "... sdr-lib.o"
@echo "... sdr-lib.i"
@echo "... sdr-lib.s"
@echo "... utils.o"
@echo "... utils.i"
@echo "... utils.s"
.PHONY : help
#=============================================================================
# Special targets to cleanup operation of make.
# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system
### Sounder Framework
This folder includes a library of code for running channel sounding
experiments with an RENEW base station hardware. To run, follow steps below:
```shell
cmake ./
make -j
./sounder files/tddconfig.json
```
For more details, see [RENEW Documentation](https://docs.renew-wireless.org/dev-suite/design-flows)
This diff is collapsed.
/*
Copyright (c) 2018-2019, Rice University
RENEW OPEN SOURCE LICENSE: http://renew-wireless.org/license
Author(s): Rahman Doost-Mohamamdy: doost@rice.edu
---------------------------------------------------------------------
Reads configuration parameters from file
---------------------------------------------------------------------
*/
#include "include/config.h"
#include "include/comms-lib.h"
Config::Config(std::string jsonfile)
//freq(0),rate(0),prefix(0),postfix(0),sampsPerSymbol(0),fftSize(0),cpSize(0)
{
std::string conf;
Utils::loadTDDConfig(jsonfile, conf);
const auto jConf = json::parse(conf);
std::stringstream ss;
json tddConf;
ss << jConf.value("BaseStations", tddConf);
tddConf = json::parse(ss);
bsPresent = (!tddConf.empty());
if (bsPresent) std::cout << tddConf << "\n\n";
ss.clear();
json tddConfCl;
ss << jConf.value("Clients", tddConfCl);
tddConfCl = json::parse(ss);
clPresent = (!tddConfCl.empty());
if (clPresent) std::cout << tddConfCl << "\n\n";
ss.clear();
// common (BaseStation config overrides these)
if (bsPresent)
{
freq = tddConf.value("frequency", 3.6e9);
rate = tddConf.value("rate", 5e6);
int samps = tddConf.value("subframe_size", 0);
prefix = tddConf.value("prefix", 0);
postfix = tddConf.value("postfix", 0);
sampsPerSymbol = samps + prefix + postfix;
fftSize = tddConf.value("fft_size", 0);
cpSize = tddConf.value("cp_size", 0);
beacon_seq = tddConf.value("beacon_seq", "gold_ifft");
pilot_seq = tddConf.value("pilot_seq", "lts");
// BS
hub_file = tddConf.value("hub_id", "hub_serials.txt");
json bs_sdr_ids = tddConf.value("sdr_id", json::array());
nCells = bs_sdr_ids.size();
for (int i = 0; i < nCells; i++) bs_sdr_file.push_back(bs_sdr_ids.at(i).get<std::string>());
bsSdrCh = tddConf.value("polarization", "single") == "single"? 1 : 2;
auto jBsFrames = tddConf.value("frame_schedule", json::array());
framePeriod = jBsFrames.size();
for(int f = 0; f < framePeriod; f++) frames.push_back(jBsFrames.at(f).get<std::string>());
txgainA = tddConf.value("txgainA", 20);
rxgainA = tddConf.value("rxgainA", 20);
txgainB = tddConf.value("txgainB", 20);
rxgainB = tddConf.value("rxgainB", 20);
beamsweep = tddConf.value("beamsweep", false);
beacon_ant = tddConf.value("beacon_antenna", 0);
}
// Clients
if (clPresent)
{
auto jClSdrs = tddConfCl.value("sdr_id", json::array());
nClSdrs = jClSdrs.size();
for (int i = 0; i < nClSdrs; i++) cl_sdr_ids.push_back(jClSdrs.at(i).get<std::string>());
clSdrCh = tddConfCl.value("polarization", "single") == "single"? 1 : 2;
clAgcEn = tddConfCl.value("agc_en", false);
clDataMod = tddConfCl.value("modulation", "QPSK");
clTxgainA = tddConfCl.value("txgainA", 20);
clRxgainA = tddConfCl.value("rxgainA", 20);
clTxgainB = tddConfCl.value("txgainB", 20);
clRxgainB = tddConfCl.value("rxgainB", 20);
auto jClFrames = tddConfCl.value("frame_schedule", json::array());
assert(nClSdrs == jClFrame.size());
for(int f = 0; f < nClSdrs; f++) clFrames.push_back(jClFrames.at(f).get<std::string>());
// read commons from Client json config
if (!bsPresent)
{
freq = tddConfCl.value("frequency", 3.6e9);
rate = tddConfCl.value("rate", 5e6);
int samps = tddConfCl.value("subframe_size", 0);
prefix = tddConfCl.value("prefix", 0);
postfix = tddConfCl.value("postfix", 0);
sampsPerSymbol = samps + prefix + postfix;
fftSize = tddConfCl.value("fft_size", 0);
cpSize = tddConfCl.value("cp_size", 0);
beacon_seq = tddConfCl.value("beacon_seq", "gold_ifft");
pilot_seq = tddConfCl.value("pilot_seq", "lts");
}
}
if (!clPresent) nClSdrs = std::count(frames.at(0).begin(), frames.at(0).end(), 'P');
if (bsPresent)
{
bs_sdr_ids.resize(nCells);
nBsSdrs.resize(nCells);
nBsAntennas.resize(nCells);
for (int i = 0; i < nCells; i++)
{
Utils::loadDevices(bs_sdr_file[i], bs_sdr_ids[i]);
nBsSdrs[i] = bs_sdr_ids[i].size();
nBsAntennas[i] = bsSdrCh * nBsSdrs[i];
}
Utils::loadDevices(hub_file, hub_ids);
symbolsPerFrame = frames.at(0).size();
//std::vector<std::vector<size_t>> pilotSymbols = Utils::loadSymbols(frames, 'P');
//std::vector<std::vector<size_t>> ULSymbols = Utils::loadSymbols(frames, 'T');
//std::vector<std::vector<size_t>> DLSymbols = Utils::loadSymbols(frames, 'R');
pilotSymbols.resize(framePeriod);
for(int f = 0; f < framePeriod; f++)
{
std::string fr = frames[f];
for (int g = 0; g < symbolsPerFrame; g++)
{
if (fr[g] == 'P')
pilotSymbols[f].push_back(g);
}
}
ULSymbols.resize(framePeriod);
for(int f = 0; f < framePeriod; f++)
{
std::string fr = frames[f];
for (int g = 0; g < symbolsPerFrame; g++)
{
if (fr[g] == 'U')
ULSymbols[f].push_back(g);
}
}
DLSymbols.resize(framePeriod);
for(int f = 0; f < framePeriod; f++)
{
std::string fr = frames[f];
for (int g = 0; g < symbolsPerFrame; g++)
{
if (fr[g] == 'D')
DLSymbols[f].push_back(g);
}
}
pilotSymsPerFrame = pilotSymbols[0].size();
ulSymsPerFrame = ULSymbols[0].size();
dlSymsPerFrame = DLSymbols[0].size();
}
else if (clPresent)
symbolsPerFrame = clFrames.at(0).size();
std::cout << "Configuration file was successfully parsed!" << std::endl;
}
int Config::getNumAntennas()
{
return nBsSdrs[0]*bsSdrCh;
}
Config::~Config(){}
int Config::getClientId(int frame_id, int symbol_id)
{
std::vector<size_t>::iterator it;
int fid = frame_id % framePeriod;
it = find(pilotSymbols[fid].begin(), pilotSymbols[fid].end(), symbol_id);
if (it != pilotSymbols[fid].end())
{
#if DEBUG_PRINT
printf("getClientId(%d, %d) = %d\n",frame_id, symbol_id, it-pilotSymbols[fid].begin());
#endif
return it-pilotSymbols[fid].begin();
}else
return -1;
}
int Config::getUlSFIndex(int frame_id, int symbol_id)
{
std::vector<size_t>::iterator it;
int fid = frame_id % framePeriod;
it = find(ULSymbols[fid].begin(), ULSymbols[fid].end(), symbol_id);
if (it != ULSymbols[fid].end())
{
#if DEBUG_PRINT
printf("getUlSFIndexId(%d, %d) = %d\n",frame_id, symbol_id, it-ULSymbols[fid].begin());
#endif
return it-ULSymbols[fid].begin();
}else
return -1;
}
int Config::getDlSFIndex(int frame_id, int symbol_id)
{
std::vector<size_t>::iterator it;
int fid = frame_id % framePeriod;
it = find(DLSymbols[fid].begin(), DLSymbols[fid].end(), symbol_id);
if (it != DLSymbols[fid].end())
return it-DLSymbols[fid].begin();
else
return -1;
}
bool Config::isPilot(int frame_id, int symbol_id)
{
int fid = frame_id % framePeriod;
#if DEBUG_PRINT
printf("isPilot(%d, %d) = %c\n",frame_id, symbol_id, frames[fid].at(symbol_id));
#endif
return frames[fid].at(symbol_id) == 'P' ? true : false;
}
bool Config::isData(int frame_id, int symbol_id)
{
int fid = frame_id % framePeriod;
#if DEBUG_PRINT
printf("isData(%d, %d) = %c\n",frame_id, symbol_id, frames[fid].at(symbol_id));
#endif
return frames[fid].at(symbol_id) == 'U' ? true : false;
}
{
"BaseStations" : {
"frequency" : 3.6e9,
"polarization" : "single",
"rxgainA" : 20,
"txgainA" : 40,
"rxgainB" : 20,
"txgainB" : 40,
"rate" : 5e6,
"fft_size" : 64,
"subframe_size" : 400,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"frame_schedule" : [
"BGPPUGGGGGGGGGGGGGGG"
],
"pilot_seq" : "lts",
"beacon_seq" : "gold_ifft",
"beamsweep" : false,
"beacon_antenna" : 0,
"cells" : 1,
"sdr_id" : ["conf/iris_serials.txt"],
"hub_id" : "conf/hub_serials.txt"
}
}
0328
0339
0268
0282
0344
0233
0334
0402
{
"BaseStations" : {
"cells" : 1,
"sdr_id" : ["files/iris_serials.txt"],
"hub_id" : "files/hub_serials.txt",
"frequency" : 3.6e9,
"polarization" : "single",
"rxgainA" : 20,
"txgainA" : 40,
"rxgainB" : 20,
"txgainB" : 40,
"rate" : 5e6,
"frame_schedule" : [
"BGPPGGGGGGGGGGGGGGGG"
],
"subframe_size" : 400,
"fft_size" : 64,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"beacon_seq" : "gold_ifft",
"beamsweep" : false,
"beacon_antenna" : 0,
"pilot_seq" : "lts"
},
"Clients" : {
"sdr_id" : [
"RF3E000029",
"RF3E000040"
],
"frequency" : 3.6e9,
"polarization" : "single",
"agc_en" : false,
"rxgainA" : 20,