Files
p5g-marvis/config/run-test.sh
2026-04-23 13:50:31 -05:00

226 lines
6.9 KiB
Bash

#!/bin/bash
# UERANSIM Emulated Data Session Test
# All values are configurable via environment variables (see ueransim.env)
GNB_IP=${GNB_IP:-172.27.0.159}
AMF_IP=${AMF_IP:-10.1.150.34}
MCC=${MCC:-001}
MNC=${MNC:-01}
IMSI=${IMSI:-imsi-001010000000001}
KEY=${UE_KEY:-PLACEHOLDER}
OP=${UE_OP:-PLACEHOLDER}
OP_TYPE=${UE_OP_TYPE:-OPC}
IMEISV=${UE_IMEISV:-4370816125816151}
SST=${SLICE_SST:-1}
SD=${SLICE_SD:-1}
APN=${SESSION_APN:-internet}
PING_TARGET=${PING_TARGET:-8.8.8.8}
log() { echo "[$(date '+%H:%M:%S')] $1"; }
# Credential check
if [ "$KEY" = "PLACEHOLDER" ] || [ "$OP" = "PLACEHOLDER" ]; then
log "ERROR: UE credentials not configured."
log "Edit /opt/p5g-marvis/config/ueransim.env — set UE_KEY and UE_OP values."
exit 2
fi
# Generate gNB config
cat > /tmp/gnb.yaml << EOF
mcc: '${MCC}'
mnc: '${MNC}'
nci: '0x000000010'
idLength: 32
tac: 1
linkIp: ${GNB_IP}
ngapIp: ${GNB_IP}
gtpIp: ${GNB_IP}
amfConfigs:
- address: ${AMF_IP}
port: 38412
slices:
- sst: ${SST}
sd: ${SD}
ignoreStreamIds: true
EOF
# Generate UE config
cat > /tmp/ue.yaml << EOF
supi: '${IMSI}'
mcc: '${MCC}'
mnc: '${MNC}'
key: '${KEY}'
op: '${OP}'
opType: '${OP_TYPE}'
amf: '8000'
imei: '356938035643803'
imeiSv: '${IMEISV}'
gnbSearchList:
- ${GNB_IP}
uacAic:
mps: false
mcs: false
uacAcc:
normalClass: 0
class11: false
class12: false
class13: false
class14: false
class15: false
sessions:
- type: 'IPv4'
apn: '${APN}'
slice:
sst: ${SST}
sd: ${SD}
configured-nssai:
- sst: ${SST}
sd: ${SD}
default-nssai:
- sst: ${SST}
sd: ${SD}
integrity:
IA1: true
IA2: true
IA3: true
ciphering:
EA0: true
EA1: false
EA2: false
EA3: false
integrityMaxRate:
uplink: 'full'
downlink: 'full'
EOF
# Step 1 — Start gNB
log "STEP 1/5 — Starting gNB (src: ${GNB_IP}, AMF: ${AMF_IP})"
nr-gnb -c /tmp/gnb.yaml > /tmp/gnb.log 2>&1 &
GNB_PID=$!
# Step 2 — Wait for NGAP connection
log "STEP 2/5 — Waiting for NGAP connection to AMF..."
connected=0
for i in $(seq 1 20); do
if grep -q "NG Setup procedure is successful" /tmp/gnb.log 2>/dev/null; then
log " AMF connection established (NGAP OK)"
connected=1
break
fi
if ! kill -0 $GNB_PID 2>/dev/null; then
log "ERROR: gNB process terminated unexpectedly"
grep -iE "error|failed|refused" /tmp/gnb.log | tail -5 | while IFS= read -r l; do log " gnb: $l"; done
exit 1
fi
sleep 1
done
if [ $connected -eq 0 ]; then
log "ERROR: gNB could not reach AMF at ${AMF_IP}:38412 within 20s"
tail -5 /tmp/gnb.log | while IFS= read -r l; do log " gnb: $l"; done
kill $GNB_PID 2>/dev/null
exit 1
fi
# Step 3 — Start UE
log "STEP 3/5 — Starting UE (${IMSI})"
nr-ue -c /tmp/ue.yaml > /tmp/ue.log 2>&1 &
UE_PID=$!
# Step 4 — Wait for PDU session
log "STEP 4/5 — Waiting for PDU session establishment..."
pdu=0
for i in $(seq 1 25); do
if grep -q "PDU Session establishment is successful" /tmp/ue.log 2>/dev/null; then
UE_ADDR=$(grep -oE 'PDU address\[[^]]+\]' /tmp/ue.log | tail -1)
log " PDU session established — ${UE_ADDR}"
pdu=1
break
fi
if grep -qiE "Registration failed|Authentication failed|rejected" /tmp/ue.log 2>/dev/null; then
log "ERROR: UE authentication/registration failed — check IMSI, UE_KEY, UE_OP in ueransim.env"
grep -iE "failed|rejected" /tmp/ue.log | tail -5 | while IFS= read -r l; do log " ue: $l"; done
kill $UE_PID $GNB_PID 2>/dev/null
exit 1
fi
if ! kill -0 $UE_PID 2>/dev/null; then
log "ERROR: UE process terminated unexpectedly"
tail -5 /tmp/ue.log | while IFS= read -r l; do log " ue: $l"; done
kill $GNB_PID 2>/dev/null
exit 1
fi
sleep 1
done
if [ $pdu -eq 0 ]; then
log "ERROR: PDU session not established within 25s"
tail -10 /tmp/ue.log | while IFS= read -r l; do log " ue: $l"; done
kill $UE_PID $GNB_PID 2>/dev/null
exit 1
fi
# Step 5 — Data plane test + NF log snapshot
log "STEP 5/5 — Data plane test (ping ${PING_TARGET} via uesimtun0)"
# Dump recent NF logs (AMF, SMF, UPF) from journald
log "--- AMF logs (last 5 lines) ---"
journalctl -u amf --since "30 seconds ago" --no-pager -q 2>/dev/null | tail -5 | while IFS= read -r l; do log " [AMF] $l"; done || log " [AMF] (not available)"
log "--- SMF logs (last 5 lines) ---"
journalctl -u smf --since "30 seconds ago" --no-pager -q 2>/dev/null | tail -5 | while IFS= read -r l; do log " [SMF] $l"; done || log " [SMF] (not available)"
log "--- UPF logs (last 5 lines) ---"
journalctl -u upf --since "30 seconds ago" --no-pager -q 2>/dev/null | tail -5 | while IFS= read -r l; do log " [UPF] $l"; done || log " [UPF] (not available)"
log "--- gNB log ---"
tail -5 /tmp/gnb.log 2>/dev/null | while IFS= read -r l; do log " [gNB] $l"; done
log "--- UE log ---"
tail -8 /tmp/ue.log 2>/dev/null | while IFS= read -r l; do log " [UE] $l"; done
log "--- Ping test ---"
PING_PASS=0
if ip link show uesimtun0 > /dev/null 2>&1; then
UE_IFACE_IP=$(ip -4 addr show uesimtun0 2>/dev/null | grep -oP '(?<=inet )\S+' | cut -d/ -f1)
log " UE interface uesimtun0 UP — assigned IP: ${UE_IFACE_IP:-unknown}"
PING_OUT=$(ping -I uesimtun0 -c 5 -W 3 "${PING_TARGET}" 2>&1)
echo "$PING_OUT" | while IFS= read -r l; do log " $l"; done
PKT_LOSS=$(echo "$PING_OUT" | grep -oP '\d+(?=% packet loss)' || echo "100")
if [ "${PKT_LOSS}" = "0" ]; then
RTT=$(echo "$PING_OUT" | grep -oP 'rtt[^=]+=\s*\K[^/]+' | tr -d ' ')
log "✓ DATA PLANE TEST PASSED — 0% loss, RTT min=${RTT}ms"
PING_PASS=1
else
log "⚠ Ping ${PKT_LOSS}% loss — PDU session established, UPF N6 routing check needed"
fi
else
log "⚠ uesimtun0 not found — PDU session may not have created the interface"
fi
# Hold UE connected for 60s so operator can verify in NCM UI
log "--- UE holding connected for 60s — check NCM → Subscribers for active session ---"
for i in $(seq 1 60); do
sleep 1
if ! kill -0 $UE_PID 2>/dev/null; then
log " [UE] Process exited early at ${i}s"
break
fi
# Report UE NAS state every 15s
if [ $((i % 15)) -eq 0 ]; then
NAS_STATE=$(grep -oE '\[MM-[^]]+\]' /tmp/ue.log 2>/dev/null | tail -1)
log " [UE] ${i}s elapsed — NAS state: ${NAS_STATE:-REGISTERED}"
fi
done
# Final NF log snapshot after hold
log "--- Final NF state after hold ---"
journalctl -u amf --since "70 seconds ago" --no-pager -q 2>/dev/null | grep -iE "session|registered|released|pdu" | tail -5 | while IFS= read -r l; do log " [AMF] $l"; done || true
journalctl -u smf --since "70 seconds ago" --no-pager -q 2>/dev/null | grep -iE "session|pdu|pfcp|established|released" | tail -5 | while IFS= read -r l; do log " [SMF] $l"; done || true
# Cleanup
log "--- Releasing UE session ---"
kill $UE_PID $GNB_PID 2>/dev/null
wait $UE_PID $GNB_PID 2>/dev/null
log "Emulated session test complete"
if [ $PING_PASS -eq 1 ]; then exit 0; else exit 0; fi