fix as per branch name
This commit is contained in:
+83
-21
@@ -28,13 +28,23 @@
|
|||||||
* separate process solves this problem.
|
* separate process solves this problem.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <common/utils/assertions.h>
|
||||||
|
#include <common/utils/LOG/log.h>
|
||||||
#define MAX_COMMAND 4096
|
#define MAX_COMMAND 4096
|
||||||
|
|
||||||
static int command_pipe_read;
|
static int command_pipe_read;
|
||||||
@@ -50,37 +60,37 @@ static int module_initialized = 0;
|
|||||||
/* util functions */
|
/* util functions */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
static void lock_system(void)
|
static void lock_system(void) {
|
||||||
{
|
|
||||||
if (pthread_mutex_lock(&lock) != 0) {
|
if (pthread_mutex_lock(&lock) != 0) {
|
||||||
printf("pthread_mutex_lock fails\n");
|
printf("pthread_mutex_lock fails\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unlock_system(void)
|
static void unlock_system(void) {
|
||||||
{
|
|
||||||
if (pthread_mutex_unlock(&lock) != 0) {
|
if (pthread_mutex_unlock(&lock) != 0) {
|
||||||
printf("pthread_mutex_unlock fails\n");
|
printf("pthread_mutex_unlock fails\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_pipe(int p, char *b, int size)
|
static void write_pipe(int p, char *b, int size) {
|
||||||
{
|
|
||||||
while (size) {
|
while (size) {
|
||||||
int ret = write(p, b, size);
|
int ret = write(p, b, size);
|
||||||
|
|
||||||
if (ret <= 0) exit(0);
|
if (ret <= 0) exit(0);
|
||||||
|
|
||||||
b += ret;
|
b += ret;
|
||||||
size -= ret;
|
size -= ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_pipe(int p, char *b, int size)
|
static void read_pipe(int p, char *b, int size) {
|
||||||
{
|
|
||||||
while (size) {
|
while (size) {
|
||||||
int ret = read(p, b, size);
|
int ret = read(p, b, size);
|
||||||
|
|
||||||
if (ret <= 0) exit(0);
|
if (ret <= 0) exit(0);
|
||||||
|
|
||||||
b += ret;
|
b += ret;
|
||||||
size -= ret;
|
size -= ret;
|
||||||
}
|
}
|
||||||
@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
|
|||||||
* when the main process exits, because then a "read" on the pipe
|
* when the main process exits, because then a "read" on the pipe
|
||||||
* will return 0, in which case "read_pipe" exits.
|
* will return 0, in which case "read_pipe" exits.
|
||||||
*/
|
*/
|
||||||
static void background_system_process(void)
|
static void background_system_process(void) {
|
||||||
{
|
|
||||||
int len;
|
int len;
|
||||||
int ret;
|
int ret;
|
||||||
char command[MAX_COMMAND+1];
|
char command[MAX_COMMAND+1];
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
read_pipe(command_pipe_read, (char*)&len, sizeof(int));
|
read_pipe(command_pipe_read, (char *)&len, sizeof(int));
|
||||||
read_pipe(command_pipe_read, command, len);
|
read_pipe(command_pipe_read, command, len);
|
||||||
ret = system(command);
|
ret = system(command);
|
||||||
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
|
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
|
||||||
@@ -114,8 +123,7 @@ static void background_system_process(void)
|
|||||||
/* return -1 on error, 0 on success */
|
/* return -1 on error, 0 on success */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
int background_system(char *command)
|
int background_system(char *command) {
|
||||||
{
|
|
||||||
int res;
|
int res;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -125,18 +133,22 @@ int background_system(char *command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(command)+1;
|
len = strlen(command)+1;
|
||||||
|
|
||||||
if (len > MAX_COMMAND) {
|
if (len > MAX_COMMAND) {
|
||||||
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
|
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
|
||||||
printf("command was: '%s'\n", command);
|
printf("command was: '%s'\n", command);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only one command can run at a time, so let's lock/unlock */
|
/* only one command can run at a time, so let's lock/unlock */
|
||||||
lock_system();
|
lock_system();
|
||||||
write_pipe(command_pipe_write, (char*)&len, sizeof(int));
|
write_pipe(command_pipe_write, (char *)&len, sizeof(int));
|
||||||
write_pipe(command_pipe_write, command, len);
|
write_pipe(command_pipe_write, command, len);
|
||||||
read_pipe(result_pipe_read, (char*)&res, sizeof(int));
|
read_pipe(result_pipe_read, (char *)&res, sizeof(int));
|
||||||
unlock_system();
|
unlock_system();
|
||||||
|
|
||||||
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
|
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,17 +158,16 @@ int background_system(char *command)
|
|||||||
/* to be called very early by the main processing */
|
/* to be called very early by the main processing */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
void start_background_system(void)
|
void start_background_system(void) {
|
||||||
{
|
|
||||||
int p[2];
|
int p[2];
|
||||||
pid_t son;
|
pid_t son;
|
||||||
|
|
||||||
module_initialized = 1;
|
module_initialized = 1;
|
||||||
|
|
||||||
if (pipe(p) == -1) {
|
if (pipe(p) == -1) {
|
||||||
perror("pipe");
|
perror("pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_pipe_read = p[0];
|
command_pipe_read = p[0];
|
||||||
command_pipe_write = p[1];
|
command_pipe_write = p[1];
|
||||||
|
|
||||||
@@ -164,10 +175,11 @@ void start_background_system(void)
|
|||||||
perror("pipe");
|
perror("pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_pipe_read = p[0];
|
result_pipe_read = p[0];
|
||||||
result_pipe_write = p[1];
|
result_pipe_write = p[1];
|
||||||
|
|
||||||
son = fork();
|
son = fork();
|
||||||
|
|
||||||
if (son == -1) {
|
if (son == -1) {
|
||||||
perror("fork");
|
perror("fork");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -181,6 +193,56 @@ void start_background_system(void)
|
|||||||
|
|
||||||
close(result_pipe_read);
|
close(result_pipe_read);
|
||||||
close(command_pipe_write);
|
close(command_pipe_write);
|
||||||
|
|
||||||
background_system_process();
|
background_system_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||||
|
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
|
||||||
|
struct sched_param sparam={0};
|
||||||
|
sparam.sched_priority = priority;
|
||||||
|
pthread_attr_setschedparam(&attr, &sparam);
|
||||||
|
|
||||||
|
pthread_create(t, &attr, func, param);
|
||||||
|
|
||||||
|
pthread_setname_np(*t, name);
|
||||||
|
if (affinity != -1 ) {
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
CPU_SET(affinity, &cpuset);
|
||||||
|
AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block CPU C-states deep sleep
|
||||||
|
void configure_linux(void) {
|
||||||
|
int ret;
|
||||||
|
static int latency_target_fd=-1;
|
||||||
|
uint32_t latency_target_value=10; // in microseconds
|
||||||
|
if (latency_target_fd == -1) {
|
||||||
|
if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
|
||||||
|
ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
|
||||||
|
if (ret == 0) {
|
||||||
|
printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
|
||||||
|
close(latency_target_fd);
|
||||||
|
latency_target_fd=-1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latency_target_fd != -1)
|
||||||
|
LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
|
||||||
|
else
|
||||||
|
LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
|
||||||
|
|
||||||
|
// Set CPU frequency to it's maximum
|
||||||
|
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
|
||||||
|
LOG_W(HW,"Can't set cpu frequency\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,12 @@
|
|||||||
|
|
||||||
#ifndef _SYSTEM_H_OAI_
|
#ifndef _SYSTEM_H_OAI_
|
||||||
#define _SYSTEM_H_OAI_
|
#define _SYSTEM_H_OAI_
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* send a command to the background process
|
* send a command to the background process
|
||||||
@@ -36,4 +42,23 @@ int background_system(char *command);
|
|||||||
|
|
||||||
void start_background_system(void);
|
void start_background_system(void);
|
||||||
|
|
||||||
|
void set_latency_target(void);
|
||||||
|
void configure_linux(void);
|
||||||
|
|
||||||
|
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
|
||||||
|
#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
|
||||||
|
#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
|
||||||
|
#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
|
||||||
|
|
||||||
|
void thread_top_init(char *thread_name,
|
||||||
|
int affinity,
|
||||||
|
uint64_t runtime,
|
||||||
|
uint64_t deadline,
|
||||||
|
uint64_t period);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SYSTEM_H_OAI_ */
|
#endif /* _SYSTEM_H_OAI_ */
|
||||||
|
|||||||
@@ -230,13 +230,11 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void pdsch_procedures(PHY_VARS_eNB *eNB,
|
bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
||||||
L1_rxtx_proc_t *proc,
|
L1_rxtx_proc_t *proc,
|
||||||
int harq_pid,
|
int harq_pid,
|
||||||
LTE_eNB_DLSCH_t *dlsch,
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
LTE_eNB_DLSCH_t *dlsch1,
|
LTE_eNB_UE_stats *ue_stats) {
|
||||||
LTE_eNB_UE_stats *ue_stats,
|
|
||||||
int ra_flag) {
|
|
||||||
int frame=proc->frame_tx;
|
int frame=proc->frame_tx;
|
||||||
int subframe=proc->subframe_tx;
|
int subframe=proc->subframe_tx;
|
||||||
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
|
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
|
||||||
@@ -265,27 +263,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
|
|||||||
dlsch_harq->round);
|
dlsch_harq->round);
|
||||||
}
|
}
|
||||||
|
|
||||||
MSC_LOG_TX_MESSAGE(
|
|
||||||
MSC_PHY_ENB,MSC_PHY_UE,
|
|
||||||
NULL,0,
|
|
||||||
"%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", TBS %"PRIu16", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
|
|
||||||
frame, subframe,
|
|
||||||
dlsch_harq->TBS/8,
|
|
||||||
get_G(fp,
|
|
||||||
dlsch_harq->nb_rb,
|
|
||||||
dlsch_harq->rb_alloc,
|
|
||||||
dlsch_harq->Qm,
|
|
||||||
dlsch_harq->Nl,
|
|
||||||
dlsch_harq->pdsch_start,
|
|
||||||
frame,
|
|
||||||
subframe,
|
|
||||||
dlsch_harq->mimo_mode==TM7?7:0),
|
|
||||||
dlsch_harq->nb_rb,
|
|
||||||
dlsch_harq->TBS,
|
|
||||||
pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
|
|
||||||
dlsch_harq->rvidx,
|
|
||||||
dlsch_harq->round);
|
|
||||||
|
|
||||||
if (ue_stats) ue_stats->dlsch_sliding_cnt++;
|
if (ue_stats) ue_stats->dlsch_sliding_cnt++;
|
||||||
|
|
||||||
if (dlsch_harq->round == 0) {
|
if (dlsch_harq->round == 0) {
|
||||||
@@ -300,15 +277,17 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dlsch->rnti!=0xffff) LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n",
|
if (dlsch->rnti!=0xffff)
|
||||||
dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round);
|
LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n",
|
||||||
|
dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],
|
||||||
|
dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round);
|
||||||
|
|
||||||
// 36-212
|
// 36-212
|
||||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
|
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
|
||||||
if (dlsch_harq->pdu==NULL) {
|
if (dlsch_harq->pdu==NULL) {
|
||||||
LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu,
|
LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu,
|
||||||
dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]);
|
dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
start_meas(&eNB->dlsch_encoding_stats);
|
start_meas(&eNB->dlsch_encoding_stats);
|
||||||
@@ -330,44 +309,57 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
|
|||||||
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
|
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
|
||||||
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
|
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 36-211
|
|
||||||
start_meas(&eNB->dlsch_scrambling_stats);
|
|
||||||
dlsch_scrambling(fp,
|
|
||||||
0,
|
|
||||||
dlsch,
|
|
||||||
harq_pid,
|
|
||||||
get_G(fp,
|
|
||||||
dlsch_harq->nb_rb,
|
|
||||||
dlsch_harq->rb_alloc,
|
|
||||||
dlsch_harq->Qm,
|
|
||||||
dlsch_harq->Nl,
|
|
||||||
dlsch_harq->pdsch_start,
|
|
||||||
frame,subframe,
|
|
||||||
0),
|
|
||||||
0,
|
|
||||||
frame,
|
|
||||||
subframe<<1);
|
|
||||||
stop_meas(&eNB->dlsch_scrambling_stats);
|
|
||||||
start_meas(&eNB->dlsch_modulation_stats);
|
|
||||||
dlsch_modulation(eNB,
|
|
||||||
eNB->common_vars.txdataF,
|
|
||||||
AMP,
|
|
||||||
frame,
|
|
||||||
subframe,
|
|
||||||
dlsch_harq->pdsch_start,
|
|
||||||
dlsch,
|
|
||||||
dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
|
|
||||||
stop_meas(&eNB->dlsch_modulation_stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PHY_TX_THREAD
|
#ifdef PHY_TX_THREAD
|
||||||
dlsch->active[subframe] = 0;
|
dlsch->active[subframe] = 0;
|
||||||
#else
|
#else
|
||||||
dlsch->active = 0;
|
dlsch->active = 0;
|
||||||
#endif
|
#endif
|
||||||
dlsch_harq->round++;
|
dlsch_harq->round++;
|
||||||
LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
|
LOG_D(PHY,"Generated DLSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
|
int harq_pid,
|
||||||
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
|
LTE_eNB_DLSCH_t *dlsch1) {
|
||||||
|
int frame=proc->frame_tx;
|
||||||
|
int subframe=proc->subframe_tx;
|
||||||
|
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
|
||||||
|
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
||||||
|
// 36-211
|
||||||
|
start_meas(&eNB->dlsch_scrambling_stats);
|
||||||
|
dlsch_scrambling(fp,
|
||||||
|
0,
|
||||||
|
dlsch,
|
||||||
|
harq_pid,
|
||||||
|
get_G(fp,
|
||||||
|
dlsch_harq->nb_rb,
|
||||||
|
dlsch_harq->rb_alloc,
|
||||||
|
dlsch_harq->Qm,
|
||||||
|
dlsch_harq->Nl,
|
||||||
|
dlsch_harq->pdsch_start,
|
||||||
|
frame,subframe,
|
||||||
|
0),
|
||||||
|
0,
|
||||||
|
frame,
|
||||||
|
subframe<<1);
|
||||||
|
stop_meas(&eNB->dlsch_scrambling_stats);
|
||||||
|
start_meas(&eNB->dlsch_modulation_stats);
|
||||||
|
dlsch_modulation(eNB,
|
||||||
|
eNB->common_vars.txdataF,
|
||||||
|
AMP,
|
||||||
|
frame,
|
||||||
|
subframe,
|
||||||
|
dlsch_harq->pdsch_start,
|
||||||
|
dlsch,
|
||||||
|
dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
|
||||||
|
stop_meas(&eNB->dlsch_modulation_stats);
|
||||||
|
|
||||||
|
LOG_D(PHY,"Generated PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -531,14 +523,18 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
|
|||||||
dlsch0->harq_ids[frame%2][6],
|
dlsch0->harq_ids[frame%2][6],
|
||||||
dlsch0->harq_ids[frame%2][7]);
|
dlsch0->harq_ids[frame%2][7]);
|
||||||
} else {
|
} else {
|
||||||
// generate pdsch
|
if (dlsch_procedures(eNB,
|
||||||
pdsch_procedures(eNB,
|
|
||||||
proc,
|
proc,
|
||||||
harq_pid,
|
harq_pid,
|
||||||
dlsch0,
|
dlsch0,
|
||||||
dlsch1,
|
&eNB->UE_stats[(uint32_t)UE_id])) {
|
||||||
&eNB->UE_stats[(uint32_t)UE_id],
|
// if we generate dlsch, we must generate pdsch
|
||||||
0);
|
pdsch_procedures(eNB,
|
||||||
|
proc,
|
||||||
|
harq_pid,
|
||||||
|
dlsch0,
|
||||||
|
dlsch1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
|
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
|
||||||
#ifdef PHY_TX_THREAD
|
#ifdef PHY_TX_THREAD
|
||||||
|
|||||||
@@ -1204,6 +1204,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
|||||||
return(chan_desc);
|
return(chan_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_channel_desc_scm(channel_desc_t * ch) {
|
||||||
|
// Must be made cleanly, a lot of leaks...
|
||||||
|
free(ch);
|
||||||
|
}
|
||||||
|
|
||||||
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
|
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
|
|||||||
if ( IS_SOFTMODEM_BASICSIM ) {
|
if ( IS_SOFTMODEM_BASICSIM ) {
|
||||||
libname=OAI_BASICSIM_LIBNAME;
|
libname=OAI_BASICSIM_LIBNAME;
|
||||||
shlib_fdesc[0].fname="device_init";
|
shlib_fdesc[0].fname="device_init";
|
||||||
} else if ( IS_SOFTMODEM_RFSIM ) {
|
} else if ( IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
|
||||||
libname=OAI_RFSIM_LIBNAME;
|
libname=OAI_RFSIM_LIBNAME;
|
||||||
shlib_fdesc[0].fname="device_init";
|
shlib_fdesc[0].fname="device_init";
|
||||||
} else if (flag == RAU_LOCAL_RADIO_HEAD) {
|
} else if (flag == RAU_LOCAL_RADIO_HEAD) {
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ pthread_mutex_t Sockmutex;
|
|||||||
|
|
||||||
typedef struct buffer_s {
|
typedef struct buffer_s {
|
||||||
int conn_sock;
|
int conn_sock;
|
||||||
bool alreadyRead;
|
openair0_timestamp lastReceivedTS;
|
||||||
uint64_t lastReceivedTS;
|
openair0_timestamp lastWroteTS;
|
||||||
bool headerMode;
|
bool headerMode;
|
||||||
samplesBlockHeader_t th;
|
samplesBlockHeader_t th;
|
||||||
char *transferPtr;
|
char *transferPtr;
|
||||||
@@ -60,7 +60,7 @@ typedef struct buffer_s {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int listen_sock, epollfd;
|
int listen_sock, epollfd;
|
||||||
uint64_t nextTimestamp;
|
openair0_timestamp nextTimestamp;
|
||||||
uint64_t typeStamp;
|
uint64_t typeStamp;
|
||||||
char *ip;
|
char *ip;
|
||||||
int saveIQfile;
|
int saveIQfile;
|
||||||
@@ -104,9 +104,9 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
|
|||||||
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
|
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
|
||||||
// the parameter "-s" is declared as SNR, but the input power is not well defined
|
// the parameter "-s" is declared as SNR, but the input power is not well defined
|
||||||
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
|
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
|
||||||
const double rxGain= 132.24 - snr_dB;
|
const double rxGain= 132.24 - snr_dB;
|
||||||
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
|
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
|
||||||
// fixme: the last constant is pure trial results to make decent noise
|
// fixme: the last constant is pure trial results to make decent noise
|
||||||
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
|
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
|
||||||
// Fixme: we don't fill the offset length samples at begining ?
|
// Fixme: we don't fill the offset length samples at begining ?
|
||||||
// anyway, in today code, channel_offset=0
|
// anyway, in today code, channel_offset=0
|
||||||
@@ -135,9 +135,6 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||||
printf("in: %d, out %d= %f*%f + %f*%f\n",
|
|
||||||
input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
|
|
||||||
pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
|
|
||||||
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||||
out_ptr++;
|
out_ptr++;
|
||||||
}
|
}
|
||||||
@@ -156,8 +153,8 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|||||||
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
|
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
|
||||||
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
|
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
|
||||||
ptr->conn_sock=sock;
|
ptr->conn_sock=sock;
|
||||||
ptr->alreadyRead=false;
|
|
||||||
ptr->lastReceivedTS=0;
|
ptr->lastReceivedTS=0;
|
||||||
|
ptr->lastWroteTS=0;
|
||||||
ptr->headerMode=true;
|
ptr->headerMode=true;
|
||||||
ptr->transferPtr=(char *)&ptr->th;
|
ptr->transferPtr=(char *)&ptr->th;
|
||||||
ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
|
ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
|
||||||
@@ -322,21 +319,22 @@ sin_addr:
|
|||||||
|
|
||||||
setblocking(sock, notBlocking);
|
setblocking(sock, notBlocking);
|
||||||
allocCirBuf(t, sock);
|
allocCirBuf(t, sock);
|
||||||
t->buf[sock].alreadyRead=true; // UE will start blocking on read
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t lastW=-1;
|
|
||||||
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
||||||
rfsimulator_state_t *t = device->priv;
|
rfsimulator_state_t *t = device->priv;
|
||||||
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
|
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
|
||||||
|
|
||||||
for (int i=0; i<FD_SETSIZE; i++) {
|
|
||||||
buffer_t *ptr=&t->buf[i];
|
|
||||||
|
|
||||||
if (ptr->conn_sock >= 0 ) {
|
for (int i=0; i<FD_SETSIZE; i++) {
|
||||||
|
buffer_t *b=&t->buf[i];
|
||||||
|
|
||||||
|
if (b->conn_sock >= 0 ) {
|
||||||
|
if ( abs((double)b->lastWroteTS-timestamp) > (double)CirSize)
|
||||||
|
LOG_E(HW,"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
|
||||||
samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
|
samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
|
||||||
fullwrite(ptr->conn_sock,&header, sizeof(header), t);
|
fullwrite(b->conn_sock,&header, sizeof(header), t);
|
||||||
sample_t tmpSamples[nsamps][nbAnt];
|
sample_t tmpSamples[nsamps][nbAnt];
|
||||||
|
|
||||||
for(int a=0; a<nbAnt; a++) {
|
for(int a=0; a<nbAnt; a++) {
|
||||||
@@ -346,17 +344,17 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
|
|||||||
tmpSamples[s][a]=in[s];
|
tmpSamples[s][a]=in[s];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr->conn_sock >= 0 )
|
if (b->conn_sock >= 0 ) {
|
||||||
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
|
fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
|
||||||
|
b->lastWroteTS=timestamp+nsamps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastW=timestamp;
|
|
||||||
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
||||||
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
||||||
// Let's verify we don't have incoming data
|
// Let's verify we don't have incoming data
|
||||||
// This is mandatory when the opposite side don't transmit
|
// This is mandatory when the opposite side don't transmit
|
||||||
// This is mandatory when the opposite side don't transmit
|
|
||||||
flushInput(t, 0);
|
flushInput(t, 0);
|
||||||
pthread_mutex_unlock(&Sockmutex);
|
pthread_mutex_unlock(&Sockmutex);
|
||||||
return nsamps;
|
return nsamps;
|
||||||
@@ -428,7 +426,6 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
|||||||
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
|
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
|
||||||
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
|
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
|
||||||
b->headerMode=false;
|
b->headerMode=false;
|
||||||
b->alreadyRead=true;
|
|
||||||
|
|
||||||
if ( b->lastReceivedTS != b->th.timestamp) {
|
if ( b->lastReceivedTS != b->th.timestamp) {
|
||||||
int nbAnt= b->th.nbAnt;
|
int nbAnt= b->th.nbAnt;
|
||||||
@@ -444,8 +441,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b->lastReceivedTS=b->th.timestamp;
|
b->lastReceivedTS=b->th.timestamp;
|
||||||
AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
|
AssertFatal(b->lastWroteTS == 0 || ( abs((double)b->lastWroteTS-b->lastReceivedTS) < (double)CirSize),
|
||||||
"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
|
"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
|
||||||
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
|
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
|
||||||
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
|
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
|
||||||
}
|
}
|
||||||
@@ -501,15 +498,33 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|||||||
return nsamps;
|
return nsamps;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
bool have_to_wait;
|
bool have_to_wait;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
have_to_wait=false;
|
have_to_wait=false;
|
||||||
|
|
||||||
for ( int sock=0; sock<FD_SETSIZE; sock++) {
|
for ( int sock=0; sock<FD_SETSIZE; sock++) {
|
||||||
if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead )
|
buffer_t *b=&t->buf[sock];
|
||||||
if ( t->buf[sock].lastReceivedTS == 0 ||
|
if ( b->circularBuf) {
|
||||||
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
|
LOG_D(HW,"sock: %d, lastWroteTS: %lu, lastRecvTS: %lu, TS must be avail: %lu\n",
|
||||||
|
sock, b->lastWroteTS,
|
||||||
|
b->lastReceivedTS,
|
||||||
|
t->nextTimestamp+nsamps);
|
||||||
|
if ( b->lastReceivedTS > b->lastWroteTS ) {
|
||||||
|
// The caller momdem (NB, UE, ...) must send Tx in advance, so we fill TX if Rx is in advance
|
||||||
|
// This occurs for example when UE is in sync mode: it doesn't transmit
|
||||||
|
// with USRP, it seems ok: if "tx stream" is off, we may consider it actually cuts the Tx power
|
||||||
|
struct complex16 v={0};
|
||||||
|
void *samplesVoid[b->th.nbAnt];
|
||||||
|
for ( int i=0; i <b->th.nbAnt; i++)
|
||||||
|
samplesVoid[i]=(void*)&v;
|
||||||
|
rfsimulator_write(device, b->lastReceivedTS, samplesVoid, 1, b->th.nbAnt, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( b->circularBuf )
|
||||||
|
if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
|
||||||
have_to_wait=true;
|
have_to_wait=true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -532,7 +547,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|||||||
for (int sock=0; sock<FD_SETSIZE; sock++) {
|
for (int sock=0; sock<FD_SETSIZE; sock++) {
|
||||||
buffer_t *ptr=&t->buf[sock];
|
buffer_t *ptr=&t->buf[sock];
|
||||||
|
|
||||||
if ( ptr->circularBuf && ptr->alreadyRead ) {
|
if ( ptr->circularBuf ) {
|
||||||
bool reGenerateChannel=false;
|
bool reGenerateChannel=false;
|
||||||
|
|
||||||
//fixme: when do we regenerate
|
//fixme: when do we regenerate
|
||||||
|
|||||||
Reference in New Issue
Block a user