mirror of https://github.com/PentHertz/srsLTE.git
Merge branch 'next'
This commit is contained in:
commit
afcdf21dcc
|
@ -59,6 +59,9 @@
|
||||||
|
|
||||||
// cf_t definition
|
// cf_t definition
|
||||||
typedef _Complex float cf_t;
|
typedef _Complex float cf_t;
|
||||||
|
|
||||||
|
#ifdef ENABLE_C16
|
||||||
typedef _Complex short int c16_t;
|
typedef _Complex short int c16_t;
|
||||||
|
#endif /* ENABLE_C16 */
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#define SRSLTE_CQI_MAX_BITS 64
|
#define SRSLTE_CQI_MAX_BITS 64
|
||||||
#define SRSLTE_DIF_CQI_MAX_BITS 3
|
#define SRSLTE_DIF_CQI_MAX_BITS 3
|
||||||
#define SRSLTE_PMI_MAX_BITS 4
|
#define SRSLTE_PMI_MAX_BITS 4
|
||||||
|
#define SRSLTE_CQI_STR_MAX_CHAR 32
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool configured;
|
bool configured;
|
||||||
|
|
|
@ -150,7 +150,10 @@
|
||||||
#endif /* LV_HAVE_AVX2 */
|
#endif /* LV_HAVE_AVX2 */
|
||||||
#endif /* LV_HAVE_AVX512 */
|
#endif /* LV_HAVE_AVX512 */
|
||||||
|
|
||||||
|
#ifndef ENABLE_C16
|
||||||
|
#undef SRSLTE_SIMD_C16_SIZE
|
||||||
|
#define SRSLTE_SIMD_C16_SIZE 0
|
||||||
|
#endif /* ENABLE_C16 */
|
||||||
|
|
||||||
#if SRSLTE_SIMD_F_SIZE
|
#if SRSLTE_SIMD_F_SIZE
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,9 @@ SRSLTE_API cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y,
|
||||||
|
|
||||||
SRSLTE_API cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len);
|
SRSLTE_API cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len);
|
||||||
|
|
||||||
|
#ifdef ENABLE_C16
|
||||||
SRSLTE_API c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len);
|
SRSLTE_API c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len);
|
||||||
|
#endif /* ENABLE_C16 */
|
||||||
|
|
||||||
SRSLTE_API int srslte_vec_dot_prod_sss_simd(const int16_t *x, const int16_t *y, const int len);
|
SRSLTE_API int srslte_vec_dot_prod_sss_simd(const int16_t *x, const int16_t *y, const int len);
|
||||||
|
|
||||||
|
|
|
@ -456,8 +456,16 @@ int srslte_cqi_hl_get_no_subbands(int nof_prb)
|
||||||
|
|
||||||
void srslte_cqi_to_str(const uint8_t *cqi_value, int cqi_len, char *str, int str_len) {
|
void srslte_cqi_to_str(const uint8_t *cqi_value, int cqi_len, char *str, int str_len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < cqi_len && i < (str_len - 1); i++) {
|
|
||||||
|
for (i = 0; i < cqi_len && i < (str_len - 5); i++) {
|
||||||
str[i] = (cqi_value[i] == 0)?(char)'0':(char)'1';
|
str[i] = (cqi_value[i] == 0)?(char)'0':(char)'1';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == (str_len - 5)) {
|
||||||
|
str[i++] = '.';
|
||||||
|
str[i++] = '.';
|
||||||
|
str[i++] = '.';
|
||||||
|
str[i++] = (cqi_value[cqi_len - 1] == 0)?(char)'0':(char)'1';
|
||||||
|
}
|
||||||
str[i] = '\0';
|
str[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,8 @@ void parse_args(int argc, char **argv) {
|
||||||
cfi = atoi(argv[optind]);
|
cfi = atoi(argv[optind]);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
strncpy(mimo_type_str, argv[optind], 32);
|
strncpy(mimo_type_str, argv[optind], 31);
|
||||||
|
mimo_type_str[31] = 0;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pmi = (uint32_t) atoi(argv[optind]);
|
pmi = (uint32_t) atoi(argv[optind]);
|
||||||
|
|
|
@ -711,13 +711,12 @@ int rf_uhd_recv_with_time(void *h,
|
||||||
}
|
}
|
||||||
|
|
||||||
int rf_uhd_recv_with_time_multi(void *h,
|
int rf_uhd_recv_with_time_multi(void *h,
|
||||||
void **data,
|
void *data[SRSLTE_MAX_PORTS],
|
||||||
uint32_t nsamples,
|
uint32_t nsamples,
|
||||||
bool blocking,
|
bool blocking,
|
||||||
time_t *secs,
|
time_t *secs,
|
||||||
double *frac_secs)
|
double *frac_secs)
|
||||||
{
|
{
|
||||||
|
|
||||||
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
|
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
|
||||||
uhd_rx_metadata_handle *md = &handler->rx_md_first;
|
uhd_rx_metadata_handle *md = &handler->rx_md_first;
|
||||||
size_t rxd_samples = 0;
|
size_t rxd_samples = 0;
|
||||||
|
|
|
@ -433,6 +433,7 @@ cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_C16
|
||||||
c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len) {
|
c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
c16_t result = 0;
|
c16_t result = 0;
|
||||||
|
@ -460,6 +461,7 @@ c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const in
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_C16 */
|
||||||
|
|
||||||
cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, const int len)
|
cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, const int len)
|
||||||
{
|
{
|
||||||
|
@ -620,6 +622,7 @@ void srslte_vec_prod_ccc_split_simd(const float *a_re, const float *a_im, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_C16
|
||||||
void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, const int16_t *b_re, const int16_t *b_im,
|
void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, const int16_t *b_re, const int16_t *b_im,
|
||||||
int16_t *r_re, int16_t *r_im, const int len) {
|
int16_t *r_re, int16_t *r_im, const int len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -652,6 +655,7 @@ void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, cons
|
||||||
r_im[i] = a_re[i]*b_im[i] + a_im[i]*b_re[i];
|
r_im[i] = a_re[i]*b_im[i] + a_im[i]*b_re[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_C16 */
|
||||||
|
|
||||||
void srslte_vec_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len) {
|
void srslte_vec_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -551,7 +551,7 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
ue_db[rnti].phich_info.n_prb_lowest = enb_ul.pusch_cfg.grant.n_prb_tilde[0];
|
ue_db[rnti].phich_info.n_prb_lowest = enb_ul.pusch_cfg.grant.n_prb_tilde[0];
|
||||||
ue_db[rnti].phich_info.n_dmrs = phy_grant.ncs_dmrs;
|
ue_db[rnti].phich_info.n_dmrs = phy_grant.ncs_dmrs;
|
||||||
|
|
||||||
char cqi_str[64];
|
char cqi_str[SRSLTE_CQI_STR_MAX_CHAR];
|
||||||
if (cqi_enabled) {
|
if (cqi_enabled) {
|
||||||
if (ue_db[rnti].cqi_en) {
|
if (ue_db[rnti].cqi_en) {
|
||||||
wideband_cqi_value = cqi_value.wideband.wideband_cqi;
|
wideband_cqi_value = cqi_value.wideband.wideband_cqi;
|
||||||
|
@ -578,7 +578,7 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
|
||||||
cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.N);
|
cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 64);
|
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
|
||||||
//snprintf(cqi_str, 64, ", cqi=%s", wideband_cqi_value);
|
//snprintf(cqi_str, 64, ", cqi=%s", wideband_cqi_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -609,6 +609,7 @@ int setup_if_addr(char *ip_addr)
|
||||||
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
|
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
|
||||||
{
|
{
|
||||||
perror("ioctl1");
|
perror("ioctl1");
|
||||||
|
close(tun_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,12 +618,14 @@ int setup_if_addr(char *ip_addr)
|
||||||
if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr))
|
if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr))
|
||||||
{
|
{
|
||||||
perror("socket");
|
perror("socket");
|
||||||
|
close(tun_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
|
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
|
||||||
if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr))
|
if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr))
|
||||||
{
|
{
|
||||||
perror("ioctl2");
|
perror("ioctl2");
|
||||||
|
close(tun_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,6 +636,7 @@ int setup_if_addr(char *ip_addr)
|
||||||
if(0 > ioctl(sock, SIOCSIFADDR, &ifr))
|
if(0 > ioctl(sock, SIOCSIFADDR, &ifr))
|
||||||
{
|
{
|
||||||
perror("ioctl");
|
perror("ioctl");
|
||||||
|
close(tun_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ifr.ifr_netmask.sa_family = AF_INET;
|
ifr.ifr_netmask.sa_family = AF_INET;
|
||||||
|
@ -640,6 +644,7 @@ int setup_if_addr(char *ip_addr)
|
||||||
if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr))
|
if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr))
|
||||||
{
|
{
|
||||||
perror("ioctl");
|
perror("ioctl");
|
||||||
|
close(tun_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,8 @@ public:
|
||||||
float avg_rsrp;
|
float avg_rsrp;
|
||||||
float avg_rsrp_dbm;
|
float avg_rsrp_dbm;
|
||||||
float avg_rsrq_db;
|
float avg_rsrq_db;
|
||||||
|
float avg_rssi_dbm;
|
||||||
|
float last_radio_rssi;
|
||||||
float rx_gain_offset;
|
float rx_gain_offset;
|
||||||
float avg_snr_db;
|
float avg_snr_db;
|
||||||
float avg_noise;
|
float avg_noise;
|
||||||
|
|
|
@ -158,6 +158,8 @@ private:
|
||||||
float cfo;
|
float cfo;
|
||||||
bool rar_cqi_request;
|
bool rar_cqi_request;
|
||||||
|
|
||||||
|
uint32_t rssi_read_cnt;
|
||||||
|
|
||||||
// Metrics
|
// Metrics
|
||||||
dl_metrics_t dl_metrics;
|
dl_metrics_t dl_metrics;
|
||||||
ul_metrics_t ul_metrics;
|
ul_metrics_t ul_metrics;
|
||||||
|
|
|
@ -100,6 +100,7 @@ void phch_worker::reset()
|
||||||
rar_cqi_request = false;
|
rar_cqi_request = false;
|
||||||
I_sr = 0;
|
I_sr = 0;
|
||||||
cfi = 0;
|
cfi = 0;
|
||||||
|
rssi_read_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void phch_worker::set_common(phch_common* phy_)
|
void phch_worker::set_common(phch_common* phy_)
|
||||||
|
@ -222,13 +223,20 @@ void phch_worker::work_imp()
|
||||||
bool ul_grant_available = false;
|
bool ul_grant_available = false;
|
||||||
bool dl_ack[SRSLTE_MAX_CODEWORDS] = {false};
|
bool dl_ack[SRSLTE_MAX_CODEWORDS] = {false};
|
||||||
|
|
||||||
mac_interface_phy::mac_grant_t dl_mac_grant;
|
mac_interface_phy::mac_grant_t dl_mac_grant = {};
|
||||||
mac_interface_phy::tb_action_dl_t dl_action;
|
mac_interface_phy::tb_action_dl_t dl_action = {};
|
||||||
bzero(&dl_action, sizeof(mac_interface_phy::tb_action_dl_t));
|
|
||||||
|
|
||||||
mac_interface_phy::mac_grant_t ul_mac_grant;
|
mac_interface_phy::mac_grant_t ul_mac_grant = {};
|
||||||
mac_interface_phy::tb_action_ul_t ul_action;
|
mac_interface_phy::tb_action_ul_t ul_action = {};
|
||||||
bzero(&ul_action, sizeof(mac_interface_phy::tb_action_ul_t));
|
|
||||||
|
|
||||||
|
/** Calculate RSSI on the input signal before generating the output */
|
||||||
|
|
||||||
|
// Average RSSI over all symbols
|
||||||
|
float rssi_dbm = 10*log10(srslte_vec_avg_power_cf(signal_buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb))) + 30;
|
||||||
|
if (isnormal(rssi_dbm)) {
|
||||||
|
phy->avg_rssi_dbm = SRSLTE_VEC_EMA(rssi_dbm, phy->avg_rssi_dbm, phy->args->snr_ema_coeff);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */
|
/* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */
|
||||||
bool chest_ok = extract_fft_and_pdcch_llr();
|
bool chest_ok = extract_fft_and_pdcch_llr();
|
||||||
|
@ -287,7 +295,8 @@ void phch_worker::work_imp()
|
||||||
|
|
||||||
// Decode PHICH
|
// Decode PHICH
|
||||||
bool ul_ack = false;
|
bool ul_ack = false;
|
||||||
bool ul_ack_available = decode_phich(&ul_ack);
|
bool ul_ack_available = decode_phich(&ul_ack);
|
||||||
|
|
||||||
|
|
||||||
/***** Uplink Processing + Transmission *******/
|
/***** Uplink Processing + Transmission *******/
|
||||||
|
|
||||||
|
@ -388,13 +397,14 @@ void phch_worker::compute_ri(uint8_t *ri, uint8_t *pmi, float *sinr) {
|
||||||
Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn);
|
Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn);
|
||||||
} else {
|
} else {
|
||||||
/* If only one receiving antenna, force RI for 1 layer */
|
/* If only one receiving antenna, force RI for 1 layer */
|
||||||
uci_data.uci_ri = 0;
|
if (ri) {
|
||||||
|
*ri = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uci_data.uci_ri_len = 1;
|
uci_data.uci_ri_len = 1;
|
||||||
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
|
||||||
srslte_ue_dl_ri_pmi_select(&ue_dl, ri, pmi, sinr);
|
srslte_ue_dl_ri_pmi_select(&ue_dl, ri, pmi, sinr);
|
||||||
Debug("TM4 ri=%d; pmi=%d; SINR=%.1fdB\n", ue_dl.ri, ue_dl.pmi[ue_dl.ri], 10*log10f(ue_dl.sinr[ue_dl.ri][ue_dl.pmi[ue_dl.ri]]));
|
Debug("TM4 ri=%d; pmi=%d; SINR=%.1fdB\n", ue_dl.ri, ue_dl.pmi[ue_dl.ri], 10*log10f(ue_dl.sinr[ue_dl.ri][ue_dl.pmi[ue_dl.ri]]));
|
||||||
uci_data.uci_ri_len = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,11 +905,11 @@ void phch_worker::set_uci_aperiodic_cqi()
|
||||||
{
|
{
|
||||||
uint8_t ri = (uint8_t) ue_dl.ri;
|
uint8_t ri = (uint8_t) ue_dl.ri;
|
||||||
uint8_t pmi = (uint8_t) ue_dl.pmi[ri];
|
uint8_t pmi = (uint8_t) ue_dl.pmi[ri];
|
||||||
float sinr = ue_dl.sinr[ri][pmi];
|
float sinr_db = ue_dl.sinr[ri][pmi];
|
||||||
|
|
||||||
if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) {
|
if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) {
|
||||||
/* Compute RI, PMI and SINR */
|
/* Compute RI, PMI and SINR */
|
||||||
compute_ri(&ri, &pmi, &sinr);
|
compute_ri(&ri, &pmi, &sinr_db);
|
||||||
|
|
||||||
switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) {
|
switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) {
|
||||||
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30:
|
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30:
|
||||||
|
@ -919,18 +929,24 @@ void phch_worker::set_uci_aperiodic_cqi()
|
||||||
|
|
||||||
// TODO: implement subband CQI properly
|
// TODO: implement subband CQI properly
|
||||||
cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands
|
cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands
|
||||||
cqi_report.subband_hl.N = (cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0;
|
cqi_report.subband_hl.N = (cell.nof_prb > 7) ? (uint32_t) srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0;
|
||||||
|
|
||||||
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
int cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
||||||
|
if (cqi_len < 0) {
|
||||||
|
Error("Error packing CQI value (Aperiodic reporting mode RM31).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uci_data.uci_cqi_len = (uint32_t) cqi_len;
|
||||||
|
|
||||||
char cqi_str[64] = {0};
|
char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = {0};
|
||||||
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 64);
|
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
|
||||||
|
|
||||||
Info("PUSCH: Aperiodic CQI=%s, SNR=%.1f dB, for %d subbands\n", cqi_str, phy->avg_snr_db, cqi_report.subband_hl.N);
|
/* Set RI = 1 */
|
||||||
|
uci_data.uci_ri = ri;
|
||||||
|
uci_data.uci_ri_len = 1;
|
||||||
|
|
||||||
/* Fake RI = 1 */
|
Info("PUSCH: Aperiodic RM30 ri%s, CQI=%s, SNR=%.1f dB, for %d subbands\n",
|
||||||
uci_data.uci_ri = 0;
|
(uci_data.uci_ri == 0)?"=1":"~1", cqi_str, phy->avg_snr_db, cqi_report.subband_hl.N);
|
||||||
uci_data.uci_ri_len = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31:
|
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31:
|
||||||
|
@ -946,11 +962,6 @@ void phch_worker::set_uci_aperiodic_cqi()
|
||||||
other transmission modes they are reported conditioned on rank 1.
|
other transmission modes they are reported conditioned on rank 1.
|
||||||
*/
|
*/
|
||||||
if (rnti_is_set) {
|
if (rnti_is_set) {
|
||||||
/* Select RI, PMI and SINR */
|
|
||||||
uint32_t ri = ue_dl.ri; // Select RI (0: 1 layer, 1: 2 layer, otherwise: not implemented)
|
|
||||||
uint32_t pmi = ue_dl.pmi[ri]; // Select PMI
|
|
||||||
float sinr_db = 10 * log10(ue_dl.sinr[ri][pmi]);
|
|
||||||
|
|
||||||
/* Fill CQI Report */
|
/* Fill CQI Report */
|
||||||
srslte_cqi_value_t cqi_report = {0};
|
srslte_cqi_value_t cqi_report = {0};
|
||||||
cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
|
cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
|
||||||
|
@ -971,17 +982,24 @@ void phch_worker::set_uci_aperiodic_cqi()
|
||||||
// TODO: implement subband CQI properly
|
// TODO: implement subband CQI properly
|
||||||
cqi_report.subband_hl.N = (uint32_t) ((cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0);
|
cqi_report.subband_hl.N = (uint32_t) ((cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0);
|
||||||
|
|
||||||
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
int cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
|
||||||
|
if (cqi_len < 0) {
|
||||||
|
Error("Error packing CQI value (Aperiodic reporting mode RM31).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uci_data.uci_cqi_len = (uint32_t) cqi_len;
|
||||||
|
uci_data.uci_ri_len = 1;
|
||||||
|
uci_data.uci_ri = ri;
|
||||||
|
|
||||||
char cqi_str[64] = {0};
|
char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = {0};
|
||||||
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 64);
|
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
|
||||||
|
|
||||||
if (cqi_report.subband_hl.rank_is_not_one) {
|
if (cqi_report.subband_hl.rank_is_not_one) {
|
||||||
Info("PUSCH: Aperiodic ri~1, CQI=%02d/%02d, SINR=%2.1f/%2.1fdB, pmi=%d for %d subbands\n",
|
Info("PUSCH: Aperiodic RM31 ri~1, CQI=%02d/%02d, SINR=%2.1f/%2.1fdB, pmi=%d for %d subbands\n",
|
||||||
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1,
|
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1,
|
||||||
sinr_db, sinr_db, pmi, cqi_report.subband_hl.N);
|
sinr_db, sinr_db, pmi, cqi_report.subband_hl.N);
|
||||||
} else {
|
} else {
|
||||||
Info("PUSCH: Aperiodic ri=1, CQI=%02d, SINR=%2.1f, pmi=%d for %d subbands\n",
|
Info("PUSCH: Aperiodic RM31 ri=1, CQI=%02d, SINR=%2.1f, pmi=%d for %d subbands\n",
|
||||||
cqi_report.subband_hl.wideband_cqi_cw0,
|
cqi_report.subband_hl.wideband_cqi_cw0,
|
||||||
sinr_db, pmi, cqi_report.subband_hl.N);
|
sinr_db, pmi, cqi_report.subband_hl.N);
|
||||||
}
|
}
|
||||||
|
@ -1049,8 +1067,8 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui
|
||||||
snprintf(timestr, 64, ", tot_time=%4d us", (int) logtime_start[0].tv_usec);
|
snprintf(timestr, 64, ", tot_time=%4d us", (int) logtime_start[0].tv_usec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char cqi_str[32] = "";
|
char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = "";
|
||||||
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 32);
|
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
|
||||||
|
|
||||||
uint8_t dummy[2] = {0,0};
|
uint8_t dummy[2] = {0,0};
|
||||||
log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n",
|
log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n",
|
||||||
|
@ -1103,8 +1121,8 @@ void phch_worker::encode_pucch()
|
||||||
float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len);
|
float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len);
|
||||||
float gain = set_power(tx_power);
|
float gain = set_power(tx_power);
|
||||||
|
|
||||||
char str_cqi[32] = "";
|
char str_cqi[SRSLTE_CQI_STR_MAX_CHAR] = "";
|
||||||
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, str_cqi, 32);
|
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, str_cqi, SRSLTE_CQI_STR_MAX_CHAR);
|
||||||
|
|
||||||
Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n",
|
Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n",
|
||||||
(tti + 4) % 10240,
|
(tti + 4) % 10240,
|
||||||
|
@ -1141,10 +1159,7 @@ void phch_worker::encode_srs()
|
||||||
|
|
||||||
float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss);
|
float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss);
|
||||||
float gain = set_power(tx_power);
|
float gain = set_power(tx_power);
|
||||||
uint32_t fi = srslte_vec_max_fi((float*) signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
|
||||||
float *f = (float*) signal_buffer;
|
|
||||||
Info("SRS: power=%.2f dBm, tti_tx=%d%s\n", tx_power, TTI_TX(tti), timestr);
|
Info("SRS: power=%.2f dBm, tti_tx=%d%s\n", tx_power, TTI_TX(tti), timestr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void phch_worker::enable_pregen_signals(bool enabled)
|
void phch_worker::enable_pregen_signals(bool enabled)
|
||||||
|
@ -1325,42 +1340,50 @@ void phch_worker::update_measurements()
|
||||||
{
|
{
|
||||||
float snr_ema_coeff = phy->args->snr_ema_coeff;
|
float snr_ema_coeff = phy->args->snr_ema_coeff;
|
||||||
if (chest_done) {
|
if (chest_done) {
|
||||||
/* Compute ADC/RX gain offset every ~10s */
|
|
||||||
if (tti== 0 || phy->rx_gain_offset == 0) {
|
/* Only worker 0 reads the RSSI sensor every ~1-nof_cores s */
|
||||||
float rx_gain_offset = 0;
|
if (get_id() == 0) {
|
||||||
if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) {
|
if (rssi_read_cnt) {
|
||||||
float rssi_all_signal = 30+10*log10(srslte_vec_avg_power_cf(signal_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))));
|
if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) {
|
||||||
rx_gain_offset = 30+rssi_all_signal-phy->get_radio()->get_rssi();
|
phy->last_radio_rssi = phy->get_radio()->get_rssi();
|
||||||
} else {
|
phy->rx_gain_offset = phy->avg_rssi_dbm - phy->last_radio_rssi + 30;
|
||||||
rx_gain_offset = phy->get_radio()->get_rx_gain();
|
} else {
|
||||||
|
phy->rx_gain_offset = phy->get_radio()->get_rx_gain();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (phy->rx_gain_offset) {
|
rssi_read_cnt++;
|
||||||
phy->rx_gain_offset = SRSLTE_VEC_EMA(rx_gain_offset, phy->rx_gain_offset, 0.5);
|
if (rssi_read_cnt == 1000) {
|
||||||
} else {
|
rssi_read_cnt = 0;
|
||||||
phy->rx_gain_offset = rx_gain_offset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Average RSRQ
|
// Average RSRQ
|
||||||
float rsrq_db = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest));
|
float rsrq_db = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest));
|
||||||
if (isnormal(rsrq_db)) {
|
if (isnormal(rsrq_db)) {
|
||||||
phy->avg_rsrq_db = SRSLTE_VEC_EMA(rsrq_db, phy->avg_rsrq_db, snr_ema_coeff);
|
if (!phy->avg_rsrq_db) {
|
||||||
|
phy->avg_rsrq_db = SRSLTE_VEC_EMA(rsrq_db, phy->avg_rsrq_db, snr_ema_coeff);
|
||||||
|
} else {
|
||||||
|
phy->avg_rsrq_db = rsrq_db;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Average RSRP
|
// Average RSRP
|
||||||
float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest);
|
float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest);
|
||||||
if (isnormal(rsrp_lin)) {
|
if (isnormal(rsrp_lin)) {
|
||||||
phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff);
|
if (!phy->avg_rsrp) {
|
||||||
|
phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff);
|
||||||
|
} else {
|
||||||
|
phy->avg_rsrp = rsrp_lin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Correct absolute power measurements by RX gain offset */
|
/* Correct absolute power measurements by RX gain offset */
|
||||||
float rsrp_dbm = 10*log10(rsrp_lin) + 30 - phy->rx_gain_offset;
|
float rsrp_dbm = 10*log10(rsrp_lin) + 30 - phy->rx_gain_offset;
|
||||||
float rssi_db = 10*log10(srslte_chest_dl_get_rssi(&ue_dl.chest)) + 30 - phy->rx_gain_offset;
|
|
||||||
|
|
||||||
// Serving cell measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC
|
// Serving cell measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC
|
||||||
if (isnormal(rsrp_dbm)) {
|
if (isnormal(rsrp_dbm)) {
|
||||||
if (!phy->avg_rsrp_dbm) {
|
if (!phy->avg_rsrp_dbm) {
|
||||||
phy->avg_rsrp_dbm= rsrp_dbm;
|
phy->avg_rsrp_dbm = rsrp_dbm;
|
||||||
} else {
|
} else {
|
||||||
phy->avg_rsrp_dbm = SRSLTE_VEC_EMA(rsrp_dbm, phy->avg_rsrp_dbm, snr_ema_coeff);
|
phy->avg_rsrp_dbm = SRSLTE_VEC_EMA(rsrp_dbm, phy->avg_rsrp_dbm, snr_ema_coeff);
|
||||||
}
|
}
|
||||||
|
@ -1390,7 +1413,7 @@ void phch_worker::update_measurements()
|
||||||
dl_metrics.n = phy->avg_noise;
|
dl_metrics.n = phy->avg_noise;
|
||||||
dl_metrics.rsrp = phy->avg_rsrp_dbm;
|
dl_metrics.rsrp = phy->avg_rsrp_dbm;
|
||||||
dl_metrics.rsrq = phy->avg_rsrq_db;
|
dl_metrics.rsrq = phy->avg_rsrq_db;
|
||||||
dl_metrics.rssi = rssi_db;
|
dl_metrics.rssi = phy->avg_rssi_dbm;
|
||||||
dl_metrics.pathloss = phy->pathloss;
|
dl_metrics.pathloss = phy->pathloss;
|
||||||
dl_metrics.sinr = phy->avg_snr_db;
|
dl_metrics.sinr = phy->avg_snr_db;
|
||||||
dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch);
|
dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch);
|
||||||
|
|
|
@ -193,9 +193,9 @@ void nas::notify_connection_setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
|
void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
|
||||||
uint8 pd;
|
uint8 pd = 0;
|
||||||
uint8 msg_type;
|
uint8 msg_type = 0;
|
||||||
uint8 sec_hdr_type;
|
uint8 sec_hdr_type = 0;
|
||||||
bool mac_valid = false;
|
bool mac_valid = false;
|
||||||
|
|
||||||
nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str());
|
nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str());
|
||||||
|
@ -216,7 +216,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
|
||||||
case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT:
|
case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n",msg_type);
|
nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type);
|
||||||
pool->deallocate(pdu);
|
pool->deallocate(pdu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srsue::ma
|
||||||
memcpy(&common.pusch_cnfg, &sib2->rr_config_common_sib.pusch_cnfg, sizeof(LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT));
|
memcpy(&common.pusch_cnfg, &sib2->rr_config_common_sib.pusch_cnfg, sizeof(LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT));
|
||||||
memcpy(&common.pucch_cnfg, &sib2->rr_config_common_sib.pucch_cnfg, sizeof(LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT));
|
memcpy(&common.pucch_cnfg, &sib2->rr_config_common_sib.pucch_cnfg, sizeof(LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT));
|
||||||
memcpy(&common.ul_pwr_ctrl, &sib2->rr_config_common_sib.ul_pwr_ctrl, sizeof(LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT));
|
memcpy(&common.ul_pwr_ctrl, &sib2->rr_config_common_sib.ul_pwr_ctrl, sizeof(LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT));
|
||||||
memcpy(&common.prach_cnfg, &sib2->rr_config_common_sib.prach_cnfg, sizeof(LIBLTE_RRC_PRACH_CONFIG_STRUCT));
|
memcpy(&common.prach_cnfg, &sib2->rr_config_common_sib.prach_cnfg, sizeof(LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT));
|
||||||
if (sib2->rr_config_common_sib.srs_ul_cnfg.present) {
|
if (sib2->rr_config_common_sib.srs_ul_cnfg.present) {
|
||||||
memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT));
|
memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT));
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue