# BTLE puts a BLE sniffer and a raw packet transmitter on a software radio

> JiaoXianjun/BTLE is a Bluetooth Low Energy suite built on software defined radio, with a receiver that parses standard advertising and data packets and follows channel hopping, and a transmitter that can emit raw GFSK bit patterns. It is aimed at protocol researchers and hardware developers who need to see or craft the air interface itself.

**JiaoXianjun/BTLE** — Bluetooth Low Energy (BLE) packet sniffer and transmitter for both standard and non standard (raw bit) based on Software Defined Radio (SDR).

- Repository: https://github.com/JiaoXianjun/BTLE
- Website: http://sdr-x.github.io/
- Stars: 949 · Forks: 177
- Language: Jupyter Notebook
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/jiaoxianjun-btle

## The BLE stack is software, down to the baseband

BTLE is a Bluetooth Low Energy suite that runs on a software defined radio rather than on a dedicated Bluetooth chip. The README is explicit about the design: the PHY and upper layer are implemented in software in C, and the project calls this full software defined radio flexibility.

The repository is a collection of related pieces rather than a single application. At the top level there is host/ for the PC side tools, fpga/ for the AD9361 plus Xilinx Zynq implementation, open_btle_baseband_chip/ for the open chip design, verilog/ and python/ for algorithm work, matlab/ for algorithm evaluation and scripts, firmware/, doc/ and usrp_replay_example/. The project description adds another role: a BLE packet sniffer and transmitter for both standard and non standard, meaning raw bit, traffic.

Two command line tools carry most of the practical value. btle_rx is the sniffer, and beyond sniffing broadcast and fixed channel traffic it can track the channel hopping of an active link. btle_tx is a universal transmitter that works with the BLE standard and also supports a raw bit mode to generate arbitrary GFSK packets, which the documentation points at use for testing non standard protocols or a standard that is still under discussion before the chip reaches the market.

The link layer coverage described is all ADV and DATA channel packet formats in Core_V4.0, chapters 2 and 3, part B, volume 6. The licence field on the repository says Apache-2.0, which is a permissive notice, but the hardware libraries it links against are separate projects with their own terms.

## btle_rx follows a connection, it does not just listen on 37

Most casual Bluetooth sniffers only see advertising. The capability that separates btle_rx is that it parses and tracks the channel hopping pattern automatically, not limited to the broadcast channel or a fixed channel.

The switch is the hop option, and the mechanism behind it is a two stage capture. The access address default is 8e89bed6 for the three advertising channels, and the CRC init default is 555555 for the advertising channel. For data channels you have to supply the correct values, and the documentation says to take them from the captured connection setup procedure. Once the receiver has seen the ADV_CONNECT_REQ packet on an advertising channel, it knows the connection parameters and can follow the link onto the data channels.

```bash
./btle-tools/src/btle_rx -o --hop
```

That is a two stage dependency a user has to understand rather than a switch they can flip blindly. If the access address or CRC init do not match the connection being sniffed, the receiver will not lock on.

The tool also has a raw mode, which prints the following raw 42 bytes after the access address is detected, without descrambling or parsing, and an access mask that lets you treat a bit as taking part in the packet existence decision, which is useful if you want a shorter or sparser unique word for detection. Packets can be stored to a pcap file with the filename option, and the verbose mode prints more information when there is an error.

Gain tuning gets explicit attention too. The receive gain range depends on the radio, with a HackRF default of 6 and a valid range up to 62, and a bladeRF maximum of 66. The documentation advises starting from low gain, because high gain always causes severe distortion.

## Packets are described as hyphen separated field strings

The transmitter has its own small language, and understanding it is the difference between sending something meaningful and sending noise.

A packet descriptor is one string. It starts with the BTLE channel number, 0 to 39, then the packet type, which can be RAW, iBeacon, ADV_IND, ADV_DIRECT_IND and the other formats, and then a list of field and value pairs specific to that packet type. The last pair can be a Space value, which specifies how many milliseconds to wait after that packet is sent.

```bash
channel_number-packet_type-field-value-field-value-...-Space-value
```

