Skip to content

Instantly share code, notes, and snippets.

@dw5
Forked from JamesHagerman/stslte-notes.md
Created May 12, 2021 19:33
Show Gist options
  • Save dw5/46749f8c8d110e600cb8830edba11fc6 to your computer and use it in GitHub Desktop.
Save dw5/46749f8c8d110e600cb8830edba11fc6 to your computer and use it in GitHub Desktop.
My notes about running srsLTE

srsLTE notes

These are notes I've taken while rying to get srslte up and running. This is messy, sorry...

Working solution - LimeSDR + SoapySDR + srsLTE

Dependencies:

sudo apt install tree vim git g++ make cmake pkg-config libpython-dev python-numpy swig libi2c-dev libusb-1.0-0-dev libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev gnuradio

# For the graphical LimeSuiteGUI
sudo apt-get install libboost-system-dev libboost-test-dev libboost-thread-dev libqwt-qt5-dev qtbase5-dev

Sources:

git clone https://github.com/pothosware/SoapySDR.git
git clone https://github.com/myriadrf/LimeSuite.git
git clone https://github.com/Nuand/bladeRF.git            - Optional
git clone https://github.com/pothosware/SoapyBladeRF.git  - Optional
git clone https://github.com/srsLTE/srsGUI.git            - Optional (has to be installed before srsLTE is compiled)
git clone https://github.com/srsLTE/srsLTE.git

Build:

For my laptop, these versions work. For the RPi4, see the dedicated section below.

pushd SoapySDR
git checkout tags/soapy-sdr-0.7.2 -b soapy-sdr-0.7.2
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig
popd

pushd LimeSuite
git checkout tags/v19.04.0 -b v19.04.0
mkdir builddir
cd builddir
cmake ..
make
sudo make install
sudo ldconfig
cd ../udev-rules
sudo sh ./install.sh
popd

pushd bladeRF/host/
mkdir build
cd build/
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DINSTALL_UDEV_RULES=ON -DBLADERF_GROUP=plugdev ..
make
sudo make install
sudo ldconfig
sudo mkdir -p /etc/Nuand/bladeRF/
sudo wget https://www.nuand.com/fpga/hostedx40-latest.rbf --output-document /etc/Nuand/bladeRF/hostedx40.rbf
sudo scp user@othermachine:/.Nuand/bladeRF/whatever-serial-number_dc_rx.tbl /etc/Nuand/bladeRF/whatever-serial-number_dc_rx.tbl
popd

pushd SoapyBladeRF
mkdir build
cd build
cmake ..
make
sudo make install
popd

pushd srsLTE
# See note about which versions work on RPi4...
mkdir build
cd build
cmake ../
make
make test
sudo make install
sudo ldconfig
sudo ./srslte_install_configs.sh service
popd

Then write yourself a SIM, cd to ~/.config/srslte, configure srsLTE, and run both the eNodeB and EPC!

These are the bare minimum config files I changed away from the defaults:

enb.conf:

n_prb = 25
tx_gain = 72
all_level = info

The dl_earfcn = 3400 value is okay for my needs. You should be sure you're aware of the implications of using Band 7.

Raspberry Pi 4 - Issues with the current version of srsLTE

While the latest version of srsLTE works on my laptop without any issues, they do not work on the RPi4 based on my testing.

Back in October, a user named Ralph posted details about his working RPi4, srsLTE, and LimeSDR Mini setup to the srsLTE mailing list. Here is the original message, for reference: http://www.softwareradiosystems.com/pipermail/srslte-users/2019-October/003063.html

Here are the versions he called out in that message:

LimeSDR Mini, Gateware 1.30

SoapySDR: 189bc69217846581e34456f391683cc07c43ae0d
LimeSuite: 627c82c76938765e93e85784cb359ea4aa71554e
srsGUI: 31c75d17b61c27271cd7c48a5de8873d15e2bd23
srsLTE: 62d295671510630ea9aea1754835f6c346de6ed7

That's version 19.09 of srsLTE. When I tried that version on my RPi4 the system was not stable and I keep getting this error: SCHED: Could not transmit RAR within the window.

