write BCH to PCAP

this patch moves the BCH payload buffer into the UE sync object and
therefore allows to pass it to the MAC for PCAP logging
master
Andre Puschmann 5 years ago
parent 6baa89cd2c
commit 08ca9ebd4e

@ -104,7 +104,7 @@ private:
void reset(); void reset();
float get_last_cfo(); float get_last_cfo();
void set_agc_enable(bool enable); void set_agc_enable(bool enable);
ret_code run(srslte_cell_t* cell); ret_code run(srslte_cell_t* cell, std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload);
private: private:
sync* p = nullptr; sync* p = nullptr;
@ -128,9 +128,15 @@ private:
uint32_t nof_subframes = SFN_SYNC_NOF_SUBFRAMES); uint32_t nof_subframes = SFN_SYNC_NOF_SUBFRAMES);
void reset(); void reset();
bool set_cell(srslte_cell_t cell); bool set_cell(srslte_cell_t cell);
ret_code run_subframe(srslte_cell_t* cell, uint32_t* tti_cnt, bool sfidx_only = false); ret_code run_subframe(srslte_cell_t* cell,
ret_code uint32_t* tti_cnt,
decode_mib(srslte_cell_t* cell, uint32_t* tti_cnt, cf_t* ext_buffer[SRSLTE_MAX_PORTS], bool sfidx_only = false); std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload,
bool sfidx_only = false);
ret_code decode_mib(srslte_cell_t* cell,
uint32_t* tti_cnt,
cf_t* ext_buffer[SRSLTE_MAX_PORTS],
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload,
bool sfidx_only = false);
private: private:
const static int SFN_SYNC_NOF_SUBFRAMES = 100; const static int SFN_SYNC_NOF_SUBFRAMES = 100;
@ -342,6 +348,7 @@ private:
float time_adv_sec = 0; float time_adv_sec = 0;
float next_time_adv_sec = 0; float next_time_adv_sec = 0;
uint32_t tti = 0; uint32_t tti = 0;
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN> mib;
uint32_t tx_worker_cnt = 0; uint32_t tx_worker_cnt = 0;
uint32_t nof_workers = 0; uint32_t nof_workers = 0;

@ -336,22 +336,19 @@ bool sync::cell_is_camping()
return phy_state.is_camping(); return phy_state.is_camping();
} }
/** /**
* MAIN THREAD * MAIN THREAD
* *
* The main thread process the SYNC state machine. Every state except IDLE must have exclusive access to * The main thread process the SYNC state machine. Every state except IDLE must have exclusive access to
* all variables. If any change of cell configuration must be done, the thread must be in IDLE. * all variables. If any change of cell configuration must be done, the thread must be in IDLE.
* *
* On each state except campling, 1 function is called and the thread jumps to the next state based on the output. * On each state except campling, 1 function is called and the thread jumps to the next state based on the output.
* *
* It has 3 states: Cell search, SFN syncrhonization, intial measurement and camping. * It has 3 states: Cell search, SFN synchronization, initial measurement and camping.
* - CELL_SEARCH: Initial Cell id and MIB acquisition. Uses 1.92 MHz sampling rate * - CELL_SEARCH: Initial Cell id and MIB acquisition. Uses 1.92 MHz sampling rate
* - CELL_SYNC: Full sampling rate, uses MIB to obtain SFN. When SFN is obtained, moves to CELL_CAMP * - CELL_SYNC: Full sampling rate, uses MIB to obtain SFN. When SFN is obtained, moves to CELL_CAMP
* - CELL_CAMP: Cell camping state. Calls the PHCH workers to process subframes and mantains cell synchronization. * - CELL_CAMP: Cell camping state. Calls the PHCH workers to process subframes and maintains cell synchronization.
* - IDLE: Receives and discards received samples. Does not mantain synchronization. * - IDLE: Receives and discards received samples. Does not maintain synchronization.
* *
*/ */
@ -393,7 +390,8 @@ void sync::run_thread()
/* Search for a cell in the current frequency and go to IDLE. /* Search for a cell in the current frequency and go to IDLE.
* The function search_p.run() will not return until the search finishes * The function search_p.run() will not return until the search finishes
*/ */
cell_search_ret = search_p.run(&cell); cell_search_ret = search_p.run(&cell, mib);
stack->bch_decoded_ok(mib.data(), mib.size() / 8);
phy_state.state_exit(); phy_state.state_exit();
break; break;
case sync_state::SFN_SYNC: case sync_state::SFN_SYNC:
@ -401,7 +399,7 @@ void sync::run_thread()
/* SFN synchronization using MIB. run_subframe() receives and processes 1 subframe /* SFN synchronization using MIB. run_subframe() receives and processes 1 subframe
* and returns * and returns
*/ */
switch(sfn_p.run_subframe(&cell, &tti)) { switch (sfn_p.run_subframe(&cell, &tti, mib)) {
case sfn_sync::SFN_FOUND: case sfn_sync::SFN_FOUND:
stack->in_sync(); stack->in_sync();
phy_state.state_exit(); phy_state.state_exit();
@ -442,7 +440,7 @@ void sync::run_thread()
// Force decode MIB if required // Force decode MIB if required
if (force_camping_sfn_sync) { if (force_camping_sfn_sync) {
uint32_t _tti = 0; uint32_t _tti = 0;
sync::sfn_sync::ret_code ret = sfn_p.decode_mib(&cell, &_tti, buffer[0]); sync::sfn_sync::ret_code ret = sfn_p.decode_mib(&cell, &_tti, buffer[0], mib);
if (ret == sfn_sync::SFN_FOUND) { if (ret == sfn_sync::SFN_FOUND) {
// Force tti // Force tti
@ -995,15 +993,12 @@ void sync::search::set_agc_enable(bool enable)
} }
} }
sync::search::ret_code sync::search::run(srslte_cell_t* cell) sync::search::ret_code sync::search::run(srslte_cell_t* cell, std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload)
{ {
if (!cell) { if (!cell) {
return ERROR; return ERROR;
} }
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
srslte_ue_cellsearch_result_t found_cells[3]; srslte_ue_cellsearch_result_t found_cells[3];
bzero(cell, sizeof(srslte_cell_t)); bzero(cell, sizeof(srslte_cell_t));
@ -1062,11 +1057,13 @@ sync::search::ret_code sync::search::run(srslte_cell_t* cell)
/* Find and decode MIB */ /* Find and decode MIB */
int sfn_offset; int sfn_offset;
ret = srslte_ue_mib_sync_decode(&ue_mib_sync, ret = srslte_ue_mib_sync_decode(&ue_mib_sync, 40, bch_payload.data(), &cell->nof_ports, &sfn_offset);
40,
bch_payload, &cell->nof_ports, &sfn_offset);
if (ret == 1) { if (ret == 1) {
srslte_pbch_mib_unpack(bch_payload, cell, NULL); srslte_pbch_mib_unpack(bch_payload.data(), cell, NULL);
// pack MIB and store inplace for PCAP dump
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN / 8> mib_packed;
srslte_bit_pack_vector(bch_payload.data(), mib_packed.data(), SRSLTE_BCH_PAYLOAD_LEN);
std::copy(std::begin(mib_packed), std::end(mib_packed), std::begin(bch_payload));
fprintf(stdout, fprintf(stdout,
"Found Cell: Mode=%s, PCI=%d, PRB=%d, Ports=%d, CFO=%.1f KHz\n", "Found Cell: Mode=%s, PCI=%d, PRB=%d, Ports=%d, CFO=%.1f KHz\n",
@ -1147,7 +1144,10 @@ void sync::sfn_sync::reset()
srslte_ue_mib_reset(&ue_mib); srslte_ue_mib_reset(&ue_mib);
} }
sync::sfn_sync::ret_code sync::sfn_sync::run_subframe(srslte_cell_t* cell, uint32_t* tti_cnt, bool sfidx_only) sync::sfn_sync::ret_code sync::sfn_sync::run_subframe(srslte_cell_t* cell,
uint32_t* tti_cnt,
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload,
bool sfidx_only)
{ {
int ret = srslte_ue_sync_zerocopy(ue_sync, buffer); int ret = srslte_ue_sync_zerocopy(ue_sync, buffer);
@ -1157,7 +1157,7 @@ sync::sfn_sync::ret_code sync::sfn_sync::run_subframe(srslte_cell_t* cell, uint3
} }
if (ret == 1) { if (ret == 1) {
sync::sfn_sync::ret_code ret2 = decode_mib(cell, tti_cnt, NULL, sfidx_only); sync::sfn_sync::ret_code ret2 = decode_mib(cell, tti_cnt, NULL, bch_payload, sfidx_only);
if (ret2 != SFN_NOFOUND) { if (ret2 != SFN_NOFOUND) {
return ret2; return ret2;
} }
@ -1174,12 +1174,12 @@ sync::sfn_sync::ret_code sync::sfn_sync::run_subframe(srslte_cell_t* cell, uint3
return IDLE; return IDLE;
} }
sync::sfn_sync::ret_code sync::sfn_sync::ret_code sync::sfn_sync::decode_mib(srslte_cell_t* cell,
sync::sfn_sync::decode_mib(srslte_cell_t* cell, uint32_t* tti_cnt, cf_t* ext_buffer[SRSLTE_MAX_PORTS], bool sfidx_only) uint32_t* tti_cnt,
cf_t* ext_buffer[SRSLTE_MAX_PORTS],
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload,
bool sfidx_only)
{ {
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
// If external buffer provided not equal to internal buffer, copy data // If external buffer provided not equal to internal buffer, copy data
if ((ext_buffer != NULL) && (ext_buffer != buffer)) { if ((ext_buffer != NULL) && (ext_buffer != buffer)) {
memcpy(buffer[0], ext_buffer[0], sizeof(cf_t) * ue_sync->sf_len); memcpy(buffer[0], ext_buffer[0], sizeof(cf_t) * ue_sync->sf_len);
@ -1196,14 +1196,14 @@ sync::sfn_sync::decode_mib(srslte_cell_t* cell, uint32_t* tti_cnt, cf_t* ext_buf
} }
int sfn_offset = 0; int sfn_offset = 0;
int n = srslte_ue_mib_decode(&ue_mib, bch_payload, NULL, &sfn_offset); int n = srslte_ue_mib_decode(&ue_mib, bch_payload.data(), NULL, &sfn_offset);
switch (n) { switch (n) {
default: default:
Error("SYNC: Error decoding MIB while synchronising SFN"); Error("SYNC: Error decoding MIB while synchronising SFN");
return ERROR; return ERROR;
case SRSLTE_UE_MIB_FOUND: case SRSLTE_UE_MIB_FOUND:
uint32_t sfn; uint32_t sfn;
srslte_pbch_mib_unpack(bch_payload, cell, &sfn); srslte_pbch_mib_unpack(bch_payload.data(), cell, &sfn);
sfn = (sfn + sfn_offset) % 1024; sfn = (sfn + sfn_offset) % 1024;
if (tti_cnt) { if (tti_cnt) {

Loading…
Cancel
Save