There are two rules that are easy to trip over. Space characters are not allowed inside a command line packet descriptor, so a name such as SDR Bluetooth Low Energy has its spaces written as slashes, while the same descriptor in a text file may use real spaces. The hyphen character is the field separator, so it cannot appear inside a field value either.

Sequences are sent either as a list of descriptors on the command line, or from a text file where one descriptor sits per line, lines starting with a hash character are comments, and a trailing rN means the whole sequence is repeated N times. Without rN the sequence is sent once.

```bash
./btle-tools/src/btle_tx ../btle-tools/src/packets_discovery.txt
```

The repository also ships a discovery packet list, a connection establishment example in doc/TI-BLE-INTRODUCTION.pdf, and an appendix of descriptor examples for all the packet formats.

## Building requires the SDR driver stack to work first

The build instructions are short, and they begin with a warning rather than a step. The README says to make sure the SDR hardware environment, meaning the driver and library, has been set up correctly before running the project. The project links against HackRF, bladeRF, and a compatible version of the HackRF and bladeRF libraries, with the specifics recorded in compatible_hackrf_bladerf_lib.txt.

```bash
git clone https://github.com/JiaoXianjun/BTLE.git
cd BTLE/host
mkdir build
cd build
cmake ../                   (default. for HackRF)
cmake ../ -DUSE_BLADERF=1   (only for bladeRF)

make
./btle-tools/src/btle_rx
```

The cmake line is the switch between the two supported radios, and the default is HackRF. The final command starts the sniffer on channel 37, and the expected result is many packets on screen if there are BLE devices such as a phone, a pad or a laptop nearby.

The transmitter is started the same way, with a descriptor that advertises a name.

```bash
./btle-tools/src/btle_tx 37-DISCOVERY-TxAdd-1-RxAdd-0-AdvA-010203040506-LOCAL_NAME09-SDR/Bluetooth/Low/Energy r500 
```

The check is done with a second BLE sniffer app such as LightBlue, where you should see a device with the advertised name.

There is one performance note for HackRF users, and it is not a configuration option but a source change. The README suggests editing the HackRF library so that a transfer count of 4 and a transfer buffer size of 4096 are used, then recompiling the library, reinstalling it, and recompiling BTLE so the change takes effect. A fast operation sequence depends on the host library behaving well, and the fix lives outside this repository.

## The open baseband chip takes the design down to a PDK

The most unusual part of the project is open_btle_baseband_chip, which is not a tool but a hardware design. The README describes it as the BTLE baseband with an algorithms description, a Python and Verilog implementation, and FPGA and SkyWater 130 PDK results produced through an OpenLane2 workflow.

That places the project at three levels of abstraction, and a reader has to pick one. The tools level is the C code for the host that talks to a commercial SDR. The algorithmic level is Python and Verilog, which lets you evaluate a baseband algorithm before committing it to hardware. The silicon level is the SkyWater 130 process run through OpenLane, which produces an open chip layout rather than a binary blob.

For protocol research the useful consequence is that a receiver design can be modified and re-simulated. For an RF engineer the interesting consequence is that the same baseband that runs on a HackRF also has a path to a chip.

The repository is also organised around reuse rather than a single binary. There is a python/ directory, a verilog/ directory, a firmware/ directory and a usrp_replay_example/, which suggests the same packet definitions are consumed by more than one radio environment.

## The last push is recent but the tagged releases are from 2015

The maintenance picture needs two dates, and they point in different directions. The last push to the repository was on 2026-06-08, so the working tree is being touched. The tagged releases, on the other hand, are old: v0.2 on 2015-11-11, v0.1.2 on 2015-11-07 and v0.1.1 on 2015-11-05, and each carries the same short description about the BTLE packet sender and the sniffer scanner.

So the code has moved, but the release history has not been touched in the same period, and there is no versioned artefact you can download to get a known good pairing of the host tools with a particular SDR library revision. That matters more here than in most projects, because the host tools link against hardware libraries that themselves move. The compatible_hackrf_bladerf_lib.txt file exists precisely because that pairing is not something you can assume.

A second dating signal is the specification revision. The link layer coverage is described against Core_V4.0. A newer revision of the Bluetooth core specification may define packet formats and behaviour this implementation does not handle, and the documentation does not claim otherwise.

The practical advice is to treat the trunk as a research tool and to read the current source rather than a release, and to verify the radio pairing yourself before a long session.

## Where BTLE is the wrong tool

The hardware requirement is the first boundary. You need a HackRF or a bladeRF, and both are specialist instruments rather than something on every desk. You also need a working driver and library environment, and the project's own build note puts that check first for a reason.

The second boundary is scope of analysis. btle_rx works at the link layer, parsing advertising and data channel packets, tracking hops and writing pcap. It is not a Bluetooth profile analyser, and the raw mode explicitly stops short of descrambling and parsing, which means traffic protected at the upper layer stays opaque to it. If your question is about an application profile, a GAP or GATT interaction above the link layer, this is the wrong layer of the stack.

The third boundary is the transmitter, and it is a real one. btle_tx can emit raw GFSK packets that are not valid BLE traffic at all, and the documentation encourages using it to test protocols that do not exist yet. That is exactly what makes it valuable for hardware and protocol development, and it is also why the tool is for work on hardware and systems you are responsible for, whether that is your own device, your own test setup or a lab you have permission to work in.

The alternative worth knowing is a dedicated commercial or vendor Bluetooth sniffer, which arrives with a supported radio, a maintained parser and a vendor behind it. BTLE inverts that trade. You get a protocol-transparent view and the ability to transmit things no commercial tool will send, at the cost of owning the radio stack and the driver maintenance that comes with it.

## Conclusion

Adopt BTLE if your research question is about the air interface itself, because btle_rx gives you decoded link layer packets with hop tracking and a pcap writer, and btle_tx lets you put a not yet shipping packet on the air. Do not adopt it for ordinary Bluetooth debugging, since it needs a HackRF or bladeRF, a working SDR driver stack, and the receiver tuning path is manual rather than plug and play. Verify first that your radio firmware and library combination is in the compatible_hackrf_bladerf_lib.txt list, that the spec revision you care about is covered, since the link layer support described is Core_V4.0, and that the licences of the radio libraries you link against permit what you plan to do, since this project is Apache-2.0 while the hardware libraries are separate.

## FAQ

### Which SDR radios does BTLE support?

The README lists HackRF and bladeRF as the supported hardware, plus a compatible version of the HackRF and bladeRF libraries listed in compatible_hackrf_bladerf_lib.txt. The cmake step chooses between them, with HackRF as the default and a bladeRF build enabled by passing -DUSE_BLADERF=1.

### How do I build and run the BTLE sniffer?

Clone the repository, build in the host/build directory with cmake and make, then run ./btle-tools/src/btle_rx. That sniffs channel 37 by default, and you should see many packets on screen if there are BLE devices nearby. The README asks that the SDR driver and library environment be set up correctly first.

### Can BTLE track a connected Bluetooth session rather than only advertisements?

Yes. The -o option turns on data channel tracking after the link setup information has been captured in the ADV_CONNECT_REQ packet on the advertising channel. For a data channel you also need the correct access address and CRC init values for that connection.

### How do I send a custom BLE advertisement with btle_tx?

Pass a descriptor string that starts with the channel number, then the packet type, then field and value pairs, and optionally a Space value for the delay. Spaces are written as slashes on the command line, and a trailing rN repeats the sequence N times. The repository ships a discovery packet list you can run directly.

### What licence is BTLE released under?

The licence field on the repository says Apache-2.0, a permissive notice with a patent grant. The HackRF and bladeRF libraries it links against are separate projects with their own licences, and compatible_hackrf_bladerf_lib.txt records the versions the build expects.

## Sources

- [JiaoXianjun/BTLE on GitHub](https://github.com/JiaoXianjun/BTLE)
- [License: Apache-2.0](https://github.com/JiaoXianjun/BTLE/blob/master/LICENSE)
- [Project website](http://sdr-x.github.io/)
- [README](https://github.com/JiaoXianjun/BTLE/blob/master/README.md)
- [Releases](https://github.com/JiaoXianjun/BTLE/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jiaoxianjun-btle
