Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PPM Correction under Raspbian using LTE-Cell-Scanner

LTE-Cell-Scanner under Raspbian (and maybe Ubuntu/Debian)

Mark Jessop vk5qi@rfhead.net 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.

1. Dependencies

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

3. Build

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...)

4. Running

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.

Enjoy.

@tejaskale
Copy link

tejaskale commented Jan 5, 2021

Try make -j4 to build 4x faster.

I build the binaries on a Rpi3b+ in ~5 mins.

@squirrelcage
Copy link

squirrelcage commented Feb 1, 2022

Using this in Japan, for several service providers, none of the PR entries have a value of "one", all are unknown of UKN. Is there any way to use this information to come up with a proper PPM?

Sample (excluding most of the scanning):

$ ./CellSearch --freq-start 773000000 --freq-end 775000000
LTE CellSearch v1.0.0 (release) beginning
Search frequency range: 773-775 MHz
PPM: 120
correction: 1
Found Fitipower FC0012 tuner
Examining center frequency 773 MHz ...
Examining center frequency 773.1 MHz ...
Examining center frequency 773.2 MHz ...
Examining center frequency 773.3 MHz ...
Detected a cell!
cell ID: 463
RX power level: -20.722 dB
residual frequency offset: -21008.9 Hz
...
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
463255 773.3M -21k -20.7 E 255 U UNK 0.99997283292940430943
238255 773.4M -9.11k -19.3 E 255 U UNK 0.99998821613320865165
144255 773.4M -10.1k -19.6 E 255 U UNK 0.99998687647935546874
486255 773.5M -30.4k -19.4 E 255 U UNK 0.99996064508567916729
101255 773.6M 13.4k -19 E 255 U UNK 1.0000173317359384306
257255 773.6M 21.7k -19.1 E 255 U UNK 1.0000280360962403581
381255 773.6M 20.7k -19.3 E 255 U UNK 1.0000267029420359943
195255 773.6M 14.2k -19.5 E 255 U UNK 1.0000183619686751069
319255 773.6M -3.17k -19.6 E 255 U UNK 0.99999589751912809632
408255 773.6M -30.2k -19.7 E 255 U UNK 0.99996092381182699604
485255 773.6M 22.1k -19.8 N 255 U UNK 1.0000285080687061345
401255 773.7M 6.62k -18.3 E 255 U UNK 1.0000085591094423076
275255 773.7M -3.91k -18.4 N 255 U UNK 0.99999494373049346851
347255 773.7M -4.98k -18.6 E 255 U UNK 0.99999355924751787139
179255 773.7M 625h -18.6 E 255 U UNK 1.0000008083986193785
121255 773.7M -14.5k -18.7 E 255 U UNK 0.99998127986713458704
389255 773.7M -14.9k -19 N 255 U UNK 0.99998075789518792167
268255 773.7M 5.36k -19.1 N 255 U UNK 1.0000069332811578615
113255 773.7M -9.5k -19.1 E 255 U UNK 0.99998771899749649972
60255 773.7M -9.1k -19.2 N 255 U UNK 0.99998823620539067925
383255 773.7M -35.3k -19.2 E 255 U UNK 0.99995441190924927444
61255 773.7M -47.2k -19.3 E 255 U UNK 0.9999389934883765596
428255 773.7M -20.5k -19.3 N 255 U UNK 0.99997344429272660982
226255 773.7M -28k -19.3 E 255 U UNK 0.99996377432401362118
17255 773.7M -22.6k -19.4 E 255 U UNK 0.99997082052258290386
240255 773.7M 3.23k -19.4 N 255 U UNK 1.000004169456055747
135255 775M -12.3k -16.7 N 255 U UNK 0.99998408588370568673
164255 773.7M -16k -19.4 E 255 U UNK 0.99997935379357116847
306255 773.8M 34.5k -18.9 E 255 U UNK 1.0000446035137167122
313255 773.8M -11k -19 E 255 U UNK 0.99998582621177212193
338255 773.8M 2.21k -19 N 255 U UNK 1.0000028551999169402
50255 773.8M -14k -19 N 255 U UNK 0.99998192289602827465
123255 773.8M -11.2k -19.1 E 255 U UNK 0.99998549357547172889
104255 773.8M -11.1k -19.1 E 255 U UNK 0.99998571408240422009
271255 773.9M -43.5k -18.3 E 255 U UNK 0.99994378136544781466
119255 773.9M -13k -18.3 N 255 U UNK 0.99998316923784924537
272255 773.9M -8.74k -18.4 N 255 U UNK 0.99998871111017517688
330255 774M -15.7k -17.8 E 255 U UNK 0.99997975313230647032
281255 774M -23.2k -17.8 E 255 U UNK 0.99996999855063872786
260255 774M -13.6k -18 N 255 U UNK 0.99998239430875224265
16255 774M -5.68k -18.3 E 255 U UNK 0.999992655532549235
344255 774M 14.9k -18.5 E 255 U UNK 1.0000192316167542117
475255 774.1M -4.62k -18.4 E 255 U UNK 0.99999402872267995068
64255 774.1M -23.2k -18.6 E 255 U UNK 0.99997001285958175831
186255 774.2M -18.4k -17.7 E 255 U UNK 0.99997627678624334546
362255 774.3M -17.3k -18.2 E 255 U UNK 0.99997763273324180577
352255 774.9M -17.9k -16.9 N 255 U UNK 0.99997690561542895704
270255 774.9M -15.2k -17.1 E 255 U UNK 0.99998036767011855286
226255 775M -5.35k -16.3 N 255 U UNK 0.99999309449637996394
311255 775M -27.3k -16.8 N 255 U UNK 0.99996474653814793054
185255 775M 1.41k -17 N 255 U UNK 1.0000018174739393473
267255 775M -3.31k -17.1 E 255 U UNK 0.99999573341847547425
376255 775M -10.5k -17.1 N 255 U UNK 0.99998651274561911606
448255 775M 1.38k -17.1 N 255 U UNK 1.0000017777973446709

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment