Added condvar synchronization to ue itf class. SIB1 test working.

master
ismagom 10 years ago
parent bb08b2f04b
commit 736517babb

@ -63,7 +63,7 @@ namespace ue {
bool init_cell(srslte_cell_t cell, params *params_db);
void free_cell();
bool recv_ue_sync(uint32_t current_tti, srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time);
bool recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time);
bool get_ul_grant(pdcch_ul_search_t mode, uint32_t rnti, sched_grant *grant);
bool get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant *grant);
bool decode_phich(srslte_phich_alloc_t assignment);
@ -77,7 +77,6 @@ namespace ue {
uint32_t cfi;
bool sf_symbols_and_ce_done;
bool pdcch_llr_extracted;
uint32_t tti;
};
}
}

@ -26,6 +26,7 @@
*/
#include "srslte/srslte.h"
#include "srslte/ue_itf/tti_sync.h"
#include "srslte/ue_itf/dl_buffer.h"
#include "srslte/ue_itf/ul_buffer.h"
#include "srslte/ue_itf/prach.h"
@ -36,10 +37,6 @@
#ifndef UEPHY_H
#define UEPHY_H
#define SYNC_MODE_CV 0
#define SYNC_MODE_CALLBACK 1
#define SYNC_MODE SYNC_MODE_CALLBACK
namespace srslte {
namespace ue {
@ -62,11 +59,7 @@ class SRSLTE_API phy
{
public:
typedef void (*ue_phy_callback_tti_t) (uint32_t);
typedef void (*ue_phy_callback_status_t) (void);
ue_phy_callback_tti_t tti_clock_callback;
ue_phy_callback_status_t status_change;
bool init(ue_phy_callback_tti_t tti_clock_callback, ue_phy_callback_status_t status_change);
bool init(tti_sync *ttisync);
void stop();
// These functions can be called only if PHY is in IDLE (ie, not RX/TX)
@ -98,11 +91,6 @@ public:
static uint32_t tti_to_SFN(uint32_t tti);
static uint32_t tti_to_subf(uint32_t tti);
#if SYNC_MODE==SYNC_MODE_CV
std::condition_variable tti_cv;
std::mutex tti_mutex;
#endif
ul_buffer* get_ul_buffer(uint32_t tti);
dl_buffer* get_dl_buffer(uint32_t tti);
@ -113,11 +101,12 @@ private:
IDLE, RXTX
} phy_state;
tti_sync *ttisync;
srslte_cell_t cell;
bool cell_is_set;
bool is_sfn_synched = false;
bool started = false;
uint32_t current_tti;
srslte_ue_sync_t ue_sync;
srslte_ue_mib_t ue_mib;

@ -72,7 +72,7 @@ public:
bool is_ready_to_send() {
return state == READY;
}
uint32_t tti;
protected:
enum {
RELEASED, READY
@ -82,7 +82,7 @@ public:
queue(uint32_t nof_elements, uint32_t element_size);
~queue();
element* get(uint32_t idx);
element* get(uint32_t tti);
private:
uint32_t nof_elements;

@ -39,12 +39,11 @@ namespace ue {
public:
typedef enum {DOWNLINK=0, UPLINK=1} direction_t;
sched_grant(uint16_t rnti);
uint16_t get_rnti();
uint32_t get_rv();
void set_rv(uint32_t rv);
bool get_ndi();
uint32_t get_current_tti();
bool get_cqi_request();
int get_harq_process();
bool is_uplink();
@ -58,7 +57,6 @@ namespace ue {
};
direction_t dir;
uint16_t rnti;
uint32_t current_tti;
};
}

@ -0,0 +1,72 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2014 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* A copy of the GNU Lesser General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <stdint.h>
#include "srslte/srslte.h"
#ifndef TTISYNC_H
#define TTISYNC_H
namespace srslte {
namespace ue {
/* Interface used for PHY-MAC synchronization (producer-consumer model).
* The consumer waits while its counter is lower than the producer counter.
* The PHY is the consumer. The MAC is the producer.
*/
class SRSLTE_API tti_sync
{
public:
tti_sync(uint32_t modulus_)
{
modulus = modulus_;
init_counters(0);
}
virtual void increase() = 0;
virtual uint32_t wait() = 0;
virtual void set_producer_cntr(uint32_t) = 0;
uint32_t get_producer_cntr() { return producer_cntr; }
uint32_t get_consumer_cntr() { return consumer_cntr; }
protected:
void increase_producer() { producer_cntr = (producer_cntr + 1)%modulus; }
void increase_consumer() { consumer_cntr = (consumer_cntr + 1)%modulus; }
bool wait_condition() { return producer_cntr == consumer_cntr; }
void init_counters(uint32_t val)
{
consumer_cntr = val;
producer_cntr = val;
}
uint32_t modulus;
uint32_t producer_cntr;
uint32_t consumer_cntr;
};
}
}
#endif

@ -0,0 +1,58 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2014 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* A copy of the GNU Lesser General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <pthread.h>
#include "srslte/ue_itf/tti_sync.h"
#include "srslte/srslte.h"
#ifndef TTISYNC_CV_H
#define TTISYNC_CV_H
namespace srslte {
namespace ue {
/* Implements tti_sync interface with condition variables.
*/
class SRSLTE_API tti_sync_cv : public tti_sync
{
public:
tti_sync_cv(uint32_t modulus);
~tti_sync_cv();
void increase();
uint32_t wait();
void set_producer_cntr(uint32_t producer_cntr);
private:
pthread_cond_t cond;
pthread_mutex_t mutex;
};
}
}
#endif

@ -284,19 +284,9 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui
nof_bits <= DCI_MAX_BITS)
{
DEBUG("Rm input: ", 0);
if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_f(stdout, e, E);
}
/* unrate matching */
srslte_rm_conv_rx(e, E, q->rm_f, 3 * (nof_bits + 16));
DEBUG("Viterbi input: ", 0);
if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_f(stdout, q->rm_f, 3 * (nof_bits + 16));
}
/* viterbi decoder */
srslte_viterbi_decode_f(&q->decoder, q->rm_f, data, nof_bits + 16);
@ -425,11 +415,6 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT
/* descramble */
srslte_scrambling_f_offset(&q->seq[nsubframe], q->llr, 0, e_bits);
DEBUG("llr: ", 0);
if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_f(stdout, q->llr, e_bits);
}
ret = SRSLTE_SUCCESS;
}
return ret;

@ -351,8 +351,8 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, srslte_harq_t *harq, cf_t *sf_sy
harq != NULL)
{
INFO("Decoding PDSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
harq->sf_idx, srslte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
harq->sf_idx, rnti, srslte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
/* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) {

@ -281,13 +281,11 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) {
/* Make sure subframe idx is what we expect */
if ((q->sf_idx != srslte_sync_get_sf_idx(&q->strack)) && q->decode_sss_on_track) {
if (srslte_sync_get_cell_id(&q->strack) == q->cell.id) {
INFO("Warning: Expected SF idx %d but got %d (%d,%g - %d,%g)!\n",
q->sf_idx, srslte_sync_get_sf_idx(&q->strack),
q->strack.m0, q->strack.m0_value, q->strack.m1, q->strack.m1_value);
q->sf_idx = srslte_sync_get_sf_idx(&q->strack);
}
}
// Adjust time offset
q->time_offset = ((int) track_idx - (int) q->strack.frame_size/2 - (int) q->strack.fft_size);

@ -63,12 +63,11 @@ void dl_buffer::free_cell()
}
// FIXME: Avoid this memcpy modifying ue_sync to directly write into provided pointer
bool dl_buffer::recv_ue_sync(uint32_t current_tti, srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time)
bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time)
{
if (signal_buffer) {
INFO("DL Buffer TTI %d: Receiving packet\n", tti);
cf_t *sf_buffer = NULL;
tti = current_tti;
if (srslte_ue_sync_get_buffer(ue_sync, &sf_buffer) == 1) {
memcpy(signal_buffer, sf_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
srslte_ue_sync_get_last_timestamp(ue_sync, rx_time);
@ -111,8 +110,6 @@ bool dl_buffer::get_ul_grant(pdcch_ul_search_t mode, uint32_t rnti, sched_grant
}
uint8_t data[1024];
bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant *grant)
{
if (signal_buffer) {
@ -136,6 +133,7 @@ bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant
srslte_vec_save_file((char*) "ce1", ue_dl.ce[0], SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp)*sizeof(cf_t));
srslte_vec_save_file((char*) "ce2", ue_dl.ce[1], SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp)*sizeof(cf_t));
srslte_vec_save_file((char*) "pdcch_d", ue_dl.pdcch.d, 36*ue_dl.pdcch.nof_cce*sizeof(cf_t));
srslte_vec_save_file((char*) "pdcch_llr", ue_dl.pdcch.llr, 72*ue_dl.pdcch.nof_cce*sizeof(cf_t));
}
srslte_dci_msg_t dci_msg;
@ -143,15 +141,11 @@ bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant
return false;
}
uint32_t sfn = tti/10;
uint32_t rvidx = ((uint32_t) ceilf((float)3*((sfn/2)%4)/2))%4;
srslte_ue_dl_decode_rnti_rv_packet(&ue_dl, &dci_msg, data, cfi, tti%10, rnti, rvidx);
/* if (srslte_dci_msg_to_ra_dl(&dci_msg, rnti, cell, cfi,
if (srslte_dci_msg_to_ra_dl(&dci_msg, rnti, cell, cfi,
(srslte_ra_pdsch_t*) grant->get_grant_ptr())) {
return false;
}
*/
return true;
}
}

@ -51,11 +51,10 @@ bool phy::init_radio_handler(char *args) {
return true;
}
bool phy::init(ue_phy_callback_tti_t tti_clock_callback_, ue_phy_callback_status_t status_change_)
bool phy::init(tti_sync *ttisync_)
{
started = false;
tti_clock_callback = tti_clock_callback_;
status_change = status_change_;
ttisync = ttisync_;
ul_buffer_queue = new queue(6, sizeof(ul_buffer));
dl_buffer_queue = new queue(6, sizeof(dl_buffer));
@ -142,7 +141,6 @@ bool phy::start_rxtx()
// Start streaming
cuhd_start_rx_stream(radio_handler);
phy_state = RXTX;
status_change();
return true;
} else {
fprintf(stderr, "Can not change state to RXTX: cell is not set\n");
@ -159,7 +157,6 @@ bool phy::stop_rxtx()
// Stop streaming
cuhd_stop_rx_stream(radio_handler);
phy_state = IDLE;
status_change();
return true;
} else {
fprintf(stderr, "Can not change state to RXTX: invalid state %d\n", phy_state);
@ -176,7 +173,7 @@ bool phy::status_is_rxtx() {
}
uint32_t phy::get_current_tti() {
return current_tti;
return ttisync->get_producer_cntr();
}
uint32_t phy::tti_to_SFN(uint32_t tti) {
return tti/10;
@ -304,9 +301,7 @@ bool phy::decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell_ptr, uint8_t b
srslte_ue_mib_sync_free(&ue_mib_sync);
if (ret == 1) {
srslte_pbch_mib_unpack(bch_payload, cell_ptr, &sfn);
sfn = (sfn + sfn_offset)%1024;
current_tti = sfn*10+1;
srslte_pbch_mib_unpack(bch_payload, cell_ptr, NULL);
return true;
} else {
printf("Error decoding MIB: Error decoding PBCH\n");
@ -321,6 +316,7 @@ int phy::sync_sfn(void) {
int ret = SRSLTE_ERROR;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
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");
@ -340,7 +336,8 @@ int phy::sync_sfn(void) {
srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
sfn = (sfn + sfn_offset)%1024;
current_tti = sfn*10 + 1;
ttisync->set_producer_cntr(10*sfn+1);
srslte_ue_sync_decode_sss_on_track(&ue_sync, false);
return 1;
}
}
@ -348,7 +345,6 @@ int phy::sync_sfn(void) {
return 0;
}
void phy::run_rx_tx_state()
{
int ret;
@ -359,16 +355,17 @@ void phy::run_rx_tx_state()
phy_state = IDLE;
break;
case 1:
printf("SFN synched ok\n");
is_sfn_synched = true;
break;
case 0:
break;
}
} else {
uint32_t current_tti = ttisync->get_producer_cntr();
// Receive alligned buffer for the current tti
srslte_timestamp_t rx_time;
get_dl_buffer(current_tti)->recv_ue_sync(current_tti, &ue_sync, &rx_time);
get_dl_buffer(current_tti)->recv_ue_sync(&ue_sync, &rx_time);
// send prach if we have to
if (prach_buffer.is_ready_to_send(current_tti)) {
@ -378,8 +375,7 @@ void phy::run_rx_tx_state()
if (get_ul_buffer(current_tti)->is_ready_to_send()) {
get_ul_buffer(current_tti)->send_packet(radio_handler, rx_time);
}
tti_clock_callback(current_tti);
current_tti = (current_tti + 1)%10240;
ttisync->increase();
}
}

@ -53,9 +53,11 @@ namespace ue {
}
}
queue::element* queue::get(uint32_t idx)
queue::element* queue::get(uint32_t tti)
{
return (queue::element*) buffer_of_elements[idx%nof_elements];
queue::element* el = (queue::element*) buffer_of_elements[tti%nof_elements];
el->tti = tti;
return el;
}
} // namespace ue

@ -35,6 +35,11 @@
namespace srslte {
namespace ue {
sched_grant::sched_grant(uint16_t rnti_)
{
rnti = rnti_;
}
/* Returns the RNTI associated with the UL/DL scheduling grant */
uint16_t sched_grant::get_rnti() {
return rnti;
@ -80,10 +85,6 @@ namespace ue {
}
}
uint32_t sched_grant::get_current_tti() {
return current_tti;
}
int sched_grant::get_harq_process() {
if (dir == UPLINK) {
return -1;

@ -0,0 +1,75 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2014 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* A copy of the GNU Lesser General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <pthread.h>
#include "srslte/ue_itf/tti_sync_cv.h"
namespace srslte {
namespace ue {
tti_sync_cv::tti_sync_cv(uint32_t modulus): tti_sync(modulus)
{
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
}
tti_sync_cv::~tti_sync_cv()
{
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
}
uint32_t tti_sync_cv::wait()
{
pthread_mutex_lock(&mutex);
while(wait_condition()) {
pthread_cond_wait(&cond, &mutex);
}
uint32_t x = consumer_cntr;
increase_consumer();
pthread_mutex_unlock(&mutex);
return x;
}
void tti_sync_cv::set_producer_cntr(uint32_t producer_cntr)
{
pthread_mutex_lock(&mutex);
init_counters(producer_cntr);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
void tti_sync_cv::increase()
{
pthread_mutex_lock(&mutex);
increase_producer();
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
}

@ -22,6 +22,6 @@
LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
IF(${CUHD_FIND} GREATER -1)
ADD_EXECUTABLE(ue_itf_test ue_itf_test.cc)
TARGET_LINK_LIBRARIES(ue_itf_test srslte++ cuhd)
ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc)
TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srslte++ cuhd)
ENDIF(${CUHD_FIND} GREATER -1)

@ -29,11 +29,7 @@
#include "srslte/utils/debug.h"
#include "srslte/ue_itf/phy.h"
void tti_callback();
void status_change();
#include "srslte/ue_itf/tti_sync_cv.h"
@ -95,9 +91,9 @@ uint32_t total_errors=0;
uint8_t payload[1024];
// This is the MAC implementation
void tti_callback(uint32_t tti) {
srslte::ue::sched_grant grant;
INFO("called tti: %d\n", tti);
void run_tti(uint32_t tti) {
srslte::ue::sched_grant grant = srslte::ue::sched_grant(SRSLTE_SIRNTI);
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) {
@ -108,33 +104,24 @@ void tti_callback(uint32_t tti) {
// Get DL grant
if (buffer->get_dl_grant(srslte::ue::dl_buffer::PDCCH_DL_SEARCH_SIRNTI, SRSLTE_SIRNTI, &grant))
{
// MAC sets RV
total_dci++;
// MAC sets RV and RNTI
grant.set_rv(((uint32_t) ceilf((float)3*((phy.tti_to_SFN(tti)/2)%4)/2))%4);
// Decode packet
if (buffer->decode_pdsch(grant, payload)) {
printf("Decoded SIB1 ok TBS: %d\n", grant.get_tbs());
srslte_vec_fprint_hex(stdout, payload, grant.get_tbs());
exit(0);
} else {
if (!buffer->decode_pdsch(grant, payload)) {
total_errors++;
}
exit(0);
total_dci++;
}
total_pkts++;
if (total_pkts==4) {
exit(-1);
}
}
printf("PDCCH BLER %.3f \%% PDSCH BLER %.3f \%% (total pkts: %d) \r",
1-(float) total_dci/total_pkts,
(float) total_errors/total_pkts,
if (srslte_verbose == SRSLTE_VERBOSE_NONE) {
printf("PDCCH BLER %.1f \%% PDSCH BLER %.1f \%% (total pkts: %5u) \r",
100-(float) 100*total_dci/total_pkts,
(float) 100*total_errors/total_pkts,
total_pkts);
}
void status_change() {
printf("called status change\n");
}
}
int main(int argc, char *argv[])
@ -142,11 +129,12 @@ 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);
parse_args(&prog_args, argc, argv);
// Init PHY
phy.init(tti_callback, status_change);
phy.init(&ttisync);
// Give it time to create thread
sleep(1);
@ -175,6 +163,7 @@ int main(int argc, char *argv[])
}
/* go to idle and process each tti */
while(1) {
sleep(1);
uint32_t tti = ttisync.wait();
run_tti(tti);
}
}
Loading…
Cancel
Save