mirror of https://github.com/PentHertz/srsLTE.git
ConnectionSetup working with MAC test
This commit is contained in:
parent
68d193a725
commit
0b3c611f38
|
@ -1,21 +1,26 @@
|
|||
clear;
|
||||
sym_len=128;
|
||||
hflen = (sym_len/128)*1920*10;
|
||||
hflen = (sym_len/128)*1920*5;
|
||||
samp_rate = (sym_len/128)*1920000;
|
||||
N_id_2=1;
|
||||
input=read_complex('../../build/lte_signal.dat', hflen*500);
|
||||
input=read_complex('../../build/lte_signal.dat', hflen*200);
|
||||
|
||||
cp0_len=160*sym_len/2048;
|
||||
cp1_len=144*sym_len/2048;
|
||||
|
||||
%t = (0:length(input)-1).'/samp_rate;
|
||||
%input = input .* exp(-1i*2*pi*2000.0*t);
|
||||
|
||||
subframes=reshape(input,hflen,[]);
|
||||
[n m]=size(subframes);
|
||||
|
||||
cfdl=struct('NDLRB',6,'CyclicPrefix','Normal','DuplexMode','FDD');
|
||||
cfo=zeros(m,2);
|
||||
for i=1:m
|
||||
cfo(i,1) = cfo_estimate_cp(subframes(1:960,i),1,sym_len,cp0_len,cp1_len);
|
||||
[~, cfo(i,2)] = find_pss(subframes(:,i),N_id_2);
|
||||
|
||||
[toffset, cfo(i,2)] = find_pss(subframes(:,i),N_id_2);
|
||||
cfo(i,1) = lteFrequencyOffset(cfdl,subframes(:,i),toffset)/15000;
|
||||
end
|
||||
|
||||
plot(cfo)
|
||||
legend('CP-based','PSS-based')
|
||||
plot(cfo*15000)
|
||||
legend('Matlab','PSS-based')
|
||||
disp(mean(cfo)*15)
|
||||
|
|
|
@ -10,7 +10,7 @@ NULRB=[6 15 25 50 100];
|
|||
|
||||
for n_rb=3:length(NULRB)
|
||||
for format=0;
|
||||
for seqIdx=0:17:237
|
||||
for seqIdx=7:17:237
|
||||
fprintf('RB: %d, format %d, seqIdx: %d\n',NULRB(n_rb),format,seqIdx);
|
||||
for preambleIdx=0:23:63
|
||||
for CyclicShift=1:3:15
|
||||
|
@ -24,10 +24,10 @@ for n_rb=3:length(NULRB)
|
|||
prachConfig.HighSpeed=hs;
|
||||
prachConfig.FreqIdx=0;
|
||||
prachConfig.FreqOffset=0;
|
||||
lib=srslte_prach(ueConfig,prachConfig);
|
||||
lib=srslte_prach(ueConfig,prachConfig)*2.4645;
|
||||
|
||||
[mat, info]=ltePRACH(ueConfig,prachConfig);
|
||||
err=mean(abs(mat(:)-lib(1:length(mat))));
|
||||
err=mean(abs(mat-lib));
|
||||
if (err > 10^-3)
|
||||
disp(err)
|
||||
error('Error!');
|
||||
|
|
|
@ -40,10 +40,10 @@
|
|||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#define Error(fmt, ...) log_h->error(tti, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Warning(fmt, ...) log_h->warning(tti, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Info(fmt, ...) log_h->info(tti, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Debug(fmt, ...) log_h->debug(tti, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Error(fmt, ...) log_h->error(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Warning(fmt, ...) log_h->warning(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Info(fmt, ...) log_h->info(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define Debug(fmt, ...) log_h->debug(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -53,23 +53,42 @@ class log
|
|||
{
|
||||
public:
|
||||
|
||||
log(string service_name_) { service_name = service_name_; }
|
||||
log(string service_name_) { service_name = service_name_; tti = 0; level = LOG_LEVEL_NONE; }
|
||||
|
||||
// This function shall be called at the start of every tti for printing tti
|
||||
void step(uint32_t tti_) {
|
||||
tti = tti_;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
LOG_LEVEL_NONE = 0,
|
||||
LOG_LEVEL_INFO,
|
||||
LOG_LEVEL_DEBUG
|
||||
} log_level_t;
|
||||
|
||||
void set_level_info() {
|
||||
level = LOG_LEVEL_INFO;
|
||||
}
|
||||
void set_level_debug() {
|
||||
level = LOG_LEVEL_DEBUG;
|
||||
}
|
||||
|
||||
// Pure virtual methods for logging
|
||||
virtual void error(uint32_t tti, string message, ...) = 0;
|
||||
virtual void warning(uint32_t tti, string message, ...) = 0;
|
||||
virtual void info(uint32_t tti, string message, ...) = 0;
|
||||
virtual void debug(uint32_t tti, string message, ...) = 0;
|
||||
virtual void error(string message, ...) = 0;
|
||||
virtual void warning(string message, ...) = 0;
|
||||
virtual void info(string message, ...) = 0;
|
||||
virtual void debug(string message, ...) = 0;
|
||||
|
||||
// Same with line and file info
|
||||
virtual void error(uint32_t tti, string file, int line, string message, ...) = 0;
|
||||
virtual void warning(uint32_t tti, string file, int line, string message, ...) = 0;
|
||||
virtual void info(uint32_t tti, string file, int line, string message, ...) = 0;
|
||||
virtual void debug(uint32_t tti, string file, int line, string message, ...) = 0;
|
||||
virtual void error(string file, int line, string message, ...) = 0;
|
||||
virtual void warning(string file, int line, string message, ...) = 0;
|
||||
virtual void info(string file, int line, string message, ...) = 0;
|
||||
virtual void debug(string file, int line, string message, ...) = 0;
|
||||
|
||||
protected:
|
||||
string get_service_name() { return service_name; }
|
||||
|
||||
uint32_t tti;
|
||||
log_level_t level;
|
||||
private:
|
||||
string service_name;
|
||||
};
|
||||
|
|
|
@ -53,16 +53,16 @@ public:
|
|||
|
||||
log_stdout(string service_name_) : log(service_name_) { }
|
||||
|
||||
void error(uint32_t tti, string message, ...);
|
||||
void warning(uint32_t tti, string message, ...);
|
||||
void info(uint32_t tti, string message, ...);
|
||||
void debug(uint32_t tti, string message, ...);
|
||||
void error(string message, ...);
|
||||
void warning(string message, ...);
|
||||
void info(string message, ...);
|
||||
void debug(string message, ...);
|
||||
|
||||
// Same with line and file info
|
||||
void error(uint32_t tti, string file, int line, string message, ...);
|
||||
void warning(uint32_t tti, string file, int line, string message, ...);
|
||||
void info(uint32_t tti, string file, int line, string message, ...);
|
||||
void debug(uint32_t tti, string file, int line, string message, ...);
|
||||
void error(string file, int line, string message, ...);
|
||||
void warning(string file, int line, string message, ...);
|
||||
void info(string file, int line, string message, ...);
|
||||
void debug(string file, int line, string message, ...);
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
|
|
|
@ -59,7 +59,7 @@ void log_stdout::printlog(level_t type, uint32_t tti, string file, int line, str
|
|||
vprintf(msg.c_str(), args);
|
||||
}
|
||||
|
||||
void log_stdout::error(uint32_t tti, string msg, ...)
|
||||
void log_stdout::error(string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
@ -67,23 +67,27 @@ void log_stdout::error(uint32_t tti, string msg, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
void log_stdout::info(uint32_t tti, string msg, ...)
|
||||
void log_stdout::info(string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(INFO, tti, msg, args);
|
||||
va_end(args);
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(INFO, tti, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::debug(uint32_t tti, string msg, ...)
|
||||
void log_stdout::debug(string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(DEBUG, tti, msg, args);
|
||||
va_end(args);
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(DEBUG, tti, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::warning(uint32_t tti, string msg, ...)
|
||||
void log_stdout::warning(string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
@ -92,7 +96,7 @@ void log_stdout::warning(uint32_t tti, string msg, ...)
|
|||
}
|
||||
|
||||
|
||||
void log_stdout::error(uint32_t tti, string file, int line, string msg, ...)
|
||||
void log_stdout::error(string file, int line, string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
@ -100,23 +104,27 @@ void log_stdout::error(uint32_t tti, string file, int line, string msg, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
void log_stdout::info(uint32_t tti, string file, int line, string msg, ...)
|
||||
void log_stdout::info(string file, int line, string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(INFO, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(INFO, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::debug(uint32_t tti, string file, int line, string msg, ...)
|
||||
void log_stdout::debug(string file, int line, string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(DEBUG, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
printlog(DEBUG, tti, file, line, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::warning(uint32_t tti, string file, int line, string msg, ...)
|
||||
void log_stdout::warning(string file, int line, string msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace srslte {
|
|||
|
||||
virtual void set_tx_gain(float gain) = 0;
|
||||
virtual void set_rx_gain(float gain) = 0;
|
||||
virtual double set_rx_gain_th(float gain) = 0;
|
||||
|
||||
virtual void set_tx_freq(float freq) = 0;
|
||||
virtual void set_rx_freq(float freq) = 0;
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
|
||||
|
||||
#include "srsapps/radio/radio.h"
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/common/radio.h"
|
||||
#include "srslte/cuhd/cuhd.h"
|
||||
|
||||
#ifndef RADIO_UHD_H
|
||||
|
@ -44,6 +44,8 @@ namespace srslte {
|
|||
public:
|
||||
bool init();
|
||||
bool init(char *args);
|
||||
bool init_agc();
|
||||
bool init_agc(char *args);
|
||||
|
||||
void get_time(srslte_timestamp_t *now);
|
||||
bool tx(void *buffer, uint32_t nof_samples, srslte_timestamp_t tx_time);
|
||||
|
@ -52,6 +54,8 @@ namespace srslte {
|
|||
|
||||
void set_tx_gain(float gain);
|
||||
void set_rx_gain(float gain);
|
||||
void set_tx_rx_gain_offset(float offset);
|
||||
double set_rx_gain_th(float gain);
|
||||
|
||||
void set_tx_freq(float freq);
|
||||
void set_rx_freq(float freq);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
*/
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/common/radio.h"
|
||||
#include "srsapps/radio/radio_uhd.h"
|
||||
|
||||
|
||||
|
@ -47,6 +46,26 @@ bool radio_uhd::init(char *args)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool radio_uhd::init_agc()
|
||||
{
|
||||
return init_agc((char*) "");
|
||||
}
|
||||
|
||||
void radio_uhd::set_tx_rx_gain_offset(float offset) {
|
||||
cuhd_set_tx_rx_gain_offset(uhd, offset);
|
||||
}
|
||||
|
||||
bool radio_uhd::init_agc(char *args)
|
||||
{
|
||||
printf("Opening UHD device with threaded RX Gain control ...\n");
|
||||
if (cuhd_open_th(args, &uhd, true)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
return false;
|
||||
}
|
||||
cuhd_set_rx_gain(uhd, 40);
|
||||
cuhd_set_tx_gain(uhd, 40);
|
||||
return true;
|
||||
}
|
||||
bool radio_uhd::rx_at(void* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time)
|
||||
{
|
||||
fprintf(stderr, "Not implemented\n");
|
||||
|
@ -85,6 +104,12 @@ void radio_uhd::set_rx_gain(float gain)
|
|||
cur_rx_gain = cuhd_set_rx_gain(uhd, gain);
|
||||
}
|
||||
|
||||
double radio_uhd::set_rx_gain_th(float gain)
|
||||
{
|
||||
cur_rx_gain = cuhd_set_rx_gain_th(uhd, gain);
|
||||
return cur_rx_gain;
|
||||
}
|
||||
|
||||
void radio_uhd::set_rx_srate(float srate)
|
||||
{
|
||||
cur_rx_srate = cuhd_set_rx_srate(uhd, srate);
|
||||
|
|
|
@ -48,11 +48,13 @@ public:
|
|||
demux();
|
||||
void init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_);
|
||||
|
||||
void push_pdu(uint32_t tti, uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu_bcch(uint32_t tti, uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu_temp_crnti(uint32_t tti, uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu(uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu_bcch(uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
void push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits);
|
||||
bool is_temp_crnti_pending();
|
||||
void demultiplex_pending_pdu(uint32_t tti);
|
||||
bool is_contention_resolution_id_pending();
|
||||
void demultiplex_pending_pdu();
|
||||
void discard_pending_pdu();
|
||||
|
||||
uint64_t get_contention_resolution_id();
|
||||
|
||||
|
@ -65,12 +67,12 @@ private:
|
|||
|
||||
uint64_t contention_resolution_id;
|
||||
bool pending_temp_rnti;
|
||||
bool has_pending_contention_resolution_id;
|
||||
|
||||
phy *phy_h;
|
||||
log *log_h;
|
||||
mac_io *mac_io_h;
|
||||
timers *timers_db;
|
||||
uint32_t tti;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,10 +52,9 @@ public:
|
|||
const static uint32_t HARQ_BCCH_PID = NOF_HARQ_PROC;
|
||||
|
||||
dl_harq_entity();
|
||||
~dl_harq_entity();
|
||||
bool init(srslte_cell_t cell, uint32_t max_payload_len, srslte::log *log_h_, timers *timers_, demux *demux_unit);
|
||||
bool is_sps(uint32_t pid);
|
||||
void set_harq_info(uint32_t tti, uint32_t pid, dl_sched_grant *grant);
|
||||
void set_harq_info(uint32_t pid, dl_sched_grant *grant);
|
||||
void receive_data(uint32_t tti, uint32_t pid, dl_buffer *dl_buffer, phy *phy_h);
|
||||
void reset();
|
||||
bool is_ack_pending_resolution();
|
||||
|
@ -67,7 +66,7 @@ private:
|
|||
public:
|
||||
dl_harq_process();
|
||||
bool init(srslte_cell_t cell, uint32_t max_payload_len, dl_harq_entity *parent);
|
||||
void set_harq_info(uint32_t tti, dl_sched_grant *grant);
|
||||
void set_harq_info(dl_sched_grant *grant);
|
||||
void receive_data(uint32_t tti, dl_buffer *dl_buffer, phy *phy_h);
|
||||
void reset();
|
||||
// Called after the contention resolution is terminated to send pending ACKs, if any
|
||||
|
@ -90,7 +89,7 @@ private:
|
|||
srslte_softbuffer_rx_t softbuffer;
|
||||
};
|
||||
|
||||
dl_harq_process *proc;
|
||||
dl_harq_process proc[NOF_HARQ_PROC+1];
|
||||
timers *timers_db;
|
||||
demux *demux_unit;
|
||||
srslte::log *log_h;
|
||||
|
|
|
@ -79,7 +79,13 @@ namespace ue {
|
|||
RA_PREAMBLETRANSMAX,
|
||||
RA_INITRECEIVEDPOWER,
|
||||
RA_CONTENTIONTIMER,
|
||||
RA_MAXTXMSG3,
|
||||
|
||||
SR_PUCCH_RESINDEX,
|
||||
SR_CONFIG_INDEX,
|
||||
SR_TRANS_MAX,
|
||||
|
||||
HARQ_MAXTX,
|
||||
HARQ_MAXMSG3TX,
|
||||
|
||||
PDSCH_RSPOWER,
|
||||
PDSCH_PB,
|
||||
|
|
|
@ -50,14 +50,14 @@ public:
|
|||
|
||||
bool is_pending_sdu();
|
||||
|
||||
uint8_t* pdu_pop(uint32_t tti_, uint32_t pdu_sz);
|
||||
bool pdu_move_to_msg3(uint32_t tti, uint32_t pdu_sz);
|
||||
uint8_t* pdu_pop(uint32_t pdu_sz);
|
||||
bool pdu_move_to_msg3(uint32_t pdu_sz);
|
||||
void pdu_release();
|
||||
|
||||
uint8_t* msg3_pop(uint32_t tti_, uint32_t pdu_sz);
|
||||
uint8_t* msg3_pop(uint32_t pdu_sz);
|
||||
void msg3_flush();
|
||||
void msg3_release();
|
||||
bool msg3_isempty();
|
||||
void msg3_transmitted();
|
||||
bool msg3_is_transmitted();
|
||||
|
||||
void append_crnti_ce_next_tx(uint16_t crnti);
|
||||
|
||||
|
@ -81,7 +81,6 @@ private:
|
|||
|
||||
log *log_h;
|
||||
mac_io *mac_io_h;
|
||||
uint32_t tti;
|
||||
uint16_t pending_crnti_ce;
|
||||
|
||||
/* Msg3 Buffer */
|
||||
|
@ -92,6 +91,7 @@ private:
|
|||
static const uint32_t PDU_BUFF_SZ = 16*1024;
|
||||
qbuff pdu_buff;
|
||||
sch_pdu pdu_msg;
|
||||
bool msg3_has_been_transmitted;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ public:
|
|||
|
||||
// Section 6.1.2
|
||||
void parse_packet(uint8_t *ptr) {
|
||||
uint8_t *init_ptr = ptr;
|
||||
nof_subheaders = 0;
|
||||
while(subheaders[nof_subheaders].read_subheader(&ptr)) {
|
||||
nof_subheaders++;
|
||||
|
@ -177,6 +178,8 @@ public:
|
|||
// Reading functions
|
||||
bool is_sdu();
|
||||
cetype ce_type();
|
||||
uint32_t size_plus_header();
|
||||
void set_payload_size(uint32_t size);
|
||||
|
||||
bool read_subheader(uint8_t** ptr);
|
||||
void read_payload(uint8_t **ptr);
|
||||
|
@ -218,10 +221,12 @@ public:
|
|||
|
||||
sch_pdu(uint32_t max_rars) : pdu(max_rars) {}
|
||||
|
||||
void parse_packet(uint8_t *ptr);
|
||||
bool write_packet(uint8_t *ptr);
|
||||
bool has_space_ce(uint32_t nbytes);
|
||||
bool has_space_sdu(uint32_t nbytes);
|
||||
static uint32_t size_plus_header_pdu(uint32_t nbytes);
|
||||
uint32_t size();
|
||||
static uint32_t size_plus_header_sdu(uint32_t nbytes);
|
||||
bool update_space_ce(uint32_t nbytes);
|
||||
bool update_space_sdu(uint32_t nbytes);
|
||||
void fprint(FILE *stream);
|
||||
|
|
|
@ -59,6 +59,7 @@ class ra_proc : public proc,timer_callback
|
|||
void start_mac_order();
|
||||
void step(uint32_t tti);
|
||||
bool is_successful();
|
||||
bool is_response_error();
|
||||
bool is_contention_resolution();
|
||||
bool is_error();
|
||||
bool in_progress();
|
||||
|
@ -67,7 +68,7 @@ class ra_proc : public proc,timer_callback
|
|||
|
||||
private:
|
||||
|
||||
void process_timeadv_cmd(uint32_t tti, uint32_t ta_cmd);
|
||||
void process_timeadv_cmd(uint32_t ta_cmd);
|
||||
void step_initialization();
|
||||
void step_initialization_wait();
|
||||
void step_resource_selection();
|
||||
|
@ -98,7 +99,6 @@ private:
|
|||
uint32_t preambleTransMax;
|
||||
uint32_t iniReceivedTargetPower;
|
||||
int delta_preamble_db;
|
||||
uint32_t maxharq_msg3tx;
|
||||
uint32_t contentionResolutionTimer;
|
||||
uint32_t maskIndex;
|
||||
int preambleIndex;
|
||||
|
@ -145,7 +145,6 @@ private:
|
|||
|
||||
pthread_t pt_init_prach;
|
||||
|
||||
uint64_t received_contention_id;
|
||||
uint64_t transmitted_contention_id;
|
||||
uint16_t transmitted_crnti;
|
||||
enum {
|
||||
|
|
|
@ -51,18 +51,13 @@ public:
|
|||
const static uint32_t NOF_HARQ_PROC = 8;
|
||||
static uint32_t pidof(uint32_t tti);
|
||||
|
||||
ul_harq_entity();
|
||||
~ul_harq_entity();
|
||||
|
||||
bool init(srslte_cell_t cell, log *log_h, timers* timers_, mux *mux_unit);
|
||||
void set_maxHARQ_Tx(uint32_t maxHARQ_Tx, uint32_t maxHARQ_Msg3Tx);
|
||||
bool init(srslte_cell_t cell, mac_params *params_db, log *log_h, timers* timers_, mux *mux_unit);
|
||||
|
||||
void reset();
|
||||
void reset_ndi();
|
||||
bool is_sps(uint32_t pid);
|
||||
void run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_);
|
||||
void run_tti(uint32_t tti, dl_buffer *dl_buffer, phy *phy_);
|
||||
bool is_last_retx_msg3();
|
||||
void run_tti(uint32_t tti, phy *phy_);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -72,40 +67,40 @@ private:
|
|||
bool init(srslte_cell_t cell, ul_harq_entity *parent);
|
||||
void reset();
|
||||
void reset_ndi();
|
||||
void set_maxHARQ_Tx(uint32_t maxHARQ_Tx_, uint32_t maxHARQ_Msg3Tx_);
|
||||
|
||||
void generate_retx(ul_buffer *ul);
|
||||
void generate_retx(ul_sched_grant *ul_grant, ul_buffer *ul);
|
||||
void generate_new_tx(uint8_t *payload, bool is_msg3, ul_sched_grant* grant, ul_buffer *ul);
|
||||
void generate_retx(uint32_t tti_tx, ul_buffer *ul);
|
||||
void generate_retx(uint32_t tti_tx, ul_sched_grant *ul_grant, ul_buffer *ul);
|
||||
void generate_new_tx(uint32_t tti_tx, uint8_t *payload, bool is_msg3, ul_sched_grant* grant, ul_buffer *ul);
|
||||
|
||||
uint32_t get_rv();
|
||||
bool has_grant();
|
||||
ul_sched_grant *get_grant();
|
||||
void set_harq_feedback(bool ack);
|
||||
bool get_ndi();
|
||||
uint32_t last_tx_tti();
|
||||
|
||||
uint32_t tti;
|
||||
private:
|
||||
uint32_t current_tx_nb;
|
||||
uint32_t current_irv;
|
||||
bool harq_feedback;
|
||||
bool ndi;
|
||||
srslte::log *log_h;
|
||||
log *log_h;
|
||||
ul_harq_entity *harq_entity;
|
||||
ul_sched_grant cur_grant;
|
||||
bool is_grant_configured;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
uint32_t maxHARQ_Tx, maxHARQ_Msg3Tx;
|
||||
bool is_msg3;
|
||||
bool is_initiated;
|
||||
uint32_t tti_last_tx;
|
||||
|
||||
void generate_tx(uint8_t *pdu_payload, ul_buffer* ul);
|
||||
void generate_tx(uint32_t tti_tx, uint8_t *pdu_payload, ul_buffer* ul);
|
||||
};
|
||||
|
||||
bool last_retx_is_msg3;
|
||||
timers *timers_db;
|
||||
mux *mux_unit;
|
||||
ul_harq_process *proc;
|
||||
srslte::log *log_h;
|
||||
ul_harq_process proc[NOF_HARQ_PROC];
|
||||
log *log_h;
|
||||
mac_params *params_db;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ demux::demux() : mac_msg(20),pending_mac_msg(20)
|
|||
{
|
||||
contention_resolution_id = 0;
|
||||
pending_temp_rnti = false;
|
||||
has_pending_contention_resolution_id = false;
|
||||
}
|
||||
|
||||
void demux::init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_)
|
||||
|
@ -52,10 +53,15 @@ bool demux::is_temp_crnti_pending()
|
|||
return pending_temp_rnti;
|
||||
}
|
||||
|
||||
bool demux::is_contention_resolution_id_pending() {
|
||||
return has_pending_contention_resolution_id;
|
||||
}
|
||||
|
||||
uint64_t demux::get_contention_resolution_id()
|
||||
{
|
||||
uint64_t x = contention_resolution_id;
|
||||
contention_resolution_id = 0;
|
||||
has_pending_contention_resolution_id = false;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
@ -63,9 +69,8 @@ uint64_t demux::get_contention_resolution_id()
|
|||
/* Demultiplexing of MAC PDU associated with SI-RNTI. The PDU passes through
|
||||
* the MAC in transparent mode
|
||||
*/
|
||||
void demux::push_pdu_bcch(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
void demux::push_pdu_bcch(uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
{
|
||||
tti = tti_;
|
||||
mac_io_h->get(mac_io::MAC_LCH_BCCH_DL)->send(mac_pdu, nof_bits);
|
||||
Debug("Pushed BCCH MAC PDU in transparent mode\n");
|
||||
}
|
||||
|
@ -76,35 +81,32 @@ void demux::push_pdu_bcch(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bits)
|
|||
* wether the PDU shall pass to upper layers or not, which depends on the
|
||||
* Contention Resolution result
|
||||
*/
|
||||
void demux::push_pdu_temp_crnti(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
{
|
||||
tti = tti_;
|
||||
if (!pending_temp_rnti) {
|
||||
// Unpack DLSCH MAC PDU
|
||||
pending_mac_msg.init(nof_bits/8);
|
||||
pending_mac_msg.parse_packet(mac_pdu);
|
||||
pending_mac_msg.fprint(stdout);
|
||||
|
||||
//MIRAR ACK PENDING. EL QUE PASSA ES QUE AL HARQ NO FA RES SI EL CONTENTION RES ID ES 0, PERQUE ES 0???
|
||||
|
||||
// Look for Contention Resolution UE ID
|
||||
contention_resolution_id = 0;
|
||||
while(pending_mac_msg.next()) {
|
||||
if (pending_mac_msg.get()->ce_type() == sch_subh::CON_RES_ID) {
|
||||
contention_resolution_id = pending_mac_msg.get()->get_con_res_id();
|
||||
has_pending_contention_resolution_id = true;
|
||||
Info("Found Contention Resolution ID CE\n");
|
||||
}
|
||||
}
|
||||
pending_mac_msg.reset();
|
||||
pending_temp_rnti = true;
|
||||
Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
Info("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
} else {
|
||||
Warning("Error pushing PDU with Temporal C-RNTI: Another PDU is still in pending\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Demultiplexing of logical channels and dissassemble of MAC CE */
|
||||
void demux::push_pdu(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
void demux::push_pdu(uint8_t *mac_pdu, uint32_t nof_bits)
|
||||
{
|
||||
tti = tti_;
|
||||
// Unpack DLSCH MAC PDU
|
||||
mac_msg.init(nof_bits/8);
|
||||
mac_msg.parse_packet(mac_pdu);
|
||||
|
@ -112,14 +114,18 @@ void demux::push_pdu(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bits)
|
|||
Debug("Normal MAC PDU processed\n");
|
||||
}
|
||||
|
||||
void demux::demultiplex_pending_pdu(uint32_t tti_)
|
||||
void demux::discard_pending_pdu()
|
||||
{
|
||||
pending_temp_rnti = false;
|
||||
pending_mac_msg.reset();
|
||||
}
|
||||
|
||||
void demux::demultiplex_pending_pdu()
|
||||
{
|
||||
tti = tti_;
|
||||
if (pending_temp_rnti) {
|
||||
process_pdu(&pending_mac_msg);
|
||||
Debug("Temporal C-RNTI MAC PDU processed\n");
|
||||
pending_temp_rnti = false;
|
||||
pending_mac_msg.reset();
|
||||
discard_pending_pdu();
|
||||
Info("Temporal C-RNTI MAC PDU processed\n");
|
||||
} else {
|
||||
Error("Error demultiplex pending PDU: No pending PDU\n");
|
||||
}
|
||||
|
@ -129,6 +135,7 @@ void demux::demultiplex_pending_pdu(uint32_t tti_)
|
|||
|
||||
void demux::process_pdu(sch_pdu *pdu_msg)
|
||||
{
|
||||
Info("Processing PDU\n");
|
||||
while(pdu_msg->next()) {
|
||||
if (pdu_msg->get()->is_sdu()) {
|
||||
// Route logical channel
|
||||
|
@ -136,7 +143,7 @@ void demux::process_pdu(sch_pdu *pdu_msg)
|
|||
qbuff *dest_lch = mac_io_h->get(pdu_msg->get()->get_sdu_lcid());
|
||||
if (dest_lch) {
|
||||
dest_lch->send(pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_sdu_nbytes()*8);
|
||||
Debug("Sent MAC SDU len=%d bytes to lchid=%d\n",
|
||||
Info("Sent MAC SDU len=%d bytes to lchid=%d\n",
|
||||
pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid());
|
||||
} else {
|
||||
Error("Getting destination channel LCID=%d\n", pdu_msg->get()->get_sdu_lcid());
|
||||
|
@ -168,8 +175,10 @@ bool demux::process_ce(sch_subh *subh) {
|
|||
timers_db->get(mac::TIME_ALIGNMENT)->run();
|
||||
Debug("Set TimeAdvance Command %d\n", subh->get_ta_cmd());
|
||||
break;
|
||||
case sch_subh::PADDING:
|
||||
break;
|
||||
default:
|
||||
Error("MAC CE not supported\n");
|
||||
Error("MAC CE 0x%x not supported\n", subh->ce_type());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -43,16 +43,11 @@ namespace srslte {
|
|||
|
||||
dl_harq_entity::dl_harq_entity()
|
||||
{
|
||||
proc = new dl_harq_process[NOF_HARQ_PROC+1]; // BCCH process is separate
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC+1;i++) {
|
||||
proc[i].pid = i;
|
||||
}
|
||||
pending_ack_pid = -1;
|
||||
}
|
||||
dl_harq_entity::~dl_harq_entity()
|
||||
{
|
||||
delete proc;
|
||||
}
|
||||
bool dl_harq_entity::init(srslte_cell_t cell, uint32_t max_payload_len, log* log_h_, timers* timers_, demux *demux_unit_)
|
||||
{
|
||||
timers_db = timers_;
|
||||
|
@ -70,9 +65,9 @@ bool dl_harq_entity::is_sps(uint32_t pid)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
void dl_harq_entity::set_harq_info(uint32_t tti, uint32_t pid, dl_sched_grant* grant)
|
||||
void dl_harq_entity::set_harq_info(uint32_t pid, dl_sched_grant* grant)
|
||||
{
|
||||
proc[pid%(NOF_HARQ_PROC+1)].set_harq_info(tti, grant);
|
||||
proc[pid%(NOF_HARQ_PROC+1)].set_harq_info(grant);
|
||||
}
|
||||
|
||||
void dl_harq_entity::receive_data(uint32_t tti, uint32_t pid, dl_buffer* dl_buffer, phy* phy_h)
|
||||
|
@ -127,6 +122,7 @@ void dl_harq_entity::dl_harq_process::reset() {
|
|||
void dl_harq_entity::dl_harq_process::send_pending_ack_contention_resolution()
|
||||
{
|
||||
if (pending_ul_buffer) {
|
||||
Info("Generating Pending ACK=%d for UL TTI=%d\n", pending_ack, pending_ul_buffer->tti);
|
||||
pending_ul_buffer->generate_ack(pending_ack, &pending_ack_grant);
|
||||
}
|
||||
}
|
||||
|
@ -142,18 +138,19 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_
|
|||
if (dl_buffer->decode_data(&cur_grant, &softbuffer, payload)) {
|
||||
Info("Decoded OK\n");
|
||||
// RX OK
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.get_tbs()/8);
|
||||
if (pid == HARQ_BCCH_PID) {
|
||||
harq_entity->demux_unit->push_pdu_bcch(tti, payload, cur_grant.get_tbs());
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.get_tbs()/8);
|
||||
harq_entity->demux_unit->push_pdu_bcch(payload, cur_grant.get_tbs());
|
||||
is_first_tx = true;
|
||||
} else {
|
||||
if (is_first_decoded) {
|
||||
if (cur_grant.is_temp_rnti()) {
|
||||
harq_entity->demux_unit->push_pdu_temp_crnti(tti, payload, cur_grant.get_tbs());
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", cur_grant.get_tbs()/8);
|
||||
harq_entity->demux_unit->push_pdu_temp_crnti(payload, cur_grant.get_tbs());
|
||||
} else {
|
||||
harq_entity->demux_unit->push_pdu(tti, payload, cur_grant.get_tbs());
|
||||
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.get_tbs()/8);
|
||||
harq_entity->demux_unit->push_pdu(payload, cur_grant.get_tbs());
|
||||
}
|
||||
is_first_decoded = false;
|
||||
}
|
||||
ack = true;
|
||||
}
|
||||
|
@ -186,7 +183,7 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_
|
|||
}
|
||||
}
|
||||
// Implement 5.3.2.2
|
||||
void dl_harq_entity::dl_harq_process::set_harq_info(uint32_t tti, srslte::ue::dl_sched_grant* new_grant) {
|
||||
void dl_harq_entity::dl_harq_process::set_harq_info(srslte::ue::dl_sched_grant* new_grant) {
|
||||
bool is_new_transmission = false;
|
||||
if (new_grant->get_ndi() && !cur_grant.get_ndi() || is_first_tx) {
|
||||
is_new_transmission = true;
|
||||
|
|
|
@ -55,7 +55,7 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
|
|||
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
param.sched_priority = -20;
|
||||
param.sched_priority = sched_get_priority_min(SCHED_FIFO) ;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
|
||||
pthread_attr_setschedparam(&attr, ¶m);
|
||||
|
@ -132,7 +132,7 @@ void mac::main_radio_loop() {
|
|||
|
||||
// Init HARQ for this cell
|
||||
Info("Init UL/DL HARQ\n");
|
||||
ul_harq.init(cell, log_h, &timers_db, &mux_unit);
|
||||
ul_harq.init(cell, ¶ms_db, log_h, &timers_db, &mux_unit);
|
||||
dl_harq.init(cell, 8*1024, log_h, &timers_db, &demux_unit);
|
||||
|
||||
// Set the current PHY cell to the detected cell
|
||||
|
@ -140,13 +140,15 @@ void mac::main_radio_loop() {
|
|||
if (phy_h->set_cell(cell)) {
|
||||
Info("Starting RX streaming\n");
|
||||
if (phy_h->start_rxtx()) {
|
||||
log_h->step(ttisync->wait());
|
||||
|
||||
Info("Receiver synchronized\n");
|
||||
|
||||
// Send MIB to RRC
|
||||
mac_io_lch.get(mac_io::MAC_LCH_BCCH_DL)->send(bch_payload, SRSLTE_BCH_PAYLOAD_LEN);
|
||||
|
||||
ttisync->resync();
|
||||
Info("Wait to sync\n");
|
||||
Info("Wait for AGC, CFO estimation, etc. \n");
|
||||
for (int i=0;i<1000;i++) {
|
||||
tti = ttisync->wait();
|
||||
}
|
||||
|
@ -168,6 +170,7 @@ void mac::main_radio_loop() {
|
|||
/* Warning: Here order of invocation of procedures is important!! */
|
||||
|
||||
tti = ttisync->wait();
|
||||
log_h->step(tti);
|
||||
|
||||
// Step all procedures
|
||||
ra_procedure.step(tti);
|
||||
|
@ -181,18 +184,22 @@ void mac::main_radio_loop() {
|
|||
// Process DL grants always
|
||||
process_dl_grants(tti);
|
||||
|
||||
// Process UL grants if RA procedure is done and we have pending data or in contention resolution
|
||||
if (ra_procedure.is_contention_resolution() ||
|
||||
ra_procedure.is_successful() && mux_unit.is_pending_sdu())
|
||||
{
|
||||
process_ul_grants(tti);
|
||||
}
|
||||
|
||||
// Send pending HARQ ACK, if any, and contention resolution is resolved
|
||||
if (dl_harq.is_ack_pending_resolution()) {
|
||||
if (ra_procedure.is_successful()) {
|
||||
ra_procedure.step(tti);
|
||||
if (ra_procedure.is_successful() || ra_procedure.is_response_error()) {
|
||||
Info("Sending pending ACK for contention resolution\n");
|
||||
dl_harq.send_pending_ack_contention_resolution();
|
||||
}
|
||||
}
|
||||
|
||||
// Process UL grants if RA procedure is done or in contention resolution
|
||||
if (ra_procedure.is_successful() || ra_procedure.is_contention_resolution()) {
|
||||
process_ul_grants(tti);
|
||||
}
|
||||
timers_db.step_all();
|
||||
|
||||
// Check if there is pending CCCH SDU in Multiplexing Unit
|
||||
|
@ -300,13 +307,14 @@ void mac::process_dl_grants(uint32_t tti) {
|
|||
if (i == mac_params::RNTI_C && dl_harq.is_sps(harq_pid)) {
|
||||
ue_grant.set_ndi(true);
|
||||
}
|
||||
dl_harq.set_harq_info(tti, harq_pid, &ue_grant);
|
||||
Info("Processing DL grant TBS=%d, RNTI=%d, RV=%d\n", ue_grant.get_tbs(), ue_grant.get_rnti(), ue_grant.get_rv());
|
||||
dl_harq.set_harq_info(harq_pid, &ue_grant);
|
||||
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
|
||||
} else {
|
||||
uint32_t harq_pid = get_harq_sps_pid(tti);
|
||||
if (ue_grant.get_ndi()) {
|
||||
ue_grant.set_ndi(false);
|
||||
dl_harq.set_harq_info(tti, harq_pid, &ue_grant);
|
||||
dl_harq.set_harq_info(harq_pid, &ue_grant);
|
||||
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
|
||||
} else {
|
||||
if (ue_grant.is_sps_release()) {
|
||||
|
@ -318,7 +326,7 @@ void mac::process_dl_grants(uint32_t tti) {
|
|||
} else {
|
||||
dl_sps_assig.reset(tti, &ue_grant);
|
||||
ue_grant.set_ndi(true);
|
||||
dl_harq.set_harq_info(tti, harq_pid, &ue_grant);
|
||||
dl_harq.set_harq_info(harq_pid, &ue_grant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -331,7 +339,7 @@ void mac::process_dl_grants(uint32_t tti) {
|
|||
Info("Processing SPS grant\n");
|
||||
uint32_t harq_pid = get_harq_sps_pid(tti);
|
||||
sps_grant->set_ndi(true);
|
||||
dl_harq.set_harq_info(tti, harq_pid, sps_grant);
|
||||
dl_harq.set_harq_info(harq_pid, sps_grant);
|
||||
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
|
||||
}
|
||||
|
||||
|
@ -355,7 +363,7 @@ void mac::process_dl_grants(uint32_t tti) {
|
|||
}
|
||||
si_grant.set_rv(((uint32_t) ceilf((float)1.5*k))%4);
|
||||
Info("DL grant found, sending to HARQ with RV: %d\n", si_grant.get_rv());
|
||||
dl_harq.set_harq_info(tti, dl_harq_entity::HARQ_BCCH_PID, &si_grant);
|
||||
dl_harq.set_harq_info(dl_harq_entity::HARQ_BCCH_PID, &si_grant);
|
||||
dl_harq.receive_data(tti, dl_harq_entity::HARQ_BCCH_PID, dl_buffer, phy_h);
|
||||
params_db.set_param(mac_params::BCCH_SI_WINDOW_ST, 0);
|
||||
params_db.set_param(mac_params::BCCH_SI_WINDOW_LEN, 0);
|
||||
|
@ -380,7 +388,7 @@ void mac::process_ul_grants(uint32_t tti) {
|
|||
ul_sched_grant ul_grant(rnti_type(i), params_db.get_param(i));
|
||||
if (dl_buffer->get_ul_grant(&ul_grant)) {
|
||||
if (ul_grant.is_from_rar()) {
|
||||
dl_buffer->release_pending_rar_grant();
|
||||
dl_buffer->discard_pending_rar_grant();
|
||||
}
|
||||
if (ra_procedure.is_contention_resolution() && i == mac_params::RNTI_C) {
|
||||
ra_procedure.pdcch_to_crnti(true);
|
||||
|
@ -389,11 +397,8 @@ void mac::process_ul_grants(uint32_t tti) {
|
|||
if (i == mac_params::RNTI_C && ul_harq.is_sps(tti)) {
|
||||
ul_grant.set_ndi(true);
|
||||
}
|
||||
Info("Found UL Grant TBS=%d RNTI=%d is_from_rar=%d\n", ul_grant.get_tbs(), params_db.get_param(i), ul_grant.is_from_rar());
|
||||
ul_harq.run_tti(tti, &ul_grant, phy_h);
|
||||
if (i == mac_params::RNTI_TEMP) {
|
||||
// Discard already processed RAR grant
|
||||
dl_buffer->discard_pending_rar_grant();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (i == mac_params::RNTI_SPS) {
|
||||
|
@ -422,7 +427,7 @@ void mac::process_ul_grants(uint32_t tti) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
ul_harq.run_tti(tti, dl_buffer, phy_h);
|
||||
ul_harq.run_tti(tti, phy_h);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ mux::mux() : pdu_msg(20)
|
|||
pdu_buff.init(1, PDU_BUFF_SZ);
|
||||
bzero(nof_tx_pkts, sizeof(uint32_t) * mac_io::NOF_UL_LCH);
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
msg3_has_been_transmitted = false;
|
||||
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
priority[i] = 1;
|
||||
|
@ -107,9 +108,8 @@ void mux::pdu_release()
|
|||
pdu_buff.release();
|
||||
}
|
||||
|
||||
bool mux::pdu_move_to_msg3(uint32_t tti_, uint32_t pdu_sz)
|
||||
bool mux::pdu_move_to_msg3(uint32_t pdu_sz)
|
||||
{
|
||||
tti = tti_;
|
||||
if (pdu_buff.isempty()) {
|
||||
if (assemble_pdu(pdu_sz)) {
|
||||
if (pdu_buff.pending_data() < MSG3_BUFF_SZ) {
|
||||
|
@ -131,9 +131,8 @@ bool mux::pdu_move_to_msg3(uint32_t tti_, uint32_t pdu_sz)
|
|||
}
|
||||
|
||||
// Multiplexing and logical channel priorization as defined in Section 5.4.3
|
||||
uint8_t* mux::pdu_pop(uint32_t tti_, uint32_t pdu_sz)
|
||||
uint8_t* mux::pdu_pop(uint32_t pdu_sz)
|
||||
{
|
||||
tti = tti_;
|
||||
if (pdu_buff.isempty()) {
|
||||
if (assemble_pdu(pdu_sz)) {
|
||||
return (uint8_t*) pdu_buff.pop();
|
||||
|
@ -221,7 +220,7 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
/* Release SDUs */
|
||||
/* Release all SDUs */
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
while(nof_tx_pkts[i] > 0) {
|
||||
mac_io_h->get(IO_IDX(i))->release();
|
||||
|
@ -229,6 +228,7 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
}
|
||||
}
|
||||
|
||||
Info("Assembled MAC PDU msg size %d bytes\n", pdu_msg.size());
|
||||
/* Generate MAC PDU and save to buffer */
|
||||
if (pdu_msg.write_packet(buff)) {
|
||||
pdu_buff.push(pdu_sz_nbits);
|
||||
|
@ -270,15 +270,21 @@ bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz)
|
|||
void mux::msg3_flush()
|
||||
{
|
||||
msg3_buff.flush();
|
||||
msg3_has_been_transmitted = false;
|
||||
}
|
||||
|
||||
bool mux::msg3_isempty()
|
||||
void mux::msg3_transmitted()
|
||||
{
|
||||
return msg3_buff.isempty();
|
||||
msg3_has_been_transmitted = true;
|
||||
}
|
||||
|
||||
bool mux::msg3_is_transmitted()
|
||||
{
|
||||
return msg3_has_been_transmitted;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the Msg3 buffer */
|
||||
uint8_t* mux::msg3_pop(uint32_t tti, uint32_t TB_size)
|
||||
uint8_t* mux::msg3_pop(uint32_t TB_size)
|
||||
{
|
||||
uint32_t len;
|
||||
uint8_t *msg3 = (uint8_t*) msg3_buff.pop(&len);
|
||||
|
@ -294,12 +300,6 @@ uint8_t* mux::msg3_pop(uint32_t tti, uint32_t TB_size)
|
|||
return msg3;
|
||||
}
|
||||
|
||||
void mux::msg3_release()
|
||||
{
|
||||
msg3_buff.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,18 +52,39 @@ void sch_subh::fprint(FILE* stream)
|
|||
fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti());
|
||||
break;
|
||||
case CON_RES_ID:
|
||||
fprintf(stream, "Contention Resolution ID CE: %d\n", get_con_res_id());
|
||||
fprintf(stream, "Contention Resolution ID CE: 0x%lx\n", get_con_res_id());
|
||||
break;
|
||||
case TA_CMD:
|
||||
fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd());
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sch_pdu::parse_packet(uint8_t *ptr)
|
||||
{
|
||||
pdu::parse_packet(ptr);
|
||||
|
||||
// Correct size for last SDU
|
||||
if (nof_subheaders > 0) {
|
||||
uint32_t read_len = 0;
|
||||
for (int i=0;i<nof_subheaders-1;i++) {
|
||||
read_len += subheaders[i].size_plus_header();
|
||||
}
|
||||
if (pdu_len-read_len-1 >= 0) {
|
||||
subheaders[nof_subheaders-1].set_payload_size(pdu_len-read_len-1);
|
||||
} else {
|
||||
fprintf(stderr,"Reading MAC PDU: negative payload for last subheader\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Section 6.1.2
|
||||
bool sch_pdu::write_packet(uint8_t* ptr)
|
||||
{
|
||||
uint8_t *init_ptr = ptr;
|
||||
// Add single or two-byte padding if required
|
||||
if (rem_len == 1 || rem_len == 2) {
|
||||
sch_subh padding;
|
||||
|
@ -108,12 +129,16 @@ bool sch_pdu::write_packet(uint8_t* ptr)
|
|||
}
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t)*8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t sch_pdu::size()
|
||||
{
|
||||
return pdu_len - rem_len;
|
||||
}
|
||||
|
||||
|
||||
uint32_t sch_pdu::size_plus_header_pdu(uint32_t nbytes)
|
||||
uint32_t sch_pdu::size_plus_header_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (nbytes < 128) {
|
||||
return nbytes + 2;
|
||||
|
@ -131,7 +156,7 @@ bool sch_pdu::has_space_ce(uint32_t nbytes)
|
|||
}
|
||||
bool sch_pdu::has_space_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (rem_len >= size_plus_header_pdu(nbytes)) {
|
||||
if (rem_len >= size_plus_header_sdu(nbytes)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -146,7 +171,7 @@ bool sch_pdu::update_space_ce(uint32_t nbytes)
|
|||
bool sch_pdu::update_space_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (has_space_sdu(nbytes)) {
|
||||
rem_len -= size_plus_header_pdu(nbytes);
|
||||
rem_len -= size_plus_header_sdu(nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +194,18 @@ sch_subh::cetype sch_subh::ce_type()
|
|||
}
|
||||
}
|
||||
|
||||
void sch_subh::set_payload_size(uint32_t size) {
|
||||
nof_bytes = size;
|
||||
}
|
||||
|
||||
uint32_t sch_subh::size_plus_header() {
|
||||
if (is_sdu()) {
|
||||
return sch_pdu::size_plus_header_sdu(nof_bytes);
|
||||
} else {
|
||||
return nof_bytes + 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sch_subh::sizeof_ce(uint32_t lcid, bool is_ul)
|
||||
{
|
||||
if (is_ul) {
|
||||
|
@ -221,7 +258,7 @@ uint32_t sch_subh::get_sdu_lcid()
|
|||
}
|
||||
uint32_t sch_subh::get_sdu_nbytes()
|
||||
{
|
||||
return *((uint32_t*) ce_payload);
|
||||
return nof_bytes;
|
||||
}
|
||||
uint8_t* sch_subh::get_sdu_ptr()
|
||||
{
|
||||
|
@ -297,16 +334,18 @@ void sch_subh::write_subheader(uint8_t** ptr, bool is_last)
|
|||
if (is_sdu()) {
|
||||
// MAC SDU: R/R/E/LCID/F/L subheader
|
||||
srslte_bit_pack(0, ptr, 2); // R, R
|
||||
srslte_bit_pack(is_last?1:0, ptr, 1); // E
|
||||
srslte_bit_pack(is_last?0:1, ptr, 1); // E
|
||||
srslte_bit_pack(lcid, ptr, 5); // LCID
|
||||
|
||||
// 2nd and 3rd octet
|
||||
srslte_bit_pack(F_bit?1:0, ptr, 1); // F
|
||||
srslte_bit_pack(nof_bytes, ptr, nof_bytes<128?7:15); // L
|
||||
if (!is_last) {
|
||||
srslte_bit_pack(F_bit?1:0, ptr, 1); // F
|
||||
srslte_bit_pack(nof_bytes, ptr, nof_bytes<128?7:15); // L
|
||||
}
|
||||
} else {
|
||||
// MAC CE: R/R/E/LCID MAC Subheader
|
||||
srslte_bit_pack(0, ptr, 2); // R, R
|
||||
srslte_bit_pack(is_last?1:0, ptr, 1); // E
|
||||
srslte_bit_pack(is_last?0:1, ptr, 1); // E
|
||||
srslte_bit_pack(lcid, ptr, 5); // LCID
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +354,9 @@ void sch_subh::write_payload(uint8_t** ptr)
|
|||
if (is_sdu()) {
|
||||
memcpy(*ptr, sdu_payload_ptr, nof_bytes*8*sizeof(uint8_t));
|
||||
} else {
|
||||
srslte_bit_pack_vector(ce_payload, *ptr, nof_bytes*8);
|
||||
for (int i=0;i<nof_bytes;i++) {
|
||||
srslte_bit_pack(ce_payload[nof_bytes-i-1], ptr, 8);
|
||||
}
|
||||
}
|
||||
*ptr += nof_bytes*8;
|
||||
}
|
||||
|
@ -326,8 +367,13 @@ bool sch_subh::read_subheader(uint8_t** ptr)
|
|||
bool e_bit = srslte_bit_unpack(ptr, 1)?true:false;
|
||||
lcid = srslte_bit_unpack(ptr, 5);
|
||||
if (is_sdu()) {
|
||||
F_bit = srslte_bit_unpack(ptr, 1)?true:false;
|
||||
nof_bytes = srslte_bit_unpack(ptr, F_bit?7:15);
|
||||
if (e_bit) {
|
||||
F_bit = srslte_bit_unpack(ptr, 1)?true:false;
|
||||
nof_bytes = srslte_bit_unpack(ptr, F_bit?7:15);
|
||||
} else {
|
||||
nof_bytes = 0;
|
||||
F_bit = 0;
|
||||
}
|
||||
} else {
|
||||
nof_bytes = sizeof_ce(lcid, parent->is_ul());
|
||||
}
|
||||
|
@ -337,10 +383,12 @@ void sch_subh::read_payload(uint8_t** ptr)
|
|||
{
|
||||
if (is_sdu()) {
|
||||
sdu_payload_ptr = *ptr;
|
||||
} else {
|
||||
srslte_bit_unpack_vector(ce_payload, *ptr, nof_bytes*8);
|
||||
*ptr += nof_bytes*8;
|
||||
} else {
|
||||
for (int i=0;i<nof_bytes;i++) {
|
||||
ce_payload[nof_bytes-i-1] = srslte_bit_unpack(ptr, 8);
|
||||
}
|
||||
}
|
||||
*ptr += nof_bytes*8;
|
||||
}
|
||||
|
||||
|
||||
|
@ -455,7 +503,7 @@ void rar_subh::set_temp_crnti(uint16_t temp_rnti_)
|
|||
// Section 6.2.2
|
||||
void rar_subh::write_subheader(uint8_t** ptr, bool is_last)
|
||||
{
|
||||
srslte_bit_pack(is_last?1:0, ptr, 1); // E
|
||||
srslte_bit_pack(is_last?0:1, ptr, 1); // E
|
||||
srslte_bit_pack(1, ptr, 1); // T
|
||||
srslte_bit_pack(preamble, ptr, 6); // RAPID
|
||||
}
|
||||
|
|
|
@ -91,7 +91,6 @@ void ra_proc::read_params() {
|
|||
powerRampingStep = params_db->get_param(mac_params::RA_POWERRAMPINGSTEP);
|
||||
preambleTransMax = params_db->get_param(mac_params::RA_PREAMBLETRANSMAX);
|
||||
iniReceivedTargetPower = params_db->get_param(mac_params::RA_INITRECEIVEDPOWER);
|
||||
maxharq_msg3tx = params_db->get_param(mac_params::RA_MAXTXMSG3);
|
||||
contentionResolutionTimer = params_db->get_param(mac_params::RA_CONTENTIONTIMER);
|
||||
|
||||
delta_preamble_db = delta_preamble_db_table[configIndex];
|
||||
|
@ -111,6 +110,10 @@ bool ra_proc::is_successful() {
|
|||
return state == COMPLETION;
|
||||
}
|
||||
|
||||
bool ra_proc::is_response_error() {
|
||||
return state == RESPONSE_ERROR;
|
||||
}
|
||||
|
||||
bool ra_proc::is_contention_resolution() {
|
||||
return state == CONTENTION_RESOLUTION;
|
||||
}
|
||||
|
@ -145,7 +148,7 @@ const char* state_str[11] = {"Idle",
|
|||
|
||||
|
||||
// Process Timing Advance Command as defined in Section 5.2
|
||||
void ra_proc::process_timeadv_cmd(uint32_t tti, uint32_t ta) {
|
||||
void ra_proc::process_timeadv_cmd(uint32_t ta) {
|
||||
if (preambleIndex > 0) {
|
||||
// Preamble not selected by UE MAC
|
||||
phy_h->set_timeadv_rar(ta);
|
||||
|
@ -177,7 +180,6 @@ void* init_prach_thread(void *arg) {
|
|||
void ra_proc::step_initialization() {
|
||||
read_params();
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
||||
received_contention_id = 0;
|
||||
transmitted_contention_id = 0;
|
||||
preambleTransmissionCounter = 1;
|
||||
first_rar_received = true;
|
||||
|
@ -274,7 +276,6 @@ void ra_proc::step_response_reception() {
|
|||
|
||||
rar_pdu_msg.init(rar_grant.get_tbs()/8);
|
||||
rar_pdu_msg.parse_packet(rar_pdu_buffer);
|
||||
rar_pdu_msg.fprint(stdout);
|
||||
|
||||
// Set Backoff parameter
|
||||
if (rar_pdu_msg.has_backoff()) {
|
||||
|
@ -287,7 +288,7 @@ void ra_proc::step_response_reception() {
|
|||
if (rar_pdu_msg.get()->get_rapid() == sel_preamble) {
|
||||
rInfo("Received RAPID=%d\n", sel_preamble);
|
||||
|
||||
process_timeadv_cmd(tti, rar_pdu_msg.get()->get_ta_cmd());
|
||||
process_timeadv_cmd(rar_pdu_msg.get()->get_ta_cmd());
|
||||
|
||||
// FIXME: Indicate received target power
|
||||
//phy_h->set_target_power_rar(iniReceivedTargetPower, (preambleTransmissionCounter-1)*powerRampingStep);
|
||||
|
@ -323,7 +324,8 @@ void ra_proc::step_response_reception() {
|
|||
phy_h->get_dl_buffer(tti+2)->get_ul_grant(&msg3_grant);
|
||||
|
||||
// Move MAC PDU from Multiplexing and assembly unit to Msg3
|
||||
mux_unit->pdu_move_to_msg3(tti, msg3_grant.get_tbs()); // 56 is the minimum grant provided
|
||||
rInfo("Generating Msg3 for TBS=%d\n", msg3_grant.get_tbs());
|
||||
mux_unit->pdu_move_to_msg3(msg3_grant.get_tbs()); // 56 is the minimum grant provided
|
||||
}
|
||||
rDebug("Going to Contention Resolution state\n");
|
||||
state = CONTENTION_RESOLUTION;
|
||||
|
@ -348,7 +350,6 @@ void ra_proc::step_response_reception() {
|
|||
}
|
||||
|
||||
void ra_proc::step_response_error() {
|
||||
mux_unit->msg3_flush();
|
||||
|
||||
preambleTransmissionCounter++;
|
||||
if (preambleTransmissionCounter == preambleTransMax + 1) {
|
||||
|
@ -379,7 +380,7 @@ void ra_proc::step_backoff_wait() {
|
|||
|
||||
void ra_proc::step_contention_resolution() {
|
||||
// If Msg3 has been sent
|
||||
if (mux_unit->msg3_isempty()) {
|
||||
if (mux_unit->msg3_is_transmitted()) {
|
||||
msg3_transmitted = true;
|
||||
if (pdcch_to_crnti_received != PDCCH_CRNTI_NOT_RECEIVED)
|
||||
{
|
||||
|
@ -396,23 +397,28 @@ void ra_proc::step_contention_resolution() {
|
|||
|
||||
} else if (demux_unit->is_temp_crnti_pending())
|
||||
{
|
||||
// Random Access initiated by RRC by the transmission of CCCH SDU
|
||||
received_contention_id = demux_unit->get_contention_resolution_id();
|
||||
if (received_contention_id) {
|
||||
rInfo("Received UE Contention Resolution ID\n");
|
||||
rInfo("MAC PDU with Temporal C-RNTI has been decoded\n");
|
||||
// Random Access initiated by RRC by the transmission of CCCH SDU
|
||||
if (demux_unit->is_contention_resolution_id_pending()) {
|
||||
rInfo("MAC PDU Contains Contention Resolution ID CE\n");
|
||||
// MAC PDU successfully decoded and contains MAC CE contention Id
|
||||
if (transmitted_contention_id == received_contention_id) {
|
||||
|
||||
uint64_t rx_contention_id = demux_unit->get_contention_resolution_id();
|
||||
timers_db->get(mac::CONTENTION_TIMER)->stop();
|
||||
if (transmitted_contention_id == rx_contention_id) {
|
||||
rInfo("MAC PDU Contention Resolution ID matches the one transmitted in CCCH SDU\n");
|
||||
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
||||
timers_db->get(mac::CONTENTION_TIMER)->stop();
|
||||
params_db->set_param(mac_params::RNTI_C, params_db->get_param(mac_params::RNTI_TEMP));
|
||||
|
||||
// finish the disassembly and demultiplexing of the MAC PDU
|
||||
demux_unit->demultiplex_pending_pdu(tti);
|
||||
demux_unit->demultiplex_pending_pdu();
|
||||
state = COMPLETION;
|
||||
} else {
|
||||
rInfo("Transmitted UE Contention Id differs from received Contention ID\n");
|
||||
rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%lx != 0x%lx)\n", transmitted_contention_id, rx_contention_id);
|
||||
// Discard MAC PDU
|
||||
demux_unit->discard_pending_pdu();
|
||||
|
||||
// Contention Resolution not successfully is like RAR not successful
|
||||
// FIXME: Need to flush Msg3 HARQ buffer. Why?
|
||||
state = RESPONSE_ERROR;
|
||||
}
|
||||
params_db->set_param(mac_params::RNTI_TEMP, 0);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
|
||||
#include "srsapps/ue/mac/mac_params.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
#include "srsapps/ue/mac/ul_harq.h"
|
||||
|
||||
|
@ -40,17 +41,11 @@ namespace srslte {
|
|||
*
|
||||
*********************************************************/
|
||||
|
||||
ul_harq_entity::ul_harq_entity() {
|
||||
proc = new ul_harq_process[NOF_HARQ_PROC]; // BCCH process is separate
|
||||
}
|
||||
ul_harq_entity::~ul_harq_entity() {
|
||||
delete proc;
|
||||
}
|
||||
bool ul_harq_entity::init(srslte_cell_t cell, log *log_h_, timers *timers_db_, mux *mux_unit_) {
|
||||
bool ul_harq_entity::init(srslte_cell_t cell, mac_params *params_db_, log *log_h_, timers *timers_db_, mux *mux_unit_) {
|
||||
log_h = log_h_;
|
||||
mux_unit = mux_unit_;
|
||||
params_db = params_db_;
|
||||
timers_db = timers_db_;
|
||||
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
if (!proc[i].init(cell, this)) {
|
||||
return false;
|
||||
|
@ -58,13 +53,8 @@ bool ul_harq_entity::init(srslte_cell_t cell, log *log_h_, timers *timers_db_, m
|
|||
}
|
||||
return true;
|
||||
}
|
||||
void ul_harq_entity::set_maxHARQ_Tx(uint32_t maxHARQ_Tx, uint32_t maxHARQ_Msg3Tx) {
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
proc[i].set_maxHARQ_Tx(maxHARQ_Tx, maxHARQ_Msg3Tx);
|
||||
}
|
||||
}
|
||||
uint32_t ul_harq_entity::pidof(uint32_t tti) {
|
||||
return tti%NOF_HARQ_PROC;
|
||||
return (uint32_t) tti%NOF_HARQ_PROC;
|
||||
}
|
||||
void ul_harq_entity::reset() {
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
|
@ -80,36 +70,53 @@ bool ul_harq_entity::is_sps(uint32_t pid) {
|
|||
return false;
|
||||
}
|
||||
// Called with no UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, dl_buffer *dl_buffer, phy *phy_) {
|
||||
// TODO: Receive HARQ information from PHY (PHICH) and perform retransmissions
|
||||
void ul_harq_entity::run_tti(uint32_t tti, phy *phy_h) {
|
||||
run_tti(tti, NULL, phy_h);
|
||||
}
|
||||
|
||||
// Implements Section 5.4.2.1
|
||||
// Called with UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
|
||||
{
|
||||
uint32_t pid = pidof(tti);
|
||||
proc[pid].tti = tti;
|
||||
last_retx_is_msg3 = false;
|
||||
uint32_t tti_tx = (tti+4)%10240;
|
||||
uint32_t pid = pidof(tti_tx);
|
||||
|
||||
// Receive and route HARQ feedbacks
|
||||
int tti_harq = (int) tti - 4;
|
||||
if (tti_harq < 0) {
|
||||
tti_harq += 10240;
|
||||
}
|
||||
uint32_t pid_harq = pidof(tti_harq);
|
||||
if (proc[pid_harq].has_grant() && proc[pid_harq].last_tx_tti() <= tti_harq) {
|
||||
Info("Receiving HARQ feedback for PID=%d, TTI last TX %d, TTI harq %d\n", pid_harq, proc[pid_harq].last_tx_tti(), tti_harq);
|
||||
proc[pid_harq].set_harq_feedback(phy_h->get_dl_buffer(tti)->decode_ack(proc[pid_harq].get_grant()));
|
||||
}
|
||||
|
||||
if (grant) {
|
||||
if ((grant->is_temp_rnti() && grant->get_ndi() != proc[pid].get_ndi()) ||
|
||||
(grant->is_crnti() && !proc[pid].has_grant()) ||
|
||||
grant->is_from_rar())
|
||||
{
|
||||
// New transmission
|
||||
uint8_t* msg3_ptr = (uint8_t*) mux_unit->msg3_pop(tti, grant->get_tbs());
|
||||
uint8_t* msg3_ptr = (uint8_t*) mux_unit->msg3_pop(grant->get_tbs());
|
||||
|
||||
// Uplink grant in a RAR
|
||||
if (msg3_ptr && grant->is_from_rar()) {
|
||||
proc[pid].generate_new_tx(msg3_ptr, true, grant, phy_h->get_ul_buffer(tti+4));
|
||||
mux_unit->msg3_release();
|
||||
if (grant->is_from_rar()) {
|
||||
if (msg3_ptr) {
|
||||
Info("Generating New Msg3 Transmission for PID=%d TTI=%d\n", pid, tti_tx);
|
||||
proc[pid].generate_new_tx(tti_tx, msg3_ptr, true, grant, phy_h->get_ul_buffer(tti_tx));
|
||||
mux_unit->msg3_transmitted();
|
||||
} else {
|
||||
Warning("UL RAR grant available but no Msg3 on buffer\n");
|
||||
}
|
||||
|
||||
// Normal UL grant
|
||||
} else {
|
||||
// Request a MAC PDU from the Multiplexing & Assemble Unit
|
||||
uint8_t* mac_pdu = mux_unit->pdu_pop(tti, grant->get_tbs());
|
||||
Info("Generating New Transmission for PID=%d TTI=%d\n", pid, tti_tx);
|
||||
uint8_t* mac_pdu = mux_unit->pdu_pop(grant->get_tbs());
|
||||
if (mac_pdu) {
|
||||
proc[pid].generate_new_tx(mac_pdu, false, grant, phy_h->get_ul_buffer(tti+4));
|
||||
proc[pid].generate_new_tx(tti_tx, mac_pdu, false, grant, phy_h->get_ul_buffer(tti_tx));
|
||||
mux_unit->pdu_release();
|
||||
} else {
|
||||
Warning("Uplink grant with MAC PDU available in Multiplex Unit\n");
|
||||
|
@ -117,24 +124,15 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
|
|||
}
|
||||
} else {
|
||||
// Adaptive Re-TX
|
||||
proc[pid].generate_retx(grant, phy_h->get_ul_buffer(tti+4));
|
||||
Info("Generating Adaptive Retransmission for PID=%d RV=%d\n", pid, proc[pid].get_rv());
|
||||
proc[pid].generate_retx(tti_tx, grant, phy_h->get_ul_buffer(tti_tx));
|
||||
}
|
||||
} else if (proc[pid].has_grant()) {
|
||||
// Non-Adaptive Re-Tx
|
||||
proc[pid].generate_retx(phy_h->get_ul_buffer(tti+4));
|
||||
Info("Generating Non-adaptive Retransmission for PID=%d RV=%d\n", pid, proc[pid].get_rv());
|
||||
proc[pid].generate_retx(tti_tx, phy_h->get_ul_buffer(tti_tx));
|
||||
}
|
||||
|
||||
// Receive and route HARQ feedbacks
|
||||
for (uint32_t i=0;i<NOF_HARQ_PROC;i++) {
|
||||
if (proc[pid].has_grant()) {
|
||||
proc[pid].set_harq_feedback(phy_h->get_dl_buffer(tti)->decode_ack(proc[pid].get_grant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ul_harq_entity::is_last_retx_msg3()
|
||||
{
|
||||
return last_retx_is_msg3;
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,11 +151,13 @@ ul_harq_entity::ul_harq_process::ul_harq_process() : cur_grant(0) {
|
|||
current_irv = 0;
|
||||
is_initiated = false;
|
||||
is_grant_configured = false;
|
||||
tti_last_tx = 0;
|
||||
bzero(&cur_grant, sizeof(ul_sched_grant));
|
||||
}
|
||||
void ul_harq_entity::ul_harq_process::reset() {
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
tti_last_tx = 0;
|
||||
is_grant_configured = false;
|
||||
bzero(&cur_grant, sizeof(ul_sched_grant));
|
||||
if (is_initiated) {
|
||||
|
@ -175,6 +175,11 @@ bool ul_harq_entity::ul_harq_process::get_ndi()
|
|||
return ndi;
|
||||
}
|
||||
|
||||
uint32_t ul_harq_entity::ul_harq_process::get_rv()
|
||||
{
|
||||
return rv_of_irv[current_irv%4];
|
||||
}
|
||||
|
||||
ul_sched_grant* ul_harq_entity::ul_harq_process::get_grant()
|
||||
{
|
||||
return &cur_grant;
|
||||
|
@ -182,10 +187,13 @@ ul_sched_grant* ul_harq_entity::ul_harq_process::get_grant()
|
|||
|
||||
void ul_harq_entity::ul_harq_process::set_harq_feedback(bool ack) {
|
||||
harq_feedback = ack;
|
||||
}
|
||||
void ul_harq_entity::ul_harq_process::set_maxHARQ_Tx(uint32_t maxHARQ_Tx_, uint32_t maxHARQ_Msg3Tx_) {
|
||||
maxHARQ_Tx = maxHARQ_Tx_;
|
||||
maxHARQ_Msg3Tx = maxHARQ_Msg3Tx_;
|
||||
// UL packet successfully delivered
|
||||
if (ack) {
|
||||
Info("HARQ = ACK for UL transmission. Discarting TB.\n");
|
||||
reset();
|
||||
} else {
|
||||
Info("HARQ = NACK for UL transmission\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, ul_harq_entity *parent) {
|
||||
|
@ -196,23 +204,24 @@ bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, ul_harq_entity *p
|
|||
is_initiated = true;
|
||||
harq_entity = parent;
|
||||
log_h = harq_entity->log_h;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Retransmission with or w/o grant (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(ul_sched_grant* grant, ul_buffer* ul)
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_sched_grant* grant, ul_buffer* ul)
|
||||
{
|
||||
current_tx_nb++;
|
||||
current_tx_nb++;
|
||||
if (grant) {
|
||||
// HARQ entity requests an adaptive transmission
|
||||
memcpy(&cur_grant, grant, sizeof(grant));
|
||||
memcpy(&cur_grant, grant, sizeof(ul_sched_grant));
|
||||
current_irv = irv_of_rv[grant->get_rv()%4];
|
||||
harq_feedback = false;
|
||||
generate_tx(NULL, ul);
|
||||
generate_tx(tti_tx, NULL, ul);
|
||||
} else {
|
||||
// HARQ entity requests a non-adaptive transmission
|
||||
if (!harq_feedback) {
|
||||
generate_tx(NULL, ul);
|
||||
generate_tx(tti_tx, NULL, ul);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,47 +231,56 @@ void ul_harq_entity::ul_harq_process::generate_retx(ul_sched_grant* grant, ul_bu
|
|||
}
|
||||
}
|
||||
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_buffer* ul)
|
||||
{
|
||||
generate_retx(tti_tx, NULL, ul);
|
||||
}
|
||||
|
||||
|
||||
// New transmission (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_new_tx(uint8_t *pdu_payload, bool is_msg3_, ul_sched_grant* ul_grant, ul_buffer* ul)
|
||||
void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, uint8_t *pdu_payload, bool is_msg3_, ul_sched_grant* ul_grant, ul_buffer* ul)
|
||||
{
|
||||
if (ul_grant && pdu_payload) {
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
// Store the uplink grant
|
||||
memcpy(&cur_grant, ul_grant, sizeof(ul_sched_grant));
|
||||
harq_feedback = false;
|
||||
generate_tx(pdu_payload, ul);
|
||||
is_grant_configured = true;
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
is_msg3 = is_msg3_;
|
||||
Info("New %s transmission PDU Len %d bytes\n", is_msg3_?"Msg3":"", cur_grant.get_tbs());
|
||||
generate_tx(tti_tx, pdu_payload, ul);
|
||||
}
|
||||
}
|
||||
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(ul_buffer* ul)
|
||||
// Transmission of pending frame (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_tx(uint32_t tti_tx, uint8_t *pdu_payload, ul_buffer* ul)
|
||||
{
|
||||
generate_retx(NULL, ul);
|
||||
}
|
||||
|
||||
// Transmission of pending frame (Section 5.4.2.2)
|
||||
void ul_harq_entity::ul_harq_process::generate_tx(uint8_t *pdu_payload, ul_buffer* ul)
|
||||
{
|
||||
cur_grant.set_rv(rv_of_irv[current_irv%4]);
|
||||
cur_grant.set_rv(get_rv());
|
||||
ul->set_current_tx_nb(current_tx_nb);
|
||||
ul->generate_data(&cur_grant, &softbuffer, pdu_payload);
|
||||
|
||||
current_irv = (current_irv+1)%4;
|
||||
Info("UL transmission RV=%d, TBS=%d\n", cur_grant.get_rv(), cur_grant.get_tbs());
|
||||
tti_last_tx = tti_tx;
|
||||
if (is_msg3) {
|
||||
if (current_tx_nb == maxHARQ_Msg3Tx) {
|
||||
if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX)) {
|
||||
Info("Maximum number of ReTX for Msg3 reached (%d). Discarting TB.\n", harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX));
|
||||
reset();
|
||||
}
|
||||
} else {
|
||||
if (current_tx_nb == maxHARQ_Tx) {
|
||||
if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXTX)) {
|
||||
Info("Maximum number of ReTX reached (%d). Discarting TB.\n", harq_entity->params_db->get_param(mac_params::HARQ_MAXTX));
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t ul_harq_entity::ul_harq_process::last_tx_tti()
|
||||
{
|
||||
return tti_last_tx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -45,19 +45,21 @@ typedef struct {
|
|||
float uhd_tx_freq;
|
||||
float uhd_rx_gain;
|
||||
float uhd_tx_gain;
|
||||
int verbose;
|
||||
}prog_args_t;
|
||||
|
||||
void args_default(prog_args_t *args) {
|
||||
args->uhd_rx_freq = -1.0;
|
||||
args->uhd_tx_freq = -1.0;
|
||||
args->uhd_rx_gain = 60.0;
|
||||
args->uhd_tx_gain = 60.0;
|
||||
args->uhd_rx_gain = -1; // set to autogain
|
||||
args->uhd_tx_gain = -1;
|
||||
args->verbose = 0;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
printf("Usage: %s [gv] -f rx_frequency (in Hz) -F tx_frequency (in Hz)\n", prog);
|
||||
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_rx_gain);
|
||||
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_tx_gain);
|
||||
printf("\t-g UHD RX gain [Default AGC]\n");
|
||||
printf("\t-G UHD TX gain [Default same as RX gain (AGC)]\n");
|
||||
printf("\t-v [increase verbosity, default none]\n");
|
||||
}
|
||||
|
||||
|
@ -79,7 +81,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
args->uhd_tx_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
args->verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(args, argv[0]);
|
||||
|
@ -119,7 +121,7 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u
|
|||
liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_CONTENTIONTIMER,
|
||||
liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]);
|
||||
mac->set_param(srslte::ue::mac_params::RA_MAXTXMSG3,
|
||||
mac->set_param(srslte::ue::mac_params::HARQ_MAXMSG3TX,
|
||||
sib2->rr_config_common_sib.rach_cnfg.max_harq_msg3_tx);
|
||||
|
||||
printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n",
|
||||
|
@ -195,6 +197,20 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u
|
|||
sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_config_index);
|
||||
}
|
||||
|
||||
void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac *mac, srslte::ue::phy *phy) {
|
||||
mac->set_param(srslte::ue::mac_params::HARQ_MAXTX,
|
||||
liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx]);
|
||||
|
||||
mac->set_param(srslte::ue::mac_params::SR_PUCCH_RESINDEX, msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_pucch_resource_idx);
|
||||
mac->set_param(srslte::ue::mac_params::SR_CONFIG_INDEX, msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx);
|
||||
mac->set_param(srslte::ue::mac_params::SR_TRANS_MAX, liblte_rrc_dsr_trans_max_num[msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.dsr_trans_max]);
|
||||
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_ACK, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ack_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_CQI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_cqi_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_RI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ri_idx);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
prog_args_t prog_args;
|
||||
|
@ -202,25 +218,39 @@ int main(int argc, char *argv[])
|
|||
srslte::radio_uhd radio_uhd;
|
||||
srslte::ue::phy phy;
|
||||
srslte::ue::mac mac;
|
||||
srslte::log_stdout log("MAC");
|
||||
srslte::log_stdout mac_log("MAC"), phy_log("PHY");
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
// Init Radio
|
||||
radio_uhd.init();
|
||||
|
||||
// Init PHY
|
||||
phy.init(&radio_uhd, &ttisync);
|
||||
|
||||
// Init MAC
|
||||
mac.init(&phy, &ttisync, &log);
|
||||
|
||||
// Set RX freq and gain
|
||||
radio_uhd.set_rx_freq(prog_args.uhd_rx_freq);
|
||||
radio_uhd.set_rx_gain(prog_args.uhd_rx_gain);
|
||||
radio_uhd.set_tx_freq(prog_args.uhd_tx_freq);
|
||||
radio_uhd.set_tx_gain(prog_args.uhd_tx_gain);
|
||||
switch (prog_args.verbose) {
|
||||
case 1:
|
||||
mac_log.set_level_info();
|
||||
phy_log.set_level_info();
|
||||
break;
|
||||
case 2:
|
||||
mac_log.set_level_debug();
|
||||
phy_log.set_level_debug();
|
||||
break;
|
||||
}
|
||||
|
||||
// Init Radio and PHY
|
||||
if (prog_args.uhd_rx_gain > 0 && prog_args.uhd_tx_gain > 0) {
|
||||
radio_uhd.init();
|
||||
radio_uhd.set_rx_gain(prog_args.uhd_rx_gain);
|
||||
radio_uhd.set_tx_gain(prog_args.uhd_tx_gain);
|
||||
phy.init(&radio_uhd, &ttisync, &phy_log);
|
||||
} else {
|
||||
radio_uhd.init_agc();
|
||||
radio_uhd.set_tx_rx_gain_offset(-10);
|
||||
phy.init_agc(&radio_uhd, &ttisync, &phy_log);
|
||||
}
|
||||
// Init MAC
|
||||
mac.init(&phy, &ttisync, &mac_log);
|
||||
|
||||
// Set RX freq
|
||||
radio_uhd.set_rx_freq(prog_args.uhd_rx_freq);
|
||||
radio_uhd.set_tx_freq(prog_args.uhd_tx_freq);
|
||||
|
||||
LIBLTE_BIT_MSG_STRUCT bit_msg;
|
||||
LIBLTE_RRC_MIB_STRUCT bch_msg;
|
||||
LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT dlsch_msg;
|
||||
|
@ -252,8 +282,6 @@ int main(int argc, char *argv[])
|
|||
sib2_period = liblte_rrc_si_periodicity_num[dlsch_msg.sibs[0].sib.sib1.sched_info[0].si_periodicity];
|
||||
printf("SIB1 received %d bytes, CellID=%d, si_window=%d, sib2_period=%d\n",
|
||||
n/8, dlsch_msg.sibs[0].sib.sib1.cell_id&0xfff, si_window_len, sib2_period);
|
||||
printf("Payload: ");
|
||||
srslte_vec_fprint_hex(stdout, bit_msg.msg, n);
|
||||
state = SIB2;
|
||||
} else {
|
||||
tti = mac.get_tti();
|
||||
|
@ -268,8 +296,6 @@ int main(int argc, char *argv[])
|
|||
bit_msg.N_bits = n;
|
||||
liblte_rrc_unpack_bcch_dlsch_msg(&bit_msg, &dlsch_msg);
|
||||
printf("SIB2 received %d bytes\n", n/8);
|
||||
printf("Payload: ");
|
||||
srslte_vec_fprint_hex(stdout, bit_msg.msg, n);
|
||||
setup_mac_phy_sib2(&dlsch_msg.sibs[0].sib.sib2, &mac, &phy);
|
||||
|
||||
// Prepare ConnectionRequest packet
|
||||
|
@ -278,10 +304,18 @@ int main(int argc, char *argv[])
|
|||
ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000;
|
||||
ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_DATA;
|
||||
liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, &bit_msg);
|
||||
|
||||
mac.set_param(srslte::ue::mac_params::CONTENTION_ID, ul_ccch_msg.msg.rrc_con_req.ue_id.random);
|
||||
|
||||
uint64_t uecri=0;
|
||||
uint8_t *ue_cri_ptr = (uint8_t*) &uecri;
|
||||
uint32_t nbytes = bit_msg.N_bits/8;
|
||||
uint8_t *ptr = bit_msg.msg;
|
||||
for (int i=0;i<nbytes;i++) {
|
||||
ue_cri_ptr[nbytes-i-1] = (uint8_t) srslte_bit_unpack(&ptr, 8);
|
||||
}
|
||||
mac.set_param(srslte::ue::mac_params::CONTENTION_ID, uecri);
|
||||
|
||||
// Send ConnectionRequest Packet
|
||||
printf("Send ConnectionRequest %d bytes\n", nbytes);
|
||||
mac.send_ccch_sdu(bit_msg.msg, bit_msg.N_bits);
|
||||
state = CONNECT;
|
||||
} else {
|
||||
|
@ -298,15 +332,21 @@ int main(int argc, char *argv[])
|
|||
bit_msg.N_bits = n;
|
||||
liblte_rrc_unpack_dl_ccch_msg(&bit_msg, &dl_ccch_msg);
|
||||
printf("Response: %s\n", liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg.msg_type]);
|
||||
if (dl_ccch_msg.msg_type == LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP) {
|
||||
// Process ConnectionRequest
|
||||
}
|
||||
exit(0);
|
||||
switch (dl_ccch_msg.msg_type) {
|
||||
case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP:
|
||||
// Process ConnectionSetup
|
||||
process_connsetup(&dl_ccch_msg.msg.rrc_con_setup, &mac, &phy);
|
||||
break;
|
||||
case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ:
|
||||
mac.set_param(srslte::ue::mac_params::RNTI_C, 0);
|
||||
break;
|
||||
}
|
||||
// exit(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/common/queue.h"
|
||||
#include "srsapps/ue/phy/ul_sched_grant.h"
|
||||
#include "srsapps/ue/phy/dl_sched_grant.h"
|
||||
|
@ -47,7 +48,7 @@ namespace ue {
|
|||
|
||||
int buffer_id;
|
||||
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db);
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h_);
|
||||
void free_cell();
|
||||
bool recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time);
|
||||
bool get_ul_grant(ul_sched_grant *grant);
|
||||
|
@ -55,7 +56,6 @@ namespace ue {
|
|||
void discard_pending_rar_grant();
|
||||
void set_rar_grant(srslte_dci_rar_grant_t *rar_grant);
|
||||
void set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]);
|
||||
void release_pending_rar_grant();
|
||||
void reset_softbuffer();
|
||||
bool decode_ack(ul_sched_grant *pusch_grant);
|
||||
bool decode_data(dl_sched_grant *pdsch_grant, uint8_t *payload); // returns true or false for CRC OK/NOK
|
||||
|
@ -63,6 +63,7 @@ namespace ue {
|
|||
|
||||
private:
|
||||
phy_params *params_db;
|
||||
log *log_h;
|
||||
srslte_cell_t cell;
|
||||
srslte_ue_dl_t ue_dl;
|
||||
srslte_phich_t phich;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/common/tti_sync.h"
|
||||
#include "srsapps/ue/phy/dl_buffer.h"
|
||||
#include "srsapps/ue/phy/ul_buffer.h"
|
||||
|
@ -36,7 +37,7 @@
|
|||
#include "srsapps/ue/phy/phy_params.h"
|
||||
#include "srsapps/ue/phy/sched_grant.h"
|
||||
#include "srsapps/common/queue.h"
|
||||
#include "srslte/common/radio.h"
|
||||
#include "srsapps/radio/radio.h"
|
||||
|
||||
#ifndef UEPHY_H
|
||||
#define UEPHY_H
|
||||
|
@ -68,7 +69,8 @@ public:
|
|||
cell_is_set = false;
|
||||
phy_state = IDLE;
|
||||
}
|
||||
bool init(radio *radio_handler, tti_sync *ttisync);
|
||||
bool init(radio *radio_handler, tti_sync *ttisync, log *log_h);
|
||||
bool init_agc(radio *radio_handler, tti_sync *ttisync, log *log_h);
|
||||
void stop();
|
||||
|
||||
// These functions can be called only if PHY is in IDLE (ie, not RX/TX)
|
||||
|
@ -81,6 +83,8 @@ public:
|
|||
bool start_rxtx();
|
||||
bool stop_rxtx();
|
||||
|
||||
float get_agc_gain();
|
||||
|
||||
// Indicate the PHY to send PRACH as soon as possible
|
||||
bool init_prach();
|
||||
bool send_prach(uint32_t preamble_idx);
|
||||
|
@ -122,7 +126,8 @@ private:
|
|||
|
||||
tti_sync *ttisync;
|
||||
radio *radio_handler;
|
||||
|
||||
log *log_h;
|
||||
|
||||
srslte_cell_t cell;
|
||||
bool cell_is_set;
|
||||
bool is_sfn_synched;
|
||||
|
@ -142,6 +147,9 @@ private:
|
|||
bool radio_is_streaming;
|
||||
srslte_timestamp_t last_rx_time;
|
||||
float cellsearch_cfo;
|
||||
bool do_agc;
|
||||
double last_gain;
|
||||
bool init_(radio *radio_handler, tti_sync *ttisync, log *log_h, bool do_agc);
|
||||
static void *phy_thread_fnc(void *arg);
|
||||
bool decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]);
|
||||
int sync_sfn();
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/common/radio.h"
|
||||
#include "srsapps/radio/radio.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/common/queue.h"
|
||||
#include "srsapps/ue/phy/phy_params.h"
|
||||
|
||||
|
@ -45,7 +46,7 @@ namespace ue {
|
|||
initiated = false;
|
||||
signal_buffer = NULL;
|
||||
}
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db);
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h);
|
||||
void free_cell();
|
||||
bool prepare_to_send(uint32_t preamble_idx);
|
||||
bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe);
|
||||
|
@ -56,6 +57,7 @@ namespace ue {
|
|||
private:
|
||||
static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission
|
||||
phy_params *params_db = NULL;
|
||||
log *log_h;
|
||||
int preamble_idx;
|
||||
int allowed_subframe;
|
||||
bool initiated = false;
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/common/radio.h"
|
||||
#include "srsapps/radio/radio.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/common/queue.h"
|
||||
#include "srsapps/ue/phy/ul_sched_grant.h"
|
||||
#include "srsapps/ue/phy/dl_sched_grant.h"
|
||||
|
@ -46,7 +47,7 @@ namespace ue {
|
|||
class ul_buffer : public queue::element {
|
||||
|
||||
public:
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db);
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h);
|
||||
void free_cell();
|
||||
void set_current_tx_nb(uint32_t current_tx_nb);
|
||||
bool generate_ack(bool ack, dl_sched_grant *last_dl_grant);
|
||||
|
@ -61,6 +62,7 @@ namespace ue {
|
|||
static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission
|
||||
|
||||
private:
|
||||
log *log_h;
|
||||
phy_params *params_db;
|
||||
srslte_cell_t cell;
|
||||
srslte_ue_ul_t ue_ul;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <pthread.h>
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/sched_grant.h"
|
||||
#include "srsapps/ue/phy/dl_buffer.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
|
@ -39,8 +40,9 @@
|
|||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
bool dl_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_)
|
||||
bool dl_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_)
|
||||
{
|
||||
log_h = log_h_;
|
||||
params_db = params_db_;
|
||||
cell = cell_;
|
||||
sf_symbols_and_ce_done = false;
|
||||
|
@ -68,7 +70,6 @@ bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_t
|
|||
{
|
||||
bool ret = false;
|
||||
if (signal_buffer) {
|
||||
DEBUG("DL Buffer TTI %d: Receiving packet\n", tti);
|
||||
cf_t *sf_buffer = NULL;
|
||||
sf_symbols_and_ce_done = false;
|
||||
pdcch_llr_extracted = false;
|
||||
|
@ -86,10 +87,6 @@ void dl_buffer::discard_pending_rar_grant() {
|
|||
pending_rar_grant = false;
|
||||
}
|
||||
|
||||
void dl_buffer::release_pending_rar_grant() {
|
||||
pending_rar_grant = false;
|
||||
}
|
||||
|
||||
bool dl_buffer::get_ul_grant(ul_sched_grant *grant)
|
||||
{
|
||||
if (signal_buffer) {
|
||||
|
@ -124,29 +121,27 @@ void dl_buffer::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN])
|
|||
{
|
||||
pending_rar_grant = true;
|
||||
srslte_dci_rar_grant_unpack(&rar_grant, grant_payload);
|
||||
srslte_dci_rar_grant_fprint(stdout, &rar_grant);
|
||||
}
|
||||
|
||||
void dl_buffer::set_rar_grant(srslte_dci_rar_grant_t* rar_grant_)
|
||||
{
|
||||
pending_rar_grant = true;
|
||||
memcpy(&rar_grant, rar_grant_, sizeof(srslte_dci_rar_grant_t));
|
||||
srslte_dci_rar_grant_fprint(stdout, &rar_grant);
|
||||
}
|
||||
|
||||
bool dl_buffer::get_dl_grant(dl_sched_grant *grant)
|
||||
{
|
||||
if (signal_buffer && is_ready()) {
|
||||
DEBUG("DL Buffer TTI %d: Getting DL grant\n", tti);
|
||||
Debug("DL Buffer TTI %d: Getting DL grant\n", tti);
|
||||
if (!sf_symbols_and_ce_done) {
|
||||
DEBUG("DL Buffer TTI %d: Getting DL grant. Calling fft estimate\n", tti);
|
||||
Debug("DL Buffer TTI %d: Getting DL grant. Calling fft estimate\n", tti);
|
||||
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
|
||||
return false;
|
||||
}
|
||||
sf_symbols_and_ce_done = true;
|
||||
}
|
||||
if (!pdcch_llr_extracted) {
|
||||
DEBUG("DL Buffer TTI %d: Getting DL grant. extracting LLR\n", tti);
|
||||
Debug("DL Buffer TTI %d: Getting DL grant. extracting LLR\n", tti);
|
||||
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -196,9 +191,9 @@ bool dl_buffer::decode_data(dl_sched_grant *grant, uint8_t *payload)
|
|||
bool dl_buffer::decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softbuffer, uint8_t *payload)
|
||||
{
|
||||
if (signal_buffer && is_ready()) {
|
||||
DEBUG("DL Buffer TTI %d: Decoding PDSCH\n", tti);
|
||||
Debug("DL Buffer TTI %d: Decoding PDSCH\n", tti);
|
||||
if (!sf_symbols_and_ce_done) {
|
||||
DEBUG("DL Buffer TTI %d: Decoding PDSCH. Calling fft estimate\n", tti);
|
||||
Debug("DL Buffer TTI %d: Decoding PDSCH. Calling fft estimate\n", tti);
|
||||
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/phy/prach.h"
|
||||
#include "srsapps/ue/phy/ul_buffer.h"
|
||||
|
@ -39,15 +40,26 @@
|
|||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
bool phy::init(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_)
|
||||
|
||||
bool phy::init(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h) {
|
||||
return init_(radio_handler_, ttisync_, log_h, false);
|
||||
}
|
||||
|
||||
bool phy::init_agc(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h) {
|
||||
return init_(radio_handler_, ttisync_, log_h, true);
|
||||
}
|
||||
|
||||
bool phy::init_(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h_, bool do_agc_)
|
||||
{
|
||||
started = false;
|
||||
radio_is_streaming = false;
|
||||
ttisync = ttisync_;
|
||||
log_h = log_h_;
|
||||
radio_handler = radio_handler_;
|
||||
ul_buffer_queue = new queue(6, sizeof(ul_buffer));
|
||||
dl_buffer_queue = new queue(6, sizeof(dl_buffer));
|
||||
do_agc = do_agc_;
|
||||
last_gain = 1e4;
|
||||
|
||||
// Set default params
|
||||
params_db.set_param(phy_params::CELLSEARCH_TIMEOUT_PSS_NFRAMES, 100);
|
||||
|
@ -56,7 +68,7 @@ bool phy::init(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_)
|
|||
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
param.sched_priority = -20;
|
||||
param.sched_priority = sched_get_priority_min(SCHED_FIFO) ;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
|
||||
pthread_attr_setschedparam(&attr, ¶m);
|
||||
|
@ -93,13 +105,13 @@ radio* phy::get_radio() {
|
|||
void phy::set_timeadv_rar(uint32_t ta_cmd) {
|
||||
n_ta = srslte_N_ta_new_rar(ta_cmd);
|
||||
time_adv_sec = SRSLTE_TA_OFFSET+((float) n_ta)*SRSLTE_LTE_TS;
|
||||
INFO("Set TA RAR: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, n_ta, time_adv_sec*1e6);
|
||||
Info("Set TA RAR: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, n_ta, time_adv_sec*1e6);
|
||||
}
|
||||
|
||||
void phy::set_timeadv(uint32_t ta_cmd) {
|
||||
n_ta = srslte_N_ta_new(n_ta, ta_cmd);
|
||||
time_adv_sec = SRSLTE_TA_OFFSET+((float) n_ta)*SRSLTE_LTE_TS;
|
||||
INFO("Set TA: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, n_ta, time_adv_sec*1e6);
|
||||
Info("Set TA: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, n_ta, time_adv_sec*1e6);
|
||||
}
|
||||
|
||||
void phy::rar_ul_grant(srslte_dci_rar_grant_t *rar, ul_sched_grant *grant)
|
||||
|
@ -153,10 +165,10 @@ bool phy::start_rxtx()
|
|||
phy_state = RXTX;
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "Can not change state to RXTX: cell is not set\n");
|
||||
Error("Can not change state to RXTX: cell is not set\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Can not change state to RXTX: invalid state %d\n", phy_state);
|
||||
Error("Can not change state to RXTX: invalid state %d\n", phy_state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -169,11 +181,16 @@ bool phy::stop_rxtx()
|
|||
phy_state = IDLE;
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "Can not change state to RXTX: invalid state %d\n", phy_state);
|
||||
Error("Can not change state to RXTX: invalid state %d\n", phy_state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float phy::get_agc_gain()
|
||||
{
|
||||
return 10*log10(srslte_agc_get_gain(&ue_sync.agc));
|
||||
}
|
||||
|
||||
bool phy::status_is_idle() {
|
||||
return phy_state == IDLE;
|
||||
}
|
||||
|
@ -206,6 +223,11 @@ int radio_recv_wrapper_cs(void *h,void *data, uint32_t nsamples, srslte_timestam
|
|||
return n;
|
||||
}
|
||||
|
||||
double callback_set_rx_gain(void *h, double gain) {
|
||||
radio *radio_handler = (radio*) h;
|
||||
return radio_handler->set_rx_gain_th(gain);
|
||||
}
|
||||
|
||||
bool phy::set_cell(srslte_cell_t cell_) {
|
||||
if (phy_state == IDLE) {
|
||||
cell_is_set = false;
|
||||
|
@ -215,29 +237,33 @@ bool phy::set_cell(srslte_cell_t cell_) {
|
|||
if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_handler))
|
||||
{
|
||||
|
||||
if (do_agc) {
|
||||
srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain);
|
||||
}
|
||||
|
||||
srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo);
|
||||
for(uint32_t i=0;i<6;i++) {
|
||||
((ul_buffer*) ul_buffer_queue->get(i))->init_cell(cell, ¶ms_db);
|
||||
((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, ¶ms_db);
|
||||
((ul_buffer*) ul_buffer_queue->get(i))->init_cell(cell, ¶ms_db, log_h);
|
||||
((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, ¶ms_db, log_h);
|
||||
((dl_buffer*) dl_buffer_queue->get(i))->buffer_id = i;
|
||||
((ul_buffer*) ul_buffer_queue->get(i))->ready();
|
||||
((dl_buffer*) dl_buffer_queue->get(i))->release();
|
||||
}
|
||||
cell_is_set = true;
|
||||
} else {
|
||||
fprintf(stderr, "Error setting cell: initiating ue_sync");
|
||||
Error("Error setting cell: initiating ue_sync");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error setting cell: initiating ue_mib\n");
|
||||
Error("Error setting cell: initiating ue_mib\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error setting cell: Invalid state %d\n", phy_state);
|
||||
Error("Error setting cell: Invalid state %d\n", phy_state);
|
||||
}
|
||||
return cell_is_set;
|
||||
}
|
||||
|
||||
bool phy::init_prach() {
|
||||
return prach_buffer.init_cell(cell, ¶ms_db);
|
||||
return prach_buffer.init_cell(cell, ¶ms_db, log_h);
|
||||
}
|
||||
|
||||
ul_buffer* phy::get_ul_buffer(uint32_t tti)
|
||||
|
@ -253,7 +279,7 @@ ul_buffer* phy::get_ul_buffer_adv(uint32_t tti)
|
|||
dl_buffer* phy::get_dl_buffer(uint32_t tti)
|
||||
{
|
||||
if (tti + 6 < get_current_tti()) {
|
||||
printf("Warning access to PHY too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
|
||||
Warning("Warning access to PHY too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
|
||||
}
|
||||
return (dl_buffer*) dl_buffer_queue->get(tti);
|
||||
}
|
||||
|
@ -277,6 +303,11 @@ bool phy::decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell_ptr, uint8_t b
|
|||
return false;
|
||||
}
|
||||
|
||||
if (do_agc) {
|
||||
srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, last_gain);
|
||||
}
|
||||
|
||||
|
||||
srslte_ue_cellsearch_set_nof_frames_to_scan(&cs, params_db.get_param(phy_params::CELLSEARCH_TIMEOUT_PSS_NFRAMES));
|
||||
srslte_ue_cellsearch_set_threshold(&cs, (float)
|
||||
params_db.get_param(phy_params::CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD)/10);
|
||||
|
@ -294,23 +325,25 @@ bool phy::decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell_ptr, uint8_t b
|
|||
ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell);
|
||||
}
|
||||
|
||||
last_gain = srslte_agc_get_gain(&cs.ue_sync.agc);
|
||||
|
||||
radio_handler->stop_rx();
|
||||
srslte_ue_cellsearch_free(&cs);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding MIB: Error searching PSS\n");
|
||||
Error("Error decoding MIB: Error searching PSS\n");
|
||||
return false;
|
||||
} else if (ret == 0) {
|
||||
fprintf(stderr, "Error decoding MIB: Could not find any PSS in this frequency\n");
|
||||
Error("Error decoding MIB: Could not find any PSS in this frequency\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Save result
|
||||
cell_ptr->id = found_cells[max_peak_cell].cell_id;
|
||||
cell_ptr->cp = found_cells[max_peak_cell].cp;
|
||||
cellsearch_cfo = found_cells[max_peak_cell].cfo;
|
||||
|
||||
INFO("\nFound CELL ID: %d CP: %s, CFO: %f\n", cell_ptr->id, srslte_cp_string(cell_ptr->cp), cellsearch_cfo);
|
||||
Info("\nFound CELL ID: %d CP: %s, CFO: %f\n", cell_ptr->id, srslte_cp_string(cell_ptr->cp), cellsearch_cfo);
|
||||
|
||||
srslte_ue_mib_sync_t ue_mib_sync;
|
||||
|
||||
|
@ -318,6 +351,10 @@ bool phy::decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell_ptr, uint8_t b
|
|||
return false;
|
||||
}
|
||||
|
||||
if (do_agc) {
|
||||
srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, last_gain);
|
||||
}
|
||||
|
||||
/* Find and decode MIB */
|
||||
uint32_t sfn, sfn_offset;
|
||||
|
||||
|
@ -325,13 +362,15 @@ bool phy::decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell_ptr, uint8_t b
|
|||
ret = srslte_ue_mib_sync_decode(&ue_mib_sync, params_db.get_param(phy_params::CELLSEARCH_TIMEOUT_MIB_NFRAMES),
|
||||
bch_payload, &cell_ptr->nof_ports, &sfn_offset);
|
||||
radio_handler->stop_rx();
|
||||
last_gain = srslte_agc_get_gain(&ue_mib_sync.ue_sync.agc);
|
||||
srslte_ue_mib_sync_free(&ue_mib_sync);
|
||||
|
||||
|
||||
if (ret == 1) {
|
||||
srslte_pbch_mib_unpack(bch_payload, cell_ptr, NULL);
|
||||
return true;
|
||||
} else {
|
||||
printf("Error decoding MIB: Error decoding PBCH\n");
|
||||
Warning("Error decoding MIB: Error decoding PBCH\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +385,7 @@ int phy::sync_sfn(void) {
|
|||
srslte_ue_sync_decode_sss_on_track(&ue_sync, true);
|
||||
ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error calling ue_sync_get_buffer");
|
||||
Error("Error calling ue_sync_get_buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -356,7 +395,7 @@ int phy::sync_sfn(void) {
|
|||
srslte_pbch_decode_reset(&ue_mib.pbch);
|
||||
int n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding MIB while synchronising SFN");
|
||||
Error("Error decoding MIB while synchronising SFN");
|
||||
return -1;
|
||||
} else if (n == SRSLTE_UE_MIB_FOUND) {
|
||||
uint32_t sfn;
|
||||
|
@ -395,6 +434,7 @@ void phy::run_rx_tx_state()
|
|||
}
|
||||
} else {
|
||||
uint32_t current_tti = ttisync->get_producer_cntr();
|
||||
log_h->step(current_tti);
|
||||
float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000;
|
||||
|
||||
// Prepare transmission for the next tti
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/cuhd/cuhd.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/prach.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/phy/phy_params.h"
|
||||
|
@ -55,9 +55,10 @@ void prach::free_cell()
|
|||
}
|
||||
}
|
||||
|
||||
bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_)
|
||||
bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_)
|
||||
{
|
||||
cell = cell_;
|
||||
log_h = log_h_;
|
||||
params_db = params_db_;
|
||||
preamble_idx = -1;
|
||||
if (srslte_prach_init(&prach_obj, srslte_symbol_sz(cell.nof_prb),
|
||||
|
@ -97,7 +98,7 @@ bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, int t
|
|||
preamble_idx = preamble_idx_;
|
||||
allowed_subframe = allowed_subframe_;
|
||||
transmitted_tti = -1;
|
||||
INFO("PRACH Buffer: Prepare to send preamble %d\n", preamble_idx);
|
||||
Info("PRACH Buffer: Prepare to send preamble %d\n", preamble_idx);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -122,14 +123,13 @@ bool prach::is_ready_to_send(uint32_t current_tti_) {
|
|||
if ((current_tti%10) == sf_config.sf[i] && allowed_subframe == -1 ||
|
||||
((current_tti%10) == sf_config.sf[i] && (current_tti%10) == allowed_subframe))
|
||||
{
|
||||
INFO("PRACH Buffer: Ready to send at tti: %d (now is %d)\n", current_tti, current_tti_);
|
||||
Info("PRACH Buffer: Ready to send at tti: %d (now is %d)\n", current_tti, current_tti_);
|
||||
transmitted_tti = current_tti;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG("PRACH Buffer: Not ready to send at tti: %d\n", current_tti_);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -149,13 +149,12 @@ bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t rx_time)
|
|||
srslte_timestamp_add(&tx_time, 0, 1e-3*tx_advance_sf);
|
||||
|
||||
// Correct CFO before transmission
|
||||
srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, 1.5*cfo/srslte_symbol_sz(cell.nof_prb));
|
||||
srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, cfo /srslte_symbol_sz(cell.nof_prb));
|
||||
|
||||
// transmit
|
||||
radio_handler->tx(signal_buffer, len, tx_time);
|
||||
INFO("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n",
|
||||
Info("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n",
|
||||
cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs);
|
||||
//srslte_vec_save_file("prach", buffer, len*sizeof(cf_t));
|
||||
preamble_idx = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/sched_grant.h"
|
||||
#include "srsapps/ue/phy/ul_buffer.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
|
@ -40,8 +41,9 @@
|
|||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_) {
|
||||
bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) {
|
||||
cell = cell_;
|
||||
log_h = log_h_;
|
||||
params_db = params_db_;
|
||||
current_tx_nb = 0;
|
||||
if (!srslte_ue_ul_init(&ue_ul, cell)) {
|
||||
|
@ -142,7 +144,7 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
|
|||
pucch_cfg.group_hopping_en = dmrs_cfg.group_hopping_en;
|
||||
pucch_cfg.N_cs = params_db->get_param(phy_params::PUCCH_CYCLIC_SHIFT);
|
||||
pucch_cfg.n_rb_2 = params_db->get_param(phy_params::PUCCH_N_RB_2);
|
||||
|
||||
|
||||
srslte_pucch_sched_t pucch_sched;
|
||||
bzero(&pucch_sched, sizeof(srslte_pucch_sched_t));
|
||||
pucch_sched.n_cce = last_n_cce;
|
||||
|
@ -164,12 +166,22 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
|
|||
// Transmit on PUSCH if UL grant available, otherwise in PUCCH
|
||||
if (grant) {
|
||||
|
||||
INFO("Encoding PUSCH TBS=%d, rb_start=%d n_prb=%d, rv=%d, rnti=%d\n",
|
||||
grant->get_tbs(), pusch_cfg.grant.L_prb, pusch_cfg.grant.n_prb[0], grant->get_rv(), grant->get_rnti());
|
||||
|
||||
grant->to_pusch_cfg(tti%10, cell.cp, &pusch_cfg);
|
||||
n = srslte_ue_ul_pusch_encode_cfg(&ue_ul, &pusch_cfg,
|
||||
payload, uci_data,
|
||||
softbuffer,
|
||||
grant->get_rnti(),
|
||||
signal_buffer);
|
||||
|
||||
if (grant->get_rv() == 0) {
|
||||
bzero(signal_buffer, 7680*sizeof(cf_t));
|
||||
}
|
||||
} else {
|
||||
Info("Encoding PUCCH n_cce=%d, ack=%d\n", last_n_cce, uci_data.uci_ack);
|
||||
|
||||
n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti&10, signal_buffer);
|
||||
}
|
||||
// Reset UCI data
|
||||
|
@ -196,8 +208,9 @@ bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo
|
|||
srslte_timestamp_add(&tx_time, 0, tx_advance_sf*1e-3 - time_adv_sec);
|
||||
|
||||
// Compute peak
|
||||
float max = -1;
|
||||
#ifdef compute_peak
|
||||
if (SRSLTE_VERBOSE_ISINFO()) {
|
||||
float max = 0;
|
||||
float *t = (float*) signal_buffer;
|
||||
for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) {
|
||||
if (fabsf(t[i]) > max) {
|
||||
|
@ -205,15 +218,20 @@ bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo
|
|||
}
|
||||
}
|
||||
}
|
||||
INFO("Send PUSCH TTI: %d, CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us PeakAmplitude=%f\n",
|
||||
tti, cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb),
|
||||
#endif
|
||||
|
||||
Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us\n",
|
||||
cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb),
|
||||
srslte_timestamp_real(&rx_time),
|
||||
srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max);
|
||||
srslte_timestamp_real(&tx_time), time_adv_sec*1000000);
|
||||
|
||||
// Correct CFO before transmission
|
||||
srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, 1.5*cfo / srslte_symbol_sz(cell.nof_prb));
|
||||
srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb));
|
||||
|
||||
radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time);
|
||||
|
||||
//srslte_vec_save_file("pucch_tx", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
ready();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "srslte/utils/debug.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log_stdout.h"
|
||||
#include "srsapps/common/tti_sync_cv.h"
|
||||
#include "srsapps/radio/radio_uhd.h"
|
||||
|
||||
|
@ -48,15 +49,15 @@ prog_args_t prog_args;
|
|||
void args_default(prog_args_t *args) {
|
||||
args->uhd_rx_freq = -1.0;
|
||||
args->uhd_tx_freq = -1.0;
|
||||
args->uhd_rx_gain = 60.0;
|
||||
args->uhd_tx_gain = 40.0;
|
||||
args->uhd_rx_gain = -1; // set to autogain
|
||||
args->uhd_tx_gain = -1;
|
||||
args->continous = false;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
printf("Usage: %s [gGcv] -f rx_frequency -F tx_frequency (in Hz)\n", prog);
|
||||
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_rx_gain);
|
||||
printf("\t-G UHD TX gain [Default %.2f dB]\n", args->uhd_tx_gain);
|
||||
printf("\t-g UHD RX gain [Default AGC]\n");
|
||||
printf("\t-G UHD TX gain [Default same as RX gain (AGC)]\n");
|
||||
printf("\t-c Run continuously [Default only once]\n");
|
||||
printf("\t-v [increase verbosity, default none]\n");
|
||||
}
|
||||
|
@ -208,7 +209,7 @@ void config_phy() {
|
|||
phy.set_param(srslte::ue::phy_params::PRACH_FREQ_OFFSET, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX, 0);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 4);
|
||||
phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 1);
|
||||
|
||||
phy.set_param(srslte::ue::phy_params::PUSCH_BETA, 10);
|
||||
phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_HOPPING_EN, 0);
|
||||
|
@ -398,12 +399,15 @@ void run_tti(uint32_t tti) {
|
|||
state = RA;
|
||||
}
|
||||
}
|
||||
|
||||
float gain = prog_args.uhd_rx_gain;
|
||||
if (gain < 0) {
|
||||
gain = phy.get_agc_gain();
|
||||
}
|
||||
if (srslte_verbose == SRSLTE_VERBOSE_NONE && prog_args.continous) {
|
||||
printf("RECV RAR %2.1f \%% RECV ConnSetup %2.1f \%% (%5u/%5u) \r",
|
||||
printf("RECV RAR %2.1f \%% RECV ConnSetup %2.1f \%% (%5u/%5u) Gain: %.1f dB\r",
|
||||
(float) 100*nof_rx_rar/nof_tx_ra,
|
||||
(float) 100*nof_rx_connsetup/nof_tx_ra,
|
||||
nof_rx_connsetup, nof_tx_ra);
|
||||
nof_rx_connsetup, nof_tx_ra, gain);
|
||||
}
|
||||
|
||||
|
||||
|
@ -415,14 +419,21 @@ int main(int argc, char *argv[])
|
|||
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
|
||||
srslte::ue::tti_sync_cv ttisync(10240);
|
||||
srslte::radio_uhd radio_uhd;
|
||||
srslte::log_stdout log("PHY");
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
// Init Radio
|
||||
radio_uhd.init();
|
||||
|
||||
// Init PHY
|
||||
phy.init(&radio_uhd, &ttisync);
|
||||
// Init Radio and PHY
|
||||
if (prog_args.uhd_rx_gain > 0 && prog_args.uhd_tx_gain > 0) {
|
||||
radio_uhd.init();
|
||||
radio_uhd.set_rx_gain(prog_args.uhd_rx_gain);
|
||||
radio_uhd.set_tx_gain(prog_args.uhd_tx_gain);
|
||||
phy.init(&radio_uhd, &ttisync, &log);
|
||||
} else {
|
||||
radio_uhd.init_agc();
|
||||
radio_uhd.set_tx_rx_gain_offset(-10);
|
||||
phy.init_agc(&radio_uhd, &ttisync, &log);
|
||||
}
|
||||
|
||||
// Give it time to create thread
|
||||
sleep(1);
|
||||
|
@ -430,11 +441,9 @@ int main(int argc, char *argv[])
|
|||
// Setup PHY parameters
|
||||
config_phy();
|
||||
|
||||
// Set RX freq and gain
|
||||
phy.get_radio()->set_rx_freq(prog_args.uhd_rx_freq);
|
||||
phy.get_radio()->set_tx_freq(prog_args.uhd_tx_freq);
|
||||
phy.get_radio()->set_rx_gain(prog_args.uhd_rx_gain);
|
||||
phy.get_radio()->set_tx_gain(prog_args.uhd_tx_gain);
|
||||
// Set RX freq
|
||||
radio_uhd.set_rx_freq(prog_args.uhd_rx_freq);
|
||||
radio_uhd.set_tx_freq(prog_args.uhd_tx_freq);
|
||||
|
||||
/* Instruct the PHY to decode BCH */
|
||||
if (!phy.decode_mib_best(&cell, bch_payload)) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "srslte/utils/debug.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log_stdout.h"
|
||||
#include "srsapps/common/tti_sync_cv.h"
|
||||
#include "srsapps/radio/radio_uhd.h"
|
||||
|
||||
|
@ -43,12 +44,12 @@ typedef struct {
|
|||
|
||||
void args_default(prog_args_t *args) {
|
||||
args->uhd_freq = -1.0;
|
||||
args->uhd_gain = 60.0;
|
||||
args->uhd_gain = -1.0;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
printf("Usage: %s [gv] -f rx_frequency (in Hz)\n", prog);
|
||||
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_gain);
|
||||
printf("\t-g UHD RX gain [Default AGC]\n");
|
||||
printf("\t-v [increase verbosity, default none]\n");
|
||||
}
|
||||
|
||||
|
@ -84,6 +85,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
|
||||
|
||||
srslte::ue::phy phy;
|
||||
prog_args_t prog_args;
|
||||
|
||||
uint32_t total_pkts=0;
|
||||
uint32_t total_dci=0;
|
||||
|
@ -114,11 +116,15 @@ void run_tti(uint32_t tti) {
|
|||
}
|
||||
total_pkts++;
|
||||
}
|
||||
float gain = prog_args.uhd_gain;
|
||||
if (gain < 0) {
|
||||
gain = phy.get_agc_gain();
|
||||
}
|
||||
if (srslte_verbose == SRSLTE_VERBOSE_NONE) {
|
||||
printf("PDCCH BLER %.1f \%% PDSCH BLER %.1f \%% (total pkts: %5u) \r",
|
||||
printf("PDCCH BLER %.1f \%% PDSCH BLER %.1f \%% (total pkts: %5u) Gain: %.1f dB\r",
|
||||
100-(float) 100*total_dci/total_pkts,
|
||||
(float) 100*total_errors/total_pkts,
|
||||
total_pkts);
|
||||
total_pkts, gain);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,17 +132,21 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
srslte_cell_t cell;
|
||||
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
|
||||
prog_args_t prog_args;
|
||||
srslte::ue::tti_sync_cv ttisync(10240);
|
||||
srslte::radio_uhd radio_uhd;
|
||||
srslte::log_stdout log("PHY");
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
// Init Radio
|
||||
radio_uhd.init();
|
||||
|
||||
// Init PHY
|
||||
phy.init(&radio_uhd, &ttisync);
|
||||
// Init Radio and PHY
|
||||
if (prog_args.uhd_gain > 0) {
|
||||
radio_uhd.init();
|
||||
radio_uhd.set_rx_gain(prog_args.uhd_gain);
|
||||
phy.init(&radio_uhd, &ttisync, &log);
|
||||
} else {
|
||||
radio_uhd.init_agc();
|
||||
phy.init_agc(&radio_uhd, &ttisync, &log);
|
||||
}
|
||||
|
||||
// Give it time to create thread
|
||||
sleep(1);
|
||||
|
|
|
@ -267,14 +267,14 @@ int main(int argc, char **argv) {
|
|||
/* Set receiver gain */
|
||||
if (prog_args.uhd_gain > 0) {
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open_th(prog_args.uhd_args, &uhd)) {
|
||||
if (cuhd_open(prog_args.uhd_args, &uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
exit(-1);
|
||||
}
|
||||
cuhd_set_rx_gain(uhd, prog_args.uhd_gain);
|
||||
} else {
|
||||
printf("Opening UHD device with threaded RX Gain control ...\n");
|
||||
if (cuhd_open_th(prog_args.uhd_args, &uhd)) {
|
||||
if (cuhd_open_th(prog_args.uhd_args, &uhd, false)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "srslte/config.h"
|
||||
|
||||
#define SRSLTE_AGC_DEFAULT_TARGET 0.7
|
||||
#define SRSLTE_AGC_DEFAULT_BW (5e-2)
|
||||
#define SRSLTE_AGC_DEFAULT_BW (5e-1)
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
SRSLTE_AGC_MODE_ENERGY = 0,
|
||||
|
|
|
@ -39,7 +39,8 @@ SRSLTE_API int cuhd_open(char *args,
|
|||
void **handler);
|
||||
|
||||
SRSLTE_API int cuhd_open_th(char *args,
|
||||
void **handler);
|
||||
void **handler,
|
||||
bool tx_gain_same_rx);
|
||||
|
||||
SRSLTE_API int cuhd_close(void *h);
|
||||
|
||||
|
@ -60,9 +61,11 @@ SRSLTE_API double cuhd_set_rx_srate(void *h,
|
|||
SRSLTE_API double cuhd_set_rx_gain(void *h,
|
||||
double gain);
|
||||
|
||||
SRSLTE_API void cuhd_set_tx_rx_gain_offset(void *h,
|
||||
double offset);
|
||||
|
||||
SRSLTE_API double cuhd_set_rx_gain_th(void *h,
|
||||
double gain);
|
||||
|
||||
SRSLTE_API double cuhd_get_rx_gain(void *h);
|
||||
|
||||
SRSLTE_API double cuhd_set_rx_freq(void *h,
|
||||
|
|
|
@ -140,6 +140,7 @@ SRSLTE_API int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q,
|
|||
srslte_pusch_cfg_t *cfg,
|
||||
uint8_t *data,
|
||||
srslte_uci_data_t uci_data,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint16_t rnti,
|
||||
cf_t *output_signal);
|
||||
|
||||
|
|
|
@ -42,5 +42,7 @@ public:
|
|||
pthread_mutex_t mutex;
|
||||
double cur_rx_gain;
|
||||
double new_rx_gain;
|
||||
bool tx_gain_same_rx;
|
||||
float tx_rx_gain_offset;
|
||||
uhd::gain_range_t rx_gain_range;
|
||||
};
|
||||
|
|
|
@ -121,7 +121,6 @@ int cuhd_start_rx_stream_nsamples(void *h, uint32_t nsamples)
|
|||
double cuhd_set_rx_gain_th(void *h, double gain)
|
||||
{
|
||||
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
|
||||
// round to avoid histeresis
|
||||
gain = handler->rx_gain_range.clip(gain);
|
||||
pthread_mutex_lock(&handler->mutex);
|
||||
handler->new_rx_gain = gain;
|
||||
|
@ -130,6 +129,11 @@ double cuhd_set_rx_gain_th(void *h, double gain)
|
|||
return gain;
|
||||
}
|
||||
|
||||
void cuhd_set_tx_rx_gain_offset(void *h, double offset) {
|
||||
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
|
||||
handler->tx_rx_gain_offset = offset;
|
||||
}
|
||||
|
||||
/* This thread listens for set_rx_gain commands to the USRP */
|
||||
static void* thread_gain_fcn(void *h) {
|
||||
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
|
||||
|
@ -141,11 +145,14 @@ static void* thread_gain_fcn(void *h) {
|
|||
handler->cur_rx_gain = handler->new_rx_gain;
|
||||
pthread_mutex_unlock(&handler->mutex);
|
||||
cuhd_set_rx_gain(h, handler->cur_rx_gain);
|
||||
if (handler->tx_gain_same_rx) {
|
||||
cuhd_set_tx_gain(h, handler->cur_rx_gain+handler->tx_rx_gain_offset);
|
||||
}
|
||||
//printf("Set gain %.2f\n", handler->cur_rx_gain);
|
||||
}
|
||||
}
|
||||
|
||||
int cuhd_open_(char *args, void **h, bool create_thread_gain)
|
||||
int cuhd_open_(char *args, void **h, bool create_thread_gain, bool tx_gain_same_rx)
|
||||
{
|
||||
cuhd_handler *handler = new cuhd_handler();
|
||||
std::string _args = std::string(args);
|
||||
|
@ -165,7 +172,8 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain)
|
|||
handler->rx_stream = handler->usrp->get_rx_stream(stream_args);
|
||||
handler->tx_stream = handler->usrp->get_tx_stream(stream_args);
|
||||
|
||||
|
||||
handler->tx_gain_same_rx = tx_gain_same_rx;
|
||||
handler->tx_rx_gain_offset = 0.0;
|
||||
handler->rx_gain_range = handler->usrp->get_rx_gain_range();
|
||||
|
||||
|
||||
|
@ -189,11 +197,11 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain)
|
|||
}
|
||||
|
||||
int cuhd_open(char *args, void **h) {
|
||||
return cuhd_open_(args, h, false);
|
||||
return cuhd_open_(args, h, false, false);
|
||||
}
|
||||
|
||||
int cuhd_open_th(char *args, void **h) {
|
||||
return cuhd_open_(args, h, true);
|
||||
int cuhd_open_th(char *args, void **h, bool tx_gain_same_rx) {
|
||||
return cuhd_open_(args, h, true, tx_gain_same_rx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -347,8 +347,6 @@ int srslte_prach_init(srslte_prach_t *p,
|
|||
}
|
||||
}
|
||||
|
||||
printf("N_cs=%d, ZCZC=%d\n", p->N_cs, p->zczc);
|
||||
|
||||
// Set up containers
|
||||
p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*p->N_zc);
|
||||
p->corr_spec = srslte_vec_malloc(sizeof(cf_t)*p->N_zc);
|
||||
|
@ -425,7 +423,7 @@ int srslte_prach_gen(srslte_prach_t *p,
|
|||
uint32_t N_rb_ul = prach_get_rb_ul(p->N_ifft_ul);
|
||||
uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2;
|
||||
uint32_t K = DELTA_F/DELTA_F_RA;
|
||||
uint32_t begin = PHI + (K*k_0) + (K/2);
|
||||
uint32_t begin = PHI + (K*k_0) + (K/2) + 1;
|
||||
|
||||
DEBUG("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin);
|
||||
// Map dft-precoded sequence to ifft bins
|
||||
|
|
|
@ -150,6 +150,7 @@ uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, u
|
|||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
m = cfg->n_rb_2;
|
||||
|
||||
uint32_t c=SRSLTE_CP_ISNORM(cp)?3:2;
|
||||
if (n_pucch >= c*cfg->N_cs/cfg->delta_pucch_shift) {
|
||||
m = (n_pucch-c*cfg->N_cs/cfg->delta_pucch_shift)/(c*SRSLTE_NRE/cfg->delta_pucch_shift)
|
||||
|
@ -495,8 +496,8 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
|
|||
if (n_prime_ns%2) {
|
||||
S_ns = M_PI/2;
|
||||
}
|
||||
DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d\n",
|
||||
__real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns);
|
||||
DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n",
|
||||
__real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2);
|
||||
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
|
||||
q->z[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->pucch_cfg.beta_pucch
|
||||
*q->d[0]*w_n_oc[n_oc%3][m]*cexpf(I*(q->tmp_arg[n]+alpha*n+S_ns));
|
||||
|
|
|
@ -170,33 +170,39 @@ int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_
|
|||
}
|
||||
|
||||
static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant) {
|
||||
int tbs = -1;
|
||||
// 8.6.2 First paragraph
|
||||
if (dci->mcs_idx <= 28) {
|
||||
/* Table 8.6.1-1 on 36.213 */
|
||||
if (dci->mcs_idx < 11) {
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->L_prb);
|
||||
tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->L_prb);
|
||||
} else if (dci->mcs_idx < 21) {
|
||||
grant->mcs.mod = SRSLTE_MOD_16QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->L_prb);
|
||||
tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->L_prb);
|
||||
} else if (dci->mcs_idx < 29) {
|
||||
grant->mcs.mod = SRSLTE_MOD_64QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->L_prb);
|
||||
tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->L_prb);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid MCS index %d\n", dci->mcs_idx);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
} else if (dci->mcs_idx == 29 && dci->cqi_request && grant->L_prb <= 4) {
|
||||
// 8.6.1 and 8.6.2 36.213 second paragraph
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = 0;
|
||||
tbs = 0;
|
||||
} else if (dci->mcs_idx >= 29) {
|
||||
// Else use last TBS/Modulation and use mcs to obtain rv_idx
|
||||
grant->mcs.tbs = 0;
|
||||
tbs = 0;
|
||||
grant->mcs.mod = 0;
|
||||
dci->rv_idx = dci->mcs_idx - 28;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
if (tbs < 0) {
|
||||
fprintf(stderr, "Error computing TBS\n");
|
||||
return SRSLTE_ERROR;
|
||||
} else {
|
||||
grant->mcs.tbs = (uint32_t) tbs;
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/** Compute PRB allocation for Uplink as defined in 8.1 and 8.4 of 36.213 */
|
||||
|
@ -364,29 +370,28 @@ static int dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_dl_
|
|||
/* Modulation order and transport block size determination 7.1.7 in 36.213 */
|
||||
static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, bool crc_is_crnti) {
|
||||
uint32_t n_prb;
|
||||
int tbs = -1;
|
||||
switch(dci->dci_format) {
|
||||
case SRSLTE_RA_DCI_FORMAT1:
|
||||
/* Table 7.1.7.1-1 on 36.213 */
|
||||
if (dci->mcs_idx < 10) {
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->nof_prb);
|
||||
tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->nof_prb);
|
||||
} else if (dci->mcs_idx < 17) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_16QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->nof_prb);
|
||||
tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->nof_prb);
|
||||
} else if (dci->mcs_idx < 29) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_64QAM;
|
||||
grant->mcs.tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->nof_prb);
|
||||
tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->nof_prb);
|
||||
} else if (dci->mcs_idx == 29) {
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
grant->mcs.tbs = 0;
|
||||
tbs = 0;
|
||||
} else if (dci->mcs_idx == 30) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_16QAM;
|
||||
grant->mcs.tbs = 0;
|
||||
tbs = 0;
|
||||
} else if (dci->mcs_idx == 31) {
|
||||
grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_64QAM;
|
||||
grant->mcs.tbs = 0;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
tbs = 0;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_RA_DCI_FORMAT1A:
|
||||
|
@ -397,23 +402,24 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr
|
|||
n_prb = dci->type2_alloc.n_prb1a == SRSLTE_RA_TYPE2_NPRB1A_2 ? 2 : 3;
|
||||
}
|
||||
if (dci->mcs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {
|
||||
grant->mcs.tbs = tbs_table[dci->mcs_idx][n_prb - 1];
|
||||
tbs = tbs_table[dci->mcs_idx][n_prb - 1];
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SRSLTE_RA_DCI_FORMAT1C:
|
||||
/* Downlink Transport Block size for Format 1C as defined in 7.1.7.2.2-1 on 36.213 */
|
||||
if (dci->mcs_idx < 32) {
|
||||
grant->mcs.tbs = tbs_format1c_table[dci->mcs_idx];
|
||||
tbs = tbs_format1c_table[dci->mcs_idx];
|
||||
grant->mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
if (tbs < 0) {
|
||||
return SRSLTE_ERROR;
|
||||
} else {
|
||||
grant->mcs.tbs = (uint32_t) tbs;
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/** Obtains a DL grant from a DCI grant for PDSCH */
|
||||
|
@ -528,6 +534,7 @@ int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb) {
|
|||
if (tbs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {
|
||||
return tbs_table[tbs_idx][n_prb - 1];
|
||||
} else {
|
||||
fprintf(stderr, "Error computing TBS: Invalid TBS_idx=%d or n_prb=%d\n", tbs_idx, n_prb);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ static int encode_tb(srslte_sch_t *q,
|
|||
if (cb_segm->C > 0) {
|
||||
gamma = Gp%cb_segm->C;
|
||||
}
|
||||
|
||||
|
||||
if (data) {
|
||||
/* Compute transport block CRC */
|
||||
par = srslte_crc_checksum(&q->crc_tb, data, cb_segm->tbs);
|
||||
|
|
|
@ -102,7 +102,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
return;
|
||||
}
|
||||
|
||||
srslte_vec_sc_prod_cfc(signal, 1.0/sqrtf(N_ifft_ul), signal, prach.N_seq+prach.N_cp);
|
||||
srslte_vec_sc_prod_cfc(signal, 1.0/sqrtf(N_ifft_ul), signal, nof_samples);
|
||||
|
||||
if (nlhs >= 0) {
|
||||
mexutils_write_cf(signal, &plhs[0], nof_samples, 1);
|
||||
|
|
|
@ -161,6 +161,7 @@ void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
|
|||
srslte_pucch_sched_t *pucch_sched)
|
||||
{
|
||||
srslte_refsignal_ul_set_pusch_cfg(&q->dmrs, dmrs_cfg);
|
||||
srslte_refsignal_ul_set_pucch_cfg(&q->dmrs, pucch_cfg);
|
||||
srslte_pusch_set_hopping_cfg(&q->pusch, pusch_hopping_cfg);
|
||||
srslte_pucch_set_cfg(&q->pucch, pucch_cfg);
|
||||
if (pucch_sched) {
|
||||
|
@ -264,6 +265,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
|||
}
|
||||
srslte_refsignal_dmrs_pucch_put(&q->dmrs, format, n_pucch, q->refsignal, q->sf_symbols);
|
||||
|
||||
|
||||
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal);
|
||||
|
||||
if (q->cfo_en) {
|
||||
|
@ -274,7 +276,6 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
|||
float norm_factor = (float) q->cell.nof_prb/10;
|
||||
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
}
|
||||
srslte_vec_save_file("pucch", output_signal, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -325,13 +326,14 @@ int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *
|
|||
q->pusch_cfg.cp = q->cell.cp;
|
||||
srslte_cbsegm(&q->pusch_cfg.cb_segm, grant->mcs.tbs);
|
||||
|
||||
return srslte_ue_ul_pusch_encode_cfg(q, &q->pusch_cfg, data, uci_data, rnti, output_signal);
|
||||
return srslte_ue_ul_pusch_encode_cfg(q, &q->pusch_cfg, data, uci_data, &q->softbuffer, rnti, output_signal);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
|
||||
uint8_t *data, srslte_uci_data_t uci_data,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint16_t rnti,
|
||||
cf_t *output_signal)
|
||||
{
|
||||
|
@ -342,7 +344,7 @@ int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
|
|||
cfg != NULL &&
|
||||
output_signal != NULL)
|
||||
{
|
||||
if (srslte_pusch_encode_rnti(&q->pusch, cfg, &q->softbuffer, data, rnti, q->sf_symbols)) {
|
||||
if (srslte_pusch_encode_rnti(&q->pusch, cfg, softbuffer, data, rnti, q->sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue