Experiments in RF: Hunting for LTE

As AT&T and Verizon announce the timeline to sunset their 2G and 3G networks, respectively, LTE is no longer just the overtaking technology looming on the horizon; it’s here. Major providers have announced their intent to pivot to a mimimum-4G network and phase out the stepping stones of antiquated bands such as GSM, UMTS, CdmaOne (2G), and CDMA2000 (3G).

It’s been well-known for several years how to use a specific type of PC accessory to access the raw signal of a basic band like GSM and “sniff” the information going across it. However, as these older, less secure bands disappear and are replaced with 4G technologies (with modern encryption), tools have evolved to support some discovery functionality.

I took some time recently to play with something that has been an interest of mine since I was a teenager; a radio receiver. A lot of consumer electronics kits for kids include project instructions for a basic radio receiver, but it doesn’t have to stop at receiving your local news report. Radio frequencies make up a large percentage of consumer devices, and any of those frequencies can be received with the right hardware…

Cue the SDR (Software Defined Radio). This is a networked or USB-connected radio with a digital, software-controlled tuner. The one I used for this experiment was the Software Defined Radio Starter Kit from Hak5. This includes an RTL-SDR running on the R820T chipset, which is one of the most broadly compatible radio chipsets on the market.

Because I don’t like taking the easy way out, I decided to also build the setup for portability and try to make the setup work on a Raspberry Pi 3.

First, I cloned the repository Evrytania/LTE-Cell-Scanner. There is another repository out there by JiaoXianjun which is more recent and has been improved with OpenCL support, but it doesn’t work properly on the gcc-arm-linux-gnueabihf toolchain as-is.

I made the following modifications to account for the setup of Raspbian jessie on the RPi3:

Added “/usr/lib/arm-linux-gnueabihf” to the section FIND_LIBRARY, above “NO_DEFAULT_PATH”, to all the .cmake files in cmake/Modules/

Edit CmakeLists.txt, replace this line (should be line 11, as of this writing):



SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03 -ggdb -Wall")


I then installed the dependencies needed to build the project:

sudo apt-get install cmake libncurses5-dev liblapack-dev libblas-dev libboost-thead-dev libboost-system-dev libitpp-dev librtlsdr-dev libfftw3-dev


After that, I ran the following commands from the repository root:

mkdir build
cd build
cmake ..
sudo make install


Now I can use the tools provided, CellSearch and LTE-Tracker, to scan for the presence and signal strength of phones around me. I advise against using LTE-Tracker on the Pi, as its ncurses interface seems to have a problem running on the device, and repeatedly segfaults.

For example, if I want to search US LTE Band 13 (Verizon’s primary LTE band, and the only Verizon band that runs within the frequency response of the SDR I’m using):

CellSearch --freq-start 746e6 --freq-end 756e6

This will give you a table that looks something like this:

Detected the following cells:
A: #antenna ports C: CP type ; P: PHICH duration ; PR: PHICH resource type
CID A      fc   foff RXPWR C nRB P  PR CrystalCorrectionFactor
277 2    751M -2.05k -4.62 N  50 N one 0.99999722639394528212
271 2    751M -2.05k -5.21 N  50 N one 0.99999722679001878944
256 2    751M -2.05k -9.01 N  50 N one 0.9999972314719194344
259 2    751M -2.07k -9.91 N  50 N one 0.99999720228692212665
150 2    754M -2.07k -6.07 N  50 N one 0.99999721052901307361

In this example, looking at the first line, an LTE device with the CID (or PCI, if you’re looking at LTE Discovery for Android) 277, which has 2 transmit antennas, is at 751MHz. The frequency offset between that cell phone and the radio was -2.05kHz. The received power was -4.62dB with a Normal cyclic prefix. This cell phone occupies 50 resource blocks (10MHz) and the PHICH has a Normal duration and resource type one. The last field is the correction factor, which can be passed to CellSearch with –correction (and setting –ppm to 10) to make the search quicker.

A few notes about my experiences with the RTL-SDR: If you’ve never used a radio before, be aware that the accuracy of the crystal varies over time, most notably between hot and cold states. I did use kalibrate-rtl at first to calibrate my radio, but as there aren’t strong enough GSM frequencies in my area, it took several times to find something usable.

If you want to manually figure out how much offset there is between the tuner frequency and the actual broadcast frequency, try looking between 162.400MHz and 162.550MHz to find a known frequency to calculate offset from.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s