diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 50fb0807e..4bf8dc2e0 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -599,7 +599,7 @@ int main(int argc, char **argv) { } #ifndef DISABLE_RF - if (prog_args.rf_gain < 0) { + if (prog_args.rf_gain < 0 && !prog_args.input_file_name) { srslte_rf_info_t *rf_info = srslte_rf_get_info(&rf); srslte_ue_sync_start_agc(&ue_sync, srslte_rf_set_rx_gain_th_wrapper_, diff --git a/lib/include/srslte/phy/phch/cqi.h b/lib/include/srslte/phy/phch/cqi.h index 4363ccaa7..481fce494 100644 --- a/lib/include/srslte/phy/phch/cqi.h +++ b/lib/include/srslte/phy/phch/cqi.h @@ -43,7 +43,7 @@ #define SRSLTE_CQI_MAX_BITS 64 #define SRSLTE_DIF_CQI_MAX_BITS 3 #define SRSLTE_PMI_MAX_BITS 4 -#define SRSLTE_CQI_STR_MAX_CHAR 32 +#define SRSLTE_CQI_STR_MAX_CHAR 64 typedef struct { bool configured; @@ -150,6 +150,9 @@ SRSLTE_API int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg SRSLTE_API int srslte_cqi_value_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_value_t *value); +SRSLTE_API int srslte_cqi_value_tostring(srslte_cqi_value_t *value, char *buff, uint32_t buff_len); + + SRSLTE_API int srslte_cqi_hl_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_hl_subband_t *msg); diff --git a/lib/include/srslte/radio/radio_multi.h b/lib/include/srslte/radio/radio_multi.h index efb1e31b6..097fe55e2 100644 --- a/lib/include/srslte/radio/radio_multi.h +++ b/lib/include/srslte/radio/radio_multi.h @@ -45,7 +45,8 @@ namespace srslte { class radio_multi : public radio { public: - + radio_multi() {} + ~radio_multi() {} bool init_multi(uint32_t nof_rx_antennas, char *args = NULL, char *devname = NULL); bool rx_now(cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t *rxd_time); }; diff --git a/lib/src/asn1/liblte_rrc.cc b/lib/src/asn1/liblte_rrc.cc index eb264a0ec..488a23e51 100644 --- a/lib/src/asn1/liblte_rrc.cc +++ b/lib/src/asn1/liblte_rrc.cc @@ -1384,11 +1384,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ue_eutra_capability_ie(LIBLTE_RRC_UE_EUTRA_CAP LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(ue_eutra_capability != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Option indicator - featureGroupIndicators liblte_value_2_bits(ue_eutra_capability->feature_group_indicator_present, &msg_ptr, 1); @@ -10548,11 +10550,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ul_information_transfer_msg(LIBLTE_RRC_UL_INFO LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(ul_info_transfer != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -10586,11 +10590,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ul_information_transfer_msg(LIBLTE_BIT_MSG_S LIBLTE_RRC_UL_INFORMATION_TRANSFER_STRUCT *ul_info_transfer) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && ul_info_transfer != NULL) { + msg_ptr = msg->msg; + // Extension choice bool ext = liblte_bits_2_value(&msg_ptr, 1); @@ -10598,7 +10604,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ul_information_transfer_msg(LIBLTE_BIT_MSG_S liblte_bits_2_value(&msg_ptr, 2); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Dedicated info type choice ul_info_transfer->dedicated_info_type = (LIBLTE_RRC_UL_INFORMATION_TRANSFER_TYPE_ENUM)liblte_bits_2_value(&msg_ptr, 2); @@ -10652,11 +10658,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ue_information_request_msg(LIBLTE_RRC_UE_INFOR LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(ue_info_req != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(ue_info_req->rrc_transaction_id, &msg_ptr); @@ -10688,11 +10696,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ue_information_request_msg(LIBLTE_BIT_MSG_ST LIBLTE_RRC_UE_INFORMATION_REQUEST_STRUCT *ue_info_req) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && ue_info_req != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &ue_info_req->rrc_transaction_id); @@ -10704,7 +10714,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ue_information_request_msg(LIBLTE_BIT_MSG_ST liblte_bits_2_value(&msg_ptr, 2); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // RACH report required ue_info_req->rach_report_req = liblte_bits_2_value(&msg_ptr, 1); @@ -10732,12 +10742,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ue_capability_information_msg(LIBLTE_RRC_UE_CA LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; if(ue_capability_info != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(ue_capability_info->rrc_transaction_id, &msg_ptr); @@ -10797,12 +10809,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ue_capability_information_msg(LIBLTE_BIT_MSG LIBLTE_RRC_UE_CAPABILITY_INFORMATION_STRUCT *ue_capability_info) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; if(msg != NULL && ue_capability_info != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &ue_capability_info->rrc_transaction_id); @@ -10814,7 +10828,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ue_capability_information_msg(LIBLTE_BIT_MSG liblte_bits_2_value(&msg_ptr, 3); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); ue_capability_info->N_ue_caps = liblte_bits_2_value(&msg_ptr, 4); for(i=0; iN_ue_caps; i++) @@ -10861,12 +10875,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ue_capability_enquiry_msg(LIBLTE_RRC_UE_CAPABI LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; if(ue_cap_enquiry != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(ue_cap_enquiry->rrc_transaction_id, &msg_ptr); @@ -10899,12 +10915,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ue_capability_enquiry_msg(LIBLTE_BIT_MSG_STR LIBLTE_RRC_UE_CAPABILITY_ENQUIRY_STRUCT *ue_cap_enquiry) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; if(msg != NULL && ue_cap_enquiry != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &ue_cap_enquiry->rrc_transaction_id); @@ -10916,7 +10934,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ue_capability_enquiry_msg(LIBLTE_BIT_MSG_STR liblte_bits_2_value(&msg_ptr, 2); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); ue_cap_enquiry->N_ue_cap_reqs = liblte_bits_2_value(&msg_ptr, 3) + 1; for(i=0; iN_ue_cap_reqs; i++) @@ -10946,7 +10964,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_sys_info_block_type_1_msg(LIBLTE_RRC_SYS_INFO_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; uint32 j; uint8 non_crit_ext_opt = false; @@ -10957,6 +10975,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_sys_info_block_type_1_msg(LIBLTE_RRC_SYS_INFO_ if(sib1 != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Optional indicators liblte_value_2_bits(sib1->p_max_present, &msg_ptr, 1); liblte_value_2_bits(sib1->tdd, &msg_ptr, 1); @@ -11038,7 +11058,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_block_type_1_msg(LIBLTE_BIT_MSG_STR uint32 *N_bits_used) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; uint32 j; bool tdd_config_opt; @@ -11051,6 +11071,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_block_type_1_msg(LIBLTE_BIT_MSG_STR sib1 != NULL && N_bits_used != NULL) { + msg_ptr = msg->msg; // Optional indicators sib1->p_max_present = liblte_bits_2_value(&msg_ptr, 1); @@ -11152,7 +11173,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_sys_info_msg(LIBLTE_RRC_SYS_INFO_MSG_STRUCT *s LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 *length_ptr; uint32 length; uint32 pad_bits; @@ -11161,6 +11182,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_sys_info_msg(LIBLTE_RRC_SYS_INFO_MSG_STRUCT *s if(sibs != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Critical extensions choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -11275,7 +11298,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_msg(LIBLTE_BIT_MSG_STRUCT LIBLTE_RRC_SYS_INFO_MSG_STRUCT *sibs) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 *head_ptr; uint32 i; uint32 length_determinant_octets; @@ -11284,6 +11307,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_sys_info_msg(LIBLTE_BIT_MSG_STRUCT if(msg != NULL && sibs != NULL) { + msg_ptr = msg->msg; + // Critical extensions choice if(0 == liblte_bits_2_value(&msg_ptr, 1)) { @@ -11398,11 +11423,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_security_mode_failure_msg(LIBLTE_RRC_SECURITY_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(security_mode_failure != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(security_mode_failure->rrc_transaction_id, &msg_ptr); @@ -11425,11 +11452,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_security_mode_failure_msg(LIBLTE_BIT_MSG_STR LIBLTE_RRC_SECURITY_MODE_FAILURE_STRUCT *security_mode_failure) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && security_mode_failure != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &security_mode_failure->rrc_transaction_id); @@ -11438,7 +11467,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_security_mode_failure_msg(LIBLTE_BIT_MSG_STR bool ext = liblte_bits_2_value(&msg_ptr, 1); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -11460,11 +11489,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_security_mode_complete_msg(LIBLTE_RRC_SECURITY LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(security_mode_complete != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(security_mode_complete->rrc_transaction_id, &msg_ptr); @@ -11487,11 +11518,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_security_mode_complete_msg(LIBLTE_BIT_MSG_ST LIBLTE_RRC_SECURITY_MODE_COMPLETE_STRUCT *security_mode_complete) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && security_mode_complete != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &security_mode_complete->rrc_transaction_id); @@ -11500,7 +11533,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_security_mode_complete_msg(LIBLTE_BIT_MSG_ST bool ext = liblte_bits_2_value(&msg_ptr, 1); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -11521,11 +11554,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_security_mode_command_msg(LIBLTE_RRC_SECURITY_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(security_mode_cmd != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(security_mode_cmd->rrc_transaction_id, &msg_ptr); @@ -11558,11 +11593,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_security_mode_command_msg(LIBLTE_BIT_MSG_STR LIBLTE_RRC_SECURITY_MODE_COMMAND_STRUCT *security_mode_cmd) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; - if(msg_ptr != NULL && + if(msg != NULL && security_mode_cmd != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &security_mode_cmd->rrc_transaction_id); @@ -11574,7 +11611,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_security_mode_command_msg(LIBLTE_BIT_MSG_STR liblte_bits_2_value(&msg_ptr, 2); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Extension indicator bool ext2 = liblte_bits_2_value(&msg_ptr, 1); @@ -11605,11 +11642,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_setup_complete_msg(LIBLTE_RRC_C LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_setup_complete != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_setup_complete->rrc_transaction_id, &msg_ptr); @@ -11662,11 +11701,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_setup_complete_msg(LIBLTE_BIT LIBLTE_RRC_CONNECTION_SETUP_COMPLETE_STRUCT *con_setup_complete) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_setup_complete != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_setup_complete->rrc_transaction_id); @@ -11679,7 +11720,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_setup_complete_msg(LIBLTE_BIT // Optional indicators con_setup_complete->registered_mme_present = liblte_bits_2_value(&msg_ptr, 1); - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Selected PLMN identity con_setup_complete->selected_plmn_id = liblte_bits_2_value(&msg_ptr, 3) + 1; @@ -11726,11 +11767,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_setup_msg(LIBLTE_RRC_CONNECTION LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_setup != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_setup->rrc_transaction_id, &msg_ptr); @@ -11759,11 +11802,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_setup_msg(LIBLTE_BIT_MSG_STRU LIBLTE_RRC_CONNECTION_SETUP_STRUCT *con_setup) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_setup != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_setup->rrc_transaction_id); @@ -11775,7 +11820,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_setup_msg(LIBLTE_BIT_MSG_STRU liblte_bits_2_value(&msg_ptr, 3); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Radio Resource Config Dedicated liblte_rrc_unpack_rr_config_dedicated_ie(&msg_ptr, &con_setup->rr_cnfg); @@ -11800,12 +11845,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_request_msg(LIBLTE_RRC_CONNECTI LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(con_req != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(ext, &msg_ptr, 1); @@ -11843,11 +11890,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_request_msg(LIBLTE_BIT_MSG_ST LIBLTE_RRC_CONNECTION_REQUEST_STRUCT *con_req) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_req != NULL) { + msg_ptr = msg->msg; + // Extension Choice bool ext = liblte_bits_2_value(&msg_ptr, 1); @@ -11886,11 +11935,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_release_msg(LIBLTE_RRC_CONNECTI LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_release != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_release->rrc_transaction_id, &msg_ptr); @@ -11921,11 +11972,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_release_msg(LIBLTE_BIT_MSG_ST LIBLTE_RRC_CONNECTION_RELEASE_STRUCT *con_release) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_release != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_release->rrc_transaction_id); @@ -11937,9 +11990,9 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_release_msg(LIBLTE_BIT_MSG_ST liblte_bits_2_value(&msg_ptr, 2); // Optional indicators - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Release cause con_release->release_cause = (LIBLTE_RRC_RELEASE_CAUSE_ENUM)liblte_bits_2_value(&msg_ptr, 2); @@ -11963,11 +12016,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reject_msg(LIBLTE_RRC_CONNECTIO LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_rej != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -11992,11 +12047,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reject_msg(LIBLTE_BIT_MSG_STR LIBLTE_RRC_CONNECTION_REJECT_STRUCT *con_rej) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_rej != NULL) { + msg_ptr = msg->msg; + // Extension choice bool ext = liblte_bits_2_value(&msg_ptr, 1); @@ -12004,7 +12061,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reject_msg(LIBLTE_BIT_MSG_STR liblte_bits_2_value(&msg_ptr, 2); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Wait Time con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4) + 1; @@ -12029,12 +12086,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reestablishment_request_msg(LIB LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(con_reest_req != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(ext, &msg_ptr, 1); @@ -12064,11 +12123,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reestablishment_request_msg(L LIBLTE_RRC_CONNECTION_REESTABLISHMENT_REQUEST_STRUCT *con_reest_req) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_reest_req != NULL) { + msg_ptr = msg->msg; + // Extension Choice bool ext = liblte_bits_2_value(&msg_ptr, 1); @@ -12100,11 +12161,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reestablishment_reject_msg(LIBL LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_reest_rej != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -12123,16 +12186,18 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reestablishment_reject_msg(LI LIBLTE_RRC_CONNECTION_REESTABLISHMENT_REJECT_STRUCT *con_reest_rej) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_reest_rej != NULL) { + msg_ptr = msg->msg; + // Extension choice bool ext = liblte_bits_2_value(&msg_ptr, 1); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -12154,11 +12219,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reestablishment_complete_msg(LI LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_reest_complete != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_reest_complete->rrc_transaction_id, &msg_ptr); @@ -12181,11 +12248,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reestablishment_complete_msg( LIBLTE_RRC_CONNECTION_REESTABLISHMENT_COMPLETE_STRUCT *con_reest_complete) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_reest_complete != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_reest_complete->rrc_transaction_id); @@ -12194,7 +12263,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reestablishment_complete_msg( bool ext = liblte_bits_2_value(&msg_ptr, 1); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -12215,11 +12284,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reestablishment_msg(LIBLTE_RRC_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_reest != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_reest->rrc_transaction_id, &msg_ptr); @@ -12251,11 +12322,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reestablishment_msg(LIBLTE_BI LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *con_reest) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_reest != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_reest->rrc_transaction_id); @@ -12267,7 +12340,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reestablishment_msg(LIBLTE_BI liblte_bits_2_value(&msg_ptr, 3); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Radio Resource Config Dedicated liblte_rrc_unpack_rr_config_dedicated_ie(&msg_ptr, &con_reest->rr_cnfg); @@ -12295,11 +12368,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reconfiguration_complete_msg(LI LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(con_reconfig_complete != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_reconfig_complete->rrc_transaction_id, &msg_ptr); @@ -12322,11 +12397,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reconfiguration_complete_msg( LIBLTE_RRC_CONNECTION_RECONFIGURATION_COMPLETE_STRUCT *con_reconfig_complete) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && con_reconfig_complete != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_reconfig_complete->rrc_transaction_id); @@ -12335,7 +12412,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reconfiguration_complete_msg( bool ext = liblte_bits_2_value(&msg_ptr, 1); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -12356,12 +12433,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reconfiguration_msg(LIBLTE_RRC_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; if(con_reconfig != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(con_reconfig->rrc_transaction_id, &msg_ptr); @@ -12461,13 +12540,15 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reconfiguration_msg(LIBLTE_BI LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *con_reconfig) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; bool ded_info_nas_list_present; if(msg != NULL && con_reconfig != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &con_reconfig->rrc_transaction_id); @@ -12483,7 +12564,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reconfiguration_msg(LIBLTE_BI ded_info_nas_list_present = liblte_bits_2_value(&msg_ptr, 1); con_reconfig->rr_cnfg_ded_present = liblte_bits_2_value(&msg_ptr, 1); con_reconfig->sec_cnfg_ho_present = liblte_bits_2_value(&msg_ptr, 1); - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Meas Config if(con_reconfig->meas_cnfg_present) @@ -12574,11 +12655,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rn_reconfiguration_complete_msg(LIBLTE_RRC_RN_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(rn_reconfig_complete != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(rn_reconfig_complete->rrc_transaction_id, &msg_ptr); @@ -12605,11 +12688,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rn_reconfiguration_complete_msg(LIBLTE_BIT_M LIBLTE_RRC_RN_RECONFIGURATION_COMPLETE_STRUCT *rn_reconfig_complete) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && rn_reconfig_complete != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &rn_reconfig_complete->rrc_transaction_id); @@ -12621,8 +12706,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rn_reconfiguration_complete_msg(LIBLTE_BIT_M liblte_bits_2_value(&msg_ptr, 2); // Optional indicators - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -12655,11 +12740,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_proximity_indication_msg(LIBLTE_RRC_PROXIMITY_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(proximity_ind != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -12700,11 +12787,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_proximity_indication_msg(LIBLTE_BIT_MSG_STRU LIBLTE_RRC_PROXIMITY_INDICATION_STRUCT *proximity_ind) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && proximity_ind != NULL) { + msg_ptr = msg->msg; + // Extension choice bool ext = liblte_bits_2_value(&msg_ptr, 1); @@ -12712,13 +12801,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_proximity_indication_msg(LIBLTE_BIT_MSG_STRU liblte_bits_2_value(&msg_ptr, 2); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Proximity indication type proximity_ind->type = (LIBLTE_RRC_PROXIMITY_INDICATION_TYPE_ENUM)liblte_bits_2_value(&msg_ptr, 1); // Carrier frequency type extension indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); // Carrier frequency type proximity_ind->carrier_freq_type = (LIBLTE_RRC_PROXIMITY_INDICATION_CARRIER_FREQ_TYPE_ENUM)liblte_bits_2_value(&msg_ptr, 1); @@ -12752,13 +12841,15 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_paging_msg(LIBLTE_RRC_PAGING_STRUCT *page, LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; uint32 j; if(page != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Optional indicators if(page->paging_record_list_size != 0) { @@ -12850,7 +12941,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_paging_msg(LIBLTE_BIT_MSG_STRUCT *msg, LIBLTE_RRC_PAGING_STRUCT *page) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; uint32 j; uint8 paging_record_list_present; @@ -12858,6 +12949,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_paging_msg(LIBLTE_BIT_MSG_STRUCT *msg, if(msg != NULL && page != NULL) { + msg_ptr = msg->msg; + // Optional indicators paging_record_list_present = liblte_bits_2_value(&msg_ptr, 1); page->system_info_modification_present = liblte_bits_2_value(&msg_ptr, 1); @@ -13113,11 +13206,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_measurement_report_msg(LIBLTE_RRC_MEASUREMENT_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(meas_report != NULL && msg != NULL) { + msg_ptr = msg->msg; + //MeasurementReport liblte_value_2_bits(0, &msg_ptr, 1); //critical extensions liblte_value_2_bits(0, &msg_ptr, 3); //c1 @@ -13157,11 +13252,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_measurement_report_msg(LIBLTE_BIT_MSG_STRUCT LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *meas_report) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && meas_report != NULL) { + msg_ptr = msg->msg; + //MeasurementReport bool crit_ext = liblte_bits_2_value(&msg_ptr, 1); //critical extensions liblte_bits_2_value(&msg_ptr, 3); //c1 @@ -13212,12 +13309,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_mbsfn_area_configuration_r9_msg(LIBLTE_RRC_MBS LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; if(mbsfn_area_cnfg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Non-critical extension liblte_value_2_bits(0, &msg_ptr, 1); @@ -13248,13 +13347,15 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_mbsfn_area_configuration_r9_msg(LIBLTE_BIT_M LIBLTE_RRC_MBSFN_AREA_CONFIGURATION_R9_STRUCT *mbsfn_area_cnfg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 i; bool ext; if(msg != NULL && mbsfn_area_cnfg != NULL) { + msg_ptr = msg->msg; + // Non-critical extension ext = liblte_bits_2_value(&msg_ptr, 1); liblte_rrc_warning_not_handled(ext, __func__); @@ -13324,11 +13425,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_dl_information_transfer_msg(LIBLTE_RRC_DL_INFO LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(dl_info_transfer != NULL && msg != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_pack_rrc_transaction_identifier_ie(dl_info_transfer->rrc_transaction_id, &msg_ptr); @@ -13366,11 +13469,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_dl_information_transfer_msg(LIBLTE_BIT_MSG_S LIBLTE_RRC_DL_INFORMATION_TRANSFER_STRUCT *dl_info_transfer) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && dl_info_transfer != NULL) { + msg_ptr = msg->msg; + // RRC Transaction ID liblte_rrc_unpack_rrc_transaction_identifier_ie(&msg_ptr, &dl_info_transfer->rrc_transaction_id); @@ -13427,11 +13532,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_csfb_parameters_request_cdma2000_msg(LIBLTE_RR LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(csfb_params_req_cdma2000 != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -13450,16 +13557,18 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_csfb_parameters_request_cdma2000_msg(LIBLTE_ LIBLTE_RRC_CSFB_PARAMETERS_REQUEST_CDMA2000_STRUCT *csfb_params_req_cdma2000) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && csfb_params_req_cdma2000 != NULL) { + msg_ptr = msg->msg; + // Extension choice bool ext = liblte_bits_2_value(&msg_ptr, 1); // Optional indicator - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); @@ -13503,11 +13612,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_bcch_bch_msg(LIBLTE_RRC_MIB_STRUCT *mib, LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(mib != NULL && msg != NULL) { + msg_ptr = msg->msg; + // DL Bandwidth liblte_value_2_bits(mib->dl_bw, &msg_ptr, 3); @@ -13532,11 +13643,13 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_bcch_bch_msg(LIBLTE_BIT_MSG_STRUCT *msg, LIBLTE_RRC_MIB_STRUCT *mib) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; if(msg != NULL && mib != NULL) { + msg_ptr = msg->msg; + // DL Bandwidth mib->dl_bw = (LIBLTE_RRC_DL_BANDWIDTH_ENUM)liblte_bits_2_value(&msg_ptr, 3); @@ -13565,12 +13678,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_bcch_dlsch_msg(LIBLTE_RRC_BCCH_DLSCH_MSG_STRUC LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(bcch_dlsch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator liblte_value_2_bits(ext, &msg_ptr, 1); @@ -13612,13 +13727,15 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_bcch_dlsch_msg(LIBLTE_BIT_MSG_STRUCT LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT *bcch_dlsch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 N_bits_used; uint8 ext; if(msg != NULL && bcch_dlsch_msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator ext = liblte_bits_2_value(&msg_ptr, 1); @@ -13664,12 +13781,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_mcch_msg(LIBLTE_RRC_MCCH_MSG_STRUCT *mcch_msg, LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(mcch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // MCCH choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -13691,14 +13810,16 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_mcch_msg(LIBLTE_BIT_MSG_STRUCT *msg, LIBLTE_RRC_MCCH_MSG_STRUCT *mcch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 N_bits_used; if(msg != NULL && mcch_msg != NULL) { + msg_ptr = msg->msg; + // MCCH choice - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); if((msg->N_bits-(msg_ptr-msg->msg)) <= (LIBLTE_MAX_MSG_SIZE_BITS - 1)) { @@ -13724,12 +13845,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_pcch_msg(LIBLTE_RRC_PCCH_MSG_STRUCT *pcch_msg, LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(pcch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Paging choice liblte_value_2_bits(0, &msg_ptr, 1); @@ -13751,14 +13874,16 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_pcch_msg(LIBLTE_BIT_MSG_STRUCT *msg, LIBLTE_RRC_PCCH_MSG_STRUCT *pcch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint32 N_bits_used; if(msg != NULL && pcch_msg != NULL) { + msg_ptr = msg->msg; + // Paging choice - liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; + liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__); if((msg->N_bits-(msg_ptr-msg->msg)) <= (LIBLTE_MAX_MSG_SIZE_BITS - 1)) { @@ -13784,12 +13909,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_dl_ccch_msg(LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(dl_ccch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator liblte_value_2_bits(ext, &msg_ptr, 1); @@ -13827,12 +13954,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_dl_ccch_msg(LIBLTE_BIT_MSG_STRUCT *m LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ccch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext; if(msg != NULL && dl_ccch_msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator ext = liblte_bits_2_value(&msg_ptr, 1); @@ -13876,12 +14005,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_dl_dcch_msg(LIBLTE_RRC_DL_DCCH_MSG_STRUCT *dl_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(dl_dcch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator liblte_value_2_bits(ext, &msg_ptr, 1); @@ -13950,12 +14081,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_dl_dcch_msg(LIBLTE_BIT_MSG_STRUCT *m LIBLTE_RRC_DL_DCCH_MSG_STRUCT *dl_dcch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext; if(msg != NULL && dl_dcch_msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator ext = liblte_bits_2_value(&msg_ptr, 1); @@ -14029,12 +14162,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ul_ccch_msg(LIBLTE_RRC_UL_CCCH_MSG_STRUCT *ul_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(ul_ccch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator liblte_value_2_bits(ext, &msg_ptr, 1); @@ -14066,12 +14201,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ul_ccch_msg(LIBLTE_BIT_MSG_STRUCT *m LIBLTE_RRC_UL_CCCH_MSG_STRUCT *ul_ccch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext; if(msg != NULL && ul_ccch_msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator ext = liblte_bits_2_value(&msg_ptr, 1); @@ -14109,12 +14246,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ul_dcch_msg(LIBLTE_RRC_UL_DCCH_MSG_STRUCT *ul_ LIBLTE_BIT_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext = false; if(ul_dcch_msg != NULL && msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator liblte_value_2_bits(ext, &msg_ptr, 1); @@ -14186,12 +14325,14 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ul_dcch_msg(LIBLTE_BIT_MSG_STRUCT *m LIBLTE_RRC_UL_DCCH_MSG_STRUCT *ul_dcch_msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + uint8 *msg_ptr; uint8 ext; if(msg != NULL && ul_dcch_msg != NULL) { + msg_ptr = msg->msg; + // Extension indicator ext = liblte_bits_2_value(&msg_ptr, 1); diff --git a/lib/src/common/thread_pool.cc b/lib/src/common/thread_pool.cc index 6f4fa5d8b..17b539232 100644 --- a/lib/src/common/thread_pool.cc +++ b/lib/src/common/thread_pool.cc @@ -81,7 +81,6 @@ thread_pool::thread_pool(uint32_t max_workers_) : status(max_workers_), cvar(max_workers_), mutex(max_workers_) - { max_workers = max_workers_; for (uint32_t i=0;icell.nof_prb)/15/sqrt(q->ifft[0].symbol_sz); + float norm_factor = 0.05f / sqrt(q->cell.nof_prb); for (int i = 0; i < q->cell.nof_ports; i++) { srslte_ofdm_tx_sf(&q->ifft[i]); srslte_vec_sc_prod_cfc(q->ifft[i].out_buffer, norm_factor, q->ifft[i].out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); @@ -397,7 +397,7 @@ void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q) void srslte_enb_dl_gen_signal_mbsfn(srslte_enb_dl_t *q) { - float norm_factor = (float) sqrt(q->cell.nof_prb)/15/sqrt(q->ifft_mbsfn.symbol_sz); + float norm_factor = 0.05f / sqrt(q->cell.nof_prb); srslte_ofdm_tx_sf(&q->ifft_mbsfn); srslte_vec_sc_prod_cfc(q->ifft_mbsfn.out_buffer, norm_factor, q->ifft_mbsfn.out_buffer, (uint32_t) SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } @@ -416,7 +416,7 @@ int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, srslte_dci_format_t format, srslte_dci_location_t location, uint16_t rnti, uint32_t sf_idx) { - srslte_dci_msg_t dci_msg; + srslte_dci_msg_t dci_msg = {}; bool rnti_is_user = true; if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || (rnti >= SRSLTE_RARNTI_START && rnti <= SRSLTE_RARNTI_END)) { @@ -436,7 +436,7 @@ int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, srslte_ra_ul_dci_t *grant, srslte_dci_location_t location, uint16_t rnti, uint32_t sf_idx) { - srslte_dci_msg_t dci_msg; + srslte_dci_msg_t dci_msg = {}; srslte_dci_msg_pack_pusch(grant, &dci_msg, q->cell.nof_prb); if (srslte_pdcch_encode(&q->pdcch, &dci_msg, location, rnti, q->sf_symbols, sf_idx, q->cfi)) { diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index 683144439..7c945850a 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -234,6 +234,87 @@ int srslte_cqi_value_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_value_ return -1; } +/******************************************************* + * TO STRING FUNCTIONS * + *******************************************************/ + +static int srslte_cqi_format2_wideband_tostring(srslte_cqi_format2_wideband_t *msg, char *buff, uint32_t buff_len) { + int n = 0; + + n += snprintf(buff + n, buff_len - n, ", cqi=%d", msg->wideband_cqi); + + if (msg->pmi_present) { + if (msg->rank_is_not_one) { + n += snprintf(buff + n, buff_len - n, ", diff_cqi=%d", msg->spatial_diff_cqi); + } + n += snprintf(buff + n, buff_len - n, ", pmi=%d", msg->pmi); + } + + return n; +} + +static int srslte_cqi_format2_subband_tostring(srslte_cqi_format2_subband_t *msg, char *buff, uint32_t buff_len) { + int n = 0; + + n += snprintf(buff + n, buff_len - n, ", cqi=%d", msg->subband_cqi); + n += snprintf(buff + n, buff_len - n, ", label=%d", msg->subband_label); + + return n; +} + +static int srslte_cqi_ue_subband_tostring(srslte_cqi_ue_subband_t *msg, char *buff, uint32_t buff_len) { + int n = 0; + + n += snprintf(buff + n, buff_len - n, ", cqi=%d", msg->wideband_cqi); + n += snprintf(buff + n, buff_len - n, ", diff_cqi=%d", msg->subband_diff_cqi); + n += snprintf(buff + n, buff_len - n, ", L=%d", msg->L); + + return n; +} + +static int srslte_cqi_hl_subband_tostring(srslte_cqi_hl_subband_t *msg, char *buff, uint32_t buff_len) { + int n = 0; + + n += snprintf(buff + n, buff_len - n, ", cqi=%d", msg->wideband_cqi_cw0); + n += snprintf(buff + n, buff_len - n, ", diff=%d", msg->subband_diff_cqi_cw0); + + if (msg->rank_is_not_one) { + n += snprintf(buff + n, buff_len - n, ", cqi1=%d", msg->wideband_cqi_cw1); + n += snprintf(buff + n, buff_len - n, ", diff1=%d", msg->subband_diff_cqi_cw1); + } + + if (msg->pmi_present) { + n += snprintf(buff + n, buff_len - n, ", pmi=%d", msg->pmi); + } + + n += snprintf(buff + n, buff_len - n, ", N=%d", msg->N); + + return n; +} + +int srslte_cqi_value_tostring(srslte_cqi_value_t *value, char *buff, uint32_t buff_len) { + int ret = -1; + + switch (value->type) { + case SRSLTE_CQI_TYPE_WIDEBAND: + ret = srslte_cqi_format2_wideband_tostring(&value->wideband, buff, buff_len); + break; + case SRSLTE_CQI_TYPE_SUBBAND: + ret = srslte_cqi_format2_subband_tostring(&value->subband, buff, buff_len); + break; + case SRSLTE_CQI_TYPE_SUBBAND_UE: + ret = srslte_cqi_ue_subband_tostring(&value->subband_ue, buff, buff_len); + break; + case SRSLTE_CQI_TYPE_SUBBAND_HL: + ret = srslte_cqi_hl_subband_tostring(&value->subband_hl, buff, buff_len); + break; + default: + /* Do nothing */; + } + + return ret; +} + int srslte_cqi_size(srslte_cqi_value_t *value) { int size = 0; diff --git a/lib/src/phy/rf/rf_helper.h b/lib/src/phy/rf/rf_helper.h new file mode 100644 index 000000000..7cc721df8 --- /dev/null +++ b/lib/src/phy/rf/rf_helper.h @@ -0,0 +1,52 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \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 Affero 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 Affero General Public License for more details. + * + * A copy of the GNU Affero 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/. + * + */ + +// A bunch of helper functions to process device arguments + + +#define REMOVE_SUBSTRING_WITHCOMAS(S, TOREMOVE) \ + remove_substring(S, TOREMOVE ",");\ + remove_substring(S, TOREMOVE ", ");\ + remove_substring(S, "," TOREMOVE);\ + remove_substring(S, ", " TOREMOVE);\ + remove_substring(S, TOREMOVE) + +static void remove_substring(char *s,const char *toremove) { + while((s=strstr(s,toremove))) { + memmove(s,s+strlen(toremove),1+strlen(s+strlen(toremove))); + } +} + +static void copy_subdev_string(char *dst, char *src) { + int n = 0; + size_t len = strlen(src); + /* Copy until end of string or comma */ + while (n < len && src[n] != '\0' && src[n] != ',') { + dst[n] = src[n]; + n++; + } + dst[n] = '\0'; +} \ No newline at end of file diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 15854682f..1e939061d 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -32,21 +32,42 @@ #include "srslte/srslte.h" #include "rf_soapy_imp.h" -#include "srslte/phy/rf/rf.h" +#include "rf_helper.h" #include #include +#include +#include +#include + +#define USE_TX_MTU 0 +#define SET_RF_BW 1 + +#define PRINT_RX_STATS 0 +#define PRINT_TX_STATS 0 + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) typedef struct { - char *devname; - SoapySDRKwargs args; - SoapySDRDevice *device; - SoapySDRRange *ranges; - SoapySDRStream *rxStream; - SoapySDRStream *txStream; - bool tx_stream_active; - bool rx_stream_active; - srslte_rf_info_t info; + char *devname; + SoapySDRKwargs args; + SoapySDRDevice *device; + SoapySDRRange *ranges; + SoapySDRStream *rxStream; + SoapySDRStream *txStream; + bool tx_stream_active; + bool rx_stream_active; + srslte_rf_info_t info; + double tx_rate; + size_t rx_mtu, tx_mtu; + + uint32_t num_time_errors; + uint32_t num_lates; + uint32_t num_overflows; + uint32_t num_underflows; + uint32_t num_other_errors; + uint32_t num_stream_curruption; } rf_soapy_handler_t; @@ -61,31 +82,31 @@ int soapy_error(void *h) void rf_soapy_get_freq_range(void *h) { - + // not supported } void rf_soapy_suppress_handler(const char *x) { - // not supported + // not supported } void rf_soapy_msg_handler(const char *msg) { - // not supported + // not supported } void rf_soapy_suppress_stdout(void *h) { - // not supported + // not supported } void rf_soapy_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler) { - // not supported + // not supported } @@ -109,14 +130,19 @@ bool rf_soapy_rx_wait_lo_locked(void *h) void rf_soapy_set_tx_cal(void *h, srslte_rf_cal_t *cal) { - printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n"); - // not supported + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + double actual_bw = SoapySDRDevice_getBandwidth(handler->device, SOAPY_SDR_TX, 0); + char str_buf[25]; + snprintf(str_buf, sizeof(str_buf), "%f", actual_bw); + if (SoapySDRDevice_writeSetting(handler->device, "CALIBRATE_TX", str_buf)) { + printf("Error calibrating Rx\n"); + } } void rf_soapy_set_rx_cal(void *h, srslte_rf_cal_t *cal) { - printf("TODO: implement rf_soapy_set_rx_cal()\n"); + // not supported } @@ -202,13 +228,15 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) printf("No Soapy devices found.\n"); return SRSLTE_ERROR; } - char* devname = NULL; + char* devname = DEVNAME_NONE; for (size_t i = 0; i < length; i++) { printf("Soapy has found device #%d: ", (int)i); for (size_t j = 0; j < soapy_args[i].size; j++) { printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]); if(!strcmp(soapy_args[i].keys[j],"name") && !strcmp(soapy_args[i].vals[j], "LimeSDR-USB")){ devname = DEVNAME_LIME; + } else if (!strcmp(soapy_args[i].keys[j],"name") && !strcmp(soapy_args[i].vals[j], "LimeSDR Mini")){ + devname = DEVNAME_LIME_MINI; } } printf("\n"); @@ -228,39 +256,46 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) handler->tx_stream_active = false; handler->rx_stream_active = false; handler->devname = devname; - if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_RX) > 0){ + + // init rx/tx rate to lowest LTE rate to avoid decimation warnings + rf_soapy_set_rx_srate(handler, 1.92e6); + rf_soapy_set_tx_srate(handler, 1.92e6); + + if(SoapySDRDevice_getNumChannels(handler->device, SOAPY_SDR_RX) > 0){ printf("Setting up RX stream\n"); if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { printf("Rx setupStream fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; - } + } + handler->rx_mtu = SoapySDRDevice_getStreamMTU(handler->device, handler->rxStream); } - if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_TX) > 0){ + if(SoapySDRDevice_getNumChannels(handler->device, SOAPY_SDR_TX) > 0){ printf("Setting up TX stream\n"); if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { printf("Tx setupStream fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; - } + } + handler->tx_mtu = SoapySDRDevice_getStreamMTU(handler->device, handler->txStream); } // list device sensors - size_t sensor_length; - char** sensors; - sensors = SoapySDRDevice_listSensors(handler->device, &sensor_length); + size_t list_length; + char** list; + list = SoapySDRDevice_listSensors(handler->device, &list_length); printf("Available device sensors: \n"); - for(int i = 0; i < sensor_length; i++) { - printf(" - %s\n", sensors[i]); + for(int i = 0; i < list_length; i++) { + printf(" - %s\n", list[i]); } // list channel sensors - sensors = SoapySDRDevice_listChannelSensors(handler->device, SOAPY_SDR_RX, 0, &sensor_length); + list = SoapySDRDevice_listChannelSensors(handler->device, SOAPY_SDR_RX, 0, &list_length); printf("Available sensors for RX channel 0: \n"); - for(int i = 0; i < sensor_length; i++) { - printf(" - %s\n", sensors[i]); + for(int i = 0; i < list_length; i++) { + printf(" - %s\n", list[i]); } - /* Set static radio info */ + // Set static radio info SoapySDRRange tx_range = SoapySDRDevice_getGainRange(handler->device, SOAPY_SDR_TX, 0); SoapySDRRange rx_range = SoapySDRDevice_getGainRange(handler->device, SOAPY_SDR_RX, 0); handler->info.min_tx_gain = tx_range.minimum; @@ -268,6 +303,87 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) handler->info.min_rx_gain = rx_range.minimum; handler->info.max_rx_gain = rx_range.maximum; + // Check device arguments + if (args) { + // config file + const char config_arg[] = "config="; + char config_str[64] = {0}; + char *config_ptr = strstr(args, config_arg); + if (config_ptr) { + copy_subdev_string(config_str, config_ptr + strlen(config_arg)); + printf("Loading config file %s\n", config_str); + SoapySDRDevice_writeSetting(handler->device, "LOAD_CONFIG", config_str); + remove_substring(args, config_arg); + remove_substring(args, config_str); + } + + // rx antenna + const char rx_ant_arg[] = "rxant="; + char rx_ant_str[64] = {0}; + char *rx_ant_ptr = strstr(args, rx_ant_arg); + if (rx_ant_ptr) { + copy_subdev_string(rx_ant_str, rx_ant_ptr + strlen(rx_ant_arg)); + printf("Setting Rx antenna to %s\n", rx_ant_str); + if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_RX, 0, rx_ant_str) != 0) { + fprintf(stderr, "Failed to set Rx antenna.\n"); + } + remove_substring(args, rx_ant_arg); + remove_substring(args, rx_ant_str); + } + + // tx antenna + const char tx_ant_arg[] = "txant="; + char tx_ant_str[64] = {0}; + char *tx_ant_ptr = strstr(args, tx_ant_arg); + if (tx_ant_ptr) { + copy_subdev_string(tx_ant_str, tx_ant_ptr + strlen(tx_ant_arg)); + printf("Setting Tx antenna to %s\n", tx_ant_str); + if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_TX, 0, tx_ant_str) != 0) { + fprintf(stderr, "Failed to set Tx antenna.\n"); + } + remove_substring(args, tx_ant_arg); + remove_substring(args, tx_ant_str); + } + } + + // receive one subframe to allow for transceiver calibration + if (strstr(devname, "lime")) { + // set default tx gain and leave some time to calibrate tx + rf_soapy_set_tx_gain(handler, 45); + rf_soapy_set_rx_gain(handler, 35); + + cf_t dummy_buffer[1920]; + cf_t *dummy_buffer_array[SRSLTE_MAX_PORTS]; + dummy_buffer_array[0] = dummy_buffer; + rf_soapy_start_rx_stream(handler, true); + rf_soapy_recv_with_time_multi(handler, (void**)dummy_buffer_array, 1920, false, NULL, NULL); + rf_soapy_stop_rx_stream(handler); + + usleep(10000); + //SoapySDR_setLogLevel(SOAPY_SDR_ERROR); + } + + // list gains and AGC mode + bool has_agc = SoapySDRDevice_hasGainMode(handler->device, SOAPY_SDR_RX, 0); + list = SoapySDRDevice_listGains(handler->device, SOAPY_SDR_RX, 0, &list_length); + printf("State of gain elements for Rx channel 0 (AGC %s):\n", has_agc ? "supported":"not supported"); + for(int i = 0; i < list_length; i++) { + printf(" - %s: %.2f dB\n", list[i], SoapySDRDevice_getGainElement(handler->device, SOAPY_SDR_RX, 0, list[i])); + } + + has_agc = SoapySDRDevice_hasGainMode(handler->device, SOAPY_SDR_TX, 0); + printf("State of gain elements for Tx channel 0 (AGC %s):\n", has_agc ? "supported":"not supported"); + for(int i = 0; i < list_length; i++) { + printf(" - %s: %.2f dB\n", list[i], SoapySDRDevice_getGainElement(handler->device, SOAPY_SDR_TX, 0, list[i])); + } + + // print actual antenna configuration + char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_RX, 0); + printf("Rx antenna set to %s\n", ant); + + ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_TX, 0); + printf("Tx antenna set to %s\n", ant); + return SRSLTE_SUCCESS; } @@ -293,14 +409,25 @@ int rf_soapy_close(void *h) SoapySDRDevice_unmake(handler->device); free(handler); - + + // print statistics + if (handler->num_lates) printf("#lates=%d\n", handler->num_lates); + if (handler->num_overflows) printf("#overflows=%d\n", handler->num_overflows); + if (handler->num_underflows) printf("#underflows=%d\n", handler->num_underflows); + if (handler->num_time_errors) printf("#time_errors=%d\n", handler->num_time_errors); + if (handler->num_other_errors) printf("#other_errors=%d\n", handler->num_other_errors); + return SRSLTE_SUCCESS; } void rf_soapy_set_master_clock_rate(void *h, double rate) { - // Allow the soapy to automatically set the appropriate clock rate + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_setMasterClockRate(handler->device, rate) != 0) { + printf("rf_soapy_set_master_clock_rate Rx fail: %s\n", SoapySDRDevice_lastError()); + } + printf("Set master clock rate to %.2f MHz\n", SoapySDRDevice_getMasterClockRate(handler->device)/1e6); } @@ -314,21 +441,75 @@ bool rf_soapy_is_master_clock_dynamic(void *h) double rf_soapy_set_rx_srate(void *h, double rate) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + + // Restart streaming, as the Lime seems to have problems reconfiguring the sample rate during streaming + bool rx_stream_active = handler->rx_stream_active; + if (rx_stream_active) { + rf_soapy_stop_rx_stream(handler); + } + if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0) { printf("setSampleRate Rx fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } + +#if SET_RF_BW + // Set bandwidth close to current rate + size_t bw_length; + SoapySDRRange *bw_range = SoapySDRDevice_getBandwidthRange(handler->device, SOAPY_SDR_RX, 0, &bw_length); + double bw = rate; + bw = MIN(bw, bw_range->maximum); + bw = MAX(bw, bw_range->minimum); + bw = MAX(bw, 2.5e6); // For the Lime to avoid warnings + if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_RX, 0, bw) != 0) { + printf("setBandwidth fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + printf("Set Rx bandwidth to %.2f MHz\n", SoapySDRDevice_getBandwidth(handler->device, SOAPY_SDR_RX, 0)/1e6); +#endif + + if (rx_stream_active) { + rf_soapy_start_rx_stream(handler, true); + } + return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0); } double rf_soapy_set_tx_srate(void *h, double rate) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + + // stop/start streaming during rate reconfiguration + bool rx_stream_active = handler->rx_stream_active; + if (handler->rx_stream_active) { + rf_soapy_stop_rx_stream(handler); + } + if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0) { printf("setSampleRate Tx fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } - return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); + +#if SET_RF_BW + size_t bw_length; + SoapySDRRange *bw_range = SoapySDRDevice_getBandwidthRange(handler->device, SOAPY_SDR_TX, 0, &bw_length); + // try to set the BW to the actual sampling rate but make sure to stay within device boundaries + double bw = rate; + bw = MIN(rate, bw_range->maximum); + bw = MAX(rate, bw_range->minimum); + if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_TX, 0, bw) != 0) { + printf("setBandwidth fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + printf("Set Tx bandwidth to %.2f MHz\n", SoapySDRDevice_getBandwidth(handler->device, SOAPY_SDR_TX, 0)/1e6); +#endif + + if (rx_stream_active) { + rf_soapy_start_rx_stream(handler, true); + } + + handler->tx_rate = SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX, 0); + return handler->tx_rate; } @@ -359,14 +540,14 @@ double rf_soapy_set_tx_gain(void *h, double gain) double rf_soapy_get_rx_gain(void *h) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_RX,0); + return SoapySDRDevice_getGain(handler->device, SOAPY_SDR_RX, 0); } double rf_soapy_get_tx_gain(void *h) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_TX,0); + return SoapySDRDevice_getGain(handler->device, SOAPY_SDR_TX, 0); } @@ -389,14 +570,10 @@ double rf_soapy_set_rx_freq(void *h, double freq) printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } + printf("Tuned Rx to %.2f MHz\n", SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0)/1e6); - // Todo: expose antenna setting - if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_RX, 0, "LNAH") != 0) { - fprintf(stderr, "Failed to set Rx antenna.\n"); - } - - char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_RX, 0); - printf("Rx antenna set to %s\n", ant); + // wait until LO is locked + rf_soapy_rx_wait_lo_locked(handler); return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0); } @@ -410,13 +587,7 @@ double rf_soapy_set_tx_freq(void *h, double freq) return SRSLTE_ERROR; } - // Todo: expose antenna name in arguments - if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_TX, 0, "BAND1") != 0) { - fprintf(stderr, "Failed to set Tx antenna.\n"); - } - - char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_TX, 0); - printf("Tx antenna set to %s\n", ant); + printf("Tuned Tx to %.2f MHz\n", SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0)/1e6); return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0); } @@ -439,42 +610,59 @@ int rf_soapy_recv_with_time_multi(void *h, rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; int flags; //flags set by receive operation int num_channels = 1; // temp - const long timeoutUs = 1000000; // arbitrarily chosen + const long timeoutUs = 400000; // arbitrarily chosen int trials = 0; int ret = 0; long long timeNs; //timestamp for receive buffer int n = 0; + +#if PRINT_RX_STATS + printf("rx: nsamples=%d rx_mtu=%zd\n", nsamples, handler->rx_mtu); +#endif + do { - size_t rx_samples = nsamples; - - if (rx_samples > nsamples - n){ - rx_samples = nsamples - n; - } + size_t rx_samples = MIN(nsamples - n, handler->rx_mtu); +#if PRINT_RX_STATS + printf(" - rx_samples=%zd\n", rx_samples); +#endif + void *buffs_ptr[4]; for (int i=0; idevice, handler->rxStream, buffs_ptr, rx_samples, &flags, &timeNs, timeoutUs); - if(ret < 0) { - // continue when getting overflows - if (ret == SOAPY_SDR_OVERFLOW) { - fprintf(stderr, "O"); - fflush(stderr); - continue; - } else { - return SRSLTE_ERROR; - } + if (ret == SOAPY_SDR_OVERFLOW || (ret > 0 && (flags & SOAPY_SDR_END_ABRUPT) != 0)) { + handler->num_overflows++; + fprintf(stderr, "O"); + fflush(stderr); + continue; + } else + if (ret == SOAPY_SDR_TIMEOUT) { + handler->num_time_errors++; + fprintf(stderr, "T"); + fflush(stderr); + continue; + } else + if (ret < 0) { + // unspecific error + printf("SoapySDRDevice_readStream returned %d: %s\n", ret, SoapySDR_errToStr(ret)); + handler->num_other_errors++; } - // update rx time - if (secs != NULL && frac_secs != NULL) { + // update rx time only for first segment + if (secs != NULL && frac_secs != NULL && n == 0) { *secs = timeNs / 1e9; *frac_secs = (timeNs % 1000000000)/1e9; - //printf("rx_time: secs=%d, frac_secs=%lf timeNs=%lld\n", *secs, *frac_secs, timeNs); + //printf("rx_time: secs=%lld, frac_secs=%lf timeNs=%llu\n", *secs, *frac_secs, timeNs); } +#if PRINT_RX_STATS + printf(" - rx: %d/%zd\n", ret, rx_samples); +#endif + n += ret; trials++; } while (n < nsamples && trials < 100); @@ -522,65 +710,103 @@ int rf_soapy_send_timed_multi(void *h, { rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h; int flags = 0; - const long timeoutUs = 2000; // arbitrarily chosen + const long timeoutUs = 100000; // arbitrarily chosen long long timeNs = 0; int trials = 0; int ret = 0; int n = 0; +#if PRINT_TX_STATS + printf("tx: namples=%d, mtu=%zd\n", nsamples, handler->tx_mtu); +#endif if (!handler->tx_stream_active) { rf_soapy_start_tx_stream(h); } - if (is_start_of_burst && is_end_of_burst) { - flags |= SOAPY_SDR_ONE_PACKET; - } - - if (is_end_of_burst) { - flags |= SOAPY_SDR_END_BURST; - } - + // Convert initial tx time if (has_time_spec) { - flags |= SOAPY_SDR_HAS_TIME; timeNs = secs * 1000000000; timeNs = timeNs + (frac_secs * 1000000000); - //printf("time_spec: secs=%d, frac_secs=%lf timeNs=%lld\n", secs, frac_secs, timeNs); } do { +#if USE_TX_MTU + size_t tx_samples = MIN(nsamples - n, handler->tx_mtu); +#else size_t tx_samples = nsamples; if (tx_samples > nsamples - n) { tx_samples = nsamples - n; } +#endif - ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, (const void *)data, tx_samples, &flags, timeNs, timeoutUs); - if (ret == SOAPY_SDR_TIMEOUT) { - printf("L"); - continue; + // (re-)set stream flags + flags = 0; + if (is_start_of_burst && is_end_of_burst) { + flags |= SOAPY_SDR_ONE_PACKET; } - if (ret == SOAPY_SDR_OVERFLOW) { - printf("O"); - continue; + + if (is_end_of_burst) { + flags |= SOAPY_SDR_END_BURST; } - if (ret == SOAPY_SDR_UNDERFLOW) { - printf("U"); - continue; + + // only set time flag for first tx + if(has_time_spec && n == 0) { + flags |= SOAPY_SDR_HAS_TIME; + } + +#if PRINT_TX_STATS + printf(" - tx_samples=%zd at timeNs=%llu flags=%d\n", tx_samples, timeNs, flags); +#endif + + ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, (const void *)data, tx_samples, &flags, timeNs, timeoutUs); + if (ret >= 0) { + // Tx was ok +#if PRINT_TX_STATS + printf(" - tx: %d/%zd\n", ret, tx_samples); +#endif + // Advance tx time + if (has_time_spec && ret < nsamples) { + long long adv = SoapySDR_ticksToTimeNs(ret, handler->tx_rate); +#if PRINT_TX_STATS + printf(" - tx: timeNs_old=%llu, adv=%llu, timeNs_new=%llu, tx_rate=%f\n", timeNs, adv, timeNs+adv, handler->tx_rate); +#endif + timeNs += adv; + } + n += ret; } + else if (ret < 0) { - fprintf(stderr, "Error during writeStream\n"); - exit(-1); - return SRSLTE_ERROR; + // An error has occured + switch (ret) { + case SOAPY_SDR_TIMEOUT: + handler->num_lates++; + printf("L"); + break; + case SOAPY_SDR_STREAM_ERROR: + handler->num_stream_curruption++; + printf("E"); + break; + case SOAPY_SDR_TIME_ERROR: + handler->num_time_errors++; + printf("T"); + break; + case SOAPY_SDR_UNDERFLOW: + handler->num_underflows++; + printf("U"); + break; + default: + fprintf(stderr, "Error during writeStream\n"); + exit(-1); + return SRSLTE_ERROR; + } } - - n += ret; trials++; } while (n < nsamples && trials < 100); if (n != nsamples) { - fprintf(stderr, "Couldn't write all samples.\n"); - return SRSLTE_ERROR; + fprintf(stderr, "Couldn't write all samples after %d trials.\n", trials); } - return ret; + return n; } diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index a2ccf106a..5b1787304 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -28,7 +28,9 @@ #include #include "srslte/config.h" #include "srslte/phy/rf/rf.h" +#define DEVNAME_NONE "none" #define DEVNAME_LIME "lime" +#define DEVNAME_LIME_MINI "lime_mini" SRSLTE_API int rf_soapy_open(char *args, void **handler); diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index f287f5579..d009bb696 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -32,7 +32,7 @@ #include "srslte/srslte.h" #include "rf_uhd_imp.h" -#include "srslte/phy/rf/rf.h" +#include "rf_helper.h" #include "uhd_c_api.h" #define HAVE_ASYNC_THREAD 1 @@ -320,31 +320,6 @@ int rf_uhd_open(char *args, void **h) return rf_uhd_open_multi(args, h, 1); } -#define REMOVE_SUBSTRING_WITHCOMAS(S, TOREMOVE) \ - remove_substring(S, TOREMOVE ",");\ - remove_substring(S, TOREMOVE ", ");\ - remove_substring(S, "," TOREMOVE);\ - remove_substring(S, ", " TOREMOVE);\ - remove_substring(S, TOREMOVE) - -static void remove_substring(char *s,const char *toremove) -{ - while((s=strstr(s,toremove))) { - memmove(s,s+strlen(toremove),1+strlen(s+strlen(toremove))); - } -} - -static void copy_subdev_string(char *dst, char *src) { - int n = 0; - size_t len = strlen(src); - /* Copy until end of string or comma */ - while (n < len && src[n] != '\0' && src[n] != ',') { - dst[n] = src[n]; - n++; - } - dst[n] = '\0'; -} - int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) { if (h) { diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 7bcbbf578..558f8b5fe 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -491,6 +491,9 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, int found_dci = srslte_ue_dl_find_dl_dci(q, tm, cfi, sf_idx, rnti, &dci_msg); if (found_dci == 1) { + INFO("PDCCH: DL DCI %s rnti=0x%x, cce_index=%d, L=%d, tti=%d\n", srslte_dci_format_string(dci_msg.format), + q->current_rnti, q->last_location.ncce, (1<last_location.L), tti); + if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) { fprintf(stderr, "Error unpacking DCI\n"); return SRSLTE_ERROR; diff --git a/lib/src/radio/CMakeLists.txt b/lib/src/radio/CMakeLists.txt index 1e7829e87..7fa479f8c 100644 --- a/lib/src/radio/CMakeLists.txt +++ b/lib/src/radio/CMakeLists.txt @@ -23,3 +23,5 @@ if(RF_FOUND) target_link_libraries(srslte_radio srslte_rf) install(TARGETS srslte_radio DESTINATION ${LIBRARY_DIR}) endif(RF_FOUND) + +add_subdirectory(test) \ No newline at end of file diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 1b114968b..117c626bc 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -59,7 +59,7 @@ bool radio::init(char *args, char *devname, uint32_t nof_channels) } else if (strstr(srslte_rf_name(&rf_device), "bladerf")) { burst_preamble_sec = blade_default_burst_preamble_sec; } else { - burst_preamble_sec = 0; + burst_preamble_sec = 0; printf("\nWarning burst preamble is not calibrated for device %s. Set a value manually\n\n", srslte_rf_name(&rf_device)); } @@ -81,7 +81,9 @@ bool radio::is_init() { void radio::stop() { - srslte_rf_close(&rf_device); + if (is_initialized) { + srslte_rf_close(&rf_device); + } } void radio::reset() diff --git a/lib/src/radio/test/CMakeLists.txt b/lib/src/radio/test/CMakeLists.txt new file mode 100644 index 000000000..c44fd826e --- /dev/null +++ b/lib/src/radio/test/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# Copyright 2013-2017 Software Radio Systems Limited +# +# This file is part of srsLTE +# +# srsLTE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# A copy of the GNU Affero 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/. +# + +if(RF_FOUND) + add_executable(benchmark_radio benchmark_radio.cc) + target_link_libraries(benchmark_radio srslte_radio) +endif(RF_FOUND) + + diff --git a/lib/src/radio/test/benchmark_radio.cc b/lib/src/radio/test/benchmark_radio.cc new file mode 100644 index 000000000..d9279a351 --- /dev/null +++ b/lib/src/radio/test/benchmark_radio.cc @@ -0,0 +1,182 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \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 Affero 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 Affero General Public License for more details. + * + * A copy of the GNU Affero 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 +#include "srslte/srslte.h" +#include "srslte/radio/radio_multi.h" + +using namespace srslte; + +std::string device_args = "auto"; + +double freq = 2630e6; +uint32_t nof_ports = 1; +double srate = 1.92e6; /* Hz */ +double duration = 0.01; /* in seconds, 10 ms by default */ +cf_t *buffers[SRSLTE_MAX_PORTS]; +bool tx_enable = false; + + +void usage(char *prog) { + printf("Usage: %s [rpstvh]\n", prog); + printf("\t-f Carrier frequency in Hz [Default %f]\n", freq); + printf("\t-a Arguments for first radio [Default %s]\n", device_args.c_str()); + printf("\t-p number of ports 1-%d [Default %d]\n", SRSLTE_MAX_PORTS, nof_ports); + printf("\t-s sampling rate [Default %.0f]\n", srate); + printf("\t-t duration in seconds [Default %.3f]\n", duration); + printf("\t-x enable transmit [Default %s]\n", (tx_enable) ? "enabled" : "disabled"); + printf("\t-v Set srslte_verbose to info (v) or debug (vv) [Default none]\n"); + printf("\t-h show this message\n"); +} + +void parse_args(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "foabcderpstvhmxw")) != -1) { + switch (opt) { + case 'f': + freq = atof(argv[optind]); + break; + case 'a': + device_args = std::string(argv[optind]); + break; + case 'p': + nof_ports = (uint32_t) atoi(argv[optind]); + break; + case 's': + srate = atof(argv[optind]); + break; + case 't': + duration = atof(argv[optind]); + break; + case 'x': + tx_enable ^= true; + break; + case 'v': + srslte_verbose++; + break; + case 'h': + default: + usage(argv[0]); + exit(-1); + } + } +} + +int main(int argc, char **argv) +{ + int ret = SRSLTE_ERROR; + srslte::radio_multi *radio_h = NULL; + srslte_timestamp_t ts_rx = {}, ts_tx = {}; + + /* Parse args */ + parse_args(argc, argv); + + uint32_t nof_samples = (uint32_t) (duration * srate); + uint32_t frame_size = (uint32_t) (srate / 1000.0); /* 1 ms at srate */ + uint32_t nof_frames = (uint32_t) ceil(nof_samples / frame_size); + + radio_h = new radio_multi(); + if (!radio_h) { + fprintf(stderr, "Error: Calling radio_multi constructor\n"); + goto clean_exit; + } + + for (uint32_t p = 0; p < SRSLTE_MAX_PORTS; p++) { + buffers[p] = NULL; + } + + for (uint32_t p = 0; p < nof_ports; p++) { + buffers[p] = (cf_t *) srslte_vec_malloc(sizeof(cf_t) * frame_size); + if (!buffers[p]) { + fprintf(stderr, "Error: Allocating buffer (%d)\n", p); + goto clean_exit; + } + } + + /* Initialise instances */ + printf("Initialising instances...\n"); + if (!radio_h->init((char*)device_args.c_str(), NULL, nof_ports)) { + fprintf(stderr, "Error: Calling radio_multi constructor\n"); + goto clean_exit; + } + + radio_h->set_rx_freq(freq); + + /* Set radio */ + printf("Setting radio...\n"); + if (srate < 10e6) { + radio_h->set_master_clock_rate(4 * srate); + } else { + radio_h->set_master_clock_rate(srate); + } + + radio_h->set_rx_srate(srate); + if (tx_enable) { + radio_h->set_tx_srate(srate); + } + + /* Receive */ + printf("Initial receive for aligning radios...\n"); + radio_h->rx_now(buffers, frame_size, &ts_rx); + + printf("Start capturing %d frames of %d samples...\n", nof_frames, frame_size); + + for (uint32_t i = 0; i < nof_frames; i++) { + frame_size = SRSLTE_MIN(frame_size, nof_samples); + radio_h->rx_now(buffers, frame_size, &ts_rx); + + if (tx_enable) { + srslte_timestamp_copy(&ts_tx, &ts_rx); + srslte_timestamp_add(&ts_tx, 0, 0.004); + radio_h->tx_single(buffers[0], frame_size, ts_tx); + } + + nof_samples -= frame_size; + } + + printf("Finished streaming ...\n"); + + ret = SRSLTE_SUCCESS; + +clean_exit: + printf("Tearing down...\n"); + + radio_h->stop(); + + for (uint32_t p = 0; p < nof_ports; p++) { + if (buffers[p]) { + free(buffers[p]); + } + } + + if (ret) { + printf("Failed!\n"); + } else { + printf("Ok!\n"); + } + + return ret; +} diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 5036c18cd..ebedc9fec 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -78,31 +78,19 @@ public: uint32_t get_next_mme_ue_s1ap_id(); enb_ctx_t* find_enb_ctx(uint16_t enb_id); void add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo* enb_sri); + void get_enb_ctx(uint16_t sctp_stream); bool add_ue_ctx_to_imsi_map(ue_ctx_t *ue_ctx); bool add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx_t *ue_ctx); + bool add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id); ue_ctx_t* find_ue_ctx_from_imsi(uint64_t imsi); ue_ctx_t* find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); - void release_ues_ecm_ctx_in_enb(uint16_t enb_id); + void release_ues_ecm_ctx_in_enb(int32_t enb_assoc); bool delete_ue_ctx(uint64_t imsi); - //ue_ctx_t* find_ue_ctx(uint32_t mme_ue_s1ap_id); - //void add_new_ue_ctx(const ue_ctx_t &ue_ctx); - - //void add_new_ue_emm_ctx(const ue_emm_ctx_t &ue_emm_ctx); - //void add_new_ue_ecm_ctx(const ue_ecm_ctx_t &ue_ecm_ctx); - //ue_emm_ctx_t* find_ue_emm_ctx_from_imsi(uint64_t imsi); - //ue_ecm_ctx_t* find_ue_ecm_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); - //bool delete_ue_emm_ctx(uint64_t imsi); - //bool delete_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); - //void delete_ues_ecm_ctx_in_enb(uint16_t enb_id); - - //void store_tmp_ue_emm_ctx(const ue_emm_ctx_t &ue_ecm_ctx); - //bool get_tmp_ue_emm_ctx(uint32_t mme_ue_s1ap_id, ue_emm_ctx_t* ue_emm_ptr); - uint32_t allocate_m_tmsi(uint64_t imsi); s1ap_args_t m_s1ap_args; @@ -127,16 +115,11 @@ private: int m_s1mme; std::map m_active_enbs; std::map m_sctp_to_enb_id; - std::map > m_enb_id_to_ue_ids; - + std::map > m_enb_assoc_to_ue_ids; std::map m_imsi_to_ue_ctx; std::map m_mme_ue_s1ap_id_to_ue_ctx; - //std::map m_imsi_to_ue_emm_ctx; - //std::map m_mme_ue_s1ap_id_to_ue_ecm_ctx; - //std::map m_mme_ue_s1ap_id_to_tmp_ue_emm_ctx; - uint32_t m_next_mme_ue_s1ap_id; uint32_t m_next_m_tmsi; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index ccd2536c1..180859f08 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -299,7 +299,7 @@ s1ap::add_new_enb_ctx(const enb_ctx_t &enb_ctx, const struct sctp_sndrcvinfo *en memcpy(enb_ptr,&enb_ctx,sizeof(enb_ctx_t)); m_active_enbs.insert(std::pair(enb_ptr->enb_id,enb_ptr)); m_sctp_to_enb_id.insert(std::pair(enb_sri->sinfo_assoc_id, enb_ptr->enb_id)); - m_enb_id_to_ue_ids.insert(std::pair >(enb_ptr->enb_id,ue_set)); + m_enb_assoc_to_ue_ids.insert(std::pair >(enb_sri->sinfo_assoc_id,ue_set)); return; } @@ -335,7 +335,7 @@ s1ap::delete_enb_ctx(int32_t assoc_id) m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); //Delete connected UEs ctx - release_ues_ecm_ctx_in_enb(enb_id); + release_ues_ecm_ctx_in_enb(assoc_id); //Delete eNB delete it_ctx->second; @@ -397,6 +397,27 @@ s1ap::add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx_t *ue_ctx) return true; } +bool +s1ap::add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id) +{ + + std::map >::iterator ues_in_enb = m_enb_assoc_to_ue_ids.find(enb_assoc); + if(ues_in_enb == m_enb_assoc_to_ue_ids.end()) + { + m_s1ap_log->error("Could not find eNB from eNB SCTP association %d",enb_assoc); + return false; + } + std::set::iterator ue_id = ues_in_enb->second.find(mme_ue_s1ap_id); + if(ue_id != ues_in_enb->second.end()) + { + m_s1ap_log->error("UE with MME UE S1AP Id already exists %d",mme_ue_s1ap_id); + return false; + } + ues_in_enb->second.insert(mme_ue_s1ap_id); + m_s1ap_log->debug("Added UE with MME-UE S1AP Id %d to eNB with association %d\n", mme_ue_s1ap_id, enb_assoc); + return true; +} + ue_ctx_t* s1ap::find_ue_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id) { @@ -426,21 +447,34 @@ s1ap::find_ue_ctx_from_imsi(uint64_t imsi) } void -s1ap::release_ues_ecm_ctx_in_enb(uint16_t enb_id) +s1ap::release_ues_ecm_ctx_in_enb(int32_t enb_assoc) { + m_s1ap_log->console("Releasing UEs context\n"); //delete UEs ctx - std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); + std::map >::iterator ues_in_enb = m_enb_assoc_to_ue_ids.find(enb_assoc); std::set::iterator ue_id = ues_in_enb->second.begin(); - while(ue_id != ues_in_enb->second.end() ) + if(ue_id == ues_in_enb->second.end()) { - std::map::iterator ue_ctx = m_mme_ue_s1ap_id_to_ue_ctx.find(*ue_id); - ue_ecm_ctx_t *ecm_ctx = &ue_ctx->second->ecm_ctx; - m_s1ap_log->info("Releasing UE ECM context. UE-MME S1AP Id: %d\n", ecm_ctx->mme_ue_s1ap_id); - m_s1ap_log->console("Releasing UE ECM context. UE-MME S1AP Id: %d\n", ecm_ctx->mme_ue_s1ap_id); - ues_in_enb->second.erase(ecm_ctx->mme_ue_s1ap_id); - ecm_ctx->state = ECM_STATE_IDLE; - ecm_ctx->mme_ue_s1ap_id = 0; - ecm_ctx->enb_ue_s1ap_id = 0; + m_s1ap_log->console("No UEs to be released\n"); + } else { + while(ue_id != ues_in_enb->second.end() ) + { + std::map::iterator ue_ctx = m_mme_ue_s1ap_id_to_ue_ctx.find(*ue_id); + ue_emm_ctx_t *emm_ctx = &ue_ctx->second->emm_ctx; + ue_ecm_ctx_t *ecm_ctx = &ue_ctx->second->ecm_ctx; + + m_s1ap_log->info("Releasing UE context. IMSI: %015lu, UE-MME S1AP Id: %d\n", emm_ctx->imsi, ecm_ctx->mme_ue_s1ap_id); + if(emm_ctx->state == EMM_STATE_REGISTERED) + { + m_mme_gtpc->send_delete_session_request(emm_ctx->imsi); + emm_ctx->state = EMM_STATE_DEREGISTERED; + } + m_s1ap_log->console("Releasing UE ECM context. UE-MME S1AP Id: %d\n", ecm_ctx->mme_ue_s1ap_id); + ecm_ctx->state = ECM_STATE_IDLE; + ecm_ctx->mme_ue_s1ap_id = 0; + ecm_ctx->enb_ue_s1ap_id = 0; + ues_in_enb->second.erase(ue_id++); + } } } @@ -463,8 +497,8 @@ s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) return false; } uint16_t enb_id = it->second; - std::map >::iterator ue_set = m_enb_id_to_ue_ids.find(enb_id); - if(ue_set == m_enb_id_to_ue_ids.end()) + std::map >::iterator ue_set = m_enb_assoc_to_ue_ids.find(ecm_ctx->enb_sri.sinfo_assoc_id); + if(ue_set == m_enb_assoc_to_ue_ids.end()) { m_s1ap_log->error("Could not find the eNB's UEs.\n"); return false; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index f4114603a..e8ee25a1d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -371,7 +371,7 @@ s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id, //Get attach type from attach request if(attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) - { + { m_s1ap_log->console("Attach Request -- IMSI-style attach request\n"); m_s1ap_log->info("Attach Request -- IMSI-style attach request\n"); handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); @@ -510,6 +510,7 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, memcpy(new_ctx,&ue_ctx,sizeof(ue_ctx_t)); m_s1ap->add_ue_ctx_to_imsi_map(new_ctx); m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(new_ctx); + m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,ecm_ctx->mme_ue_s1ap_id); //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, autn, rand); @@ -623,6 +624,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, ue_ctx_t *new_ctx = new ue_ctx_t; memcpy(new_ctx,&ue_ctx,sizeof(ue_ctx_t)); m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(new_ctx); + m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,ecm_ctx->mme_ue_s1ap_id); pack_identity_request(reply_buffer, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); *reply_flag = true; @@ -646,7 +648,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, if(msg_valid == true && emm_ctx->state == EMM_STATE_DEREGISTERED) { m_s1ap_log->console("GUTI Attach Integrity valid. UL count %d, DL count %d\n",emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.dl_nas_count); - + //Create new MME UE S1AP Identity emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); ecm_ctx->mme_ue_s1ap_id = emm_ctx->mme_ue_s1ap_id; @@ -672,7 +674,8 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, //Store context based on MME UE S1AP id m_s1ap->add_ue_ctx_to_mme_ue_s1ap_id_map(ue_ctx); - + m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,ecm_ctx->mme_ue_s1ap_id); + //Re-generate K_eNB srslte::security_generate_k_enb(emm_ctx->security_ctxt.k_asme, emm_ctx->security_ctxt.ul_nas_count, emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",emm_ctx->security_ctxt.ul_nas_count); diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index ce53e8833..244657975 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -162,6 +162,7 @@ private: srslte_ue_ul_t ue_ul; srslte_timestamp_t tx_time; srslte_uci_data_t uci_data; + srslte_cqi_value_t cqi_report; uint16_t ul_rnti; // UL configuration parameters diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index e6e7727fd..43a31ba0e 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1032,7 +1032,8 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) void phch_worker::reset_uci() { - bzero(&uci_data, sizeof(srslte_uci_data_t)); + ZERO_OBJECT(uci_data); + ZERO_OBJECT(cqi_report); } void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], bool tb_en[SRSLTE_MAX_CODEWORDS]) @@ -1082,7 +1083,6 @@ void phch_worker::set_uci_periodic_cqi() compute_ri(NULL, NULL, NULL); phy->last_pmi = (uint8_t) ue_dl.pmi[phy->last_ri % SRSLTE_MAX_LAYERS]; - srslte_cqi_value_t cqi_report; ZERO_OBJECT(cqi_report); if (period_cqi.format_is_subband) { @@ -1110,6 +1110,8 @@ void phch_worker::set_uci_periodic_cqi() Debug("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db_cqi); } uci_data.uci_cqi_len = (uint32_t) srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi); + uci_data.uci_ri = phy->last_ri; + uci_data.uci_ri_len = 0; rar_cqi_request = false; } } @@ -1135,7 +1137,6 @@ void phch_worker::set_uci_aperiodic_cqi() reported RI. For other transmission modes they are reported conditioned on rank 1. */ if (rnti_is_set) { - srslte_cqi_value_t cqi_report; ZERO_OBJECT(cqi_report); cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL; @@ -1289,11 +1290,13 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui #endif char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = ""; - srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR); + if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + srslte_cqi_value_tostring(&cqi_report, cqi_str, SRSLTE_CQI_STR_MAX_CHAR); + } uint8_t dummy[2] = {0,0}; log_h->info_hex(payload, grant->mcs.tbs/8, - "PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n", + "PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s\n", (tti + HARQ_DELAY_MS) % 10240, grant->n_prb[0], grant->n_prb[0] + grant->L_prb, grant->mcs.tbs / 8, grant->mcs.idx, rv, @@ -1301,7 +1304,6 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "", uci_data.uci_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "", cfo * 15, timestr, - uci_data.uci_cqi_len > 0 ? ", cqi=" : "", uci_data.uci_cqi_len > 0 ? cqi_str : ""); // Store metrics @@ -1343,17 +1345,18 @@ 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 gain = set_power(tx_power); - char str_cqi[SRSLTE_CQI_STR_MAX_CHAR] = ""; - srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, str_cqi, SRSLTE_CQI_STR_MAX_CHAR); + char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = ""; + if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + srslte_cqi_value_tostring(&cqi_report, cqi_str, 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, sr=%s, cfo=%.1f KHz%s\n", (tti + 4) % 10240, ue_ul.pucch.last_n_pucch, ue_ul.pucch.last_n_prb, uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? "1" : "0") : "no", uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "", uci_data.uci_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "", - uci_data.uci_cqi_len > 0 ? ", cqi=" : "", - uci_data.uci_cqi_len > 0 ? str_cqi : "", + uci_data.uci_cqi_len > 0 ? cqi_str : "", uci_data.scheduling_request ? "yes" : "no", cfo * 15, timestr); }