Fixes and updates for taps client rewrite

This commit is contained in:
Nima Chaharba
2026-05-06 17:18:35 +02:00
parent 040d8785ea
commit 052b774354
20 changed files with 363 additions and 17 deletions

View File

@@ -138,11 +138,16 @@ ID = GNB_PHY_UL_PAYLOAD_RX_BITS
ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE
DESC = gNodeB channel estimation in the frequency domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_f
FORMAT = int,gNB_ID : int,rnti : int,frame : int,zero : int,ant : int,p_ind : buffer,chest_f
ID = GNB_PHY_UL_TIME_CHANNEL_ESTIMATE
DESC = gNodeB channel estimation in the time domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_t
ID = GNB_PHY_SRS_LS_CH_ESTIMATE
DESC = gNB SRS LS channel estimation (frequency domain)
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,ant : int,port : int,symbol : buffer,srs_ch
ID = GNB_PHY_UL_SNR_ESTIMATE
DESC = gNodeB SNR estimation based on SRS
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB

Binary file not shown.

View File

View File

@@ -0,0 +1,76 @@
# live_srs.py
import socket, struct, numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
HOST, PORT = '127.0.0.1', 2021
ofdm_size = 2048
target_id = 33 # GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()
lines = []
for i, ax in enumerate(axes):
line, = ax.plot([], [], 'b-', linewidth=0.8)
ax.set_xlim(0, ofdm_size)
ax.set_ylim(0, 600)
ax.set_title(f'RX Antenna {i} — SRS |H(f)|')
ax.set_xlabel('Subcarrier')
ax.set_ylabel('Magnitude')
ax.grid(True)
lines.append(line)
# Latest data per antenna
latest = {0: None, 1: None, 2: None, 3: None}
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.setblocking(False)
# Send activation message for our event
# T-tracer protocol: send "on EVENT_NAME\n"
sock.setblocking(True)
sock.send(b'on GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE\n')
sock.setblocking(False)
buf = b''
def recv_events():
global buf
try:
buf += sock.recv(65536)
except BlockingIOError:
return
while len(buf) >= 20:
# [8B ts][4B id][4B gnb_id][4B rnti][4B frame][4B ant][4B port][4B buflen][data]
if len(buf) < 36:
break
ev_id = struct.unpack_from('<I', buf, 8)[0]
if ev_id != target_id:
buf = buf[1:] # shouldn't happen but safety
continue
rx_ant = struct.unpack_from('<i', buf, 24)[0]
buf_len = struct.unpack_from('<I', buf, 32)[0]
total = 36 + buf_len
if len(buf) < total:
break
if buf_len > 0 and rx_ant in latest:
raw = buf[36:36+buf_len]
s = np.frombuffer(raw, dtype=np.int16)
I = s[0::2].astype(float)
Q = s[1::2].astype(float)
latest[rx_ant] = np.sqrt(I**2 + Q**2)
buf = buf[total:]
def update(frame):
recv_events()
for ant, line in enumerate(lines):
if latest[ant] is not None:
line.set_data(np.arange(ofdm_size), latest[ant])
return lines
ani = animation.FuncAnimation(fig, update, interval=100, blit=True)
plt.suptitle('Live SRS Channel Estimates — 4 RU Antenna Positions')
plt.tight_layout()
plt.show()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -805,6 +805,7 @@ int nr_srs_ls_channel_estimation(int ant,
srs_ls_estimated_channel[srs_symbol_offset + subcarrier + ktc] = ls_estimated;
}
#ifdef SRS_DEBUG
int subcarrier_log = subcarrier - subcarrier_offset;
if (subcarrier_log < 0) {
@@ -834,6 +835,16 @@ int nr_srs_ls_channel_estimation(int ant,
c16_t ch_estimates_time[ofdm_symbol_size] __attribute__((aligned(32)));
nr_est_delay(ofdm_symbol_size, srs_ls_estimated_channel, ch_estimates_time, delay);
}
#if T_TRACER
if (T_ACTIVE(T_GNB_PHY_SRS_LS_CH_ESTIMATE)) {
T(T_GNB_PHY_SRS_LS_CH_ESTIMATE,
T_INT(ant),
T_INT(p_index),
T_INT(srs_symb),
T_BUFFER(&srs_ls_estimated_channel[srs_symb * ofdm_symbol_size],
ofdm_symbol_size * sizeof(c16_t)));
}
#endif
} // for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++)
return 0;
@@ -1081,6 +1092,7 @@ int nr_srs_channel_interpolation(int ant,
LOG_W(NR_PHY, "Received SRS signal power is 0\n");
return -1;
}
return 0;
}

View File

