mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Export CIR via UDP (127.0.0.1:63140) instead of using file-based channel input
This commit is contained in:
@@ -1 +0,0 @@
|
||||
B׿8ƒÓ„·Î7•5±s4G$‡µk6A³
|
||||
Binary file not shown.
@@ -2,7 +2,6 @@
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
#define DEVELOP_CIR
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -50,13 +49,10 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1};
|
||||
#include "nfapi_interface.h"
|
||||
#include <nfapi/oai_integration/vendor_ext.h>
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
#include <cblas.h>
|
||||
|
||||
static void NRRCconfig_RU(configmodule_interface_t *cfg);
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
#include <cblas.h>
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
/*************************************************************/
|
||||
/* Southbound Fronthaul functions, RCC/RAU */
|
||||
|
||||
@@ -343,8 +339,7 @@ void fh_if4p5_north_out(RU_t *ru)
|
||||
stop_meas(&ru->tx_fhaul);
|
||||
}
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
// noise reader
|
||||
// Noise reader
|
||||
static void noise_reader(RU_t *ru, cf_t *ret_noise, int nsamps, int nb_antennas)
|
||||
{
|
||||
cf_t *noise_1d = (cf_t *)ret_noise;
|
||||
@@ -363,7 +358,6 @@ static void noise_reader(RU_t *ru, cf_t *ret_noise, int nsamps, int nb_antennas)
|
||||
ru->noise_index = noise_index;
|
||||
pthread_mutex_unlock(&ru->proc.mutex_noise);
|
||||
}
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
{
|
||||
@@ -373,14 +367,6 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
uint32_t samples_per_slot = get_samples_per_slot(*slot, fp);
|
||||
AssertFatal(*slot < fp->slots_per_frame && *slot >= 0, "slot %d is illegal (%d)\n", *slot, fp->slots_per_frame);
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
int a_rx;
|
||||
int nb_tx = ru->nb_tx;
|
||||
int nb_rx = ru->nb_rx;
|
||||
cf_t pathLossLinear = {0};
|
||||
cf_t noise_per_sample = {0};
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
start_meas(&ru->rx_fhaul);
|
||||
int nb = ru->nb_rx * ru->num_beams_period;
|
||||
void *rxp[nb];
|
||||
@@ -395,12 +381,15 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, samples_per_slot, nb);
|
||||
proc->timestamp_rx = ts-ru->ts_offset;
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
|
||||
nfapi_nr_config_request_scf_t *config = &ru->config;
|
||||
int slot_type = nr_slot_select(config, *frame, *slot % fp->slots_per_frame);
|
||||
|
||||
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
if (ru->cir_was_received && (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT)) {
|
||||
int nb_tx = ru->nb_tx;
|
||||
int nb_rx = ru->nb_rx;
|
||||
cf_t pathLossLinear = {0};
|
||||
cf_t noise_per_sample = {0};
|
||||
|
||||
// init common variables
|
||||
pathLossLinear.r = ru->pathLossLinear;
|
||||
noise_per_sample.r = ru->noise_per_sample;
|
||||
@@ -443,7 +432,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
int delayed_boundary_s = (ru->common.buffboundary - l + ru->common.circular_buff_size) % ru->common.circular_buff_size;
|
||||
int delayed_boundary_e =
|
||||
(ru->common.buffboundary + samples_per_slot - l + ru->common.circular_buff_size) % ru->common.circular_buff_size;
|
||||
for (a_rx = 0; a_rx < nb_rx; a_rx++) {
|
||||
for (int a_rx = 0; a_rx < nb_rx; a_rx++) {
|
||||
if (delayed_boundary_s < delayed_boundary_e) { // data is contiguous in the buffer
|
||||
memcpy(&ru->common.simul_input[(nb_rx * lp + a_rx) * samples_per_slot],
|
||||
&ru->common.circular_buff[a_rx][delayed_boundary_s],
|
||||
@@ -509,8 +498,6 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
if (rxs != samples_per_slot)
|
||||
LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n", samples_per_slot, rxs);
|
||||
|
||||
@@ -715,20 +702,16 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
for (int i = 0; i < nt; i++)
|
||||
txp[i] = (void *)&ru->common.txdata[i][get_samples_slot_timestamp(fp, slot)] - sf_extension * sizeof(int32_t);
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
int a_tx;
|
||||
int nb_tx = ru->nb_tx;
|
||||
int nb_rx = ru->nb_rx;
|
||||
int samples_per_slot = siglen + sf_extension;
|
||||
cf_t pathLossLinear = {0};
|
||||
cf_t noise_per_sample = {0};
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
|
||||
int slot_type = nr_slot_select(cfg, frame, slot % fp->slots_per_frame);
|
||||
|
||||
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
if (ru->cir_was_received && (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT)) {
|
||||
int a_tx;
|
||||
int nb_tx = ru->nb_tx;
|
||||
int nb_rx = ru->nb_rx;
|
||||
int samples_per_slot = siglen + sf_extension;
|
||||
cf_t pathLossLinear = {0};
|
||||
cf_t noise_per_sample = {0};
|
||||
|
||||
// init common variables
|
||||
pathLossLinear.r = ru->pathLossLinear;
|
||||
noise_per_sample.r = ru->noise_per_sample;
|
||||
@@ -837,8 +820,6 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
// prepare tx buffer pointers
|
||||
uint32_t txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
timestamp + ru->ts_offset - sf_extension,
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
|
||||
#define DEVELOP_CIR
|
||||
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
#ifdef SMBV
|
||||
@@ -71,11 +69,12 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "x2ap_eNB.h"
|
||||
#include "openair1/SCHED_NR/sched_nr.h"
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
#ifdef DEVELOP_CIR
|
||||
static char cir_conf_file[] = "../../../cir_conf.txt";
|
||||
static const char cir_file_template[] = "../../../cir/output/binary/delayamplist";
|
||||
static const char delayindexlist_template[] = "../../../cir/output/binary/delayindexlist";
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define OAIBOX_DT_CHANNEL_EXPORT_ADDRESS "127.0.0.1"
|
||||
#define OAIBOX_DT_CHANNEL_EXPORT_PORT 63140
|
||||
#define MAX_UDP_SIZE 65536 // maximum UDP payload buffer
|
||||
|
||||
RAN_CONTEXT_t RC;
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
@@ -504,136 +503,116 @@ static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
|
||||
void init_eNB_afterRU(void);
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
void *refresh_cir_variables(void *param) {
|
||||
void *refresh_cir_variables(void *param)
|
||||
{
|
||||
RU_t *ru = (RU_t *)param;
|
||||
static int refresh_status;
|
||||
FILE *fptr;
|
||||
cf_t path_loss_dB = (cf_t){0.0, 0.0};
|
||||
float amp_gain_dB = 0.0;
|
||||
cf_t noise_power_dB = (cf_t){0.0, 0.0};
|
||||
int channel_length = 1;
|
||||
int CIR_NUM_OF_FILES = 1;
|
||||
int nb_tx = ru->nb_tx;
|
||||
int nb_rx = ru->nb_rx;
|
||||
static int fi = 0; // File index for periodically reading CIR binary files
|
||||
char str[256];
|
||||
char cir_file_path[256];
|
||||
char delayindexlist_path[256];
|
||||
int last_processed_frame = -1;
|
||||
|
||||
int sockfd;
|
||||
struct sockaddr_in servaddr, cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
uint8_t buffer[MAX_UDP_SIZE];
|
||||
|
||||
// Create UDP socket
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) {
|
||||
perror("UDP socket creation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Bind
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = inet_addr(OAIBOX_DT_CHANNEL_EXPORT_ADDRESS);
|
||||
servaddr.sin_port = htons(OAIBOX_DT_CHANNEL_EXPORT_PORT);
|
||||
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
|
||||
perror("UDP bind failed");
|
||||
close(sockfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOG_I(NR_PHY, "CIR UDP receiver listening on %s:%d\n", OAIBOX_DT_CHANNEL_EXPORT_ADDRESS, OAIBOX_DT_CHANNEL_EXPORT_PORT);
|
||||
|
||||
while (1) {
|
||||
if (ru->proc.frame_rx % 10 == 0 && last_processed_frame != ru->proc.frame_rx) {
|
||||
last_processed_frame = ru->proc.frame_rx;
|
||||
fptr = fopen(cir_conf_file, "r");
|
||||
if (fptr) {
|
||||
// pathLoss_dB
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%f", &path_loss_dB.r);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading path_loss_dB from cir_conf.txt\n");
|
||||
}
|
||||
ssize_t n = recvfrom(sockfd, buffer, MAX_UDP_SIZE, 0, (struct sockaddr *)&cliaddr, &len);
|
||||
|
||||
// amp_gain_dB
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%f", &_gain_dB);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading amp_gain_dB from cir_conf.txt\n");
|
||||
}
|
||||
if (n <= 0)
|
||||
continue;
|
||||
|
||||
// noise_per_sample
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%f", &noise_power_dB.r);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading noise_power_dB from cir_conf.txt\n");
|
||||
}
|
||||
|
||||
// num of taps
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%d", &channel_length);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading channel_length from cir_conf.txt\n");
|
||||
}
|
||||
|
||||
// num of CIR files
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%d", &CIR_NUM_OF_FILES);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading CIR_NUM_OF_FILES from cir_conf.txt\n");
|
||||
}
|
||||
fclose(fptr);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "error: cir_conf.txt\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// write params
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
ru->pathLossLinear = pow(10, (path_loss_dB.r + amp_gain_dB) / 20.0);
|
||||
ru->noise_per_sample = pow(10, noise_power_dB.r / 20.0) * 256; // TODO: check formula
|
||||
ru->channel_length = channel_length;
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
|
||||
// read cir data
|
||||
cf_t cir_buffer[channel_length * ru->nb_tx * ru->nb_rx];
|
||||
memset(cir_buffer, 0, sizeof(cir_buffer));
|
||||
sprintf(cir_file_path, "%s%04d.b", cir_file_template, fi);
|
||||
fptr = fopen(cir_file_path, "rb");
|
||||
if (fptr) {
|
||||
if (fread(cir_buffer, sizeof(cir_buffer), 1, fptr) != 1)
|
||||
LOG_D(NR_PHY, "Error reading CIR data from file\n");
|
||||
fclose(fptr);
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
for (int l = 0; l < channel_length; l++) {
|
||||
for (int a_tx = 0; a_tx < ru->nb_tx; a_tx++) {
|
||||
for (int a_rx = 0; a_rx < ru->nb_rx; a_rx++) {
|
||||
ru->cirMIMO_simulmatrix[a_rx * channel_length * nb_tx + l * nb_rx + a_tx].r =
|
||||
cir_buffer[l * nb_tx * nb_rx + nb_rx * a_tx + a_rx].r;
|
||||
|
||||
ru->cirMIMO_simulmatrix[a_rx * channel_length * nb_tx + l * nb_rx + a_tx].i =
|
||||
cir_buffer[l * nb_tx * nb_rx + nb_rx * a_tx + a_rx].i;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
}
|
||||
|
||||
// read delay index list
|
||||
int delayindexlist_tmp[channel_length];
|
||||
memset(delayindexlist_tmp, 0, sizeof(delayindexlist_tmp));
|
||||
sprintf(delayindexlist_path, "%s%04d.b", delayindexlist_template, fi);
|
||||
fptr = fopen(delayindexlist_path, "rb");
|
||||
if (fptr) {
|
||||
if (fread(delayindexlist_tmp, sizeof(delayindexlist_tmp), 1, fptr) != 1)
|
||||
LOG_D(NR_PHY, "Error reading delayindexlist from file\n");
|
||||
fclose(fptr);
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
for (int l = 0; l < channel_length; l++) {
|
||||
ru->delayindexlist[l] = delayindexlist_tmp[l];
|
||||
}
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
}
|
||||
|
||||
// update fi
|
||||
fi = (fi + 1 + CIR_NUM_OF_FILES) % CIR_NUM_OF_FILES;
|
||||
if (n < 12) {
|
||||
LOG_W(NR_PHY, "Packet too small\n");
|
||||
continue;
|
||||
}
|
||||
usleep(1000);
|
||||
|
||||
// Parse header (network byte order / big-endian)
|
||||
char magic[5] = {0};
|
||||
memcpy(magic, buffer, 4);
|
||||
uint32_t version;
|
||||
memcpy(&version, buffer + 4, 4);
|
||||
uint32_t N;
|
||||
memcpy(&N, buffer + 8, 4);
|
||||
version = ntohl(version);
|
||||
N = ntohl(N);
|
||||
if (strncmp(magic, "OAIB", 4) != 0) {
|
||||
LOG_W(NR_PHY, "Invalid magic header\n");
|
||||
continue;
|
||||
}
|
||||
LOG_D(NR_PHY, "Received CIR packet: version=%u, N=%u\n", version, N);
|
||||
|
||||
// Validate expected size
|
||||
size_t expected_size = 12 + (N * 2 * sizeof(float)) + (N * sizeof(int32_t));
|
||||
if ((size_t)n < expected_size) {
|
||||
LOG_W(NR_PHY, "Incomplete packet (got %ld, expected %zu)\n", n, expected_size);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract interleaved complex floats
|
||||
cf_t *taps = (cf_t *)(buffer + 12);
|
||||
|
||||
// Extract delay indices
|
||||
int32_t *delay_idx = (int32_t *)(buffer + 12 + (N * 2 * sizeof(float)));
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
LOG_D(NR_PHY, "Tap[%d]: %+.6e %+.6e delay_idx=%d\n", i, taps[i].r, taps[i].i, delay_idx[i]);
|
||||
}
|
||||
|
||||
// Store into RU structure
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
memset(ru->cirMIMO_simulmatrix, 0, nb_tx * nb_rx * ru->channel_length * sizeof(cf_t));
|
||||
for (int l = 0; l < ru->channel_length; l++) {
|
||||
for (int a_tx = 0; a_tx < nb_tx; a_tx++) {
|
||||
for (int a_rx = 0; a_rx < nb_rx; a_rx++) {
|
||||
if (l * nb_tx * nb_rx + nb_rx * a_tx + a_rx >= N)
|
||||
break;
|
||||
ru->cirMIMO_simulmatrix[a_rx * ru->channel_length * nb_tx + l * nb_rx + a_tx] =
|
||||
taps[l * nb_tx * nb_rx + nb_rx * a_tx + a_rx];
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(ru->delayindexlist, 0, ru->channel_length * sizeof(int));
|
||||
for (int l = 0; l < ru->channel_length && l < N; l++) {
|
||||
ru->delayindexlist[l] = delay_idx[l];
|
||||
}
|
||||
|
||||
ru->cir_was_received = true;
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
}
|
||||
refresh_status = 0;
|
||||
return &refresh_status;
|
||||
|
||||
close(sockfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *refresh_noise(void *param)
|
||||
{
|
||||
RU_t *ru = (RU_t *)param;
|
||||
uint32_t counter = 0;
|
||||
int a, c;
|
||||
static int refresh_status;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int siglen = get_samples_per_slot(0, fp);
|
||||
uint32_t siglen = get_samples_per_slot(0, fp);
|
||||
while (1) {
|
||||
for (a = 0; a < ru->nb_tx; a++) {
|
||||
c = counter % siglen;
|
||||
for (int a = 0; a < ru->nb_tx; a++) {
|
||||
uint32_t c = counter % siglen;
|
||||
pthread_mutex_lock(&ru->proc.mutex_noise);
|
||||
ru->noise_array[a][c].r = (float)gaussZiggurat(0.0, 1.0);
|
||||
ru->noise_array[a][c].i = (float)gaussZiggurat(0.0, 1.0);
|
||||
@@ -642,10 +621,8 @@ void *refresh_noise(void *param)
|
||||
counter = (counter + 1) % UINT32_MAX;
|
||||
usleep(1000);
|
||||
}
|
||||
refresh_status = 0;
|
||||
return &refresh_status;
|
||||
return NULL;
|
||||
}
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
int ru_id, CC_id = 0;
|
||||
@@ -850,13 +827,11 @@ int main( int argc, char **argv ) {
|
||||
pthread_cond_broadcast(&sync_cond);
|
||||
pthread_mutex_unlock(&sync_mutex);
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
// create thread: refresh mimo matrix, noise
|
||||
// Create thread: refresh mimo matrix, noise
|
||||
for (int i = 0; i < RC.nb_RU; i++) {
|
||||
threadCreate(&RC.ru[i]->proc.pthread_mimo, refresh_cir_variables, (void *)RC.ru[i], "refresh_cir_variables", -1, OAI_PRIORITY_RT_LOW);
|
||||
threadCreate(&RC.ru[i]->proc.pthread_mimo, refresh_noise, (void *)RC.ru[i], "refresh_noise", -1, OAI_PRIORITY_RT_LOW);
|
||||
}
|
||||
#endif // DEVELOP_CIR
|
||||
}
|
||||
|
||||
// wait for end of program
|
||||
|
||||
@@ -8,35 +8,26 @@
|
||||
#include "openair1/PHY/defs_RU.h"
|
||||
#include "openair1/PHY/defs_nr_common.h"
|
||||
#include "openair1/PHY/defs_gNB.h"
|
||||
|
||||
#define DEVELOP_CIR
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
#include "SIMULATION/TOOLS/sim.h"
|
||||
static char cir_conf_file[] = "../../../cir_conf.txt";
|
||||
static const char cir_file_template[] = "../../../cir/output/binary/delayamplist";
|
||||
static const char delayindexlist_template[] = "../../../cir/output/binary/delayindexlist";
|
||||
#endif
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
void init_cir_variables(void *param)
|
||||
static void init_cir_variables(void* param)
|
||||
{
|
||||
RU_t *ru = (RU_t *)param;
|
||||
FILE *fptr;
|
||||
cf_t path_loss_dB = (cf_t){0.0, 0.0};
|
||||
float amp_gain_dB = 0.0;
|
||||
cf_t noise_power_dB = (cf_t){0.0, 0.0};
|
||||
RU_t* ru = (RU_t*)param;
|
||||
int nb_tx = ru->nb_tx;
|
||||
int nb_rx = ru->nb_rx;
|
||||
float path_loss_dB = 0.0f;
|
||||
float amp_gain_dB = 0.0f;
|
||||
float noise_power_dB = 0.0f;
|
||||
int channel_length = 1;
|
||||
char str[256];
|
||||
char cir_file_path[256];
|
||||
char delayindexlist_path[256];
|
||||
|
||||
// read file: pathloss_db, noise_power_dB
|
||||
fptr = fopen(cir_conf_file, "r");
|
||||
// Read file: pathloss_db, noise_power_dB
|
||||
char cir_conf_file[] = "../../../cir_conf.txt";
|
||||
FILE* fptr = fopen(cir_conf_file, "r");
|
||||
if (fptr) {
|
||||
// pathLossLinear
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%f", &path_loss_dB.r);
|
||||
sscanf(str, "%f", &path_loss_dB);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading path_loss_dB from cir_conf.txt\n");
|
||||
}
|
||||
@@ -50,7 +41,7 @@ void init_cir_variables(void *param)
|
||||
|
||||
// noise_per_sample
|
||||
if (fgets(str, sizeof(str), fptr) != NULL) {
|
||||
sscanf(str, "%f", &noise_power_dB.r);
|
||||
sscanf(str, "%f", &noise_power_dB);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "Error reading noise_power_dB from cir_conf.txt\n");
|
||||
}
|
||||
@@ -65,63 +56,41 @@ void init_cir_variables(void *param)
|
||||
fclose(fptr);
|
||||
} else {
|
||||
LOG_E(NR_PHY, "error: cir_conf.txt\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// write params
|
||||
// Write params
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
ru->pathLossLinear = pow(10, (path_loss_dB.r + amp_gain_dB) / 20.0);
|
||||
ru->noise_per_sample = pow(10, noise_power_dB.r / 20.0) * 256; // TODO: check formula
|
||||
ru->pathLossLinear = pow(10, (path_loss_dB + amp_gain_dB) / 20.0);
|
||||
ru->noise_per_sample = pow(10, noise_power_dB / 20.0) * 256; // The useful signal is scaled on the order of 256.
|
||||
ru->channel_length = channel_length;
|
||||
ru->cir_was_received = false;
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
|
||||
// read cir data
|
||||
cf_t cir_buffer[channel_length * ru->nb_tx * ru->nb_rx];
|
||||
memset(cir_buffer, 0, sizeof(cir_buffer));
|
||||
ru->cirMIMO_simulmatrix = malloc16_clear(ru->nb_tx * ru->nb_rx * channel_length * sizeof(cf_t));
|
||||
sprintf(cir_file_path, "%s0000.b", cir_file_template);
|
||||
fptr = fopen(cir_file_path, "rb");
|
||||
if (fptr) {
|
||||
if (fread(cir_buffer, sizeof(cir_buffer), 1, fptr) != 1)
|
||||
LOG_D(NR_PHY, "Error reading cir_buffer from file\n");
|
||||
fclose(fptr);
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
for (int l = 0; l < channel_length; l++) {
|
||||
for (int a_tx = 0; a_tx < ru->nb_tx; a_tx++) {
|
||||
for (int a_rx = 0; a_rx < ru->nb_rx; a_rx++) {
|
||||
ru->cirMIMO_simulmatrix[a_rx * channel_length * ru->nb_tx + l * ru->nb_rx + a_tx].r =
|
||||
cir_buffer[l * ru->nb_tx * ru->nb_rx + ru->nb_rx * a_tx + a_rx].r;
|
||||
|
||||
ru->cirMIMO_simulmatrix[a_rx * channel_length * ru->nb_tx + l * ru->nb_rx + a_tx].i =
|
||||
cir_buffer[l * ru->nb_tx * ru->nb_rx + ru->nb_rx * a_tx + a_rx].i;
|
||||
}
|
||||
}
|
||||
// CIR data
|
||||
ru->cirMIMO_simulmatrix = malloc16_clear(nb_tx * nb_rx * channel_length * sizeof(cf_t));
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
int l = 0;
|
||||
for (int a_tx = 0; a_tx < nb_tx; a_tx++) {
|
||||
for (int a_rx = 0; a_rx < nb_rx; a_rx++) {
|
||||
ru->cirMIMO_simulmatrix[a_rx * channel_length * nb_tx + l * nb_rx + a_tx].r = 1.0f / ru->pathLossLinear;
|
||||
ru->cirMIMO_simulmatrix[a_rx * channel_length * nb_tx + l * nb_rx + a_tx].i = 0.0f;
|
||||
}
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
}
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
|
||||
// read delay index list
|
||||
int delayindexlist_tmp[channel_length];
|
||||
memset(delayindexlist_tmp, 0, sizeof(delayindexlist_tmp));
|
||||
// Delay index list
|
||||
ru->delayindexlist = malloc16_clear(channel_length * sizeof(int));
|
||||
sprintf(delayindexlist_path, "%s0000.b", delayindexlist_template);
|
||||
fptr = fopen(delayindexlist_path, "rb");
|
||||
if (fptr) {
|
||||
if (fread(delayindexlist_tmp, sizeof(delayindexlist_tmp), 1, fptr) != 1)
|
||||
LOG_D(NR_PHY, "Error reading delayindexlist from file\n");
|
||||
fclose(fptr);
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
for (int l = 0; l < channel_length; l++) {
|
||||
ru->delayindexlist[l] = delayindexlist_tmp[l];
|
||||
}
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
pthread_mutex_lock(&ru->proc.mutex_mimo);
|
||||
for (int l = 0; l < channel_length; l++) {
|
||||
ru->delayindexlist[l] = l;
|
||||
}
|
||||
pthread_mutex_unlock(&ru->proc.mutex_mimo);
|
||||
}
|
||||
|
||||
void init_noise(void *param)
|
||||
static void init_noise(void* param)
|
||||
{
|
||||
RU_t *ru = (RU_t *)param;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
RU_t* ru = (RU_t*)param;
|
||||
NR_DL_FRAME_PARMS* fp = ru->nr_frame_parms;
|
||||
int samples_per_slot = get_samples_per_slot(0, fp) + ru->sf_extension;
|
||||
|
||||
randominit();
|
||||
@@ -142,8 +111,6 @@ void init_noise(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEVELOP_CIR
|
||||
|
||||
void nr_phy_init_RU(RU_t *ru)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
@@ -238,28 +205,18 @@ void nr_phy_init_RU(RU_t *ru)
|
||||
LOG_D(PHY, "[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
|
||||
} // !=IF5
|
||||
|
||||
#ifdef DEVELOP_CIR
|
||||
printf("INIT DEVELOP_CIR\n");
|
||||
fflush(stdout);
|
||||
|
||||
// init cir variables
|
||||
// Init CIR variables
|
||||
init_cir_variables(ru); // init: convolution matrix, channel_length, pathLossLinear, noise_per_sample
|
||||
init_noise(ru); // init: noise array
|
||||
|
||||
ru->common.buffboundary = 0;
|
||||
ru->common.circular_buff_size = fp->samples_per_frame;
|
||||
|
||||
ru->common.circular_buff = malloc16_clear(ru->nb_rx * sizeof(cf_t));
|
||||
for (int a = 0; a < ru->nb_rx; a++) {
|
||||
for (int a = 0; a < ru->nb_rx; a++)
|
||||
ru->common.circular_buff[a] = malloc16_clear(ru->common.circular_buff_size * sizeof(cf_t));
|
||||
}
|
||||
|
||||
int samples_per_slot = fp->samples_per_slot0 + ru->sf_extension;
|
||||
ru->common.noise_array = malloc16_clear(ru->nb_rx * samples_per_slot * sizeof(cf_t));
|
||||
|
||||
// allocate MIMO temporary store fields
|
||||
ru->common.simul_input = malloc16_clear(ru->nb_tx * ru->channel_length * samples_per_slot * sizeof(cf_t));
|
||||
#endif // DEVELOP_CIR
|
||||
ru->common.simul_input =
|
||||
malloc16_clear(ru->nb_tx * ru->channel_length * samples_per_slot * sizeof(cf_t)); // allocate MIMO temporary store fields
|
||||
}
|
||||
|
||||
void nr_phy_free_RU(RU_t *ru)
|
||||
@@ -309,18 +266,16 @@ void nr_phy_free_RU(RU_t *ru)
|
||||
PHY_VARS_gNB *gNB0 = ru->gNB_list[0];
|
||||
gNB0->num_RU--;
|
||||
DevAssert(gNB0->num_RU >= 0);
|
||||
#ifdef DEVELOP_CIR
|
||||
printf("terminate DEVELOP_CIR\n");
|
||||
fflush(stdout);
|
||||
|
||||
// Free CIR variables
|
||||
free(ru->common.simul_input);
|
||||
free(ru->delayindexlist);
|
||||
free(ru->cirMIMO_simulmatrix);
|
||||
for (int a = 0; a < ru->nb_tx; a++) free(ru->noise_array[a]);
|
||||
for (int a = 0; a < ru->nb_tx; a++)
|
||||
free(ru->noise_array[a]);
|
||||
free(ru->noise_array);
|
||||
|
||||
for (int a = 0; a < ru->nb_rx; a++) free(ru->common.circular_buff[a]);
|
||||
for (int a = 0; a < ru->nb_rx; a++)
|
||||
free(ru->common.circular_buff[a]);
|
||||
free(ru->common.circular_buff);
|
||||
|
||||
free(ru->common.noise_array);
|
||||
#endif // DEVELOP_CIR
|
||||
}
|
||||
|
||||
@@ -629,6 +629,7 @@ typedef struct RU_t_s {
|
||||
float noise_per_sample;
|
||||
int32_t channel_length;
|
||||
uint32_t noise_index;
|
||||
bool cir_was_received;
|
||||
} RU_t;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user