Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

When an interviewer asks "Tell me about your experience with 5G" or "Walk me through a project you worked on", use this 60-second opener:

"I worked on building and testing a private 5G SA testbed from scratch. My work spanned four areas. First, I set up a URLLC-optimized gNB using OpenAirInterface with a B210 USRP radio — I tuned TDD patterns, MAC scheduler parameters, and PHY settings to bring the average round-trip latency down to about 12 milliseconds. Second, I deployed the Open5GS 5G core on a Kubernetes cluster and stress-tested it with 20 simulated UEs using UERANSIM — I wrote custom benchmarking scripts and proved the core is CPU-bound, not memory-bound under user-plane traffic. Third, I built a UE automation framework that drives a real Pixel 7a phone via ADB through 20 different traffic scenarios — browsing, voice calls, downloads, and stress combinations — to reproducibly trigger specific RRC events. And fourth, I did deep RRC Reconfiguration analysis from live PCAP captures, extracting bearer configurations, DRX parameters, and MAC/RLC settings to understand how the network adapts to different traffic types."

Tip

Pause here. Let the interviewer pick which area interests them. Don't dump everything at once. They'll follow up on what excites them.


Table of Contents

  1. Project Overview
  2. Project 1: URLLC Setup with OAI & srsRAN
  3. Project 2: 5G Core Stress Testing (Open5GS on K3s)
  4. Project 3: UE Automation & RRC Trigger Framework
  5. Project 4: RRC Reconfiguration Analysis
  6. Quick-Reference Cheat Sheet
  7. Common Interview Q&A

Project Overview

graph TD
    A["5G Lab Testbed"] --> B["URLLC Setup"]
    A --> C["Core Stress Testing"]
    A --> D["UE Automation"]
    A --> E["RRC Analysis"]
    B --> B1["OAI gNB + B210 USRP"]
    B --> B2["srsRAN Low Latency Fork"]
    B --> B3["Open5GS / OAI Core"]
    C --> C1["Open5GS on K3s"]
    C --> C2["UERANSIM 20-UE Load"]
    C --> C3["CPU/RAM Benchmarking"]
    D --> D1["Pixel 7a via ADB"]
    D --> D2["20 Traffic Scenarios"]
    D --> D3["Logcat Radio Log Capture"]
    E --> E1["tshark PCAP Parsing"]
    E --> E2["DRB/Bearer Analysis"]
    E --> E3["MAC/RLC Config Extraction"]
Loading

Project 1: URLLC Setup with OAI & srsRAN

What I Built

An end-to-end 5G SA URLLC testbed using:

Component Choice Details
gNB OAI nr-softmodem Built from source (openairinterface5g)
SDR Ettus B210 USRP USB 3.0, 2× TX/RX
Core (option A) OAI Core (Docker) SPGWU / VPP / eBPF UPF variants
Core (option B) Open5GS Source-built, ~/open5gs
Frequency n78 (3.5 GHz) 30 kHz SCS, 106 PRBs
TDD Pattern 2 ms (DDDSU) dl_UL_TransmissionPeriodicity = 4

Key URLLC Optimizations

TDD — 2 ms Periodicity

Slot 0 (DL)    Slot 1 (DL)    Slot 2 (Special)     Slot 3 (UL)
──────────     ──────────     ─────────────────    ──────────
│▼▼▼▼▼▼▼│     │▼▼▼▼▼▼▼│     │▼▼▼▼│░░░░│         │▲▲▲▲▲▲▲│
│14 sym  │     │14 sym  │     │ DL │ GP │         │14 sym  │
  • Why 2 ms? Reduces one-way user-plane latency from ~5 ms (5 ms period) to ~2 ms by increasing UL opportunities.

MAC Scheduler Tuning (OAI)

Parameter Value Why
ulsch_max_frame_inactivity 0 Never stop scheduling UL → ensures always-on UL grant
min_grant_prb 20 Guarantees minimum UL allocation even with no BSR
max_ldpc_iterations 4 Faster LDPC decoding → lower processing latency
sl_ahead 4 Required for B210 USB 3 timing stability

srsRAN Low Latency Fork — Additional Knobs

Parameter Value OAI Equivalent
min_k1 2 N/A — fine-grained HARQ-ACK timing
min_k2 2 N/A — fine-grained PUSCH scheduling delay
max_proc_delay 1 slot N/A
periodic_bsr_timer 1 ms N/A
sr_period_ms 2 ms N/A

Measured Latency Results (Ping to UE via UPF)

Configuration Min Avg Max Packet Loss
External CLK 7.90 ms 11.84 ms 77.4 ms 0% (180/180)
Internal CLK 7.48 ms 11.83 ms 28.2 ms 0% (180/180)

Key insight: Internal clock had a tighter max (28 ms vs 77 ms) suggesting external clock sync jitter on USB. Average RTT ~12 ms is excellent for a B210 setup.

🎤 How to Speak About This in an Interview

Step 1 — Set the context (10 sec):

"I set up an end-to-end 5G Standalone URLLC testbed. The hardware was an Ettus B210 USRP connected via USB 3 to a Linux machine running OAI's nr-softmodem as the gNB, with Open5GS as the 5G core network."

Step 2 — State the problem (10 sec):

"The challenge was that default OAI configurations give 5 ms TDD periodicity, which means UL opportunities come only every 5 ms. For URLLC, we needed to cut that down. Also, the B210's USB 3 interface introduces timing jitter that the gNB has to compensate for."

Step 3 — Explain what you did (20 sec):

"I changed the TDD pattern to 2 ms periodicity — that's 4 slots of 0.5 ms each at 30 kHz SCS, configured as 2 DL + 1 special + 1 UL. Then I tuned the MAC scheduler — I set ulsch_max_frame_inactivity to zero so the base station never stops sending UL grants even during silence periods. I also reduced LDPC decoder iterations from 8 to 4 to speed up PHY-layer processing, and set sl_ahead to 4 to give the B210 enough TX preparation time over USB."

Step 4 — Give results (10 sec):

"The result was an average RTT of about 12 ms with a minimum of 7.9 ms over 180 consecutive pings — zero packet loss. I also compared OAI with srsRAN's low-latency fork, which exposes additional knobs like K1 and K2 timing for HARQ feedback control that OAI doesn't yet support."

If they probe deeper — challenges you faced:

  • "The B210 would throw late TX errors ('L L L L O O' in the log) when sl_ahead was too low. I had to experiment between 3, 4, and 5 to find the sweet spot."
  • "External clock reference via GPSDO showed higher max latency (77 ms spikes) compared to internal clock (28 ms max). I traced this to USB-level jitter in the clock sync path."
  • "I also had to tune PRACH — the detection threshold was too low, causing missed random access attempts. Setting prach_dtx_threshold to 160 fixed it."

If they ask about srsRAN comparison:

"srsRAN's low-latency fork provides parameters like min_k1 and min_k2 that directly control HARQ-ACK and PUSCH scheduling delays. OAI doesn't expose these — it uses default K values. srsRAN also lets you control max_proc_delay and radio_heads_prep_time, which are crucial for real hardware. For pure URLLC, srsRAN gave me finer tuning, but OAI was more stable for the B210 specifically."


Project 2: 5G Core Stress Testing (Open5GS on K3s)

What I Built

A Kubernetes-based 5G core network deployment for scalability and stress testing:

Component Details
Core Open5GS deployed on K3s (lightweight Kubernetes)
RAN Simulator UERANSIM (gNB + 20 UEs in Kubernetes pods)
Monitoring Custom benchmark.sh capturing per-pod CPU/RAM via kubectl top
Test Types ICMP ping flood, HTTP load (20 concurrent fetches), UE churn

Architecture

