Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3fac8b1ce9 | |||
| 948f1c80ae | |||
| f85bfca13a | |||
| 8814b4b333 | |||
| 7565ec5246 | |||
| 2c95b5e07f | |||
| df4f14f220 | |||
| c664ac99a7 | |||
| 9614b4a459 | |||
| 73095d93f3 | |||
| cf0af12054 | |||
| c8de2646ae | |||
| 1d682b172b | |||
| f2dc4c4f0b | |||
| 137cc3e944 | |||
| 8300907d85 | |||
| 73317734f3 | |||
| 023ede6821 | |||
| e1dbdef395 | |||
| a04945a35b | |||
| fe4ae7f802 |
@@ -1,13 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[**.{cc,h,xml}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
@@ -5,5 +5,3 @@ examples/*.py
|
||||
.pydevproject
|
||||
.settings
|
||||
*.pyc
|
||||
**/.DS_Store
|
||||
.clang_complete
|
||||
|
||||
+19
-19
@@ -37,7 +37,6 @@ if(NOT WIN32)
|
||||
#http://gcc.gnu.org/wiki/Visibility
|
||||
add_definitions(-fvisibility=hidden)
|
||||
add_definitions(-std=c++0x)
|
||||
add_definitions(-msse2)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
@@ -82,31 +81,29 @@ set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
|
||||
# Find gnuradio build dependencies
|
||||
########################################################################
|
||||
set(GR_REQUIRED_COMPONENTS RUNTIME FILTER FFT PMT DIGITAL)
|
||||
|
||||
find_package(Gnuradio)
|
||||
if(NOT GNURADIO_RUNTIME_FOUND)
|
||||
message(FATAL_ERROR "GNU Radio required to compile gr-ieee802-11")
|
||||
endif()
|
||||
|
||||
find_package(CppUnit)
|
||||
find_package(ITPP)
|
||||
|
||||
if(NOT GNURADIO_RUNTIME_FOUND)
|
||||
message(FATAL_ERROR "GnuRadio Runtime required to compile ieee802-11")
|
||||
endif()
|
||||
|
||||
if(NOT CPPUNIT_FOUND)
|
||||
message(FATAL_ERROR "CppUnit required to compile gr-ieee802-11")
|
||||
message(FATAL_ERROR "CppUnit required to compile ieee802-11")
|
||||
endif()
|
||||
|
||||
find_package(Log4cpp)
|
||||
if (LOG4CPP_FOUND)
|
||||
message(STATUS "Found LOG4CPP: ${LOG4CPP_LIBRARIES}")
|
||||
add_definitions("-DGR_IEEE80211_LOG4CPP")
|
||||
else ()
|
||||
message(STATUS "LOG4CPP not found (not required).")
|
||||
endif ()
|
||||
|
||||
find_package(SWIG)
|
||||
if(NOT SWIG_FOUND)
|
||||
message(FATAL_ERROR "SWIG required to compile gr-ieee802-11")
|
||||
if(NOT ITPP_FOUND)
|
||||
message(FATAL_ERROR "ITPP required to compile ieee802-11")
|
||||
endif()
|
||||
|
||||
find_package(Doxygen)
|
||||
########################################################################
|
||||
# Setup logging options
|
||||
########################################################################
|
||||
|
||||
include(GrMiscUtils)
|
||||
GR_LOGGING()
|
||||
|
||||
########################################################################
|
||||
# On Apple only, set install name and use rpath correctly, if not already set
|
||||
########################################################################
|
||||
@@ -136,13 +133,16 @@ include_directories(
|
||||
${CMAKE_BINARY_DIR}/include
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${CPPUNIT_INCLUDE_DIRS}
|
||||
${ITPP_INCLUDE_DIR}
|
||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||
${LOG4CPP_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${Boost_LIBRARY_DIRS}
|
||||
${CPPUNIT_LIBRARY_DIRS}
|
||||
${GNURADIO_RUNTIME_LIBRARY_DIRS}
|
||||
${LOG4CPP_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
Hi!
|
||||
|
||||
This an IEEE 802.11 a/g/p transceiver for GNU Radio that is fitted for operation
|
||||
with Ettus N210s and B210s. Interoperability was tested with many off-the-shelf
|
||||
WiFi cards and IEEE 802.11p prototypes. The code can also be used in
|
||||
simulations.
|
||||
|
||||
|
||||
# Development
|
||||
|
||||
Like GNU Radio, this module uses *master* and *maint* branches for development.
|
||||
These branches are supposed to be used with the corresponding GNU Radio
|
||||
branches. This means: the *maint-3.7* branch is compatible with GNU Radio 3.7,
|
||||
*maint-3.8* is compatible with GNU Radio 3.8, and *master* is compatible with
|
||||
GNU Radio master, which tracks the development towards GNU Radio 3.9.
|
||||
Hi,
|
||||
|
||||
this an IEEE 802.11 a/g/p transceiver for GNU Radio v3.7. Over the air, I tested it with the Ettus USRP N210 with XCVR2450 and CBX daughterboards. For interoperability tests I use mainly an Atheros (ath5k) WiFi card. The code can also be used for packet error rate simulations.
|
||||
|
||||
# Installation
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
Please note that ```apt-get``` is the package manager of Debian/Ubuntu based systems, while ```port``` is one package manager for OSX. So use either (not both) according to your needs.
|
||||
|
||||
### GNU Radio
|
||||
|
||||
### log4cpp
|
||||
|
||||
I use the new [logging feature](http://gnuradio.org/doc/doxygen/page_logger.html) of GNU Radio which relies on log4cpp. This should be an optional dependency some day, but currently it is required. You can install it with
|
||||
|
||||
sudo apt-get install liblog4cpp5-dev
|
||||
sudo port install log4cpp
|
||||
|
||||
|
||||
### GNU Radio v3.7
|
||||
|
||||
You need at least version 3.7.3.
|
||||
|
||||
There are several ways to install GNU Radio. You can use
|
||||
|
||||
- [pybombs](http://gnuradio.org/redmine/projects/pybombs/wiki)
|
||||
- [pre-compiled binaries](http://gnuradio.org/redmine/projects/gnuradio/wiki/BinaryPackages)
|
||||
- [pre-combiled binaries](http://gnuradio.org/redmine/projects/gnuradio/wiki/BinaryPackages)
|
||||
- [from source](http://gnuradio.org/redmine/projects/gnuradio/wiki/InstallingGRFromSource)
|
||||
|
||||
|
||||
### IT++
|
||||
|
||||
I use the Viterbi decoder of IT++.
|
||||
|
||||
sudo apt-get install libitpp-dev
|
||||
sudo port install itpp
|
||||
|
||||
|
||||
### gr-foo
|
||||
|
||||
I have some non project specific GNU Radio blocks in my gr-foo repo that are
|
||||
needed. For example the Wireshark connector. You can find these blocks at
|
||||
[https://github.com/bastibl/gr-foo](https://github.com/bastibl/gr-foo). They are
|
||||
installed with the typical command sequence:
|
||||
I have some non project specific GNU Radio blocks in my gr-foo repo that are needed. For example the Wireshark connector. You can find these blocks at [https://github.com/bastibl/gr-foo](https://github.com/bastibl/gr-foo). They are installed with the typical command sequence:
|
||||
|
||||
git clone https://github.com/bastibl/gr-foo.git
|
||||
cd gr-foo
|
||||
@@ -61,73 +65,48 @@ To actually install the blocks do
|
||||
sudo ldconfig
|
||||
|
||||
### Adjust Maximum Shared Memory
|
||||
Since the transmitter is using the Tagged Stream blocks it has to store a
|
||||
complete frame in the buffer before processing it. The default maximum shared
|
||||
memory might not be enough on most Linux systems. It can be increased with
|
||||
Since the transmitter is using the Tagged Stream blocks it has to store a complete frame in the buffer before processing it. The default maximum shared memory might not be enough on most Linux systems. It can be increased with
|
||||
|
||||
sudo sysctl -w kernel.shmmax=2147483648
|
||||
|
||||
|
||||
### OFDM PHY
|
||||
|
||||
The physical layer is encapsulated in a hierarchical block to allow for a
|
||||
clearer transceiver structure in GNU Radio Companion. This hierarchical block is
|
||||
not included in the installation process. You have to open
|
||||
```/examples/wifi_phy_hier.grc``` with GNU Radio Companion and build it. This
|
||||
will install the block in ```~/.grc_gnuradio/```.
|
||||
The physical layer is encapsulated in a hierarchical block to allow for a clearer transceiver structure in GNU Radio Companion. This hierarchical block is not included in the installation process. You have to open ```/examples/wifi_phy_hier.grc``` with GNU Radio Companion and build it. This will install the block in ```~/.grc_gnuradio/```.
|
||||
|
||||
|
||||
### Check message port connections
|
||||
|
||||
Sometime the connections between the message ports (the gray ones in GNU Radio
|
||||
Companion) break. Therefore, please open the flow graphs and assert that
|
||||
everything is connected. It should be pretty obvious how the blocks are supposed
|
||||
to be wired. Actually this should not happen anymore, so if your ports are still
|
||||
unconnected please drop me a mail.
|
||||
Sometime the connections between the message ports (the gray ones in GNU Radio Companion) break. Therefore, please open the flow graphs and assert that everything is connected. It should be pretty obvious how the blocks are supposed to be wired. Actually this should not happen anymore, so if your ports are still unconnected please drop me a mail.
|
||||
|
||||
|
||||
### Python OpenGL
|
||||
|
||||
If you want to run the receive demo (the one that plots the subcarrier
|
||||
constellations), please assert that you have python-opengl installed. The nongl
|
||||
version of the plot does not work for me.
|
||||
If you want to run the receive demo (the one that plots the subcarrier constellations), please assert that you have python-opengl installed. The nongl version of the plot does not work for me.
|
||||
|
||||
|
||||
### Run volk_profile
|
||||
|
||||
volk_profile is part of GNU Radio. It benchmarks different SIMD implementations
|
||||
on your PC and creates a configuration file that stores the fastest version of
|
||||
every function. This can speed up the computation considerably and is required
|
||||
in order to deal with the high rate of incoming samples.
|
||||
volk_profile is part of GNU Radio. It benchmarks different SIMD implementations on your PC and creates a configuration file that stores the fastest version of every function. This can speed up the computation considerably and is required in order to deal with the high rate of incoming samples.
|
||||
|
||||
|
||||
### Calibrate your daughterboard
|
||||
|
||||
If you have a WBX, SBX, or CBX daughterboard you should calibrate it in order to
|
||||
minimize IQ imbalance and TX DC offsets. See the [application
|
||||
notes](http://files.ettus.com/manual/page_calibration.html).
|
||||
If you have a WBX, SBX, or CBX daughterboard you should calibrate it in order to minimize IQ imbalance and TX DC offsets. See the [application notes](http://files.ettus.com/uhd_docs/manual/html/calibration.html).
|
||||
|
||||
|
||||
# Checking your installation
|
||||
|
||||
As a first step I recommend to test the ```wifi_loopback.grc``` flow graph. This
|
||||
flow graph does not need any hardware and allows you to ensure that the software
|
||||
part is installed correctly. So open the flow graph and run it. If everything
|
||||
works as intended you should see some decoded packets on the console.
|
||||
# Checking you installation
|
||||
|
||||
As a first step I recommend to test the ```wifi_loopback.grc``` flow graph. This flow graph does not need any hardware and allows you to ensure that the software part is installed correctly. So open the flow graph and run it. If everything works as intended you should see some decoded 'Hello World' packets in the console.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If GRC complains that it can't find some blocks (other than performance counters
|
||||
and hierarchical blocks) like
|
||||
If GRC complains that it can't find some blocks (other than performance counters and hierarchical blocks) like
|
||||
|
||||
>>> Error: Block key "ieee802_11_ofdm_mac" not found in Platform - grc(GNU Radio Companion)
|
||||
>>> Error: Block key "foo_packet_pad" not found in Platform - grc(GNU Radio Companion)
|
||||
|
||||
Most likely you used a different ```CMAKE_INSTALL_PREFIX``` for the module than
|
||||
for GNU Radio. Therefore, the blocks of the module ended up in a different
|
||||
directory and GRC can't find them. You have to tell GRC where these blocks are
|
||||
by creating/adding to your ```~/.gnuradio/config.conf``` something like
|
||||
Most likely you used a different ```CMAKE_INSTALL_PREFIX``` for the module than for GNU Radio. Therefore, the blocks of the module ended up in a different directory and GRC can't find them. You have to tell GRC where these blocks are by creating/adding to your ```~/.gnuradio/config.conf``` something like
|
||||
|
||||
[grc]
|
||||
global_blocks_path = /opt/local/share/gnuradio/grc/blocks
|
||||
@@ -141,69 +120,71 @@ But with the directories that match your installation.
|
||||
|
||||
## Simulation
|
||||
|
||||
The loopback flow graph should give you an idea of how simulations can be
|
||||
conducted. To ease use, most blocks have debugging and logging capabilities that
|
||||
can generate traces of the simulation. You can read about the logging feature
|
||||
and how to use it on the [GNU Radio
|
||||
Wiki](http://gnuradio.org/doc/doxygen/page_logger.html).
|
||||
The loopback flow graph should give you an idea of how simulations can be conducted. To ease use, most blocks have debugging and logging capabilities that can generate traces of the simulation. You can read about the logging feature and how to use it on the [GNU Radio Wiki](http://gnuradio.org/doc/doxygen/page_logger.html).
|
||||
|
||||
|
||||
## Unidirectional communication
|
||||
|
||||
As first over the air test I recommend to try ```wifi_rx.grc``` and
|
||||
```wifi_tx.grc```. Just open the flow graphs in GNU Radio companion and execute
|
||||
them. If it does not work out of the box, try to play around with the gain. If
|
||||
everything works as intended you should see similar output as in the
|
||||
```wifi_loopback.grc``` example.
|
||||
As first over the air test I recommend to try ```wifi_rx.grc``` and ```wifi_tx.grc```. Just open the flow graphs in GNU Radio companion and execute them. If it does not work out of the box, try to play around with the gain. If everything works as intended you should see similar output as in the ```wifi_loopback.grc``` example.
|
||||
|
||||
|
||||
## RX frames from a WiFi card
|
||||
|
||||
TBD
|
||||
|
||||
|
||||
## TX frames to a WiFi card
|
||||
|
||||
TBD
|
||||
|
||||
|
||||
## Transceiver (SDR <-> SDR)
|
||||
|
||||
TBD
|
||||
|
||||
|
||||
## Ad Hoc Network with WiFi card
|
||||
|
||||
- The transceiver is currently connected to a TAP device, i.e. is a virtual
|
||||
Ethernet interface. Therefore, we have no WiFi signaling like association
|
||||
requests and hence, the transceiver can not "join" an ad hoc network. You have
|
||||
to make some small changes to the kernel in order to convince you WiFi card to
|
||||
send to this hosts nevertheless.
|
||||
- The transceiver can not respond to ACKs in time. This is kind of an
|
||||
architectural limitation of USRP + GNU Radio since Ethernet and computations
|
||||
on a normal CPU introduce some latency. You can set the number of ACK retries
|
||||
to zero and handle retransmits on higher layers (-> TCP).
|
||||
- RTS/CTS is not working for the same reason. You can however just disable this
|
||||
mechanism.
|
||||
- Currently, there is no CSMA/CA mechanism, but this can be implemented on the
|
||||
FPGA.
|
||||
- The transceiver is currently connected to a TAP device, i.e. is a virtual Ethernet interface. Therefore, we have no WiFi signaling like association requests and hence, the transceiver can not "join" an ad hoc network. You have to make some small changes to the kernel in order to convince you WiFi card to send to this hosts nevertheless.
|
||||
- The transceiver can not respond to ACKs in time. This is kind of an architectural limitation of USRP + GNU Radio since Ethernet and computations on a normal CPU introduce some latency. You can set the number of ACK retries to zero and handle retransmits on higher layers (-> TCP).
|
||||
- RTS/CTS is not working for the same reason. You can however just disable this mechanism.
|
||||
- Currently, there is no CSMA/CA mechanism, but this can be implemented on the FPGA.
|
||||
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
- Please check compile and installation logs. They might contain interesting
|
||||
information.
|
||||
- Did you calibrate your daughterboard?
|
||||
- Did you run volk_profile?
|
||||
- Did you try different gain settings?
|
||||
- Did you close the case of the devices?
|
||||
- Did you try real-time priority?
|
||||
- Did you compile GNU Radio and gr-ieee802-11 in release mode?
|
||||
- If you see warnings that ```blocks_ctrlport_monitor_performance``` is missing
|
||||
that means that you installed GNU Radio without control port or performance
|
||||
counters. These blocks allow you to monitor the performance of the transceiver
|
||||
while it is running, but are not required. You can just delete them from the
|
||||
flow graph.
|
||||
- If you see warnings that ```blocks_ctrlport_monitor_performance``` is missing that means that you installed GNU Radio without control port or performance counters. These blocks allow you to monitor the performance of the transceiver while it is running, but are not required. You can just delete them from the flow graph.
|
||||
- The message
|
||||
|
||||
You must now use ifconfig to set its IP address. E.g.,
|
||||
$ sudo ifconfig tap0 192.168.200.1
|
||||
|
||||
is normal and is output by the TUN/Tap Block during startup. The configuration
|
||||
of the TUN/TAP interface is handled by the scripts in the ```apps``` folder.
|
||||
- Did you try to tune the RF frequency out of the band of interest (i.e. used
|
||||
the LO offset menu of the flow graphs)?
|
||||
- If 'D's appear, it might be related to your Ethernet card. Assert that you
|
||||
made the sysconf changes recommended by Ettus. Did you try to connect you PC
|
||||
directly to the USRP without a switch in between?
|
||||
is normal and is output by the TUN/Tap Block during startup. The configuration of the TUN/TAP interface is handled by the scripts in the ```apps``` folder.
|
||||
- Did you try to tune the RF frequency out of the band of interest (i.e. used the LO offset menu of the flow graphs)?
|
||||
- If 'D's appear, it might be related to your Ethernet card. Assert that you made the sysconf changes recommended by Ettus. Did you try to connect you PC directly to the USRP without a switch in between?
|
||||
|
||||
|
||||
# Asking for help
|
||||
|
||||
In order to help you it is crucial that you provide enough information about what is going wrong and what you are actually trying to do. So if you write me please include at least the following
|
||||
|
||||
- OS (Ubuntu, OSX...)
|
||||
- hardware (SDR and daughterboard)
|
||||
- GNU Radio version
|
||||
- What are you trying to do
|
||||
- What is you setup, i.e. are you transmitting between SDRs or with WiFi cards.
|
||||
- Bandwidth and frequency
|
||||
- What did you already do to debug?
|
||||
- Where exactly does it break, i.e. is frame detection working? Is the signal field decoded correctly?).
|
||||
|
||||
|
||||
# Further information
|
||||
|
||||
For further information please checkout our project page
|
||||
[https://www.wime-project.net](https://www.wime-project.net)
|
||||
[http://www.ccs-labs.org/projects/wime/](http://www.ccs-labs.org/projects/wime/)
|
||||
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
FILE="/tmp/ofdm.pcap"
|
||||
FLOWGRAPH="rx_agc_demo.py"
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
### create fifo
|
||||
if [ -e ${FILE} ]
|
||||
then
|
||||
echo "${FILE}: file already exists"
|
||||
if ! [ -p ${FILE} ]
|
||||
then
|
||||
echo "ERROR: ${FILE} exists and is not a FIFO"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "creating fifo: ${FILE}"
|
||||
mkfifo ${FILE}
|
||||
fi
|
||||
|
||||
|
||||
### create tap interface
|
||||
if [[ `ifconfig -a | grep tap0 | wc -l` -eq 0 ]]
|
||||
then
|
||||
sudo ip tuntap add dev tap0 user ${USER} mode tap
|
||||
fi
|
||||
|
||||
### reconfigure it in any case, just to be sure it's up
|
||||
sudo ifconfig tap0 down
|
||||
sudo ifconfig tap0 hw ether 12:34:56:78:90:ab
|
||||
sudo ifconfig tap0 up
|
||||
sudo ifconfig tap0 192.168.123.1
|
||||
|
||||
|
||||
### start transceiver
|
||||
cd ${DIR}
|
||||
cd ../examples/
|
||||
./${FLOWGRAPH} &
|
||||
sleep 1
|
||||
|
||||
|
||||
### start wireshark
|
||||
wireshark -k -i ${FILE} &
|
||||
sleep 1
|
||||
|
||||
|
||||
### start netcat
|
||||
echo "##########################################################################"
|
||||
echo "### starting netcat. Just type and the lines will be send to the flowgraph"
|
||||
echo "##########################################################################"
|
||||
sleep 2
|
||||
|
||||
#echo | nc -u localhost 52001
|
||||
cat
|
||||
|
||||
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
### Enable Wireshark Connector in wifi_rx flow graph
|
||||
|
||||
FILE="/tmp/wifi.pcap"
|
||||
FILE="/tmp/ofdm.pcap"
|
||||
FLOWGRAPH="wifi_rx.py"
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
|
||||
FIND_PATH(CPPUNIT_INCLUDE_DIRS
|
||||
NAMES cppunit/TestCase.h
|
||||
HINTS ${PC_CPPUNIT_INCLUDE_DIR}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
@@ -24,8 +23,6 @@ FIND_PATH(CPPUNIT_INCLUDE_DIRS
|
||||
FIND_LIBRARY(CPPUNIT_LIBRARIES
|
||||
NAMES cppunit
|
||||
HINTS ${PC_CPPUNIT_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS
|
||||
${CPPUNIT_INCLUDE_DIRS}/../lib
|
||||
/usr/local/lib
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime)
|
||||
|
||||
if(PC_GNURADIO_RUNTIME_FOUND)
|
||||
# look for include files
|
||||
FIND_PATH(
|
||||
GNURADIO_RUNTIME_INCLUDE_DIRS
|
||||
NAMES gnuradio/top_block.h
|
||||
HINTS $ENV{GNURADIO_RUNTIME_DIR}/include
|
||||
${PC_GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
# look for libs
|
||||
FIND_LIBRARY(
|
||||
GNURADIO_RUNTIME_LIBRARIES
|
||||
NAMES gnuradio-runtime
|
||||
HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib
|
||||
${PC_GNURADIO_RUNTIME_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib/
|
||||
${CMAKE_INSTALL_PREFIX}/lib64/
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND})
|
||||
endif(PC_GNURADIO_RUNTIME_FOUND)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
# do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used.
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES)
|
||||
MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS)
|
||||
@@ -0,0 +1,70 @@
|
||||
# - Find ITPP
|
||||
# Find the native ITPP includes and library
|
||||
# This module defines
|
||||
# ITPP_INCLUDE_DIR, where to find itpp/itbase.h, etc.
|
||||
# ITPP_LIBRARIES, the libraries needed to use ITPP.
|
||||
# ITPP_FOUND, If false, do not try to use ITPP.
|
||||
# also defined, but not for general use are
|
||||
# ITPP_LIBRARY, where to find the ITPP library.
|
||||
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(PC_ITPP itpp)
|
||||
|
||||
find_path(ITPP_INCLUDE_DIR
|
||||
NAMES itpp/itbase.h
|
||||
HINTS ${PC_ITPP_INCLUDEDIR}/include
|
||||
${ITPP_DIR}/include
|
||||
/usr/pkgs64/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
find_library(ITPP_LIBRARY_NORMAL
|
||||
NAMES itpp
|
||||
HINTS ${PC_ITPP_LIBDIR}
|
||||
PATHS ${ITPP_DIR}/libs
|
||||
"${ITPP_DIR}\\win32\\lib"
|
||||
/usr/pkgs64/lib
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
find_library(ITPP_LIBRARY_DEBUG
|
||||
NAMES itpp_debug
|
||||
HINTS ${PC_ITPP_LIBDIR}
|
||||
PATHS ${ITPP_DIR}/libs
|
||||
"${ITPP_DIR}\\win32\\lib"
|
||||
/usr/pkgs64/lib
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if (ITPP_LIBRARY_NORMAL OR ITPP_LIBRARY_DEBUG)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ITPP_LIBRARY_DEBUG)
|
||||
SET (ITPP_LIBRARY ${ITPP_LIBRARY_DEBUG})
|
||||
else (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ITPP_LIBRARY_DEBUG)
|
||||
SET (ITPP_LIBRARY ${ITPP_LIBRARY_NORMAL})
|
||||
endif (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ITPP_LIBRARY_DEBUG)
|
||||
endif (ITPP_LIBRARY_NORMAL OR ITPP_LIBRARY_DEBUG)
|
||||
|
||||
if (ITPP_LIBRARY AND ITPP_INCLUDE_DIR)
|
||||
SET(ITPP_LIBRARIES ${ITPP_LIBRARY})
|
||||
SET(ITPP_FOUND "YES")
|
||||
else (ITPP_LIBRARY AND ITPP_INCLUDE_DIR)
|
||||
SET(ITPP_FOUND "NO")
|
||||
endif (ITPP_LIBRARY AND ITPP_INCLUDE_DIR)
|
||||
|
||||
if (ITPP_FOUND)
|
||||
if (NOT ITPP_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found ITPP: ${ITPP_LIBRARIES}")
|
||||
endif (NOT ITPP_FIND_QUIETLY)
|
||||
else (ITPP_FOUND)
|
||||
if (ITPP_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find ITPP library")
|
||||
endif (ITPP_FIND_REQUIRED)
|
||||
endif (ITPP_FOUND)
|
||||
|
||||
mark_as_advanced(
|
||||
ITPP_LIBRARY
|
||||
ITPP_INCLUDE_DIR
|
||||
)
|
||||
@@ -94,13 +94,7 @@ macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
|
||||
if(${have})
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
|
||||
STRING(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_dup)
|
||||
if(${flag_dup} EQUAL -1)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
|
||||
endif(${flag_dup} EQUAL -1)
|
||||
endif(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
|
||||
add_definitions(${flag})
|
||||
endif(${have})
|
||||
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
|
||||
|
||||
|
||||
@@ -29,15 +29,15 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(LINUX TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/debian_version")
|
||||
if(LINUX AND EXISTS "/etc/debian_version")
|
||||
set(DEBIAN TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/redhat-release")
|
||||
if(LINUX AND EXISTS "/etc/redhat-release")
|
||||
set(REDHAT TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/slackware-version")
|
||||
if(LINUX AND EXISTS "/etc/slackware-version")
|
||||
set(SLACKWARE TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -185,6 +185,7 @@ function(GR_PYTHON_INSTALL)
|
||||
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
|
||||
)
|
||||
|
||||
|
||||
####################################################################
|
||||
elseif(GR_PYTHON_INSTALL_PROGRAMS)
|
||||
####################################################################
|
||||
@@ -206,7 +207,7 @@ function(GR_PYTHON_INSTALL)
|
||||
add_custom_command(
|
||||
OUTPUT ${pyexefile} DEPENDS ${pyfile}
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c
|
||||
"import re; R=re.compile('^\#!.*$\\n',flags=re.MULTILINE); open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+R.sub('',open('${pyfile}','r').read()))"
|
||||
"open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())"
|
||||
COMMENT "Shebangin ${pyfile_name}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ function(GR_SWIG_MAKE_DOCS output_file)
|
||||
set(input_files)
|
||||
unset(INPUT_PATHS)
|
||||
foreach(input_path ${ARGN})
|
||||
if(IS_DIRECTORY ${input_path}) #when input path is a directory
|
||||
if (IS_DIRECTORY ${input_path}) #when input path is a directory
|
||||
file(GLOB input_path_h_files ${input_path}/*.h)
|
||||
else() #otherwise its just a file, no glob
|
||||
set(input_path_h_files ${input_path})
|
||||
@@ -110,7 +110,7 @@ macro(GR_SWIG_MAKE name)
|
||||
# vector<long unsigned int> (on 64-bit machines). Use this to test
|
||||
# the size of size_t, then set SIZE_T_32 if it's a 32-bit machine
|
||||
# or not if it's 64-bit. The logic in gr_type.i handles the rest.
|
||||
INCLUDE(CheckTypeSize)
|
||||
INCLUDE (CheckTypeSize)
|
||||
CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
|
||||
CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT)
|
||||
if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
|
||||
@@ -118,7 +118,7 @@ macro(GR_SWIG_MAKE name)
|
||||
endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
|
||||
|
||||
#do swig doc generation if specified
|
||||
if(GR_SWIG_DOC_FILE)
|
||||
if (GR_SWIG_DOC_FILE)
|
||||
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
|
||||
list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS})
|
||||
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
|
||||
@@ -172,9 +172,6 @@ macro(GR_SWIG_MAKE name)
|
||||
include(UseSWIG)
|
||||
SWIG_ADD_MODULE(${name} python ${ifiles})
|
||||
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
|
||||
if(${name} STREQUAL "runtime_swig")
|
||||
SET_TARGET_PROPERTIES(${SWIG_MODULE_runtime_swig_REAL_NAME} PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS")
|
||||
endif(${name} STREQUAL "runtime_swig")
|
||||
|
||||
endmacro(GR_SWIG_MAKE)
|
||||
|
||||
|
||||
@@ -1,304 +0,0 @@
|
||||
# - SWIG module for CMake
|
||||
# Defines the following macros:
|
||||
# SWIG_ADD_MODULE(name language [ files ])
|
||||
# - Define swig module with given name and specified language
|
||||
# SWIG_LINK_LIBRARIES(name [ libraries ])
|
||||
# - Link libraries to swig module
|
||||
# All other macros are for internal use only.
|
||||
# To get the actual name of the swig module,
|
||||
# use: ${SWIG_MODULE_${name}_REAL_NAME}.
|
||||
# Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify
|
||||
# special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add
|
||||
# special flags to all swig calls.
|
||||
# Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify
|
||||
# where to write all the swig generated module (swig -outdir option)
|
||||
# The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used
|
||||
# to specify extra dependencies for the generated modules.
|
||||
# If the source file generated by swig need some special flag you can use
|
||||
# set_source_files_properties( ${swig_generated_file_fullname}
|
||||
# PROPERTIES COMPILE_FLAGS "-bla")
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2004-2009 Kitware, Inc.
|
||||
# Copyright 2009 Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
set(SWIG_CXX_EXTENSION "cxx")
|
||||
set(SWIG_EXTRA_LIBRARIES "")
|
||||
|
||||
set(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py")
|
||||
|
||||
#
|
||||
# For given swig module initialize variables associated with it
|
||||
#
|
||||
macro(SWIG_MODULE_INITIALIZE name language)
|
||||
string(TOUPPER "${language}" swig_uppercase_language)
|
||||
string(TOLOWER "${language}" swig_lowercase_language)
|
||||
set(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}")
|
||||
set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")
|
||||
|
||||
set(SWIG_MODULE_${name}_REAL_NAME "${name}")
|
||||
if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN")
|
||||
message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
|
||||
elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON")
|
||||
# when swig is used without the -interface it will produce in the module.py
|
||||
# a 'import _modulename' statement, which implies having a corresponding
|
||||
# _modulename.so (*NIX), _modulename.pyd (Win32).
|
||||
set(SWIG_MODULE_${name}_REAL_NAME "_${name}")
|
||||
elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL")
|
||||
set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# For a given language, input file, and output file, determine extra files that
|
||||
# will be generated. This is internal swig macro.
|
||||
#
|
||||
|
||||
macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
|
||||
set(${outfiles} "")
|
||||
get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename
|
||||
${infile} SWIG_MODULE_NAME)
|
||||
if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
|
||||
get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE)
|
||||
endif()
|
||||
foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSION})
|
||||
set(${outfiles} ${${outfiles}}
|
||||
"${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}")
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# Take swig (*.i) file and add proper custom commands for it
|
||||
#
|
||||
macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
|
||||
set(swig_full_infile ${infile})
|
||||
get_filename_component(swig_source_file_path "${infile}" PATH)
|
||||
get_filename_component(swig_source_file_name_we "${infile}" NAME_WE)
|
||||
get_source_file_property(swig_source_file_generated ${infile} GENERATED)
|
||||
get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS)
|
||||
get_source_file_property(swig_source_file_flags ${infile} SWIG_FLAGS)
|
||||
if("${swig_source_file_flags}" STREQUAL "NOTFOUND")
|
||||
set(swig_source_file_flags "")
|
||||
endif()
|
||||
set(swig_source_file_fullname "${infile}")
|
||||
if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
string(REGEX REPLACE
|
||||
"^${CMAKE_CURRENT_SOURCE_DIR}" ""
|
||||
swig_source_file_relative_path
|
||||
"${swig_source_file_path}")
|
||||
else()
|
||||
if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
|
||||
string(REGEX REPLACE
|
||||
"^${CMAKE_CURRENT_BINARY_DIR}" ""
|
||||
swig_source_file_relative_path
|
||||
"${swig_source_file_path}")
|
||||
set(swig_source_file_generated 1)
|
||||
else()
|
||||
set(swig_source_file_relative_path "${swig_source_file_path}")
|
||||
if(swig_source_file_generated)
|
||||
set(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}")
|
||||
else()
|
||||
set(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(swig_generated_file_fullname
|
||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if(swig_source_file_relative_path)
|
||||
set(swig_generated_file_fullname
|
||||
"${swig_generated_file_fullname}/${swig_source_file_relative_path}")
|
||||
endif()
|
||||
# If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
|
||||
if(CMAKE_SWIG_OUTDIR)
|
||||
set(swig_outdir ${CMAKE_SWIG_OUTDIR})
|
||||
else()
|
||||
set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
|
||||
swig_extra_generated_files
|
||||
"${swig_outdir}"
|
||||
"${infile}")
|
||||
set(swig_generated_file_fullname
|
||||
"${swig_generated_file_fullname}/${swig_source_file_name_we}")
|
||||
# add the language into the name of the file (i.e. TCL_wrap)
|
||||
# this allows for the same .i file to be wrapped into different languages
|
||||
set(swig_generated_file_fullname
|
||||
"${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap")
|
||||
|
||||
if(swig_source_file_cplusplus)
|
||||
set(swig_generated_file_fullname
|
||||
"${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}")
|
||||
else()
|
||||
set(swig_generated_file_fullname
|
||||
"${swig_generated_file_fullname}.c")
|
||||
endif()
|
||||
|
||||
# Shut up some warnings from poor SWIG code generation that we
|
||||
# can do nothing about, when this flag is available
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
|
||||
if(HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
|
||||
set_source_files_properties(${swig_generated_file_fullname}
|
||||
PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable")
|
||||
endif(HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
|
||||
|
||||
get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES)
|
||||
set(swig_include_dirs)
|
||||
foreach(it ${cmake_include_directories})
|
||||
set(swig_include_dirs ${swig_include_dirs} "-I${it}")
|
||||
endforeach()
|
||||
|
||||
set(swig_special_flags)
|
||||
# default is c, so add c++ flag if it is c++
|
||||
if(swig_source_file_cplusplus)
|
||||
set(swig_special_flags ${swig_special_flags} "-c++")
|
||||
endif()
|
||||
set(swig_extra_flags)
|
||||
if(SWIG_MODULE_${name}_EXTRA_FLAGS)
|
||||
set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
|
||||
endif()
|
||||
|
||||
# hack to work around CMake bug in add_custom_command with multiple OUTPUT files
|
||||
|
||||
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
|
||||
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
|
||||
print(re.sub('\\W', '_', '${name} ${reldir} ' + unique))"
|
||||
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
file(
|
||||
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in
|
||||
"int main(void){return 0;}\n"
|
||||
)
|
||||
|
||||
# create dummy dependencies
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp
|
||||
DEPENDS "${swig_source_file_fullname}" ${SWIG_MODULE_${name}_EXTRA_DEPS}
|
||||
COMMENT ""
|
||||
)
|
||||
|
||||
# create the dummy target
|
||||
add_executable(${_target} ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp)
|
||||
|
||||
# add a custom command to the dummy target
|
||||
add_custom_command(
|
||||
TARGET ${_target}
|
||||
# Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir)
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir}
|
||||
COMMAND "${SWIG_EXECUTABLE}"
|
||||
ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
|
||||
${swig_source_file_flags}
|
||||
${CMAKE_SWIG_FLAGS}
|
||||
-outdir ${swig_outdir}
|
||||
${swig_special_flags}
|
||||
${swig_extra_flags}
|
||||
${swig_include_dirs}
|
||||
-o "${swig_generated_file_fullname}"
|
||||
"${swig_source_file_fullname}"
|
||||
COMMENT "Swig source"
|
||||
)
|
||||
|
||||
#add dummy independent dependencies from the _target to each file
|
||||
#that will be generated by the SWIG command above
|
||||
|
||||
set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
|
||||
|
||||
foreach(swig_gen_file ${${outfiles}})
|
||||
add_custom_command(
|
||||
OUTPUT ${swig_gen_file}
|
||||
COMMAND ""
|
||||
DEPENDS ${_target}
|
||||
COMMENT ""
|
||||
)
|
||||
endforeach()
|
||||
|
||||
set_source_files_properties(
|
||||
${outfiles} PROPERTIES GENERATED 1
|
||||
)
|
||||
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# Create Swig module
|
||||
#
|
||||
macro(SWIG_ADD_MODULE name language)
|
||||
SWIG_MODULE_INITIALIZE(${name} ${language})
|
||||
set(swig_dot_i_sources)
|
||||
set(swig_other_sources)
|
||||
foreach(it ${ARGN})
|
||||
if(${it} MATCHES ".*\\.i$")
|
||||
set(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
|
||||
else()
|
||||
set(swig_other_sources ${swig_other_sources} "${it}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(swig_generated_sources)
|
||||
foreach(it ${swig_dot_i_sources})
|
||||
SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it})
|
||||
set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
|
||||
endforeach()
|
||||
get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
|
||||
set_directory_properties(PROPERTIES
|
||||
ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
|
||||
add_library(${SWIG_MODULE_${name}_REAL_NAME}
|
||||
MODULE
|
||||
${swig_generated_sources}
|
||||
${swig_other_sources})
|
||||
string(TOLOWER "${language}" swig_lowercase_language)
|
||||
if ("${swig_lowercase_language}" STREQUAL "java")
|
||||
if (APPLE)
|
||||
# In java you want:
|
||||
# System.loadLibrary("LIBRARY");
|
||||
# then JNI will look for a library whose name is platform dependent, namely
|
||||
# MacOS : libLIBRARY.jnilib
|
||||
# Windows: LIBRARY.dll
|
||||
# Linux : libLIBRARY.so
|
||||
set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
|
||||
endif ()
|
||||
endif ()
|
||||
if ("${swig_lowercase_language}" STREQUAL "python")
|
||||
# this is only needed for the python case where a _modulename.so is generated
|
||||
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
|
||||
# Python extension modules on Windows must have the extension ".pyd"
|
||||
# instead of ".dll" as of Python 2.5. Older python versions do support
|
||||
# this suffix.
|
||||
# http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000
|
||||
# <quote>
|
||||
# Windows: .dll is no longer supported as a filename extension for extension modules.
|
||||
# .pyd is now the only filename extension that will be searched for.
|
||||
# </quote>
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
|
||||
endif()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# Like TARGET_LINK_LIBRARIES but for swig modules
|
||||
#
|
||||
macro(SWIG_LINK_LIBRARIES name)
|
||||
if(SWIG_MODULE_${name}_REAL_NAME)
|
||||
target_link_libraries(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN})
|
||||
else()
|
||||
message(SEND_ERROR "Cannot find Swig library \"${name}\".")
|
||||
endif()
|
||||
endmacro()
|
||||
+1029
-1614
File diff suppressed because it is too large
Load Diff
+1518
-1541
File diff suppressed because it is too large
Load Diff
+2462
-3432
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2358
-3493
File diff suppressed because it is too large
Load Diff
+1697
-1734
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
<block>
|
||||
<name>Chunks to Symbols</name>
|
||||
<key>ieee802_11_chunks_to_symbols_xx</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.chunks_to_symbols()</make>
|
||||
<sink>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<block>
|
||||
<name>Ethernet Encapsulation</name>
|
||||
<key>ieee802_11_ether_encap</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ether_encap($debug)</make>
|
||||
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi Frame Equalizer</name>
|
||||
<key>ieee802_11_frame_equalizer</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.frame_equalizer($algo, $freq, $bw, $log, $debug)</make>
|
||||
<callback>set_algorithm($algo)</callback>
|
||||
<callback>set_frequency($freq)</callback>
|
||||
<callback>set_bandwidth($bw)</callback>
|
||||
|
||||
<param>
|
||||
<name>Algorithm</name>
|
||||
<key>algo</key>
|
||||
<value>ieee802_11.LS</value>
|
||||
<type>int</type>
|
||||
|
||||
<option>
|
||||
<name>LS</name>
|
||||
<key>ieee802_11.LS</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>LMS</name>
|
||||
<key>ieee802_11.LMS</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Comb</name>
|
||||
<key>ieee802_11.COMB</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>STA</name>
|
||||
<key>ieee802_11.STA</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>Frequency</name>
|
||||
<key>freq</key>
|
||||
<value>5.89e9</value>
|
||||
<type>real</type>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>Bandwidth</name>
|
||||
<key>bw</key>
|
||||
<value>10e6</value>
|
||||
<type>real</type>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
<key>log</key>
|
||||
<value>False</value>
|
||||
<type>bool</type>
|
||||
|
||||
<option>
|
||||
<name>Enable</name>
|
||||
<key>True</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Disable</name>
|
||||
<key>False</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>Debug</name>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
<type>bool</type>
|
||||
|
||||
<option>
|
||||
<name>Enable</name>
|
||||
<key>True</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Disable</name>
|
||||
<key>False</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type>complex</type>
|
||||
<vlen>64</vlen>
|
||||
<nports>1</nports>
|
||||
</sink>
|
||||
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type>byte</type>
|
||||
<vlen>48</vlen>
|
||||
<nports>1</nports>
|
||||
</source>
|
||||
|
||||
<source>
|
||||
<name>symbols</name>
|
||||
<type>message</type>
|
||||
<optional>1</optional>
|
||||
</source>
|
||||
|
||||
</block>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<block>
|
||||
<name>Moving Average</name>
|
||||
<key>ieee802_11_moving_average_xx</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.moving_average_$(type.fcn)($length)</make>
|
||||
<callback>set_length($length)</callback>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi Decode MAC</name>
|
||||
<key>ieee802_11_decode_mac</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<name>OFDM Decode MAC</name>
|
||||
<key>ieee802_11_ofdm_decode_mac</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.decode_mac($log, $debug)</make>
|
||||
<make>ieee802_11.ofdm_decode_mac($log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -41,14 +41,14 @@
|
||||
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type>byte</type>
|
||||
<type>complex</type>
|
||||
<vlen>48</vlen>
|
||||
<nports>1</nports>
|
||||
</sink>
|
||||
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type>message</type>
|
||||
<optional>1</optional>
|
||||
</source>
|
||||
|
||||
</block>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Decode Signal</name>
|
||||
<key>ieee802_11_ofdm_decode_signal</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_decode_signal($log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
<key>log</key>
|
||||
<value>False</value>
|
||||
<type>bool</type>
|
||||
|
||||
<option>
|
||||
<name>Enable</name>
|
||||
<key>True</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Disable</name>
|
||||
<key>False</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>Debug</name>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
<type>bool</type>
|
||||
|
||||
<option>
|
||||
<name>Enable</name>
|
||||
<key>True</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Disable</name>
|
||||
<key>False</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type>complex</type>
|
||||
<vlen>48</vlen>
|
||||
<nports>1</nports>
|
||||
</sink>
|
||||
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type>complex</type>
|
||||
<vlen>48</vlen>
|
||||
<nports>1</nports>
|
||||
</source>
|
||||
|
||||
</block>
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Equalize Symbols</name>
|
||||
<key>ieee802_11_ofdm_equalize_symbols</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_equalize_symbols($algo, $debug)</make>
|
||||
<callback>set_algorithm($algo)</callback>
|
||||
|
||||
<param>
|
||||
<name>Algorithm</name>
|
||||
<key>algo</key>
|
||||
<value>ieee802_11.LINEAR_COMB</value>
|
||||
<type>int</type>
|
||||
|
||||
<option>
|
||||
<name>LMS</name>
|
||||
<key>ieee802_11.LMS</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>linear comb</name>
|
||||
<key>ieee802_11.LINEAR_COMB</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>Debug</name>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
<type>bool</type>
|
||||
|
||||
<option>
|
||||
<name>Enable</name>
|
||||
<key>True</key>
|
||||
</option>
|
||||
<option>
|
||||
<name>Disable</name>
|
||||
<key>False</key>
|
||||
</option>
|
||||
</param>
|
||||
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type>complex</type>
|
||||
<vlen>64</vlen>
|
||||
<nports>1</nports>
|
||||
</sink>
|
||||
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type>complex</type>
|
||||
<vlen>48</vlen>
|
||||
<nports>1</nports>
|
||||
</source>
|
||||
|
||||
</block>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi MAC</name>
|
||||
<key>ieee802_11_mac</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<name>OFDM MAC</name>
|
||||
<key>ieee802_11_ofdm_mac</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.mac($src_mac, $dst_mac, $bss_mac)</make>
|
||||
<make>ieee802_11.ofdm_mac($src_mac, $dst_mac, $bss_mac)</make>
|
||||
|
||||
<param>
|
||||
<name>SRC MAC</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi Mapper</name>
|
||||
<key>ieee802_11_mapper</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<name>OFDM Mapper</name>
|
||||
<key>ieee802_11_ofdm_mapper</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.mapper($encoding, $debug)</make>
|
||||
<make>ieee802_11.ofdm_mapper($encoding, $debug)</make>
|
||||
<callback>set_encoding($encoding)</callback>
|
||||
|
||||
<param>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi Parse MAC</name>
|
||||
<key>ieee802_11_parse_mac</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<name>OFDM Parse MAC</name>
|
||||
<key>ieee802_11_ofdm_parse_mac</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.parse_mac($log, $debug)</make>
|
||||
<make>ieee802_11.ofdm_parse_mac($log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi Sync Long</name>
|
||||
<key>ieee802_11_sync_long</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<name>OFDM Sync Long</name>
|
||||
<key>ieee802_11_ofdm_sync_long</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.sync_long($sync_length, $log, $debug)</make>
|
||||
<make>ieee802_11.ofdm_sync_long($sync_length, $log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi Sync Short</name>
|
||||
<key>ieee802_11_sync_short</key>
|
||||
<category>[IEEE802.11]</category>
|
||||
<name>OFDM Sync Short</name>
|
||||
<key>ieee802_11_ofdm_sync_short</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.sync_short($threshold, $min_plateau, $log, $debug)</make>
|
||||
<make>ieee802_11.ofdm_sync_short($threshold, $min_plateau, $log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>WiFi EDCA</name>
|
||||
<key>ieee802_11_wifi_edca</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.wifi_edca($cw_min, $aifsn)</make>
|
||||
|
||||
<param>
|
||||
<name>CW min</name>
|
||||
<key>cw_min</key>
|
||||
<value>[15, 15, 7, 3]</value>
|
||||
<type>int_vector</type>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>AIFSN [slots]</name>
|
||||
<key>aifsn</key>
|
||||
<value>[9, 6, 3, 2]</value>
|
||||
<type>int_vector</type>
|
||||
</param>
|
||||
|
||||
<check>len($cw_min) == len($aifsn)</check>
|
||||
|
||||
<sink>
|
||||
<name>ac in</name>
|
||||
<type>message</type>
|
||||
<nports>len($cw_min)</nports>
|
||||
<optional>1</optional>
|
||||
</sink>
|
||||
|
||||
<source>
|
||||
<name>mac out</name>
|
||||
<type>message</type>
|
||||
</source>
|
||||
</block>
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -70,16 +70,17 @@ list(APPEND include_sources
|
||||
${generated_includes}
|
||||
api.h
|
||||
chunks_to_symbols.h
|
||||
constellations.h
|
||||
decode_mac.h
|
||||
ether_encap.h
|
||||
frame_equalizer.h
|
||||
mac.h
|
||||
mapper.h
|
||||
parse_mac.h
|
||||
signal_field.h
|
||||
sync_long.h
|
||||
sync_short.h
|
||||
ofdm_decode_mac.h
|
||||
ofdm_decode_signal.h
|
||||
ofdm_equalize_symbols.h
|
||||
ofdm_mac.h
|
||||
ofdm_mapper.h
|
||||
ofdm_parse_mac.h
|
||||
ofdm_sync_long.h
|
||||
ofdm_sync_short.h
|
||||
wifi_edca.h
|
||||
wifi_signal_field.h
|
||||
)
|
||||
|
||||
install(
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_CONSTELLATIONS_H
|
||||
#define INCLUDED_IEEE802_11_CONSTELLATIONS_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/digital/constellation.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API constellation_bpsk : virtual public digital::constellation
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<gr::ieee802_11::constellation_bpsk> sptr;
|
||||
static sptr make();
|
||||
|
||||
protected:
|
||||
constellation_bpsk();
|
||||
};
|
||||
|
||||
class IEEE802_11_API constellation_qpsk : virtual public digital::constellation
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<gr::ieee802_11::constellation_qpsk> sptr;
|
||||
static sptr make();
|
||||
|
||||
protected:
|
||||
constellation_qpsk();
|
||||
};
|
||||
|
||||
class IEEE802_11_API constellation_16qam : virtual public digital::constellation
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<gr::ieee802_11::constellation_16qam> sptr;
|
||||
static sptr make();
|
||||
|
||||
protected:
|
||||
constellation_16qam();
|
||||
};
|
||||
|
||||
class IEEE802_11_API constellation_64qam : virtual public digital::constellation
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<gr::ieee802_11::constellation_64qam> sptr;
|
||||
static sptr make();
|
||||
|
||||
protected:
|
||||
constellation_64qam();
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_CONSTELLATIONS_H */
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_FRAME_EQUALIZER_H
|
||||
#define INCLUDED_IEEE802_11_FRAME_EQUALIZER_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
enum Equalizer {
|
||||
LS = 0,
|
||||
LMS = 1,
|
||||
COMB = 2,
|
||||
STA = 3,
|
||||
};
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API frame_equalizer : virtual public gr::block
|
||||
{
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<frame_equalizer> sptr;
|
||||
static sptr make(Equalizer algo, double freq, double bw,
|
||||
bool log, bool debug);
|
||||
virtual void set_algorithm(Equalizer algo) = 0;
|
||||
virtual void set_bandwidth(double bw) = 0;
|
||||
virtual void set_frequency(double freq) = 0;
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_FRAME_EQUALIZER_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,8 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_PARSE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_PARSE_MAC_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,16 +23,18 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API parse_mac : virtual public block
|
||||
class IEEE802_11_API ofdm_decode_mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<parse_mac> sptr;
|
||||
typedef boost::shared_ptr<ofdm_decode_mac> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H */
|
||||
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_PARSE_MAC_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_DECODE_SIGNAL_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_DECODE_SIGNAL_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_decode_signal : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_decode_signal> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_DECODE_SIGNAL_H */
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
enum Equalizer {
|
||||
LMS = 0,
|
||||
LINEAR_COMB = 1,
|
||||
};
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_equalize_symbols : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_equalize_symbols> sptr;
|
||||
static sptr make(Equalizer algo, bool debug = false);
|
||||
virtual void set_algorithm(Equalizer algo) = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,8 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_MAC_H
|
||||
#define INCLUDED_IEEE802_11_MAC_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_MAC_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API mac : virtual public block
|
||||
class IEEE802_11_API ofdm_mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<mac> sptr;
|
||||
typedef boost::shared_ptr<ofdm_mac> sptr;
|
||||
static sptr make(std::vector<uint8_t> src_mac,
|
||||
std::vector<uint8_t> dst_mac,
|
||||
std::vector<uint8_t> bss_mac);
|
||||
@@ -36,4 +36,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_MAC_H */
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_MAC_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,8 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_MAPPER_H
|
||||
#define INCLUDED_IEEE802_11_MAPPER_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_MAPPER_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_MAPPER_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -34,11 +34,11 @@ enum Encoding {
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API mapper : virtual public block
|
||||
class IEEE802_11_API ofdm_mapper : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<mapper> sptr;
|
||||
typedef boost::shared_ptr<ofdm_mapper> sptr;
|
||||
static sptr make(Encoding mcs, bool debug = false);
|
||||
virtual void set_encoding(Encoding mcs) = 0;
|
||||
};
|
||||
@@ -46,4 +46,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_MAPPER_H */
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_MAPPER_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,8 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_DECODE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_DECODE_MAC_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API decode_mac : virtual public block
|
||||
class IEEE802_11_API ofdm_parse_mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<decode_mac> sptr;
|
||||
typedef boost::shared_ptr<ofdm_parse_mac> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
@@ -35,6 +35,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_DECODE_MAC_H */
|
||||
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,8 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_SYNC_LONG_H
|
||||
#define INCLUDED_IEEE802_11_SYNC_LONG_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API sync_long : virtual public block
|
||||
class IEEE802_11_API ofdm_sync_long : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<sync_long> sptr;
|
||||
typedef boost::shared_ptr<ofdm_sync_long> sptr;
|
||||
static sptr make(unsigned int sync_length,
|
||||
bool log = false, bool debug = false);
|
||||
|
||||
@@ -36,4 +36,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_SYNC_LONG_H */
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,8 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_SYNC_SHORT_H
|
||||
#define INCLUDED_IEEE802_11_SYNC_SHORT_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API sync_short : virtual public block
|
||||
class IEEE802_11_API ofdm_sync_short : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<sync_short> sptr;
|
||||
typedef boost::shared_ptr<ofdm_sync_short> sptr;
|
||||
static sptr make(double threshold, unsigned int min_plateau, bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
@@ -35,4 +35,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_SYNC_SHORT_H */
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_WIFI_EDCA_H
|
||||
#define INCLUDED_IEEE802_11_WIFI_EDCA_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API wifi_edca : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<wifi_edca> sptr;
|
||||
static sptr make(std::vector<uint16_t>cw_min, std::vector<uint16_t>aifsn);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_WIFI_EDCA_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,8 +15,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_H
|
||||
#define INCLUDED_IEEE802_11_SIGNAL_FIELD_H
|
||||
#ifndef INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H
|
||||
#define INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/digital/packet_header_default.h>
|
||||
@@ -24,18 +24,18 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API signal_field : virtual public digital::packet_header_default
|
||||
class IEEE802_11_API wifi_signal_field : virtual public digital::packet_header_default
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<signal_field> sptr;
|
||||
typedef boost::shared_ptr<wifi_signal_field> sptr;
|
||||
static sptr make();
|
||||
|
||||
protected:
|
||||
signal_field();
|
||||
wifi_signal_field();
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_H */
|
||||
#endif /* INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H */
|
||||
|
||||
+14
-16
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -94,29 +94,27 @@ add_dependencies(ieee802_11_generated_sources ieee802_11_generated_includes)
|
||||
########################################################################
|
||||
list(APPEND gr_ieee802_11_sources
|
||||
${generated_sources}
|
||||
chunks_to_symbols_impl.cc
|
||||
constellations_impl.cc
|
||||
decode_mac.cc
|
||||
equalizer/base.cc
|
||||
equalizer/comb.cc
|
||||
equalizer/ls.cc
|
||||
equalizer/linear_comb.cc
|
||||
equalizer/lms.cc
|
||||
equalizer/sta.cc
|
||||
chunks_to_symbols_impl.cc
|
||||
ether_encap_impl.cc
|
||||
frame_equalizer_impl.cc
|
||||
mac.cc
|
||||
mapper.cc
|
||||
parse_mac.cc
|
||||
signal_field_impl.cc
|
||||
sync_long.cc
|
||||
sync_short.cc
|
||||
ofdm_decode_mac.cc
|
||||
ofdm_decode_signal.cc
|
||||
ofdm_equalize_symbols.cc
|
||||
ofdm_mac.cc
|
||||
ofdm_mapper.cc
|
||||
ofdm_parse_mac.cc
|
||||
ofdm_sync_long.cc
|
||||
ofdm_sync_short.cc
|
||||
utils.cc
|
||||
viterbi_decoder.cc
|
||||
wifi_edca.cc
|
||||
wifi_signal_field_impl.cc
|
||||
)
|
||||
|
||||
list(APPEND gr_ieee802_11_libs
|
||||
${Boost_LIBRARIES}
|
||||
${GNURADIO_ALL_LIBRARIES}
|
||||
${ITPP_LIBRARIES}
|
||||
${LOG4CPP_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
@@ -28,17 +28,10 @@ chunks_to_symbols::make()
|
||||
return gnuradio::get_initial_sptr(new chunks_to_symbols_impl());
|
||||
}
|
||||
|
||||
chunks_to_symbols_impl::chunks_to_symbols_impl() :
|
||||
tagged_stream_block("chunks_to_symbols",
|
||||
io_signature::make(1, 1, sizeof(char)),
|
||||
io_signature::make(1, 1, sizeof(gr_complex)), "packet_len") {
|
||||
|
||||
d_bpsk = constellation_bpsk::make();
|
||||
d_qpsk = constellation_qpsk::make();
|
||||
d_16qam = constellation_16qam::make();
|
||||
d_64qam = constellation_64qam::make();
|
||||
|
||||
d_mapping = d_bpsk;
|
||||
chunks_to_symbols_impl::chunks_to_symbols_impl()
|
||||
: tagged_stream_block("wifi_chunks_to_symbols",
|
||||
io_signature::make(1, 1, sizeof(char)),
|
||||
io_signature::make(1, 1, sizeof(gr_complex)), "packet_len") {
|
||||
}
|
||||
|
||||
chunks_to_symbols_impl::~chunks_to_symbols_impl() { }
|
||||
@@ -63,25 +56,27 @@ chunks_to_symbols_impl::work(int noutput_items,
|
||||
|
||||
Encoding encoding = (Encoding)pmt::to_long(tags[0].value);
|
||||
|
||||
const gr_complex *mapping;
|
||||
|
||||
switch (encoding) {
|
||||
case BPSK_1_2:
|
||||
case BPSK_3_4:
|
||||
d_mapping = d_bpsk;
|
||||
mapping = BPSK;
|
||||
break;
|
||||
|
||||
case QPSK_1_2:
|
||||
case QPSK_3_4:
|
||||
d_mapping = d_qpsk;
|
||||
mapping = QPSK;
|
||||
break;
|
||||
|
||||
case QAM16_1_2:
|
||||
case QAM16_3_4:
|
||||
d_mapping = d_16qam;
|
||||
mapping = QAM16;
|
||||
break;
|
||||
|
||||
case QAM64_2_3:
|
||||
case QAM64_3_4:
|
||||
d_mapping = d_64qam;
|
||||
mapping = QAM64;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -90,8 +85,60 @@ chunks_to_symbols_impl::work(int noutput_items,
|
||||
}
|
||||
|
||||
for(int i = 0; i < ninput_items[0]; i++) {
|
||||
d_mapping->map_to_points(in[i], out + i);
|
||||
out[i] = mapping[in[i]];
|
||||
}
|
||||
|
||||
return ninput_items[0];
|
||||
}
|
||||
|
||||
const gr_complex chunks_to_symbols_impl::BPSK[2] = {
|
||||
gr_complex(-1.0, 0.0), gr_complex(1.0, 0.0)};
|
||||
|
||||
const gr_complex chunks_to_symbols_impl::QPSK[4] = {
|
||||
gr_complex(-0.7071, -0.7071), gr_complex(-0.7071, 0.7071),
|
||||
gr_complex(+0.7071, -0.7071), gr_complex(+0.7071, 0.7071)};
|
||||
|
||||
const gr_complex chunks_to_symbols_impl::QAM16[16] = {
|
||||
gr_complex(-0.9487, -0.9487), gr_complex(-0.9487, -0.3162),
|
||||
gr_complex(-0.9487, 0.9487), gr_complex(-0.9487, 0.3162),
|
||||
gr_complex(-0.3162, -0.9487), gr_complex(-0.3162, -0.3162),
|
||||
gr_complex(-0.3162, 0.9487), gr_complex(-0.3162, 0.3162),
|
||||
gr_complex(0.9487, -0.9487), gr_complex(0.9487, -0.3162),
|
||||
gr_complex(0.9487, 0.9487), gr_complex(0.9487, 0.3162),
|
||||
gr_complex(0.3162, -0.9487), gr_complex(0.3162, -0.3162),
|
||||
gr_complex(0.3162, 0.9487), gr_complex(0.3162, 0.3162)};
|
||||
|
||||
const gr_complex chunks_to_symbols_impl::QAM64[64] = {
|
||||
gr_complex(-1.0801, -1.0801), gr_complex(-1.0801, -0.7715),
|
||||
gr_complex(-1.0801, -0.1543), gr_complex(-1.0801, -0.4629),
|
||||
gr_complex(-1.0801, 1.0801), gr_complex(-1.0801, 0.7715),
|
||||
gr_complex(-1.0801, 0.1543), gr_complex(-1.0801, 0.4629),
|
||||
gr_complex(-0.7715, -1.0801), gr_complex(-0.7715, -0.7715),
|
||||
gr_complex(-0.7715, -0.1543), gr_complex(-0.7715, -0.4629),
|
||||
gr_complex(-0.7715, 1.0801), gr_complex(-0.7715, 0.7715),
|
||||
gr_complex(-0.7715, 0.1543), gr_complex(-0.7715, 0.4629),
|
||||
gr_complex(-0.1543, -1.0801), gr_complex(-0.1543, -0.7715),
|
||||
gr_complex(-0.1543, -0.1543), gr_complex(-0.1543, -0.4629),
|
||||
gr_complex(-0.1543, 1.0801), gr_complex(-0.1543, 0.7715),
|
||||
gr_complex(-0.1543, 0.1543), gr_complex(-0.1543, 0.4629),
|
||||
gr_complex(-0.4629, -1.0801), gr_complex(-0.4629, -0.7715),
|
||||
gr_complex(-0.4629, -0.1543), gr_complex(-0.4629, -0.4629),
|
||||
gr_complex(-0.4629, 1.0801), gr_complex(-0.4629, 0.7715),
|
||||
gr_complex(-0.4629, 0.1543), gr_complex(-0.4629, 0.4629),
|
||||
gr_complex(1.0801, -1.0801), gr_complex(1.0801, -0.7715),
|
||||
gr_complex(1.0801, -0.1543), gr_complex(1.0801, -0.4629),
|
||||
gr_complex(1.0801, 1.0801), gr_complex(1.0801, 0.7715),
|
||||
gr_complex(1.0801, 0.1543), gr_complex(1.0801, 0.4629),
|
||||
gr_complex(0.7715, -1.0801), gr_complex(0.7715, -0.7715),
|
||||
gr_complex(0.7715, -0.1543), gr_complex(0.7715, -0.4629),
|
||||
gr_complex(0.7715, 1.0801), gr_complex(0.7715, 0.7715),
|
||||
gr_complex(0.7715, 0.1543), gr_complex(0.7715, 0.4629),
|
||||
gr_complex(0.1543, -1.0801), gr_complex(0.1543, -0.7715),
|
||||
gr_complex(0.1543, -0.1543), gr_complex(0.1543, -0.4629),
|
||||
gr_complex(0.1543, 1.0801), gr_complex(0.1543, 0.7715),
|
||||
gr_complex(0.1543, 0.1543), gr_complex(0.1543, 0.4629),
|
||||
gr_complex(0.4629, -1.0801), gr_complex(0.4629, -0.7715),
|
||||
gr_complex(0.4629, -0.1543), gr_complex(0.4629, -0.4629),
|
||||
gr_complex(0.4629, 1.0801), gr_complex(0.4629, 0.7715),
|
||||
gr_complex(0.4629, 0.1543), gr_complex(0.4629, 0.4629)};
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#define INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_IMPL_H
|
||||
|
||||
#include <ieee802-11/chunks_to_symbols.h>
|
||||
#include <ieee802-11/constellations.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
@@ -34,12 +33,11 @@ public:
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<gr::digital::constellation> d_mapping;
|
||||
constellation_bpsk::sptr d_bpsk;
|
||||
constellation_qpsk::sptr d_qpsk;
|
||||
constellation_16qam::sptr d_16qam;
|
||||
constellation_64qam::sptr d_64qam;
|
||||
protected:
|
||||
static const gr_complex BPSK[2];
|
||||
static const gr_complex QPSK[4];
|
||||
static const gr_complex QAM16[16];
|
||||
static const gr_complex QAM64[64];
|
||||
};
|
||||
|
||||
} /* namespace ieee802_11 */
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "constellations_impl.h"
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
constellation_bpsk::sptr
|
||||
constellation_bpsk::make() {
|
||||
return constellation_bpsk::sptr(new constellation_bpsk_impl());
|
||||
}
|
||||
|
||||
constellation_bpsk::constellation_bpsk() {}
|
||||
|
||||
constellation_bpsk_impl::constellation_bpsk_impl() {
|
||||
d_constellation.resize(2);
|
||||
d_constellation[0] = gr_complex(-1, 0);
|
||||
d_constellation[1] = gr_complex(1, 0);
|
||||
d_rotational_symmetry = 2;
|
||||
d_dimensionality = 1;
|
||||
calc_arity();
|
||||
}
|
||||
|
||||
constellation_bpsk_impl::~constellation_bpsk_impl() {
|
||||
}
|
||||
|
||||
unsigned int
|
||||
constellation_bpsk_impl::decision_maker(const gr_complex *sample) {
|
||||
return (real(*sample) > 0);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
constellation_qpsk::sptr
|
||||
constellation_qpsk::make() {
|
||||
return constellation_qpsk::sptr(new constellation_qpsk_impl());
|
||||
}
|
||||
|
||||
constellation_qpsk::constellation_qpsk() {}
|
||||
|
||||
constellation_qpsk_impl::constellation_qpsk_impl() {
|
||||
const float level = sqrt(float(0.5));
|
||||
d_constellation.resize(4);
|
||||
// Gray-coded
|
||||
d_constellation[0] = gr_complex(-level, -level);
|
||||
d_constellation[1] = gr_complex( level, -level);
|
||||
d_constellation[2] = gr_complex(-level, level);
|
||||
d_constellation[3] = gr_complex( level, level);
|
||||
|
||||
d_rotational_symmetry = 4;
|
||||
d_dimensionality = 1;
|
||||
calc_arity();
|
||||
}
|
||||
|
||||
constellation_qpsk_impl::~constellation_qpsk_impl() {
|
||||
}
|
||||
|
||||
unsigned int
|
||||
constellation_qpsk_impl::decision_maker(const gr_complex *sample) {
|
||||
return 2*(imag(*sample)>0) + (real(*sample)>0);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
constellation_16qam::sptr
|
||||
constellation_16qam::make() {
|
||||
return constellation_16qam::sptr(new constellation_16qam_impl());
|
||||
}
|
||||
|
||||
constellation_16qam::constellation_16qam() {}
|
||||
|
||||
constellation_16qam_impl::constellation_16qam_impl()
|
||||
{
|
||||
const float level = sqrt(float(0.1));
|
||||
d_constellation.resize(16);
|
||||
|
||||
d_constellation[ 0] = gr_complex(-3*level,-3*level);
|
||||
d_constellation[ 1] = gr_complex( 3*level,-3*level);
|
||||
d_constellation[ 2] = gr_complex(-1*level,-3*level);
|
||||
d_constellation[ 3] = gr_complex( 1*level,-3*level);
|
||||
d_constellation[ 4] = gr_complex(-3*level, 3*level);
|
||||
d_constellation[ 5] = gr_complex( 3*level, 3*level);
|
||||
d_constellation[ 6] = gr_complex(-1*level, 3*level);
|
||||
d_constellation[ 7] = gr_complex( 1*level, 3*level);
|
||||
d_constellation[ 8] = gr_complex(-3*level,-1*level);
|
||||
d_constellation[ 9] = gr_complex( 3*level,-1*level);
|
||||
d_constellation[10] = gr_complex(-1*level,-1*level);
|
||||
d_constellation[11] = gr_complex( 1*level,-1*level);
|
||||
d_constellation[12] = gr_complex(-3*level, 1*level);
|
||||
d_constellation[13] = gr_complex( 3*level, 1*level);
|
||||
d_constellation[14] = gr_complex(-1*level, 1*level);
|
||||
d_constellation[15] = gr_complex( 1*level, 1*level);
|
||||
|
||||
d_rotational_symmetry = 4;
|
||||
d_dimensionality = 1;
|
||||
calc_arity();
|
||||
}
|
||||
|
||||
constellation_16qam_impl::~constellation_16qam_impl() {
|
||||
}
|
||||
|
||||
unsigned int
|
||||
constellation_16qam_impl::decision_maker(const gr_complex *sample)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
const float level = sqrt(float(0.1));
|
||||
float re = sample->real();
|
||||
float im = sample->imag();
|
||||
|
||||
ret |= re > 0;
|
||||
ret |= (std::abs(re) < (2*level)) << 1;
|
||||
ret |= (im > 0) << 2;
|
||||
ret |= (std::abs(im) < (2*level)) << 3;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
constellation_64qam::sptr
|
||||
constellation_64qam::make() {
|
||||
return constellation_64qam::sptr(new constellation_64qam_impl());
|
||||
}
|
||||
|
||||
constellation_64qam::constellation_64qam() {}
|
||||
|
||||
constellation_64qam_impl::constellation_64qam_impl() {
|
||||
const float level = sqrt(float(1/42.0));
|
||||
d_constellation.resize(64);
|
||||
|
||||
d_constellation[ 0] = gr_complex(-7*level,-7*level);
|
||||
d_constellation[ 1] = gr_complex( 7*level,-7*level);
|
||||
d_constellation[ 2] = gr_complex(-1*level,-7*level);
|
||||
d_constellation[ 3] = gr_complex( 1*level,-7*level);
|
||||
d_constellation[ 4] = gr_complex(-5*level,-7*level);
|
||||
d_constellation[ 5] = gr_complex( 5*level,-7*level);
|
||||
d_constellation[ 6] = gr_complex(-3*level,-7*level);
|
||||
d_constellation[ 7] = gr_complex( 3*level,-7*level);
|
||||
d_constellation[ 8] = gr_complex(-7*level, 7*level);
|
||||
d_constellation[ 9] = gr_complex( 7*level, 7*level);
|
||||
d_constellation[10] = gr_complex(-1*level, 7*level);
|
||||
d_constellation[11] = gr_complex( 1*level, 7*level);
|
||||
d_constellation[12] = gr_complex(-5*level, 7*level);
|
||||
d_constellation[13] = gr_complex( 5*level, 7*level);
|
||||
d_constellation[14] = gr_complex(-3*level, 7*level);
|
||||
d_constellation[15] = gr_complex( 3*level, 7*level);
|
||||
d_constellation[16] = gr_complex(-7*level,-1*level);
|
||||
d_constellation[17] = gr_complex( 7*level,-1*level);
|
||||
d_constellation[18] = gr_complex(-1*level,-1*level);
|
||||
d_constellation[19] = gr_complex( 1*level,-1*level);
|
||||
d_constellation[20] = gr_complex(-5*level,-1*level);
|
||||
d_constellation[21] = gr_complex( 5*level,-1*level);
|
||||
d_constellation[22] = gr_complex(-3*level,-1*level);
|
||||
d_constellation[23] = gr_complex( 3*level,-1*level);
|
||||
d_constellation[24] = gr_complex(-7*level, 1*level);
|
||||
d_constellation[25] = gr_complex( 7*level, 1*level);
|
||||
d_constellation[26] = gr_complex(-1*level, 1*level);
|
||||
d_constellation[27] = gr_complex( 1*level, 1*level);
|
||||
d_constellation[28] = gr_complex(-5*level, 1*level);
|
||||
d_constellation[29] = gr_complex( 5*level, 1*level);
|
||||
d_constellation[30] = gr_complex(-3*level, 1*level);
|
||||
d_constellation[31] = gr_complex( 3*level, 1*level);
|
||||
d_constellation[32] = gr_complex(-7*level,-5*level);
|
||||
d_constellation[33] = gr_complex( 7*level,-5*level);
|
||||
d_constellation[34] = gr_complex(-1*level,-5*level);
|
||||
d_constellation[35] = gr_complex( 1*level,-5*level);
|
||||
d_constellation[36] = gr_complex(-5*level,-5*level);
|
||||
d_constellation[37] = gr_complex( 5*level,-5*level);
|
||||
d_constellation[38] = gr_complex(-3*level,-5*level);
|
||||
d_constellation[39] = gr_complex( 3*level,-5*level);
|
||||
d_constellation[40] = gr_complex(-7*level, 5*level);
|
||||
d_constellation[41] = gr_complex( 7*level, 5*level);
|
||||
d_constellation[42] = gr_complex(-1*level, 5*level);
|
||||
d_constellation[43] = gr_complex( 1*level, 5*level);
|
||||
d_constellation[44] = gr_complex(-5*level, 5*level);
|
||||
d_constellation[45] = gr_complex( 5*level, 5*level);
|
||||
d_constellation[46] = gr_complex(-3*level, 5*level);
|
||||
d_constellation[47] = gr_complex( 3*level, 5*level);
|
||||
d_constellation[48] = gr_complex(-7*level,-3*level);
|
||||
d_constellation[49] = gr_complex( 7*level,-3*level);
|
||||
d_constellation[50] = gr_complex(-1*level,-3*level);
|
||||
d_constellation[51] = gr_complex( 1*level,-3*level);
|
||||
d_constellation[52] = gr_complex(-5*level,-3*level);
|
||||
d_constellation[53] = gr_complex( 5*level,-3*level);
|
||||
d_constellation[54] = gr_complex(-3*level,-3*level);
|
||||
d_constellation[55] = gr_complex( 3*level,-3*level);
|
||||
d_constellation[56] = gr_complex(-7*level, 3*level);
|
||||
d_constellation[57] = gr_complex( 7*level, 3*level);
|
||||
d_constellation[58] = gr_complex(-1*level, 3*level);
|
||||
d_constellation[59] = gr_complex( 1*level, 3*level);
|
||||
d_constellation[60] = gr_complex(-5*level, 3*level);
|
||||
d_constellation[61] = gr_complex( 5*level, 3*level);
|
||||
d_constellation[62] = gr_complex(-3*level, 3*level);
|
||||
d_constellation[63] = gr_complex( 3*level, 3*level);
|
||||
|
||||
d_rotational_symmetry = 4;
|
||||
d_dimensionality = 1;
|
||||
calc_arity();
|
||||
}
|
||||
|
||||
constellation_64qam_impl::~constellation_64qam_impl() {
|
||||
}
|
||||
|
||||
unsigned int
|
||||
constellation_64qam_impl::decision_maker(const gr_complex *sample) {
|
||||
unsigned int ret = 0;
|
||||
const float level = sqrt(float(1/42.0));
|
||||
float re = sample->real();
|
||||
float im = sample->imag();
|
||||
|
||||
ret |= re > 0;
|
||||
ret |= (std::abs(re) < (4*level)) << 1;
|
||||
ret |= (std::abs(re) < (6*level) && std::abs(re) > (2*level)) << 2;
|
||||
ret |= (im > 0) << 3;
|
||||
ret |= (std::abs(im) < (4*level)) << 4;
|
||||
ret |= (std::abs(im) < (6*level) && std::abs(im) > (2*level)) << 5;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_CONSTELLATIONS_IMPL_H
|
||||
#define INCLUDED_IEEE802_11_CONSTELLATIONS_IMPL_H
|
||||
|
||||
#include <ieee802-11/constellations.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class constellation_bpsk_impl : public constellation_bpsk
|
||||
{
|
||||
public:
|
||||
constellation_bpsk_impl();
|
||||
~constellation_bpsk_impl();
|
||||
|
||||
unsigned int decision_maker(const gr_complex *sample);
|
||||
};
|
||||
|
||||
|
||||
class constellation_qpsk_impl : public constellation_qpsk
|
||||
{
|
||||
public:
|
||||
constellation_qpsk_impl();
|
||||
~constellation_qpsk_impl();
|
||||
|
||||
unsigned int decision_maker(const gr_complex *sample);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class constellation_16qam_impl : public constellation_16qam
|
||||
{
|
||||
public:
|
||||
constellation_16qam_impl();
|
||||
~constellation_16qam_impl();
|
||||
|
||||
unsigned int decision_maker(const gr_complex *sample);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class constellation_64qam_impl : public constellation_64qam
|
||||
{
|
||||
public:
|
||||
constellation_64qam_impl();
|
||||
~constellation_64qam_impl();
|
||||
|
||||
unsigned int decision_maker(const gr_complex *sample);
|
||||
};
|
||||
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_CONSTELLATIONS_IMPL_H */
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/decode_mac.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "viterbi_decoder.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
#define LINKTYPE_IEEE802_11 105 /* http://www.tcpdump.org/linktypes.html */
|
||||
|
||||
class decode_mac_impl : public decode_mac {
|
||||
|
||||
public:
|
||||
decode_mac_impl(bool log, bool debug) :
|
||||
block("decode_mac",
|
||||
gr::io_signature::make(1, 1, 48),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_log(log),
|
||||
d_debug(debug),
|
||||
d_snr(0),
|
||||
d_nom_freq(0.0),
|
||||
d_freq_offset(0.0),
|
||||
d_ofdm(BPSK_1_2),
|
||||
d_frame(d_ofdm, 0),
|
||||
d_frame_complete(true) {
|
||||
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items) {
|
||||
|
||||
const uint8_t *in = (const uint8_t*)input_items[0];
|
||||
|
||||
int i = 0;
|
||||
|
||||
std::vector<gr::tag_t> tags;
|
||||
const uint64_t nread = this->nitems_read(0);
|
||||
|
||||
dout << "Decode MAC: input " << ninput_items[0] << std::endl;
|
||||
|
||||
while(i < ninput_items[0]) {
|
||||
|
||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
||||
pmt::string_to_symbol("wifi_start"));
|
||||
|
||||
if(tags.size()) {
|
||||
if (d_frame_complete == false) {
|
||||
dout << "Warning: starting to receive new frame before old frame was complete" << std::endl;
|
||||
dout << "Already copied " << copied << " out of " << d_frame.n_sym << " symbols of last frame" << std::endl;
|
||||
}
|
||||
d_frame_complete = false;
|
||||
|
||||
pmt::pmt_t dict = tags[0].value;
|
||||
int len_data = pmt::to_uint64(pmt::dict_ref(dict, pmt::mp("frame_bytes"), pmt::from_uint64(MAX_PSDU_SIZE+1)));
|
||||
int encoding = pmt::to_uint64(pmt::dict_ref(dict, pmt::mp("encoding"), pmt::from_uint64(0)));
|
||||
d_snr = pmt::to_double(pmt::dict_ref(dict, pmt::mp("snr"), pmt::from_double(0)));
|
||||
d_nom_freq = pmt::to_double(pmt::dict_ref(dict, pmt::mp("freq"), pmt::from_double(0)));
|
||||
d_freq_offset = pmt::to_double(pmt::dict_ref(dict, pmt::mp("freq_offset"), pmt::from_double(0)));
|
||||
|
||||
ofdm_param ofdm = ofdm_param((Encoding)encoding);
|
||||
frame_param frame = frame_param(ofdm, len_data);
|
||||
|
||||
// check for maximum frame size
|
||||
if(frame.n_sym <= MAX_SYM && frame.psdu_size <= MAX_PSDU_SIZE) {
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
copied = 0;
|
||||
dout << "Decode MAC: frame start -- len " << len_data
|
||||
<< " symbols " << frame.n_sym << " encoding "
|
||||
<< encoding << std::endl;
|
||||
} else {
|
||||
dout << "Dropping frame which is too large (symbols or bits)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(copied < d_frame.n_sym) {
|
||||
dout << "copy one symbol, copied " << copied << " out of " << d_frame.n_sym << std::endl;
|
||||
std::memcpy(d_rx_symbols + (copied * 48), in, 48);
|
||||
copied++;
|
||||
|
||||
if(copied == d_frame.n_sym) {
|
||||
dout << "received complete frame - decoding" << std::endl;
|
||||
decode();
|
||||
in += 48;
|
||||
i++;
|
||||
d_frame_complete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in += 48;
|
||||
i++;
|
||||
}
|
||||
|
||||
consume(0, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void decode() {
|
||||
|
||||
for(int i = 0; i < d_frame.n_sym * 48; i++) {
|
||||
for(int k = 0; k < d_ofdm.n_bpsc; k++) {
|
||||
d_rx_bits[i*d_ofdm.n_bpsc + k] = !!(d_rx_symbols[i] & (1 << k));
|
||||
}
|
||||
}
|
||||
|
||||
deinterleave();
|
||||
uint8_t *decoded = d_decoder.decode(&d_ofdm, &d_frame, d_deinterleaved_bits);
|
||||
descramble(decoded);
|
||||
print_output();
|
||||
|
||||
// skip service field
|
||||
boost::crc_32_type result;
|
||||
result.process_bytes(out_bytes + 2, d_frame.psdu_size);
|
||||
if(result.checksum() != 558161692) {
|
||||
dout << "checksum wrong -- dropping" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||
% d_ofdm.encoding % d_frame.psdu_size % d_frame.n_sym);
|
||||
|
||||
// create PDU
|
||||
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_frame.psdu_size - 4);
|
||||
pmt::pmt_t enc = pmt::from_uint64(d_ofdm.encoding);
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("encoding"), enc);
|
||||
dict = pmt::dict_add(dict, pmt::mp("snr"), pmt::from_double(d_snr));
|
||||
dict = pmt::dict_add(dict, pmt::mp("nomfreq"), pmt::from_double(d_nom_freq));
|
||||
dict = pmt::dict_add(dict, pmt::mp("freqofs"), pmt::from_double(d_freq_offset));
|
||||
dict = pmt::dict_add(dict, pmt::mp("dlt"), pmt::from_long(LINKTYPE_IEEE802_11));
|
||||
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
|
||||
}
|
||||
|
||||
void deinterleave() {
|
||||
|
||||
int n_cbps = d_ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
int second[n_cbps];
|
||||
int s = std::max(d_ofdm.n_bpsc / 2, 1);
|
||||
|
||||
for(int j = 0; j < n_cbps; j++) {
|
||||
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
||||
}
|
||||
|
||||
for(int i = 0; i < n_cbps; i++) {
|
||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for(int i = 0; i < d_frame.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
d_deinterleaved_bits[i * n_cbps + second[first[k]]] = d_rx_bits[i * n_cbps + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void descramble (uint8_t *decoded_bits) {
|
||||
|
||||
int state = 0;
|
||||
std::memset(out_bytes, 0, d_frame.psdu_size+2);
|
||||
|
||||
for(int i = 0; i < 7; i++) {
|
||||
if(decoded_bits[i]) {
|
||||
state |= 1 << (6 - i);
|
||||
}
|
||||
}
|
||||
out_bytes[0] = state;
|
||||
|
||||
int feedback;
|
||||
int bit;
|
||||
|
||||
for(int i = 7; i < d_frame.psdu_size*8+16; i++) {
|
||||
feedback = ((!!(state & 64))) ^ (!!(state & 8));
|
||||
bit = feedback ^ (decoded_bits[i] & 0x1);
|
||||
out_bytes[i/8] |= bit << (i%8);
|
||||
state = ((state << 1) & 0x7e) | feedback;
|
||||
}
|
||||
}
|
||||
|
||||
void print_output() {
|
||||
|
||||
dout << std::endl;
|
||||
dout << "psdu size" << d_frame.psdu_size << std::endl;
|
||||
for(int i = 2; i < d_frame.psdu_size+2; i++) {
|
||||
dout << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " ";
|
||||
if(i % 16 == 15) {
|
||||
dout << std::endl;
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
for(int i = 2; i < d_frame.psdu_size+2; i++) {
|
||||
if((out_bytes[i] > 31) && (out_bytes[i] < 127)) {
|
||||
dout << ((char) out_bytes[i]);
|
||||
} else {
|
||||
dout << ".";
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
bool d_debug;
|
||||
bool d_log;
|
||||
|
||||
frame_param d_frame;
|
||||
ofdm_param d_ofdm;
|
||||
double d_snr; // dB
|
||||
double d_nom_freq; // nominal frequency, Hz
|
||||
double d_freq_offset; // frequency offset, Hz
|
||||
viterbi_decoder d_decoder;
|
||||
|
||||
uint8_t d_rx_symbols[48 * MAX_SYM];
|
||||
uint8_t d_rx_bits[MAX_ENCODED_BITS];
|
||||
uint8_t d_deinterleaved_bits[MAX_ENCODED_BITS];
|
||||
uint8_t out_bytes[MAX_PSDU_SIZE + 2]; // 2 for signal field
|
||||
|
||||
int copied;
|
||||
bool d_frame_complete;
|
||||
};
|
||||
|
||||
decode_mac::sptr
|
||||
decode_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new decode_mac_impl(log, debug));
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "base.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace gr::ieee802_11::equalizer;
|
||||
|
||||
const gr_complex base::LONG[] = {
|
||||
0, 0, 0, 0, 0, 0, 1, 1, -1, -1,
|
||||
1, 1, -1, 1, -1, 1, 1, 1, 1, 1,
|
||||
1, -1, -1, 1, 1, -1, 1, -1, 1, 1,
|
||||
1, 1, 0, 1, -1, -1, 1, 1, -1, 1,
|
||||
-1, 1, -1, -1, -1, -1, -1, 1, 1, -1,
|
||||
-1, 1, -1, 1, -1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
const gr_complex base::POLARITY[127] = {
|
||||
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
|
||||
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
|
||||
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
|
||||
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
|
||||
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
|
||||
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
|
||||
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
|
||||
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
|
||||
@@ -19,7 +19,6 @@
|
||||
#define INCLUDED_IEEE802_11_EQUALIZER_BASE_H
|
||||
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/digital/constellation.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
@@ -28,13 +27,7 @@ namespace equalizer {
|
||||
class base {
|
||||
public:
|
||||
virtual ~base() {};
|
||||
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) = 0;
|
||||
virtual double get_snr() = 0;
|
||||
|
||||
static const gr_complex POLARITY[127];
|
||||
|
||||
protected:
|
||||
static const gr_complex LONG[64];
|
||||
virtual void equalize(const gr_complex *in, gr_complex *out, int n) = 0;
|
||||
};
|
||||
|
||||
} /* namespace channel_estimation */
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "comb.h"
|
||||
|
||||
using namespace gr::ieee802_11::equalizer;
|
||||
|
||||
void comb::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) {
|
||||
|
||||
gr_complex pilot[4];
|
||||
|
||||
if(n < 2) {
|
||||
pilot[0] = in[11];
|
||||
pilot[1] = -in[25];
|
||||
pilot[2] = in[39];
|
||||
pilot[3] = in[53];
|
||||
} else {
|
||||
gr_complex p = POLARITY[(n - 2) % 127];
|
||||
pilot[0] = in[11] * p;
|
||||
pilot[1] = in[25] * p;
|
||||
pilot[2] = in[39] * p;
|
||||
pilot[3] = in[53] * -p;
|
||||
}
|
||||
|
||||
gr_complex avg = (pilot[0] + pilot[1] + pilot[2] + pilot[3]) / gr_complex(4, 0);
|
||||
|
||||
for(int i = 0; i < 64; i++) {
|
||||
gr_complex H;
|
||||
if(i <= 11) {
|
||||
H = gr_complex((11-i) / 11.0, 0) * avg + gr_complex( i / 11.0, 0) * pilot[0];
|
||||
} else if(i <= 25) {
|
||||
H = gr_complex((25-i) / 14.0, 0) * pilot[0] + gr_complex((i-11) / 14.0, 0) * pilot[1];
|
||||
} else if(i <= 39) {
|
||||
H = gr_complex((39-i) / 14.0, 0) * pilot[1] + gr_complex((i-25) / 14.0, 0) * pilot[2];
|
||||
} else if(i <= 53) {
|
||||
H = gr_complex((53-i) / 14.0, 0) * pilot[2] + gr_complex((i-39) / 14.0, 0) * pilot[3];
|
||||
} else {
|
||||
H = gr_complex((64-i) / 11.0, 0) * pilot[3] + gr_complex((i-53) / 11.0, 0) * avg;
|
||||
}
|
||||
|
||||
if(n == 0) {
|
||||
d_H[i] = H;
|
||||
} else {
|
||||
d_H[i] = gr_complex(1-alpha, 0) * d_H[i] + gr_complex(alpha, 0) * H;
|
||||
}
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
} else {
|
||||
symbols[c] = in[i] / d_H[i];
|
||||
bits[c] = mod->decision_maker(&symbols[c]);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
comb::get_snr() {
|
||||
return 42;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "linear_comb.h"
|
||||
|
||||
using namespace gr::ieee802_11::equalizer;
|
||||
|
||||
void linear_comb::equalize(const gr_complex *in, gr_complex *out, int n) {
|
||||
if(n < 2)
|
||||
return;
|
||||
|
||||
double avg_mag = (abs(in[11]) + abs(in[25]) + abs(in[39]) + abs(in[53])) / 4;
|
||||
|
||||
gr_complex p = POLARITY[(n - 2) % 127 ];
|
||||
|
||||
double p1 = arg( p * in[11]);
|
||||
double p2 = arg( p * in[25] * conj(p * in[11])) + p1;
|
||||
double p3 = arg( p * in[39] * conj(p * in[25])) + p2;
|
||||
double p4 = arg(-p * in[53] * conj(p * in[39])) + p3;
|
||||
|
||||
double my = (p1 + p2 + p3 + p4) / 4;
|
||||
double mx = (11.0 + 25 + 39 + 53) / 4;
|
||||
|
||||
double var = (((11.0 * 11.0) + (25.0 * 25.0) + (39.0 * 39.0) + (53.0 * 53.0)) / 4) - (mx * mx);
|
||||
double cov = (( (p1 * 11) + (p2 * 25) + (p3 * 39) + (p4 * 53) ) / 4) - (mx * my);
|
||||
double beta = cov / var;
|
||||
double alpha = my - beta * mx;
|
||||
|
||||
int c = 0;
|
||||
for(int n = 0; n < 64; n++) {
|
||||
if( (n == 11) || (n == 25) || (n == 32) || (n == 39) || (n == 53) || (n < 6) || ( n > 58)) {
|
||||
continue;
|
||||
} else {
|
||||
out[c] = in[n] * exp(gr_complex(0, -n * beta - alpha)) * gr_complex(1 / avg_mag, 0);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const gr_complex linear_comb::POLARITY[127] = {
|
||||
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
|
||||
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
|
||||
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
|
||||
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
|
||||
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
|
||||
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
|
||||
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
|
||||
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
|
||||
@@ -15,8 +15,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_EQUALIZER_COMB_H
|
||||
#define INCLUDED_IEEE802_11_EQUALIZER_COMB_H
|
||||
#ifndef INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H
|
||||
#define INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
@@ -24,21 +24,16 @@ namespace gr {
|
||||
namespace ieee802_11 {
|
||||
namespace equalizer {
|
||||
|
||||
class comb: public base {
|
||||
class linear_comb: public base {
|
||||
public:
|
||||
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod);
|
||||
double get_snr();
|
||||
|
||||
virtual void equalize(const gr_complex *in, gr_complex *out, int n);
|
||||
private:
|
||||
gr_complex d_H[64];
|
||||
|
||||
|
||||
const double alpha = 0.2;
|
||||
static const gr_complex POLARITY[127];
|
||||
};
|
||||
|
||||
} /* namespace channel_estimation */
|
||||
} /* namespace ieee802_11 */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_EQUALIZER_COMB_H */
|
||||
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H */
|
||||
|
||||
+64
-24
@@ -21,44 +21,84 @@
|
||||
|
||||
using namespace gr::ieee802_11::equalizer;
|
||||
|
||||
void lms::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) {
|
||||
void lms::equalize(const gr_complex *in, gr_complex *out, int n) {
|
||||
|
||||
static float freq_offset = 0;
|
||||
static float freq_sum = 0;
|
||||
static float alpha = 0.9;
|
||||
|
||||
if(n == 0) {
|
||||
std::memcpy(d_H, in, 64 * sizeof(gr_complex));
|
||||
|
||||
std::memcpy(carrier, in, 64 * sizeof(gr_complex));
|
||||
} else if(n == 1) {
|
||||
double signal = 0;
|
||||
double noise = 0;
|
||||
gr_complex sum =
|
||||
(carrier[11] * conj(in[11])) +
|
||||
(carrier[25] * conj(in[25])) +
|
||||
(carrier[39] * conj(in[39])) +
|
||||
(carrier[53] * conj(in[53]));
|
||||
freq_offset = arg(sum);
|
||||
freq_sum = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if((i == 32) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
}
|
||||
noise += std::pow(std::abs(d_H[i] - in[i]), 2);
|
||||
signal += std::pow(std::abs(d_H[i] + in[i]), 2);
|
||||
d_H[i] += in[i];
|
||||
d_H[i] /= LONG[i] * gr_complex(2, 0);
|
||||
carrier[i] += in[i];
|
||||
carrier[i] *= ref[i] * gr_complex(0.5, 0);
|
||||
}
|
||||
|
||||
d_snr = 10 * std::log10(signal / noise / 2);
|
||||
|
||||
} else {
|
||||
|
||||
gr_complex p = POLARITY[(n - 2) % 127];
|
||||
gr_complex sum =
|
||||
(carrier[11] * conj(in[11]) * p) +
|
||||
(carrier[25] * conj(in[25]) * p) +
|
||||
(carrier[39] * conj(in[39]) * p) +
|
||||
(carrier[53] * conj(in[53]) * -p);
|
||||
|
||||
freq_offset = (1 - alpha) * freq_offset + alpha * arg(sum);
|
||||
freq_sum += freq_offset;
|
||||
|
||||
//std::cout << "lms: symbol " << n
|
||||
// << " p1 " << abs(carrier[11] * conj(in[11]) * p)
|
||||
// << " p2 " << abs(carrier[25] * conj(in[25]) * p)
|
||||
// << " p3 " << abs(carrier[39] * conj(in[39]) * p)
|
||||
// << " p4 " << abs(carrier[53] * conj(in[53]) * -p)
|
||||
// << std::endl;
|
||||
//std::cout << "lms: symbol " << n
|
||||
// << " p1 " << arg(carrier[11] * conj(in[11]) * p)
|
||||
// << " p2 " << arg(carrier[25] * conj(in[25]) * p)
|
||||
// << " p3 " << arg(carrier[39] * conj(in[39]) * p)
|
||||
// << " p4 " << arg(carrier[53] * conj(in[53]) * -p)
|
||||
// << std::endl;
|
||||
|
||||
carrier[11] = in[11] * p;
|
||||
carrier[25] = in[25] * p;
|
||||
carrier[39] = in[39] * p;
|
||||
carrier[53] = in[53] * -p;
|
||||
|
||||
int c = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
} else {
|
||||
symbols[c] = in[i] / d_H[i];
|
||||
bits[c] = mod->decision_maker(&symbols[c]);
|
||||
gr_complex point;
|
||||
mod->map_to_points(bits[c], &point);
|
||||
d_H[i] = gr_complex(1-alpha,0) * d_H[i] + gr_complex(alpha,0) * in[i] / point;
|
||||
out[c] = in[i] / carrier[i] * exp(gr_complex(0, freq_sum));
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
lms::get_snr() {
|
||||
return d_snr;
|
||||
}
|
||||
const gr_complex lms::ref[] = {
|
||||
0, 0, 0, 0, 0, 0, 1, 1, -1, -1,
|
||||
1, 1, -1, 1, -1, 1, 1, 1, 1, 1,
|
||||
1, -1, -1, 1, 1, -1, 1, -1, 1, 1,
|
||||
1, 1, 0, 1, -1, -1, 1, 1, -1, 1,
|
||||
-1, 1, -1, -1, -1, -1, -1, 1, 1, -1,
|
||||
-1, 1, -1, 1, -1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
const gr_complex lms::POLARITY[127] = {
|
||||
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
|
||||
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
|
||||
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
|
||||
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
|
||||
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
|
||||
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
|
||||
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
|
||||
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
|
||||
|
||||
+5
-7
@@ -27,14 +27,11 @@ namespace equalizer {
|
||||
|
||||
class lms: public base {
|
||||
public:
|
||||
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod);
|
||||
virtual void equalize(const gr_complex *in, gr_complex *out, int n);
|
||||
private:
|
||||
double get_snr();
|
||||
|
||||
|
||||
gr_complex d_H[64];
|
||||
double d_snr;
|
||||
const double alpha = 0.5;
|
||||
gr_complex carrier[64];
|
||||
static const gr_complex ref[64];
|
||||
static const gr_complex POLARITY[127];
|
||||
};
|
||||
|
||||
} /* namespace channel_estimation */
|
||||
@@ -42,3 +39,4 @@ private:
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LMS_H */
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ls.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace gr::ieee802_11::equalizer;
|
||||
|
||||
void ls::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) {
|
||||
|
||||
if(n == 0) {
|
||||
std::memcpy(d_H, in, 64 * sizeof(gr_complex));
|
||||
|
||||
} else if(n == 1) {
|
||||
double signal = 0;
|
||||
double noise = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if((i == 32) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
}
|
||||
noise += std::pow(std::abs(d_H[i] - in[i]), 2);
|
||||
signal += std::pow(std::abs(d_H[i] + in[i]), 2);
|
||||
d_H[i] += in[i];
|
||||
d_H[i] /= LONG[i] * gr_complex(2, 0);
|
||||
}
|
||||
|
||||
d_snr = 10 * std::log10(signal / noise / 2);
|
||||
|
||||
} else {
|
||||
|
||||
int c = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
} else {
|
||||
symbols[c] = in[i] / d_H[i];
|
||||
bits[c] = mod->decision_maker(&symbols[c]);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double ls::get_snr() {
|
||||
return d_snr;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_EQUALIZER_LS_H
|
||||
#define INCLUDED_IEEE802_11_EQUALIZER_LS_H
|
||||
|
||||
#include "base.h"
|
||||
#include <vector>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
namespace equalizer {
|
||||
|
||||
class ls: public base {
|
||||
public:
|
||||
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod);
|
||||
virtual double get_snr();
|
||||
private:
|
||||
gr_complex d_H[64];
|
||||
double d_snr;
|
||||
};
|
||||
|
||||
} /* namespace channel_estimation */
|
||||
} /* namespace ieee802_11 */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LS_H */
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sta.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace gr::ieee802_11::equalizer;
|
||||
|
||||
void sta::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) {
|
||||
|
||||
if(n == 0) {
|
||||
std::memcpy(d_H, in, 64 * sizeof(gr_complex));
|
||||
|
||||
} else if(n == 1) {
|
||||
double signal = 0;
|
||||
double noise = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if((i == 32) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
}
|
||||
noise += std::pow(std::abs(d_H[i] - in[i]), 2);
|
||||
signal += std::pow(std::abs(d_H[i] + in[i]), 2);
|
||||
d_H[i] += in[i];
|
||||
d_H[i] /= LONG[i] * gr_complex(2, 0);
|
||||
}
|
||||
|
||||
d_snr = 10 * std::log10(signal / noise / 2);
|
||||
|
||||
} else {
|
||||
|
||||
gr_complex H_update[64];
|
||||
gr_complex H[64];
|
||||
|
||||
gr_complex p = POLARITY[(n - 2) % 127];
|
||||
|
||||
H[11] = in[11] * p;
|
||||
H[25] = in[25] * p;
|
||||
H[39] = in[39] * p;
|
||||
H[53] = in[53] * -p;
|
||||
|
||||
int c = 0;
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
} else {
|
||||
symbols[c] = in[i] / d_H[i];
|
||||
bits[c] = mod->decision_maker(&symbols[c]);
|
||||
gr_complex point;
|
||||
mod->map_to_points(bits[c], &point);
|
||||
H[i] = in[i] / point;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < 64; i++) {
|
||||
int n = 0;
|
||||
gr_complex s = 0;
|
||||
for(int k = i-beta; k <= i+beta; k++) {
|
||||
if((k == 32) || (k < 6) || ( k > 58)) {
|
||||
continue;
|
||||
}
|
||||
n++;
|
||||
s += H[k];
|
||||
}
|
||||
H_update[i] = s / gr_complex(n, 0);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 64; i++) {
|
||||
if((i < 6) || ( i > 58)) {
|
||||
continue;
|
||||
}
|
||||
d_H[i] = gr_complex(1-alpha,0) * d_H[i] + gr_complex(alpha,0) * H_update[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
sta::get_snr() {
|
||||
return d_snr;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_EQUALIZER_STA_H
|
||||
#define INCLUDED_IEEE802_11_EQUALIZER_STA_H
|
||||
|
||||
#include "base.h"
|
||||
#include <vector>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
namespace equalizer {
|
||||
|
||||
class sta: public base {
|
||||
public:
|
||||
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod);
|
||||
double get_snr();
|
||||
|
||||
private:
|
||||
gr_complex d_H[64];
|
||||
double d_snr;
|
||||
|
||||
const double alpha = 0.5;
|
||||
const int beta = 2;
|
||||
};
|
||||
|
||||
} /* namespace channel_estimation */
|
||||
} /* namespace ieee802_11 */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_EQUALIZER_STA_H */
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "frame_equalizer_impl.h"
|
||||
#include "equalizer/base.h"
|
||||
#include "equalizer/comb.h"
|
||||
#include "equalizer/lms.h"
|
||||
#include "equalizer/ls.h"
|
||||
#include "equalizer/sta.h"
|
||||
#include "utils.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
frame_equalizer::sptr
|
||||
frame_equalizer::make(Equalizer algo, double freq, double bw, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr
|
||||
(new frame_equalizer_impl(algo, freq, bw, log, debug));
|
||||
}
|
||||
|
||||
|
||||
frame_equalizer_impl::frame_equalizer_impl(Equalizer algo, double freq, double bw, bool log, bool debug) :
|
||||
gr::block("frame_equalizer",
|
||||
gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, 48)),
|
||||
d_current_symbol(0), d_log(log), d_debug(debug), d_equalizer(NULL),
|
||||
d_freq(freq), d_bw(bw), d_frame_bytes(0), d_frame_symbols(0),
|
||||
d_freq_offset_from_synclong(0.0) {
|
||||
|
||||
message_port_register_out(pmt::mp("symbols"));
|
||||
|
||||
d_bpsk = constellation_bpsk::make();
|
||||
d_qpsk = constellation_qpsk::make();
|
||||
d_16qam = constellation_16qam::make();
|
||||
d_64qam = constellation_64qam::make();
|
||||
|
||||
d_frame_mod = d_bpsk;
|
||||
|
||||
set_tag_propagation_policy(block::TPP_DONT);
|
||||
set_algorithm(algo);
|
||||
}
|
||||
|
||||
frame_equalizer_impl::~frame_equalizer_impl() {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
frame_equalizer_impl::set_algorithm(Equalizer algo) {
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
delete d_equalizer;
|
||||
|
||||
switch(algo) {
|
||||
|
||||
case COMB:
|
||||
dout << "Comb" << std::endl;
|
||||
d_equalizer = new equalizer::comb();
|
||||
break;
|
||||
case LS:
|
||||
dout << "LS" << std::endl;
|
||||
d_equalizer = new equalizer::ls();
|
||||
break;
|
||||
case LMS:
|
||||
dout << "LMS" << std::endl;
|
||||
d_equalizer = new equalizer::lms();
|
||||
break;
|
||||
case STA:
|
||||
dout << "STA" << std::endl;
|
||||
d_equalizer = new equalizer::sta();
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Algorithm not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
frame_equalizer_impl::set_bandwidth(double bw) {
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
d_bw = bw;
|
||||
}
|
||||
|
||||
void
|
||||
frame_equalizer_impl::set_frequency(double freq) {
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
d_freq = freq;
|
||||
}
|
||||
|
||||
void
|
||||
frame_equalizer_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) {
|
||||
ninput_items_required[0] = noutput_items;
|
||||
}
|
||||
|
||||
int
|
||||
frame_equalizer_impl::general_work (int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items) {
|
||||
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
|
||||
const gr_complex *in = (const gr_complex *) input_items[0];
|
||||
uint8_t *out = (uint8_t *) output_items[0];
|
||||
|
||||
int i = 0;
|
||||
int o = 0;
|
||||
gr_complex symbols[48];
|
||||
gr_complex current_symbol[64];
|
||||
|
||||
dout << "FRAME EQUALIZER: input " << ninput_items[0] << " output " << noutput_items << std::endl;
|
||||
|
||||
while((i < ninput_items[0]) && (o < noutput_items)) {
|
||||
|
||||
get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("wifi_start"));
|
||||
|
||||
// new frame
|
||||
if(tags.size()) {
|
||||
d_current_symbol = 0;
|
||||
d_frame_symbols = 0;
|
||||
d_frame_mod = d_bpsk;
|
||||
|
||||
d_freq_offset_from_synclong = pmt::to_double(tags.front().value) * d_bw / (2 * M_PI);
|
||||
d_epsilon0 = pmt::to_double(tags.front().value) * d_bw / (2 * M_PI * d_freq);
|
||||
d_er = 0;
|
||||
|
||||
dout << "epsilon: " << d_epsilon0 << std::endl;
|
||||
}
|
||||
|
||||
// not interesting -> skip
|
||||
if(d_current_symbol > (d_frame_symbols + 2)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::memcpy(current_symbol, in + i*64, 64*sizeof(gr_complex));
|
||||
|
||||
// compensate sampling offset
|
||||
for(int i = 0; i < 64; i++) {
|
||||
current_symbol[i] *= exp(gr_complex(0, 2*M_PI*d_current_symbol*80*(d_epsilon0 + d_er)*(i-32)/64));
|
||||
}
|
||||
|
||||
gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127];
|
||||
|
||||
double beta;
|
||||
if(d_current_symbol < 2) {
|
||||
beta = arg(
|
||||
current_symbol[11] -
|
||||
current_symbol[25] +
|
||||
current_symbol[39] +
|
||||
current_symbol[53]);
|
||||
|
||||
} else {
|
||||
beta = arg(
|
||||
(current_symbol[11] * p) +
|
||||
(current_symbol[39] * p) +
|
||||
(current_symbol[25] * p) +
|
||||
(current_symbol[53] * -p));
|
||||
}
|
||||
|
||||
double er = arg(
|
||||
(conj(d_prev_pilots[0]) * current_symbol[11] * p) +
|
||||
(conj(d_prev_pilots[1]) * current_symbol[25] * p) +
|
||||
(conj(d_prev_pilots[2]) * current_symbol[39] * p) +
|
||||
(conj(d_prev_pilots[3]) * current_symbol[53] * -p));
|
||||
|
||||
er *= d_bw / (2 * M_PI * d_freq * 80);
|
||||
|
||||
if(d_current_symbol < 2) {
|
||||
d_prev_pilots[0] = current_symbol[11];
|
||||
d_prev_pilots[1] = -current_symbol[25];
|
||||
d_prev_pilots[2] = current_symbol[39];
|
||||
d_prev_pilots[3] = current_symbol[53];
|
||||
} else {
|
||||
d_prev_pilots[0] = current_symbol[11] * p;
|
||||
d_prev_pilots[1] = current_symbol[25] * p;
|
||||
d_prev_pilots[2] = current_symbol[39] * p;
|
||||
d_prev_pilots[3] = current_symbol[53] * -p;
|
||||
}
|
||||
|
||||
// compensate residual frequency offset
|
||||
for(int i = 0; i < 64; i++) {
|
||||
current_symbol[i] *= exp(gr_complex(0, -beta));
|
||||
}
|
||||
|
||||
// update estimate of residual frequency offset
|
||||
if(d_current_symbol >= 2) {
|
||||
|
||||
double alpha = 0.1;
|
||||
d_er = (1-alpha) * d_er + alpha * er;
|
||||
}
|
||||
|
||||
// do equalization
|
||||
d_equalizer->equalize(current_symbol, d_current_symbol,
|
||||
symbols, out + o * 48, d_frame_mod);
|
||||
|
||||
// signal field
|
||||
if(d_current_symbol == 2) {
|
||||
|
||||
if(decode_signal_field(out + o * 48)) {
|
||||
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("frame_bytes"), pmt::from_uint64(d_frame_bytes));
|
||||
dict = pmt::dict_add(dict, pmt::mp("encoding"), pmt::from_uint64(d_frame_encoding));
|
||||
dict = pmt::dict_add(dict, pmt::mp("snr"), pmt::from_double(d_equalizer->get_snr()));
|
||||
dict = pmt::dict_add(dict, pmt::mp("freq"), pmt::from_double(d_freq));
|
||||
dict = pmt::dict_add(dict, pmt::mp("freq_offset"), pmt::from_double(d_freq_offset_from_synclong));
|
||||
add_item_tag(0, nitems_written(0) + o,
|
||||
pmt::string_to_symbol("wifi_start"),
|
||||
dict,
|
||||
pmt::string_to_symbol(alias()));
|
||||
}
|
||||
}
|
||||
|
||||
if(d_current_symbol > 2) {
|
||||
o++;
|
||||
pmt::pmt_t pdu = pmt::make_dict();
|
||||
message_port_pub(pmt::mp("symbols"), pmt::cons(pmt::make_dict(), pmt::init_c32vector(48, symbols)));
|
||||
}
|
||||
|
||||
i++;
|
||||
d_current_symbol++;
|
||||
}
|
||||
|
||||
consume(0, i);
|
||||
return o;
|
||||
}
|
||||
|
||||
bool
|
||||
frame_equalizer_impl::decode_signal_field(uint8_t *rx_bits) {
|
||||
|
||||
static ofdm_param ofdm(BPSK_1_2);
|
||||
static frame_param frame(ofdm, 0);
|
||||
|
||||
deinterleave(rx_bits);
|
||||
uint8_t *decoded_bits = d_decoder.decode(&ofdm, &frame, d_deinterleaved);
|
||||
|
||||
return parse_signal(decoded_bits);
|
||||
}
|
||||
|
||||
void
|
||||
frame_equalizer_impl::deinterleave(uint8_t *rx_bits) {
|
||||
for(int i = 0; i < 48; i++) {
|
||||
d_deinterleaved[i] = rx_bits[interleaver_pattern[i]];
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
frame_equalizer_impl::parse_signal(uint8_t *decoded_bits) {
|
||||
|
||||
int r = 0;
|
||||
d_frame_bytes = 0;
|
||||
bool parity = false;
|
||||
for(int i = 0; i < 17; i++) {
|
||||
parity ^= decoded_bits[i];
|
||||
|
||||
if((i < 4) && decoded_bits[i]) {
|
||||
r = r | (1 << i);
|
||||
}
|
||||
|
||||
if(decoded_bits[i] && (i > 4) && (i < 17)) {
|
||||
d_frame_bytes = d_frame_bytes | (1 << (i-5));
|
||||
}
|
||||
}
|
||||
|
||||
if(parity != decoded_bits[17]) {
|
||||
dout << "SIGNAL: wrong parity" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(r) {
|
||||
case 11:
|
||||
d_frame_encoding = 0;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 24);
|
||||
d_frame_mod = d_bpsk;
|
||||
dout << "Encoding: 3 Mbit/s ";
|
||||
break;
|
||||
case 15:
|
||||
d_frame_encoding = 1;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 36);
|
||||
d_frame_mod = d_bpsk;
|
||||
dout << "Encoding: 4.5 Mbit/s ";
|
||||
break;
|
||||
case 10:
|
||||
d_frame_encoding = 2;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 48);
|
||||
d_frame_mod = d_qpsk;
|
||||
dout << "Encoding: 6 Mbit/s ";
|
||||
break;
|
||||
case 14:
|
||||
d_frame_encoding = 3;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 72);
|
||||
d_frame_mod = d_qpsk;
|
||||
dout << "Encoding: 9 Mbit/s ";
|
||||
break;
|
||||
case 9:
|
||||
d_frame_encoding = 4;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 96);
|
||||
d_frame_mod = d_16qam;
|
||||
dout << "Encoding: 12 Mbit/s ";
|
||||
break;
|
||||
case 13:
|
||||
d_frame_encoding = 5;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 144);
|
||||
d_frame_mod = d_16qam;
|
||||
dout << "Encoding: 18 Mbit/s ";
|
||||
break;
|
||||
case 8:
|
||||
d_frame_encoding = 6;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 192);
|
||||
d_frame_mod = d_64qam;
|
||||
dout << "Encoding: 24 Mbit/s ";
|
||||
break;
|
||||
case 12:
|
||||
d_frame_encoding = 7;
|
||||
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 216);
|
||||
d_frame_mod = d_64qam;
|
||||
dout << "Encoding: 27 Mbit/s ";
|
||||
break;
|
||||
default:
|
||||
dout << "unknown encoding" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||
% d_frame_encoding % d_frame_bytes % d_frame_symbols);
|
||||
return true;
|
||||
}
|
||||
|
||||
const int
|
||||
frame_equalizer_impl::interleaver_pattern[48] = {
|
||||
0, 3, 6, 9,12,15,18,21,
|
||||
24,27,30,33,36,39,42,45,
|
||||
1, 4, 7,10,13,16,19,22,
|
||||
25,28,31,34,37,40,43,46,
|
||||
2, 5, 8,11,14,17,20,23,
|
||||
26,29,32,35,38,41,44,47};
|
||||
|
||||
} /* namespace ieee802_11 */
|
||||
} /* namespace gr */
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H
|
||||
#define INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H
|
||||
|
||||
#include <ieee802-11/frame_equalizer.h>
|
||||
#include <ieee802-11/constellations.h>
|
||||
#include "equalizer/base.h"
|
||||
#include "viterbi_decoder.h"
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class frame_equalizer_impl : virtual public frame_equalizer
|
||||
{
|
||||
|
||||
public:
|
||||
frame_equalizer_impl(Equalizer algo, double freq, double bw, bool log, bool debug);
|
||||
~frame_equalizer_impl();
|
||||
|
||||
void set_algorithm(Equalizer algo);
|
||||
void set_bandwidth(double bw);
|
||||
void set_frequency(double freq);
|
||||
|
||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
||||
int general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
bool parse_signal(uint8_t *signal);
|
||||
bool decode_signal_field(uint8_t *rx_bits);
|
||||
void deinterleave(uint8_t *rx_bits);
|
||||
|
||||
equalizer::base *d_equalizer;
|
||||
gr::thread::mutex d_mutex;
|
||||
std::vector<gr::tag_t> tags;
|
||||
bool d_debug;
|
||||
bool d_log;
|
||||
int d_current_symbol;
|
||||
viterbi_decoder d_decoder;
|
||||
|
||||
// freq offset
|
||||
double d_freq; // Hz
|
||||
double d_freq_offset_from_synclong; // Hz, estimation from "sync_long" block
|
||||
double d_bw; // Hz
|
||||
double d_er;
|
||||
double d_epsilon0;
|
||||
gr_complex d_prev_pilots[4];
|
||||
|
||||
int d_frame_bytes;
|
||||
int d_frame_symbols;
|
||||
int d_frame_encoding;
|
||||
|
||||
uint8_t d_deinterleaved[48];
|
||||
gr_complex symbols[48];
|
||||
|
||||
boost::shared_ptr<gr::digital::constellation> d_frame_mod;
|
||||
constellation_bpsk::sptr d_bpsk;
|
||||
constellation_qpsk::sptr d_qpsk;
|
||||
constellation_16qam::sptr d_16qam;
|
||||
constellation_64qam::sptr d_64qam;
|
||||
|
||||
static const int interleaver_pattern[48];
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H */
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/ofdm_decode_mac.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <itpp/itcomm.h>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
using namespace itpp;
|
||||
|
||||
class ofdm_decode_mac_impl : public ofdm_decode_mac {
|
||||
|
||||
public:
|
||||
ofdm_decode_mac_impl(bool log, bool debug) : block("ofdm_decode_mac",
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_log(log),
|
||||
d_debug(debug),
|
||||
d_ofdm(BPSK_1_2),
|
||||
d_tx(d_ofdm, 0),
|
||||
d_frame_complete(true) {
|
||||
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
|
||||
// bpsk
|
||||
int bpsk_bits[] = {0, 1};
|
||||
bpsk.set(cvec(BPSK_D, 2), ivec(bpsk_bits, 2));
|
||||
|
||||
// qpsk
|
||||
int qpsk_bits[] = {0, 1, 2, 3};
|
||||
qpsk.set(cvec(QPSK_D, 4), ivec(qpsk_bits, 4));
|
||||
|
||||
// qam16
|
||||
int qam16_bits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
qam16.set(cvec(QAM16_D, 16), ivec(qam16_bits, 16));
|
||||
|
||||
// qam64
|
||||
int qam64_bits[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63};
|
||||
qam64.set(cvec(QAM64_D, 64), ivec(qam64_bits, 64));
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items) {
|
||||
|
||||
const gr_complex *in = (const gr_complex*)input_items[0];
|
||||
|
||||
int i = 0;
|
||||
|
||||
std::vector<gr::tag_t> tags;
|
||||
const uint64_t nread = this->nitems_read(0);
|
||||
|
||||
dout << "Decode MAC: input " << ninput_items[0] << std::endl;
|
||||
|
||||
while(i < ninput_items[0]) {
|
||||
|
||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
||||
pmt::string_to_symbol("ofdm_start"));
|
||||
|
||||
if(tags.size()) {
|
||||
if (d_frame_complete == false) {
|
||||
dout << "Warning: starting to receive new frame before old frame was complete" << std::endl;
|
||||
dout << "Already copied " << copied << " out of " << d_tx.n_sym << " symbols of last frame" << std::endl;
|
||||
}
|
||||
d_frame_complete = false;
|
||||
|
||||
pmt::pmt_t tuple = tags[0].value;
|
||||
int len_data = pmt::to_uint64(pmt::car(tuple));
|
||||
int encoding = pmt::to_uint64(pmt::cdr(tuple));
|
||||
|
||||
ofdm_param ofdm = ofdm_param((Encoding)encoding);
|
||||
tx_param tx = tx_param(ofdm, len_data);
|
||||
|
||||
// sanity check, more than MAX_SYM may indicate garbage
|
||||
if(tx.n_sym <= MAX_SYM && tx.n_encoded_bits <= MAX_BITS) {
|
||||
d_ofdm = ofdm;
|
||||
d_tx = tx;
|
||||
copied = 0;
|
||||
dout << "Decode MAC: frame start -- len " << len_data
|
||||
<< " symbols " << tx.n_sym << " encoding "
|
||||
<< encoding << std::endl;
|
||||
} else {
|
||||
dout << "Dropping frame which is too large (symbols or bits)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(copied < d_tx.n_sym) {
|
||||
dout << "copy one symbol, copied " << copied << " out of " << d_tx.n_sym << std::endl;
|
||||
std::memcpy(sym + (copied * 48), in, 48 * sizeof(gr_complex));
|
||||
copied++;
|
||||
|
||||
if(copied == d_tx.n_sym) {
|
||||
dout << "received complete frame - decoding" << std::endl;
|
||||
decode();
|
||||
in += 48;
|
||||
i++;
|
||||
d_frame_complete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in += 48;
|
||||
i++;
|
||||
}
|
||||
|
||||
consume(0, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void decode() {
|
||||
demodulate();
|
||||
deinterleave();
|
||||
decode_conv();
|
||||
descramble();
|
||||
print_output();
|
||||
|
||||
// skip service field
|
||||
boost::crc_32_type result;
|
||||
result.process_bytes(out_bytes + 2, d_tx.psdu_size);
|
||||
if(result.checksum() != 558161692) {
|
||||
dout << "checksum wrong -- dropping" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||
% d_ofdm.encoding % d_tx.psdu_size % d_tx.n_sym);
|
||||
|
||||
// create PDU
|
||||
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_tx.psdu_size - 4);
|
||||
pmt::pmt_t enc = pmt::from_uint64(d_ofdm.encoding);
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("encoding"), enc);
|
||||
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
|
||||
}
|
||||
|
||||
void demodulate() {
|
||||
|
||||
cvec symbols;
|
||||
symbols.set_length(d_tx.n_sym * 48);
|
||||
for(int i = 0; i < d_tx.n_sym * 48; i++) {
|
||||
symbols[i] = std::complex<double>(sym[i]);
|
||||
}
|
||||
|
||||
switch(d_ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case BPSK_3_4:
|
||||
|
||||
bits = to_vec(bpsk.demodulate_bits(symbols));
|
||||
break;
|
||||
|
||||
case QPSK_1_2:
|
||||
case QPSK_3_4:
|
||||
|
||||
bits = to_vec(qpsk.demodulate_bits(symbols));
|
||||
break;
|
||||
|
||||
case QAM16_1_2:
|
||||
case QAM16_3_4:
|
||||
bits = to_vec(qam16.demodulate_bits(symbols));
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
case QAM64_3_4:
|
||||
bits = to_vec(qam64.demodulate_bits(symbols));
|
||||
break;
|
||||
}
|
||||
|
||||
// I hate the guy who wrote itpp
|
||||
bits = bits * (-2) + 1;
|
||||
}
|
||||
|
||||
void deinterleave() {
|
||||
|
||||
int n_cbps = d_ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
int second[n_cbps];
|
||||
int s = std::max(d_ofdm.n_bpsc / 2, 1);
|
||||
|
||||
for(int j = 0; j < n_cbps; j++) {
|
||||
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
||||
}
|
||||
|
||||
for(int i = 0; i < n_cbps; i++) {
|
||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||
}
|
||||
|
||||
for(int i = 0; i < d_tx.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
deinter[i * n_cbps + second[first[k]]] = bits[i * n_cbps + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decode_conv() {
|
||||
Punctured_Convolutional_Code code;
|
||||
ivec generator(2);
|
||||
generator(0)=0133;
|
||||
generator(1)=0171;
|
||||
code.set_generator_polynomials(generator, 7);
|
||||
|
||||
bmat puncture_matrix;
|
||||
switch(d_ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
puncture_matrix = "1 1; 1 1";
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
puncture_matrix = "1 1 0; 1 0 1;";
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
puncture_matrix = "1 1 1 1 1 1; 1 0 1 0 1 0;";
|
||||
break;
|
||||
}
|
||||
code.set_puncture_matrix(puncture_matrix);
|
||||
code.set_truncation_length(30);
|
||||
|
||||
dout << "coding rate " << code.get_rate() << std::endl;
|
||||
dout << d_tx.n_encoded_bits << std::endl;
|
||||
|
||||
vec rx_signal(deinter, d_tx.n_encoded_bits);
|
||||
|
||||
code.reset();
|
||||
decoded_bits.set_length(d_tx.n_encoded_bits);
|
||||
code.decode_tail(rx_signal, decoded_bits);
|
||||
|
||||
//dout << "length decoded " << decoded_bits.size() << std::endl;
|
||||
//std::cout << decoded_bits << std::endl;
|
||||
}
|
||||
|
||||
void descramble () {
|
||||
int state = 0;
|
||||
for(int i = 0; i < 7; i++) {
|
||||
if(decoded_bits(i)) {
|
||||
state |= 1 << (6 - i);
|
||||
}
|
||||
}
|
||||
|
||||
int feedback;
|
||||
|
||||
for(int i = 7; i < decoded_bits.size(); i++) {
|
||||
feedback = ((!!(state & 64))) ^ (!!(state & 8));
|
||||
out_bits[i] = feedback ^ (int)decoded_bits(i);
|
||||
state = ((state << 1) & 0x7e) | feedback;
|
||||
}
|
||||
|
||||
for(int i = 0; i < decoded_bits.size(); i++) {
|
||||
int bit = i % 8;
|
||||
int byte = i / 8;
|
||||
if(bit == 0) {
|
||||
out_bytes[byte] = 0;
|
||||
}
|
||||
|
||||
if(out_bits[i]) {
|
||||
out_bytes[byte] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_output() {
|
||||
|
||||
dout << std::endl;
|
||||
for(int i = 0; i < decoded_bits.size() / 8; i++) {
|
||||
dout << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " ";
|
||||
if(i % 16 == 15) {
|
||||
dout << std::endl;
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
for(int i = 0; i < decoded_bits.size() / 8; i++) {
|
||||
if((out_bytes[i] > 31) && (out_bytes[i] < 127)) {
|
||||
dout << ((char) out_bytes[i]);
|
||||
} else {
|
||||
dout << ".";
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
gr_complex sym[1000 * 48 * 100];
|
||||
vec bits;
|
||||
double deinter[1000 * 48];
|
||||
char out_bits[40000];
|
||||
char out_bytes[40000];
|
||||
bvec decoded_bits;
|
||||
|
||||
bool d_debug;
|
||||
bool d_log;
|
||||
tx_param d_tx;
|
||||
ofdm_param d_ofdm;
|
||||
int copied;
|
||||
bool d_frame_complete;
|
||||
|
||||
Modulator<std::complex<double> > bpsk;
|
||||
Modulator<std::complex<double> > qpsk;
|
||||
Modulator<std::complex<double> > qam16;
|
||||
Modulator<std::complex<double> > qam64;
|
||||
};
|
||||
|
||||
ofdm_decode_mac::sptr
|
||||
ofdm_decode_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_decode_mac_impl(log, debug));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/ofdm_decode_signal.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include "utils.h"
|
||||
|
||||
#include <itpp/itcomm.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
using namespace itpp;
|
||||
|
||||
|
||||
class ofdm_decode_signal_impl : public ofdm_decode_signal {
|
||||
|
||||
public:
|
||||
ofdm_decode_signal_impl(bool log, bool debug) : block("ofdm_decode_signal",
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
||||
d_log(log),
|
||||
d_debug(debug),
|
||||
d_copy_symbols(0) {
|
||||
|
||||
decoded_bits.set_size(24);
|
||||
set_relative_rate(1);
|
||||
set_tag_propagation_policy(block::TPP_DONT);
|
||||
}
|
||||
|
||||
~ofdm_decode_signal_impl(){
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items) {
|
||||
|
||||
const gr_complex *in = (const gr_complex*)input_items[0];
|
||||
gr_complex *out = (gr_complex*)output_items[0];
|
||||
|
||||
int i = 0;
|
||||
int o = 0;
|
||||
|
||||
std::vector<gr::tag_t> tags;
|
||||
const uint64_t nread = nitems_read(0);
|
||||
|
||||
dout << "Decode Signal: input " << ninput_items[0]
|
||||
<< " output " << noutput_items << std::endl;
|
||||
|
||||
while((i < ninput_items[0]) && (o < noutput_items)) {
|
||||
|
||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
||||
pmt::string_to_symbol("ofdm_start"));
|
||||
|
||||
if(tags.size()) {
|
||||
for(int n = 0; n < 48; n++) {
|
||||
bits[n] = -real(in[n]);
|
||||
}
|
||||
|
||||
deinterleave();
|
||||
|
||||
decode();
|
||||
|
||||
if(print_signal()) {
|
||||
|
||||
add_item_tag(0, nitems_written(0) + o * 48,
|
||||
pmt::string_to_symbol("ofdm_start"),
|
||||
pmt::cons(pmt::from_uint64(d_len),
|
||||
pmt::from_uint64(d_encoding)),
|
||||
pmt::string_to_symbol(name()));
|
||||
}
|
||||
|
||||
} else if(d_copy_symbols) {
|
||||
|
||||
std::memcpy(out, in, 48 * sizeof(gr_complex));
|
||||
o++;
|
||||
out += 48;
|
||||
d_copy_symbols--;
|
||||
}
|
||||
|
||||
in += 48;
|
||||
i++;
|
||||
}
|
||||
|
||||
dout << "Decode Signal consumed " << i <<
|
||||
" produced " << o << std::endl;
|
||||
|
||||
consume(0, i);
|
||||
return o;
|
||||
}
|
||||
|
||||
void deinterleave() {
|
||||
double tmp[48];
|
||||
for(int i = 0; i < 48; i++) {
|
||||
tmp[i] = bits[inter[i]];
|
||||
}
|
||||
for(int i = 0; i < 48; i++) {
|
||||
bits[i] = tmp[i];
|
||||
}
|
||||
for(int i = 0; i < 48; i++) {
|
||||
dout << bits[i] << " ";
|
||||
}
|
||||
dout << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void decode() {
|
||||
|
||||
Convolutional_Code code;
|
||||
ivec generator(2);
|
||||
generator(0)=0133;
|
||||
generator(1)=0171;
|
||||
code.set_generator_polynomials(generator, 7);
|
||||
code.set_truncation_length(30);
|
||||
|
||||
vec rx_signal(bits, 48);
|
||||
code.reset();
|
||||
code.decode_tail(rx_signal, decoded_bits);
|
||||
|
||||
dout << "length rx " << rx_signal.size() << std::endl;
|
||||
dout << rx_signal << std::endl;
|
||||
dout << "length decoded " << decoded_bits.size() << std::endl;
|
||||
dout << decoded_bits << std::endl;
|
||||
|
||||
}
|
||||
|
||||
bool print_signal() {
|
||||
|
||||
int r = 0;
|
||||
d_len = 0;
|
||||
bool parity = false;
|
||||
for(int i = 0; i < 17; i++) {
|
||||
parity ^= (bool)decoded_bits[i];
|
||||
|
||||
if((i < 4) && decoded_bits[i]) {
|
||||
r = r | (1 << i);
|
||||
}
|
||||
|
||||
if(decoded_bits[i] && (i > 4) && (i < 17)) {
|
||||
d_len = d_len | (1 << (i-5));
|
||||
}
|
||||
}
|
||||
|
||||
if(parity != (bool)decoded_bits[17]) {
|
||||
dout << "SIGNAL: wrong parity" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(r == 11) {
|
||||
d_encoding = 0;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 24);
|
||||
dout << "Encoding: 3 Mbit/s ";
|
||||
} else if(r == 15) {
|
||||
d_encoding = 1;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 36);
|
||||
dout << "Encoding: 4.5 Mbit/s ";
|
||||
} else if(r == 10) {
|
||||
d_encoding = 2;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 48);
|
||||
dout << "Encoding: 6 Mbit/s ";
|
||||
} else if(r == 14) {
|
||||
d_encoding = 3;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 72);
|
||||
dout << "Encoding: 9 Mbit/s ";
|
||||
} else if(r == 9) {
|
||||
d_encoding = 4;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 96);
|
||||
dout << "Encoding: 12 Mbit/s ";
|
||||
} else if(r == 13) {
|
||||
d_encoding = 5;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 144);
|
||||
dout << "Encoding: 18 Mbit/s ";
|
||||
} else if(r == 8) {
|
||||
d_encoding = 6;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 192);
|
||||
dout << "Encoding: 24 Mbit/s ";
|
||||
} else if(r == 12) {
|
||||
d_encoding = 7;
|
||||
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 216);
|
||||
dout << "Encoding: 27 Mbit/s ";
|
||||
} else {
|
||||
dout << "unknown encoding" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||
% d_encoding % d_len % d_copy_symbols);
|
||||
|
||||
dout << "d_copy_symbols: " << d_copy_symbols << std::endl;
|
||||
dout << "length: " << d_len << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int d_len;
|
||||
int d_encoding;
|
||||
bool d_log;
|
||||
bool d_debug;
|
||||
double bits[48];
|
||||
int d_copy_symbols;
|
||||
bvec decoded_bits;
|
||||
static int inter[48];
|
||||
};
|
||||
|
||||
ofdm_decode_signal::sptr
|
||||
ofdm_decode_signal::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_decode_signal_impl(log, debug));
|
||||
}
|
||||
|
||||
int ofdm_decode_signal_impl::inter[48]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47};
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/ofdm_equalize_symbols.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "equalizer/base.h"
|
||||
#include "equalizer/linear_comb.h"
|
||||
#include "equalizer/lms.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
|
||||
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
|
||||
|
||||
public:
|
||||
ofdm_equalize_symbols_impl(Equalizer algo, bool debug) : block("ofdm_equalize_symbols",
|
||||
gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
||||
d_debug(debug), d_equalizer(NULL) {
|
||||
|
||||
set_relative_rate(1);
|
||||
set_tag_propagation_policy(block::TPP_DONT);
|
||||
set_algorithm(algo);
|
||||
}
|
||||
|
||||
~ofdm_equalize_symbols_impl(){
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items) {
|
||||
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
|
||||
const gr_complex *in = (const gr_complex*)input_items[0];
|
||||
gr_complex *out = (gr_complex*)output_items[0];
|
||||
|
||||
int i = 0;
|
||||
int o = 0;
|
||||
|
||||
dout << "SYMBOLS: input " << ninput_items[0] << " output " << noutput_items << std::endl;
|
||||
|
||||
while((i < ninput_items[0]) && (o < noutput_items)) {
|
||||
|
||||
get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("ofdm_start"));
|
||||
|
||||
// new WiFi frame
|
||||
if(tags.size()) {
|
||||
d_nsym = 0;
|
||||
}
|
||||
|
||||
// first data symbol (= signal field)
|
||||
if(d_nsym == 2) {
|
||||
add_item_tag(0, nitems_written(0) + o,
|
||||
pmt::string_to_symbol("ofdm_start"),
|
||||
pmt::PMT_T,
|
||||
pmt::string_to_symbol(name()));
|
||||
}
|
||||
|
||||
d_equalizer->equalize(in + (i * 64), out + (o * 48), d_nsym);
|
||||
|
||||
if(d_nsym > 1) {
|
||||
o++;
|
||||
}
|
||||
i++;
|
||||
d_nsym++;
|
||||
}
|
||||
|
||||
dout << "SYMBOLS: consumed " << i << " produced " << o << std::endl;
|
||||
|
||||
consume(0, i);
|
||||
return o;
|
||||
}
|
||||
|
||||
void set_algorithm(Equalizer algo) {
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
delete d_equalizer;
|
||||
|
||||
switch(algo) {
|
||||
case LMS:
|
||||
dout << "LMS" << std::endl;
|
||||
d_equalizer = new equalizer::lms();
|
||||
break;
|
||||
|
||||
case LINEAR_COMB:
|
||||
dout << "Linear Comb" << std::endl;
|
||||
d_equalizer = new equalizer::linear_comb();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int d_nsym;
|
||||
const bool d_debug;
|
||||
equalizer::base *d_equalizer;
|
||||
std::vector<gr::tag_t> tags;
|
||||
gr::thread::mutex d_mutex;
|
||||
};
|
||||
|
||||
|
||||
ofdm_equalize_symbols::sptr
|
||||
ofdm_equalize_symbols::make(Equalizer algo, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_equalize_symbols_impl(algo, debug));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/mac.h>
|
||||
#include <ieee802-11/ofdm_mac.h>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/block_detail.h>
|
||||
@@ -34,12 +34,12 @@
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
class mac_impl : public mac {
|
||||
class ofdm_mac_impl : public ofdm_mac {
|
||||
|
||||
public:
|
||||
|
||||
mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) :
|
||||
block("mac",
|
||||
ofdm_mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) :
|
||||
block("ofdm_mac",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_seq_nr(0) {
|
||||
@@ -48,10 +48,10 @@ mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector
|
||||
message_port_register_out(pmt::mp("app out"));
|
||||
|
||||
message_port_register_in(pmt::mp("app in"));
|
||||
set_msg_handler(pmt::mp("app in"), boost::bind(&mac_impl::app_in, this, _1));
|
||||
set_msg_handler(pmt::mp("app in"), boost::bind(&ofdm_mac_impl::app_in, this, _1));
|
||||
|
||||
message_port_register_in(pmt::mp("phy in"));
|
||||
set_msg_handler(pmt::mp("phy in"), boost::bind(&mac_impl::phy_in, this, _1));
|
||||
set_msg_handler(pmt::mp("phy in"), boost::bind(&ofdm_mac_impl::phy_in, this, _1));
|
||||
|
||||
if(!check_mac(src_mac)) throw std::invalid_argument("wrong mac address size");
|
||||
if(!check_mac(dst_mac)) throw std::invalid_argument("wrong mac address size");
|
||||
@@ -66,9 +66,8 @@ mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector
|
||||
|
||||
void phy_in (pmt::pmt_t msg) {
|
||||
// this must be a pair
|
||||
if (!pmt::is_blob(pmt::cdr(msg))) {
|
||||
if (!pmt::is_blob(pmt::cdr(msg)))
|
||||
throw std::runtime_error("PMT must be blob");
|
||||
}
|
||||
|
||||
// strip MAC header
|
||||
// TODO: check for frame type to determine header size
|
||||
@@ -84,25 +83,34 @@ void app_in (pmt::pmt_t msg) {
|
||||
|
||||
size_t msg_len;
|
||||
const char *msdu;
|
||||
std::string str;
|
||||
|
||||
if(pmt::is_symbol(msg)) {
|
||||
// dict
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
|
||||
if(pmt::is_eof_object(msg)) {
|
||||
message_port_pub(pmt::mp("phy out"), pmt::PMT_EOF);
|
||||
detail().get()->set_done(true);
|
||||
return;
|
||||
|
||||
} else if(pmt::is_symbol(msg)) {
|
||||
|
||||
std::string str;
|
||||
str = pmt::symbol_to_string(msg);
|
||||
msg_len = str.length();
|
||||
msdu = str.data();
|
||||
|
||||
} else if(pmt::is_pair(msg)) {
|
||||
|
||||
dict = pmt::car(msg);
|
||||
msg_len = pmt::blob_length(pmt::cdr(msg));
|
||||
msdu = reinterpret_cast<const char *>(pmt::blob_data(pmt::cdr(msg)));
|
||||
|
||||
} else {
|
||||
throw std::invalid_argument("MAC expects PDUs or strings");
|
||||
return;
|
||||
throw std::invalid_argument("OFDM MAC expects PDUs or strings");
|
||||
return;
|
||||
}
|
||||
|
||||
if(msg_len > MAX_PAYLOAD_SIZE) {
|
||||
if(msg_len > 1500) {
|
||||
throw std::invalid_argument("Frame too large (> 1500)");
|
||||
}
|
||||
|
||||
@@ -110,10 +118,21 @@ void app_in (pmt::pmt_t msg) {
|
||||
int psdu_length;
|
||||
generate_mac_data_frame(msdu, msg_len, &psdu_length);
|
||||
|
||||
// dict
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("crc_included"), pmt::PMT_T);
|
||||
|
||||
// check if csma is enabled
|
||||
pmt::pmt_t pmt_cw = pmt::dict_ref(dict, pmt::mp("cw_min"), pmt::PMT_NIL);
|
||||
if(pmt_cw != pmt::PMT_NIL) {
|
||||
uint64_t cw = pmt::to_long(pmt_cw);
|
||||
pmt::pmt_t backoffs = pmt::make_u64vector(2, 0);
|
||||
pmt::u64vector_set(backoffs, 0, rand() % cw);
|
||||
pmt::u64vector_set(backoffs, 1, rand() % cw);
|
||||
|
||||
dict = pmt::dict_add(dict, pmt::mp("backoffs"), backoffs);
|
||||
dict = pmt::dict_add(dict, pmt::mp("csma"), pmt::PMT_T);
|
||||
}
|
||||
|
||||
|
||||
// blob
|
||||
pmt::pmt_t mac = pmt::make_blob(d_psdu, psdu_length);
|
||||
|
||||
@@ -168,11 +187,11 @@ private:
|
||||
uint8_t d_src_mac[6];
|
||||
uint8_t d_dst_mac[6];
|
||||
uint8_t d_bss_mac[6];
|
||||
uint8_t d_psdu[MAX_PSDU_SIZE];
|
||||
uint8_t d_psdu[1528];
|
||||
};
|
||||
|
||||
mac::sptr
|
||||
mac::make(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) {
|
||||
return gnuradio::get_initial_sptr(new mac_impl(src_mac, dst_mac, bss_mac));
|
||||
ofdm_mac::sptr
|
||||
ofdm_mac::make(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_mac_impl(src_mac, dst_mac, bss_mac));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,40 +14,39 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/mapper.h>
|
||||
#include <ieee802-11/ofdm_mapper.h>
|
||||
#include "utils.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
|
||||
class mapper_impl : public mapper {
|
||||
class ofdm_mapper_impl : public ofdm_mapper {
|
||||
public:
|
||||
|
||||
static const int DATA_CARRIERS = 48;
|
||||
|
||||
mapper_impl(Encoding e, bool debug) :
|
||||
block ("mapper",
|
||||
ofdm_mapper_impl(Encoding e, bool debug) :
|
||||
block ("ofdm_mapper",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(1, 1, sizeof(char))),
|
||||
d_symbols_offset(0),
|
||||
d_symbols(NULL),
|
||||
d_debug(debug),
|
||||
d_scrambler(1),
|
||||
d_ofdm(e) {
|
||||
|
||||
message_port_register_in(pmt::mp("in"));
|
||||
set_encoding(e);
|
||||
}
|
||||
|
||||
~mapper_impl() {
|
||||
~ofdm_mapper_impl() {
|
||||
free(d_symbols);
|
||||
}
|
||||
|
||||
void print_message(const char *msg, size_t len) {
|
||||
|
||||
|
||||
dout << std::hex << "MAPPER input symbols" << std::endl
|
||||
dout << std::hex << "OFDM MAPPER input symbols" << std::endl
|
||||
<< "===========================" << std::endl;
|
||||
|
||||
for(int i = 0; i < len; i++) {
|
||||
@@ -63,62 +62,63 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
||||
gr_vector_void_star& output_items ) {
|
||||
|
||||
unsigned char *out = (unsigned char*)output_items[0];
|
||||
dout << "MAPPER called offset: " << d_symbols_offset <<
|
||||
dout << "OFDM MAPPER called offset: " << d_symbols_offset <<
|
||||
" length: " << d_symbols_len << std::endl;
|
||||
|
||||
while(!d_symbols_offset) {
|
||||
pmt::pmt_t msg(delete_head_nowait(pmt::intern("in")));
|
||||
pmt::pmt_t msg(delete_head_blocking(pmt::intern("in")));
|
||||
|
||||
if(!msg.get()) {
|
||||
return 0;
|
||||
}
|
||||
if(pmt::is_eof_object(msg)) {
|
||||
dout << "MAPPER: exiting" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pmt::is_pair(msg)) {
|
||||
dout << "MAPPER: received new message" << std::endl;
|
||||
dout << "OFDM MAPPER: received new message" << std::endl;
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
|
||||
int psdu_length = pmt::blob_length(pmt::cdr(msg));
|
||||
const char *psdu = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
|
||||
|
||||
// ############ INSERT MAC STUFF
|
||||
frame_param frame(d_ofdm, psdu_length);
|
||||
if(frame.n_sym > MAX_SYM) {
|
||||
tx_param tx(d_ofdm, psdu_length);
|
||||
if(tx.n_sym > MAX_SYM) {
|
||||
std::cout << "packet too large, maximum number of symbols is " << MAX_SYM << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//alloc memory for modulation steps
|
||||
char *data_bits = (char*)calloc(frame.n_data_bits, sizeof(char));
|
||||
char *scrambled_data = (char*)calloc(frame.n_data_bits, sizeof(char));
|
||||
char *encoded_data = (char*)calloc(frame.n_data_bits * 2, sizeof(char));
|
||||
char *punctured_data = (char*)calloc(frame.n_encoded_bits, sizeof(char));
|
||||
char *interleaved_data = (char*)calloc(frame.n_encoded_bits, sizeof(char));
|
||||
char *symbols = (char*)calloc((frame.n_encoded_bits / d_ofdm.n_bpsc), sizeof(char));
|
||||
char *data_bits = (char*)calloc(tx.n_data, sizeof(char));
|
||||
char *scrambled_data = (char*)calloc(tx.n_data, sizeof(char));
|
||||
char *encoded_data = (char*)calloc(tx.n_data * 2, sizeof(char));
|
||||
char *punctured_data = (char*)calloc(tx.n_encoded_bits, sizeof(char));
|
||||
char *interleaved_data = (char*)calloc(tx.n_encoded_bits, sizeof(char));
|
||||
char *symbols = (char*)calloc((tx.n_encoded_bits / d_ofdm.n_bpsc), sizeof(char));
|
||||
|
||||
//generate the WIFI data field, adding service field and pad bits
|
||||
generate_bits(psdu, data_bits, frame);
|
||||
|
||||
// scrambling
|
||||
scramble(data_bits, scrambled_data, frame, d_scrambler++);
|
||||
if(d_scrambler > 127) {
|
||||
d_scrambler = 1;
|
||||
}
|
||||
//generate the OFDM data field, adding service field and pad bits
|
||||
generate_bits(psdu, data_bits, tx);
|
||||
//print_hex_array(data_bits, tx.n_data);
|
||||
|
||||
// first step, scrambling
|
||||
scramble(data_bits, scrambled_data, tx, 23);
|
||||
//print_hex_array(scrambled_data, tx.n_data);
|
||||
// reset tail bits
|
||||
reset_tail_bits(scrambled_data, frame);
|
||||
reset_tail_bits(scrambled_data, tx);
|
||||
//print_hex_array(scrambled_data, tx.n_data);
|
||||
// encoding
|
||||
convolutional_encoding(scrambled_data, encoded_data, frame);
|
||||
convolutional_encoding(scrambled_data, encoded_data, tx);
|
||||
//print_hex_array(encoded_data, tx.n_data * 2);
|
||||
// puncturing
|
||||
puncturing(encoded_data, punctured_data, frame, d_ofdm);
|
||||
puncturing(encoded_data, punctured_data, tx, d_ofdm);
|
||||
//std::cout << "punctured" << std::endl;
|
||||
// interleaving
|
||||
interleave(punctured_data, interleaved_data, frame, d_ofdm);
|
||||
interleave(punctured_data, interleaved_data, tx, d_ofdm);
|
||||
//std::cout << "interleaved" << std::endl;
|
||||
|
||||
// one byte per symbol
|
||||
split_symbols(interleaved_data, symbols, frame, d_ofdm);
|
||||
// one byte per symbol
|
||||
split_symbols(interleaved_data, symbols, tx, d_ofdm);
|
||||
|
||||
d_symbols_len = frame.n_sym * 48;
|
||||
d_symbols_len = tx.n_sym * 48;
|
||||
|
||||
d_symbols = (char*)calloc(d_symbols_len, 1);
|
||||
std::memcpy(d_symbols, symbols, d_symbols_len);
|
||||
@@ -138,6 +138,14 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
||||
add_item_tag(0, nitems_written(0), pmt::mp("encoding"),
|
||||
encoding, srcid);
|
||||
|
||||
pmt::pmt_t dict_items(pmt::dict_items(pmt::car(msg)));
|
||||
while (!pmt::is_null(dict_items)) {
|
||||
pmt::pmt_t this_item(pmt::car(dict_items));
|
||||
|
||||
add_item_tag(0, nitems_written(0), pmt::car(this_item),
|
||||
pmt::cdr(this_item), srcid);
|
||||
dict_items = pmt::cdr(dict_items);
|
||||
}
|
||||
|
||||
free(data_bits);
|
||||
free(scrambled_data);
|
||||
@@ -165,14 +173,13 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
||||
|
||||
void set_encoding(Encoding encoding) {
|
||||
|
||||
std::cout << "MAPPER: encoding: " << encoding << std::endl;
|
||||
std::cout << "OFDM MAPPER: encoding: " << encoding << std::endl;
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
|
||||
d_ofdm = ofdm_param(encoding);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t d_scrambler;
|
||||
bool d_debug;
|
||||
char* d_symbols;
|
||||
int d_symbols_offset;
|
||||
@@ -181,7 +188,7 @@ private:
|
||||
gr::thread::mutex d_mutex;
|
||||
};
|
||||
|
||||
mapper::sptr
|
||||
mapper::make(Encoding mcs, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new mapper_impl(mcs, debug));
|
||||
ofdm_mapper::sptr
|
||||
ofdm_mapper::make(Encoding mcs, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_mapper_impl(mcs, debug));
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/parse_mac.h>
|
||||
#include <ieee802-11/ofdm_parse_mac.h>
|
||||
#include "utils.h"
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
@@ -23,24 +23,24 @@
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
class parse_mac_impl : public parse_mac {
|
||||
class ofdm_parse_mac_impl : public ofdm_parse_mac {
|
||||
|
||||
public:
|
||||
|
||||
parse_mac_impl(bool log, bool debug) :
|
||||
block("parse_mac",
|
||||
ofdm_parse_mac_impl(bool log, bool debug) :
|
||||
block("ofdm_parse_mac",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_log(log), d_last_seq_no(-1),
|
||||
d_debug(debug) {
|
||||
|
||||
message_port_register_in(pmt::mp("in"));
|
||||
set_msg_handler(pmt::mp("in"), boost::bind(&parse_mac_impl::parse, this, _1));
|
||||
set_msg_handler(pmt::mp("in"), boost::bind(&ofdm_parse_mac_impl::parse, this, _1));
|
||||
|
||||
message_port_register_out(pmt::mp("fer"));
|
||||
}
|
||||
|
||||
~parse_mac_impl() {
|
||||
~ofdm_parse_mac_impl() {
|
||||
|
||||
}
|
||||
|
||||
@@ -358,9 +358,9 @@ private:
|
||||
int d_last_seq_no;
|
||||
};
|
||||
|
||||
parse_mac::sptr
|
||||
parse_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new parse_mac_impl(log, debug));
|
||||
ofdm_parse_mac::sptr
|
||||
ofdm_parse_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_parse_mac_impl(log, debug));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/sync_long.h>
|
||||
#include <ieee802-11/ofdm_sync_long.h>
|
||||
#include "utils.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/filter/fir_filter.h>
|
||||
@@ -31,10 +31,10 @@ bool compare_abs(const std::pair<gr_complex, int>& first, const std::pair<gr_com
|
||||
return abs(get<0>(first)) > abs(get<0>(second));
|
||||
}
|
||||
|
||||
class sync_long_impl : public sync_long {
|
||||
class ofdm_sync_long_impl : public ofdm_sync_long {
|
||||
|
||||
public:
|
||||
sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("sync_long",
|
||||
ofdm_sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("ofdm_sync_long",
|
||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||
d_fir(gr::filter::kernel::fir_filter_ccc(1, LONG)),
|
||||
@@ -48,7 +48,7 @@ sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("sync_lon
|
||||
d_correlation = gr::fft::malloc_complex(8192);
|
||||
}
|
||||
|
||||
~sync_long_impl(){
|
||||
~ofdm_sync_long_impl(){
|
||||
gr::fft::free(d_correlation);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
||||
if(d_state == COPY) {
|
||||
d_state = RESET;
|
||||
}
|
||||
d_freq_offset_short = pmt::to_double(d_tags.front().value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +103,6 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
||||
|
||||
if(d_offset == SYNC_LENGTH) {
|
||||
search_frame_start();
|
||||
mylog(boost::format("LONG: frame start at %1%") % d_frame_start);
|
||||
d_offset = 0;
|
||||
d_count = 0;
|
||||
d_state = COPY;
|
||||
@@ -122,9 +120,9 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
||||
|
||||
if(!rel) {
|
||||
add_item_tag(0, nitems_written(0),
|
||||
pmt::string_to_symbol("wifi_start"),
|
||||
pmt::from_double(d_freq_offset_short - d_freq_offset),
|
||||
pmt::string_to_symbol(name()));
|
||||
pmt::string_to_symbol("ofdm_start"),
|
||||
pmt::PMT_T,
|
||||
pmt::string_to_symbol(name()));
|
||||
}
|
||||
|
||||
if(rel >= 0 && (rel < 128 || ((rel - 128) % 80) > 15)) {
|
||||
@@ -202,17 +200,19 @@ void search_frame_start() {
|
||||
}
|
||||
int diff = abs(get<1>(vec[i]) - get<1>(vec[k]));
|
||||
if(diff == 64) {
|
||||
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k]));
|
||||
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64 - 128 - 1;
|
||||
d_freq_offset = arg(first * conj(second)) / 64;
|
||||
//std::cout << "frequency offset " << d_freq_offset << std::endl;
|
||||
// nice match found, return immediately
|
||||
return;
|
||||
|
||||
// TODO: check if these offsets make sense
|
||||
} else if(diff == 63) {
|
||||
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k]));
|
||||
d_freq_offset = arg(first * conj(second)) / 63;
|
||||
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 63 - 128 - 1;
|
||||
d_freq_offset = arg(first * conj(second)) / 64;
|
||||
} else if(diff == 65) {
|
||||
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k]));
|
||||
d_freq_offset = arg(first * conj(second)) / 65;
|
||||
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64 - 128 - 1;
|
||||
d_freq_offset = arg(first * conj(second)) / 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,7 +224,6 @@ private:
|
||||
int d_offset;
|
||||
int d_frame_start;
|
||||
float d_freq_offset;
|
||||
double d_freq_offset_short;
|
||||
|
||||
gr_complex *d_correlation;
|
||||
list<pair<gr_complex, int> > d_cor;
|
||||
@@ -238,28 +237,28 @@ private:
|
||||
static const std::vector<gr_complex> LONG;
|
||||
};
|
||||
|
||||
sync_long::sptr
|
||||
sync_long::make(unsigned int sync_length, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, debug));
|
||||
ofdm_sync_long::sptr
|
||||
ofdm_sync_long::make(unsigned int sync_length, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_sync_long_impl(sync_length, log, debug));
|
||||
}
|
||||
|
||||
const std::vector<gr_complex> sync_long_impl::LONG = {
|
||||
const std::vector<gr_complex> ofdm_sync_long_impl::LONG = {
|
||||
|
||||
gr_complex(-0.0455, -1.0679), gr_complex( 0.3528, -0.9865), gr_complex( 0.8594, 0.7348), gr_complex( 0.1874, 0.2475),
|
||||
gr_complex( 0.5309, -0.7784), gr_complex(-1.0218, -0.4897), gr_complex(-0.3401, -0.9423), gr_complex( 0.8657, -0.2298),
|
||||
gr_complex( 0.4734, 0.0362), gr_complex( 0.0088, -1.0207), gr_complex(-1.2142, -0.4205), gr_complex( 0.2172, -0.5195),
|
||||
gr_complex( 0.5207, -0.1326), gr_complex(-0.1995, 1.4259), gr_complex( 1.0583, -0.0363), gr_complex( 0.5547, -0.5547),
|
||||
gr_complex( 0.3277, 0.8728), gr_complex(-0.5077, 0.3488), gr_complex(-1.1650, 0.5789), gr_complex( 0.7297, 0.8197),
|
||||
gr_complex( 0.6173, 0.1253), gr_complex(-0.5353, 0.7214), gr_complex(-0.5011, -0.1935), gr_complex(-0.3110, -1.3392),
|
||||
gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), gr_complex( 0.6663, -0.6571), gr_complex(-0.0249, 0.4773),
|
||||
gr_complex(-0.8155, 1.0218), gr_complex( 0.8140, 0.9396), gr_complex( 0.1090, 0.8662), gr_complex(-1.3868, -0.0000),
|
||||
gr_complex( 0.1090, -0.8662), gr_complex( 0.8140, -0.9396), gr_complex(-0.8155, -1.0218), gr_complex(-0.0249, -0.4773),
|
||||
gr_complex( 0.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470), gr_complex(-0.3110, 1.3392),
|
||||
gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253), gr_complex( 0.7297, -0.8197),
|
||||
gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728), gr_complex( 0.5547, 0.5547),
|
||||
gr_complex( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326), gr_complex( 0.2172, 0.5195),
|
||||
gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362), gr_complex( 0.8657, 0.2298),
|
||||
gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784), gr_complex( 0.1874, -0.2475),
|
||||
gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679), gr_complex( 1.3868, -0.0000),
|
||||
gr_complex( 1.3868, 0.0000), gr_complex(-0.0455, -1.0679), gr_complex( 0.3528, -0.9865), gr_complex( 0.8594, 0.7348),
|
||||
gr_complex( 0.1874, 0.2475), gr_complex( 0.5309, -0.7784), gr_complex(-1.0218, -0.4897), gr_complex(-0.3401, -0.9423),
|
||||
gr_complex( 0.8657, -0.2298), gr_complex( 0.4734, 0.0362), gr_complex( 0.0088, -1.0207), gr_complex(-1.2142, -0.4205),
|
||||
gr_complex( 0.2172, -0.5195), gr_complex( 0.5207, -0.1326), gr_complex(-0.1995, 1.4259), gr_complex( 1.0583, -0.0363),
|
||||
gr_complex( 0.5547, -0.5547), gr_complex( 0.3277, 0.8728), gr_complex(-0.5077, 0.3488), gr_complex(-1.1650, 0.5789),
|
||||
gr_complex( 0.7297, 0.8197), gr_complex( 0.6173, 0.1253), gr_complex(-0.5353, 0.7214), gr_complex(-0.5011, -0.1935),
|
||||
gr_complex(-0.3110, -1.3392), gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), gr_complex( 0.6663, -0.6571),
|
||||
gr_complex(-0.0249, 0.4773), gr_complex(-0.8155, 1.0218), gr_complex( 0.8140, 0.9396), gr_complex( 0.1090, 0.8662),
|
||||
gr_complex(-1.3868, 0.0000), gr_complex( 0.1090, -0.8662), gr_complex( 0.8140, -0.9396), gr_complex(-0.8155, -1.0218),
|
||||
gr_complex(-0.0249, -0.4773), gr_complex( 0.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470),
|
||||
gr_complex(-0.3110, 1.3392), gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253),
|
||||
gr_complex( 0.7297, -0.8197), gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728),
|
||||
gr_complex( 0.5547, 0.5547), gr_complex( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326),
|
||||
gr_complex( 0.2172, 0.5195), gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362),
|
||||
gr_complex( 0.8657, 0.2298), gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784),
|
||||
gr_complex( 0.1874, -0.2475), gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679)
|
||||
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/sync_short.h>
|
||||
#include <ieee802-11/ofdm_sync_short.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include "utils.h"
|
||||
|
||||
@@ -25,11 +25,11 @@ using namespace gr::ieee802_11;
|
||||
static const int MIN_GAP = 480;
|
||||
static const int MAX_SAMPLES = 540 * 80;
|
||||
|
||||
class sync_short_impl : public sync_short {
|
||||
class ofdm_sync_short_impl : public ofdm_sync_short {
|
||||
|
||||
public:
|
||||
sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) :
|
||||
block("sync_short",
|
||||
ofdm_sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) :
|
||||
block("ofdm_sync_short",
|
||||
gr::io_signature::make3(3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||
d_log(log),
|
||||
@@ -73,7 +73,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
d_copied = 0;
|
||||
d_freq_offset = arg(in_abs[i]) / 16;
|
||||
d_plateau = 0;
|
||||
insert_tag(nitems_written(0), d_freq_offset, nitems_read(0) + i);
|
||||
insert_tag(nitems_written(0));
|
||||
dout << "SHORT Frame!" << std::endl;
|
||||
break;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
d_copied = 0;
|
||||
d_plateau = 0;
|
||||
d_freq_offset = arg(in_abs[o]) / 16;
|
||||
insert_tag(nitems_written(0) + o, d_freq_offset, nitems_read(0) + o);
|
||||
insert_tag(nitems_written(0) + o);
|
||||
dout << "SHORT Frame!" << std::endl;
|
||||
break;
|
||||
}
|
||||
@@ -128,11 +128,11 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void insert_tag(uint64_t item, double freq_offset, uint64_t input_item) {
|
||||
mylog(boost::format("frame start at in: %2% out: %1%") % item % input_item);
|
||||
void insert_tag(uint64_t item) {
|
||||
mylog(boost::format("frame start at %1%") % item);
|
||||
|
||||
const pmt::pmt_t key = pmt::string_to_symbol("wifi_start");
|
||||
const pmt::pmt_t value = pmt::from_double(freq_offset);
|
||||
const pmt::pmt_t key = pmt::string_to_symbol("ofdm_start");
|
||||
const pmt::pmt_t value = pmt::PMT_T;
|
||||
const pmt::pmt_t srcid = pmt::string_to_symbol(name());
|
||||
add_item_tag(0, item, key, value, srcid);
|
||||
}
|
||||
@@ -148,7 +148,7 @@ private:
|
||||
const unsigned int MIN_PLATEAU;
|
||||
};
|
||||
|
||||
sync_short::sptr
|
||||
sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new sync_short_impl(threshold, min_plateau, log, debug));
|
||||
ofdm_sync_short::sptr
|
||||
ofdm_sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold, min_plateau, log, debug));
|
||||
}
|
||||
+105
-22
@@ -20,6 +20,62 @@
|
||||
#include <cstring>
|
||||
#include <math.h>
|
||||
|
||||
// constellations for different modulations (normalized to avg power 1)
|
||||
const std::complex<double> BPSK_D[2] = {
|
||||
std::complex<double>(-1.0, 0.0), std::complex<double>(1.0, 0.0)};
|
||||
|
||||
|
||||
const std::complex<double> QPSK_D[4] = {
|
||||
std::complex<double>(-0.7071, -0.7071), std::complex<double>(-0.7071, 0.7071),
|
||||
std::complex<double>(+0.7071, -0.7071), std::complex<double>(+0.7071, 0.7071)};
|
||||
|
||||
|
||||
const std::complex<double> QAM16_D[16] = {
|
||||
std::complex<double>(-0.9487, -0.9487), std::complex<double>(-0.9487, -0.3162),
|
||||
std::complex<double>(-0.9487, 0.9487), std::complex<double>(-0.9487, 0.3162),
|
||||
std::complex<double>(-0.3162, -0.9487), std::complex<double>(-0.3162, -0.3162),
|
||||
std::complex<double>(-0.3162, 0.9487), std::complex<double>(-0.3162, 0.3162),
|
||||
std::complex<double>(0.9487, -0.9487), std::complex<double>(0.9487, -0.3162),
|
||||
std::complex<double>(0.9487, 0.9487), std::complex<double>(0.9487, 0.3162),
|
||||
std::complex<double>(0.3162, -0.9487), std::complex<double>(0.3162, -0.3162),
|
||||
std::complex<double>(0.3162, 0.9487), std::complex<double>(0.3162, 0.3162)};
|
||||
|
||||
|
||||
const std::complex<double> QAM64_D[64] = {
|
||||
std::complex<double>(-1.0801, -1.0801), std::complex<double>(-1.0801, -0.7715),
|
||||
std::complex<double>(-1.0801, -0.1543), std::complex<double>(-1.0801, -0.4629),
|
||||
std::complex<double>(-1.0801, 1.0801), std::complex<double>(-1.0801, 0.7715),
|
||||
std::complex<double>(-1.0801, 0.1543), std::complex<double>(-1.0801, 0.4629),
|
||||
std::complex<double>(-0.7715, -1.0801), std::complex<double>(-0.7715, -0.7715),
|
||||
std::complex<double>(-0.7715, -0.1543), std::complex<double>(-0.7715, -0.4629),
|
||||
std::complex<double>(-0.7715, 1.0801), std::complex<double>(-0.7715, 0.7715),
|
||||
std::complex<double>(-0.7715, 0.1543), std::complex<double>(-0.7715, 0.4629),
|
||||
std::complex<double>(-0.1543, -1.0801), std::complex<double>(-0.1543, -0.7715),
|
||||
std::complex<double>(-0.1543, -0.1543), std::complex<double>(-0.1543, -0.4629),
|
||||
std::complex<double>(-0.1543, 1.0801), std::complex<double>(-0.1543, 0.7715),
|
||||
std::complex<double>(-0.1543, 0.1543), std::complex<double>(-0.1543, 0.4629),
|
||||
std::complex<double>(-0.4629, -1.0801), std::complex<double>(-0.4629, -0.7715),
|
||||
std::complex<double>(-0.4629, -0.1543), std::complex<double>(-0.4629, -0.4629),
|
||||
std::complex<double>(-0.4629, 1.0801), std::complex<double>(-0.4629, 0.7715),
|
||||
std::complex<double>(-0.4629, 0.1543), std::complex<double>(-0.4629, 0.4629),
|
||||
std::complex<double>(1.0801, -1.0801), std::complex<double>(1.0801, -0.7715),
|
||||
std::complex<double>(1.0801, -0.1543), std::complex<double>(1.0801, -0.4629),
|
||||
std::complex<double>(1.0801, 1.0801), std::complex<double>(1.0801, 0.7715),
|
||||
std::complex<double>(1.0801, 0.1543), std::complex<double>(1.0801, 0.4629),
|
||||
std::complex<double>(0.7715, -1.0801), std::complex<double>(0.7715, -0.7715),
|
||||
std::complex<double>(0.7715, -0.1543), std::complex<double>(0.7715, -0.4629),
|
||||
std::complex<double>(0.7715, 1.0801), std::complex<double>(0.7715, 0.7715),
|
||||
std::complex<double>(0.7715, 0.1543), std::complex<double>(0.7715, 0.4629),
|
||||
std::complex<double>(0.1543, -1.0801), std::complex<double>(0.1543, -0.7715),
|
||||
std::complex<double>(0.1543, -0.1543), std::complex<double>(0.1543, -0.4629),
|
||||
std::complex<double>(0.1543, 1.0801), std::complex<double>(0.1543, 0.7715),
|
||||
std::complex<double>(0.1543, 0.1543), std::complex<double>(0.1543, 0.4629),
|
||||
std::complex<double>(0.4629, -1.0801), std::complex<double>(0.4629, -0.7715),
|
||||
std::complex<double>(0.4629, -0.1543), std::complex<double>(0.4629, -0.4629),
|
||||
std::complex<double>(0.4629, 1.0801), std::complex<double>(0.4629, 0.7715),
|
||||
std::complex<double>(0.4629, 0.1543), std::complex<double>(0.4629, 0.4629)};
|
||||
|
||||
|
||||
ofdm_param::ofdm_param(Encoding e) {
|
||||
encoding = e;
|
||||
|
||||
@@ -97,37 +153,37 @@ ofdm_param::print() {
|
||||
}
|
||||
|
||||
|
||||
frame_param::frame_param(ofdm_param &ofdm, int psdu_length) {
|
||||
tx_param::tx_param(ofdm_param &ofdm, int psdu_length) {
|
||||
|
||||
psdu_size = psdu_length;
|
||||
|
||||
// number of symbols (17-11)
|
||||
n_sym = (int) ceil((16 + 8 * psdu_size + 6) / (double) ofdm.n_dbps);
|
||||
|
||||
n_data_bits = n_sym * ofdm.n_dbps;
|
||||
// number of bits of the data field (17-12)
|
||||
n_data = n_sym * ofdm.n_dbps;
|
||||
|
||||
// number of padding bits (17-13)
|
||||
n_pad = n_data_bits - (16 + 8 * psdu_size + 6);
|
||||
n_pad = n_data - (16 + 8 * psdu_size + 6);
|
||||
|
||||
n_encoded_bits = n_sym * ofdm.n_cbps;
|
||||
}
|
||||
void
|
||||
frame_param::print() {
|
||||
std::cout << "FRAME Parameters:" << std::endl;
|
||||
tx_param::print() {
|
||||
std::cout << "TX Parameters:" << std::endl;
|
||||
std::cout << "psdu_size: " << psdu_size << std::endl;
|
||||
std::cout << "n_sym: " << n_sym << std::endl;
|
||||
std::cout << "n_data: " << n_data << std::endl;
|
||||
std::cout << "n_pad: " << n_pad << std::endl;
|
||||
std::cout << "n_encoded_bits: " << n_encoded_bits << std::endl;
|
||||
std::cout << "n_data_bits: " << n_data_bits << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void scramble(const char *in, char *out, frame_param &frame, char initial_state) {
|
||||
void scramble(const char *in, char *out, tx_param &tx, char initial_state) {
|
||||
|
||||
int state = initial_state;
|
||||
int feedback;
|
||||
|
||||
for (int i = 0; i < frame.n_data_bits; i++) {
|
||||
for (int i = 0; i < tx.n_data; i++) {
|
||||
|
||||
feedback = (!!(state & 64)) ^ (!!(state & 8));
|
||||
out[i] = feedback ^ in[i];
|
||||
@@ -136,8 +192,8 @@ void scramble(const char *in, char *out, frame_param &frame, char initial_state)
|
||||
}
|
||||
|
||||
|
||||
void reset_tail_bits(char *scrambled_data, frame_param &frame) {
|
||||
memset(scrambled_data + frame.n_data_bits - frame.n_pad - 6, 0, 6 * sizeof(char));
|
||||
void reset_tail_bits(char *scrambled_data, tx_param &tx) {
|
||||
memset(scrambled_data + tx.n_data - tx.n_pad - 6, 0, 6 * sizeof(char));
|
||||
}
|
||||
|
||||
|
||||
@@ -152,11 +208,11 @@ int ones(int n) {
|
||||
}
|
||||
|
||||
|
||||
void convolutional_encoding(const char *in, char *out, frame_param &frame) {
|
||||
void convolutional_encoding(const char *in, char *out, tx_param &tx) {
|
||||
|
||||
int state = 0;
|
||||
|
||||
for(int i = 0; i < frame.n_data_bits; i++) {
|
||||
for(int i = 0; i < tx.n_data; i++) {
|
||||
assert(in[i] == 0 || in[i] == 1);
|
||||
state = ((state << 1) & 0x7e) | in[i];
|
||||
out[i * 2] = ones(state & 0155) % 2;
|
||||
@@ -165,11 +221,11 @@ void convolutional_encoding(const char *in, char *out, frame_param &frame) {
|
||||
}
|
||||
|
||||
|
||||
void puncturing(const char *in, char *out, frame_param &frame, ofdm_param &ofdm) {
|
||||
void puncturing(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
|
||||
int mod;
|
||||
|
||||
for (int i = 0; i < frame.n_data_bits * 2; i++) {
|
||||
for (int i = 0; i < tx.n_data * 2; i++) {
|
||||
switch(ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
@@ -203,7 +259,7 @@ void puncturing(const char *in, char *out, frame_param &frame, ofdm_param &ofdm)
|
||||
}
|
||||
|
||||
|
||||
void interleave(const char *in, char *out, frame_param &frame, ofdm_param &ofdm, bool reverse) {
|
||||
void interleave(const char *in, char *out, tx_param &tx, ofdm_param &ofdm, bool reverse) {
|
||||
|
||||
int n_cbps = ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
@@ -218,7 +274,7 @@ void interleave(const char *in, char *out, frame_param &frame, ofdm_param &ofdm,
|
||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||
}
|
||||
|
||||
for(int i = 0; i < frame.n_sym; i++) {
|
||||
for(int i = 0; i < tx.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
if(reverse) {
|
||||
out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k];
|
||||
@@ -230,28 +286,55 @@ void interleave(const char *in, char *out, frame_param &frame, ofdm_param &ofdm,
|
||||
}
|
||||
|
||||
|
||||
void split_symbols(const char *in, char *out, frame_param &frame, ofdm_param &ofdm) {
|
||||
void interleave(const double *in, double *out, tx_param &tx, ofdm_param &ofdm, bool reverse) {
|
||||
|
||||
int symbols = frame.n_sym * 48;
|
||||
int n_cbps = ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
int second[n_cbps];
|
||||
int s = std::max(ofdm.n_bpsc / 2, 1);
|
||||
|
||||
for(int j = 0; j < n_cbps; j++) {
|
||||
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
||||
}
|
||||
|
||||
for(int i = 0; i < n_cbps; i++) {
|
||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||
}
|
||||
|
||||
for(int i = 0; i < tx.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
if(reverse) {
|
||||
out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k];
|
||||
} else {
|
||||
out[i * n_cbps + k] = in[i * n_cbps + second[first[k]]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void split_symbols(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
|
||||
int symbols = tx.n_sym * 48;
|
||||
|
||||
for (int i = 0; i < symbols; i++) {
|
||||
out[i] = 0;
|
||||
for(int k = 0; k < ofdm.n_bpsc; k++) {
|
||||
assert(*in == 1 || *in == 0);
|
||||
out[i] |= (*in << k);
|
||||
out[i] |= (*in << (ofdm.n_bpsc - k - 1));
|
||||
in++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void generate_bits(const char *psdu, char *data_bits, frame_param &frame) {
|
||||
void generate_bits(const char *psdu, char *data_bits, tx_param &tx) {
|
||||
|
||||
// first 16 bits are zero (SERVICE/DATA field)
|
||||
memset(data_bits, 0, 16);
|
||||
data_bits += 16;
|
||||
|
||||
for(int i = 0; i < frame.psdu_size; i++) {
|
||||
for(int i = 0; i < tx.psdu_size; i++) {
|
||||
for(int b = 0; b < 8; b++) {
|
||||
data_bits[i * 8 + b] = !!(psdu[i] & (1 << b));
|
||||
}
|
||||
|
||||
+28
-22
@@ -14,28 +14,32 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_UTILS_H
|
||||
#define INCLUDED_IEEE802_11_UTILS_H
|
||||
#ifndef INCLUDED_IEEE802_11_OFDM_UTILS_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_UTILS_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <ieee802-11/mapper.h>
|
||||
#include <ieee802-11/ofdm_mapper.h>
|
||||
#include <gnuradio/config.h>
|
||||
#include <cinttypes>
|
||||
#include <iostream>
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 1500
|
||||
#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC
|
||||
#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1)
|
||||
#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288)
|
||||
const int MAX_SYM = 520; // enough for 1500 byte BPSK 1/2
|
||||
const int MAX_BITS = 1550 * 8 * 2;
|
||||
|
||||
#define dout d_debug && std::cout
|
||||
|
||||
#if defined(HAVE_LOG4CPP) && defined(ENABLE_GR_LOG) && defined(GR_IEEE80211_LOG4CPP)
|
||||
#define mylog(msg) do { if(d_log) { GR_LOG_INFO(d_logger, msg); }} while(0);
|
||||
#if defined(HAVE_LOG4CPP) && defined(ENABLE_GR_LOG)
|
||||
#define mylog(msg) do { if(d_log) { *d_logger << log4cpp::Priority::INFO << msg << log4cpp::eol; }} while(0);
|
||||
#else
|
||||
#define mylog(msg) do { d_log && std::cout << msg << std::endl; } while(0);
|
||||
#endif
|
||||
|
||||
// same mappings in double (itpp sucks)
|
||||
extern const std::complex<double> BPSK_D[2];
|
||||
extern const std::complex<double> QPSK_D[4];
|
||||
extern const std::complex<double> QAM16_D[16];
|
||||
extern const std::complex<double> QAM64_D[64];
|
||||
|
||||
struct mac_header {
|
||||
//protocol version, type, subtype, to_ds, from_ds, ...
|
||||
uint16_t frame_control;
|
||||
@@ -47,7 +51,7 @@ struct mac_header {
|
||||
}__attribute__((packed));
|
||||
|
||||
/**
|
||||
* WIFI parameters
|
||||
* OFDM parameters
|
||||
*/
|
||||
class ofdm_param {
|
||||
public:
|
||||
@@ -70,18 +74,18 @@ public:
|
||||
/**
|
||||
* packet specific parameters
|
||||
*/
|
||||
class frame_param {
|
||||
class tx_param {
|
||||
public:
|
||||
frame_param(ofdm_param &ofdm, int psdu_length);
|
||||
tx_param(ofdm_param &ofdm, int psdu_length);
|
||||
// PSDU size in bytes
|
||||
int psdu_size;
|
||||
// number of OFDM symbols (17-11)
|
||||
int n_sym;
|
||||
// number of data bits in the DATA field, including service and padding (17-12)
|
||||
int n_data;
|
||||
// number of padding bits in the DATA field (17-13)
|
||||
int n_pad;
|
||||
int n_encoded_bits;
|
||||
// number of data bits, including service and padding (17-12)
|
||||
int n_data_bits;
|
||||
|
||||
void print();
|
||||
};
|
||||
@@ -100,18 +104,20 @@ public:
|
||||
*/
|
||||
void generate_mac_data_frame(const char *msdu, int msdu_size, char **psdu, int *psdu_size, char seq);
|
||||
|
||||
void scramble(const char *input, char *out, frame_param &frame, char initial_state);
|
||||
|
||||
void reset_tail_bits(char *scrambled_data, frame_param &frame);
|
||||
void scramble(const char *input, char *out, tx_param &tx, char initial_state);
|
||||
|
||||
void convolutional_encoding(const char *input, char *out, frame_param &frame);
|
||||
void reset_tail_bits(char *scrambled_data, tx_param &tx);
|
||||
|
||||
void puncturing(const char *input, char *out, frame_param &frame, ofdm_param &ofdm);
|
||||
void convolutional_encoding(const char *input, char *out, tx_param &tx);
|
||||
|
||||
void interleave(const char *input, char *out, frame_param &frame, ofdm_param &ofdm, bool reverse = false);
|
||||
void puncturing(const char *input, char *out, tx_param &tx, ofdm_param &ofdm);
|
||||
|
||||
void split_symbols(const char *input, char *out, frame_param &frame, ofdm_param &ofdm);
|
||||
void interleave(const char *input, char *out, tx_param &tx, ofdm_param &ofdm, bool reverse = false);
|
||||
void interleave(const double *input, double *out, tx_param &tx, ofdm_param &ofdm, bool reverse = false);
|
||||
|
||||
void generate_bits(const char *psdu, char *data_bits, frame_param &frame);
|
||||
void split_symbols(const char *input, char *out, tx_param &tx, ofdm_param &ofdm);
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_UTILS_H */
|
||||
void generate_bits(const char *psdu, char *data_bits, tx_param &tx);
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_UTILS_H */
|
||||
|
||||
@@ -1,419 +0,0 @@
|
||||
/*
|
||||
* Copyright 1995 Phil Karn, KA9Q
|
||||
* Copyright 2008 Free Software Foundation, Inc.
|
||||
* 2014 Added SSE2 implementation Bogdan Diaconescu
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Viterbi decoder for K=7 rate=1/2 convolutional code
|
||||
* Some modifications from original Karn code by Matt Ettus
|
||||
* Major modifications by adding SSE2 code by Bogdan Diaconescu
|
||||
*/
|
||||
#include "viterbi_decoder.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
/* The basic Viterbi decoder operation, called a "butterfly"
|
||||
* operation because of the way it looks on a trellis diagram. Each
|
||||
* butterfly involves an Add-Compare-Select (ACS) operation on the two nodes
|
||||
* where the 0 and 1 paths from the current node merge at the next step of
|
||||
* the trellis.
|
||||
*
|
||||
* The code polynomials are assumed to have 1's on both ends. Given a
|
||||
* function encode_state() that returns the two symbols for a given
|
||||
* encoder state in the low two bits, such a code will have the following
|
||||
* identities for even 'n' < 64:
|
||||
*
|
||||
* encode_state(n) = encode_state(n+65)
|
||||
* encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n))
|
||||
*
|
||||
* Any convolutional code you would actually want to use will have
|
||||
* these properties, so these assumptions aren't too limiting.
|
||||
*
|
||||
* Doing this as a macro lets the compiler evaluate at compile time the
|
||||
* many expressions that depend on the loop index and encoder state and
|
||||
* emit them as immediate arguments.
|
||||
* This makes an enormous difference on register-starved machines such
|
||||
* as the Intel x86 family where evaluating these expressions at runtime
|
||||
* would spill over into memory.
|
||||
*/
|
||||
|
||||
#define BUTTERFLY(i,sym) { \
|
||||
int m0,m1,m2,m3; \
|
||||
/* ACS for 0 branch */ \
|
||||
m0 = state[i].metric + mets[sym]; /* 2*i */ \
|
||||
m1 = state[i+32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
|
||||
if(m0 > m1){ \
|
||||
next[2*i].metric = m0; \
|
||||
next[2*i].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2*i].metric = m1; \
|
||||
next[2*i].path = (state[i+32].path << 1)|1; \
|
||||
} \
|
||||
/* ACS for 1 branch */ \
|
||||
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
|
||||
m3 = state[i+32].metric + mets[sym]; /* 2*i + 65 */ \
|
||||
if(m2 > m3){ \
|
||||
next[2*i+1].metric = m2; \
|
||||
next[2*i+1].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2*i+1].metric = m3; \
|
||||
next[2*i+1].path = (state[i+32].path << 1)|1; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
|
||||
viterbi_decoder::viterbi_decoder() :
|
||||
d_store_pos(0) {
|
||||
}
|
||||
|
||||
viterbi_decoder::~viterbi_decoder() {
|
||||
}
|
||||
|
||||
void
|
||||
viterbi_decoder::viterbi_butterfly2_sse2(unsigned char *symbols,
|
||||
__m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1) {
|
||||
int i;
|
||||
|
||||
__m128i *metric0, *metric1;
|
||||
__m128i *path0, *path1;
|
||||
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
|
||||
__m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1;
|
||||
__m128i metsv, metsvm;
|
||||
__m128i shift0, shift1;
|
||||
__m128i tmp0, tmp1;
|
||||
__m128i sym0v, sym1v;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[0]);
|
||||
sym1v = _mm_set1_epi8(symbols[1]);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[0] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
} else if (symbols[1] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
} else {
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
}
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
|
||||
metric0 = mm1;
|
||||
path0 = pp1;
|
||||
metric1 = mm0;
|
||||
path1 = pp0;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[2]);
|
||||
sym1v = _mm_set1_epi8(symbols[3]);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[2] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
|
||||
} else if (symbols[3] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
|
||||
} else {
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
}
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
}
|
||||
|
||||
// Find current best path
|
||||
unsigned char
|
||||
viterbi_decoder::viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0,
|
||||
int ntraceback, unsigned char *outbuf) {
|
||||
int i;
|
||||
int bestmetric, minmetric;
|
||||
int beststate = 0;
|
||||
int pos = 0;
|
||||
|
||||
// circular buffer with the last ntraceback paths
|
||||
d_store_pos = (d_store_pos + 1) % ntraceback;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
_mm_store_si128((__m128i *) &d_mmresult[i*16], mm0[i]);
|
||||
_mm_store_si128((__m128i *) &d_ppresult[d_store_pos][i*16], pp0[i]);
|
||||
}
|
||||
|
||||
// Find out the best final state
|
||||
bestmetric = d_mmresult[beststate];
|
||||
minmetric = d_mmresult[beststate];
|
||||
|
||||
for (i = 1; i < 64; i++) {
|
||||
if (d_mmresult[i] > bestmetric) {
|
||||
bestmetric = d_mmresult[i];
|
||||
beststate = i;
|
||||
}
|
||||
if (d_mmresult[i] < minmetric) {
|
||||
minmetric = d_mmresult[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Trace back
|
||||
for (i = 0, pos = d_store_pos; i < (ntraceback - 1); i++) {
|
||||
// Obtain the state from the output bits
|
||||
// by clocking in the output bits in reverse order.
|
||||
// The state has only 6 bits
|
||||
beststate = d_ppresult[pos][beststate] >> 2;
|
||||
pos = (pos - 1 + ntraceback) % ntraceback;
|
||||
}
|
||||
|
||||
// Store output byte
|
||||
*outbuf = d_ppresult[pos][beststate];
|
||||
|
||||
// Zero out the path variable
|
||||
// and prevent metric overflow
|
||||
for (i = 0; i < 4; i++) {
|
||||
pp0[i] = _mm_setzero_si128();
|
||||
mm0[i] = _mm_sub_epi8(mm0[i], _mm_set1_epi8(minmetric));
|
||||
}
|
||||
|
||||
return bestmetric;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
viterbi_decoder::depuncture(uint8_t *in) {
|
||||
|
||||
int count;
|
||||
int n_cbps = d_ofdm->n_cbps;
|
||||
uint8_t *depunctured;
|
||||
|
||||
if (d_ntraceback == 5) {
|
||||
count = d_frame->n_sym * n_cbps;
|
||||
depunctured = in;
|
||||
|
||||
} else {
|
||||
depunctured = d_depunctured;
|
||||
count = 0;
|
||||
for(int i = 0; i < d_frame->n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
|
||||
depunctured[count] = 2;
|
||||
count++;
|
||||
}
|
||||
|
||||
// Insert received bits
|
||||
depunctured[count] = in[i * n_cbps + k];
|
||||
count++;
|
||||
|
||||
while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
|
||||
depunctured[count] = 2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return depunctured;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) {
|
||||
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
|
||||
reset();
|
||||
uint8_t *depunctured = depuncture(in);
|
||||
|
||||
int in_count = 0;
|
||||
int out_count = 0;
|
||||
int n_decoded = 0;
|
||||
|
||||
while(n_decoded < d_frame->n_data_bits) {
|
||||
|
||||
if ((in_count % 4) == 0) { //0 or 3
|
||||
viterbi_butterfly2_sse2(&depunctured[in_count & 0xfffffffc], d_metric0, d_metric1, d_path0, d_path1);
|
||||
|
||||
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
|
||||
unsigned char c;
|
||||
|
||||
viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, &c);
|
||||
|
||||
if (out_count >= d_ntraceback) {
|
||||
for (int i= 0; i < 8; i++) {
|
||||
d_decoded[(out_count - d_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1;
|
||||
n_decoded++;
|
||||
}
|
||||
}
|
||||
out_count++;
|
||||
}
|
||||
}
|
||||
in_count++;
|
||||
}
|
||||
|
||||
return d_decoded;
|
||||
}
|
||||
|
||||
void
|
||||
viterbi_decoder::reset() {
|
||||
|
||||
viterbi_chunks_init_sse2();
|
||||
|
||||
switch(d_ofdm->encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
d_ntraceback = 5;
|
||||
d_depuncture_pattern = PUNCTURE_1_2;
|
||||
d_k = 1;
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
d_ntraceback = 9;
|
||||
d_depuncture_pattern = PUNCTURE_2_3;
|
||||
d_k = 2;
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
d_ntraceback = 10;
|
||||
d_depuncture_pattern = PUNCTURE_3_4;
|
||||
d_k = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void // Initialize starting metrics to prefer 0 state
|
||||
viterbi_decoder::viterbi_chunks_init_sse2() {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
d_metric0[i] = _mm_setzero_si128();
|
||||
d_path0[i] = _mm_setzero_si128();
|
||||
}
|
||||
|
||||
int polys[2] = { 0x6d, 0x4f };
|
||||
for(i=0; i < 32; i++) {
|
||||
d_branchtab27_sse2[0].c[i] = (polys[0] < 0) ^ PARTAB[(2*i) & abs(polys[0])] ? 1 : 0;
|
||||
d_branchtab27_sse2[1].c[i] = (polys[1] < 0) ^ PARTAB[(2*i) & abs(polys[1])] ? 1 : 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
d_mmresult[i] = 0;
|
||||
for (j = 0; j < TRACEBACK_MAX; j++) {
|
||||
d_ppresult[j][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Parity lookup table */
|
||||
const unsigned char viterbi_decoder::PARTAB[256] = {
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
};
|
||||
|
||||
const unsigned char viterbi_decoder::PUNCTURE_1_2[2] = {1, 1};
|
||||
const unsigned char viterbi_decoder::PUNCTURE_2_3[4] = {1, 1, 1, 0};
|
||||
const unsigned char viterbi_decoder::PUNCTURE_3_4[6] = {1, 1, 1, 0, 0, 1};
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INCLUDED_IEEE802_11_VITERBI_DECODER_H
|
||||
#define INCLUDED_IEEE802_11_VITERBI_DECODER_H
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include "utils.h"
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
// Maximum number of traceback bytes
|
||||
#define TRACEBACK_MAX 24
|
||||
|
||||
/* This Viterbi decoder was taken from the gr-dvbt module of
|
||||
* GNU Radio. It is an SSE2 version of the Viterbi Decoder
|
||||
* created by Phil Karn. The SSE2 version was made by Bogdan
|
||||
* Diaconescu. For more info see: gr-dvbt/lib/d_viterbi.h
|
||||
*/
|
||||
class viterbi_decoder
|
||||
{
|
||||
public:
|
||||
|
||||
viterbi_decoder();
|
||||
virtual ~viterbi_decoder();
|
||||
|
||||
uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in);
|
||||
|
||||
private:
|
||||
|
||||
// Position in circular buffer where the current decoded byte is stored
|
||||
int d_store_pos;
|
||||
// Metrics for each state
|
||||
unsigned char d_mmresult[64] __attribute__((aligned(16)));
|
||||
// Paths for each state
|
||||
unsigned char d_ppresult[TRACEBACK_MAX][64] __attribute__((aligned(16)));
|
||||
|
||||
|
||||
union branchtab27 {
|
||||
unsigned char c[32];
|
||||
__m128i v[2];
|
||||
} d_branchtab27_sse2[2];
|
||||
|
||||
__m128i d_metric0[4] __attribute__ ((aligned(16)));
|
||||
__m128i d_metric1[4] __attribute__ ((aligned(16)));
|
||||
__m128i d_path0[4] __attribute__ ((aligned(16)));
|
||||
__m128i d_path1[4] __attribute__ ((aligned(16)));
|
||||
|
||||
int d_ntraceback;
|
||||
int d_k;
|
||||
ofdm_param *d_ofdm;
|
||||
frame_param *d_frame;
|
||||
const unsigned char *d_depuncture_pattern;
|
||||
|
||||
uint8_t d_depunctured[MAX_ENCODED_BITS];
|
||||
uint8_t d_decoded[MAX_ENCODED_BITS * 3 / 4];
|
||||
|
||||
static const unsigned char PARTAB[256];
|
||||
static const unsigned char PUNCTURE_1_2[2];
|
||||
static const unsigned char PUNCTURE_2_3[4];
|
||||
static const unsigned char PUNCTURE_3_4[6];
|
||||
|
||||
void reset();
|
||||
uint8_t* depuncture(uint8_t *in);
|
||||
void viterbi_chunks_init_sse2();
|
||||
void viterbi_butterfly2_sse2(unsigned char *symbols,
|
||||
__m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
|
||||
unsigned char viterbi_get_output_sse2(__m128i *mm0,
|
||||
__m128i *pp0, int ntraceback, unsigned char *outbuf);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_VITERBI_DECODER_H */
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/wifi_edca.h>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/block_detail.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
class wifi_edca_impl : public wifi_edca {
|
||||
|
||||
public:
|
||||
|
||||
wifi_edca_impl(std::vector<uint16_t> cw_min, std::vector<uint16_t>aifsn) :
|
||||
block("wifi_edca",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
m_cw_min(cw_min), m_aifsn(aifsn)
|
||||
{
|
||||
|
||||
if(cw_min.size() != aifsn.size()) {
|
||||
throw std::invalid_argument("WiFi EDCA: cw_min and aifsn parameters have to have same length");
|
||||
}
|
||||
|
||||
if(cw_min.size() == 0) {
|
||||
throw std::invalid_argument("WiFi EDCA need cw_min and aifsn");
|
||||
}
|
||||
|
||||
message_port_register_out(pmt::mp("mac out"));
|
||||
|
||||
if(cw_min.size() == 1) {
|
||||
message_port_register_in(pmt::mp("ac_in"));
|
||||
set_msg_handler(pmt::mp("ac_in"), boost::bind(&wifi_edca_impl::ac_in, this, _1, 0));
|
||||
} else {
|
||||
for(int i = 0; i < cw_min.size(); i++) {
|
||||
std::stringstream sstm;
|
||||
sstm << "ac in" << i;
|
||||
message_port_register_in(pmt::mp(sstm.str()));
|
||||
set_msg_handler(pmt::mp(sstm.str()), boost::bind(&wifi_edca_impl::ac_in, this, _1, i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ac_in (pmt::pmt_t msg, int i) {
|
||||
std::cout << "ac " << i << std::endl;
|
||||
|
||||
if(pmt::is_eof_object(msg)) {
|
||||
message_port_pub(pmt::mp("mac out"), pmt::PMT_EOF);
|
||||
detail().get()->set_done(true);
|
||||
|
||||
} else if(pmt::is_symbol(msg)) {
|
||||
|
||||
std::string str;
|
||||
str = pmt::symbol_to_string(msg);
|
||||
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("cw_min"), pmt::from_long(m_cw_min[i]));
|
||||
dict = pmt::dict_add(dict, pmt::mp("aifsn"), pmt::from_long(m_aifsn[i]));
|
||||
|
||||
pmt::pmt_t blob = pmt::make_blob(str.data(), str.length());
|
||||
pmt::pmt_t pair = pmt::cons(dict, blob);
|
||||
|
||||
message_port_pub(pmt::mp("mac out"), pair);
|
||||
|
||||
} else if(pmt::is_pair(msg)) {
|
||||
pmt::pmt_t dict = pmt::car(msg);
|
||||
dict = pmt::dict_add(dict, pmt::mp("cw_min"), pmt::from_long(m_cw_min[i]));
|
||||
dict = pmt::dict_add(dict, pmt::mp("aifsn"), pmt::from_long(m_aifsn[i]));
|
||||
message_port_pub(pmt::mp("mac out"), pmt::cons(dict, pmt::cdr(msg)));
|
||||
|
||||
} else {
|
||||
throw std::invalid_argument("WiFi EDCA expects PDUs or strings");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint16_t>m_cw_min;
|
||||
std::vector<uint16_t>m_aifsn;
|
||||
};
|
||||
|
||||
wifi_edca::sptr
|
||||
wifi_edca::make(std::vector<uint16_t>cw_min, std::vector<uint16_t> aifsn) {
|
||||
return gnuradio::get_initial_sptr(new wifi_edca_impl(cw_min, aifsn));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,32 +15,32 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "signal_field_impl.h"
|
||||
#include "wifi_signal_field_impl.h"
|
||||
#include "utils.h"
|
||||
#include <gnuradio/digital/lfsr.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
signal_field::sptr
|
||||
signal_field::make() {
|
||||
return signal_field::sptr(new signal_field_impl());
|
||||
wifi_signal_field::sptr
|
||||
wifi_signal_field::make() {
|
||||
return wifi_signal_field::sptr(new wifi_signal_field_impl());
|
||||
}
|
||||
|
||||
signal_field::signal_field() : packet_header_default(48, "packet_len") {};
|
||||
wifi_signal_field::wifi_signal_field() : packet_header_default(48, "packet_len") {};
|
||||
|
||||
|
||||
signal_field_impl::signal_field_impl() : packet_header_default(48, "packet_len") {}
|
||||
wifi_signal_field_impl::wifi_signal_field_impl() : packet_header_default(48, "packet_len") {}
|
||||
|
||||
|
||||
signal_field_impl::~signal_field_impl() {}
|
||||
wifi_signal_field_impl::~wifi_signal_field_impl() {}
|
||||
|
||||
|
||||
int signal_field_impl::get_bit(int b, int i) {
|
||||
int wifi_signal_field_impl::get_bit(int b, int i) {
|
||||
return (b & (1 << i) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofdm_param &ofdm) {
|
||||
void wifi_signal_field_impl::generate_signal_field(char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
|
||||
//data bits of the signal header
|
||||
char *signal_header = (char *) malloc(sizeof(char) * 24);
|
||||
@@ -51,7 +51,7 @@ void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofd
|
||||
//interleaving
|
||||
char *interleaved_signal_header = (char *) malloc(sizeof(char) * 48);
|
||||
|
||||
int length = frame.psdu_size;
|
||||
int length = tx.psdu_size;
|
||||
|
||||
// first 4 bits represent the modulation and coding scheme
|
||||
signal_header[ 0] = get_bit(ofdm.rate_field, 3);
|
||||
@@ -88,19 +88,22 @@ void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofd
|
||||
}
|
||||
|
||||
ofdm_param signal_ofdm(BPSK_1_2);
|
||||
frame_param signal_param(signal_ofdm, 0);
|
||||
tx_param signal_tx(signal_ofdm, 3);
|
||||
signal_tx.n_data = 24;
|
||||
signal_tx.n_sym = 1;
|
||||
|
||||
// convolutional encoding (scrambling is not needed)
|
||||
convolutional_encoding(signal_header, encoded_signal_header, signal_param);
|
||||
convolutional_encoding(signal_header, encoded_signal_header, signal_tx);
|
||||
// interleaving
|
||||
interleave(encoded_signal_header, out, signal_param, signal_ofdm);
|
||||
//interleave(encoded_signal_header, interleaved_signal_header, signal_tx, signal_ofdm);
|
||||
interleave(encoded_signal_header, out, signal_tx, signal_ofdm);
|
||||
|
||||
free(signal_header);
|
||||
free(encoded_signal_header);
|
||||
free(interleaved_signal_header);
|
||||
}
|
||||
|
||||
bool signal_field_impl::header_formatter(long packet_len, unsigned char *out, const std::vector<tag_t> &tags)
|
||||
bool wifi_signal_field_impl::header_formatter(long packet_len, unsigned char *out, const std::vector<tag_t> &tags)
|
||||
{
|
||||
|
||||
bool encoding_found = false;
|
||||
@@ -125,13 +128,13 @@ bool signal_field_impl::header_formatter(long packet_len, unsigned char *out, co
|
||||
}
|
||||
|
||||
ofdm_param ofdm((Encoding)encoding);
|
||||
frame_param frame(ofdm, len);
|
||||
tx_param tx(ofdm, len);
|
||||
|
||||
generate_signal_field((char*)out, frame, ofdm);
|
||||
generate_signal_field((char*)out, tx, ofdm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool signal_field_impl::header_parser(
|
||||
bool wifi_signal_field_impl::header_parser(
|
||||
const unsigned char *in, std::vector<tag_t> &tags) {
|
||||
|
||||
throw std::runtime_error("not implemented yet");
|
||||
@@ -15,20 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H
|
||||
#define INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H
|
||||
#ifndef INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H
|
||||
#define INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H
|
||||
|
||||
#include <ieee802-11/signal_field.h>
|
||||
#include <ieee802-11/wifi_signal_field.h>
|
||||
#include "utils.h"
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class signal_field_impl : public signal_field
|
||||
class wifi_signal_field_impl : public wifi_signal_field
|
||||
{
|
||||
public:
|
||||
signal_field_impl();
|
||||
~signal_field_impl();
|
||||
wifi_signal_field_impl();
|
||||
~wifi_signal_field_impl();
|
||||
|
||||
bool header_formatter(long packet_len, unsigned char *out,
|
||||
const std::vector<tag_t> &tags);
|
||||
@@ -37,11 +37,11 @@ public:
|
||||
std::vector<tag_t> &tags);
|
||||
private:
|
||||
int get_bit(int b, int i);
|
||||
void generate_signal_field(char *out, frame_param &frame, ofdm_param &ofdm);
|
||||
void generate_signal_field(char *out, tx_param &tx, ofdm_param &ofdm);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H */
|
||||
#endif /* INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H */
|
||||
|
||||
@@ -39,3 +39,4 @@ include(GrTest)
|
||||
|
||||
set(GR_TEST_TARGET_DEPS gnuradio-ieee802-11)
|
||||
set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
|
||||
#GR_ADD_TEST(qa_howto ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_howto.py)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
results/
|
||||
sim.py
|
||||
@@ -1,30 +0,0 @@
|
||||
SHELL=/bin/bash
|
||||
|
||||
MESSAGES=100
|
||||
|
||||
PCAPFILES=$(shell python -c 'import itertools; import numpy as np; print(" ".join(["results/sim_%d_%d_%.1f_.pcap" % x for x in itertools.product(range(10), range(8), np.arange(0, 30,.5))]))')
|
||||
|
||||
all: pdr.pdf
|
||||
|
||||
pdr.pdf: plot.py results/all.csv
|
||||
python ./plot.py
|
||||
|
||||
sim.py: sim.grc
|
||||
grcc -d . sim.grc
|
||||
|
||||
results/all.csv: $(PCAPFILES)
|
||||
./parse.sh
|
||||
|
||||
%.pcap: sim.py
|
||||
@echo $@
|
||||
mkdir -p results
|
||||
export GR_CONF_DEFAULT_MAX_MESSAGES=123
|
||||
$(eval REPETITION=$(shell python -c "print \"$@\".split(\"_\")[1]"))
|
||||
$(eval ENCODING=$(shell python -c "print \"$@\".split(\"_\")[2]"))
|
||||
$(eval SNR=$(shell python -c "print \"$@\".split(\"_\")[3]"))
|
||||
@echo REPETITION=$(REPETITION)
|
||||
@echo ENCODING=$(ENCODING)
|
||||
@echo SNR=$(SNR)
|
||||
./sim.py --messages=$(MESSAGES) --encoding=$(ENCODING) --snr=$(SNR) --repetition=$(REPETITION)
|
||||
#gdb -ex run -ex quit --args python ./sim.py --messages=$(MESSAGES) --encoding=$(ENCODING) --snr=$(SNR) --repetition=$(REPETITION)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
files=`ls results/*.pcap`
|
||||
outfile=results/all.csv
|
||||
rm -f ${outfile}
|
||||
|
||||
echo "repetition;encoding;snr;received"
|
||||
echo "repetition;encoding;snr;received" > ${outfile}
|
||||
|
||||
for f in ${files}
|
||||
do
|
||||
repetition=`python -c "print \"${f}\".split(\"_\")[1]"`
|
||||
encoding=`python -c "print \"${f}\".split(\"_\")[2]"`
|
||||
snr=`python -c "print \"${f}\".split(\"_\")[3]"`
|
||||
echo "file ${f} repetition ${repetition} encoding ${encoding} snr ${snr}"
|
||||
rcvd=`tshark -r ${f} | wc -l | tr -d " "`
|
||||
echo "${repetition};${encoding};${snr};${rcvd}"
|
||||
echo "${repetition};${encoding};${snr};${rcvd}" >> ${outfile}
|
||||
done
|
||||
Binary file not shown.
@@ -1,22 +0,0 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import matplotlib as mpl
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
pdr = pd.read_csv('./results/all.csv', sep=';')
|
||||
|
||||
pdr['encoding'] = pdr.encoding.astype("category", categories=range(8), ordered=True)
|
||||
|
||||
pdr.encoding.cat.categories = [
|
||||
"BPSK 1/2", "BPSK 3/4",
|
||||
"QPSK 1/2", "QPSK 3/4",
|
||||
"16-QAM 1/2", "16-QAM 3/4",
|
||||
"64-QAM 2/3", "64-QAM 3/4"]
|
||||
|
||||
a = pdr.groupby(['encoding', 'snr'])
|
||||
|
||||
b = a.agg({'received': np.mean}).reset_index()
|
||||
c = b.pivot(index='snr', columns='encoding', values='received')
|
||||
c.plot()
|
||||
plt.savefig('pdr.pdf')
|
||||
|
||||
@@ -1,957 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<?grc format='1' created='3.8.git'?>
|
||||
<flow_graph>
|
||||
<timestamp>Sat Feb 1 18:28:19 2014</timestamp>
|
||||
<block>
|
||||
<key>options</key>
|
||||
<param>
|
||||
<key>author</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>window_size</key>
|
||||
<value>1280, 1024</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>category</key>
|
||||
<value>Custom</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>description</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 13)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>generate_options</key>
|
||||
<value>no_gui</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>hier_block_src_path</key>
|
||||
<value>.:</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>sim</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>max_nouts</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>qt_qss_theme</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>realtime_scheduling</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>run_command</key>
|
||||
<value>{python} -u {filename}</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>run_options</key>
|
||||
<value>run</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>run</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>thread_safe_setters</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>title</key>
|
||||
<value></value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 260)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>filename</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value> "results/sim_%d_%d_%.1f_.pcap" % (repetition, encoding, snr)</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 93)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>out_buf_size</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>96000</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>analog_noise_source_x</key>
|
||||
<param>
|
||||
<key>amp</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(916, 616)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>90</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>analog_noise_source_x_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>noise_type</key>
|
||||
<value>analog.GR_GAUSSIAN</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>seed</key>
|
||||
<value>repetition</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_add_xx</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(904, 496)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>90</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_add_xx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>num_inputs</key>
|
||||
<value>2</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_file_sink</key>
|
||||
<param>
|
||||
<key>append</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>file</key>
|
||||
<value>filename</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(256, 388)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_file_sink_0_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>byte</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>unbuffered</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_multiply_const_vxx</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>const</key>
|
||||
<value>(10**(snr/10.0))**.5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(688, 588)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_multiply_const_vxx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value>0, 1, ..., 6, 7
|
||||
corresponds to BPSK 1/2, ..., 64-QAM 3/4</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(792, 11)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>encoding</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>e</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>foo_packet_pad2</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>delay_sec</key>
|
||||
<value>0.001</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>delay</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(512, 560)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>foo_packet_pad2_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>out_buf_size</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>pad_front</key>
|
||||
<value>1000</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>pad_tail</key>
|
||||
<value>1000</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>foo_random_periodic_msg_source</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(392, 200)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>foo_random_periodic_msg_source_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>msg_len</key>
|
||||
<value>pdu_len - 24</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>num</key>
|
||||
<value>messages</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>interval</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>quit</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>seed</key>
|
||||
<value>repetition</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>foo_wireshark_connector</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(464, 396)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>foo_wireshark_connector_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>tech</key>
|
||||
<value>127</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>ieee802_11_mac</key>
|
||||
<param>
|
||||
<key>bss_mac</key>
|
||||
<value>[0xff, 0xff, 0xff, 0xff, 0xff, 0xff]</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>dst_mac</key>
|
||||
<value>[0x42, 0x42, 0x42, 0x42, 0x42, 0x42]</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(720, 236)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>ieee802_11_mac_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>src_mac</key>
|
||||
<value>[0x23, 0x23, 0x23, 0x23, 0x23, 0x23]</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 156)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import math</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 212)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import random</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value>Number of messages to generate</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(416, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>messages</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>n</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>10</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value>Packet size (in byte)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(1048, 11)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>pdu_len</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>l</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>435</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value>Current repetition of experiment.</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(208, 11)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>repetition</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>r</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>23</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value>Signal to Noise Ratio</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(632, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>snr</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>s</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>eng_float</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>10</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>wifi_phy_hier</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(720, 408)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>wifi_phy_hier_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>bandwidth</key>
|
||||
<value>10e6</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>chan_est</key>
|
||||
<value>ieee802_11.LS</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>encoding</key>
|
||||
<value>encoding</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>frequency</key>
|
||||
<value>5.89e9</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>sensitivity</key>
|
||||
<value>0.56</value>
|
||||
</param>
|
||||
</block>
|
||||
<connection>
|
||||
<source_block_id>analog_noise_source_x_0</source_block_id>
|
||||
<sink_block_id>blocks_add_xx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>1</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_add_xx_0</source_block_id>
|
||||
<sink_block_id>wifi_phy_hier_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
||||
<sink_block_id>blocks_add_xx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>foo_packet_pad2_0</source_block_id>
|
||||
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>foo_random_periodic_msg_source_0</source_block_id>
|
||||
<sink_block_id>ieee802_11_mac_0</sink_block_id>
|
||||
<source_key>out</source_key>
|
||||
<sink_key>app in</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>foo_wireshark_connector_0</source_block_id>
|
||||
<sink_block_id>blocks_file_sink_0_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>ieee802_11_mac_0</source_block_id>
|
||||
<sink_block_id>wifi_phy_hier_0</sink_block_id>
|
||||
<source_key>phy out</source_key>
|
||||
<sink_key>mac_in</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>wifi_phy_hier_0</source_block_id>
|
||||
<sink_block_id>foo_wireshark_connector_0</sink_block_id>
|
||||
<source_key>mac_out</source_key>
|
||||
<sink_key>in</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>wifi_phy_hier_0</source_block_id>
|
||||
<sink_block_id>foo_packet_pad2_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
</flow_graph>
|
||||
@@ -1,2 +0,0 @@
|
||||
results/
|
||||
sim.py
|
||||
@@ -1,30 +0,0 @@
|
||||
SHELL=/bin/bash
|
||||
MESSAGES=100
|
||||
ENCODING=0
|
||||
|
||||
PCAPFILES=$(shell python -c 'import itertools; import numpy as np; print(" ".join(["results/sim_%d_%.2f_%.1f_.pcap" % x for x in itertools.product(range(10), np.arange(.4, .7,.02), np.arange(-3, 10, .5))]))')
|
||||
|
||||
all: pdr.pdf
|
||||
|
||||
pdr.pdf: plot.py results/all.csv
|
||||
python ./plot.py
|
||||
|
||||
sim.py: sim.grc
|
||||
grcc -d . sim.grc
|
||||
|
||||
results/all.csv: $(PCAPFILES)
|
||||
./parse.sh
|
||||
|
||||
%.pcap: sim.py
|
||||
mkdir -p results
|
||||
export GR_CONF_DEFAULT_MAX_MESSAGES=123
|
||||
@echo $@
|
||||
$(eval REPETITION=$(shell python -c "print \"$@\".split(\"_\")[1]"))
|
||||
$(eval SENSITIVITY=$(shell python -c "print \"$@\".split(\"_\")[2]"))
|
||||
$(eval SNR=$(shell python -c "print \"$@\".split(\"_\")[3]"))
|
||||
@echo REPETITION=$(REPETITION)
|
||||
@echo SENSITIVITY=$(SENSITiVITY)
|
||||
@echo SNR=$(SNR)
|
||||
./sim.py --messages=$(MESSAGES) --encoding=$(ENCODING) --sensitivity=$(SENSITIVITY) --snr=$(SNR) --repetition=$(REPETITION)
|
||||
# gdb -ex run -ex quit --args python ./sim.py --messages=$(MESSAGES) --encoding=$(ENCODING) --sensitivity=$(SENSITIVITY) --snr=$(SNR) --repetition=$(REPETITION)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
files=`ls results/*.pcap`
|
||||
outfile=results/all.csv
|
||||
rm -f ${outfile}
|
||||
|
||||
echo "repetition;sensitivity;snr;received"
|
||||
echo "repetition;sensitivity;snr;received" > ${outfile}
|
||||
|
||||
for f in ${files}
|
||||
do
|
||||
repetition=`python -c "print \"${f}\".split(\"_\")[1]"`
|
||||
sensitivity=`python -c "print \"${f}\".split(\"_\")[2]"`
|
||||
snr=`python -c "print \"${f}\".split(\"_\")[3]"`
|
||||
echo "file ${f} repetition ${repetition} sensitivity ${sensitivity} snr ${snr}"
|
||||
rcvd=`tshark -r ${f} | wc -l | tr -d " "`
|
||||
echo "${repetition};${sensitivity};${snr};${rcvd}"
|
||||
echo "${repetition};${sensitivity};${snr};${rcvd}" >> ${outfile}
|
||||
done
|
||||
Binary file not shown.
@@ -1,14 +0,0 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import matplotlib as mpl
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
pdr = pd.read_csv('./results/all.csv', sep=';')
|
||||
|
||||
a = pdr.groupby(['sensitivity', 'snr'])
|
||||
|
||||
b = a.agg({'received': np.mean}).reset_index()
|
||||
c = b.pivot(index='snr', columns='sensitivity', values='received')
|
||||
c.plot()
|
||||
plt.savefig('pdr.pdf')
|
||||
|
||||
@@ -1,993 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<?grc format='1' created='3.8.git'?>
|
||||
<flow_graph>
|
||||
<timestamp>Sat Feb 1 18:28:19 2014</timestamp>
|
||||
<block>
|
||||
<key>options</key>
|
||||
<param>
|
||||
<key>author</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>window_size</key>
|
||||
<value>1280, 1024</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>category</key>
|
||||
<value>Custom</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>description</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(7, 4)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>generate_options</key>
|
||||
<value>no_gui</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>hier_block_src_path</key>
|
||||
<value>.:</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>sim</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>max_nouts</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>qt_qss_theme</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>realtime_scheduling</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>run_command</key>
|
||||
<value>{python} -u {filename}</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>run_options</key>
|
||||
<value>run</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>run</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>thread_safe_setters</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>title</key>
|
||||
<value></value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 244)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>filename</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>"results/sim_%d_%.2f_%.1f_.pcap" % (repetition, sensitivity, snr)</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>variable</key>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 85)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>out_buf_size</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>96000</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_file_sink</key>
|
||||
<param>
|
||||
<key>append</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>file</key>
|
||||
<value>filename</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(112, 358)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_file_sink_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>byte</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>unbuffered</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>blocks_multiply_const_vxx</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>const</key>
|
||||
<value>(10**(snr/10.0))**.5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(696, 548)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>blocks_multiply_const_vxx_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>complex</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>vlen</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>channels_channel_model</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>block_tags</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>epsilon</key>
|
||||
<value>1.0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>freq_offset</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(928, 520)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>channels_channel_model_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>noise_voltage</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>seed</key>
|
||||
<value>repetition</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>taps</key>
|
||||
<value>1.0</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(208, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>encoding</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>e</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>foo_packet_pad2</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>delay_sec</key>
|
||||
<value>0.001</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>delay</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(480, 520)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>foo_packet_pad2_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>out_buf_size</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>pad_front</key>
|
||||
<value>2000</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>pad_tail</key>
|
||||
<value>2000</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>foo_random_periodic_msg_source</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(472, 184)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>foo_random_periodic_msg_source_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>msg_len</key>
|
||||
<value>pdu_len - 24</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>num</key>
|
||||
<value>messages</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>interval</key>
|
||||
<value>5</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>quit</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>seed</key>
|
||||
<value>repetition</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>foo_wireshark_connector</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>debug</key>
|
||||
<value>False</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>1</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(320, 365)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>foo_wireshark_connector_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>tech</key>
|
||||
<value>127</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>ieee802_11_mac</key>
|
||||
<param>
|
||||
<key>bss_mac</key>
|
||||
<value>[0xff, 0xff, 0xff, 0xff, 0xff, 0xff]</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>dst_mac</key>
|
||||
<value>[0x42, 0x42, 0x42, 0x42, 0x42, 0x42]</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(800, 220)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>ieee802_11_mac_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>src_mac</key>
|
||||
<value>[0x23, 0x23, 0x23, 0x23, 0x23, 0x23]</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 148)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import math</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>import</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(8, 196)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>import_0_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>import</key>
|
||||
<value>import random</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(576, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>interval</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>i</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>eng_float</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>400</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(672, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>messages</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>m</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>10</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(392, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>pdu_len</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>l</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>435</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(296, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>repetition</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>r</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>intx</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>23</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(760, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>sensitivity</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>S</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>eng_float</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>0.58</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>parameter</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(480, 6)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>snr</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>label</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>short_id</key>
|
||||
<value>s</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>type</key>
|
||||
<value>eng_float</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>10</value>
|
||||
</param>
|
||||
</block>
|
||||
<block>
|
||||
<key>wifi_phy_hier</key>
|
||||
<param>
|
||||
<key>alias</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>comment</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>affinity</key>
|
||||
<value></value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_coordinate</key>
|
||||
<value>(792, 377)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
<value>180</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>id</key>
|
||||
<value>wifi_phy_hier_0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>minoutbuf</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>bandwidth</key>
|
||||
<value>10e6</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>chan_est</key>
|
||||
<value>0</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>encoding</key>
|
||||
<value>encoding</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>frequency</key>
|
||||
<value>5.89e9</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>sensitivity</key>
|
||||
<value>sensitivity</value>
|
||||
</param>
|
||||
</block>
|
||||
<connection>
|
||||
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
|
||||
<sink_block_id>channels_channel_model_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>channels_channel_model_0</source_block_id>
|
||||
<sink_block_id>wifi_phy_hier_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>foo_packet_pad2_0</source_block_id>
|
||||
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>foo_random_periodic_msg_source_0</source_block_id>
|
||||
<sink_block_id>ieee802_11_mac_0</sink_block_id>
|
||||
<source_key>out</source_key>
|
||||
<sink_key>app in</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>foo_wireshark_connector_0</source_block_id>
|
||||
<sink_block_id>blocks_file_sink_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>ieee802_11_mac_0</source_block_id>
|
||||
<sink_block_id>wifi_phy_hier_0</sink_block_id>
|
||||
<source_key>phy out</source_key>
|
||||
<sink_key>mac_in</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>wifi_phy_hier_0</source_block_id>
|
||||
<sink_block_id>foo_wireshark_connector_0</sink_block_id>
|
||||
<source_key>mac_out</source_key>
|
||||
<sink_key>in</sink_key>
|
||||
</connection>
|
||||
<connection>
|
||||
<source_block_id>wifi_phy_hier_0</source_block_id>
|
||||
<sink_block_id>foo_packet_pad2_0</sink_block_id>
|
||||
<source_key>0</source_key>
|
||||
<sink_key>0</sink_key>
|
||||
</connection>
|
||||
</flow_graph>
|
||||
@@ -21,7 +21,6 @@
|
||||
find_package(SWIG)
|
||||
find_package(PythonLibs 2)
|
||||
if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND)
|
||||
message(FATAL_ERROR "Python or Swig not found (or version not supported).")
|
||||
return()
|
||||
endif()
|
||||
include(GrSwig)
|
||||
|
||||
+34
-57
@@ -22,80 +22,57 @@
|
||||
%include "ieee802_11_swig_doc.i"
|
||||
|
||||
%{
|
||||
#include "gnuradio/digital/packet_header_default.h"
|
||||
|
||||
#include "ieee802-11/chunks_to_symbols.h"
|
||||
#include "ieee802-11/constellations.h"
|
||||
#include "ieee802-11/decode_mac.h"
|
||||
#include "ieee802-11/ether_encap.h"
|
||||
#include "ieee802-11/frame_equalizer.h"
|
||||
#include "ieee802-11/mac.h"
|
||||
#include "ieee802-11/mapper.h"
|
||||
#include "ieee802-11/moving_average_cc.h"
|
||||
#include "ieee802-11/moving_average_ff.h"
|
||||
#include "ieee802-11/parse_mac.h"
|
||||
#include "ieee802-11/signal_field.h"
|
||||
#include "ieee802-11/sync_long.h"
|
||||
#include "ieee802-11/sync_short.h"
|
||||
#include "ieee802-11/ofdm_decode_mac.h"
|
||||
#include "ieee802-11/ofdm_decode_signal.h"
|
||||
#include "ieee802-11/ofdm_equalize_symbols.h"
|
||||
#include "ieee802-11/ofdm_mac.h"
|
||||
#include "ieee802-11/ofdm_mapper.h"
|
||||
#include "ieee802-11/ofdm_parse_mac.h"
|
||||
#include "ieee802-11/ofdm_sync_long.h"
|
||||
#include "ieee802-11/ofdm_sync_short.h"
|
||||
#include "ieee802-11/wifi_edca.h"
|
||||
#include "ieee802-11/wifi_signal_field.h"
|
||||
%}
|
||||
|
||||
%include "gnuradio/digital/packet_header_default.h"
|
||||
|
||||
%ignore gr::digital::constellation_bpsk;
|
||||
%ignore gr::digital::constellation_qpsk;
|
||||
%ignore gr::digital::constellation_16qam;
|
||||
%include "gnuradio/digital/constellation.h"
|
||||
|
||||
%include "ieee802-11/chunks_to_symbols.h"
|
||||
%include "ieee802-11/constellations.h"
|
||||
%include "ieee802-11/decode_mac.h"
|
||||
%include "ieee802-11/ether_encap.h"
|
||||
%include "ieee802-11/frame_equalizer.h"
|
||||
%include "ieee802-11/mac.h"
|
||||
%include "ieee802-11/mapper.h"
|
||||
%include "ieee802-11/moving_average_cc.h"
|
||||
%include "ieee802-11/moving_average_ff.h"
|
||||
%include "ieee802-11/parse_mac.h"
|
||||
%include "ieee802-11/signal_field.h"
|
||||
%include "ieee802-11/sync_long.h"
|
||||
%include "ieee802-11/sync_short.h"
|
||||
%include "ieee802-11/ofdm_decode_mac.h"
|
||||
%include "ieee802-11/ofdm_decode_signal.h"
|
||||
%include "ieee802-11/ofdm_equalize_symbols.h"
|
||||
%include "ieee802-11/ofdm_mac.h"
|
||||
%include "ieee802-11/ofdm_mapper.h"
|
||||
%include "ieee802-11/ofdm_parse_mac.h"
|
||||
%include "ieee802-11/ofdm_sync_long.h"
|
||||
%include "ieee802-11/ofdm_sync_short.h"
|
||||
%include "ieee802-11/wifi_edca.h"
|
||||
%include "ieee802-11/wifi_signal_field.h"
|
||||
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, chunks_to_symbols);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, decode_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ether_encap);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, frame_equalizer);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, mapper);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, moving_average_cc);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, moving_average_ff);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, parse_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, sync_long);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, sync_short);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_signal);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_equalize_symbols);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_mapper);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_parse_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_long);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_short);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, wifi_edca);
|
||||
|
||||
%template(signal_field_sptr) boost::shared_ptr<gr::ieee802_11::signal_field>;
|
||||
%template(wifi_signal_field_sptr) boost::shared_ptr<gr::ieee802_11::wifi_signal_field>;
|
||||
%pythoncode %{
|
||||
signal_field_sptr.__repr__ = lambda self: "<signal_field>"
|
||||
signal_field = signal_field.make;
|
||||
%}
|
||||
|
||||
%template(constellation_bpsk_sptr) boost::shared_ptr<gr::ieee802_11::constellation_bpsk>;
|
||||
%pythoncode %{
|
||||
constellation_bpsk_sptr.__repr__ = lambda self: "<constellation BPSK>"
|
||||
constellation_bpsk = constellation_bpsk.make;
|
||||
%}
|
||||
|
||||
%template(constellation_qpsk_sptr) boost::shared_ptr<gr::ieee802_11::constellation_qpsk>;
|
||||
%pythoncode %{
|
||||
constellation_qpsk_sptr.__repr__ = lambda self: "<constellation QPSK>"
|
||||
constellation_qpsk = constellation_qpsk.make;
|
||||
%}
|
||||
|
||||
%template(constellation_16qam_sptr) boost::shared_ptr<gr::ieee802_11::constellation_16qam>;
|
||||
%pythoncode %{
|
||||
constellation_16qam_sptr.__repr__ = lambda self: "<constellation 16QAM>"
|
||||
constellation_16qam = constellation_16qam.make;
|
||||
%}
|
||||
|
||||
%template(constellation_64qam_sptr) boost::shared_ptr<gr::ieee802_11::constellation_64qam>;
|
||||
%pythoncode %{
|
||||
constellation_64qam_sptr.__repr__ = lambda self: "<constellation 64QAM>"
|
||||
constellation_64qam = constellation_64qam.make;
|
||||
wifi_signal_field_sptr.__repr__ = lambda self: "<wifi_signal_field>"
|
||||
wifi_signal_field = wifi_signal_field .make;
|
||||
%}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,43 @@
|
||||
dB2lin <- function(x) { 10^(x/10) }
|
||||
|
||||
gain.levels <- 0:46 * 2
|
||||
gains <- dB2lin(gain.levels)
|
||||
|
||||
ref.level <- 1/0.03125 # the level we want to tune to
|
||||
ref.gain <- gains[which(gain.levels == 46)] # idle gain setting
|
||||
|
||||
abs.level <- ref.level * ref.gain / gains
|
||||
|
||||
abs.level.int <- round(abs.level * 2**15)
|
||||
|
||||
lna.level <- c(0, 16, 30)
|
||||
lna.conf <- c(0, 64, 96)
|
||||
|
||||
cat('if signed(power_in) > ', abs.level.int[1], ' then
|
||||
a <= std_logic_vector(to_unsigned(0, 7));\n');
|
||||
|
||||
last = abs.level.int[1]
|
||||
for(i in 2:length(abs.level.int)) {
|
||||
if(abs.level.int[i] == last) {
|
||||
next
|
||||
}
|
||||
last = abs.level.int[i];
|
||||
gdb = gain.levels[i]
|
||||
|
||||
lna.index = max(which(lna.level <= gdb))
|
||||
gdb = gdb - lna.level[lna.index]
|
||||
lna = lna.conf[lna.index]
|
||||
gdb = floor(gdb / 2)
|
||||
|
||||
cat('elsif signed(power_in) > ', last, ' then
|
||||
a <= std_logic_vector(to_unsigned(', lna + gdb, ', 7));\n');
|
||||
}
|
||||
|
||||
|
||||
# --if signed(power_in) > 2**24 then
|
||||
# -- a <= std_logic_vector(to_unsigned(0, 7));
|
||||
# --elsif signed(power_in) > 2**16 then
|
||||
# -- a <= std_logic_vector(to_unsigned(32, 7));
|
||||
# --else
|
||||
# -- a <= std_logic_vector(to_unsigned(127, 7));
|
||||
# --end if;
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
channels = [
|
||||
### 11g
|
||||
|
||||
1, 2412e6, "11g",
|
||||
2, 2417e6, "11g",
|
||||
3, 2422e6, "11g",
|
||||
4, 2427e6, "11g",
|
||||
5, 2432e6, "11g",
|
||||
6, 2437e6, "11g",
|
||||
7, 2442e6, "11g",
|
||||
8, 2447e6, "11g",
|
||||
9, 2452e6, "11g",
|
||||
10, 2457e6, "11g",
|
||||
11, 2462e6, "11g",
|
||||
12, 2467e6, "11g",
|
||||
13, 2472e6, "11g",
|
||||
14, 2484e6, "11g",
|
||||
|
||||
### 11a
|
||||
|
||||
34, 5170e6, "11a",
|
||||
36, 5180e6, "11a",
|
||||
38, 5190e6, "11a",
|
||||
40, 5200e6, "11a",
|
||||
42, 5210e6, "11a",
|
||||
44, 5220e6, "11a",
|
||||
46, 5230e6, "11a",
|
||||
48, 5240e6, "11a",
|
||||
|
||||
50, 5250e6, "11a",
|
||||
52, 5260e6, "11a",
|
||||
54, 5270e6, "11a",
|
||||
56, 5280e6, "11a",
|
||||
58, 5290e6, "11a",
|
||||
60, 5300e6, "11a",
|
||||
62, 5310e6, "11a",
|
||||
64, 5320e6, "11a",
|
||||
|
||||
100, 5500e6, "11a",
|
||||
102, 5510e6, "11a",
|
||||
104, 5520e6, "11a",
|
||||
106, 5530e6, "11a",
|
||||
108, 5540e6, "11a",
|
||||
110, 5550e6, "11a",
|
||||
112, 5560e6, "11a",
|
||||
114, 5570e6, "11a",
|
||||
116, 5580e6, "11a",
|
||||
118, 5590e6, "11a",
|
||||
120, 5600e6, "11a",
|
||||
122, 5610e6, "11a",
|
||||
124, 5620e6, "11a",
|
||||
126, 5630e6, "11a",
|
||||
128, 5640e6, "11a",
|
||||
132, 5660e6, "11a",
|
||||
134, 5670e6, "11a",
|
||||
136, 5680e6, "11a",
|
||||
138, 5690e6, "11a",
|
||||
140, 5700e6, "11a",
|
||||
142, 5710e6, "11a",
|
||||
144, 5720e6, "11a",
|
||||
|
||||
149, 5745e6, "11a (SRD)",
|
||||
151, 5755e6, "11a (SRD)",
|
||||
153, 5765e6, "11a (SRD)",
|
||||
155, 5775e6, "11a (SRD)",
|
||||
157, 5785e6, "11a (SRD)",
|
||||
159, 5795e6, "11a (SRD)",
|
||||
161, 5805e6, "11a (SRD)",
|
||||
165, 5825e6, "11a (SRD)",
|
||||
|
||||
|
||||
### 11p
|
||||
172, 5860e6, "11p",
|
||||
174, 5870e6, "11p",
|
||||
176, 5880e6, "11p",
|
||||
178, 5890e6, "11p",
|
||||
180, 5900e6, "11p",
|
||||
182, 5910e6, "11p",
|
||||
184, 5920e6, "11p"
|
||||
]
|
||||
|
||||
labels = []
|
||||
freqs = []
|
||||
for i in range(0, len(channels), 3):
|
||||
labels.append(repr(channels[i]).rjust(3) + " | " + repr(channels[i+1]/1e6) + " | " + channels[i+2])
|
||||
freqs.append(channels[i+1])
|
||||
|
||||
|
||||
print labels
|
||||
print freqs
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user