21 Commits

Author SHA1 Message Date
Bastian Bloessl 3fac8b1ce9 Merge branch 'master' into agc_and_csma 2015-04-23 16:26:34 +02:00
Bastian Bloessl 948f1c80ae agc level calculation script 2015-04-23 10:01:16 +02:00
Bastian Bloessl f85bfca13a Merge branch 'master' into agc_and_csma 2015-04-22 15:58:38 +02:00
Bastian Bloessl 8814b4b333 dc_offset script change dummy parameters to avoid warnings 2015-04-21 09:05:55 +02:00
Bastian Bloessl 7565ec5246 agc / csma flow graph fix lo offset 2015-04-21 09:05:22 +02:00
Bastian Bloessl 2c95b5e07f update rx agc flow graph 2015-04-20 16:10:58 +02:00
Bastian Bloessl df4f14f220 add script to enable / disable DC offset correction 2015-04-20 15:13:48 +02:00
Bastian Bloessl c664ac99a7 Merge branch 'release' into agc_and_csma 2015-04-20 15:12:54 +02:00
Bastian Bloessl 9614b4a459 add edca to csma flow graph 2015-03-04 16:54:16 +01:00
Bastian Bloessl 73095d93f3 mac: add csma parameter 2015-03-04 16:54:16 +01:00
Bastian Bloessl cf0af12054 grc:use new csma sind and agc source 2015-03-04 16:54:16 +01:00
Bastian Bloessl c8de2646ae rename flow graphs 2015-03-04 16:54:15 +01:00
Bastian Bloessl 1d682b172b delete unused example 2015-03-04 16:54:15 +01:00
Bastian Bloessl f2dc4c4f0b update csma flow graph 2015-03-04 16:54:15 +01:00
Bastian Bloessl 137cc3e944 add CSMA flow graph 2015-03-04 16:54:14 +01:00
Bastian Bloessl 8300907d85 add AGC demo example 2015-03-04 16:54:14 +01:00
Bastian Bloessl 73317734f3 make flow graph nicer 2015-03-04 16:54:13 +01:00
Bastian Bloessl 023ede6821 ofdm mapper: convert metadaata to tags 2015-03-04 16:54:13 +01:00
Bastian Bloessl e1dbdef395 mac: preserve metadata of input pdu 2015-03-04 16:54:13 +01:00
Bastian Bloessl a04945a35b edca tag pdus with edca parameters 2015-03-04 16:54:12 +01:00
Bastian Bloessl fe4ae7f802 add edca block 2015-03-04 16:54:12 +01:00
104 changed files with 17356 additions and 17100 deletions
-13
View File
@@ -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
-2
View File
@@ -5,5 +5,3 @@ examples/*.py
.pydevproject .pydevproject
.settings .settings
*.pyc *.pyc
**/.DS_Store
.clang_complete
+19 -19
View File
@@ -37,7 +37,6 @@ if(NOT WIN32)
#http://gcc.gnu.org/wiki/Visibility #http://gcc.gnu.org/wiki/Visibility
add_definitions(-fvisibility=hidden) add_definitions(-fvisibility=hidden)
add_definitions(-std=c++0x) add_definitions(-std=c++0x)
add_definitions(-msse2)
endif() endif()
######################################################################## ########################################################################
@@ -82,31 +81,29 @@ set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
# Find gnuradio build dependencies # Find gnuradio build dependencies
######################################################################## ########################################################################
set(GR_REQUIRED_COMPONENTS RUNTIME FILTER FFT PMT DIGITAL) set(GR_REQUIRED_COMPONENTS RUNTIME FILTER FFT PMT DIGITAL)
find_package(Gnuradio) 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(CppUnit)
find_package(ITPP)
if(NOT GNURADIO_RUNTIME_FOUND)
message(FATAL_ERROR "GnuRadio Runtime required to compile ieee802-11")
endif()
if(NOT CPPUNIT_FOUND) if(NOT CPPUNIT_FOUND)
message(FATAL_ERROR "CppUnit required to compile gr-ieee802-11") message(FATAL_ERROR "CppUnit required to compile ieee802-11")
endif() endif()
find_package(Log4cpp) if(NOT ITPP_FOUND)
if (LOG4CPP_FOUND) message(FATAL_ERROR "ITPP required to compile ieee802-11")
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")
endif() 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 # On Apple only, set install name and use rpath correctly, if not already set
######################################################################## ########################################################################
@@ -136,13 +133,16 @@ include_directories(
${CMAKE_BINARY_DIR}/include ${CMAKE_BINARY_DIR}/include
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${CPPUNIT_INCLUDE_DIRS} ${CPPUNIT_INCLUDE_DIRS}
${ITPP_INCLUDE_DIR}
${GNURADIO_RUNTIME_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS}
${LOG4CPP_INCLUDE_DIRS}
) )
link_directories( link_directories(
${Boost_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS}
${CPPUNIT_LIBRARY_DIRS} ${CPPUNIT_LIBRARY_DIRS}
${GNURADIO_RUNTIME_LIBRARY_DIRS} ${GNURADIO_RUNTIME_LIBRARY_DIRS}
${LOG4CPP_LIBRARY_DIRS}
) )
######################################################################## ########################################################################
+75 -94
View File
@@ -1,41 +1,45 @@
Hi! 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.
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 # Installation
## Dependencies ## 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 There are several ways to install GNU Radio. You can use
- [pybombs](http://gnuradio.org/redmine/projects/pybombs/wiki) - [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) - [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 ### gr-foo
I have some non project specific GNU Radio blocks in my gr-foo repo that are 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:
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 git clone https://github.com/bastibl/gr-foo.git
cd gr-foo cd gr-foo
@@ -61,73 +65,48 @@ To actually install the blocks do
sudo ldconfig sudo ldconfig
### Adjust Maximum Shared Memory ### Adjust Maximum Shared Memory
Since the transmitter is using the Tagged Stream blocks it has to store a 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
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 sudo sysctl -w kernel.shmmax=2147483648
### OFDM PHY ### OFDM PHY
The physical layer is encapsulated in a hierarchical block to allow for a 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/```.
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 ### Check message port connections
Sometime the connections between the message ports (the gray ones in GNU Radio 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.
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 ### Python OpenGL
If you want to run the receive demo (the one that plots the subcarrier 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.
constellations), please assert that you have python-opengl installed. The nongl
version of the plot does not work for me.
### Run volk_profile ### Run volk_profile
volk_profile is part of GNU Radio. It benchmarks different SIMD implementations 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.
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 ### Calibrate your daughterboard
If you have a WBX, SBX, or CBX daughterboard you should calibrate it in order to 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).
minimize IQ imbalance and TX DC offsets. See the [application
notes](http://files.ettus.com/manual/page_calibration.html).
# Checking your installation
As a first step I recommend to test the ```wifi_loopback.grc``` flow graph. This # Checking you installation
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.
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 ## Troubleshooting
If GRC complains that it can't find some blocks (other than performance counters If GRC complains that it can't find some blocks (other than performance counters and hierarchical blocks) like
and hierarchical blocks) like
>>> Error: Block key "ieee802_11_ofdm_mac" not found in Platform - grc(GNU Radio Companion) >>> 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) >>> 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 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
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] [grc]
global_blocks_path = /opt/local/share/gnuradio/grc/blocks global_blocks_path = /opt/local/share/gnuradio/grc/blocks
@@ -141,69 +120,71 @@ But with the directories that match your installation.
## Simulation ## Simulation
The loopback flow graph should give you an idea of how simulations can be 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).
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 ## Unidirectional communication
As first over the air test I recommend to try ```wifi_rx.grc``` and 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.
```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 ## RX frames from a WiFi card
```wifi_loopback.grc``` example.
TBD
## TX frames to a WiFi card
TBD
## Transceiver (SDR <-> SDR)
TBD
## Ad Hoc Network with WiFi card ## Ad Hoc Network with WiFi card
- The transceiver is currently connected to a TAP device, i.e. is a virtual - 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.
Ethernet interface. Therefore, we have no WiFi signaling like association - 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).
requests and hence, the transceiver can not "join" an ad hoc network. You have - RTS/CTS is not working for the same reason. You can however just disable this mechanism.
to make some small changes to the kernel in order to convince you WiFi card to - Currently, there is no CSMA/CA mechanism, but this can be implemented on the FPGA.
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 # Troubleshooting
- Please check compile and installation logs. They might contain interesting
information.
- Did you calibrate your daughterboard? - Did you calibrate your daughterboard?
- Did you run volk_profile? - Did you run volk_profile?
- Did you try different gain settings? - Did you try different gain settings?
- Did you close the case of the devices? - Did you close the case of the devices?
- Did you try real-time priority? - Did you try real-time priority?
- Did you compile GNU Radio and gr-ieee802-11 in release mode? - Did you compile GNU Radio and gr-ieee802-11 in release mode?
- If you see warnings that ```blocks_ctrlport_monitor_performance``` is missing - 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.
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 - The message
You must now use ifconfig to set its IP address. E.g., You must now use ifconfig to set its IP address. E.g.,
$ sudo ifconfig tap0 192.168.200.1 $ sudo ifconfig tap0 192.168.200.1
is normal and is output by the TUN/Tap Block during startup. The configuration 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.
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)?
- Did you try to tune the RF frequency out of the band of interest (i.e. used - 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?
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 # Asking for help
directly to the USRP without a switch in between?
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 # Further information
For further information please checkout our project page 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/)
+56
View File
@@ -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
View File
@@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
### Enable Wireshark Connector in wifi_rx flow graph FILE="/tmp/ofdm.pcap"
FILE="/tmp/wifi.pcap"
FLOWGRAPH="wifi_rx.py" FLOWGRAPH="wifi_rx.py"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-3
View File
@@ -15,7 +15,6 @@ PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
FIND_PATH(CPPUNIT_INCLUDE_DIRS FIND_PATH(CPPUNIT_INCLUDE_DIRS
NAMES cppunit/TestCase.h NAMES cppunit/TestCase.h
HINTS ${PC_CPPUNIT_INCLUDE_DIR} HINTS ${PC_CPPUNIT_INCLUDE_DIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS PATHS
/usr/local/include /usr/local/include
/usr/include /usr/include
@@ -24,8 +23,6 @@ FIND_PATH(CPPUNIT_INCLUDE_DIRS
FIND_LIBRARY(CPPUNIT_LIBRARIES FIND_LIBRARY(CPPUNIT_LIBRARIES
NAMES cppunit NAMES cppunit
HINTS ${PC_CPPUNIT_LIBDIR} HINTS ${PC_CPPUNIT_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
PATHS PATHS
${CPPUNIT_INCLUDE_DIRS}/../lib ${CPPUNIT_INCLUDE_DIRS}/../lib
/usr/local/lib /usr/local/lib
-36
View File
@@ -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)
+70
View File
@@ -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
)
+1 -7
View File
@@ -94,13 +94,7 @@ macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${flag} ${have}) CHECK_CXX_COMPILER_FLAG(${flag} ${have})
if(${have}) if(${have})
if(${CMAKE_VERSION} VERSION_GREATER "2.8.4") add_definitions(${flag})
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")
endif(${have}) endif(${have})
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
+3 -3
View File
@@ -29,15 +29,15 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINUX TRUE) set(LINUX TRUE)
endif() endif()
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/debian_version") if(LINUX AND EXISTS "/etc/debian_version")
set(DEBIAN TRUE) set(DEBIAN TRUE)
endif() endif()
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/redhat-release") if(LINUX AND EXISTS "/etc/redhat-release")
set(REDHAT TRUE) set(REDHAT TRUE)
endif() endif()
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/slackware-version") if(LINUX AND EXISTS "/etc/slackware-version")
set(SLACKWARE TRUE) set(SLACKWARE TRUE)
endif() endif()
+2 -1
View File
@@ -185,6 +185,7 @@ function(GR_PYTHON_INSTALL)
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
) )
#################################################################### ####################################################################
elseif(GR_PYTHON_INSTALL_PROGRAMS) elseif(GR_PYTHON_INSTALL_PROGRAMS)
#################################################################### ####################################################################
@@ -206,7 +207,7 @@ function(GR_PYTHON_INSTALL)
add_custom_command( add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile} OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c 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}" COMMENT "Shebangin ${pyfile_name}"
VERBATIM VERBATIM
) )
+3 -6
View File
@@ -39,7 +39,7 @@ function(GR_SWIG_MAKE_DOCS output_file)
set(input_files) set(input_files)
unset(INPUT_PATHS) unset(INPUT_PATHS)
foreach(input_path ${ARGN}) 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) file(GLOB input_path_h_files ${input_path}/*.h)
else() #otherwise its just a file, no glob else() #otherwise its just a file, no glob
set(input_path_h_files ${input_path}) 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 # 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 # 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. # 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("size_t" SIZEOF_SIZE_T)
CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT) CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT)
if(${SIZEOF_SIZE_T} EQUAL ${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}) endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
#do swig doc generation if specified #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}) set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS}) list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS})
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS}) GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
@@ -172,9 +172,6 @@ macro(GR_SWIG_MAKE name)
include(UseSWIG) include(UseSWIG)
SWIG_ADD_MODULE(${name} python ${ifiles}) SWIG_ADD_MODULE(${name} python ${ifiles})
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES}) 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) endmacro(GR_SWIG_MAKE)
-304
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1518 -1541
View File
File diff suppressed because it is too large Load Diff
+2462 -3432
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2358 -3493
View File
File diff suppressed because it is too large Load Diff
+1697 -1734
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,7 +2,7 @@
<block> <block>
<name>Chunks to Symbols</name> <name>Chunks to Symbols</name>
<key>ieee802_11_chunks_to_symbols_xx</key> <key>ieee802_11_chunks_to_symbols_xx</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <import>import ieee802_11</import>
<make>ieee802_11.chunks_to_symbols()</make> <make>ieee802_11.chunks_to_symbols()</make>
<sink> <sink>
+1 -1
View File
@@ -3,7 +3,7 @@
<block> <block>
<name>Ethernet Encapsulation</name> <name>Ethernet Encapsulation</name>
<key>ieee802_11_ether_encap</key> <key>ieee802_11_ether_encap</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <import>import ieee802_11</import>
<make>ieee802_11.ether_encap($debug)</make> <make>ieee802_11.ether_encap($debug)</make>
-105
View File
@@ -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>
+1 -1
View File
@@ -2,7 +2,7 @@
<block> <block>
<name>Moving Average</name> <name>Moving Average</name>
<key>ieee802_11_moving_average_xx</key> <key>ieee802_11_moving_average_xx</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <import>import ieee802_11</import>
<make>ieee802_11.moving_average_$(type.fcn)($length)</make> <make>ieee802_11.moving_average_$(type.fcn)($length)</make>
<callback>set_length($length)</callback> <callback>set_length($length)</callback>
@@ -1,11 +1,11 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<block> <block>
<name>WiFi Decode MAC</name> <name>OFDM Decode MAC</name>
<key>ieee802_11_decode_mac</key> <key>ieee802_11_ofdm_decode_mac</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <import>import ieee802_11</import>
<make>ieee802_11.decode_mac($log, $debug)</make> <make>ieee802_11.ofdm_decode_mac($log, $debug)</make>
<param> <param>
<name>Log</name> <name>Log</name>
@@ -41,14 +41,14 @@
<sink> <sink>
<name>in</name> <name>in</name>
<type>byte</type> <type>complex</type>
<vlen>48</vlen> <vlen>48</vlen>
<nports>1</nports>
</sink> </sink>
<source> <source>
<name>out</name> <name>out</name>
<type>message</type> <type>message</type>
<optional>1</optional>
</source> </source>
</block> </block>
+58
View File
@@ -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>
+58
View File
@@ -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"?> <?xml version="1.0"?>
<block> <block>
<name>WiFi MAC</name> <name>OFDM MAC</name>
<key>ieee802_11_mac</key> <key>ieee802_11_ofdm_mac</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <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> <param>
<name>SRC MAC</name> <name>SRC MAC</name>
@@ -1,11 +1,11 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<block> <block>
<name>WiFi Mapper</name> <name>OFDM Mapper</name>
<key>ieee802_11_mapper</key> <key>ieee802_11_ofdm_mapper</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <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> <callback>set_encoding($encoding)</callback>
<param> <param>
@@ -1,11 +1,11 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<block> <block>
<name>WiFi Parse MAC</name> <name>OFDM Parse MAC</name>
<key>ieee802_11_parse_mac</key> <key>ieee802_11_ofdm_parse_mac</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <import>import ieee802_11</import>
<make>ieee802_11.parse_mac($log, $debug)</make> <make>ieee802_11.ofdm_parse_mac($log, $debug)</make>
<param> <param>
<name>Log</name> <name>Log</name>
@@ -1,11 +1,11 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<block> <block>
<name>WiFi Sync Long</name> <name>OFDM Sync Long</name>
<key>ieee802_11_sync_long</key> <key>ieee802_11_ofdm_sync_long</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <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> <param>
<name>Log</name> <name>Log</name>
@@ -1,11 +1,11 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<block> <block>
<name>WiFi Sync Short</name> <name>OFDM Sync Short</name>
<key>ieee802_11_sync_short</key> <key>ieee802_11_ofdm_sync_short</key>
<category>[IEEE802.11]</category> <category>IEEE802.11</category>
<import>import ieee802_11</import> <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> <param>
<name>Log</name> <name>Log</name>
+37
View File
@@ -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>
+11 -10
View File
@@ -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 # 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 # it under the terms of the GNU General Public License as published by
@@ -70,16 +70,17 @@ list(APPEND include_sources
${generated_includes} ${generated_includes}
api.h api.h
chunks_to_symbols.h chunks_to_symbols.h
constellations.h
decode_mac.h
ether_encap.h ether_encap.h
frame_equalizer.h ofdm_decode_mac.h
mac.h ofdm_decode_signal.h
mapper.h ofdm_equalize_symbols.h
parse_mac.h ofdm_mac.h
signal_field.h ofdm_mapper.h
sync_long.h ofdm_parse_mac.h
sync_short.h ofdm_sync_long.h
ofdm_sync_short.h
wifi_edca.h
wifi_signal_field.h
) )
install( install(
-71
View File
@@ -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 */
-51
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_PARSE_MAC_H #ifndef INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H
#define INCLUDED_IEEE802_11_PARSE_MAC_H #define INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
@@ -23,16 +23,18 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API parse_mac : virtual public block class IEEE802_11_API ofdm_decode_mac : virtual public block
{ {
public: 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); static sptr make(bool log = false, bool debug = false);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H */
#endif /* INCLUDED_IEEE802_11_PARSE_MAC_H */
+39
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_MAC_H #ifndef INCLUDED_IEEE802_11_OFDM_MAC_H
#define INCLUDED_IEEE802_11_MAC_H #define INCLUDED_IEEE802_11_OFDM_MAC_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
@@ -23,11 +23,11 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API mac : virtual public block class IEEE802_11_API ofdm_mac : virtual public block
{ {
public: public:
typedef boost::shared_ptr<mac> sptr; typedef boost::shared_ptr<ofdm_mac> sptr;
static sptr make(std::vector<uint8_t> src_mac, static sptr make(std::vector<uint8_t> src_mac,
std::vector<uint8_t> dst_mac, std::vector<uint8_t> dst_mac,
std::vector<uint8_t> bss_mac); std::vector<uint8_t> bss_mac);
@@ -36,4 +36,4 @@ public:
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // 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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_MAPPER_H #ifndef INCLUDED_IEEE802_11_OFDM_MAPPER_H
#define INCLUDED_IEEE802_11_MAPPER_H #define INCLUDED_IEEE802_11_OFDM_MAPPER_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
@@ -34,11 +34,11 @@ enum Encoding {
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API mapper : virtual public block class IEEE802_11_API ofdm_mapper : virtual public block
{ {
public: public:
typedef boost::shared_ptr<mapper> sptr; typedef boost::shared_ptr<ofdm_mapper> sptr;
static sptr make(Encoding mcs, bool debug = false); static sptr make(Encoding mcs, bool debug = false);
virtual void set_encoding(Encoding mcs) = 0; virtual void set_encoding(Encoding mcs) = 0;
}; };
@@ -46,4 +46,4 @@ public:
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // 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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_DECODE_MAC_H #ifndef INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H
#define INCLUDED_IEEE802_11_DECODE_MAC_H #define INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
@@ -23,11 +23,11 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API decode_mac : virtual public block class IEEE802_11_API ofdm_parse_mac : virtual public block
{ {
public: 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); static sptr make(bool log = false, bool debug = false);
}; };
@@ -35,6 +35,4 @@ public:
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // 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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_SYNC_LONG_H #ifndef INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H
#define INCLUDED_IEEE802_11_SYNC_LONG_H #define INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
@@ -23,11 +23,11 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API sync_long : virtual public block class IEEE802_11_API ofdm_sync_long : virtual public block
{ {
public: public:
typedef boost::shared_ptr<sync_long> sptr; typedef boost::shared_ptr<ofdm_sync_long> sptr;
static sptr make(unsigned int sync_length, static sptr make(unsigned int sync_length,
bool log = false, bool debug = false); bool log = false, bool debug = false);
@@ -36,4 +36,4 @@ public:
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // 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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_SYNC_SHORT_H #ifndef INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H
#define INCLUDED_IEEE802_11_SYNC_SHORT_H #define INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
@@ -23,11 +23,11 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API sync_short : virtual public block class IEEE802_11_API ofdm_sync_short : virtual public block
{ {
public: 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); static sptr make(double threshold, unsigned int min_plateau, bool log = false, bool debug = false);
}; };
@@ -35,4 +35,4 @@ public:
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_SYNC_SHORT_H */ #endif /* INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H */
+37
View File
@@ -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 * 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 * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_H #ifndef INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H
#define INCLUDED_IEEE802_11_SIGNAL_FIELD_H #define INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <gnuradio/digital/packet_header_default.h> #include <gnuradio/digital/packet_header_default.h>
@@ -24,18 +24,18 @@
namespace gr { namespace gr {
namespace ieee802_11 { 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: public:
typedef boost::shared_ptr<signal_field> sptr; typedef boost::shared_ptr<wifi_signal_field> sptr;
static sptr make(); static sptr make();
protected: protected:
signal_field(); wifi_signal_field();
}; };
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_H */ #endif /* INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H */
+14 -16
View File
@@ -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 # 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 # 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 list(APPEND gr_ieee802_11_sources
${generated_sources} ${generated_sources}
chunks_to_symbols_impl.cc equalizer/linear_comb.cc
constellations_impl.cc
decode_mac.cc
equalizer/base.cc
equalizer/comb.cc
equalizer/ls.cc
equalizer/lms.cc equalizer/lms.cc
equalizer/sta.cc chunks_to_symbols_impl.cc
ether_encap_impl.cc ether_encap_impl.cc
frame_equalizer_impl.cc ofdm_decode_mac.cc
mac.cc ofdm_decode_signal.cc
mapper.cc ofdm_equalize_symbols.cc
parse_mac.cc ofdm_mac.cc
signal_field_impl.cc ofdm_mapper.cc
sync_long.cc ofdm_parse_mac.cc
sync_short.cc ofdm_sync_long.cc
ofdm_sync_short.cc
utils.cc utils.cc
viterbi_decoder.cc wifi_edca.cc
wifi_signal_field_impl.cc
) )
list(APPEND gr_ieee802_11_libs list(APPEND gr_ieee802_11_libs
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${GNURADIO_ALL_LIBRARIES} ${GNURADIO_ALL_LIBRARIES}
${ITPP_LIBRARIES}
${LOG4CPP_LIBRARIES} ${LOG4CPP_LIBRARIES}
) )
+63 -16
View File
@@ -28,17 +28,10 @@ chunks_to_symbols::make()
return gnuradio::get_initial_sptr(new chunks_to_symbols_impl()); return gnuradio::get_initial_sptr(new chunks_to_symbols_impl());
} }
chunks_to_symbols_impl::chunks_to_symbols_impl() : chunks_to_symbols_impl::chunks_to_symbols_impl()
tagged_stream_block("chunks_to_symbols", : tagged_stream_block("wifi_chunks_to_symbols",
io_signature::make(1, 1, sizeof(char)), io_signature::make(1, 1, sizeof(char)),
io_signature::make(1, 1, sizeof(gr_complex)), "packet_len") { 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() { } 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); Encoding encoding = (Encoding)pmt::to_long(tags[0].value);
const gr_complex *mapping;
switch (encoding) { switch (encoding) {
case BPSK_1_2: case BPSK_1_2:
case BPSK_3_4: case BPSK_3_4:
d_mapping = d_bpsk; mapping = BPSK;
break; break;
case QPSK_1_2: case QPSK_1_2:
case QPSK_3_4: case QPSK_3_4:
d_mapping = d_qpsk; mapping = QPSK;
break; break;
case QAM16_1_2: case QAM16_1_2:
case QAM16_3_4: case QAM16_3_4:
d_mapping = d_16qam; mapping = QAM16;
break; break;
case QAM64_2_3: case QAM64_2_3:
case QAM64_3_4: case QAM64_3_4:
d_mapping = d_64qam; mapping = QAM64;
break; break;
default: default:
@@ -90,8 +85,60 @@ chunks_to_symbols_impl::work(int noutput_items,
} }
for(int i = 0; i < ninput_items[0]; i++) { 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]; 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)};
+5 -7
View File
@@ -18,7 +18,6 @@
#define INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_IMPL_H #define INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_IMPL_H
#include <ieee802-11/chunks_to_symbols.h> #include <ieee802-11/chunks_to_symbols.h>
#include <ieee802-11/constellations.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -34,12 +33,11 @@ public:
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
private: protected:
boost::shared_ptr<gr::digital::constellation> d_mapping; static const gr_complex BPSK[2];
constellation_bpsk::sptr d_bpsk; static const gr_complex QPSK[4];
constellation_qpsk::sptr d_qpsk; static const gr_complex QAM16[16];
constellation_16qam::sptr d_16qam; static const gr_complex QAM64[64];
constellation_64qam::sptr d_64qam;
}; };
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
-235
View File
@@ -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;
}
-71
View File
@@ -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 */
-247
View File
@@ -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));
}
-42
View File
@@ -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 };
+1 -8
View File
@@ -19,7 +19,6 @@
#define INCLUDED_IEEE802_11_EQUALIZER_BASE_H #define INCLUDED_IEEE802_11_EQUALIZER_BASE_H
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include <gnuradio/digital/constellation.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -28,13 +27,7 @@ namespace equalizer {
class base { class base {
public: public:
virtual ~base() {}; 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 void equalize(const gr_complex *in, gr_complex *out, int n) = 0;
virtual double get_snr() = 0;
static const gr_complex POLARITY[127];
protected:
static const gr_complex LONG[64];
}; };
} /* namespace channel_estimation */ } /* namespace channel_estimation */
-77
View File
@@ -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;
}
+63
View File
@@ -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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_EQUALIZER_COMB_H #ifndef INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H
#define INCLUDED_IEEE802_11_EQUALIZER_COMB_H #define INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H
#include "base.h" #include "base.h"
@@ -24,21 +24,16 @@ namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
namespace equalizer { namespace equalizer {
class comb: public base { class linear_comb: public base {
public: 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);
double get_snr();
private: private:
gr_complex d_H[64]; static const gr_complex POLARITY[127];
const double alpha = 0.2;
}; };
} /* namespace channel_estimation */ } /* namespace channel_estimation */
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
#endif /* INCLUDED_IEEE802_11_EQUALIZER_COMB_H */ #endif /* INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H */
+64 -24
View File
@@ -21,44 +21,84 @@
using namespace gr::ieee802_11::equalizer; 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) { if(n == 0) {
std::memcpy(d_H, in, 64 * sizeof(gr_complex)); std::memcpy(carrier, in, 64 * sizeof(gr_complex));
} else if(n == 1) { } else if(n == 1) {
double signal = 0; gr_complex sum =
double noise = 0; (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++) { for(int i = 0; i < 64; i++) {
if((i == 32) || (i < 6) || ( i > 58)) { carrier[i] += in[i];
continue; carrier[i] *= ref[i] * gr_complex(0.5, 0);
}
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 { } 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; int c = 0;
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) { if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
continue; continue;
} else { } else {
symbols[c] = in[i] / d_H[i]; out[c] = in[i] / carrier[i] * exp(gr_complex(0, freq_sum));
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;
c++; c++;
} }
} }
} }
} }
double const gr_complex lms::ref[] = {
lms::get_snr() { 0, 0, 0, 0, 0, 0, 1, 1, -1, -1,
return d_snr; 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
View File
@@ -27,14 +27,11 @@ namespace equalizer {
class lms: public base { class lms: public base {
public: 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: private:
double get_snr(); gr_complex carrier[64];
static const gr_complex ref[64];
static const gr_complex POLARITY[127];
gr_complex d_H[64];
double d_snr;
const double alpha = 0.5;
}; };
} /* namespace channel_estimation */ } /* namespace channel_estimation */
@@ -42,3 +39,4 @@ private:
} /* namespace gr */ } /* namespace gr */
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LMS_H */ #endif /* INCLUDED_IEEE802_11_EQUALIZER_LMS_H */
-61
View File
@@ -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;
}
-42
View File
@@ -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 */
-95
View File
@@ -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;
}
-45
View File
@@ -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 */
-352
View File
@@ -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 */
-88
View File
@@ -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 */
+332
View File
@@ -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));
}
+222
View File
@@ -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};
+120
View File
@@ -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));
}
+39 -20
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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/io_signature.h>
#include <gnuradio/block_detail.h> #include <gnuradio/block_detail.h>
@@ -34,12 +34,12 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
class mac_impl : public mac { class ofdm_mac_impl : public ofdm_mac {
public: public:
mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) : ofdm_mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) :
block("mac", block("ofdm_mac",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_seq_nr(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_out(pmt::mp("app out"));
message_port_register_in(pmt::mp("app in")); 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")); 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(src_mac)) throw std::invalid_argument("wrong mac address size");
if(!check_mac(dst_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) { void phy_in (pmt::pmt_t msg) {
// this must be a pair // 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"); throw std::runtime_error("PMT must be blob");
}
// strip MAC header // strip MAC header
// TODO: check for frame type to determine header size // TODO: check for frame type to determine header size
@@ -84,25 +83,34 @@ void app_in (pmt::pmt_t msg) {
size_t msg_len; size_t msg_len;
const char *msdu; 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); str = pmt::symbol_to_string(msg);
msg_len = str.length(); msg_len = str.length();
msdu = str.data(); msdu = str.data();
} else if(pmt::is_pair(msg)) { } else if(pmt::is_pair(msg)) {
dict = pmt::car(msg);
msg_len = pmt::blob_length(pmt::cdr(msg)); msg_len = pmt::blob_length(pmt::cdr(msg));
msdu = reinterpret_cast<const char *>(pmt::blob_data(pmt::cdr(msg))); msdu = reinterpret_cast<const char *>(pmt::blob_data(pmt::cdr(msg)));
} else { } else {
throw std::invalid_argument("MAC expects PDUs or strings"); throw std::invalid_argument("OFDM MAC expects PDUs or strings");
return; return;
} }
if(msg_len > MAX_PAYLOAD_SIZE) { if(msg_len > 1500) {
throw std::invalid_argument("Frame too large (> 1500)"); throw std::invalid_argument("Frame too large (> 1500)");
} }
@@ -110,10 +118,21 @@ void app_in (pmt::pmt_t msg) {
int psdu_length; int psdu_length;
generate_mac_data_frame(msdu, msg_len, &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); 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 // blob
pmt::pmt_t mac = pmt::make_blob(d_psdu, psdu_length); 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_src_mac[6];
uint8_t d_dst_mac[6]; uint8_t d_dst_mac[6];
uint8_t d_bss_mac[6]; uint8_t d_bss_mac[6];
uint8_t d_psdu[MAX_PSDU_SIZE]; uint8_t d_psdu[1528];
}; };
mac::sptr ofdm_mac::sptr
mac::make(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) { 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 mac_impl(src_mac, dst_mac, bss_mac)); return gnuradio::get_initial_sptr(new ofdm_mac_impl(src_mac, dst_mac, bss_mac));
} }
+49 -42
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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 "utils.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
class mapper_impl : public mapper { class ofdm_mapper_impl : public ofdm_mapper {
public: public:
static const int DATA_CARRIERS = 48; static const int DATA_CARRIERS = 48;
mapper_impl(Encoding e, bool debug) : ofdm_mapper_impl(Encoding e, bool debug) :
block ("mapper", block ("ofdm_mapper",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 1, sizeof(char))), gr::io_signature::make(1, 1, sizeof(char))),
d_symbols_offset(0), d_symbols_offset(0),
d_symbols(NULL), d_symbols(NULL),
d_debug(debug), d_debug(debug),
d_scrambler(1),
d_ofdm(e) { d_ofdm(e) {
message_port_register_in(pmt::mp("in")); message_port_register_in(pmt::mp("in"));
set_encoding(e); set_encoding(e);
} }
~mapper_impl() { ~ofdm_mapper_impl() {
free(d_symbols); free(d_symbols);
} }
void print_message(const char *msg, size_t len) { 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; << "===========================" << std::endl;
for(int i = 0; i < len; i++) { 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 ) { gr_vector_void_star& output_items ) {
unsigned char *out = (unsigned char*)output_items[0]; 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; " length: " << d_symbols_len << std::endl;
while(!d_symbols_offset) { 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()) { if(pmt::is_eof_object(msg)) {
return 0; dout << "MAPPER: exiting" << std::endl;
} return -1;
}
if(pmt::is_pair(msg)) { 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); gr::thread::scoped_lock lock(d_mutex);
int psdu_length = pmt::blob_length(pmt::cdr(msg)); int psdu_length = pmt::blob_length(pmt::cdr(msg));
const char *psdu = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg))); const char *psdu = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
// ############ INSERT MAC STUFF // ############ INSERT MAC STUFF
frame_param frame(d_ofdm, psdu_length); tx_param tx(d_ofdm, psdu_length);
if(frame.n_sym > MAX_SYM) { if(tx.n_sym > MAX_SYM) {
std::cout << "packet too large, maximum number of symbols is " << MAX_SYM << std::endl; std::cout << "packet too large, maximum number of symbols is " << MAX_SYM << std::endl;
return 0; return 0;
} }
//alloc memory for modulation steps //alloc memory for modulation steps
char *data_bits = (char*)calloc(frame.n_data_bits, sizeof(char)); char *data_bits = (char*)calloc(tx.n_data, sizeof(char));
char *scrambled_data = (char*)calloc(frame.n_data_bits, sizeof(char)); char *scrambled_data = (char*)calloc(tx.n_data, sizeof(char));
char *encoded_data = (char*)calloc(frame.n_data_bits * 2, sizeof(char)); char *encoded_data = (char*)calloc(tx.n_data * 2, sizeof(char));
char *punctured_data = (char*)calloc(frame.n_encoded_bits, sizeof(char)); char *punctured_data = (char*)calloc(tx.n_encoded_bits, sizeof(char));
char *interleaved_data = (char*)calloc(frame.n_encoded_bits, sizeof(char)); char *interleaved_data = (char*)calloc(tx.n_encoded_bits, sizeof(char));
char *symbols = (char*)calloc((frame.n_encoded_bits / d_ofdm.n_bpsc), 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 the OFDM data field, adding service field and pad bits
generate_bits(psdu, data_bits, frame); generate_bits(psdu, data_bits, tx);
//print_hex_array(data_bits, tx.n_data);
// scrambling
scramble(data_bits, scrambled_data, frame, d_scrambler++);
if(d_scrambler > 127) {
d_scrambler = 1;
}
// first step, scrambling
scramble(data_bits, scrambled_data, tx, 23);
//print_hex_array(scrambled_data, tx.n_data);
// reset tail bits // reset tail bits
reset_tail_bits(scrambled_data, frame); reset_tail_bits(scrambled_data, tx);
//print_hex_array(scrambled_data, tx.n_data);
// encoding // 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
puncturing(encoded_data, punctured_data, frame, d_ofdm); puncturing(encoded_data, punctured_data, tx, d_ofdm);
//std::cout << "punctured" << std::endl; //std::cout << "punctured" << std::endl;
// interleaving // interleaving
interleave(punctured_data, interleaved_data, frame, d_ofdm); interleave(punctured_data, interleaved_data, tx, d_ofdm);
//std::cout << "interleaved" << std::endl; //std::cout << "interleaved" << std::endl;
// one byte per symbol // one byte per symbol
split_symbols(interleaved_data, symbols, frame, d_ofdm); 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); d_symbols = (char*)calloc(d_symbols_len, 1);
std::memcpy(d_symbols, symbols, d_symbols_len); 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"), add_item_tag(0, nitems_written(0), pmt::mp("encoding"),
encoding, srcid); 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(data_bits);
free(scrambled_data); free(scrambled_data);
@@ -165,14 +173,13 @@ int general_work(int noutput, gr_vector_int& ninput_items,
void set_encoding(Encoding encoding) { 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); gr::thread::scoped_lock lock(d_mutex);
d_ofdm = ofdm_param(encoding); d_ofdm = ofdm_param(encoding);
} }
private: private:
uint8_t d_scrambler;
bool d_debug; bool d_debug;
char* d_symbols; char* d_symbols;
int d_symbols_offset; int d_symbols_offset;
@@ -181,7 +188,7 @@ private:
gr::thread::mutex d_mutex; gr::thread::mutex d_mutex;
}; };
mapper::sptr ofdm_mapper::sptr
mapper::make(Encoding mcs, bool debug) { ofdm_mapper::make(Encoding mcs, bool debug) {
return gnuradio::get_initial_sptr(new mapper_impl(mcs, debug)); return gnuradio::get_initial_sptr(new ofdm_mapper_impl(mcs, debug));
} }
+10 -10
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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 "utils.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@@ -23,24 +23,24 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
class parse_mac_impl : public parse_mac { class ofdm_parse_mac_impl : public ofdm_parse_mac {
public: public:
parse_mac_impl(bool log, bool debug) : ofdm_parse_mac_impl(bool log, bool debug) :
block("parse_mac", block("ofdm_parse_mac",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_log(log), d_last_seq_no(-1), d_log(log), d_last_seq_no(-1),
d_debug(debug) { d_debug(debug) {
message_port_register_in(pmt::mp("in")); 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")); message_port_register_out(pmt::mp("fer"));
} }
~parse_mac_impl() { ~ofdm_parse_mac_impl() {
} }
@@ -358,9 +358,9 @@ private:
int d_last_seq_no; int d_last_seq_no;
}; };
parse_mac::sptr ofdm_parse_mac::sptr
parse_mac::make(bool log, bool debug) { ofdm_parse_mac::make(bool log, bool debug) {
return gnuradio::get_initial_sptr(new parse_mac_impl(log, debug)); return gnuradio::get_initial_sptr(new ofdm_parse_mac_impl(log, debug));
} }
+35 -36
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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 "utils.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <gnuradio/filter/fir_filter.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)); 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: 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::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_fir(gr::filter::kernel::fir_filter_ccc(1, LONG)), 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); d_correlation = gr::fft::malloc_complex(8192);
} }
~sync_long_impl(){ ~ofdm_sync_long_impl(){
gr::fft::free(d_correlation); gr::fft::free(d_correlation);
} }
@@ -82,7 +82,6 @@ int general_work (int noutput, gr_vector_int& ninput_items,
if(d_state == COPY) { if(d_state == COPY) {
d_state = RESET; 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) { if(d_offset == SYNC_LENGTH) {
search_frame_start(); search_frame_start();
mylog(boost::format("LONG: frame start at %1%") % d_frame_start);
d_offset = 0; d_offset = 0;
d_count = 0; d_count = 0;
d_state = COPY; d_state = COPY;
@@ -122,9 +120,9 @@ int general_work (int noutput, gr_vector_int& ninput_items,
if(!rel) { if(!rel) {
add_item_tag(0, nitems_written(0), add_item_tag(0, nitems_written(0),
pmt::string_to_symbol("wifi_start"), pmt::string_to_symbol("ofdm_start"),
pmt::from_double(d_freq_offset_short - d_freq_offset), pmt::PMT_T,
pmt::string_to_symbol(name())); pmt::string_to_symbol(name()));
} }
if(rel >= 0 && (rel < 128 || ((rel - 128) % 80) > 15)) { 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])); int diff = abs(get<1>(vec[i]) - get<1>(vec[k]));
if(diff == 64) { 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; d_freq_offset = arg(first * conj(second)) / 64;
//std::cout << "frequency offset " << d_freq_offset << std::endl;
// nice match found, return immediately // nice match found, return immediately
return; return;
// TODO: check if these offsets make sense
} else if(diff == 63) { } else if(diff == 63) {
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 63 - 128 - 1;
d_freq_offset = arg(first * conj(second)) / 63; d_freq_offset = arg(first * conj(second)) / 64;
} else if(diff == 65) { } else if(diff == 65) {
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)) / 65; d_freq_offset = arg(first * conj(second)) / 64;
} }
} }
} }
@@ -224,7 +224,6 @@ private:
int d_offset; int d_offset;
int d_frame_start; int d_frame_start;
float d_freq_offset; float d_freq_offset;
double d_freq_offset_short;
gr_complex *d_correlation; gr_complex *d_correlation;
list<pair<gr_complex, int> > d_cor; list<pair<gr_complex, int> > d_cor;
@@ -238,28 +237,28 @@ private:
static const std::vector<gr_complex> LONG; static const std::vector<gr_complex> LONG;
}; };
sync_long::sptr ofdm_sync_long::sptr
sync_long::make(unsigned int sync_length, bool log, bool debug) { ofdm_sync_long::make(unsigned int sync_length, bool log, bool debug) {
return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, 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( 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.5309, -0.7784), gr_complex(-1.0218, -0.4897), gr_complex(-0.3401, -0.9423), gr_complex( 0.8657, -0.2298), 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.4734, 0.0362), gr_complex( 0.0088, -1.0207), gr_complex(-1.2142, -0.4205), gr_complex( 0.2172, -0.5195), 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.5207, -0.1326), gr_complex(-0.1995, 1.4259), gr_complex( 1.0583, -0.0363), gr_complex( 0.5547, -0.5547), 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.3277, 0.8728), gr_complex(-0.5077, 0.3488), gr_complex(-1.1650, 0.5789), gr_complex( 0.7297, 0.8197), 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.6173, 0.1253), gr_complex(-0.5353, 0.7214), gr_complex(-0.5011, -0.1935), gr_complex(-0.3110, -1.3392), 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(-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.3110, -1.3392), gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), gr_complex( 0.6663, -0.6571),
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.0249, 0.4773), gr_complex(-0.8155, 1.0218), gr_complex( 0.8140, 0.9396), gr_complex( 0.1090, 0.8662),
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(-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.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470), gr_complex(-0.3110, 1.3392), 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.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253), gr_complex( 0.7297, -0.8197), 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(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728), gr_complex( 0.5547, 0.5547), 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( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326), gr_complex( 0.2172, 0.5195), 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(-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.2172, 0.5195), gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362),
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.8657, 0.2298), gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784),
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( 0.1874, -0.2475), gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679)
}; };
+14 -14
View File
@@ -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 * 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 * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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 <gnuradio/io_signature.h>
#include "utils.h" #include "utils.h"
@@ -25,11 +25,11 @@ using namespace gr::ieee802_11;
static const int MIN_GAP = 480; static const int MIN_GAP = 480;
static const int MAX_SAMPLES = 540 * 80; static const int MAX_SAMPLES = 540 * 80;
class sync_short_impl : public sync_short { class ofdm_sync_short_impl : public ofdm_sync_short {
public: public:
sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) : ofdm_sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) :
block("sync_short", block("ofdm_sync_short",
gr::io_signature::make3(3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)), gr::io_signature::make3(3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)),
gr::io_signature::make(1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_log(log), d_log(log),
@@ -73,7 +73,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
d_copied = 0; d_copied = 0;
d_freq_offset = arg(in_abs[i]) / 16; d_freq_offset = arg(in_abs[i]) / 16;
d_plateau = 0; 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; dout << "SHORT Frame!" << std::endl;
break; break;
} }
@@ -99,7 +99,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
d_copied = 0; d_copied = 0;
d_plateau = 0; d_plateau = 0;
d_freq_offset = arg(in_abs[o]) / 16; 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; dout << "SHORT Frame!" << std::endl;
break; break;
} }
@@ -128,11 +128,11 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
return 0; return 0;
} }
void insert_tag(uint64_t item, double freq_offset, uint64_t input_item) { void insert_tag(uint64_t item) {
mylog(boost::format("frame start at in: %2% out: %1%") % item % input_item); mylog(boost::format("frame start at %1%") % item);
const pmt::pmt_t key = pmt::string_to_symbol("wifi_start"); const pmt::pmt_t key = pmt::string_to_symbol("ofdm_start");
const pmt::pmt_t value = pmt::from_double(freq_offset); const pmt::pmt_t value = pmt::PMT_T;
const pmt::pmt_t srcid = pmt::string_to_symbol(name()); const pmt::pmt_t srcid = pmt::string_to_symbol(name());
add_item_tag(0, item, key, value, srcid); add_item_tag(0, item, key, value, srcid);
} }
@@ -148,7 +148,7 @@ private:
const unsigned int MIN_PLATEAU; const unsigned int MIN_PLATEAU;
}; };
sync_short::sptr ofdm_sync_short::sptr
sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) { ofdm_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)); return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold, min_plateau, log, debug));
} }
+105 -22
View File
@@ -20,6 +20,62 @@
#include <cstring> #include <cstring>
#include <math.h> #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) { ofdm_param::ofdm_param(Encoding e) {
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; psdu_size = psdu_length;
// number of symbols (17-11) // number of symbols (17-11)
n_sym = (int) ceil((16 + 8 * psdu_size + 6) / (double) ofdm.n_dbps); 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) // 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; n_encoded_bits = n_sym * ofdm.n_cbps;
} }
void void
frame_param::print() { tx_param::print() {
std::cout << "FRAME Parameters:" << std::endl; std::cout << "TX Parameters:" << std::endl;
std::cout << "psdu_size: " << psdu_size << std::endl; std::cout << "psdu_size: " << psdu_size << std::endl;
std::cout << "n_sym: " << n_sym << 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_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 state = initial_state;
int feedback; 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)); feedback = (!!(state & 64)) ^ (!!(state & 8));
out[i] = feedback ^ in[i]; 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) { void reset_tail_bits(char *scrambled_data, tx_param &tx) {
memset(scrambled_data + frame.n_data_bits - frame.n_pad - 6, 0, 6 * sizeof(char)); 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; 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); assert(in[i] == 0 || in[i] == 1);
state = ((state << 1) & 0x7e) | in[i]; state = ((state << 1) & 0x7e) | in[i];
out[i * 2] = ones(state & 0155) % 2; 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; 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) { switch(ofdm.encoding) {
case BPSK_1_2: case BPSK_1_2:
case QPSK_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 n_cbps = ofdm.n_cbps;
int first[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)); 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++) { for(int k = 0; k < n_cbps; k++) {
if(reverse) { if(reverse) {
out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k]; 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++) { for (int i = 0; i < symbols; i++) {
out[i] = 0; out[i] = 0;
for(int k = 0; k < ofdm.n_bpsc; k++) { for(int k = 0; k < ofdm.n_bpsc; k++) {
assert(*in == 1 || *in == 0); assert(*in == 1 || *in == 0);
out[i] |= (*in << k); out[i] |= (*in << (ofdm.n_bpsc - k - 1));
in++; 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) // first 16 bits are zero (SERVICE/DATA field)
memset(data_bits, 0, 16); memset(data_bits, 0, 16);
data_bits += 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++) { for(int b = 0; b < 8; b++) {
data_bits[i * 8 + b] = !!(psdu[i] & (1 << b)); data_bits[i * 8 + b] = !!(psdu[i] & (1 << b));
} }
+28 -22
View File
@@ -14,28 +14,32 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_UTILS_H #ifndef INCLUDED_IEEE802_11_OFDM_UTILS_H
#define INCLUDED_IEEE802_11_UTILS_H #define INCLUDED_IEEE802_11_OFDM_UTILS_H
#include <ieee802-11/api.h> #include <ieee802-11/api.h>
#include <ieee802-11/mapper.h> #include <ieee802-11/ofdm_mapper.h>
#include <gnuradio/config.h> #include <gnuradio/config.h>
#include <cinttypes> #include <cinttypes>
#include <iostream> #include <iostream>
#define MAX_PAYLOAD_SIZE 1500 const int MAX_SYM = 520; // enough for 1500 byte BPSK 1/2
#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC const int MAX_BITS = 1550 * 8 * 2;
#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1)
#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288)
#define dout d_debug && std::cout #define dout d_debug && std::cout
#if defined(HAVE_LOG4CPP) && defined(ENABLE_GR_LOG) && defined(GR_IEEE80211_LOG4CPP) #if defined(HAVE_LOG4CPP) && defined(ENABLE_GR_LOG)
#define mylog(msg) do { if(d_log) { GR_LOG_INFO(d_logger, msg); }} while(0); #define mylog(msg) do { if(d_log) { *d_logger << log4cpp::Priority::INFO << msg << log4cpp::eol; }} while(0);
#else #else
#define mylog(msg) do { d_log && std::cout << msg << std::endl; } while(0); #define mylog(msg) do { d_log && std::cout << msg << std::endl; } while(0);
#endif #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 { struct mac_header {
//protocol version, type, subtype, to_ds, from_ds, ... //protocol version, type, subtype, to_ds, from_ds, ...
uint16_t frame_control; uint16_t frame_control;
@@ -47,7 +51,7 @@ struct mac_header {
}__attribute__((packed)); }__attribute__((packed));
/** /**
* WIFI parameters * OFDM parameters
*/ */
class ofdm_param { class ofdm_param {
public: public:
@@ -70,18 +74,18 @@ public:
/** /**
* packet specific parameters * packet specific parameters
*/ */
class frame_param { class tx_param {
public: public:
frame_param(ofdm_param &ofdm, int psdu_length); tx_param(ofdm_param &ofdm, int psdu_length);
// PSDU size in bytes // PSDU size in bytes
int psdu_size; int psdu_size;
// number of OFDM symbols (17-11) // number of OFDM symbols (17-11)
int n_sym; 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) // number of padding bits in the DATA field (17-13)
int n_pad; int n_pad;
int n_encoded_bits; int n_encoded_bits;
// number of data bits, including service and padding (17-12)
int n_data_bits;
void print(); 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 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 */
-419
View File
@@ -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};
-89
View File
@@ -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 */
+106
View File
@@ -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 * 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 * 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/>. * 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 "utils.h"
#include <gnuradio/digital/lfsr.h> #include <gnuradio/digital/lfsr.h>
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
signal_field::sptr wifi_signal_field::sptr
signal_field::make() { wifi_signal_field::make() {
return signal_field::sptr(new signal_field_impl()); 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); 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 //data bits of the signal header
char *signal_header = (char *) malloc(sizeof(char) * 24); 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 //interleaving
char *interleaved_signal_header = (char *) malloc(sizeof(char) * 48); 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 // first 4 bits represent the modulation and coding scheme
signal_header[ 0] = get_bit(ofdm.rate_field, 3); 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); 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 (scrambling is not needed)
convolutional_encoding(signal_header, encoded_signal_header, signal_param); convolutional_encoding(signal_header, encoded_signal_header, signal_tx);
// interleaving // 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(signal_header);
free(encoded_signal_header); free(encoded_signal_header);
free(interleaved_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; 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); 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; return true;
} }
bool signal_field_impl::header_parser( bool wifi_signal_field_impl::header_parser(
const unsigned char *in, std::vector<tag_t> &tags) { const unsigned char *in, std::vector<tag_t> &tags) {
throw std::runtime_error("not implemented yet"); throw std::runtime_error("not implemented yet");
@@ -15,20 +15,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H #ifndef INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H
#define INCLUDED_IEEE802_11_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" #include "utils.h"
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class signal_field_impl : public signal_field class wifi_signal_field_impl : public wifi_signal_field
{ {
public: public:
signal_field_impl(); wifi_signal_field_impl();
~signal_field_impl(); ~wifi_signal_field_impl();
bool header_formatter(long packet_len, unsigned char *out, bool header_formatter(long packet_len, unsigned char *out,
const std::vector<tag_t> &tags); const std::vector<tag_t> &tags);
@@ -37,11 +37,11 @@ public:
std::vector<tag_t> &tags); std::vector<tag_t> &tags);
private: private:
int get_bit(int b, int i); 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 ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H */ #endif /* INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H */
+1
View File
@@ -39,3 +39,4 @@ include(GrTest)
set(GR_TEST_TARGET_DEPS gnuradio-ieee802-11) set(GR_TEST_TARGET_DEPS gnuradio-ieee802-11)
set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
#GR_ADD_TEST(qa_howto ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_howto.py)
-2
View File
@@ -1,2 +0,0 @@
results/
sim.py
-30
View File
@@ -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)
-19
View File
@@ -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.
-22
View File
@@ -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')
-957
View File
@@ -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>
-2
View File
@@ -1,2 +0,0 @@
results/
sim.py
-30
View File
@@ -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)
-19
View File
@@ -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.
-14
View File
@@ -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')
-993
View File
@@ -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>
-1
View File
@@ -21,7 +21,6 @@
find_package(SWIG) find_package(SWIG)
find_package(PythonLibs 2) find_package(PythonLibs 2)
if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND) if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND)
message(FATAL_ERROR "Python or Swig not found (or version not supported).")
return() return()
endif() endif()
include(GrSwig) include(GrSwig)
+34 -57
View File
@@ -22,80 +22,57 @@
%include "ieee802_11_swig_doc.i" %include "ieee802_11_swig_doc.i"
%{ %{
#include "gnuradio/digital/packet_header_default.h"
#include "ieee802-11/chunks_to_symbols.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/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_cc.h"
#include "ieee802-11/moving_average_ff.h" #include "ieee802-11/moving_average_ff.h"
#include "ieee802-11/parse_mac.h" #include "ieee802-11/ofdm_decode_mac.h"
#include "ieee802-11/signal_field.h" #include "ieee802-11/ofdm_decode_signal.h"
#include "ieee802-11/sync_long.h" #include "ieee802-11/ofdm_equalize_symbols.h"
#include "ieee802-11/sync_short.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" %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/chunks_to_symbols.h"
%include "ieee802-11/constellations.h"
%include "ieee802-11/decode_mac.h"
%include "ieee802-11/ether_encap.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_cc.h"
%include "ieee802-11/moving_average_ff.h" %include "ieee802-11/moving_average_ff.h"
%include "ieee802-11/parse_mac.h" %include "ieee802-11/ofdm_decode_mac.h"
%include "ieee802-11/signal_field.h" %include "ieee802-11/ofdm_decode_signal.h"
%include "ieee802-11/sync_long.h" %include "ieee802-11/ofdm_equalize_symbols.h"
%include "ieee802-11/sync_short.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, 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, 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_cc);
GR_SWIG_BLOCK_MAGIC2(ieee802_11, moving_average_ff); GR_SWIG_BLOCK_MAGIC2(ieee802_11, moving_average_ff);
GR_SWIG_BLOCK_MAGIC2(ieee802_11, parse_mac); GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_mac);
GR_SWIG_BLOCK_MAGIC2(ieee802_11, sync_long); GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_signal);
GR_SWIG_BLOCK_MAGIC2(ieee802_11, sync_short); 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 %{ %pythoncode %{
signal_field_sptr.__repr__ = lambda self: "<signal_field>" wifi_signal_field_sptr.__repr__ = lambda self: "<wifi_signal_field>"
signal_field = signal_field.make; wifi_signal_field = wifi_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;
%} %}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

+43
View File
@@ -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;
-92
View File
@@ -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