graph LR
    subgraph K3s Cluster
        subgraph "Open5GS Pods"
            AMF["AMF (59Mi)"]
            SMF["SMF (53Mi)"]
            UPF["UPF (31Mi)"]
            NRF["NRF (30Mi)"]
            SCP["SCP (65Mi)"]
            MongoDB["MongoDB (118-152Mi)"]
        end
        subgraph "UERANSIM Pods"
            gNB["gNB (3Mi)"]
            UEs["20 UEs (58-87Mi)"]
        end
    end
    UEs --> gNB --> AMF
    AMF --> SMF --> UPF
    AMF --> NRF
Loading

Benchmark Results (Idle Baseline → Under Load)

Metric Idle 20-UE HTTP Load Change
Total CPU ~96 m ~1485 m +15×
Total RAM ~623 Mi ~658 Mi +5.6%
MongoDB CPU ~60 m ~101 m +68%
UERANSIM UEs CPU ~21 m ~24.5 m +17%
Node CPU % 6% 7% +1%

Key finding: CPU scaled ~15× under HTTP load while RAM stayed nearly flat — demonstrating that the 5G core is CPU-bound, not memory-bound under user-plane traffic. MongoDB was the most resource-hungry component even at idle.

Custom Benchmark Script

I wrote benchmark.sh that:

  1. Captures per-pod and per-node kubectl top metrics every N seconds
  2. Outputs timestamped CSV files for plotting
  3. Generates per-pod averages and cluster totals
  4. Runs concurrently with traffic generators (ping flood / HTTP)

Stress Test Methodology

Test Method Purpose
Ping Flood 20 UEs → ping -i 0.01 -s 1400 through UPF UPF throughput under ICMP
HTTP Load 20 concurrent curl fetches to Google TCP traffic impact on core
UE Churn Register/deregister cycles AMF/AUSF/UDM signaling load
CPU Throttle cpulimit on UPF pod Simulate resource-constrained edge

🎤 How to Speak About This in an Interview

Step 1 — Why you did this (10 sec):

"I wanted to understand how the 5G core scales under load — specifically, which NF becomes the bottleneck, whether it's CPU or memory limited, and what happens to user-plane latency when you constrain resources like you would in an edge deployment."

Step 2 — What you built (15 sec):

"I deployed the full Open5GS stack — AMF, SMF, UPF, NRF, AUSF, UDM, UDR, PCF, plus MongoDB — on a K3s cluster. For load generation, I ran UERANSIM in the same cluster with one gNB pod and 20 UE pods, each establishing its own PDU session through the core."

Step 3 — How you tested (15 sec):

"I wrote a benchmark script that polls kubectl top every 5 seconds and logs per-pod CPU and RAM to CSV. I ran this alongside three types of traffic: ICMP ping flood through all 20 UEs, 20 concurrent HTTP fetches via curl, and UE churn — rapid register/deregister cycles hitting the signaling NFs."

Step 4 — What you found (15 sec):

"Under HTTP load, total core CPU jumped from about 96 millicores to 1485 — a 15× increase. But RAM barely moved, going from 623 to 658 megabytes. That clearly shows the core is CPU-bound, not memory-bound. MongoDB was the single most resource-hungry pod even at idle, consuming 60 millicores and 118 MB just sitting there."

If they probe deeper — interesting findings:

  • "ICMP and TCP showed very different load profiles. ICMP flood hammered the UPF but barely touched AMF/SMF. HTTP load hit the whole chain — AMF, SMF, and UPF all spiked."
  • "I used cpulimit on the UPF pod to artificially throttle it. This let me demonstrate latency degradation curves — showing how user-plane RTT increases as UPF CPU headroom shrinks, which is exactly what happens in a resource-constrained MEC deployment."
  • "The MongoDB spike to 101m under load told me that subscriber lookups during session establishment are a real bottleneck — an optimization would be to cache subscriber data at the UDR or use a faster DB backend."

If they ask about K3s choice:

