LTE-Cell-Scanner under Raspbian (and maybe Ubuntu/Debian)
Mark Jessop firstname.lastname@example.org 2017-11-19
Here in VK-land, GSM is dying, if not already dead in many parts of the country. As such, RTLSDR calibration tools like kalibrate-rtl are not particularly helpful! However, thanks (mainly) to Telstra, we have a very wide coverage 4G (LTE) network on 'Band 28', which is in a good frequency range for use with a RTLSDR (Downlink band 758 – 803 MHz). LTE-Cell-Scanner provides the 'CellSearch' utility, which will search for LTE cells, and determine the RTLSDR's clock offset. This gist attempt to provide some sort of guide on getting CellSearch running under Raspbian.
This is based on information from here: https://anthturner.com/2017/03/03/experiments-in-rf-hunting-for-lte/ As usual, your mileage may vary, blah blah blah. Suggestions/Improvements appreciated.
Install the required dependencies using:
$ sudo apt-get install cmake libncurses5-dev liblapack-dev libblas-dev libboost-thread-dev libboost-system-dev libitpp-dev librtlsdr-dev libfftw3-dev
(Hopefully I haven't missed anything...)
Note that the line continues off to the right on most web browsers... Make sure you copy it all!
2. Grab Source
OPTION 1: Clone Evrytania's git repository from here https://github.com/Evrytania/LTE-Cell-Scanner by running:
$ git clone https://github.com/Evrytania/LTE-Cell-Scanner.git
then make the modifications mentioned in https://anthturner.com/2017/03/03/experiments-in-rf-hunting-for-lte/
OPTION 2 - (RECOMMENDED for RPi installations): Grab a fixed tarball from here: http://rfhead.net/sats/LTE-Cell-Scanner_rpi.tar.gz using
$ wget http://rfhead.net/sats/LTE-Cell-Scanner_rpi.tar.gz $ tar -xzf LTE-Cell-Scanner_rpi.tar.gz
Built LTE-Cell-Scanner using the usual cmake build steps:
$ cd LTE-Cell-Scanner $ mkdir build $ cd build $ cmake ../
For getting PPM corrections, we only need the CellSearch binary. For some reason LTE-Tracker takes aaaaaaages to build on a RPi, so we specify the CellSearch target to speed things up.
$ make CellSearch
(And wait a while... Get a coffee. Have a beer.)
The built binary will be located at ./src/CellSearch
(TODO: Figure out how to make install without requiring LTE-Tracker to be built...)
CellSearch can then be run using: (assuming you are still in LTE-Cell-Scanner/build/)
$ cd src/ $ ./CellSearch --freq-start 770e6 --freq-end 780e6
The start and stop frequencies can be tailored based on knowledge of what frequency your local 4G towers run on. For example, here's a site near me I found in the ACMA database: https://web.acma.gov.au/rrl//site_search.site_lookup?pSITE_ID=9026709 The relevant entry is the 20 MHz wide transmitter on 778 MHz (the LTE downlink). I can narrow my search to just that tower using:
$ ./CellSearch --freq-start 778e6 --freq-end 778e6
If you're scanning a wide range of frequencies, CellSearch may take a while, especially on a Raspberry Pi.
Results show up as something like this:
$ ./CellSearch --freq-start 778e6 --freq-end 778e6 LTE CellSearch v1.0.0 (release) beginning Search frequency: 778 MHz PPM: 120 correction: 1 Found Rafael Micro R820T tuner [R82XX] PLL not locked! Examining center frequency 778 MHz ... Detected a cell! cell ID: 168 RX power level: -36.8562 dB residual frequency offset: 1660.47 Hz Detected a cell! cell ID: 206 RX power level: -42.9021 dB residual frequency offset: 1622.82 Hz <clipped> 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 280 2 778M 965h -26.3 N 100 N one 1.0000012409073122388 400255 778M 66k -27.8 E 255 U UNK 1.0000847926016689371 311255 778M -48.6k -27.9 E 255 U UNK 0.99993750489266330916 377255 778M 41.7k -28 E 255 U UNK 1.0000535847050331384 94255 778M -43.8k -28.1 E 255 U UNK 0.99994368983093617764
Look for the line which has the lowest entry in the
foff (frequency offset) column. In my case, that's the first entry, with a frequency offset of 965 Hz. The other entries are invalid detections of the same cell. Look for lines that have
PR entries of 'one'.
The CrystalCorrectionFactor value for that line can be converted to PPM correction figures (for use in correcting other applications) using: PPM = 1e6 * (1 - CrystalCorrectionFactor) in my case (calculated using python):
$ python >>> 1e6*(1-1.0000012409073122388) -1.2409073122388037
(Hey, my RTLSDR is pretty good!)
Note that you may get different PPM values from different cells. If your PPM correction is less than ~2ppm, then it's probably not worth adjusting.