Fix NR PBCH encoding/decoding

master
Xavier Arteaga 3 years ago committed by Andre Puschmann
parent 530b381c6c
commit 2ab3971ef1

@ -180,14 +180,29 @@ void srsran_pbch_nr_free(srsran_pbch_nr_t* q)
static const uint32_t G[PBCH_NR_A] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
#define PBCH_SFN_PAYLOAD_BEGIN 1
#define PBCH_SFN_PAYLOAD_LENGTH 6
#define PBCH_SFN_2ND_LSB_G (G[PBCH_SFN_PAYLOAD_LENGTH + 2])
#define PBCH_SFN_3RD_LSB_G (G[PBCH_SFN_PAYLOAD_LENGTH + 1])
static void
pbch_nr_pbch_msg_pack(const srsran_pbch_nr_cfg_t* cfg, const srsran_pbch_msg_nr_t* msg, uint8_t a[PBCH_NR_A])
{
// Extract actual payload size
uint32_t A_hat = SRSRAN_PBCH_MSG_NR_SZ;
// Put SFN in a_hat[A_hat] to a_hat[A_hat + 3]
// Put actual payload
uint32_t j_sfn = 0;
uint32_t j_other = 14;
for (uint32_t i = 0; i < A_hat; i++) {
if (i >= PBCH_SFN_PAYLOAD_BEGIN && i < (PBCH_SFN_PAYLOAD_BEGIN + PBCH_SFN_PAYLOAD_LENGTH)) {
a[G[j_sfn++]] = msg->payload[i];
} else {
a[G[j_other++]] = msg->payload[i];
}
}
// Put SFN in a_hat[A_hat] to a_hat[A_hat + 3]
a[G[j_sfn++]] = (uint8_t)((msg->sfn_4lsb >> 3U) & 1U); // 4th LSB of SFN
a[G[j_sfn++]] = (uint8_t)((msg->sfn_4lsb >> 2U) & 1U); // 3th LSB of SFN
a[G[j_sfn++]] = (uint8_t)((msg->sfn_4lsb >> 1U) & 1U); // 2th LSB of SFN
@ -207,16 +222,6 @@ pbch_nr_pbch_msg_pack(const srsran_pbch_nr_cfg_t* cfg, const srsran_pbch_msg_nr_
a[G[13]] = 0; // Reserved
}
// Put actual payload
uint32_t j_other = 14;
for (uint32_t i = 0; i < A_hat; i++) {
if (i > 0 && i < 7) {
a[G[j_sfn++]] = msg->payload[i];
} else {
a[G[j_other++]] = msg->payload[i];
}
}
if (srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
PBCH_NR_DEBUG_TX("Packed PBCH bits: ");
srsran_vec_fprint_byte(stdout, a, PBCH_NR_A);
@ -233,8 +238,18 @@ pbch_nr_pbch_msg_unpack(const srsran_pbch_nr_cfg_t* cfg, const uint8_t a[PBCH_NR
// Extract actual payload size
uint32_t A_hat = SRSRAN_PBCH_MSG_NR_SZ;
// Put SFN in a_hat[A_hat] to a_hat[A_hat + 3]
// Get actual payload
uint32_t j_sfn = 0;
uint32_t j_other = 14;
for (uint32_t i = 0; i < A_hat; i++) {
if (i >= PBCH_SFN_PAYLOAD_BEGIN && i < (PBCH_SFN_PAYLOAD_BEGIN + PBCH_SFN_PAYLOAD_LENGTH)) {
msg->payload[i] = a[G[j_sfn++]];
} else {
msg->payload[i] = a[G[j_other++]];
}
}
// Put SFN in a_hat[A_hat] to a_hat[A_hat + 3]
msg->sfn_4lsb = 0;
msg->sfn_4lsb |= (uint8_t)(a[G[j_sfn++]] << 3U); // 4th LSB of SFN
msg->sfn_4lsb |= (uint8_t)(a[G[j_sfn++]] << 2U); // 3th LSB of SFN
@ -254,16 +269,6 @@ pbch_nr_pbch_msg_unpack(const srsran_pbch_nr_cfg_t* cfg, const uint8_t a[PBCH_NR
} else {
msg->k_ssb_msb = a[G[11]];
}
// Put actual payload
uint32_t j_other = 14;
for (uint32_t i = 0; i < A_hat; i++) {
if (i > 0 && i < 7) {
msg->payload[i] = a[G[j_sfn++]];
} else {
msg->payload[i] = a[G[j_other++]];
}
}
}
static void pbch_nr_scramble(const srsran_pbch_nr_cfg_t* cfg, const uint8_t a[PBCH_NR_A], uint8_t a_prime[PBCH_NR_A])
@ -282,7 +287,7 @@ static void pbch_nr_scramble(const srsran_pbch_nr_cfg_t* cfg, const uint8_t a[PB
}
// Select value v
uint32_t v = 2 * a[G[1]] + a[G[2]];
uint32_t v = 2 * a[PBCH_SFN_3RD_LSB_G] + a[PBCH_SFN_2ND_LSB_G];
// Advance sequence
srsran_sequence_state_advance(&sequence_state, M * v);
@ -292,12 +297,14 @@ static void pbch_nr_scramble(const srsran_pbch_nr_cfg_t* cfg, const uint8_t a[PB
srsran_sequence_state_apply_bit(&sequence_state, c, c, PBCH_NR_A);
while (i < PBCH_NR_A) {
// a i corresponds to any one of the bits belonging to the SS/PBCH block index, the half frame index, and 2 nd and 3
// rd least significant bits of the system frame number
uint8_t s_i = c[j];
// else
if (i == G[11] || i == G[12] || i == G[13] || i == G[10] || i == G[1] || i == G[2]) {
// Check if i belongs to a SS/PBCH block index which is only multiplexed when L_max is 64
bool is_ssb_idx = (i == G[11] || i == G[12] || i == G[13]) && cfg->Lmax == 64;
// a i corresponds to any one of the bits belonging to the SS/PBCH block index, the half frame index, and 2 nd and 3
// rd least significant bits of the system frame number
if (is_ssb_idx || i == G[10] || i == PBCH_SFN_2ND_LSB_G || i == PBCH_SFN_3RD_LSB_G) {
s_i = 0;
} else {
j++;

@ -150,4 +150,4 @@ target_link_libraries(ssb_file_test srsran_phy)
# File test 1
# Captured with command: lib/examples/usrp_capture -a type=x300,clock=external,sampling_rate=46.08e6,rx_subdev_spec=B:0 -g 20 -r 46.08e6 -n 460800 -f 3502.8e6 -o /tmp/n78.fo35028.fs2304M.data
add_nr_test(ssb_file_test ssb_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/n78.fo35028.fs4608M.data -v -r 46.08e6 -f 3502.8e6 -F 3512.64e6 -n 460800 -A 500 357802 5 0 0 0)
add_nr_test(ssb_file_test ssb_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/n78.fo35028.fs4608M.data -v -r 46.08e6 -f 3502.8e6 -F 3512.64e6 -n 460800 -A 500 357802 2 0 1 0)

@ -43,6 +43,7 @@ cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state& phy_sta
srsran_ssb_args_t ssb_args = {};
ssb_args.enable_measure = true;
ssb_args.enable_decode = true;
if (srsran_ssb_init(&ssb, &ssb_args) < SRSRAN_SUCCESS) {
ERROR("Error initiating SSB");
return;
@ -381,6 +382,37 @@ bool cc_worker::measure_csi()
logger.debug("SSB-CSI: %s", str.data());
}
bool hrf = (dl_slot_cfg.idx % SRSRAN_NSLOTS_PER_FRAME_NR(phy.cfg.carrier.scs) >
SRSRAN_NSLOTS_PER_FRAME_NR(phy.cfg.carrier.scs) / 2);
srsran_pbch_msg_nr_t pbch_msg = {};
if (srsran_ssb_decode_pbch(&ssb, phy.cfg.carrier.pci, hrf, ssb_idx, rx_buffer[0], &pbch_msg) < SRSRAN_SUCCESS) {
logger.error("Error decoding PBCH");
return false;
}
// Check if PBCH message was decoded
if (pbch_msg.crc) {
// Unpack MIB
srsran_mib_nr_t mib = {};
if (srsran_pbch_msg_nr_mib_unpack(&pbch_msg, &mib) < SRSRAN_SUCCESS) {
logger.error("Error unpacking PBCH-MIB");
return false;
}
// Check if the SFN matches
// ...
// Log MIB information
if (logger.debug.enabled()) {
std::array<char, 512> str = {};
srsran_pbch_msg_nr_mib_info(&mib, str.data(), (uint32_t)str.size());
logger.debug("PBCH-MIB: sfn_4lsb=%d; %s", (dl_slot_cfg.idx / 10) & 0xf, str.data());
}
} else {
// CRC shall never fail if the UE is in sync
logger.warning("PBCH-MIB: CRC failed");
}
// Report SSB candidate channel measurement to the PHY state
phy.new_csi_trs_measurement(meas);
}

Loading…
Cancel
Save