"K3s is a lightweight Kubernetes distribution — same API as full K8s but runs as a single binary. It's perfect for lab environments and edge deployments. I chose it because it let me use standard Helm charts for Open5GS while running everything on a single Dell Optiplex workstation."


Project 3: UE Automation & RRC Trigger Framework

What I Built

A fully automated UE testing framework that drives a rooted Pixel 7a via ADB to generate diverse traffic patterns and capture radio layer logs (RRC/MAC/PHY).

Architecture

graph TD
    A["ue_test.sh (Main)"] --> B["adb_utils.sh"]
    A --> C["scenarios.sh (20 Scenarios)"]
    A --> D["logging.sh"]
    A --> E["analyze_logs.py"]
    B --> F["Pixel 7a via ADB/USB"]
    D --> G["Logcat Radio Logs"]
    E --> H["Correlation Report"]

    style A fill:#2d5986,stroke:#fff,color:#fff
    style E fill:#2d7d46,stroke:#fff,color:#fff
Loading

20 Test Scenarios

ID Scenario RRC Events Triggered
1 Browsing Loop DRX activity, SCell Add/Remove
2 YouTube Live Sustained DL, buffer adaptation
3 100 MB Download High throughput, CA activation
4 Voice Call DRB-5 setup (UM RLC), VoLTE bearer
5 Call + Browse Concurrent voice + data bearers
6 Call + Browse + YT Multi-bearer stress
7 Upload Stress (Ping Flood) UL CA, modulation changes
8 Data Toggle (SVC) DRB Release/Re-setup
9 Traffic Burst (Pulse) SCell Add/Remove cycling
10–13 Mixed DL+UL combos Bi-directional bearer config
14–18 Call + various traffic Voice bearer + data concurrency
19 Upload + Burst UL stress + pulsed DL
20 Full Stress (Call+UL+DL) Maximum concurrent bearers
Random Dynamic chain of 2–6 activities Unpredictable RRC patterns

Key Technical Features

  • Rooted airplane mode toggle via cmd connectivity — ensures clean attach sequence per test
  • Robust network wait — polls mDataConnectionState until 2 (CONNECTED) with 60 s timeout
  • Logcat radio capture — synchronized start/stop per scenario
  • Python log correlator (analyze_logs.py) — parses execution.log timestamps alongside logcat to produce a per-activity RRC event correlation report

Sample Analysis Output

Time                | Activity                      | RRC Events Detected
──────────────────────────────────────────────────────────────────────────────
14:02:12 - 14:03:12 | activity_upload               | DataConn: CONNECTED: 2, ServiceState Update: 5
14:03:12 - 14:04:02 | activity_browse                | DataConn: CONNECTED: 1, ServiceState Update: 3
14:04:02 - 14:04:42 | activity_call                  | DataConn: DISCONNECTED: 1, DataConn: CONNECTED: 1

🎤 How to Speak About This in an Interview

Step 1 — The problem (10 sec):

"I needed a repeatable way to trigger specific RRC events on a real device — bearer additions, SCell changes, handovers — so I could capture and analyze them in PCAPs. Doing this manually was error-prone and not reproducible."

Step 2 — What you built (20 sec):

"I wrote a modular Bash automation framework that controls a rooted Pixel 7a over ADB. It's structured in three layers: adb_utils has the low-level primitives like airplane mode toggle, call management, and URL opening; scenarios.sh has 20 composable test scenarios; and ue_test.sh is the orchestrator that manages logging and sequencing. I also wrote a Python log correlator that matches test execution timestamps against radio logcat events."

Step 3 — How each test works (15 sec):

"Each scenario follows the same flow: first we toggle airplane mode ON using root commands to get a clean radio state. Then we start capturing logcat with the radio buffer. Then we turn airplane mode OFF, wait for the data connection to come up — the script polls mDataConnectionState until it reads '2' for CONNECTED — and then runs the actual traffic activity. Finally, we stop the log capture and snapshot the telephony state."

