diff --git a/lib/include/srslte/asn1/liblte_rrc.h b/lib/include/srslte/asn1/liblte_rrc.h index 5a8515dbb..c5c3b60e2 100644 --- a/lib/include/srslte/asn1/liblte_rrc.h +++ b/lib/include/srslte/asn1/liblte_rrc.h @@ -6435,11 +6435,102 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_mobility_from_eutra_command_msg(LIBLTE_BIT_M Document Reference: 36.331 v10.0.0 Section 6.2.2 *********************************************************************/ -// Defines -// Enums +typedef struct{ + LIBLTE_RRC_CELL_GLOBAL_ID_EUTRA_STRUCT cell_global_id; + uint16 tracking_area_code; + LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_identity_list[5]; + uint32 n_plmn_identity_list; + bool have_plmn_identity_list; +}LIBLTE_RRC_CGI_INFO_STRUCT; +LIBLTE_ERROR_ENUM liblte_rrc_pack_cgi_info_ie(LIBLTE_RRC_CGI_INFO_STRUCT *cgi_info, + uint8 **ie_ptr); +LIBLTE_ERROR_ENUM liblte_rrc_unpack_cgi_info_ie(uint8 **ie_ptr, + LIBLTE_RRC_CGI_INFO_STRUCT *cgi_info); + +typedef struct{ + uint8 rsrp_result; + bool have_rsrp; + uint8 rsrq_result; + bool have_rsrq; +}LIBLTE_RRC_MEAS_RESULT_STRUCT; +LIBLTE_ERROR_ENUM liblte_rrc_pack_meas_result_ie(LIBLTE_RRC_MEAS_RESULT_STRUCT *meas_result, + uint8 **ie_ptr); +LIBLTE_ERROR_ENUM liblte_rrc_unpack_meas_result_ie(uint8 **ie_ptr, + LIBLTE_RRC_MEAS_RESULT_STRUCT *meas_result); + +typedef struct{ + uint16 phys_cell_id; + LIBLTE_RRC_CGI_INFO_STRUCT cgi_info; + bool have_cgi_info; + LIBLTE_RRC_MEAS_RESULT_STRUCT meas_result; +}LIBLTE_RRC_MEAS_RESULT_EUTRA_STRUCT; +LIBLTE_ERROR_ENUM liblte_rrc_pack_meas_result_eutra_ie(LIBLTE_RRC_MEAS_RESULT_EUTRA_STRUCT *meas_result_eutra, + uint8 **ie_ptr); +LIBLTE_ERROR_ENUM liblte_rrc_unpack_meas_result_eutra_ie(uint8 **ie_ptr, + LIBLTE_RRC_MEAS_RESULT_EUTRA_STRUCT *meas_result_eutra); + +typedef struct{ + //FIXME +}LIBLTE_RRC_MEAS_RESULT_UTRA_STRUCT; +typedef struct{ + //FIXME +}LIBLTE_RRC_MEAS_RESULT_GERAN_STRUCT; +typedef struct{ + //FIXME +}LIBLTE_RRC_MEAS_RESULT_CDMA2000_STRUCT; + + + +typedef struct{ + LIBLTE_RRC_MEAS_RESULT_EUTRA_STRUCT result_eutra_list[8]; + uint8 n_result; +}LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA_STRUCT; + +typedef struct{ + LIBLTE_RRC_MEAS_RESULT_UTRA_STRUCT result_utra_list[8]; + uint8 n_result; +}LIBLTE_RRC_MEAS_RESULT_LIST_UTRA_STRUCT; + +typedef struct{ + LIBLTE_RRC_MEAS_RESULT_GERAN_STRUCT result_geran_list[8]; + uint8 n_result; +}LIBLTE_RRC_MEAS_RESULT_LIST_GERAN_STRUCT; + + +typedef struct{ + bool pre_registration_status_HRPD; + LIBLTE_RRC_MEAS_RESULT_CDMA2000_STRUCT cdma2000[8]; +}LIBLTE_RRC_MEAS_RESULTS_CDMA2000_STRUCT; + +typedef enum{ + LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA = 0, + LIBLTE_RRC_MEAS_RESULT_LIST_UTRA, + LIBLTE_RRC_MEAS_RESULT_LIST_GERAN, + LIBLTE_RRC_MEAS_RESULTS_CDMA2000, + LIBLTE_RRC_MEAS_RESULT_N_ITEMS, +}LIBLTE_RRC_MEAS_RESULT_NEIGH_CELLS_ENUM; +static const char liblte_rrc_meas_reult_neigh_cells_text[LIBLTE_RRC_MEAS_RESULT_N_ITEMS][32] = { "measResultListEUTRA", "measResultListUTRA", "measResultListGERAN", "measResultsCDMA2000"}; + + +typedef union{ + LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA_STRUCT eutra; + LIBLTE_RRC_MEAS_RESULT_LIST_UTRA_STRUCT utra; + LIBLTE_RRC_MEAS_RESULT_LIST_GERAN_STRUCT geran; + LIBLTE_RRC_MEAS_RESULTS_CDMA2000_STRUCT cdma2000; +}LIBLTE_RRC_MEAS_RESULT_NEIGH_CELLS_UNION; + +//TODO: pack/unpack for the result lists + + // Structs typedef struct{ - // FIXME + uint8 meas_id; + uint8 pcell_rsrp_result; + uint8 pcell_rsrq_result; + + LIBLTE_RRC_MEAS_RESULT_NEIGH_CELLS_UNION meas_result_neigh_cells; + LIBLTE_RRC_MEAS_RESULT_NEIGH_CELLS_ENUM meas_result_neigh_cells_choice; + bool have_meas_result_neigh_cells; }LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT; // Functions LIBLTE_ERROR_ENUM liblte_rrc_pack_measurement_report_msg(LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *meas_report, diff --git a/lib/src/asn1/liblte_rrc.cc b/lib/src/asn1/liblte_rrc.cc index e4621994e..c53399384 100644 --- a/lib/src/asn1/liblte_rrc.cc +++ b/lib/src/asn1/liblte_rrc.cc @@ -4764,6 +4764,9 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_plmn_identity_ie(LIBLTE_RRC_PLMN_IDENTITY_STRU if(plmn_id != NULL && ie_ptr != NULL) { + if(0xFFFF == plmn_id->mcc) { + mcc_opt = false; + } liblte_value_2_bits(mcc_opt, ie_ptr, 1); if(true == mcc_opt) @@ -12754,7 +12757,241 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_paging_msg(LIBLTE_BIT_MSG_STRUCT *msg, Document Reference: 36.331 v10.0.0 Section 6.2.2 *********************************************************************/ -// FIXME +LIBLTE_ERROR_ENUM liblte_rrc_pack_cgi_info_ie(LIBLTE_RRC_CGI_INFO_STRUCT *cgi_info, + uint8 **ie_ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(cgi_info != NULL && + ie_ptr != NULL) + { + liblte_value_2_bits(cgi_info->have_plmn_identity_list, ie_ptr, 1); + liblte_rrc_pack_cell_global_id_eutra_ie(&cgi_info->cell_global_id, ie_ptr); + liblte_rrc_pack_tracking_area_code_ie(cgi_info->tracking_area_code, ie_ptr); + if(cgi_info->have_plmn_identity_list) { + liblte_value_2_bits(cgi_info->n_plmn_identity_list-1, ie_ptr, 3); + for(uint32 i=0; in_plmn_identity_list; i++) { + liblte_rrc_pack_plmn_identity_ie(&cgi_info->plmn_identity_list[i], ie_ptr); + } + } + + err = LIBLTE_SUCCESS; + } + + return(err); +} +LIBLTE_ERROR_ENUM liblte_rrc_unpack_cgi_info_ie(uint8 **ie_ptr, + LIBLTE_RRC_CGI_INFO_STRUCT *cgi_info) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie_ptr != NULL && + cgi_info != NULL) + { + cgi_info->have_plmn_identity_list = (bool)liblte_bits_2_value(ie_ptr, 1); + liblte_rrc_unpack_cell_global_id_eutra_ie(ie_ptr, &cgi_info->cell_global_id); + liblte_rrc_unpack_tracking_area_code_ie(ie_ptr, &cgi_info->tracking_area_code); + if(cgi_info->have_plmn_identity_list) { + cgi_info->n_plmn_identity_list = liblte_bits_2_value(ie_ptr, 3) + 1; + for(uint32 i=0; in_plmn_identity_list; i++) { + liblte_rrc_unpack_plmn_identity_ie(ie_ptr, &cgi_info->plmn_identity_list[i]); + } + } + err = LIBLTE_SUCCESS; + } + + return(err); +} + +LIBLTE_ERROR_ENUM liblte_rrc_pack_meas_result_ie(LIBLTE_RRC_MEAS_RESULT_STRUCT *meas_result, + uint8 **ie_ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(meas_result != NULL && + ie_ptr != NULL) + { + //ext + liblte_value_2_bits(0, ie_ptr, 1); + + //options + liblte_value_2_bits(meas_result->have_rsrp, ie_ptr, 1); + liblte_value_2_bits(meas_result->have_rsrq, ie_ptr, 1); + + if(meas_result->have_rsrp) { + liblte_rrc_pack_rsrp_range_ie(meas_result->rsrp_result, ie_ptr); + } + if(meas_result->have_rsrq) { + liblte_rrc_pack_rsrq_range_ie(meas_result->rsrq_result, ie_ptr); + } + + err = LIBLTE_SUCCESS; + } + + return(err); +} +LIBLTE_ERROR_ENUM liblte_rrc_unpack_meas_result_ie(uint8 **ie_ptr, + LIBLTE_RRC_MEAS_RESULT_STRUCT *meas_result) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie_ptr != NULL && + meas_result != NULL) + { + //ext + bool ext = liblte_bits_2_value(ie_ptr, 1); + + //options + meas_result->have_rsrp = liblte_bits_2_value(ie_ptr, 1); + meas_result->have_rsrq = liblte_bits_2_value(ie_ptr, 1); + + if(meas_result->have_rsrp) { + liblte_rrc_unpack_rsrp_range_ie(ie_ptr, &meas_result->rsrp_result); + } + if(meas_result->have_rsrq) { + liblte_rrc_unpack_rsrq_range_ie(ie_ptr, &meas_result->rsrq_result); + } + + //skip extensions + liblte_rrc_consume_noncrit_extension(ext, __func__, ie_ptr); + + err = LIBLTE_SUCCESS; + } + + return(err); +} + +LIBLTE_ERROR_ENUM liblte_rrc_pack_meas_result_eutra_ie(LIBLTE_RRC_MEAS_RESULT_EUTRA_STRUCT *meas_result_eutra, + uint8 **ie_ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(meas_result_eutra != NULL && + ie_ptr != NULL) + { + liblte_value_2_bits(meas_result_eutra->have_cgi_info, ie_ptr, 1); + liblte_rrc_pack_phys_cell_id_ie(meas_result_eutra->phys_cell_id, ie_ptr); + if(meas_result_eutra->have_cgi_info) { + liblte_rrc_pack_cgi_info_ie(&meas_result_eutra->cgi_info, ie_ptr); + } + liblte_rrc_pack_meas_result_ie(&meas_result_eutra->meas_result, ie_ptr); + + err = LIBLTE_SUCCESS; + } + + return(err); +} +LIBLTE_ERROR_ENUM liblte_rrc_unpack_meas_result_eutra_ie(uint8 **ie_ptr, + LIBLTE_RRC_MEAS_RESULT_EUTRA_STRUCT *meas_result_eutra) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie_ptr != NULL && + meas_result_eutra != NULL) + { + meas_result_eutra->have_cgi_info = liblte_bits_2_value(ie_ptr, 1); + liblte_rrc_unpack_phys_cell_id_ie(ie_ptr, &meas_result_eutra->phys_cell_id); + if(meas_result_eutra->have_cgi_info) { + liblte_rrc_unpack_cgi_info_ie(ie_ptr, &meas_result_eutra->cgi_info); + } + liblte_rrc_unpack_meas_result_ie(ie_ptr, &meas_result_eutra->meas_result); + + err = LIBLTE_SUCCESS; + } + + return(err); +} + +LIBLTE_ERROR_ENUM liblte_rrc_pack_measurement_report_msg(LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *meas_report, + LIBLTE_BIT_MSG_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8 *msg_ptr = msg->msg; + + if(meas_report != NULL && + msg != NULL) + { + //MeasurementReport + liblte_value_2_bits(0, &msg_ptr, 1); //critical extensions + liblte_value_2_bits(0, &msg_ptr, 3); //c1 + + //MeasurementReport-r8-IEs + liblte_value_2_bits(0, &msg_ptr, 1); //non-critical extensions + + //MeasResults + liblte_value_2_bits(0, &msg_ptr, 1); //ext + liblte_value_2_bits(meas_report->have_meas_result_neigh_cells, &msg_ptr, 1); + liblte_rrc_pack_meas_id_ie(meas_report->meas_id, &msg_ptr); + liblte_rrc_pack_rsrp_range_ie(meas_report->pcell_rsrp_result, &msg_ptr); + liblte_rrc_pack_rsrq_range_ie(meas_report->pcell_rsrq_result, &msg_ptr); + if(meas_report->have_meas_result_neigh_cells) { + liblte_value_2_bits(0, &msg_ptr, 1); //choice from before extension marker + liblte_value_2_bits(meas_report->meas_result_neigh_cells_choice, &msg_ptr, 2); + if(meas_report->meas_result_neigh_cells_choice != LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA) { + printf("NOT HANDLING %s\n", liblte_rrc_meas_reult_neigh_cells_text[meas_report->meas_result_neigh_cells_choice]); + } else { + //MeasResultListEUTRA + liblte_value_2_bits(meas_report->meas_result_neigh_cells.eutra.n_result-1, &msg_ptr, 3); + for(uint32 i=0; imeas_result_neigh_cells.eutra.n_result; i++) { + liblte_rrc_pack_meas_result_eutra_ie(&meas_report->meas_result_neigh_cells.eutra.result_eutra_list[i], &msg_ptr); + } + } + } + + // Fill in the number of bits used + msg->N_bits = msg_ptr - msg->msg; + + err = LIBLTE_SUCCESS; + } + + return(err); +} +LIBLTE_ERROR_ENUM liblte_rrc_unpack_measurement_report_msg(LIBLTE_BIT_MSG_STRUCT *msg, + LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *meas_report) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8 *msg_ptr = msg->msg; + + if(msg != NULL && + meas_report != NULL) + { + //MeasurementReport + bool crit_ext = liblte_bits_2_value(&msg_ptr, 1); //critical extensions + liblte_bits_2_value(&msg_ptr, 3); //c1 + + //MeasurementReport-r8-IEs + bool non_crit_ext = liblte_bits_2_value(&msg_ptr, 1); //non-critical extensions + + //MeasResults + bool ext = liblte_bits_2_value(&msg_ptr, 1); + meas_report->have_meas_result_neigh_cells = liblte_bits_2_value(&msg_ptr, 1); + liblte_rrc_unpack_meas_id_ie(&msg_ptr, &meas_report->meas_id); + liblte_rrc_unpack_rsrp_range_ie(&msg_ptr, &meas_report->pcell_rsrp_result); + liblte_rrc_unpack_rsrq_range_ie(&msg_ptr, &meas_report->pcell_rsrq_result); + if(meas_report->have_meas_result_neigh_cells) { + liblte_bits_2_value(&msg_ptr, 1); //choice from before extension marker + meas_report->meas_result_neigh_cells_choice = (LIBLTE_RRC_MEAS_RESULT_NEIGH_CELLS_ENUM) liblte_bits_2_value(&msg_ptr, 2); + if(meas_report->meas_result_neigh_cells_choice != LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA) { + printf("NOT HANDLING %s\n", liblte_rrc_meas_reult_neigh_cells_text[meas_report->meas_result_neigh_cells_choice]); + } else { + //MeasResultListEUTRA + meas_report->meas_result_neigh_cells.eutra.n_result = liblte_bits_2_value(&msg_ptr, 3) + 1; + for(uint32 i=0; imeas_result_neigh_cells.eutra.n_result; i++) { + liblte_rrc_unpack_meas_result_eutra_ie(&msg_ptr, &meas_report->meas_result_neigh_cells.eutra.result_eutra_list[i]); + } + } + } + + //skip extensions + liblte_rrc_consume_noncrit_extension(crit_ext, __func__, &msg_ptr); + liblte_rrc_consume_noncrit_extension(non_crit_ext, __func__, &msg_ptr); + liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); + + err = LIBLTE_SUCCESS; + } + + return(err); +} /********************************************************************* Message Name: MBSFN Area Configuration @@ -13550,9 +13787,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_ul_dcch_msg(LIBLTE_RRC_UL_DCCH_MSG_STRUCT *ul_ err = liblte_rrc_pack_csfb_parameters_request_cdma2000_msg((LIBLTE_RRC_CSFB_PARAMETERS_REQUEST_CDMA2000_STRUCT *)&ul_dcch_msg->msg, &global_msg); }else if(LIBLTE_RRC_UL_DCCH_MSG_TYPE_MEASUREMENT_REPORT == ul_dcch_msg->msg_type){ - printf("NOT HANDLING MEASUREMENT REPORT\n"); -// err = liblte_rrc_pack_measurement_report_msg((LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *)&ul_dcch_msg->msg, -// &global_msg); + err = liblte_rrc_pack_measurement_report_msg((LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *)&ul_dcch_msg->msg, + &global_msg); }else if(LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE == ul_dcch_msg->msg_type){ err = liblte_rrc_pack_rrc_connection_reconfiguration_complete_msg((LIBLTE_RRC_CONNECTION_RECONFIGURATION_COMPLETE_STRUCT *)&ul_dcch_msg->msg, &global_msg); @@ -13630,9 +13866,8 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_ul_dcch_msg(LIBLTE_BIT_MSG_STRUCT *m err = liblte_rrc_unpack_csfb_parameters_request_cdma2000_msg(&global_msg, (LIBLTE_RRC_CSFB_PARAMETERS_REQUEST_CDMA2000_STRUCT *)&ul_dcch_msg->msg); }else if(LIBLTE_RRC_UL_DCCH_MSG_TYPE_MEASUREMENT_REPORT == ul_dcch_msg->msg_type){ - printf("NOT HANDLING MEASUREMENT REPORT\n"); -// err = liblte_rrc_unpack_measurement_report_msg(&global_msg, -// (LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *)&ul_dcch_msg->msg); + err = liblte_rrc_unpack_measurement_report_msg(&global_msg, + (LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *)&ul_dcch_msg->msg); }else if(LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE == ul_dcch_msg->msg_type){ err = liblte_rrc_unpack_rrc_connection_reconfiguration_complete_msg(&global_msg, (LIBLTE_RRC_CONNECTION_RECONFIGURATION_COMPLETE_STRUCT *)&ul_dcch_msg->msg); diff --git a/lib/test/CMakeLists.txt b/lib/test/CMakeLists.txt index a1af8153c..72e9e9100 100644 --- a/lib/test/CMakeLists.txt +++ b/lib/test/CMakeLists.txt @@ -18,5 +18,6 @@ # and at http://www.gnu.org/licenses/. # +add_subdirectory(asn1) add_subdirectory(common) add_subdirectory(upper) diff --git a/lib/test/asn1/CMakeLists.txt b/lib/test/asn1/CMakeLists.txt new file mode 100644 index 000000000..6c52d1972 --- /dev/null +++ b/lib/test/asn1/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# 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/. +# + +add_executable(rrc_meas_test rrc_meas_test.cc) +target_link_libraries(rrc_meas_test srslte_common srslte_phy srslte_asn1) +add_test(rrc_meas_test rrc_meas_test) diff --git a/lib/test/asn1/rrc_meas_test.cc b/lib/test/asn1/rrc_meas_test.cc new file mode 100644 index 000000000..63a4d61b6 --- /dev/null +++ b/lib/test/asn1/rrc_meas_test.cc @@ -0,0 +1,91 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE 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. + * + * srsUE 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 +#include +#include "srslte/common/log_filter.h" +#include "srslte/asn1/liblte_rrc.h" + + +void basic_test() { + srslte::log_filter log1("RRC"); + log1.set_level(srslte::LOG_LEVEL_DEBUG); + log1.set_hex_limit(128); + + LIBLTE_BIT_MSG_STRUCT bit_buf; + LIBLTE_BIT_MSG_STRUCT bit_buf2; + LIBLTE_BYTE_MSG_STRUCT byte_buf; + LIBLTE_RRC_UL_DCCH_MSG_STRUCT ul_dcch_msg; + + uint32_t rrc_message_len = 18; + uint8_t rrc_message[] = {0x08, 0x10, 0x49, 0x3C, 0x0D, 0x97, 0x89, 0x83, + 0xC0, 0x84, 0x20, 0x82, 0x08, 0x21, 0x00, 0x01, + 0xBC, 0x48}; + + srslte_bit_unpack_vector(rrc_message, bit_buf.msg, rrc_message_len*8); + bit_buf.N_bits = rrc_message_len*8; + liblte_rrc_unpack_ul_dcch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &ul_dcch_msg); + + assert(ul_dcch_msg.msg_type == LIBLTE_RRC_UL_DCCH_MSG_TYPE_MEASUREMENT_REPORT); + LIBLTE_RRC_MEASUREMENT_REPORT_STRUCT *rep = &ul_dcch_msg.msg.measurement_report; + assert(rep->meas_id == 1); + assert(rep->pcell_rsrp_result == 73); + assert(rep->pcell_rsrq_result == 15); + assert(rep->have_meas_result_neigh_cells); + assert(rep->meas_result_neigh_cells_choice == LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA); + LIBLTE_RRC_MEAS_RESULT_LIST_EUTRA_STRUCT *eutra = &rep->meas_result_neigh_cells.eutra; + assert(eutra->n_result == 1); + assert(eutra->result_eutra_list[0].phys_cell_id == 357); + assert(eutra->result_eutra_list[0].have_cgi_info); + assert(eutra->result_eutra_list[0].cgi_info.have_plmn_identity_list); + assert(eutra->result_eutra_list[0].cgi_info.cell_global_id.plmn_id.mcc == 0xF898); + assert(eutra->result_eutra_list[0].cgi_info.cell_global_id.plmn_id.mnc == 0xFF78); + assert(eutra->result_eutra_list[0].cgi_info.cell_global_id.cell_id == 0x1084104); + assert(eutra->result_eutra_list[0].cgi_info.tracking_area_code == 0x1042); + assert(eutra->result_eutra_list[0].cgi_info.have_plmn_identity_list); + assert(eutra->result_eutra_list[0].cgi_info.n_plmn_identity_list == 1); + assert(eutra->result_eutra_list[0].cgi_info.plmn_identity_list[0].mcc == 0xFFFF); + assert(eutra->result_eutra_list[0].cgi_info.plmn_identity_list[0].mnc == 0xFF00); + assert(eutra->result_eutra_list[0].meas_result.have_rsrp); + assert(eutra->result_eutra_list[0].meas_result.rsrp_result == 60); + assert(eutra->result_eutra_list[0].meas_result.have_rsrp); + assert(eutra->result_eutra_list[0].meas_result.rsrq_result == 18); + + liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT*)&bit_buf2); + srslte_bit_pack_vector(bit_buf2.msg, byte_buf.msg, bit_buf2.N_bits); + byte_buf.N_bytes = (bit_buf2.N_bits+7)/8; + log1.info_hex(byte_buf.msg, byte_buf.N_bytes, "UL_DCCH Packed message\n"); + + for(uint32_t i=0; i