@@ -41,7 +41,7 @@
// Simulator role
typedef enum { ROLE_SERVER = 1, ROLE_CLIENT } role;
#define MAX_NUM_ANTENNAS_TX 4
#define MAX_NUM_ANTENNAS_TX 8
#define SAVED_SAMPLES_LEN 256
#define MAX_NUM_UES MAX_MOBILES_PER_GNB
@@ -397,11 +397,12 @@ static int vrtsim_connect(openair0_device_t *device)
if (vrtsim_state->role == ROLE_SERVER) {
parse_ue_config(vrtsim_state);
compute_ue_antenna_offsets(vrtsim_state);
int num_tx_streams = 0;
/////////////////////////// next line changed from = 0
int num_tx_streams = device->openair0_cfg[0].rx_num_channels;
int num_rx_streams = vrtsim_state->num_ues * device->openair0_cfg[0].rx_num_channels;
for (int i = 0; i < vrtsim_state->num_ues; i++) {
num_tx_streams += vrtsim_state->ue_conf[i].rx_ant;
}
//for (int i = 0; i < vrtsim_state->num_ues; i++) {
//num_tx_streams += vrtsim_state->ue_conf[i].rx_ant;
//}
vrtsim_state->channel =
shm_td_iq_channel_create(DEFAULT_CHANNEL_NAME, num_tx_streams, num_rx_streams);
LOG_A(HW, "vrtsim created a shm_td_iq_channel with config tx: %d rx: %d\n", num_tx_streams, num_rx_streams);
@@ -833,15 +834,27 @@ static int vrtsim_read(openair0_device_t *device, openair0_timestamp_t *ptimesta
}
} else {
/* Single-UE server UL read */
int ret = shm_td_iq_channel_rx(vrtsim_state->channel, vrtsim_state->last_received_sample, nsamps, 0, samplesVoid[0]);
if (ret == CHANNEL_ERROR_TOO_LATE) {
vrtsim_state->rx_samples_late += nsamps;
} else if (ret == CHANNEL_ERROR_TOO_EARLY) {
vrtsim_state->rx_early += 1;
}
for (int aarx = 1; aarx < nbAnt; aarx++) {
if (samplesVoid[aarx] != NULL)
memcpy(samplesVoid[aarx], samplesVoid[0], nsamps * sizeof(sample_t));
//int ret = shm_td_iq_channel_rx(vrtsim_state->channel, vrtsim_state->last_received_sample, nsamps, 0, samplesVoid[0]);
//if (ret == CHANNEL_ERROR_TOO_LATE) {
//vrtsim_state->rx_samples_late += nsamps;
//} else if (ret == CHANNEL_ERROR_TOO_EARLY) {
//vrtsim_state->rx_early += 1;
//}
//for (int aarx = 1; aarx < nbAnt; aarx++) {
// if (samplesVoid[aarx] != NULL)
// memcpy(samplesVoid[aarx], samplesVoid[0], nsamps * sizeof(sample_t));
//}
/////added by nima
for (int aarx = 0; aarx < nbAnt; aarx++) {
int ret = shm_td_iq_channel_rx(vrtsim_state->channel,
vrtsim_state->last_received_sample,
nsamps,
aarx, // stream per antenna, not always 0
samplesVoid[aarx]);
if (ret == CHANNEL_ERROR_TOO_LATE)
vrtsim_state->rx_samples_late += nsamps;
else if (ret == CHANNEL_ERROR_TOO_EARLY)
vrtsim_state->rx_early += 1;
}
}
} else {

14
taps.fbs Normal file
View File

@@ -0,0 +1,14 @@
// This file defines the structure of the Taps table used in the PHY layer.
namespace Phy;
// Taps form the discrete complex baseband-equivalent channel impulse response and can be used
// to model the channel characteristics in link layer simulations.
table Taps {
id:uint;
num_tx_antennas:uint;
num_rx_antennas:uint;
taps_len:uint;
taps:[float];
}
root_type Taps;

View File

@@ -0,0 +1,219 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
nr_cellid = 12345678L;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pdsch_AntennaPorts_N1 = 2;
pdsch_AntennaPorts_N2 = 2;
pusch_AntennaPorts = 8;
maxMIMO_layers = 1;
do_CSIRS = 0;
do_SRS = 1;
#uess_agg_levels = [0,1,2,2,1]
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "172.21.6.4"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.117/24";
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.117/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 8;
nb_rx = 8;
att_tx = 12;
att_rx = 12;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "internal";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = 4043;
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};
e2_agent = {
near_ric_ip_addr = "127.0.0.1";
#sm_dir = "/path/where/the/SMs/are/located/"
sm_dir = "/usr/local/lib/flexric/"
};

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
uicc0 = {
imsi = "2089900007487";
imsi = "001010000000001";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
pdu_sessions = ({ dnn = "oai"; nssai_sst = 1; });

View File

@@ -0,0 +1,7 @@
uicc0 = {
imsi = "001010000000001";
key= "8BAF473F2F8FD09487CCCBD7097C6862";
opc= "8e27b6af0e692e750f32667a3b14605d";
dnn= "internet";
nssai_sst=1;
}