Step 4 — Why 20 scenarios (10 sec):

"Different traffic patterns trigger different RRC events. A voice call creates DRB-5 with UM RLC. A large download activates Carrier Aggregation via SCell addition. The data toggle scenario forces DRB release and re-setup without detaching. Full stress — simultaneous call, upload, and download — pushes the maximum number of concurrent bearers. The random mode chains 2-to-6 activities together for unpredictable patterns you'd see in the real world."

If they probe deeper — technical challenges:

  • "The airplane mode toggle was tricky on Android 13+. The old 'settings put' method stopped working, so I used 'cmd connectivity airplane-mode enable' via root, with a fallback to 'svc data disable'. I also had to poll the settings provider to confirm the radio actually powered off before proceeding."
  • "YouTube ad skip was unreliable — screen coordinates change with updates and screen sizes. I decided not to blind-tap and just let ads play, which actually gave more realistic traffic patterns."
  • "The Python correlator handles both random session logs (where activities are sequential within one log) and individual scenario logs (one log per test). It infers the year from execution.log timestamps because logcat doesn't include the year."

If they ask about the analysis output:

"The correlator produces a table showing each activity's time window alongside the RRC events detected — data connection state changes, service state updates, signal strength changes, and airplane mode toggles. This lets me validate that, for example, a voice call scenario actually triggered a data connection state transition and a new bearer setup within the expected time window."


Project 4: RRC Reconfiguration Analysis

What I Analyzed

Packet captures (PCAPs) from a live 4G/5G EN-DC commercial network across 10 scenarios, extracting:

  • RRC Reconfiguration message timelines
  • DRB/Bearer establishment and release events
  • MAC-MainConfig parameters (DRX, timers)
  • RLC-Config parameters (AM vs UM, reordering timers)
  • Logical Channel configurations (priority, bit rates)

Scenarios Analyzed

Scenario RRC Messages Key Finding
Voice Call 21 DRB-5 (UM RLC) for VoLTE, EN-DC setup
100 MB Download 103 High CA activity (0.66 msg/sec)
Call + Download + YT 19 Intra-LTE handover to PCI 84, multi-bearer
Browsing + Download 90 EPS Bearer ID swap during SCell activation
Speed Test Peak throughput triggering max CA
YouTube Live Sustained buffer-adapted DL
WhatsApp Install Bursty app-store download

Key Findings

1. Bearer Differentiation by Service Type

Service DRB EPS Bearer RLC Mode Priority Rationale
Voice (VoLTE) DRB-5 7 (QCI 1) UM 3 (highest) No retransmissions → low latency
Data DRB-3 5 AM 4 Reliable with ARQ
Data DRB-4 6 AM 8 (lowest) Best-effort
NR Leg (EN-DC) DRB-4 5 AM 5G data path

Critical interview point: Voice uses UM (unacknowledged) RLC because retransmissions add latency unacceptable for real-time audio. Data uses AM (acknowledged) for reliability.

2. DRX Configuration (Consistent Across All Scenarios)

Parameter Value Significance
onDurationTimer 10 sf (10 ms) UE awake window each cycle
drx-InactivityTimer 100 sf (100 ms) Wait after last PDCCH before sleep
longDRX-Cycle 320 ms Deep sleep cycle
shortDRX-Cycle 80 ms Light sleep cycle

The network used the same DRX profile for all scenarios — voice and data. This means power saving is uniform; QoS differentiation happens at the bearer/RLC layer, not DRX.

3. RRC Activity Rate by Traffic Type

Voice Call:              0.24 msg/sec (low — stable bearers)
Browsing + Download:     0.71 msg/sec (high — SCell add/remove)
100 MB Download:         0.66 msg/sec (high — sustained CA)
Voice + YT + Download:  0.40 msg/sec (moderate — multi-bearer)

4. Handover Observation