After trying a bunch of things (see the list below), I ended up moving back to the latest version, 19.12. It works on my laptop and that release added important features and various bug fixes missing from 19.09. I had hoped it would fix the underlying issue and I'd prefer to be working closer to the most recent release.

But I get the same error on 19.12! So I must be missing something.

Here are the versions I'm using currently. They work on my laptop but do not work on the RPi4. If you're trying to get this working, I suggest attempting to use the versions listed in Ralph's message instead; maybe you'll have better luck than I.

$ for x in `ls`; do pushd $x; git log -1; popd; done
~/dev/LimeSuite ~/dev
commit c931854ead81307206bce750c17c2301810b5545 (HEAD -> master, origin/stable, origin/master, origin/HEAD)
Author: Ignas J <[email protected]>
Date:   Wed Jan 29 10:55:12 2020 +0200

    Remove some warnings (LimeRFE related)
~/dev
~/dev/SoapyBladeRF ~/dev
commit 1c1e8aaba5e8ee154b34c6c3b17743d1c9b9a1ea (HEAD -> master, tag: soapy-bladerf-0.4.1, origin/master, origin/HEAD)
Author: Josh Blum <[email protected]>
Date:   Sat Jan 26 12:22:27 2019 -0600

    soapybladerf: changelog entry for 0.4.1
~/dev
~/dev/SoapySDR ~/dev
commit cbdcb115239d9747b93184c5cf13bf18a8964d52 (HEAD -> soapy-sdr-0.7.2, tag: soapy-sdr-0.7.2, origin/maint)
Author: Josh Blum <[email protected]>
Date:   Sun Jan 12 12:05:37 2020 -0600

    soapysdr: changelog entry for 0.7.2
~/dev
~/dev/bladeRF ~/dev
commit 45521019c540392287eb6e03d52b8073b2fd0743 (HEAD -> master, origin/master, origin/HEAD)
Author: Robert Ghilduta <[email protected]>
Date:   Fri Dec 20 12:47:25 2019 -0800

    libbladeRF: rearrange position of get_speed in declarations
~/dev
~/dev/srsLTE ~/dev
commit d045213fb9cbf98c83c06d7c17197a9dcbfddacf (HEAD -> master, tag: release_19_12, origin/master, origin/HEAD)
Author: Andre Puschmann <[email protected]>
Date:   Wed Jan 8 13:12:35 2020 +0100

    fixing bug in RRC measurement when receiving periodic config
    
    in the UE conformance testing we've spotted an issue
    where an event was evaluated even though the trigger type for
    the report was periodic which caused an exception in RRC
~/dev

Next things to try:

  • Start over (a third time) with a blank SD card, be sure I compile all the versions Ralph suggested, and see how that goes.

  • Ralph's original work was done at 3MHz. I tried n_prb = 50 and n_prb = 25 but I still saw the RAR window issue. Because my test devices do not seem to like connecting to a 3MHz (15 resource blocks) network on Band 7 and I figured that wasn't worth testing. I'll go back and retest this with n_prb = 15 and see if I'm missing something.

  • Wait until the next release and hope the timing (and high RAM usage) improves somewhat.

  • I'm just pulling strings at this point; Maybe it's worth ensuring the clocks on both the UE and RPi4 eNB are in sync?

  • I'm not sure what else should be on this list.

Things I've tried

I tried falling back to 19.09 and ran into some other issues. I need to go back and document them.

I tried to adjust time_adv_nsamples but that didn't get the transmission to happen in time no matter what value I used:

SCHED: Could not transmit RAR within the window

90 samples
(RA TTI=7011, Window=10, Now=7029   18

100 samples:
(RA TTI=3201, Window=10, Now=3245)    44

150 samples:
(RA TTI=8641, Window=10, Now=8661)     20

250 samples:
(RA TTI=6641, Window=10, Now=6656)        15

The Carrier Offset Frequency (CFO) reported by srsue was around 1kHz off so I adjusted it with freq_offset = -1100 and it got the CFO much closer to 0 Hz

I noticed that sometimes the prefix's being sent by the UE are not the same as those being picked up by the eNB running on the RPi4 so I ran the pdsch_ue app from my laptop to check out the channel conditions visually:

cd srsLTE/build
QT_X11_NO_MITSHM=1 lib/examples/pdsch_ue -f 2685.0e6 -F

After adjusting things to get clean signal, I still hit the same issue I've been hitting all along. The RAR isn't transmitted in time.

I tried using a BladeRF x40 instead of the LimeSDR Mini and along with the RAR window issue, I saw a lot of other errors communicating with the SDR correctly (again, I'll have to go back and document them more closely).

I tried running this whole thing on a Raspberry Pi 3B+ and it very quickly ran out of memory. Early on, I tried all this with a RPi4 with 2GB and it also quickly ran out of memory.

I tried running all the tests to ensure they were passing and found one that does not pass on 19.12 on the RPi4. I looked into this and it looks to be an issue with the test more than a root cause for my issue. I opened a GitHub Issue to document the problem: srsran/srsRAN_4G#461

99% tests passed, 1 tests failed out of 579

Total Test time (real) = 4533.80 sec

The following tests FAILED:
	218 - pucch_test (Bus error)
Errors while running CTest
make: *** [Makefile:152: test] Error 8

Re-ran the test and got the same result:

$ ctest -R pucch_test
Test project /home/pi/dev/srsLTE/build
    Start 218: pucch_test
1/2 Test #218: pucch_test .......................Bus error***Exception:   0.04 sec
    Start 219: pucch_test_uci_cqi_decoder
2/2 Test #219: pucch_test_uci_cqi_decoder .......   Passed    0.97 sec

50% tests passed, 1 tests failed out of 2

Total Test time (real) =   1.04 sec

The following tests FAILED:
	218 - pucch_test (Bus error)
Errors while running CTest

SDR configuration stuff

LimeSDR USB

https://wiki.myriadrf.org/LimeSDR-USB

The LimeSDR USB exposes all 10 of the RF ports available on the LMS7002M chip.

  • Channel 0
    • TX1_1 = BAND1 (2GHz - 3.5GHz); TX1_2 = BAND2 (10MHz - 2GHz)
    • RX1_L = LNAL (10MHz - 2GHz); RX1_H = LNAH (2GHz - 3.5GHz); RX1_W = LNAW (10MHz - 2GHz)
  • Channel 1
    • TX2_1 = BAND1 (2GHz - 3.5GHz); TX2_2 = BAND2 (10MHz - 2GHz)
    • RX2_H = LNAH (2GHz - 3.5GHz); RX2_W = LNAW (10MHz - 2GHz)

UNTESTED:

device_args = rxant=LNAL,txant=BAND1

LimeSDR Mini

https://wiki.myriadrf.org/LimeSDR-Mini

The Mini has 2x RF switches that allow the 2x SMA connectors to be routed to one of 5 RF ports on the LMS7002M (2x outputs for TX, 3x inputs for RX). SoapySDR gives these ports slightly different name. These names can be put into device_args to configure the RF paths.

Note: Frequency ranges were taken from the v1.1 schematic

  • TX1_1 = BAND1 (2GHz - 2.6GHz); TX1_2 = BAND2 (30MHz - 1.9GHz)
  • RX1_H = LNAH (2GHz - 3.5GHz); RX1_W = LNAW (10MHz - 2GHz)
device_args = rxant=LNAH,txant=BAND1

OLDER STUFF BELOW HERE

Install stuff

I'm running linux.

  • Install all your SDR stuff first. I'm using a BladeRF, a LimeSDR, and a LimeSDR-Mini. That means I had to install all the stuff for each of those including soapy and the pothos stack since that's what was to implement limesdr support
  • Compile from source. rtfm
  • Install the config files to ~/.config/srslte/ or whatever

Configuring stuff

This is where things get tricky.

  • Write a SIM (see below)
  • Configure the EPC to match the SIM (apn settings, MCC, MNC, probably more)
  • Add the IMSI and other SIM data to the user_db.csv

SIMs

You need to be able to write your own SIM cards. Encryption is pretty important in LTE and without USIMs with custom stuff on them, you're going to have a bad time.

I purchased two sim reader/writers from aliexpress:

  • A black one: It came with 5 USIMs and a PCB adapter board. Name on the box is PC/SC CCID ISO7816 USB Smart Card Reader
  • A white one: Like a USB thumb drive ACR38T-D1

I had to ask the seller for the software after purchase. They sent me to some Bidu site to download two archives. The software in both archives required Windows.

I ended up spending way too much time getting the CardTool software working. It required VB6 components and wasn't clear enough about what settings to use to actually flash the cards I had. I did realize that the ACS website provides a pretty reasonable driver installer package for the thing though, so that worked out well.

The best software had the name SIM Personalize tools(Copyright: XCRFIDSIMWrite Ver 3.1.0). This worked with both reader/writers after I had installed the drivers!

After it loads up, I unplugged the SIM writers, plugged in a sim, plugged the SIM writers back into the computer, and pressed read. Without this process, it was touchy.

The SIM values popped up on screen and I was able to start going through and editing the values manually.

NOTE: Apparently Copy/Pasteing into some fields is blocked.

Actual values

Note: The information here is a little bit inaccurate. The best place to look up the meaning of these values is in the 3gpp spec. Google TS 31.102 4.2.84 pdf and search for things like EFPLMNwACT or EFAD to find info about most fields.

For the Common Parameter section, I only touched the ICCID field! Many SIM cards will brick themselves if you try to read them with the wrong PIN too many times. Like, three times. So don't muck with them unless you've okay losing a few SIMs figuring it out! I don't know why and I ain't gonna test it yet, but it feels like the PIN1 and PIN2 fields should both be 1234 for the SIMs I got? Whatever. I'll play with these later.

For srslte, I used the right hand LTE/WCDMA Paramater section, and clicked the Same with LTE button on the left hand panel every once in a while to copy the data back over to the GSM/WCDMA/LTE side of the interface. I don't know if it matters.

These are the values I changed:

Note about MCC and MNC: Use 001 and 01. These are correct test values! If you're spoofing AT&T towers, you run the risk of fucking with 911 calls! Unactivated phones basically roam to make emergency calls. Lots of kids and disadvantaged people have unactivated phones for saftey!

For some fields, I'll provide a section number that tells where inside TS 31.102 4.2.84 to find more information about the field.

IMSI15: 001010000000001               Combination Field! [MCC+MNC+ID] and the ID usually increments
AD: 00000002                          (4.2.18) This sets the phone's operation mode and the format of the MCC+MNC part of the IMSI
KI: 12341234123412341234123412341234  The special key! #1 thing you can't read or write on a normal SIM!
OPC: Empty. Click the radio button next to OP instead.
OP: 11111111111111111111111111111111  Another part of the KEY! #2 thing you can't read or write on a normal SIM!
MSISDN: A phone number                I'm sure there's a correct "test" number to use here, but I don't know it.
SPN: CMCC                             Service Provider Name. It's what gets displayed at the top of the phone.
Algorithm: Milenage                   XOR is usually only used for testing, srslte supports Milenage so use it.

I feel like I'm missing something in here still. The user_db.csv documentation has more fields that don't match any fields in this SIM tools interface.

These are the default srslte configs:

ue2,mil,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001234,7,dynamic
ue1,xor,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234,7,dynamic

Picking Frequencies (and some RF details about LTE)

This is another tricky bit.

Your UE/test phone likely supports a bunch of different LTE bands. Use https://www.frequencycheck.com/ to look up your device and the bands it supports.

From there, you can get more info about the those bands on the LTE Frequency Bands Wikipedia page. This includes some information about the frequency ranges used in each band as well as whether the band is FDD (Type 1) or TDD (Type 2).

stslte defaults to Type 1 out of the box. This means the uplink and downlink data channels are separated by frequency. This is called Frequency Division Duplexing (FDD). The documentation says it can also support Time Division Duplexing (where time is used to separate the uplink and downlink channels) but I'm not positive how that works.

FDD (Type 1) means two different frequencies are involved, one for uplink, one for downlink. TDD means just one is involved.

So how do we get from a supported band (Say, LTE B2 (1900 PCS)) to actual frequency values?

This is where I needed to dig into LTE physical layer specs.

Evolved-UTRA Absolute Radio Frequency Numbers (EARFCN's) and Resource Blocks (RBs)

In LTE land, we don't usually have to worry about picking exact frequencies. Instead, we use an EARFCN. When you see an EARFCN like 3400, a calculation will spit out the frequency values for the uplink and downlink channels. There are differeny EARFCN's for uplink and downlink, but they are related. Look for the dl_earfcn setting in enb.conf.

Here's a calculator and a post that explains the calculation:

In LTE land, we also don't usually have to worry too much about channel bandwidths. Instead, we use a Number of Physical Resource Blocks. The channel bandwidth and the Number of Physical Resource Blocks are directly related. More resource blocks require more channel bandwidth (and a higher sampling rate in your SDR, btw). Look for the n_prb setting in enb.conf.

This LTE Overview page helped a bunch while sorting this out. Here is a chart from that page describing the relationship for the bandwidths supported by LTE:

Bandwidth Resource Blocks Subcarriers (downlink) Subcarriers (uplink)
1.4 MHz 6 73 72
3 MHz 15 181 180
5 MHz 25 301 300
10 MHz 50 601 600
15 MHz 75 901 900
20 MHz 100 1201 1200

Working backwards to find LTE Band

Let's work backwards from the default dl_earfcn and n_prb values that come with srslte.

dl_earfcn = 3400
n_prb = 50

The dl_earfcn setting is the dpwnlink EARFCN. It puts us in Band 7 (IMT-E). The DL=2650.0 Mhz, UL=2530.0 MHz values logged when starting up the eNB confirm this.

The n_prb setting is the number of Physical Resource Blocks. It gives us a bandwidth of 10MHz.

To do that process manually I worked through the details without the calculator.

Band 7 has an uplink range of 2500–2570MHz (70MHz wide) and and downlink range of 2620–2690MHz (also 70MHz wide), with a Duplex spacing of 120MHz.

The srslte uplink and downlink frequencies are:

  • 30MHz above the lower edge the each band (which leaves plenty of room for the full 10MHz bandwidth; leaving 5MHz on either side of the carrier/center frequency)
  • 120MHz apart from each other (which matches the Duplex spacing for Band 7)
  • Integer multiples of 100kHz (which matches the channel raster for LTE Release 8)

Picking frequencies for a specific LTE Band

So now let's figure out the downlink EARFCN and RBs config for a band supported by my old unlocked iPhone 5c: LTE B2 (1900 PCS)

Band 2 is FDD, with an uplink of 1850-1910MHz and a downlink of 1930-1990MHz with a duplex spacing of 80MHz. It supports channel bandwidths of 1.3, 3, 5, 10, 15, and 20 MHz and those values correspond to 6, 15, 25, 50, 75, and 100 Physical Resource Blocks.

NOTE: Band 2 is used in the United States. Using this band for testing comes with two caveats: At least you'll be operating "in band". However, you may cause intereference with a real tower! While using an international LTE band likely won't cause interference with a cellular service, you may end up transmitting in another REALLY important band. Like, say, a military satellite uplink band (look up AWS-3 sell off). This is why you should really have a valid test license. Too bad no one knows how to get one of those and the no one in the HAM radio world actually give a shit about modern radio technologies...

The Downlink EARFCN range for Band 2 is 600-1199 (from here). While we could just go with that, we'd have to sort out the bandwidth details.

So, instead, I started by finding the uplink frequency, and worked backwards from there to find a reasonable downlink EARFCN.

We know want to be at least Bandwidth / 2 MHz above the bottom edge of the uplink band. We'll stick with the default n_prb setting, leaving the Number of Physical Resource Blocks at 50 giving us a bandwidth of 10MHz. That means we need to be at least 5MHz above 1850MHz... but it'd be good to have a bunch of extra space in case we want to bump n_prb to 100 for 20MHz of bandwidth in the future.

Since the uplink band is (1910 - 1850 MHz =) 60MHz wide, and we'd like to have a bit of extra spacing, let's go with 20MHz above the low edge of the band, (1850 + 20 MHz = ) 1870MHz. (That checks out okay in the EARFCN calculator link above.)

Now let's find the downlink frequency.

The duplex spacing for Band 2 is 80MHz. We should just be able to add 80 to our chosen uplink to get (1870 + 80 MHz = ) 1950MHz. This lands correctly in the provided downlink range, so we should be okay! (This also checks out okay in the EARFCN calculator.)

That gives us our final values as:

Bandwidth: 10MHz (with enough room for 20MHz in the future!)
Uplink: 1870.0 MHz
Downlink: 1950.0MHz

Plugging 1870 and a bandwidth of 20MHz into the calculator passes the Bandwidth check, and provides us downlink EARFCN of 800. This is in the range of 600-1199 but it also provides enough bandwidth for 100 Physical Resource Blocks (if we want that in the future). Just picking 600 wouldn't have cut it.

So we get these values for our enb.conf:

n_prb = 50
dl_earfcn = 800

That should be enough to sort out how to move srslte to any band your phone/LTE test device/UE supports.

Running the eNB and EPC

  • In 2 different terminal windows, cd into ~/.config/srslte/ and run sudo srsenb and sudo srsepc

Running the UE

This allows you to emulate User Equipment. That means a "mobile handset"/phone or other some other LTE device.

This means you'll need 2 computers, 2 SDRs, and 2 installs of srslte. One setup running the eNB (and probably also the EPC) and one running the UE.

Some advantages of using the UE:

  • You don't need to write SIM cards to test things
  • You can tunnel through the LTE link

I don't really care about running the UE right now.

BSoM connecting...

Built in Release mode using commit d045213f on branch master.
17:17:34.577122 [PHY0] [I] [    0] Component Carrier Worker 0 configured cell 50 PRB
17:17:34.577321 [PHY0] [I] [    0] Worker 0 configured cell 50 PRB
17:17:34.814501 [PHY1] [I] [    0] Component Carrier Worker 0 configured cell 50 PRB
17:17:34.814637 [PHY1] [I] [    0] Worker 0 configured cell 50 PRB
17:17:35.052768 [PHY2] [I] [    0] Component Carrier Worker 0 configured cell 50 PRB
17:17:35.052891 [PHY2] [I] [    0] Worker 0 configured cell 50 PRB
17:17:35.062798 [RRC ] [I] SIB payload - Tx systemInformationBlockType1 (15 B)
17:17:35.062825 [RRC ] [I] SIB payload - Tx systemInformation (27 B)
17:17:35.062833 [RRC ] [I] Allocating 2 PRBs for PUCCH
17:17:35.062856 [S1AP] [I] Proc "MME Connection" - Starting new MME connection.
17:17:35.062859 [S1AP] [I] Connecting to MME 127.0.1.100:36412
17:17:35.062976 [S1AP] [I] SCTP socket established with MME
17:17:35.063404 [S1AP] [I] Sending s1SetupRequest to MME
             0000: 00 11 00 2d 00 00 04 00 3b 00 08 00 00 f1 10 00 
             0010: 00 19 b0 00 3c 40 0a 03 80 73 72 73 65 6e 62 30 
17:17:35.063449 [S1AP] [I] Proc "MME Connection" - S1SetupRequest sent. Waiting for response...
17:17:35.066484 [S1AP] [I] Received S1AP PDU
             0000: 20 11 00 25 00 00 03 00 3d 40 0a 03 80 73 72 73 
             0010: 6d 6d 65 30 31 00 69 00 0b 00 00 00 f1 10 00 00 
17:17:35.066544 [S1AP] [I] Received S1SetupResponse
17:17:35.066578 [S1AP] [I] Proc "MME Connection" - S1Setup procedure completed successfully
17:17:35.086144 [PHY0] [I] [    0] Starting RX/TX thread nof_prb=50, sf_len=11520
Closing log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment