ConnectionSetup working with MAC test

This commit is contained in:
ismagom 2015-05-16 23:24:18 +02:00
parent 68d193a725
commit 0b3c611f38
45 changed files with 717 additions and 420 deletions

View File

@ -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)

View File

@ -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!');

View File

@ -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;
};

View File

@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
};
}
}

View File

@ -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;

View File

@ -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,

View File

@ -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;
};
}

View File

@ -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);

View File

@ -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 {

View File

@ -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;
};
}

View File

@ -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;

View File

@ -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;

View File

@ -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, &param);
@ -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, &params_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);
}

View File

@ -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();
}
}
}

View File

@ -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
}

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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, &param);
@ -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, &params_db);
((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, &params_db);
((ul_buffer*) ul_buffer_queue->get(i))->init_cell(cell, &params_db, log_h);
((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, &params_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, &params_db);
return prach_buffer.init_cell(cell, &params_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

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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

View File

@ -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));

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}