PHY test examples working

master
ismagom 10 years ago
parent 97a824c3ee
commit f65aa3be1d

@ -54,13 +54,15 @@ public:
uint32_t tti;
bool ndi;
uint32_t tbs;
srslte_rnti_type_t rnti_type;
uint32_t rv;
uint16_t rnti;
srslte_phy_grant_t phy_grant;
} mac_grant_t;
typedef struct {
bool decode_enabled;
uint16_t rv;
uint32_t rv;
uint16_t rnti;
bool generate_ack;
bool default_ack;
uint8_t *payload_ptr;
@ -70,7 +72,9 @@ public:
typedef struct {
bool tx_enabled;
uint16_t rv;
bool expect_ack;
uint32_t rv;
uint16_t rnti;
uint32_t current_tx_nb;
srslte_softbuffer_tx_t *softbuffer;
srslte_phy_grant_t phy_grant;
@ -95,6 +99,11 @@ public:
/* Indicate successfull decoding of BCH TB through PBCH */
virtual void bch_decoded_ok(uint8_t *payload) = 0;
/* Function called every start of a subframe (TTI). Warning, this function is called
* from a high priority thread and should terminate asap
*/
virtual void tti_clock(uint32_t tti) = 0;
};
/* Interface RLC -> MAC */

@ -40,13 +40,13 @@ namespace ue {
public:
params_db(uint32_t nof_params_) {
nof_params = nof_params_;
db = new int64_t[nof_params];
db = (int64_t*) calloc(sizeof(int64_t), nof_params);
for (int i=0;i<nof_params;i++) {
db[i] = 0;
}
}
~params_db() {
delete db;
free(db);
}
void set_param(uint32_t param_idx, int64_t value) {
if (param_idx < nof_params) {

@ -161,6 +161,8 @@ public:
/* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */
virtual void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
virtual void pdcch_ul_search_reset() = 0;
virtual void pdcch_dl_search_reset() = 0;
virtual uint32_t get_current_tti() = 0;

@ -54,8 +54,9 @@ public:
class worker : public thread
{
public:
void setup(uint32_t id, thread_pool *parent);
void setup(uint32_t id, thread_pool *parent, uint32_t prio=0);
void stop();
uint32_t get_id();
protected:
virtual void work_imp() = 0;
private:
@ -69,7 +70,7 @@ public:
thread_pool(uint32_t nof_workers);
void init_worker(uint32_t id, worker*);
void init_worker(uint32_t id, worker*, uint32_t prio = 0);
void stop();
worker* wait_worker();
void start_worker(worker*);
@ -85,6 +86,7 @@ private:
pthread_cond_t cvar_start, cvar_stop;
pthread_mutex_t mutex_start, mutex_stop;
uint32_t nof_workers;
bool running;
};
}

@ -25,16 +25,17 @@
*
*/
#include <stdio.h>
#include "srsapps/common/thread_pool.h"
namespace srslte {
void thread_pool::worker::setup(uint32_t id, thread_pool *parent)
void thread_pool::worker::setup(uint32_t id, thread_pool *parent, uint32_t prio)
{
my_id = id;
my_parent = parent;
start();
start(prio);
}
void thread_pool::worker::run_thread()
@ -44,14 +45,20 @@ void thread_pool::worker::run_thread()
wait_to_start();
if (running) {
work_imp();
finished();
}
finished();
}
}
uint32_t thread_pool::worker::get_id()
{
return my_id;
}
void thread_pool::worker::stop()
{
running = false;
wait_thread_finish();
}
void thread_pool::worker::wait_to_start()
@ -77,31 +84,46 @@ thread_pool::thread_pool(uint32_t nof_workers_) : workers(nof_workers_), begin(
for (int i=0;i<nof_workers;i++) {
workers[i] = NULL;
}
running = true;
pthread_mutex_init(&mutex_start, NULL);
pthread_mutex_init(&mutex_stop, NULL);
pthread_cond_init(&cvar_start, NULL);
pthread_cond_init(&cvar_stop, NULL);
}
void thread_pool::init_worker(uint32_t id, worker *obj)
void thread_pool::init_worker(uint32_t id, worker *obj, uint32_t prio)
{
if (id < nof_workers) {
pthread_mutex_lock(&mutex_stop);
begin[id] = false;
workers[id] = obj;
available_workers.push(obj);
obj->setup(id, this);
printf("Added worker to available_workers, len=%lu\n", available_workers.size());
obj->setup(id, this, prio);
pthread_cond_signal(&cvar_stop);
pthread_mutex_unlock(&mutex_stop);
}
}
void thread_pool::stop()
{
/* Stop any thread waiting for available worker */
running = false;
pthread_mutex_lock(&mutex_stop);
pthread_cond_signal(&cvar_start);
pthread_mutex_unlock(&mutex_stop);
/* Now stop all workers */
for (uint32_t i=0;i<nof_workers;i++) {
if (workers[i]) {
workers[i]->stop();
// Need to call start to wake it up
start_worker(i);
workers[i]->wait_thread_finish();
}
}
/* And destroy mutexes */
pthread_mutex_destroy(&mutex_start);
pthread_mutex_destroy(&mutex_stop);
pthread_cond_destroy(&cvar_start);
@ -143,11 +165,15 @@ thread_pool::worker* thread_pool::wait_worker()
{
thread_pool::worker *x;
pthread_mutex_lock(&mutex_stop);
while(!available_workers.empty()) {
while(available_workers.empty() && running) {
pthread_cond_wait(&cvar_stop, &mutex_stop);
}
x = (worker*) available_workers.top();
available_workers.pop();
if (running) {
x = (worker*) available_workers.top();
available_workers.pop();
} else {
x = NULL;
}
pthread_mutex_unlock(&mutex_stop);
return x;
}

@ -23,5 +23,5 @@ INCLUDE_DIRECTORIES(phy/include/)
INCLUDE_DIRECTORIES(mac/include/)
add_subdirectory(phy)
#add_subdirectory(mac)
add_subdirectory(mac)

@ -33,4 +33,4 @@ SRSLTE_SET_PIC(srsapps_ue_mac)
FILE(GLOB HEADERS_ALL "include/srsapps/ue/mac/*.h")
ADD_CUSTOM_TARGET (add_ue_mac_headers SOURCES ${HEADERS_ALL})
ADD_SUBDIRECTORY(test)
#ADD_SUBDIRECTORY(test)

@ -30,8 +30,6 @@
#include <pthread.h>
#include "srsapps/common/log.h"
#include "srsapps/common/tti_sync.h"
#include "srsapps/common/tti_sync_cv.h"
#include "srsapps/ue/phy/phy.h"
#include "srsapps/ue/mac/mac_params.h"
#include "srsapps/ue/mac/dl_harq.h"
@ -49,6 +47,7 @@
#include "srsapps/ue/mac/sdu_handler.h"
#include "srsapps/ue/mac/mac_pcap.h"
#include "srsapps/common/trace.h"
#include "srsapps/common/mac_interface.h"
#ifndef UEMAC_H
@ -59,7 +58,7 @@ namespace ue {
typedef _Complex float cf_t;
class mac : public timer_callback
class mac : public timer_callback, mac_interface_phy, mac_interface_rlc
{
public:
mac() : timers_db((uint32_t) NOF_MAC_TIMERS), tr_exec_total(1024*10), tr_exec_dl(1024*10), tr_exec_ul(1024*10) {started=false; pcap = NULL; }

@ -63,7 +63,7 @@ namespace ue {
srslte_rnti_type_t get_dl_rnti_type();
void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]);
bool get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_grant);
bool get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_grant = NULL);
void reset_pending_ack(uint32_t tti);
void set_pending_ack(uint32_t tti, uint32_t I_lowest, uint32_t n_dmrs);

@ -50,7 +50,7 @@ class phch_recv : public thread
public:
phch_recv();
bool init(radio* radio_handler, mac_interface_phy *mac, prach *prach_buffer, thread_pool *_workers_pool,
phch_common *_worker_com, log* _log_h, bool do_agc);
phch_common *_worker_com, log* _log_h, bool do_agc = false, uint32_t prio = 1);
void stop();
uint32_t get_current_tti();
@ -60,6 +60,7 @@ public:
bool status_is_sync();
void set_time_adv_sec(float time_adv_sec);
void get_current_cell(srslte_cell_t *cell);
private:
void run_thread();
@ -75,7 +76,7 @@ private:
prach *prach_buffer;
srslte_ue_sync_t ue_sync;
srslte_ue_mib_t ue_mib;
srslte_ue_mib_t ue_mib;
enum {
IDLE, CELL_SEARCH, SYNCING, SYNC_DONE

@ -56,6 +56,7 @@ public:
void set_cfo(float cfo);
void set_ul_params();
void reset_ul_params();
void set_crnti(uint16_t rnti);
void enable_pregen_signals(bool enabled);
@ -71,10 +72,10 @@ private:
bool decode_pdcch_ul(mac_interface_phy::mac_grant_t *grant);
bool decode_pdcch_dl(mac_interface_phy::mac_grant_t *grant);
bool decode_phich(bool *ack);
bool decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv);
bool decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv, uint16_t rnti);
/* ... for UL */
void encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t rv_idx, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer);
void encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer, uint32_t rv, uint16_t rnti);
void encode_pucch();
void encode_srs();
void reset_uci();
@ -116,6 +117,7 @@ private:
uint32_t I_sr;
float cfo;
bool rar_cqi_request;
uint32_t ul_payload_max_len;
};

@ -95,7 +95,9 @@ public:
/* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */
void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1);
void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1);
void pdcch_ul_search_reset();
void pdcch_dl_search_reset();
/* Get/Set PHY parameters */
void set_param(phy_param_t param, int64_t value);
int64_t get_param(phy_param_t param);
@ -103,10 +105,11 @@ public:
void reset();
uint32_t get_current_tti();
void get_current_cell(srslte_cell_t *cell);
private:
const static int NOF_WORKERS = 1;
const static int NOF_WORKERS = 1;
const static int SF_RECV_THREAD_PRIO = 1;
const static int WORKERS_THREAD_PRIO = 0;
@ -124,8 +127,6 @@ private:
/* Current time advance */
uint32_t n_ta;
srslte_cell_t cell;
bool init_(radio *radio_handler, mac_interface_phy *mac, log *log_h, bool do_agc);
trace<uint32_t> tr_start_time;

@ -57,7 +57,7 @@ namespace ue {
bool send(radio* radio_handler, float cfo, srslte_timestamp_t rx_time);
private:
static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission
static const uint32_t tx_advance_sf = 4; // Number of subframes to advance transmission
phy_params *params_db;
log *log_h;
int preamble_idx;

@ -60,14 +60,18 @@ bool phch_common::ul_rnti_active(uint32_t tti) {
(tti < ul_rnti_end && ul_rnti_end >= 0 || ul_rnti_end < 0))
{
return true;
} else {
return false;
}
}
bool phch_common::dl_rnti_active(uint32_t tti) {
if ((tti >= dl_rnti_start && dl_rnti_start >= 0 || dl_rnti_start < 0) &&
(tti < dl_rnti_end && dl_rnti_end >= 0 || dl_rnti_end < 0))
if (((tti >= dl_rnti_start && dl_rnti_start >= 0) || dl_rnti_start < 0) &&
((tti < dl_rnti_end && dl_rnti_end >= 0) || dl_rnti_end < 0))
{
return true;
} else {
return false;
}
}
@ -76,6 +80,8 @@ void phch_common::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_G
{
srslte_dci_rar_grant_unpack(&rar_grant, grant_payload);
rar_grant_pending = true;
Info("Setting RAR grant: \n");
srslte_dci_rar_grant_fprint(stdout, &rar_grant);
// PUSCH is at n+6 or n+7 and phch_worker assumes default delay of 4 ttis
if (rar_grant.ul_delay) {
rar_grant_tti = (tti + 3) % 10240;
@ -86,8 +92,11 @@ void phch_common::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_G
bool phch_common::get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_grant_)
{
if (rar_grant_pending && tti >= rar_grant_tti) {
memcpy(rar_grant_, &rar_grant, sizeof(srslte_dci_rar_grant_t));
if (rar_grant_pending && (tti >= rar_grant_tti || (tti < 10 && rar_grant_pending > 10235))) {
if (rar_grant_) {
rar_grant_pending = false;
memcpy(rar_grant_, &rar_grant, sizeof(srslte_dci_rar_grant_t));
}
return true;
}
return false;
@ -97,6 +106,8 @@ bool phch_common::get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_gran
uint16_t phch_common::get_ul_rnti(uint32_t tti) {
if (ul_rnti_active(tti)) {
return ul_rnti;
} else {
return 0;
}
}
srslte_rnti_type_t phch_common::get_ul_rnti_type() {
@ -111,6 +122,8 @@ void phch_common::set_ul_rnti(srslte_rnti_type_t type, uint16_t rnti_value, int
uint16_t phch_common::get_dl_rnti(uint32_t tti) {
if (dl_rnti_active(tti)) {
return dl_rnti;
} else {
return 0;
}
}
srslte_rnti_type_t phch_common::get_dl_rnti_type() {
@ -121,6 +134,7 @@ void phch_common::set_dl_rnti(srslte_rnti_type_t type, uint16_t rnti_value, int
dl_rnti_type = type;
dl_rnti_start = tti_start;
dl_rnti_end = tti_end;
Debug("Set DL rnti: start=%d, end=%d, value=0x%x\n", tti_start, tti_end, rnti_value);
}
void phch_common::reset_pending_ack(uint32_t tti) {
@ -131,6 +145,7 @@ void phch_common::set_pending_ack(uint32_t tti, uint32_t I_lowest, uint32_t n_dm
pending_ack[tti%10].enabled = true;
pending_ack[tti%10].I_lowest = I_lowest;
pending_ack[tti%10].n_dmrs = n_dmrs;
Debug("Set pending ACK for tti=%d I_lowest=%d, n_dmrs=%d\n", tti, I_lowest, n_dmrs);
}
bool phch_common::get_pending_ack(uint32_t tti) {

@ -42,7 +42,7 @@ phch_recv::phch_recv() {
}
bool phch_recv::init(radio* _radio_handler, mac_interface_phy *_mac, prach* _prach_buffer, thread_pool* _workers_pool,
phch_common* _worker_com, log* _log_h, bool do_agc_)
phch_common* _worker_com, log* _log_h, bool do_agc_, uint32_t prio)
{
radio_h = _radio_handler;
log_h = _log_h;
@ -55,18 +55,22 @@ bool phch_recv::init(radio* _radio_handler, mac_interface_phy *_mac, prach* _pra
time_adv_sec = 0;
cell_is_set = false;
do_agc = do_agc_;
start();
start(prio);
}
void phch_recv::stop() {
running = false;
wait_thread_finish();
}
int radio_recv_wrapper_cs(void *h,void *data, uint32_t nsamples, srslte_timestamp_t *rx_time)
int radio_recv_wrapper_cs(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *rx_time)
{
radio *radio_h = (radio*) h;
int n = radio_h->rx_now(data, nsamples, rx_time);
return n;
if (radio_h->rx_now(data, nsamples, rx_time)) {
return nsamples;
} else {
return -1;
}
}
double callback_set_rx_gain(void *h, double gain) {
@ -79,33 +83,29 @@ void phch_recv::set_time_adv_sec(float _time_adv_sec) {
}
bool phch_recv::init_cell() {
if (phy_state == IDLE) {
cell_is_set = false;
if (!srslte_ue_mib_init(&ue_mib, cell))
cell_is_set = false;
if (!srslte_ue_mib_init(&ue_mib, cell))
{
if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_h))
{
if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_h))
{
for (int i=0;i<workers_pool->get_nof_workers();i++) {
if (((phch_worker*) workers_pool->get_worker(i))->init_cell(cell)) {
Error("Error setting cell: initiating PHCH worker\n");
return false;
}
}
if (do_agc) {
srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain);
for (int i=0;i<workers_pool->get_nof_workers();i++) {
if (!((phch_worker*) workers_pool->get_worker(i))->init_cell(cell)) {
Error("Error setting cell: initiating PHCH worker\n");
return false;
}
srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo);
cell_is_set = true;
} else {
Error("Error setting cell: initiating ue_sync");
}
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);
cell_is_set = true;
} else {
Error("Error setting cell: initiating ue_mib\n");
}
Error("Error setting cell: initiating ue_sync");
}
} else {
Error("Error setting cell: Invalid state %d\n", phy_state);
}
Error("Error setting cell: initiating ue_mib\n");
}
return cell_is_set;
}
@ -130,6 +130,7 @@ bool phch_recv::cell_search(int force_N_id_2)
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
if (srslte_ue_cellsearch_init(&cs, radio_recv_wrapper_cs, radio_h)) {
Error("Initiating UE cell search\n");
return false;
}
@ -148,6 +149,7 @@ bool phch_recv::cell_search(int force_N_id_2)
/* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */
uint32_t max_peak_cell = 0;
int ret = SRSLTE_ERROR;
if (force_N_id_2 >= 0 && force_N_id_2 < 3) {
ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]);
max_peak_cell = force_N_id_2;
@ -178,6 +180,7 @@ bool phch_recv::cell_search(int force_N_id_2)
srslte_ue_mib_sync_t ue_mib_sync;
if (srslte_ue_mib_sync_init(&ue_mib_sync, cell.id, cell.cp, radio_recv_wrapper_cs, radio_h)) {
Error("Initiating UE MIB synchronization\n");
return false;
}
@ -187,7 +190,6 @@ bool phch_recv::cell_search(int force_N_id_2)
/* Find and decode MIB */
uint32_t sfn, sfn_offset;
radio_h->start_rx();
ret = srslte_ue_mib_sync_decode(&ue_mib_sync,
worker_com->params_db->get_param(phy_interface_params::CELLSEARCH_TIMEOUT_MIB_NFRAMES),
@ -198,6 +200,7 @@ bool phch_recv::cell_search(int force_N_id_2)
if (ret == 1) {
srslte_pbch_mib_unpack(bch_payload, &cell, NULL);
srslte_cell_fprint(stdout, &cell, 0);
mac->bch_decoded_ok(bch_payload);
return true;
} else {
@ -254,7 +257,10 @@ void phch_recv::run_thread()
init_cell();
radio_h->set_rx_srate((float) srslte_sampling_freq_hz(cell.nof_prb));
radio_h->set_tx_srate((float) srslte_sampling_freq_hz(cell.nof_prb));
Info("Cell found. Synchronizing...\n");
phy_state = SYNCING;
} else {
phy_state = IDLE;
}
break;
case SYNCING:
@ -269,6 +275,7 @@ void phch_recv::run_thread()
phy_state = IDLE;
break;
case 1:
Info("Synchronized.\n");
phy_state = SYNC_DONE;
break;
case 0:
@ -277,34 +284,44 @@ void phch_recv::run_thread()
break;
case SYNC_DONE:
worker = (phch_worker*) workers_pool->wait_worker();
buffer = worker->get_buffer();
if (srslte_ue_sync_zerocopy(&ue_sync, buffer) == 1) {
float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000;
worker->set_cfo(cfo);
srslte_timestamp_t rx_time;
srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time);
srslte_timestamp_add(&rx_time, 0, 1e-3 - time_adv_sec);
worker->set_tx_time(rx_time);
worker->set_tti(tti);
// Check if we need to TX a PRACH
if (prach_buffer->is_ready_to_send(tti)) {
// send prach if we have to
prach_buffer->send(radio_h, cfo, rx_time);
radio_h->tx_end();
if (worker) {
buffer = worker->get_buffer();
if (srslte_ue_sync_zerocopy(&ue_sync, buffer) == 1) {
tti = (tti + 1) % 10240;
log_h->step(tti);
/* Setup DL RNTI search to look for RAR as configured by MAC */
uint16_t rar_rnti;
uint32_t rar_start, rar_end;
prach_buffer->get_rar_cfg(&rar_rnti, &rar_start, &rar_end);
worker_com->set_dl_rnti(SRSLTE_RNTI_RAR, rar_rnti, (int) rar_start, (int) rar_end);
} else {
workers_pool->start_worker(worker);
float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000;
worker->set_cfo(cfo);
/* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */
srslte_timestamp_t rx_time, tx_time;
srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time);
srslte_timestamp_copy(&tx_time, &rx_time);
srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec);
worker->set_tx_time(tx_time);
worker->set_tti(tti);
// Check if we need to TX a PRACH
if (prach_buffer->is_ready_to_send(tti)) {
srslte_timestamp_t cur_time;
radio_h->get_time(&cur_time);
Info("TX PRACH now. RX time: %d:%f, Now: %d:%f\n", rx_time.full_secs, rx_time.frac_secs, cur_time.full_secs, cur_time.frac_secs);
// send prach if we have to
prach_buffer->send(radio_h, cfo, tx_time);
radio_h->tx_end();
/* Setup DL RNTI search to look for RAR as configured by MAC */
uint16_t rar_rnti;
uint32_t rar_start, rar_end;
prach_buffer->get_rar_cfg(&rar_rnti, &rar_start, &rar_end);
worker_com->set_dl_rnti(SRSLTE_RNTI_RAR, rar_rnti, (int) rar_start, (int) rar_end);
}
workers_pool->start_worker(worker);
}
} else {
// wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here
running = false;
}
tti = (tti + 1) % 10240;
break;
case IDLE:
usleep(1000);
@ -323,6 +340,13 @@ bool phch_recv::status_is_sync()
return phy_state == SYNC_DONE;
}
void phch_recv::get_current_cell(srslte_cell_t* cell_)
{
if (cell_) {
memcpy(cell_, &cell, sizeof(srslte_cell_t));
}
}
void phch_recv::sync_start()
{
phy_state = CELL_SEARCH;

@ -39,16 +39,14 @@ phch_worker::phch_worker()
{
phy = NULL;
signal_buffer = NULL;
bzero(&cell, sizeof(srslte_cell_t));
bzero(&ue_dl, sizeof(srslte_ue_dl_t));
bzero(&ue_ul, sizeof(srslte_ue_ul_t));
bzero(&uci_data, sizeof(srslte_uci_data_t));
ul_payload = NULL;
cell_initiated = false;
pregen_enabled = false;
rar_cqi_request = false;
cfi = 0;
cfi = 0;
reset_ul_params();
}
@ -67,6 +65,13 @@ bool phch_worker::init_cell(srslte_cell_t cell_)
Error("Allocating memory\n");
return false;
}
ul_payload_max_len = srslte_ra_tbs_from_idx(26, cell.nof_prb);
ul_payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * ul_payload_max_len);
if (!ul_payload) {
Error("Allocating memory\n");
return false;
}
if (srslte_ue_dl_init(&ue_dl, cell)) {
Error("Initiating UE DL\n");
return false;
@ -80,7 +85,7 @@ bool phch_worker::init_cell(srslte_cell_t cell_)
srslte_ue_ul_set_normalization(&ue_ul, false);
srslte_ue_ul_set_cfo_enable(&ue_ul, true);
cell_initiated = false;
cell_initiated = true;
return true;
}
@ -139,6 +144,7 @@ void phch_worker::work_imp()
/* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */
if (extract_fft_and_pdcch_llr()) {
/***** Downlink Processing *******/
/* PDCCH DL + PDSCH */
@ -149,7 +155,7 @@ void phch_worker::work_imp()
/* Decode PDSCH if instructed to do so */
bool dl_ack = dl_action.default_ack;
if (dl_action.decode_enabled) {
dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv);
dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv, dl_action.rnti);
phy->mac->tb_decoded_ok(dl_mac_grant.pid);
}
if (dl_action.generate_ack) {
@ -164,7 +170,7 @@ void phch_worker::work_imp()
/***** Uplink Processing + Transmission *******/
/* Generate UCI */
set_uci_sr();
set_uci_cqi();
@ -188,10 +194,11 @@ void phch_worker::work_imp()
/* Transmit PUSCH, PUCCH or SRS */
bool tx_signal = false;
if (ul_grant_available) {
if (ul_action.tx_enabled) {
encode_pusch(&ul_action.phy_grant.ul, ul_action.rv, ul_action.current_tx_nb, ul_action.softbuffer);
tx_signal = true;
if (ul_action.tx_enabled) {
encode_pusch(&ul_action.phy_grant.ul, ul_action.current_tx_nb, ul_action.softbuffer, ul_action.rv, ul_action.rnti);
tx_signal = true;
if (ul_action.expect_ack) {
phy->set_pending_ack(tti + 8, ue_ul.pusch_cfg.grant.n_prb_tilde[0], ul_action.phy_grant.ul.ncs_dmrs);
}
} else if (dl_action.generate_ack) {
encode_pucch();
@ -208,19 +215,21 @@ void phch_worker::work_imp()
bool phch_worker::extract_fft_and_pdcch_llr() {
bool decode_pdcch = false;
if (phy->get_ul_rnti(tti) || phy->get_dl_rnti(tti)) {
if (phy->get_ul_rnti(tti) || phy->get_dl_rnti(tti) || phy->get_pending_rar(tti)) {
decode_pdcch = true;
}
}
/* Without a grant, we might need to do fft processing if need to decode PHICH */
if (phy->get_pending_ack(tti) || decode_pdcch) {
Debug("Running FFT estimate\n");
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
Error("Getting PDCCH FFT estimate\n");
return false;
}
}
if (decode_pdcch) { /* and not in DRX mode */
Debug("Extracting PDCCH LLR\n");
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) {
Error("Extracting PDCCH LLR\n");
return false;
@ -252,10 +261,12 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr
srslte_ra_dl_dci_t dci_unpacked;
if (srslte_ue_dl_find_dl_dci_type(&ue_dl, &dci_msg, cfi, tti%10, dl_rnti, type) != 1) {
Debug("Can't find DL DCI message\n");
return false;
}
if (srslte_dci_msg_to_dl_grant(&dci_msg, dl_rnti, cell.nof_prb, &dci_unpacked, &grant->phy_grant.dl)) {
Error("Converting DCI message to DL grant\n");
return false;
}
@ -264,7 +275,8 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr
grant->pid = dci_unpacked.harq_process;
grant->tbs = grant->phy_grant.dl.mcs.tbs;
grant->tti = tti;
grant->rnti_type = type;
grant->rv = dci_unpacked.rv_idx;
grant->rnti = dl_rnti;
last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl);
@ -277,16 +289,24 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr
}
}
bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv)
bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload,
srslte_softbuffer_rx_t* softbuffer, uint32_t rv, uint16_t rnti)
{
Debug("DL Buffer TTI %d: Decoding PDSCH\n", tti);
/* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */
if (!srslte_ue_dl_cfg_grant(&ue_dl, grant, cfi, tti%10, dl_rnti, rv)) {
if (!srslte_ue_dl_cfg_grant(&ue_dl, grant, cfi, tti%10, rnti, rv)) {
if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) {
return srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols,
ue_dl.ce, 0, dl_rnti, payload) == 0;
if (srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols,
ue_dl.ce, 0, rnti, payload) == 0)
{
Debug("TB decoded OK\n");
return true;
} else {
Debug("TB decoded KO\n");
return false;
}
} else {
Warning("Received grant for TBS=0\n");
}
@ -301,8 +321,10 @@ bool phch_worker::decode_phich(bool *ack)
uint32_t I_lowest, n_dmrs;
if (phy->get_pending_ack(tti, &I_lowest, &n_dmrs)) {
if (ack) {
Debug("Decoding PHICH I_lowest=%d, n_dmrs=%d\n", I_lowest, n_dmrs);
*ack = srslte_ue_dl_decode_phich(&ue_dl, tti%10, I_lowest, n_dmrs);
}
phy->reset_pending_ack(tti);
return true;
} else {
return false;
@ -317,6 +339,7 @@ bool phch_worker::decode_phich(bool *ack)
bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
{
phy->reset_pending_ack(tti + 4);
srslte_dci_msg_t dci_msg;
srslte_ra_ul_dci_t dci_unpacked;
srslte_dci_rar_grant_t rar_grant;
@ -324,9 +347,14 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
bool ret = false;
if (phy->get_pending_rar(tti, &rar_grant)) {
if (srslte_dci_rar_to_ul_grant(&rar_grant, cell.nof_prb, pusch_hopping.hopping_offset, &dci_unpacked, &grant->phy_grant.ul)) {
Info("Pending RAR UL grant\n");
if (srslte_dci_rar_to_ul_grant(&rar_grant, cell.nof_prb, pusch_hopping.hopping_offset,
&dci_unpacked, &grant->phy_grant.ul))
{
Error("Converting RAR message to UL grant\n");
return false;
}
Info("RAR grant found for TTI=%d\n", tti);
rar_cqi_request = rar_grant.cqi_request;
ret = true;
} else {
@ -338,9 +366,14 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, ul_rnti) != 1) {
return false;
}
if (srslte_dci_msg_to_ul_grant(&dci_msg, cell.nof_prb, pusch_hopping.hopping_offset, &dci_unpacked, &grant->phy_grant.ul)) {
if (srslte_dci_msg_to_ul_grant(&dci_msg, cell.nof_prb, pusch_hopping.hopping_offset,
&dci_unpacked, &grant->phy_grant.ul))
{
Error("Converting DCI message to UL grant\n");
return false;
}
ret = true;
Info("PDCCH: UL DCI Format0 cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits);
}
}
if (ret) {
@ -348,9 +381,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
grant->pid = 0; // This is computed by MAC from TTI
grant->tbs = grant->phy_grant.ul.mcs.tbs;
grant->tti = tti;
grant->rnti_type = type;
Info("PDCCH: UL DCI Format0 cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits);
grant->rnti = ul_rnti;
if (SRSLTE_VERBOSE_ISINFO()) {
srslte_ra_pusch_fprint(stdout, &dci_unpacked, cell.nof_prb);
@ -378,8 +409,8 @@ void phch_worker::set_uci_sr()
uci_data.scheduling_request = false;
if (phy->sr_enabled) {
// Get I_sr parameter
if (srslte_ue_ul_sr_send_tti(I_sr, tti)) {
Info("SR transmission at TTI=%d\n", tti);
if (srslte_ue_ul_sr_send_tti(I_sr, tti+4)) {
Info("SR transmission at TTI=%d\n", tti+4);
uci_data.scheduling_request = true;
phy->sr_enabled = false;
}
@ -389,7 +420,7 @@ void phch_worker::set_uci_sr()
void phch_worker::set_uci_cqi()
{
if (cqi_cfg.configured || rar_cqi_request) {
if (srslte_cqi_send(cqi_cfg.pmi_idx, tti)) {
if (srslte_cqi_send(cqi_cfg.pmi_idx, tti+4)) {
uci_data.uci_cqi_len = 4;
uint8_t cqi[4] = {1, 1, 1, 1};
uci_data.uci_cqi = cqi;
@ -400,8 +431,8 @@ void phch_worker::set_uci_cqi()
bool phch_worker::srs_is_ready_to_send() {
if (srs_cfg.configured) {
if (srslte_refsignal_srs_send_cs(srs_cfg.subframe_config, tti%10) == 1 &&
srslte_refsignal_srs_send_ue(srs_cfg.I_srs, tti) == 1)
if (srslte_refsignal_srs_send_cs(srs_cfg.subframe_config, (tti+4)%10) == 1 &&
srslte_refsignal_srs_send_ue(srs_cfg.I_srs, tti+4) == 1)
{
return true;
}
@ -418,30 +449,28 @@ void phch_worker::normalize() {
srslte_vec_norm_cfc(signal_buffer, 0.9, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t rv_idx, uint32_t current_tx_nb, srslte_softbuffer_tx_t* softbuffer)
void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_nb,
srslte_softbuffer_tx_t* softbuffer, uint32_t rv, uint16_t rnti)
{
if (srslte_ue_ul_cfg_grant(&ue_ul, grant, tti, rv_idx, current_tx_nb)) {
if (srslte_ue_ul_cfg_grant(&ue_ul, grant, tti+4, rv, current_tx_nb)) {
Error("Configuring UL grant\n");
}
phy->set_pending_ack(tti + 4, grant->n_prb_tilde[0], grant->ncs_dmrs);
if (srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul,
ul_payload, uci_data,
softbuffer,
ul_rnti,
rnti,
signal_buffer))
{
Error("Encoding PUSCH\n");
}
Info("PUSCH: TTI=%d, CFO= %.1f KHz TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n",
tti, cfo*15e3, grant->mcs.tbs, srslte_mod_string(grant->mcs.mod),
tti+4, cfo*15e3, grant->mcs.tbs, srslte_mod_string(grant->mcs.mod),
grant->n_prb[0], grant->L_prb,
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
ul_rnti, ue_ul.pusch.shortened?"yes":"no");
rnti, ue_ul.pusch.shortened?"yes":"no");
normalize();
}
@ -449,13 +478,13 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t rv_idx, uin
void phch_worker::encode_pucch()
{
if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len)
if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len > 0)
{
if (srslte_ue_ul_pucch_encode(&ue_ul, uci_data, last_dl_pdcch_ncce, tti, signal_buffer)) {
if (srslte_ue_ul_pucch_encode(&ue_ul, uci_data, last_dl_pdcch_ncce, tti+4, signal_buffer)) {
Error("Encoding PUCCH\n");
}
Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, cfo*15e3, last_dl_pdcch_ncce,
Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti+4, cfo*15e3, last_dl_pdcch_ncce,
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
ue_ul.pucch.shortened?"yes":"no");
}
@ -464,12 +493,12 @@ void phch_worker::encode_pucch()
void phch_worker::encode_srs()
{
if (srslte_ue_ul_srs_encode(&ue_ul, tti, signal_buffer))
if (srslte_ue_ul_srs_encode(&ue_ul, tti+4, signal_buffer))
{
Error("Encoding SRS\n");
}
Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti, cfo*15e3);
Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti+4, cfo*15e3);
normalize();
}
@ -479,6 +508,18 @@ void phch_worker::enable_pregen_signals(bool enabled)
pregen_enabled = enabled;
}
void phch_worker::reset_ul_params()
{
bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t));
bzero(&pusch_hopping, sizeof(srslte_pusch_hopping_cfg_t));
bzero(&uci_cfg, sizeof(srslte_uci_cfg_t));
bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t));
bzero(&pucch_sched, sizeof(srslte_pucch_sched_t));
bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t));
bzero(&cqi_cfg, sizeof(srslte_cqi_cfg_t));
I_sr = 0;
}
void phch_worker::set_ul_params()
{
@ -537,6 +578,7 @@ void phch_worker::set_ul_params()
srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, &srs_cfg, &pucch_cfg, &pucch_sched, &uci_cfg, &pusch_hopping);
/* CQI configuration */
bzero(&cqi_cfg, sizeof(srslte_cqi_cfg_t));
cqi_cfg.configured = (bool) phy->params_db->get_param(phy_interface_params::CQI_PERIODIC_CONFIGURED)?true:false;
cqi_cfg.pmi_idx = (uint32_t) phy->params_db->get_param(phy_interface_params::CQI_PERIODIC_PMI_IDX);

@ -69,17 +69,14 @@ bool phy::init_(radio* radio_handler_, mac_interface_phy *mac, log *log_h_, bool
prach_buffer.init(&params_db, log_h);
workers_common.init(&params_db, log_h, radio_handler, mac);
sf_recv.init(radio_handler, mac, &prach_buffer, &workers_pool, &workers_common, log_h, do_agc);
// Add workers to workers pool and start threads
for (int i=0;i<NOF_WORKERS;i++) {
workers_pool.init_worker(i, &workers[i]);
workers[i].start(WORKERS_THREAD_PRIO);
workers[i].set_common(&workers_common);
workers_pool.init_worker(i, &workers[i], WORKERS_THREAD_PRIO);
}
// Start the Radio receiver thread
sf_recv.start(SF_RECV_THREAD_PRIO);
sf_recv.init(radio_handler, mac, &prach_buffer, &workers_pool, &workers_common, log_h, do_agc, SF_RECV_THREAD_PRIO);
return true;
}
@ -110,13 +107,12 @@ void phy::tr_log_end()
void phy::stop()
{
workers_pool.stop();
sf_recv.stop();
sf_recv.wait_thread_finish();
for (int i=0;i<NOF_WORKERS;i++) {
((phch_worker) workers[i]).free_cell();
workers[i].stop();
workers[i].wait_thread_finish();
}
prach_buffer.free_cell();
@ -144,9 +140,17 @@ int64_t phy::get_param(phy_interface_params::phy_param_t param) {
void phy::configure_prach_params()
{
Info("Configuring PRACH parameters\n");
if (prach_buffer.init_cell(cell)) {
Error("Configuring PRACH parameters\n");
if (sf_recv.status_is_sync()) {
Info("Configuring PRACH parameters\n");
srslte_cell_t cell;
sf_recv.get_current_cell(&cell);
if (!prach_buffer.init_cell(cell)) {
Error("Configuring PRACH parameters\n");
} else {
Info("Done\n");
}
} else {
Error("Cell is not synchronized\n");
}
}
@ -165,13 +169,28 @@ void phy::pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_s
void phy::pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start, int tti_end)
{
workers_common.set_dl_rnti(rnti_type, rnti);
workers_common.set_dl_rnti(rnti_type, rnti, tti_start, tti_end);
}
void phy::pdcch_dl_search_reset()
{
workers_common.set_dl_rnti(SRSLTE_RNTI_USER, 0);
}
void phy::pdcch_ul_search_reset()
{
workers_common.set_ul_rnti(SRSLTE_RNTI_USER, 0);
}
void phy::get_current_cell(srslte_cell_t *cell)
{
sf_recv.get_current_cell(cell);
}
void phy::prach_send(phy_interface::prach_cfg_t* cfg)
{
if (prach_buffer.prepare_to_send(cfg)) {
if (!prach_buffer.prepare_to_send(cfg)) {
Error("Preparing PRACH to send\n");
}
}

@ -65,11 +65,14 @@ bool prach::init_cell(srslte_cell_t cell_)
{
cell = cell_;
preamble_idx = -1;
if (srslte_prach_init(&prach_obj, srslte_symbol_sz(cell.nof_prb),
srslte_prach_get_preamble_format(params_db->get_param(phy_interface_params::PRACH_CONFIG_INDEX)),
params_db->get_param(phy_interface_params::PRACH_ROOT_SEQ_IDX),
params_db->get_param(phy_interface_params::PRACH_HIGH_SPEED_FLAG)?true:false,
params_db->get_param(phy_interface_params::PRACH_ZC_CONFIG))) {
params_db->get_param(phy_interface_params::PRACH_ZC_CONFIG)))
{
Error("Initiating PRACH library\n");
return false;
}
@ -80,6 +83,7 @@ bool prach::init_cell(srslte_cell_t cell_)
return false;
}
if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_interface_params::PRACH_FREQ_OFFSET), buffer[i])) {
Error("Generating PRACH preamble %d\n", i);
return false;
}
}
@ -87,6 +91,7 @@ bool prach::init_cell(srslte_cell_t cell_)
signal_buffer = (cf_t*) srslte_vec_malloc(len*sizeof(cf_t));
initiated = signal_buffer?true:false;
transmitted_tti = -1;
Info("PRACH Initiated %s\n", initiated?"OK":"KO");
return initiated;
}
@ -97,6 +102,7 @@ bool prach::prepare_to_send(phy_interface::prach_cfg_t* cfg)
if (ret) {
memcpy(&prach_cfg, cfg, sizeof(phy_interface::prach_cfg_t));
}
return ret;
}
bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm)
@ -105,9 +111,14 @@ bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float
preamble_idx = preamble_idx_;
allowed_subframe = allowed_subframe_;
transmitted_tti = -1;
Info("PRACH Buffer: Prepare to send preamble %d\n", preamble_idx);
Info("PRACH prepare to send preamble %d\n", preamble_idx);
return true;
} else {
if (!initiated) {
Error("PRACH not initiated\n");
} else if (preamble_idx_ >= 64) {
Error("Invalid preamble %d\n", preamble_idx_);
}
return false;
}
}
@ -139,23 +150,18 @@ void prach::get_rar_cfg(uint16_t *rar_rnti, uint32_t *tti_start, uint32_t *tti_e
}
}
bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t rx_time)
bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t tx_time)
{
// advance transmission time
srslte_timestamp_t tx_time;
srslte_timestamp_copy(&tx_time, &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, cfo /srslte_symbol_sz(cell.nof_prb));
// Normalize signal amplitude
srslte_vec_norm_cfc(signal_buffer, 0.9, signal_buffer, len);
radio_handler->tx(signal_buffer, len, tx_time);
radio_handler->tx(signal_buffer, len, tx_time);
Debug("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);
Debug("PRACH transmitted CFO: %f, preamble=%d, len=%d tx_time=%f\n",
cfo*15000, preamble_idx, len, tx_time.frac_secs);
preamble_idx = -1;
}

@ -24,6 +24,6 @@ IF(UHD_FOUND)
ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc)
TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd)
# ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc)
# TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd)
ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc)
TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd)
ENDIF(UHD_FOUND)

@ -30,7 +30,6 @@
#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"
/**********************************************************************
@ -45,6 +44,7 @@ typedef struct {
}prog_args_t;
prog_args_t prog_args;
uint32_t srsapps_verbose = 0;
void args_default(prog_args_t *args) {
args->uhd_rx_freq = -1.0;
@ -83,7 +83,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
args->continous = true;
break;
case 'v':
srslte_verbose++;
srsapps_verbose++;
break;
default:
usage(args, argv[0]);
@ -98,18 +98,6 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
typedef enum{
rar_tpc_n6dB = 0,
rar_tpc_n4dB,
rar_tpc_n2dB,
rar_tpc_0dB,
rar_tpc_2dB,
rar_tpc_4dB,
rar_tpc_6dB,
rar_tpc_8dB,
rar_tpc_n_items,
}rar_tpc_command_t;
static const char tpc_command_text[rar_tpc_n_items][8] = {"-6dB", "-4dB", "-2dB", "0dB", "2dB", "4dB", "6dB", "8dB"};
typedef enum{
rar_header_type_bi = 0,
rar_header_type_rapid,
@ -120,7 +108,7 @@ static const char rar_header_text[rar_header_type_n_items][8] = {"BI", "RAPID"};
typedef struct {
rar_header_t hdr_type;
bool hopping_flag;
rar_tpc_command_t tpc_command;
uint32_t tpc_command;
bool ul_delay;
bool csi_req;
uint16_t rba;
@ -131,28 +119,6 @@ typedef struct {
uint8_t BI;
}rar_msg_t;
char *bool_to_string(bool x) {
if (x) {
return (char*) "Enabled";
} else {
return (char*) "Disabled";
}
}
void rar_msg_fprint(FILE *stream, rar_msg_t *msg)
{
fprintf(stream, "Header type: %s\n", rar_header_text[msg->hdr_type]);
fprintf(stream, "Hopping flag: %s\n", bool_to_string(msg->hopping_flag));
fprintf(stream, "TPC command: %s\n", tpc_command_text[msg->tpc_command]);
fprintf(stream, "UL delay: %s\n", bool_to_string(msg->ul_delay));
fprintf(stream, "CSI required: %s\n", bool_to_string(msg->csi_req));
fprintf(stream, "RBA: %d\n", msg->rba);
fprintf(stream, "TA: %d\n", msg->timing_adv_cmd);
fprintf(stream, "T-CRNTI: %d\n", msg->temp_c_rnti);
fprintf(stream, "MCS: %d\n", msg->mcs);
fprintf(stream, "RAPID: %d\n", msg->RAPID);
fprintf(stream, "BI: %d\n", msg->BI);
}
int rar_unpack(uint8_t *buffer, rar_msg_t *msg)
{
@ -176,7 +142,7 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg)
msg->hopping_flag = *ptr++;
msg->rba = srslte_bit_unpack(&ptr, 10);
msg->mcs = srslte_bit_unpack(&ptr, 4);
msg->tpc_command = (rar_tpc_command_t) srslte_bit_unpack(&ptr, 3);
msg->tpc_command = srslte_bit_unpack(&ptr, 3);
msg->ul_delay = *ptr++;
msg->csi_req = *ptr++;
msg->temp_c_rnti = srslte_bit_unpack(&ptr, 16);
@ -189,236 +155,155 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg)
srslte::ue::phy phy;
srslte::ue::phy my_phy;
bool bch_decoded = false;
uint8_t payload[102400];
uint8_t payload[10240];
const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6, 0x00, 0x00, 0x00};
enum mac_state {RA, RAR, CONNREQUEST, CONNSETUP} state = RA;
uint32_t conreq_tti = 0;
uint32_t preamble_idx = 7;
uint32_t preamble_idx = 0;
rar_msg_t rar_msg;
uint32_t nof_rx_connsetup = 0, nof_rx_rar = 0, nof_tx_ra = 0;
uint32_t nof_rtx_connsetup = 0;
uint32_t rv_value[4] = {0, 2, 3, 1};
void config_phy() {
phy.set_param(srslte::ue::phy_params::PRACH_CONFIG_INDEX, 0);
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, 1);
phy.set_param(srslte::ue::phy_params::PUSCH_BETA, 10);
phy.set_param(srslte::ue::phy_params::DMRS_GROUP_HOPPING_EN, 0);
phy.set_param(srslte::ue::phy_params::DMRS_SEQUENCE_HOPPING_EN, 0);
phy.set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT, 0);
phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT, 0);
phy.set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET, 0);
phy.set_param(srslte::ue::phy_params::PUCCH_BETA, 10);
phy.set_param(srslte::ue::phy_params::PUCCH_DELTA_SHIFT, 1);
phy.set_param(srslte::ue::phy_params::PUCCH_CYCLIC_SHIFT, 0);
phy.set_param(srslte::ue::phy_params::PUCCH_N_PUCCH_1, 0);
phy.set_param(srslte::ue::phy_params::PUCCH_N_RB_2, 2);
my_phy.set_param(srslte::ue::phy_interface_params::PRACH_CONFIG_INDEX, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PRACH_FREQ_OFFSET, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PRACH_HIGH_SPEED_FLAG, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PRACH_ROOT_SEQ_IDX, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PRACH_ZC_CONFIG, 11);
my_phy.set_param(srslte::ue::phy_interface_params::DMRS_GROUP_HOPPING_EN, 0);
my_phy.set_param(srslte::ue::phy_interface_params::DMRS_SEQUENCE_HOPPING_EN, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_N_SB, 2);
my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_RS_CYCLIC_SHIFT, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_RS_GROUP_ASSIGNMENT, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_OFFSET, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_DELTA_SHIFT, 2);
my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_CYCLIC_SHIFT, 0);
my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_N_PUCCH_1, 1);
my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_N_RB_2, 2);
my_phy.configure_prach_params();
my_phy.configure_ul_params();
}
uint32_t interval(uint32_t x1, uint32_t x2) {
if (x1 > x2) {
return x1-x2;
} else {
return 10240-x2+x1;
}
}
srslte_softbuffer_rx_t softbuffer_rx;
srslte_softbuffer_tx_t softbuffer_tx;
srslte_softbuffer_rx_t softbuffer;
uint16_t temp_c_rnti;
// This is the MAC implementation
void run_tti(uint32_t tti) {
INFO("MAC running tti: %d\n", tti);
/******** MAC Interface implementation */
class testmac : public srslte::ue::mac_interface_phy
{
public:
void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) {
printf("New grant UL\n");
srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload_ptr, grant.tbs);
action->current_tx_nb = nof_rtx_connsetup;
action->rv = rv_value[nof_rtx_connsetup%4];
action->softbuffer = &softbuffer_tx;
action->rnti = temp_c_rnti;
action->expect_ack = (nof_rtx_connsetup < 5)?true:false;
memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t));
memcpy(&last_grant, &grant, sizeof(mac_grant_t));
action->tx_enabled = true;
if (action->rv == 0) {
srslte_softbuffer_tx_reset(&softbuffer_tx);
}
my_phy.pdcch_dl_search(SRSLTE_RNTI_USER, temp_c_rnti);
}
void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action) {
printf("New grant UL ACK\n");
}
// Get buffer
srslte::ue::dl_buffer *dl_buffer = phy.get_dl_buffer(tti);
void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) {
printf("harq recv hi=%d\n", ack?1:0);
if (!ack) {
nof_rtx_connsetup++;
action->current_tx_nb = nof_rtx_connsetup;
action->rv = rv_value[nof_rtx_connsetup%4];
action->softbuffer = &softbuffer_tx;
action->rnti = temp_c_rnti;
action->expect_ack = true;
memcpy(&action->phy_grant, &last_grant.phy_grant, sizeof(srslte_phy_grant_t));
action->tx_enabled = true;
if (action->rv == 0) {
srslte_softbuffer_tx_reset(&softbuffer_tx);
}
printf("Retransmission %d, rv=%d\n", nof_rtx_connsetup, action->rv);
}
}
if (state == RA) {
if (nof_tx_ra > 0 && !prog_args.continous) {
exit(0);
}
// Indicate PHY to transmit the PRACH when possible
if (phy.send_prach(preamble_idx)) {
nof_tx_ra++;
state = RAR;
void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) {
action->decode_enabled = true;
action->default_ack = false;
if (grant.rnti == 2) {
action->generate_ack = false;
} else {
fprintf(stderr, "Error sending PRACH\n");
exit(-1);
action->generate_ack = true;
}
}
if (state == RAR) {
srslte::ue::dl_sched_grant rar_grant(2);
int ra_tti = phy.get_prach_transmitted_tti();
if (ra_tti > 0) {
INFO("PRACH was transmitted at %d\n", ra_tti);
// Assume the maximum RA-window
uint32_t interval_ra = interval(tti, ra_tti);
INFO("Interval=%u\n", interval_ra);
if (interval_ra >= 3 && interval_ra <= 13) {
// Get DL grant for RA-RNTI=2
if (dl_buffer->get_dl_grant(&rar_grant))
{
srslte_softbuffer_rx_reset(&softbuffer);
// Decode packet
if (dl_buffer->decode_data(&rar_grant, &softbuffer, payload)) {
rar_unpack(payload, &rar_msg);
if (rar_msg.RAPID == preamble_idx) {
INFO("Received RAR at TTI: %d\n", tti);
nof_rx_rar++;
if (SRSLTE_VERBOSE_ISINFO()) {
rar_msg_fprint(stdout, &rar_msg);
}
// Set time advance
phy.set_timeadv_rar(rar_msg.timing_adv_cmd);
// Generate Msg3 grant
srslte::ue::ul_sched_grant connreq_grant(rar_msg.temp_c_rnti);
srslte_dci_rar_grant_t rar_grant;
rar_grant.rba = rar_msg.rba;
rar_grant.trunc_mcs = rar_msg.mcs;
rar_grant.hopping_flag = rar_msg.hopping_flag;
phy.rar_ul_grant(&rar_grant, &connreq_grant);
// Pack Msg3 bits
srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload, connreq_grant.get_tbs());
// Get UL buffer
srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+6);
// Generate PUSCH
if (ul_buffer) {
connreq_grant.set_rv(0);
INFO("Generating PUSCH for TTI: %d\n", ul_buffer->tti);
ul_buffer->generate_data(&connreq_grant, payload);
// Save transmission time
conreq_tti = ul_buffer->tti;
state = CONNREQUEST;
} else {
fprintf(stderr, "Error getting UL buffer for TTI %d\n", tti);
state = RA;
}
}
}
}
} else if (interval_ra > 13 && interval_ra < 100) { // avoid wrapping
INFO("RAR not received at TTI=%d (interval_ra=%d)\n", tti, interval_ra);
state = RA;
}
action->payload_ptr = payload;
action->rnti = grant.rnti;
memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t));
memcpy(&last_grant, &grant, sizeof(mac_grant_t));
action->rv = grant.rv;
action->softbuffer = &softbuffer_rx;
if (action->rv == 0) {
srslte_softbuffer_rx_reset(&softbuffer_rx);
}
}
if (state == CONNREQUEST) {
uint32_t interval_conreq = interval(tti, conreq_tti);
if (interval_conreq == 4) {
srslte::ue::ul_sched_grant connreq_grant(rar_msg.temp_c_rnti);
srslte_dci_rar_grant_t rar_grant;
rar_grant.rba = rar_msg.rba;
rar_grant.trunc_mcs = rar_msg.mcs;
rar_grant.hopping_flag = rar_msg.hopping_flag;
phy.rar_ul_grant(&rar_grant, &connreq_grant);
// Decode PHICH from Connection Request
if (!dl_buffer->decode_ack(&connreq_grant)) {
void tb_decoded_ok(uint32_t harq_pid) {
if (last_grant.rnti == 2) {
my_phy.pdcch_dl_search_reset();
rar_unpack(payload, &rar_msg);
if (rar_msg.RAPID == preamble_idx) {
printf("Received RAR at TTI: %d\n", last_grant.tti);
my_phy.set_timeadv_rar(rar_msg.timing_adv_cmd);
// Pack Msg3 bits
srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload, connreq_grant.get_tbs());
// Get UL buffer
srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+4);
temp_c_rnti = rar_msg.temp_c_rnti;
// Generate PUSCH
if (ul_buffer) {
nof_rtx_connsetup++;
if (nof_rtx_connsetup >= 5) {
state = RA;
} else {
connreq_grant.set_current_tx_nb(nof_rtx_connsetup);
connreq_grant.set_rv(rv_value[nof_rtx_connsetup%4]);
INFO("Generating PUSCH for TTI: %d\n", ul_buffer->tti);
ul_buffer->generate_data(&connreq_grant, payload);
// Save transmission time
conreq_tti = ul_buffer->tti;
}
} else {
fprintf(stderr, "Error getting UL buffer for TTI %d\n", tti);
state = RA;
}
} else {
srslte_softbuffer_rx_reset(&softbuffer);
state = CONNSETUP;
}
}
}
if (state == CONNSETUP) {
srslte::ue::dl_sched_grant conn_setup_grant(rar_msg.temp_c_rnti);
bool connsetup_recv = false;
// Get DL grant for tmp_rnti
if (dl_buffer->get_dl_grant(&conn_setup_grant))
{
// Decode packet
if (dl_buffer->decode_data(&conn_setup_grant, &softbuffer, payload)) {
nof_rx_connsetup++;
state = RA;
nof_rtx_connsetup=0;
if (!prog_args.continous) {
printf("Connection Setup received (%d/%d)\n", nof_rx_connsetup, nof_tx_ra);
if (last_grant.tbs > 20 + SRSLTE_RAR_GRANT_LEN) {
uint8_t rar_grant[SRSLTE_RAR_GRANT_LEN];
memcpy(rar_grant, &payload[20], sizeof(uint8_t)*SRSLTE_RAR_GRANT_LEN);
my_phy.set_rar_grant(last_grant.tti, rar_grant);
}
connsetup_recv = true;
} else {
INFO("Error decoding PDSCH for Connection Request at TTI=%d\n", tti);
printf("Received RAR RAPID=%d\n", rar_msg.RAPID);
}
// send ACK
INFO("Sending ack %d on TTI: %d\n", connsetup_recv, tti+4);
srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+4);
ul_buffer->generate_ack(connsetup_recv, &conn_setup_grant);
if (!prog_args.continous) {
while(ul_buffer->uci_ready()) {
sleep(1);
}
}
state = RA;
} else {
INFO("DCI for Connection Request not found on PDCCH at TTI=%d\n", tti);
state = RA;
}
}
float gain = prog_args.uhd_rx_gain;
if (gain < 0) {
gain = phy.get_agc_gain();
printf("Received Connection Setup\n");
my_phy.pdcch_dl_search_reset();
}
}
if (srslte_verbose == SRSLTE_VERBOSE_NONE && prog_args.continous) {
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, gain);
void bch_decoded_ok(uint8_t *payload) {
printf("BCH decoded\n");
bch_decoded = true;
srslte_cell_t cell;
my_phy.get_current_cell(&cell);
srslte_softbuffer_rx_init(&softbuffer_rx, cell);
srslte_softbuffer_tx_init(&softbuffer_tx, cell);
}
}
private:
mac_grant_t last_grant;
};
testmac my_mac;
srslte::radio_uhd radio_uhd;
int main(int argc, char *argv[])
{
srslte_cell_t cell;
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);
@ -428,56 +313,55 @@ int main(int argc, char *argv[])
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);
my_phy.init(&radio_uhd, &my_mac, &log);
} else {
radio_uhd.init_agc();
radio_uhd.set_tx_rx_gain_offset(-10);
phy.init_agc(&radio_uhd, &ttisync, &log);
radio_uhd.set_tx_rx_gain_offset(0);
my_phy.init_agc(&radio_uhd, &my_mac, &log);
}
if (srsapps_verbose == 1) {
log.set_level_info();
printf("Log level info\n");
}
if (srsapps_verbose == 2) {
log.set_level_debug();
printf("Log level debug\n");
}
// Give it time to create thread
sleep(1);
// Setup PHY parameters
config_phy();
// 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)) {
exit(-1);
}
// Print MIB
srslte_cell_fprint(stdout, &cell, phy.get_current_tti()/10);
// Instruct the PHY to configure PRACH parameters and sync to current cell
my_phy.sync_start();
// Set the current PHY cell to the detected cell
if (!phy.set_cell(cell)) {
printf("Error setting cell\n");
exit(-1);
while(!my_phy.status_is_sync()) {
usleep(20000);
}
if (!phy.init_prach()) {
printf("Error initiating PRACH\n");
exit(-1);
}
srslte_softbuffer_rx_init(&softbuffer, cell);
/* Instruct the PHY to start RX streaming and synchronize */
if (!phy.start_rxtx()) {
printf("Could not start RX\n");
exit(-1);
}
for (int i=0;i<100;i++) {
ttisync.wait();
}
// Setup PHY parameters
config_phy();
/* Instruct PHY to send PRACH and prepare it for receiving RAR */
srslte::ue::phy_interface::prach_cfg_t prach_cfg;
prach_cfg.allowed_subframe_enabled = false;
prach_cfg.preamble_idx = preamble_idx;
prach_cfg.rar_rnti = 2;
prach_cfg.rar_start = 3;
prach_cfg.rar_window = 10;
my_phy.prach_send(&prach_cfg);
/* go to idle and process each tti */
while(1) {
uint32_t tti = ttisync.wait();
run_tti(tti);
bool running = true;
while(running) {
sleep(1);
}
my_phy.stop();
radio_uhd.stop_rx();
}

@ -43,6 +43,8 @@ typedef struct {
float uhd_gain;
}prog_args_t;
uint32_t srsapps_verbose = 0;
prog_args_t prog_args;
void args_default(prog_args_t *args) {
@ -68,7 +70,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
args->uhd_freq = atof(argv[optind]);
break;
case 'v':
srslte_verbose++;
srsapps_verbose++;
break;
default:
usage(args, argv[0]);
@ -81,6 +83,13 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
}
}
srslte::ue::phy my_phy;
bool bch_decoded = false;
uint32_t total_pkts=0;
uint32_t total_dci=0;
uint32_t total_oks=0;
uint8_t payload[1024];
srslte_softbuffer_rx_t softbuffer;
/******** MAC Interface implementation */
class testmac : public srslte::ue::mac_interface_phy
@ -98,70 +107,46 @@ public:
}
void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) {
printf("New grant DL\n");
total_dci++;
action->decode_enabled = true;
action->default_ack = false;
action->generate_ack = false;
action->payload_ptr = payload;
memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t));
action->rv = ((uint32_t) ceilf((float)3*((my_phy.tti_to_SFN(grant.tti)/2)%4)/2))%4;
action->softbuffer = &softbuffer;
if (action->rv == 0) {
srslte_softbuffer_rx_reset(&softbuffer);
}
}
void tb_decoded_ok(uint32_t harq_pid) {
printf("TB decoded OK\n");
total_oks++;
}
void bch_decoded_ok(uint8_t *payload) {
printf("BCH decoded\n");
bch_decoded = true;
srslte_cell_t cell;
my_phy.get_current_cell(&cell);
srslte_softbuffer_rx_init(&softbuffer, cell);
}
};
testmac my_mac;
srslte::radio_uhd radio_uhd;
#ifdef kk
uint32_t total_pkts=0;
uint32_t total_dci=0;
uint32_t total_errors=0;
uint8_t payload[1024];
// This is the MAC implementation
void run_tti(uint32_t tti) {
INFO("MAC running tti: %d\n", tti);
// SIB1 is scheduled in subframe #5 of even frames
if ((phy.tti_to_SFN(tti)%2) == 0 && phy.tti_to_subf(tti) == 5) {
// Get buffer
srslte::ue::dl_buffer *buffer = phy.get_dl_buffer(tti);
// Get DL grant
if (buffer->get_dl_grant(&grant))
{
total_dci++;
// MAC sets RV
grant.set_rv(((uint32_t) ceilf((float)3*((phy.tti_to_SFN(tti)/2)%4)/2))%4);
// Decode packet
if (!buffer->decode_data(&grant, payload)) {
total_errors++;
}
}
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) Gain: %.1f dB\r",
100-(float) 100*total_dci/total_pkts,
(float) 100*total_errors/total_pkts,
total_pkts, gain);
}
}
#endif
int main(int argc, char *argv[])
{
srslte::ue::phy phy;
testmac mac;
srslte_cell_t cell;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
srslte::radio_uhd radio_uhd;
srslte::log_stdout log("PHY");
parse_args(&prog_args, argc, argv);
@ -170,28 +155,54 @@ int main(int argc, char *argv[])
if (prog_args.uhd_gain > 0) {
radio_uhd.init();
radio_uhd.set_rx_gain(prog_args.uhd_gain);
phy.init(&radio_uhd, &mac, &log);
my_phy.init(&radio_uhd, &my_mac, &log);
} else {
radio_uhd.init_agc();
phy.init_agc(&radio_uhd, &mac, &log);
my_phy.init_agc(&radio_uhd, &my_mac, &log);
}
if (srsapps_verbose == 1) {
log.set_level_info();
printf("Log level info\n");
}
if (srsapps_verbose == 2) {
log.set_level_debug();
printf("Log level debug\n");
}
// Give it time to create thread
sleep(1);
// Set default parameters
phy.set_param(srslte::ue::phy_interface_params::PRACH_CONFIG_INDEX, 0);
phy.set_param(srslte::ue::phy_interface_params::PRACH_ROOT_SEQ_IDX, 0);
phy.set_param(srslte::ue::phy_interface_params::PRACH_HIGH_SPEED_FLAG, 0);
phy.set_param(srslte::ue::phy_interface_params::PRACH_ZC_CONFIG, 1);
// Set RX freq and gain
radio_uhd.set_rx_freq(prog_args.uhd_freq);
radio_uhd.set_rx_gain(prog_args.uhd_gain);
phy.sync_start();
while(1) {
usleep(1000);
my_phy.sync_start();
bool running = true;
while(running) {
if (bch_decoded && my_phy.status_is_sync()) {
uint32_t tti = my_phy.get_current_tti();
// SIB1 is scheduled in subframe #5 of even frames, try to decode next frame SIB1
tti = (((tti/20)*20) + 25)%10240;
my_phy.pdcch_dl_search(SRSLTE_RNTI_SI, SRSLTE_SIRNTI, tti, tti+1);
total_pkts++;
}
usleep(30000);
if (bch_decoded && my_phy.status_is_sync() && total_pkts > 0) {
if (srslte_verbose == SRSLTE_VERBOSE_NONE && srsapps_verbose == 0) {
float gain = prog_args.uhd_gain;
if (gain < 0) {
gain = radio_uhd.get_rx_gain();
}
printf("PDCCH BLER %.1f \%% PDSCH BLER %.1f \%% (total pkts: %5u) Gain: %.1f dB\r",
100-(float) 100*total_dci/total_pkts,
(float) 100*(1 - total_oks/total_pkts),
total_pkts, gain);
}
}
}
my_phy.stop();
radio_uhd.stop_rx();
}

@ -411,15 +411,17 @@ int srslte_prach_init(srslte_prach_t *p,
p->ifft_in = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t));
p->ifft_out = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t));
p->ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){
return -1;
if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) {
fprintf(stderr, "Error creating DFT plan\n");
return -1;
}
srslte_dft_plan_set_mirror(p->ifft, true);
srslte_dft_plan_set_norm(p->ifft, true);
p->fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t));
if(srslte_dft_plan(p->fft, p->N_ifft_prach, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){
return -1;
fprintf(stderr, "Error creating DFT plan\n");
return -1;
}
srslte_dft_plan_set_mirror(p->fft, true);
srslte_dft_plan_set_norm(p->fft, true);
@ -428,6 +430,8 @@ int srslte_prach_init(srslte_prach_t *p,
p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048;
ret = SRSLTE_SUCCESS;
} else {
fprintf(stderr, "Invalid parameters\n");
}
return ret;

@ -379,7 +379,7 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr
uint32_t Ngroups = srslte_phich_ngroups(&q->phich);
uint32_t ngroup = (n_prb_lowest+n_dmrs)%Ngroups;
uint32_t nseq = ((n_prb_lowest/Ngroups)+n_dmrs)%(2*srslte_phich_nsf(&q->phich));
INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d\n",
DEBUG("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d\n",
sf_idx, n_prb_lowest, n_dmrs, ngroup, nseq);
if (!srslte_phich_decode(&q->phich, q->sf_symbols, q->ce, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) {
INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance);

@ -386,7 +386,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) {
int ret = SRSLTE_ERROR_INVALID_INPUTS;
uint32_t track_idx;
if (q != NULL &&
if (q != NULL &&
input_buffer != NULL)
{

@ -45,12 +45,15 @@ int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t *q, uint32_t input_len, uint32_
return SRSLTE_ERROR;
}
if (srslte_dft_plan(&q->input_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) {
fprintf(stderr, "Error initiating input plan\n");
return SRSLTE_ERROR;
}
if (srslte_dft_plan(&q->filter_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) {
fprintf(stderr, "Error initiating filter plan\n");
return SRSLTE_ERROR;
}
if (srslte_dft_plan(&q->output_plan,q->output_len,SRSLTE_DFT_BACKWARD,SRSLTE_DFT_COMPLEX)) {
fprintf(stderr, "Error initiating output plan\n");
return SRSLTE_ERROR;
}
srslte_dft_plan_set_norm(&q->input_plan, true);

Loading…
Cancel
Save