In the Call+Download+YT scenario, an intra-LTE handover was captured:

  • Frame 249: mobilityControlInfo → target PCI 84
  • All existing bearers (DRB-3, DRB-5) re-established on target cell
  • Voice bearer (DRB-5) was set up after the handover, showing proper bearer continuity

MAC/RLC Parameter Extraction Methodology

Used tshark with specific field filters:

# Extract all RRC Reconfiguration IEs
tshark -r capture.pcap -Y "lte-rrc.rrcConnectionReconfiguration" \
  -T fields -e frame.number -e frame.time \
  -e lte-rrc.drb_Identity -e lte-rrc.rlc_Config \
  -e lte-rrc.mac_MainConfig

# Extract DRX parameters
tshark -r capture.pcap -Y "lte-rrc.drx_Config" \
  -T fields -e lte-rrc.onDurationTimer \
  -e lte-rrc.drx_InactivityTimer \
  -e lte-rrc.longDRX_CycleStartOffset

🎤 How to Speak About This in an Interview

Step 1 — What you analyzed (10 sec):

"I captured PCAPs from a live 4G/5G EN-DC commercial network during 10 different traffic scenarios — voice calls, large downloads, streaming, combined workloads. Then I used tshark to extract every RRC Reconfiguration message along with the MAC, RLC, and logical channel configuration IEs inside them."

Step 2 — Key findings (20 sec):

"The most interesting finding was the clear differentiation between voice and data at the RLC layer. Voice always gets DRB-5 with UM RLC — unacknowledged mode, no retransmissions, because latency matters more than reliability for real-time audio. Data gets AM RLC — acknowledged mode with ARQ, because reliable delivery matters more. The voice bearer also gets highest priority — 3 on a scale of 1-16 — while data bearers sit at 4 and 8."

Step 3 — The surprising part (10 sec):

"What surprised me was that DRX configuration was completely identical across all scenarios — same on-duration timer, same inactivity timer, same short and long DRX cycles. The network doesn't differentiate power saving by traffic type at all. All QoS differentiation happens at the bearer and RLC layer."

Step 4 — RRC message rate insight (10 sec):

"I also calculated the RRC reconfiguration rate per scenario. Voice calls had only 0.24 messages per second — very stable, few reconfigurations. But a 100 MB download had 0.66 per second — three times as many — because the network was constantly adding and removing SCells for Carrier Aggregation as throughput demands changed."

If they probe deeper — methodology:

  • "I used tshark field extraction with specific RRC filter expressions. For example, to get all DRB configurations: tshark -r file.pcap -Y 'lte-rrc.rrcConnectionReconfiguration' -T fields -e lte-rrc.drb_Identity -e lte-rrc.rlc_Config. For DRX parameters, I filtered on lte-rrc.drx_Config. I compiled these into per-scenario reports."
  • "For EN-DC, the LTE RRC Reconfiguration message contains an embedded NR config inside the nr-Config-r15 IE. I extracted the NR radio bearer config to see DRB-4 being set up on the NR secondary cell group with AM RLC and LCID-1."
  • "I also observed an intra-LTE handover in one capture — the mobilityControlInfo IE in the RRC Reconfiguration tells you the target PCI. Bearers were re-established on the target cell, and the voice bearer was set up after the handover, showing proper bearer continuity."

If they ask about MAC-MainConfig:

"I extracted DRX parameters across all scenarios and compared them against 3GPP TS 36.331 specification ranges. For example, onDurationTimer was psf10 — meaning 10 subframes or 10 ms. The spec allows psf1 through psf200. drx-InactivityTimer was psf100 — meaning 100 ms of waiting after the last PDCCH activity before entering DRX. The long DRX cycle was 320 ms. These values are typical for a commercial network balancing power saving with responsiveness."


Quick-Reference Cheat Sheet

Key Numbers to Remember

Metric Value
URLLC RTT (B210, avg) ~12 ms
URLLC TDD period 2 ms
SCS 30 kHz
Core CPU under 20-UE HTTP load ~1485 m (15× idle)
Core RAM under load ~658 Mi (nearly flat)
UE automation scenarios 20
RRC analysis scenarios 10
Voice bearer DRB DRB-5, EPS Bearer 7, UM RLC, Priority 3

Technology Stack

Category Tools Used
gNB OAI nr-softmodem, srsRAN Low Latency fork
SDR Ettus B210 USRP (USB 3.0)
Core Open5GS (source), OAI Core (Docker — SPGWU/VPP/eBPF)
Simulator UERANSIM (K3s pods)
UE Pixel 7a (rooted, ADB automation)
Protocol Analysis tshark, Wireshark, MobileInsight
Infrastructure K3s, Docker Compose, Helm
Scripting Bash (automation), Python (log analysis)
Monitoring kubectl top, custom CSV benchmarking

Common Interview Q&A

Q1: "What is URLLC and how did you achieve low latency?"

URLLC (Ultra-Reliable Low-Latency Communication) targets <1 ms user-plane latency and 99.999% reliability. In my testbed, I achieved ~12 ms average RTT (limited by B210 USB interface) using:

  • 2 ms TDD periodicity — more frequent UL slots
  • Persistent UL schedulingulsch_max_frame_inactivity = 0
  • Reduced LDPC iterations — 4 instead of default 8
  • B210 timing tuningsl_ahead = 4

Q2: "Why does voice use UM RLC instead of AM?"

Voice (VoLTE) uses Unacknowledged Mode because retransmissions add latency that is worse than losing a packet. A dropped voice frame causes a brief glitch; a delayed one causes perceptible stutter. AM mode's ARQ feedback loop adds ~10-30 ms per retransmission, which is unacceptable for real-time audio.

Q3: "How did you validate your stress tests?"

I used three validation methods:

  1. Quantitative benchmarking — CSV-logged per-pod CPU/RAM metrics showed clear correlation between traffic load and resource consumption
  2. Functional verification — All 20 UERANSIM UEs maintained PDU sessions throughout the test; registration counts matched expected values
  3. Comparative analysis — ICMP vs HTTP traffic showed different load profiles; HTTP caused 15× CPU increase while ICMP (ping flood) showed different UPF characteristics

Q4: "What triggers an RRC Reconfiguration?"

From my analysis, RRC Reconfiguration is triggered by:

  • Bearer establishment (new DRB for voice or data)
  • SCell addition/removal (Carrier Aggregation changes)
  • Handover (mobilityControlInfo present)
  • DRX changes (though I observed these staying constant)
  • Measurement configuration updates
  • Security key refresh

Q5: "Explain your UE automation architecture."

A modular Bash framework with three layers:

  1. adb_utils.sh — Low-level ADB primitives (airplane toggle, network wait, URL open, call management)
  2. scenarios.sh — 20 composable test scenarios built from atomic activities
  3. ue_test.sh — Orchestrator that handles logging, session management, and scenario sequencing

A companion Python script correlates execution timestamps with radio logcat events to produce per-activity RRC event reports.

Q6: "What is the difference between OAI Core and Open5GS?"

Both are open-source 5G cores. OAI Core (Docker-based in my setup) offers three UPF options — SPGWU (default), VPP (lowest latency), and eBPF. Open5GS is lighter-weight, C-based, and what I deployed on K3s for stress testing. OAI Core has tighter integration with OAI RAN; Open5GS is more commonly paired with UERANSIM and srsRAN.

Q7: "How does DRX work and why is it important?"

DRX (Discontinuous Reception) saves UE battery by allowing it to sleep between monitoring windows:

  • On-Duration (10 ms): UE wakes and monitors PDCCH
  • Inactivity Timer (100 ms): After last activity, UE enters short DRX
  • Short DRX (80 ms cycle): Light sleep
  • Long DRX (320 ms cycle): Deep sleep

In my analysis, the network used the same DRX profile for all traffic types. QoS differentiation was done at the bearer/RLC level, not the DRX level.

Q8: "What is EN-DC and how did you observe it?"

EN-DC (EUTRA-NR Dual Connectivity) allows a UE to simultaneously connect to both LTE (master) and NR (secondary) base stations. In my PCAP analysis, I observed EN-DC setup at the RRC level — the LTE RRC Reconfiguration message contained an embedded nr-RadioBearerConfig with DRB-4 configured on the NR leg (LCID-1, AM RLC), while voice stayed on the LTE leg (DRB-5, LCID-5, UM RLC).

Q9: "What is the difference between K1 and K2 in NR scheduling?"

K1 is the slot offset between the DL data (PDSCH) and the UE's HARQ-ACK feedback on PUCCH. A smaller K1 means faster feedback → faster retransmissions. K2 is the slot offset between the UL grant (on PDCCH) and the actual PUSCH transmission. Smaller K2 means the UE transmits sooner after receiving permission. In srsRAN's low-latency fork, I set both min_k1 and min_k2 to 2 slots to minimize these delays. OAI doesn't expose these knobs yet.

Q10: "What was the most challenging debugging issue you faced?"

The Msg3 failure with OAI and the B210. The UE would sync, send PRACH, get an RAR, but Msg3 (the first PUSCH carrying RRC Setup Request) would consistently fail. I traced it to a timing advance issue specific to USB-connected SDRs — the B210's round-trip delay over USB3 was out of spec for the default TA calculation. Increasing sl_ahead from 2 to 4 gave the softmodem enough TX preparation time to align properly. I also had to increase the PRACH detection threshold to avoid false negatives.

Q11: "How does Carrier Aggregation show up in RRC messages?"

CA appears as SCell addition/modification/release in RRC Reconfiguration. In my 100 MB download capture, I saw 103 RRC messages in 157 seconds — many of them were the network adding an SCell when throughput demand spiked and removing it during quiet periods. The EPS Bearer IDs sometimes swapped between DRBs during SCell activation (e.g., DRB-3 EPS went from 6→5 and DRB-4 from 5→6), which is normal as the network re-routes traffic paths.

Q12: "Explain the 5G core control plane signaling flow for UE registration."

The UE sends a Registration Request to the AMF. AMF contacts AUSF for authentication (which uses UDM/UDR for subscriber credentials). After successful auth, AMF sends a Registration Accept. For data, the UE requests a PDU Session — AMF forwards this to SMF, which selects a UPF and establishes the GTP-U tunnel. SMF also interacts with PCF for policy rules. In my K3s stress tests, I specifically tested UE churn (rapid register/deregister) to stress the AMF→AUSF→UDM signaling chain.

Q13: "What would you do differently if you had more time?"

Three things: First, I'd integrate Grafana + Prometheus for real-time visualization instead of CSV-based benchmarking. Second, I'd extend the UE automation to capture MobileInsight Layer 2 logs (MAC and RLC PDUs) alongside logcat, giving me PHY-layer visibility. Third, I'd test with the srsRAN low-latency fork end-to-end and compare user-plane latency head-to-head with OAI under identical TDD and scheduling configurations.


💡 General Interview Tips

  1. Lead with impact, not process. Start with "I achieved 12 ms RTT" not "I edited a config file."
  2. Use numbers. "15× CPU increase," "20 UEs," "180 pings with 0% loss" — concrete numbers are memorable.
  3. Show you understand trade-offs. "UM gives low latency but no reliability; AM gives reliability but adds delay."
  4. Mention the spec. Saying "per 3GPP TS 36.331" or "QCI 1 bearer" shows you're grounded in standards.
  5. Admit limitations honestly. "12 ms is not sub-1 ms URLLC — the B210 USB interface is the bottleneck. An N310 with 10 GbE would do better."
  6. Connect to real-world use cases. "This kind of testing is exactly what operators do before launching a URLLC slice for industrial IoT or remote surgery."

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors