Open-source project
bastibl/gr-ieee802-11 avatar
bastibl/gr-ieee802-11

gr-ieee802-11 puts an 802.11 transceiver into GNU Radio

IEEE 802.11 a/g/p Transceiver

916 stars328 forksC++GPL-3.0

At a glance

What is it?
gr-ieee802-11 is an out of tree GNU Radio module that implements an IEEE 802.11 a/g/p transceiver for Ettus N210 and B210 radios and for simulation. It is a research tool with real air interface limits that the documentation is honest about, including no CSMA/CA, no working RTS/CTS and no ability to answer an acknowledgement in time.
Who is it for?
Adopt gr-ieee802-11 if you are doing wireless research that needs to look inside 802.11 frames and you are happy to work at the frame level rather than at the MAC level. Do not adopt it as a full MAC implementation, because the README states that there is no CSMA/CA mechanism, that RTS/CTS does not work, that the transceiver cannot respond to acknowledgements in time, and that joining an ad hoc network requires kernel changes.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 173 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • bastibl/gr-ieee802-11916 ★ · +1
Star history
Repository2026-10-212026-11-07
bastibl/gr-ieee802-11915916

1 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

An SDR transceiver for the wireless standard itself

The README opens in the least ceremonial way possible, with a greeting, and then says what the thing is. This is 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, and the code can also be used in simulations. Three things follow from that description. First, this is a full physical and MAC layer implementation of a wireless standard, in the sense that it talks to real consumer WiFi hardware and not just to another copy of itself. Second, it runs on general purpose SDR hardware, so the radio is a USRP rather than a dedicated chipset. Third, the same flow graphs work without hardware at all, which is what makes it a research tool rather than a driver. The audience is wireless researchers and students who need to look inside the 802.11 frame, the OFDM modulation, or the MAC handshake, and who want to do that with the same tooling they use for everything else in GNU Radio. It is part of a wider effort. The homepage points at the WIME project, and the repository has a MANIFEST.md and a MANIFEST.yml alongside the usual CMake machinery, which is the pattern used by the GNU Radio manifest system for reproducible builds of out of tree modules.

Installation is a CMake build, and gr-foo comes first

The dependency that catches people out is not a library but another GNU Radio module. The README notes that the author has some non project specific GNU Radio blocks in a separate gr-foo repository that are needed, with the Wireshark connector given as an example, and they are installed with the typical command sequence.

sh
git clone https://github.com/bastibl/gr-foo
cd gr-foo
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

The main module then installs the same way.

sh
git clone https://github.com/bastibl/gr-ieee802-11
cd gr-ieee802-11
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

The last line matters and is easy to skip. Without the ldconfig refresh the shared libraries the module installs are not found at run time, and the failure appears as a missing block rather than as a library problem. GNU Radio itself can be installed in several ways, and the README lists them: pybombs, pre-compiled binaries, or from source. Whichever route you take, the version pairing matters, because of the branch scheme described in the development section. The default branch here is maint-3.10, and the README explains the convention. Like GNU Radio, this module uses maint branches for development, and those branches are supposed to be used with the corresponding GNU Radio branches, so maint-3.7 is compatible with GNU Radio 3.7 and maint-3.8 with GNU Radio 3.8. You pick the branch to match the GNU Radio you have installed, and mixing them is the first thing to check when a flow graph misbehaves.

Shared memory limits and a hierarchical PHY block you must build yourself

Two setup steps in the README are not optional, and both have a technical reason. The first is shared memory. Since the transmitter uses the Tagged Stream blocks it has to store a complete frame in the buffer before processing it, and the default maximum shared memory might not be enough on most Linux systems.

bash
sudo sysctl -w kernel.shmmax=2147483648

A frame has to be buffered whole before it is processed, so the buffer size is a direct function of the largest frame you intend to send. The default on a typical Linux system is too small, and the symptom is a transmitter that stalls. The second is the OFDM PHY. The physical layer is encapsulated in a hierarchical block to allow for a clearer transceiver structure in GNU Radio Companion, and this hierarchical block is not included in the installation process. You have to open the example flow graph with GNU Radio Companion and build it, which installs the block into the GRC block directory.

code
/examples/wifi_phy_hier.grc

That last step is a build step inside a GUI, which is unusual and worth flagging. If you are scripting a CI environment or a reproducible setup, this block has to be generated ahead of time rather than by hand. The README also asks you to run volk_profile, which benchmarks different SIMD implementations on your machine and writes a configuration file with the fastest version of every function. The README says this can speed up the computation considerably and is required in order to deal with the high rate of incoming samples. It also asks you to calibrate a WBX, SBX or CBX daughterboard to minimise IQ imbalance and TX DC offsets.

The loopback flow graph is the acceptance test

Before you touch hardware, the README gives you a way to check that everything is wired correctly. The wifi_loopback.grc flow graph does not need any hardware and allows you to ensure that the software part is installed correctly. Open the flow graph and run it, and if everything works as intended you should see some decoded packets on the console. That is a better acceptance test than it sounds. The over the air path involves a USRP, a host PC, an SDR sample rate that has to keep up, and a live 802.11 peer, so when something fails there are many suspects. The loopback removes all of them but the software, which means a failure at that stage is unambiguously an installation problem. The simulation section points at the same graph and explains how to explore it further. Because 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. The examples directory in the repository contains the flow graphs the README refers to, including wifi_loopback.grc, wifi_rx.grc, wifi_tx.grc, wifi_transceiver.grc and the wifi_phy_hier.grc hierarchical block, so the pieces are all present in the tree rather than only in the documentation.

Over the air: no CSMA/CA, no RTS/CTS and no timely acknowledgements

This is the section that decides whether the project is useful for your work, and it is unusually candid. The transceiver is connected to a TAP device, a virtual Ethernet interface, so there is no WiFi signalling like association requests and the transceiver cannot join an ad hoc network. You have to make small changes to the kernel to convince a WiFi card to send to this host. The transceiver cannot respond to ACKs in time, and the README calls this an architectural limitation of USRP plus GNU Radio, since Ethernet and the computations on a normal CPU introduce latency. The workaround is to set the number of ACK retries to zero and handle retransmission at a higher layer, which means TCP. RTS/CTS does not work for the same reason, and the recommendation is simply to disable the mechanism. There is no CSMA/CA mechanism at present, and the README notes that this can be implemented on the FPGA. Read together, those four points describe a transceiver that transmits and receives 802.11 frames reliably but does not behave like a well mannered station. It will not contend for the channel, it will not reserve it, and it will not complete a handshake that depends on a fast acknowledgement. That is exactly what a frame level research tool wants, and exactly what a testbed for a full MAC implementation does not. The unidirectional test is the starting point. The README recommends trying wifi_rx.grc and wifi_tx.grc first, opening them in GNU Radio Companion and executing them, and if it does not work out of the box, trying to play around with the gain.

The block-not-found error almost always means an install prefix mismatch

The troubleshooting section solves one specific error that would otherwise cost hours. If GRC complains that it cannot find some blocks, other than performance counters and hierarchical blocks, such as ieee802_11_ofdm_mac or foo_packet_pad, the most likely cause is that you used a different CMAKE_INSTALL_PREFIX for the module than for GNU Radio, so the blocks of the module ended up in a different directory and GRC cannot find them. The fix is to tell GRC where the blocks are, by creating or adding to the config file in your home directory.

code
[grc]
global_blocks_path = /opt/local/share/gnuradio/grc/blocks
local_blocks_path = /Users/basti/usr/share/gnuradio/grc/blocks

The example paths are the author's own, so substitute the directories that match your installation. The rest of the troubleshooting advice is a checklist, and it is worth running through it in order. Check the compile and installation logs, which might contain interesting information. Did you calibrate your daughterboard? Did you run volk_profile? Did you try different gain settings? Did you close the case of the devices? Did you try real-time priority? Did you compile GNU Radio and gr-ieee802-11 in release mode? The last warning about the performance counter blocks is benign. If you see warnings that blocks_ctrlport_monitor_performance is missing, it means GNU Radio was installed without the control port or the performance counters, and those blocks are not required, so you can delete them.

GPL version 3, a maintenance branch, and a quiet release history

The licence field on the repository says GPL-3.0, with a LICENSE file at the root of the tree. That is the one hard constraint for anyone planning to use this code in a product. The GPL is copyleft, so linking this module into a closed source application carries obligations that a permissive licence would not. For research, teaching and experimentation it is the usual choice for a GNU Radio out of tree module, and this project follows that convention. The repository has no GitHub releases, which is normal for a GNU Radio out of tree module. The versioning lives in the branch names, with the default branch here being maint-3.10 and the rule that each maint branch tracks the matching GNU Radio release. A user pins a branch, not a tag. On activity, the repository is not archived and the last push was on 2026-05-19, which is a reasonable place for a module that follows GNU Radio's own release cycle rather than shipping on its own schedule. The top level layout shows the anatomy of an out of tree module. There is CMakeLists.txt at the root, then the code under include/, lib/, apps/, python/ and utils/, the GRC block definitions under grc/, the flow graphs under examples/ and simulations/, and the build support under cmake/ and docs/. The.conda/ directory points at a conda based build path, and the MANIFEST.md and MANIFEST.yml files are what let the module be reproduced from a manifest rather than cloned by hand.

Editorial conclusion

Adopt gr-ieee802-11 if you are doing wireless research that needs to look inside 802.11 frames and you are happy to work at the frame level rather than at the MAC level. Do not adopt it as a full MAC implementation, because the README states that there is no CSMA/CA mechanism, that RTS/CTS does not work, that the transceiver cannot respond to acknowledgements in time, and that joining an ad hoc network requires kernel changes. Before you start, check that your GNU Radio version matches the maint branch you clone, run volk_profile, and raise kernel.shmmax if the transmitter stalls on a large frame.

Frequently asked questions

What is gr-ieee802-11 and what hardware does it need?

It is an IEEE 802.11 a/g/p transceiver for GNU Radio, fitted for operation with Ettus N210s and B210s. Interoperability was tested with many off-the-shelf WiFi cards and IEEE 802.11p prototypes, and the code can also be used in simulations without hardware.

How do I install gr-ieee802-11?

Clone the repository, create a build directory, run cmake .. , make, sudo make install and sudo ldconfig. The README notes that some non project specific blocks are needed from the separate gr-foo repository, which is installed with the same command sequence first.

Why do I need to increase kernel.shmmax?

The transmitter uses the Tagged Stream blocks and has to store a complete frame in the buffer before processing it, and the README says the default maximum shared memory might not be enough on most Linux systems. It can be raised with sudo sysctl -w kernel.shmmax=2147483648.

What should I check first after installing gr-ieee802-11?

Run the wifi_loopback.grc flow graph. It needs no hardware and lets you confirm the software side is installed correctly, and if it works you should see decoded packets on the console.

Why does GNU Radio Companion report that a block key is not found?

The README says the most likely cause is a different CMAKE_INSTALL_PREFIX for the module than for GNU Radio, so the blocks ended up in another directory. You point GRC at the right place by setting global_blocks_path and local_blocks_path in the config file in your home directory.

Official sources

  1. bastibl/gr-ieee802-11 on GitHub
  2. Issues
  3. License: GPL-3.0
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bastibl-gr-ieee802-11.svg)](https://hysenlabs.com/projects/bastibl-gr-ieee802-11)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/bastibl-gr-ieee802-11.svg)](https://hysenlabs.com/projects/bastibl-gr-ieee802-11)

Was this useful?