Classroom Glossary Public page

Lab 5: OpenAirInterface LTE Attach Procedure + SNR Budget Instrumentation

373 words

Week: 6-7 -- Cellular Protocols
Points: 25
Time estimate: 90 min lab + 3 hr independent
Deliverable: lab-5-report.md


Objectives

  1. Bring up an OAI LTE eNB in Docker; connect a software UE (srsUE) and complete an LTE attach.
  2. Capture the RACH procedure in a packet capture and annotate the 4-step sequence.
  3. Measure the PUSCH SNR across the receiver chain using OAI's built-in instrumentation.
  4. Observe 5G-AKA key material derivation in the AMF logs (NSA mode optional extension).

Part A: OAI LTE Stack Bring-Up (30 min)

# Clone configuration templates
git clone https://github.com/open5gs/open5gs.git  # for EPC/MME alternative
# OR use OAI EPC (below)

# Pull OAI LTE images
docker pull oaisoftwarealliance/oai-enb:develop
docker pull oaisoftwarealliance/oai-mme:develop
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
docker pull oaisoftwarealliance/oai-hss:develop

# Create lab5 directory with docker-compose
mkdir lab5 && cd lab5

cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: oai_db
    volumes:
      - ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql

  oai-hss:
    image: oaisoftwarealliance/oai-hss:develop
    network_mode: host
    environment:
      TZ: America/New_York
      MYSQL_SERVER: 127.0.0.1
      MYSQL_USER: root
      MYSQL_PASS: root
    depends_on:
      - mysql

  oai-mme:
    image: oaisoftwarealliance/oai-mme:develop
    network_mode: host
    environment:
      TZ: America/New_York
      MCC: "208"
      MNC: "93"
      TAC: "1"
      SGW_S11_IP: "127.0.0.1"

  oai-spgwu:
    image: oaisoftwarealliance/oai-spgwu-tiny:develop
    network_mode: host
    cap_add:
      - NET_ADMIN
    environment:
      TZ: America/New_York
      SGW_INTERFACE_NAME_FOR_S1U: "lo"
      PGW_INTERFACE_NAME_FOR_SGI: "lo"

  oai-enb:
    image: oaisoftwarealliance/oai-enb:develop
    network_mode: host
    cap_add:
      - SYS_RAWIO
      - NET_ADMIN
    environment:
      TZ: America/New_York
      ENODEB_NAME: "lab5-eNB"
      MCC: "208"
      MNC: "93"
      MNC_LENGTH: "2"
      TAC: "1"
      UTRA_BAND_ID: "7"       # Band 7: 2600 MHz (or change to available band)
      DL_FREQUENCY_IN_MHZ: "2680"
      UL_FREQUENCY_OFFSET_IN_MHZ: "120"
      NB_PRB: "25"            # 25 RBs = 5 MHz channel
      MME_S1_IP: "127.0.0.1"
      ENB_S1_IP: "127.0.0.1"
      THREAD_PARALLEL_CONF: "PARALLEL_RU_L1_L2_TRX_SPLIT"
      USE_ZMQ: "yes"          # ZeroMQ RF (no physical radio needed for software UE)
EOF

# Start the stack
docker-compose up -d mysql oai-hss oai-mme oai-spgwu
sleep 10
docker-compose up -d oai-enb

# Verify eNB is running
docker-compose logs oai-enb | grep -E "eNB.*started|RRC.*SIB"

srsUE (software UE):

# Install srsRAN (includes srsUE)
sudo apt-get install srsran srsran-4g

# Configure srsUE to connect to the OAI eNB (ZMQ mode)
cat > /etc/srslte/ue.conf << 'EOF'
[rf]
freq_offset = 0
tx_gain = 80
rx_gain = 40
device_name = zmq
device_args = tx_port=tcp://127.0.0.1:2001,rx_port=tcp://127.0.0.1:2000,id=ue,base_srate=23.04e6

[usim]
mode = soft
algo = milenage
opc  = 63BFA50EE6523365FF14C1F45F88737D
k    = 00112233445566778899aabbccddeeff
imsi = 208930000000001
imei = 353490069873319
EOF

# Connect the software UE
sudo srsue /etc/srslte/ue.conf 2>&1 | tee lab5-srsue.log &
UE_PID=$!

# Watch the UE connection log
sleep 5
grep -E "RACH|Attach|RRC|NAS|CONNECTED" lab5-srsue.log | head -20

Part B: RACH Capture and Annotation (30 min)

Capture the air-interface traffic using Wireshark or tshark in the ZMQ loopback:

# Start packet capture on the loopback interface
sudo tshark -i lo -w lab5-rach.pcap -f "port 2000 or port 2001" &
TSHARK_PID=$!

# Trigger a new attach by restarting srsUE
kill $UE_PID
sudo srsue /etc/srslte/ue.conf 2>&1 | tee lab5-srsue2.log &

sleep 30  # wait for attach
kill $TSHARK_PID

# Analyze in Wireshark
# Filter: lte-rrc or nas-eps
# Look for: RRC Connection Request, RRC Connection Setup, 
#           RRC Connection Setup Complete, Attach Request, Attach Accept

Annotation task: In your report, annotate the following 5-step LTE attach sequence by matching Wireshark frames to the protocol layer:

Step Protocol message Layer What it contains
1 RACH Preamble PHY Zadoff-Chu sequence; random selection
2 RAR (Random Access Response) MAC TA, Temporary C-RNTI, UL grant
3 RRC Connection Request RRC UE identity (S-TMSI or random value)
4 RRC Connection Setup RRC Radio bearer configuration
5 Attach Request / RRC Connection Setup Complete NAS/RRC IMSI (or GUTI), UE capabilities

OAI eNB log analysis:

# Extract PHY-layer RACH events from eNB logs
docker-compose logs oai-enb | grep -E "PRACH|RA-Msg|CRNTI|SNR" | head -30

# Expected output format:
# [PHY] PRACH_RX subframe X: preamble_index Y, TA Z, RSSI -W dBm
# [MAC] RA-Msg2: UE RNTI 0xABCD TA=Z ul_grant=...
# [RRC] RRC Connection Request UE RNTI 0xABCD

Part C: PUSCH SNR Budget Instrumentation (30 min)

OAI instruments the uplink SNR at the PUSCH decoder. Extract and analyze:

# Capture PUSCH SNR logs
docker-compose logs oai-enb | grep -E "SNR|PUSCH|BLER|MCS" | tail -50

# Expected: eNB reports per-subframe SNR estimates
# Format: "UE RNTI 0xABCD PUSCH: SNR=15.2 dB, BLER=0.0, MCS=18"
#!/usr/bin/env python3
"""Lab 5 Part C: Parse and analyze OAI PUSCH SNR logs."""
import re
import numpy as np
import matplotlib.pyplot as plt

# Parse SNR measurements from eNB log
log_file = 'lab5-enb.log'
snr_values = []
mcs_values = []

with open(log_file) as f:
    for line in f:
        # Adjust regex to match actual OAI log format
        snr_match = re.search(r'SNR=(-?\d+\.?\d*)', line)
        mcs_match = re.search(r'MCS=(\d+)', line)
        if snr_match:
            snr_values.append(float(snr_match.group(1)))
        if mcs_match:
            mcs_values.append(int(mcs_match.group(1)))

if snr_values:
    print(f"PUSCH SNR statistics:")
    print(f"  Mean: {np.mean(snr_values):.1f} dB")
    print(f"  Std:  {np.std(snr_values):.1f} dB")
    print(f"  Min:  {np.min(snr_values):.1f} dB")
    print(f"  Max:  {np.max(snr_values):.1f} dB")
    
    plt.figure(figsize=(10, 4))
    plt.plot(snr_values, 'b-', alpha=0.7, label='PUSCH SNR per subframe')
    plt.axhline(np.mean(snr_values), color='r', linestyle='--', label=f'Mean = {np.mean(snr_values):.1f} dB')
    plt.xlabel('Subframe index')
    plt.ylabel('SNR (dB)')
    plt.title('OAI eNB PUSCH SNR Over Time (ZMQ loopback)')
    plt.legend()
    plt.grid(True)
    plt.savefig('lab5/pusch_snr.png', dpi=150)
else:
    print("No SNR values parsed -- check log format and regex")
    print("Manual approach: scan logs for PUSCH-related lines")

Link budget verification: Compare measured PUSCH SNR to the theoretical link budget:

# ZMQ loopback: no propagation loss (should see near-perfect SNR)
# Theoretical: limited by srsUE TX power + OAI receiver noise figure

# Fill in from OAI configuration and AD9361 (or ZMQ) parameters
tx_power_dBm = 23.0   # srsUE default UL max power
rx_nf_dB = 0.0        # ZMQ is ideal (no noise); replace with hardware NF for RF test
path_loss_dB = 0.0    # ZMQ loopback: no propagation

P_rx_dBm = tx_power_dBm - path_loss_dB
thermal_noise_dBm = -174 + 10*np.log10(180e3)  # 180 kHz RB bandwidth
SNR_theoretical_dB = P_rx_dBm - (thermal_noise_dBm + rx_nf_dB)
print(f"Theoretical PUSCH SNR (ZMQ): {SNR_theoretical_dB:.0f} dB")
print(f"(Hardware test would see ~15-25 dB depending on cable losses)")

Part D: 5G-AKA Observation (optional extension)

If OAI 5G NSA mode is available:

# Observe AMF logs for AUSF interaction during UE attach
# Look for SUCI, AUSF authentication, key derivation

docker-compose logs oai-amf | grep -E "SUCI|AUSF|5G-AKA|HXRES|KAUSF" | head -20

# Expected format (varies by OAI version):
# [AMF] Authentication: SUCI received from UE
# [AMF] NAUSF_UEAuthentication request sent to AUSF
# [AMF] 5G-AKA: HXRES* received; verifying RES*
# [AMF] Authentication success; KAUSF derived

Lab Report

Create lab-5-report.md with:

  1. eNB bring-up: docker-compose output showing all containers healthy
  2. LTE attach annotation table (5 steps completed with actual Wireshark frame numbers or OAI log timestamps)
  3. PUSCH SNR statistics: mean, std, min, max from log analysis; plot
  4. Link budget verification: theoretical vs. measured SNR (ZMQ or hardware)
  5. Analysis (150 words): "The OAI eNB's RACH procedure uses Zadoff-Chu sequences as preambles. Explain the cyclic autocorrelation property of Zadoff-Chu sequences and why it allows the eNB to distinguish 64 different preambles and simultaneously estimate the UE's timing advance."

Grading

Component Points
Stack bring-up: all containers healthy, srsUE connects 6
RACH annotation: 5 steps identified with evidence 8
PUSCH SNR: statistics and plot from log analysis 7
Analysis: Zadoff-Chu autocorrelation property explained 4
Total 25