Compare commits

...

25 Commits

Author SHA1 Message Date
Mohsen Ahadi
0cc0600062 enable SRS_CH_EST 2025-04-29 14:30:22 +02:00
ahadi
072f5707f4 srs ch est update 2024-08-08 11:30:43 +02:00
ahadi
72ec247fbc fixing the memcpy 2024-08-01 16:37:55 +02:00
ahadi
f360e9df02 updating timing_advance_offset_nsec 2024-07-30 16:43:46 +02:00
ahadi
10aa2a26dc averaging over multi srs symbols 2024-07-25 17:19:27 +02:00
ahadi
1e953cf83d fix typo 2024-07-15 16:01:07 +02:00
ahadi
abec430659 modifying toa_ns func 2024-07-12 16:15:22 +02:00
ahadi
24993a2232 updating srs toa ns 2024-07-11 19:25:55 +02:00
Adeel Malik
6d8baef0ca adding peak_val over mqtt 2024-07-08 18:17:30 +02:00
ahadi
f027875712 updating mqtt 2024-07-08 17:10:54 +02:00
Raymond Knopp
371264ba6f mqtt for vvdn 2024-06-26 15:40:27 +02:00
Raymond Knopp
07b6c48d5d bugfixes 2024-06-26 11:54:08 +02:00
Raymond Knopp
319d22fa59 bugfix 2024-06-26 11:21:28 +02:00
ahadi
d49bf5d26b adding trp_id to mqtt 2024-06-26 11:21:28 +02:00
ahadi
ace6a7ee59 updating toa mqtt 2024-06-26 11:21:28 +02:00
ahadi
98f9bb3a00 adding toa to mqtt 2024-06-26 11:21:28 +02:00
Raymond Knopp
c78e0efc35 declaring mqtt func 2024-06-26 11:21:28 +02:00
ahadi
14e3325ada adding mqtt to gnb 2024-06-26 11:21:28 +02:00
Raymond Knopp
68aafa2dfc sending srs_toa_ns to T tracer 2024-06-25 17:36:50 +02:00
Florian Kaltenberger
8872b92203 adding log for SRS power 2024-06-25 14:36:24 +02:00
Raymond Knopp
dcb17aa793 adding missing @ifdef 2024-06-21 20:56:38 +02:00
Florian Kaltenberger
bb91461aff fixing a bug in nr_est_timing_advance_srs 2024-06-21 14:21:19 -04:00
Florian Kaltenberger
3dd1929308 bugfix 2024-06-21 14:19:30 -04:00
Florian Kaltenberger
1473726411 now computing toa in ns 2024-06-21 14:19:17 -04:00
Florian Kaltenberger
4dc27e8305 reworking ToA estimation 2024-06-21 14:12:55 -04:00
13 changed files with 523 additions and 129 deletions

View File

@@ -2097,6 +2097,7 @@ target_link_libraries(nr-softmodem PRIVATE
x2ap f1ap m2ap m3ap e1ap shlib_loader
-Wl,--end-group z dl)
target_link_libraries(nr-softmodem PRIVATE paho-mqtt3c cjson)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)

View File

@@ -114,6 +114,10 @@ ID = GNB_PHY_DL_OUTPUT_SIGNAL
DESC = gNodeB output data in the freq domain for slots
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,frame : int,slot : int,antenna : buffer,txdata
ID = GNB_PHY_UL_SRS_TOA_NS
DESC = gNB ToA estimate from SRS (in ns)
GROUP = ALL:PHY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : buffer,toa_ns
#MAC logs
ID = ENB_MAC_UE_DL_SDU

View File

@@ -1253,7 +1253,23 @@ void *ru_thread( void *param ) {
//slot_duration.tv_nsec = 0.5e6;
slot_duration.tv_nsec = 0.5e6;
int rc;
extern MQTTClient client;
#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "Gnb1"
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) {
printf("Failed to create MQTT client %s, return code %d\n", CLIENTID, rc);
exit(EXIT_FAILURE);
}
conn_opts.keepAliveInterval = 60;
conn_opts.cleansession = 1;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS){
printf("Failed to create MQTT client %s, return code %d\n", CLIENTID, rc);
exit(EXIT_FAILURE);
}
while (!oai_exit) {
@@ -1407,11 +1423,14 @@ void *ru_thread( void *param ) {
}
printf( "Exiting ru_thread \n");
if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
printf("Failed to disconnect MQTT client %s, return code %d\n", CLIENTID, rc);
ru_thread_status = 0;
return &ru_thread_status;
}
ru_thread_status = 0;
return &ru_thread_status;
}
int start_streaming(RU_t *ru) {
LOG_I(PHY,"Starting streaming on third-party RRU\n");
return(ru->ifdevice.thirdparty_startstreaming(&ru->ifdevice));

View File

@@ -86,7 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h"
#endif
MQTTClient client;
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex

View File

@@ -40,7 +40,7 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "openair2/COMMON/mqtt_paramdef.h"
int l1_north_init_gNB() {
@@ -321,7 +321,24 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
* sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
pusch->ul_valid_re_per_slot = (int16_t *)malloc16_clear(sizeof(int16_t) * fp->symbols_per_slot);
} // ulsch_id
/*
paramlist_def_t MqttParamList = {CONFIG_STRING_MQTT_CONFIG,NULL,0};
paramdef_t MqttParams[] = MQTT_PARAMS_DESC;
config_getlist(&MqttParamList,MqttParams,sizeof(MqttParams)/sizeof(paramdef_t), NULL);
if(MqttParamList.numelt>0){
gNB->mqtt_cfg.MqttBrokerAddr = *(MqttParamList.paramarray[0][MQTT_BROKER_ADDR_IDX].strptr);
gNB->mqtt_cfg.MqttTopicName = *(MqttParamList.paramarray[0][MQTT_TOPIC_NAME_IDX].strptr);
gNB->mqtt_cfg.MqttClientId = *(MqttParamList.paramarray[0][MQTT_CLIENT_ID_IDX].strptr);
gNB->mqtt_cfg.MqttTrpId = *(MqttParamList.paramarray[0][MQTT_TRP_ID_IDX].uptr);
}
LOG_I(PHY, "MQTT Config\n");
LOG_I(PHY, "-----------------------------------------\n");
LOG_I(PHY, "MqttBrokerAddr %s\n", gNB->mqtt_cfg.MqttBrokerAddr);
LOG_I(PHY, "MqttTopicName %s\n", gNB->mqtt_cfg.MqttTopicName);
LOG_I(PHY, "MqttClientId %s\n", gNB->mqtt_cfg.MqttClientId);
LOG_I(PHY, "MqttTrpId %d\n", gNB->mqtt_cfg.MqttTrpId);
LOG_I(PHY, "-----------------------------------------\n");
*/
return (0);
}

View File

@@ -38,14 +38,15 @@
extern openair0_config_t openair0_cfg[MAX_CARDS];
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) {
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const uint8_t N_ap_srs,
const int32_t srs_estimated_channel_time[N_ap_srs][frame_parms->ofdm_symbol_size]) {
int timing_advance = 0;
int max_val = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
int temp = 0;
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
for (int aa = 0; aa < N_ap_srs; aa++) {
int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r;
int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i;
temp += (Re*Re/2) + (Im*Im/2);

View File

@@ -21,7 +21,7 @@
#include <string.h>
#include <math.h>
#include "nr_ul_estimation.h"
#include "PHY/sse_intrin.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
@@ -35,6 +35,18 @@
#include "executables/softmodem-common.h"
#include "nr_phy_common.h"
/*
#include <stdio.h>
#include <stdlib.h>
#include "cjson/cJSON.h"
#include "MQTTClient.h"
#define QOS 1
#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "Gnb1"
*/
#define ADDRESS "tcp://172.21.16.204:1883"
#define TOPIC "srs_toa_ns"
#define SRS_CH_EST
//#define DEBUG_CH
//#define DEBUG_PUSCH
@@ -42,6 +54,217 @@
#define NO_INTERP 1
#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y)))
#define NR_SRS_IDFT_OVERSAMP_FACTOR 8
extern MQTTClient client;
//void srs_toa_MQTT(int32_t *buffer, int32_t buf_len, int32_t gNB_id, int32_t peak_idx, int16_t ant_idx);
void srs_toa_MQTT(int32_t *buffer, int32_t buf_len, int16_t gNB_id, int16_t ant_idx);
/* Generic function to find the peak of channel estimation buffer */
int nr_est_toa_ns_srs(NR_DL_FRAME_PARMS *frame_parms,
uint8_t N_arx,
uint8_t N_ap,
uint8_t N_symb_srs,
int32_t srs_estimated_channel_freq[N_arx][N_ap][frame_parms->ofdm_symbol_size * N_symb_srs],
int32_t *srs_toa_ns)
{
int32_t chF_interpol[N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t chT_interpol[N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t chT_interpol_mag_squ_avg[NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(chF_interpol,0,sizeof(chF_interpol));
memset(chT_interpol,0,sizeof(chT_interpol));
int32_t max_val = 0, max_idx = 0, abs_val = 0, mean_val = 0;
int16_t start_offset = NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size - (frame_parms->ofdm_symbol_size>>1);
for (int arx_index = 0; arx_index < N_arx; arx_index++) {
memset(chT_interpol_mag_squ_avg,0,sizeof(chT_interpol_mag_squ_avg));
for (int symb = 0; symb < N_symb_srs; symb++){
for (int ap_index = 0; ap_index < N_ap; ap_index++) {
// Place SRS channel estimates in FFT shifted format for oversampling
memcpy((int16_t *)&chF_interpol[ap_index][0], &srs_estimated_channel_freq[arx_index][ap_index][symb*frame_parms->ofdm_symbol_size], (frame_parms->ofdm_symbol_size>>1) * sizeof(int32_t));
memcpy((int16_t *)&chF_interpol[ap_index][start_offset], &srs_estimated_channel_freq[arx_index][ap_index][symb*frame_parms->ofdm_symbol_size + (frame_parms->ofdm_symbol_size>>1)], (frame_parms->ofdm_symbol_size>>1) * sizeof(int32_t));
// Convert to time domain oversampled
freq2time(frame_parms->ofdm_symbol_size*NR_SRS_IDFT_OVERSAMP_FACTOR,
(int16_t*) chF_interpol[ap_index],
(int16_t*) chT_interpol[ap_index]);
for(int k = 0; k < NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size; k++) {
chT_interpol_mag_squ_avg[k] += squaredMod(((c16_t*)chT_interpol[ap_index])[k]);
} // Loop over samples
} // antenna port loop
} // SRS OFDM symbol loop
// average over SRS symbols
for(int k = 0; k < NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size; k++) {
chT_interpol_mag_squ_avg[k] /= N_symb_srs;
}
max_val = 0, max_idx = 0, mean_val = 0;
for(int k = 0; k < NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size; k++) {
abs_val = chT_interpol_mag_squ_avg[k];
mean_val += (abs_val - mean_val)/(k+1);
if(abs_val > max_val) {
max_val = abs_val;
max_idx = k;
}
}
if(max_idx > NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size >>1)
max_idx = max_idx - NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size;
// Check for detection threshold
//LOG_I(PHY, "SRS ToA before (RX ant %d): max_val %d, mean_val %d, max_idx %d\n", arx_index, max_val, mean_val, max_idx);
if ((mean_val != 0) && (max_val / mean_val > 100)) {
srs_toa_ns[arx_index] = (max_idx*1e9)/(NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->samples_per_frame*100);
} else {
srs_toa_ns[arx_index] = 0xFFFF;
}
//LOG_I(PHY, "SRS ToA estimator (RX ant %d): toa %d ns\n",arx_index,srs_toa_ns[arx_index]);
} // Antenna loop
// Add T tracer to log these chF and chT
/*
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE_OVER_SAMPLING,
T_INT(0),
T_INT(srs_pdu->rnti),
T_INT(frame),
T_INT(0),
T_INT(0),
T_BUFFER(chF_interpol[0][0], NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size * sizeof(int32_t)));
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE_OVER_SAMPLING,
T_INT(0),
T_INT(srs_pdu->rnti),
T_INT(frame),
T_INT(0),
T_INT(0),
T_BUFFER(chT_interpol[0][0], NR_SRS_IDFT_OVERSAMP_FACTOR*frame_parms->ofdm_symbol_size * sizeof(int32_t)));
*/
return 0;
}
void fftshift(int32_t *buffer, int32_t buf_len) {
int half = buf_len / 2;
for (int i = 0; i < half; i++) {
c16_t temp = ((c16_t*)buffer)[i];
((c16_t*)buffer)[i] = ((c16_t*)buffer)[i + half];
((c16_t*)buffer)[i + half] = temp;
}
}
/*
void srs_toa_MQTT(int32_t *buffer, int32_t buf_len, int32_t gNB_id, int32_t peak_idx, int16_t ant_idx) {
// MQTT Part
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
cJSON *mqtt_payload = cJSON_CreateObject();
cJSON_AddNumberToObject(mqtt_payload, "peak_index", peak_idx);
cJSON_AddNumberToObject(mqtt_payload, "source", gNB_id);
cJSON_AddNumberToObject(mqtt_payload, "antenna_index", ant_idx);
// PUBLISHING the Message
pubmsg.payload = cJSON_Print(mqtt_payload);
pubmsg.payloadlen = (int)strlen(pubmsg.payload);
pubmsg.qos = 0;
pubmsg.retained = 0;
// MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token) ) != MQTTCLIENT_SUCCESS){
LOG_W(PHY, "Failed to publish \"SRS ToA measurements\" MQTT message, return code %d\n", rc);
}
}
*/
void srs_toa_MQTT(int32_t *buffer, int32_t buf_len, int16_t gNB_id, int16_t ant_idx) {
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
int16_t peak_idx = 0;
int16_t peak_val = 0;
cJSON *mqtt_payload = cJSON_CreateObject();
cJSON_AddNumberToObject(mqtt_payload, "peak_index", peak_idx);
cJSON_AddNumberToObject(mqtt_payload, "peak_val", peak_val);
cJSON_AddNumberToObject(mqtt_payload, "source", gNB_id);
cJSON_AddNumberToObject(mqtt_payload, "antenna_index", ant_idx);
#ifdef SRS_CH_EST
cJSON *chest_json = cJSON_AddArrayToObject(mqtt_payload, "ch_est_T");
// Temporary array to hold channel estimation values
int32_t chest_tmp[buf_len];
#endif
fftshift(buffer, buf_len);
// Peak calculation
int32_t max_val = 0, max_idx = 0, abs_val = 0;
for (int k = 0; k < buf_len; k++) {
int Re = ((c16_t*)buffer)[k].r;
int Im = ((c16_t*)buffer)[k].i;
abs_val = (Re * Re / 2) + (Im * Im / 2);
if (abs_val > max_val) {
max_val = abs_val;
max_idx = k;
}
#ifdef SRS_CH_EST
chest_tmp[k] = abs_val; // Save to temp array
#endif
}
peak_idx = max_idx;
peak_val = max_val;
printf("ant=%d , peak=%d\n", ant_idx, peak_idx);
cJSON_SetIntValue(cJSON_GetObjectItem(mqtt_payload, "peak_index"), peak_idx);
cJSON_SetIntValue(cJSON_GetObjectItem(mqtt_payload, "peak_val"), peak_val);
#ifdef SRS_CH_EST
// Circular shift of chest_tmp
int shift = 2098;
int real_size = buf_len;
int32_t chest_shifted[real_size];
for (int i = 0; i < real_size; i++) {
chest_shifted[i] = chest_tmp[(i - shift + real_size) % real_size];
}
int chest_size = 100;
for (int i = 0; i < chest_size; i++) {
cJSON_AddItemToArray(chest_json, cJSON_CreateNumber(chest_shifted[i]));
}
#endif
pubmsg.payload = cJSON_PrintUnformatted(mqtt_payload);
pubmsg.payloadlen = (int)strlen(pubmsg.payload);
pubmsg.qos = 0;
pubmsg.retained = 0;
if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) {
LOG_W(PHY, "Failed to publish \"SRS ToA measurements\" MQTT message, return code %d\n", rc);
}
cJSON_Delete(mqtt_payload);
}
__attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *in1,
int *offset1,
@@ -679,116 +902,120 @@ int nr_srs_channel_estimation(
LOG_I(NR_PHY,"====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
#endif
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
// Estimate the SRS channel over all OFDM symbols
for (int srs_symb = 0; srs_symb<(1<<srs_pdu->num_symbols); srs_symb++) {
uint16_t srs_symbol_offset =srs_symb*frame_parms->ofdm_symbol_size;
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier + mem_offset];
int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier + srs_symbol_offset + mem_offset];
for (int k = 0; k < M_sc_b_SRS; k++) {
for (int k = 0; k < M_sc_b_SRS; k++) {
if (k%fd_cdm==0) {
if (k%fd_cdm==0) {
ls_estimated[0] = 0;
ls_estimated[1] = 0;
uint16_t subcarrier_cdm = subcarrier;
ls_estimated[0] = 0;
ls_estimated[1] = 0;
uint16_t subcarrier_cdm = subcarrier;
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm + srs_symbol_offset].r;
int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm + srs_symbol_offset].i;
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r;
int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i;
int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm + srs_symbol_offset].r;
int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm + srs_symbol_offset].i;
int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r;
int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i;
// We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag.
// So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits.
ls_estimated[0] += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits);
ls_estimated[1] += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits);
// We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag.
// So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits.
ls_estimated[0] += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits);
ls_estimated[1] += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits);
// Subcarrier increment
subcarrier_cdm += K_TC;
if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) {
subcarrier_cdm=subcarrier_cdm-frame_parms->ofdm_symbol_size;
// Subcarrier increment
subcarrier_cdm += K_TC;
if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) {
subcarrier_cdm=subcarrier_cdm-frame_parms->ofdm_symbol_size;
}
}
}
}
srs_ls_estimated_channel[subcarrier].r = ls_estimated[0];
srs_ls_estimated_channel[subcarrier].i = ls_estimated[1];
srs_ls_estimated_channel[subcarrier + srs_symbol_offset].r = ls_estimated[0];
srs_ls_estimated_channel[subcarrier + srs_symbol_offset].i = ls_estimated[1];
#ifdef SRS_DEBUG
int subcarrier_log = subcarrier-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,"------------------------------------ %d ------------------------------------\n", subcarrier_log/12);
LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n");
}
LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
subcarrier_log,
((c16_t*)srs_generated_signal[p_index])[subcarrier].r, ((c16_t*)srs_generated_signal[p_index])[subcarrier].i,
((c16_t*)srs_received_signal[ant])[subcarrier].r, ((c16_t*)srs_received_signal[ant])[subcarrier].i,
ls_estimated[0], ls_estimated[1]);
#endif
const uint16_t sc_offset = subcarrier + mem_offset;
// Channel interpolation
if(srs_pdu->comb_size == 0) {
if(k == 0) { // First subcarrier case
// filt8_start is {12288,8192,4096,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8);
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
// filt8_start is {12288,8192,4096,0,0,0,0,0}
srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier];
const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2;
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
// filt8_end is {4096,8192,12288,16384,0,0,0,0}
const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2;
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
} else if(k%2 == 1) { // 1st middle case
// filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0}
multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8);
} else if(k%2 == 0) { // 2nd middle case
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8);
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
#ifdef SRS_DEBUG
int subcarrier_log = subcarrier-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
} else {
if(k == 0) { // First subcarrier case
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16);
} else { // Middle case
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16);
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,"------------------------------------ %d ------------------------------------\n", subcarrier_log/12);
LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n");
}
}
LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
subcarrier_log,
((c16_t*)srs_generated_signal[p_index])[subcarrier].r, ((c16_t*)srs_generated_signal[p_index])[subcarrier].i,
((c16_t*)srs_received_signal[ant])[subcarrier].r, ((c16_t*)srs_received_signal[ant])[subcarrier].i,
ls_estimated[0], ls_estimated[1]);
#endif
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
const uint16_t sc_offset = subcarrier + mem_offset;
} // for (int k = 0; k < M_sc_b_SRS; k++)
// Channel interpolation
if(srs_pdu->comb_size == 0) {
if(k == 0) { // First subcarrier case
// filt8_start is {12288,8192,4096,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8);
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
// filt8_start is {12288,8192,4096,0,0,0,0,0}
srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier + srs_symbol_offset];
const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2;
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
// filt8_end is {4096,8192,12288,16384,0,0,0,0}
const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2;
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
} else if(k%2 == 1) { // 1st middle case
// filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0}
multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8);
} else if(k%2 == 0) { // 2nd middle case
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8);
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset + srs_symbol_offset];
}
} else {
if(k == 0) { // First subcarrier case
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset + srs_symbol_offset];
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16);
} else { // Middle case
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16);
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset + srs_symbol_offset];
}
}
memcpy(&srs_estimated_channel_freq[ant][p_index][0],
&srs_est[mem_offset],
(frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols))*sizeof(int32_t));
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
} // for (int k = 0; k < M_sc_b_SRS; k++)
} // for (int srs_symb = 0; srs_symb<(1<<srs_pdu->num_symbols); srs_symb++)
memcpy(&srs_estimated_channel_freq[ant][p_index][0],
&srs_est[mem_offset],
((1<<srs_pdu->num_symbols)*frame_parms->ofdm_symbol_size)*sizeof(int32_t));
// Compute noise
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
@@ -804,6 +1031,15 @@ int nr_srs_channel_estimation(
}
}
// Compute signal power
uint32_t signal_power_ant = calc_power(&ch_real[base_idx], M_sc_b_SRS) + calc_power(&ch_imag[base_idx], M_sc_b_SRS);
//#ifdef SRS_DEBUG
LOG_D(NR_PHY,"signal_power(p_index %d, ant %d) = %d dB\n", p_index, ant, dB_fixed(signal_power_ant));
//#endif
#ifdef SRS_DEBUG
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier>frame_parms->ofdm_symbol_size) {
@@ -850,24 +1086,24 @@ int nr_srs_channel_estimation(
memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1],
&srs_estimated_channel_time[ant][p_index][0],
(gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t));
} // for (int p_index = 0; p_index < N_ap; p_index++)
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
// Compute signal power
uint32_t signal_power = calc_power(ch_real, arr_len) + calc_power(ch_imag, arr_len);
// Compute signal power
uint32_t signal_power = calc_power(ch_real, arr_len) + calc_power(ch_imag, arr_len);
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"signal_power = %u\n", signal_power);
LOG_I(NR_PHY,"signal_power(p_index %d, ant %d) = %d dB\n", p_index, ant, dB_fixed(signal_power));
#endif
if (signal_power == 0) {
LOG_W(NR_PHY, "Received SRS signal power is 0\n");
return -1;
}
if (signal_power == 0) {
LOG_W(NR_PHY, "Received SRS signal power is 0\n");
return -1;
}
// Compute noise power
const uint8_t signal_power_bits = log2_approx(signal_power);
const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x)
const int32_t factor_dB = dB_fixed(1<<factor_bits);
@@ -915,6 +1151,5 @@ int nr_srs_channel_estimation(
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", noise_power, *snr);
#endif
return 0;
}

View File

@@ -63,7 +63,18 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB,
uint8_t nrOfLayers);
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
uint8_t N_ap,
const int32_t srs_estimated_channel_time[N_ap][frame_parms->ofdm_symbol_size]);
//void srs_toa_MQTT(int32_t *buffer, int32_t buf_len, int32_t gNB_id, int32_t peak_idx, int16_t ant_idx);
void srs_toa_MQTT(int32_t *buffer, int32_t buf_len, int16_t gNB_id, int16_t ant_idx);
int nr_est_toa_ns_srs(NR_DL_FRAME_PARMS *frame_parms,
uint8_t N_arx,
uint8_t N_ap,
uint8_t N_symb_srs,
int32_t srs_estimated_channel_freq[N_arx][N_ap][frame_parms->ofdm_symbol_size * N_symb_srs],
int32_t *srs_toa_ns);
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,

View File

@@ -47,6 +47,10 @@
#define MAX_NUM_RU_PER_gNB 8
#define MAX_PUCCH0_NID 8
#include "MQTTClient.h"
#include "cjson/cJSON.h"
#define QOS 1
typedef struct {
int nb_id;
int Nid[MAX_PUCCH0_NID];
@@ -561,7 +565,7 @@ typedef struct PHY_VARS_gNB_s {
PHY_MEASUREMENTS_gNB measurements;
NR_IF_Module_t *if_inst;
NR_UL_IND_t UL_INFO;
mqtt_cfg_t mqtt_cfg;
/// NFAPI RX ULSCH information
nfapi_nr_rx_data_pdu_t rx_pdu_list[MAX_UL_PDUS_PER_SLOT];
/// NFAPI RX ULSCH CRC information

View File

@@ -114,6 +114,13 @@ typedef enum{
nr_ssb_type_E
} nr_ssb_type_e;
typedef struct {
char *MqttBrokerAddr;
char *MqttTopicName;
char *MqttClientId;
uint32_t MqttTrpId;
} mqtt_cfg_t;
typedef struct {
uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS];
uint8_t srs_generated_signal_bits;

View File

@@ -975,22 +975,25 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
srs_est = -1;
}
for (int ant_rx = 0; ant_rx < gNB->frame_parms.nb_antennas_rx; ant_rx++) {
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE,
T_INT(0),
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(0),
T_INT(0),
T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
T_INT(slot_rx),
T_INT(ant_rx),
T_BUFFER(srs_estimated_channel_freq[ant_rx][0], (N_symb_SRS * frame_parms->ofdm_symbol_size) * sizeof(int32_t)));
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE,
T_INT(0),
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(0),
T_INT(0),
T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
T_INT(slot_rx),
T_INT(ant_rx),
T_BUFFER(srs_estimated_channel_time_shifted[ant_rx][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
}
gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0];
gNB->UL_INFO.srs_ind.sfn = frame_rx;
gNB->UL_INFO.srs_ind.slot = slot_rx;
@@ -998,10 +1001,36 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
nfapi_nr_srs_indication_pdu_t *srs_indication = &gNB->srs_pdu_list[gNB->UL_INFO.srs_ind.number_of_pdus];
srs_indication->handle = srs_pdu->handle;
srs_indication->rnti = srs_pdu->rnti;
uint8_t N_ap = 1<<srs_pdu->num_ant_ports;
uint8_t N_ant_rx = gNB->frame_parms.nb_antennas_rx;
int32_t srs_toa_ns[N_ant_rx];
// call ToA estimation function
nr_est_toa_ns_srs(frame_parms, N_ant_rx, N_ap ,N_symb_SRS, srs_estimated_channel_freq, srs_toa_ns);
start_meas(&gNB->srs_timing_advance_stats);
srs_indication->timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF;
srs_indication->timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, N_ap, srs_estimated_channel_time[0]) : 0xFFFF;
stop_meas(&gNB->srs_timing_advance_stats);
srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? (int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) : 0xFFFF;
srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? srs_toa_ns[0] : 0xFFFF;
//srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? (int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) : 0xFFFF;
//nr_est_toa_ns_srs(frame_parms, N_ant_rx, N_ap ,N_symb_SRS, srs_estimated_channel_freq, srs_toa_ns);
for (int ant=0;ant<N_ant_rx;ant++){
printf("srs_toa_ns[%d] = %d\n",ant,srs_toa_ns[ant]);
//srs_toa_MQTT((int32_t *)srs_estimated_channel_time[ant], frame_parms->ofdm_symbol_size, ant, srs_toa_ns[ant], ant);
srs_toa_MQTT((int32_t *)srs_estimated_channel_time[ant][0], frame_parms->ofdm_symbol_size, gNB->Mod_id, ant);
}
T(T_GNB_PHY_UL_SRS_TOA_NS,
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(slot_rx),
T_BUFFER(srs_toa_ns, N_ant_rx * sizeof(int32_t)));
//(int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) : 0xFFFF;
switch (srs_pdu->srs_parameters_v4.usage) {
case 0:
LOG_W(NR_PHY, "SRS report was not requested by MAC\n");

View File

@@ -0,0 +1,66 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file openair2/COMMON/mqtt_paramdef.h
* \brief definition of configuration parameters for MQTT
* \author
* \date 2022
* \version 0.1
* \company EURECOM
* \email:
* \note
* \warning
*/
#ifndef __MQTT_PARAMDEF__H__
#define __MQTT_PARAMDEF__H__
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* PRS configuration section names */
#define CONFIG_STRING_MQTT_CONFIG "mqtt_config"
/* Global parameters */
/* MQTT parameters */
#define CONFIG_STRING_MQTT_BROKER_ADDR "MqttBrokerAddr"
#define CONFIG_STRING_MQTT_TOPIC_NAME "MqttTopicName"
#define CONFIG_STRING_MQTT_CLIENT_ID "MqttClientId"
#define CONFIG_STRING_MQTT_TRP_ID "MqttTrpId"
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* PRS configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
#define MQTT_PARAMS_DESC { \
{CONFIG_STRING_MQTT_BROKER_ADDR, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{CONFIG_STRING_MQTT_TOPIC_NAME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{CONFIG_STRING_MQTT_CLIENT_ID, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{CONFIG_STRING_MQTT_TRP_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0} \
}
#define MQTT_BROKER_ADDR_IDX 0
#define MQTT_TOPIC_NAME_IDX 1
#define MQTT_CLIENT_ID_IDX 2
#define MQTT_TRP_ID_IDX 3
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif

View File

@@ -744,8 +744,8 @@ static NR_SetupRelease_SRS_Config_t *get_config_srs(const NR_ServingCellConfigCo
srs_res0->transmissionComb.choice.n2 = calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2));
srs_res0->transmissionComb.choice.n2->combOffset_n2 = 0;
srs_res0->transmissionComb.choice.n2->cyclicShift_n2 = 0;
srs_res0->resourceMapping.startPosition = 1;
srs_res0->resourceMapping.nrofSymbols = NR_SRS_Resource__resourceMapping__nrofSymbols_n1;
srs_res0->resourceMapping.startPosition = 4;
srs_res0->resourceMapping.nrofSymbols = NR_SRS_Resource__resourceMapping__nrofSymbols_n4;
srs_res0->resourceMapping.repetitionFactor = NR_SRS_Resource__resourceMapping__repetitionFactor_n1;
srs_res0->freqDomainPosition = 0;
srs_res0->freqDomainShift = 0;