From 7e294f73250f21a29292957466aba3eca6e6c696 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 18 Dec 2019 13:04:02 +0100 Subject: [PATCH] move common helper for eNB tests into own header file and split mobility and erab tests --- srsenb/test/upper/CMakeLists.txt | 5 + srsenb/test/upper/erab_setup_test.cc | 123 ++++++++++++ srsenb/test/upper/rrc_mobility_test.cc | 253 +------------------------ srsenb/test/upper/test_helpers.h | 197 +++++++++++++++++++ 4 files changed, 327 insertions(+), 251 deletions(-) create mode 100644 srsenb/test/upper/erab_setup_test.cc create mode 100644 srsenb/test/upper/test_helpers.h diff --git a/srsenb/test/upper/CMakeLists.txt b/srsenb/test/upper/CMakeLists.txt index 9a4797348..2e3b5e295 100644 --- a/srsenb/test/upper/CMakeLists.txt +++ b/srsenb/test/upper/CMakeLists.txt @@ -25,4 +25,9 @@ target_link_libraries(plmn_test rrc_asn1) add_executable(rrc_mobility_test rrc_mobility_test.cc) target_link_libraries(rrc_mobility_test srsenb_rrc rrc_asn1 srslte_common srslte_asn1 enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) +add_executable(erab_setup_test erab_setup_test.cc) +target_link_libraries(erab_setup_test srsenb_rrc rrc_asn1 srslte_common srslte_asn1 enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) + add_test(rrc_mobility_test rrc_mobility_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) +add_test(erab_setup_test erab_setup_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) + diff --git a/srsenb/test/upper/erab_setup_test.cc b/srsenb/test/upper/erab_setup_test.cc new file mode 100644 index 000000000..de668e617 --- /dev/null +++ b/srsenb/test/upper/erab_setup_test.cc @@ -0,0 +1,123 @@ +/* + * Copyright 2013-2019 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/. + * + */ + +#include "srsenb/hdr/enb.h" +#include "srsenb/src/enb_cfg_parser.h" +#include "srslte/asn1/rrc_asn1_utils.h" +#include "srslte/common/test_common.h" +#include "test_helpers.h" +#include + +int test_erab_setup(bool qci_exists) +{ + printf("\n===== TEST: test_erab_setup() =====\n"); + srslte::scoped_tester_log rrc_log("RRC "); + srslte::timer_handler timers; + srslte::unique_byte_buffer_t pdu; + + srsenb::all_args_t args; + rrc_cfg_t cfg; + TESTASSERT(test_helpers::parse_default_cfg(&cfg, args) == SRSLTE_SUCCESS); + + srsenb::rrc rrc; + mac_dummy mac; + rlc_dummy rlc; + test_dummies::pdcp_mobility_dummy pdcp; + phy_dummy phy; + test_dummies::s1ap_mobility_dummy s1ap; + gtpu_dummy gtpu; + rrc_log.set_level(srslte::LOG_LEVEL_INFO); + rrc_log.set_hex_limit(1024); + rrc.init(&cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, &rrc_log); + + auto tic = [&timers, &rrc] { + timers.step_all(); + rrc.tti_clock(); + }; + + uint16_t rnti = 0x46; + rrc.add_user(rnti); + + rrc_log.set_level(srslte::LOG_LEVEL_NONE); // mute all the startup log + + // Do all the handshaking until the first RRC Connection Reconf + test_helpers::bring_rrc_to_reconf_state(rrc, timers, rnti); + + rrc_log.set_level(srslte::LOG_LEVEL_DEBUG); + rrc_log.set_hex_limit(1024); + + // MME sends 2nd ERAB Setup request for DRB2 (QCI exists in config) + uint8_t drb2_erab_setup_request_ok[] = { + 0x00, 0x05, 0x00, 0x66, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x10, 0x00, 0x53, 0x00, 0x00, 0x11, 0x00, 0x4e, 0x0c, 0x00, 0x09, 0x21, 0x0f, 0x80, 0x7f, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x3f, 0x27, 0x67, 0x90, 0x99, 0xf5, 0x05, 0x62, 0x02, 0xc1, 0x01, 0x09, + 0x09, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x05, 0x01, 0x2d, 0x2d, 0x00, 0x0b, 0x27, 0x22, + 0x80, 0x80, 0x21, 0x10, 0x02, 0x00, 0x00, 0x10, 0x81, 0x06, 0x08, 0x08, 0x08, 0x08, 0x83, 0x06, 0x08, 0x08, + 0x04, 0x04, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x04, 0x04}; + + // QCI doesn't exist (in default eNB DRB config) + uint8_t drb2_erab_setup_request_fail[] = { + 0x00, 0x05, 0x00, 0x75, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x3b, 0x9a, 0xca, 0x00, 0x60, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x10, 0x00, + 0x54, 0x00, 0x00, 0x11, 0x00, 0x4f, 0x0c, 0x00, 0x05, 0x3c, 0x0f, 0x80, 0x7f, 0x00, 0x01, 0x64, 0xb3, 0xce, + 0xf1, 0xc9, 0x40, 0x27, 0xfe, 0x2a, 0x3b, 0xd1, 0x03, 0x62, 0x70, 0xc1, 0x01, 0x05, 0x17, 0x03, 0x69, 0x6d, + 0x73, 0x06, 0x6d, 0x6e, 0x63, 0x30, 0x37, 0x30, 0x06, 0x6d, 0x63, 0x63, 0x39, 0x30, 0x31, 0x04, 0x67, 0x70, + 0x72, 0x73, 0x05, 0x01, 0xc0, 0xa8, 0x04, 0x02, 0x27, 0x15, 0x80, 0x80, 0x21, 0x0a, 0x03, 0x00, 0x00, 0x0a, + 0x81, 0x06, 0x08, 0x08, 0x08, 0x08, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x08, 0x08}; + + LIBLTE_S1AP_S1AP_PDU_STRUCT s1ap_pdu; + LIBLTE_BYTE_MSG_STRUCT byte_buf; + if (qci_exists) { + byte_buf.N_bytes = sizeof(drb2_erab_setup_request_ok); + memcpy(byte_buf.msg, drb2_erab_setup_request_ok, byte_buf.N_bytes); + } else { + byte_buf.N_bytes = sizeof(drb2_erab_setup_request_fail); + memcpy(byte_buf.msg, drb2_erab_setup_request_fail, byte_buf.N_bytes); + } + + liblte_s1ap_unpack_s1ap_pdu(&byte_buf, &s1ap_pdu); + rrc.setup_ue_erabs(rnti, &s1ap_pdu.choice.initiatingMessage.choice.E_RABSetupRequest); + + if (qci_exists) { + TESTASSERT(rrc_log.error_counter == 0); + } else { + TESTASSERT(rrc_log.error_counter == 2); + } + + return SRSLTE_SUCCESS; +} + +int main(int argc, char** argv) +{ + log_h.set_level(srslte::LOG_LEVEL_INFO); + + if (argc < 3) { + argparse::usage(argv[0]); + return -1; + } + argparse::parse_args(argc, argv); + TESTASSERT(test_erab_setup(true) == SRSLTE_SUCCESS); + TESTASSERT(test_erab_setup(false) == SRSLTE_SUCCESS); + + printf("\nSuccess\n"); + + return 0; +} diff --git a/srsenb/test/upper/rrc_mobility_test.cc b/srsenb/test/upper/rrc_mobility_test.cc index 0beabcee9..ecf5a5df5 100644 --- a/srsenb/test/upper/rrc_mobility_test.cc +++ b/srsenb/test/upper/rrc_mobility_test.cc @@ -25,91 +25,10 @@ #include "srsenb/test/common/dummy_classes.h" #include "srslte/asn1/rrc_asn1_utils.h" #include "srslte/common/test_common.h" +#include "test_helpers.h" #include #include -using namespace srsenb; -using namespace asn1::rrc; - -srslte::scoped_tester_log log_h("ALL"); - -namespace argparse { - -std::string repository_dir; -srslte::LOG_LEVEL_ENUM log_level; - -void usage(char* prog) -{ - printf("Usage: %s [v] -i repository_dir\n", prog); - printf("\t-v [set srslte_verbose to debug, default none]\n"); -} - -void parse_args(int argc, char** argv) -{ - int opt; - - while ((opt = getopt(argc, argv, "i")) != -1) { - switch (opt) { - case 'i': - repository_dir = argv[optind]; - break; - case 'v': - log_level = srslte::LOG_LEVEL_DEBUG; - break; - default: - usage(argv[0]); - exit(-1); - } - } - if (repository_dir.empty()) { - usage(argv[0]); - exit(-1); - } -} - -} // namespace argparse - -namespace test_dummies { - -class s1ap_mobility_dummy : public s1ap_dummy -{ -public: - struct ho_req_data { - uint16_t rnti; - uint32_t target_eci; - srslte::plmn_id_t target_plmn; - srslte::unique_byte_buffer_t rrc_container; - } last_ho_required; - - bool send_ho_required(uint16_t rnti, - uint32_t target_eci, - srslte::plmn_id_t target_plmn, - srslte::unique_byte_buffer_t rrc_container) final - { - last_ho_required = ho_req_data{rnti, target_eci, target_plmn, std::move(rrc_container)}; - return true; - } -}; - -class pdcp_mobility_dummy : public pdcp_dummy -{ -public: - struct last_sdu_t { - uint16_t rnti; - uint32_t lcid; - srslte::unique_byte_buffer_t sdu; - } last_sdu; - - void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override - { - last_sdu.rnti = rnti; - last_sdu.lcid = lcid; - last_sdu.sdu = std::move(sdu); - } -}; - -} // namespace test_dummies - meas_cell_cfg_t generate_cell1() { meas_cell_cfg_t cell1{}; @@ -451,85 +370,6 @@ int test_mobility_class(mobility_test_params test_params) return SRSLTE_SUCCESS; } -int test_erab_setup(bool qci_exists) -{ - printf("\n===== TEST: test_erab_setup() =====\n"); - srslte::scoped_tester_log rrc_log("RRC "); - srslte::timer_handler timers; - srslte::unique_byte_buffer_t pdu; - - srsenb::all_args_t args; - rrc_cfg_t cfg; - TESTASSERT(test_helpers::parse_default_cfg(&cfg, args) == SRSLTE_SUCCESS); - - srsenb::rrc rrc; - mac_dummy mac; - rlc_dummy rlc; - test_dummies::pdcp_mobility_dummy pdcp; - phy_dummy phy; - test_dummies::s1ap_mobility_dummy s1ap; - gtpu_dummy gtpu; - rrc_log.set_level(srslte::LOG_LEVEL_INFO); - rrc_log.set_hex_limit(1024); - rrc.init(&cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, &rrc_log); - - auto tic = [&timers, &rrc] { - timers.step_all(); - rrc.tti_clock(); - }; - - uint16_t rnti = 0x46; - rrc.add_user(rnti); - - rrc_log.set_level(srslte::LOG_LEVEL_NONE); // mute all the startup log - - // Do all the handshaking until the first RRC Connection Reconf - test_helpers::bring_rrc_to_reconf_state(rrc, timers, rnti); - - rrc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rrc_log.set_hex_limit(1024); - - // MME sends 2nd ERAB Setup request for DRB2 (QCI exists in config) - uint8_t drb2_erab_setup_request_ok[] = { - 0x00, 0x05, 0x00, 0x66, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x02, 0x00, 0x10, 0x00, 0x53, 0x00, 0x00, 0x11, 0x00, 0x4e, 0x0c, 0x00, 0x09, 0x21, 0x0f, 0x80, 0x7f, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x3f, 0x27, 0x67, 0x90, 0x99, 0xf5, 0x05, 0x62, 0x02, 0xc1, 0x01, 0x09, - 0x09, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x05, 0x01, 0x2d, 0x2d, 0x00, 0x0b, 0x27, 0x22, - 0x80, 0x80, 0x21, 0x10, 0x02, 0x00, 0x00, 0x10, 0x81, 0x06, 0x08, 0x08, 0x08, 0x08, 0x83, 0x06, 0x08, 0x08, - 0x04, 0x04, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x04, 0x04}; - - // QCI doesn't exist (in default eNB DRB config) - uint8_t drb2_erab_setup_request_fail[] = { - 0x00, 0x05, 0x00, 0x75, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x01, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x3b, 0x9a, 0xca, 0x00, 0x60, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x10, 0x00, - 0x54, 0x00, 0x00, 0x11, 0x00, 0x4f, 0x0c, 0x00, 0x05, 0x3c, 0x0f, 0x80, 0x7f, 0x00, 0x01, 0x64, 0xb3, 0xce, - 0xf1, 0xc9, 0x40, 0x27, 0xfe, 0x2a, 0x3b, 0xd1, 0x03, 0x62, 0x70, 0xc1, 0x01, 0x05, 0x17, 0x03, 0x69, 0x6d, - 0x73, 0x06, 0x6d, 0x6e, 0x63, 0x30, 0x37, 0x30, 0x06, 0x6d, 0x63, 0x63, 0x39, 0x30, 0x31, 0x04, 0x67, 0x70, - 0x72, 0x73, 0x05, 0x01, 0xc0, 0xa8, 0x04, 0x02, 0x27, 0x15, 0x80, 0x80, 0x21, 0x0a, 0x03, 0x00, 0x00, 0x0a, - 0x81, 0x06, 0x08, 0x08, 0x08, 0x08, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x08, 0x08}; - - LIBLTE_S1AP_S1AP_PDU_STRUCT s1ap_pdu; - LIBLTE_BYTE_MSG_STRUCT byte_buf; - if (qci_exists) { - byte_buf.N_bytes = sizeof(drb2_erab_setup_request_ok); - memcpy(byte_buf.msg, drb2_erab_setup_request_ok, byte_buf.N_bytes); - } else { - byte_buf.N_bytes = sizeof(drb2_erab_setup_request_fail); - memcpy(byte_buf.msg, drb2_erab_setup_request_fail, byte_buf.N_bytes); - } - - liblte_s1ap_unpack_s1ap_pdu(&byte_buf, &s1ap_pdu); - rrc.setup_ue_erabs(rnti, &s1ap_pdu.choice.initiatingMessage.choice.E_RABSetupRequest); - - if (qci_exists) { - TESTASSERT(rrc_log.error_counter == 0); - } else { - TESTASSERT(rrc_log.error_counter == 2); - } - - return SRSLTE_SUCCESS; -} - int main(int argc, char** argv) { log_h.set_level(srslte::LOG_LEVEL_INFO); @@ -545,97 +385,8 @@ int main(int argc, char** argv) TESTASSERT(test_mobility_class(mobility_test_params{mobility_test_params::test_fail_at::concurrent_ho}) == 0); TESTASSERT(test_mobility_class(mobility_test_params{mobility_test_params::test_fail_at::ho_prep_failure}) == 0); TESTASSERT(test_mobility_class(mobility_test_params{mobility_test_params::test_fail_at::success}) == 0); - TESTASSERT(test_erab_setup(true) == SRSLTE_SUCCESS); - TESTASSERT(test_erab_setup(false) == SRSLTE_SUCCESS); printf("\nSuccess\n"); return 0; -} - -namespace test_helpers { - -int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args) -{ - args = {}; - *rrc_cfg = {}; - args.enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; - args.enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; - args.enb_files.drb_config = argparse::repository_dir + "/drb.conf.example"; - log_h.debug("sib file path=%s\n", args.enb_files.sib_config.c_str()); - - args.enb.dl_earfcn = 3400; - args.enb.n_prb = 50; - TESTASSERT(srslte::string_to_mcc("001", &args.stack.s1ap.mcc)); - TESTASSERT(srslte::string_to_mnc("01", &args.stack.s1ap.mnc)); - args.enb.transmission_mode = 1; - args.enb.nof_ports = 1; - args.general.eia_pref_list = "EIA2, EIA1, EIA0"; - args.general.eea_pref_list = "EEA0, EEA2, EEA1"; - - phy_cfg_t phy_cfg; - - return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &phy_cfg); -} - -void copy_msg_to_buffer(srslte::unique_byte_buffer_t& pdu, uint8_t* msg, size_t nof_bytes) -{ - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdu = srslte::allocate_unique_buffer(*pool, true); - memcpy(pdu->msg, msg, nof_bytes); - pdu->N_bytes = nof_bytes; -}; - -int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, uint16_t rnti) -{ - srslte::unique_byte_buffer_t pdu; - - // Send RRCConnectionRequest - uint8_t rrc_conn_request[] = {0x40, 0x12, 0xf6, 0xfb, 0xe2, 0xc6}; - copy_msg_to_buffer(pdu, rrc_conn_request, sizeof(rrc_conn_request)); - rrc.write_pdu(rnti, 0, std::move(pdu)); - timers.step_all(); - rrc.tti_clock(); - - // Send RRCConnectionSetupComplete - uint8_t rrc_conn_setup_complete[] = {0x20, 0x00, 0x40, 0x2e, 0x90, 0x50, 0x49, 0xe8, 0x06, 0x0e, 0x82, 0xa2, - 0x17, 0xec, 0x13, 0xe2, 0x0f, 0x00, 0x02, 0x02, 0x5e, 0xdf, 0x7c, 0x58, - 0x05, 0xc0, 0xc0, 0x00, 0x08, 0x04, 0x03, 0xa0, 0x23, 0x23, 0xc0}; - copy_msg_to_buffer(pdu, rrc_conn_setup_complete, sizeof(rrc_conn_setup_complete)); - rrc.write_pdu(rnti, 1, std::move(pdu)); - timers.step_all(); - rrc.tti_clock(); - - // S1AP receives InitialContextSetupRequest and forwards it to RRC - uint8_t s1ap_init_ctxt_setup_req[] = { - 0x00, 0x09, 0x00, 0x80, 0xc6, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x01, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x3b, 0x9a, 0xca, 0x00, 0x60, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x18, 0x00, 0x78, - 0x00, 0x00, 0x34, 0x00, 0x73, 0x45, 0x00, 0x09, 0x3c, 0x0f, 0x80, 0x0a, 0x00, 0x21, 0xf0, 0xb7, 0x36, 0x1c, 0x56, - 0x64, 0x27, 0x3e, 0x5b, 0x04, 0xb7, 0x02, 0x07, 0x42, 0x02, 0x3e, 0x06, 0x00, 0x09, 0xf1, 0x07, 0x00, 0x07, 0x00, - 0x37, 0x52, 0x66, 0xc1, 0x01, 0x09, 0x1b, 0x07, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33, 0x06, 0x6d, 0x6e, 0x63, - 0x30, 0x37, 0x30, 0x06, 0x6d, 0x63, 0x63, 0x39, 0x30, 0x31, 0x04, 0x67, 0x70, 0x72, 0x73, 0x05, 0x01, 0xc0, 0xa8, - 0x03, 0x02, 0x27, 0x0e, 0x80, 0x80, 0x21, 0x0a, 0x03, 0x00, 0x00, 0x0a, 0x81, 0x06, 0x08, 0x08, 0x08, 0x08, 0x50, - 0x0b, 0xf6, 0x09, 0xf1, 0x07, 0x80, 0x01, 0x01, 0xf6, 0x7e, 0x72, 0x69, 0x13, 0x09, 0xf1, 0x07, 0x00, 0x01, 0x23, - 0x05, 0xf4, 0xf6, 0x7e, 0x72, 0x69, 0x00, 0x6b, 0x00, 0x05, 0x18, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x49, 0x00, 0x20, - 0x45, 0x25, 0xe4, 0x9a, 0x77, 0xc8, 0xd5, 0xcf, 0x26, 0x33, 0x63, 0xeb, 0x5b, 0xb9, 0xc3, 0x43, 0x9b, 0x9e, 0xb3, - 0x86, 0x1f, 0xa8, 0xa7, 0xcf, 0x43, 0x54, 0x07, 0xae, 0x42, 0x2b, 0x63, 0xb9}; - LIBLTE_S1AP_S1AP_PDU_STRUCT s1ap_pdu; - LIBLTE_BYTE_MSG_STRUCT byte_buf; - byte_buf.N_bytes = sizeof(s1ap_init_ctxt_setup_req); - memcpy(byte_buf.msg, s1ap_init_ctxt_setup_req, byte_buf.N_bytes); - liblte_s1ap_unpack_s1ap_pdu(&byte_buf, &s1ap_pdu); - rrc.setup_ue_ctxt(rnti, &s1ap_pdu.choice.initiatingMessage.choice.InitialContextSetupRequest); - timers.step_all(); - rrc.tti_clock(); - - // Send SecurityModeComplete - uint8_t sec_mode_complete[] = {0x28, 0x00}; - copy_msg_to_buffer(pdu, sec_mode_complete, sizeof(sec_mode_complete)); - rrc.write_pdu(rnti, 1, std::move(pdu)); - timers.step_all(); - rrc.tti_clock(); - - return SRSLTE_SUCCESS; -} - -} // namespace test_helpers +} \ No newline at end of file diff --git a/srsenb/test/upper/test_helpers.h b/srsenb/test/upper/test_helpers.h new file mode 100644 index 000000000..aae4ab794 --- /dev/null +++ b/srsenb/test/upper/test_helpers.h @@ -0,0 +1,197 @@ +/* + * Copyright 2013-2019 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/. + * + */ + +#ifndef SRSENB_TEST_HELPERS_H +#define SRSENB_TEST_HELPERS_H + +#include "srsenb/test/common/dummy_classes.h" +#include + +using namespace srsenb; +using namespace asn1::rrc; + +srslte::scoped_tester_log log_h("ALL"); + +namespace argparse { + +std::string repository_dir; +srslte::LOG_LEVEL_ENUM log_level; + +void usage(char* prog) +{ + printf("Usage: %s [v] -i repository_dir\n", prog); + printf("\t-v [set srslte_verbose to debug, default none]\n"); +} + +void parse_args(int argc, char** argv) +{ + int opt; + + while ((opt = getopt(argc, argv, "i")) != -1) { + switch (opt) { + case 'i': + repository_dir = argv[optind]; + break; + case 'v': + log_level = srslte::LOG_LEVEL_DEBUG; + break; + default: + usage(argv[0]); + exit(-1); + } + } + if (repository_dir.empty()) { + usage(argv[0]); + exit(-1); + } +} + +} // namespace argparse + +namespace test_dummies { + +class s1ap_mobility_dummy : public s1ap_dummy +{ +public: + struct ho_req_data { + uint16_t rnti; + uint32_t target_eci; + srslte::plmn_id_t target_plmn; + srslte::unique_byte_buffer_t rrc_container; + } last_ho_required; + + bool send_ho_required(uint16_t rnti, + uint32_t target_eci, + srslte::plmn_id_t target_plmn, + srslte::unique_byte_buffer_t rrc_container) final + { + last_ho_required = ho_req_data{rnti, target_eci, target_plmn, std::move(rrc_container)}; + return true; + } +}; + +class pdcp_mobility_dummy : public pdcp_dummy +{ +public: + struct last_sdu_t { + uint16_t rnti; + uint32_t lcid; + srslte::unique_byte_buffer_t sdu; + } last_sdu; + + void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override + { + last_sdu.rnti = rnti; + last_sdu.lcid = lcid; + last_sdu.sdu = std::move(sdu); + } +}; + +} // namespace test_dummies + +namespace test_helpers { + +int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args) +{ + args = {}; + *rrc_cfg = {}; + args.enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; + args.enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; + args.enb_files.drb_config = argparse::repository_dir + "/drb.conf.example"; + log_h.debug("sib file path=%s\n", args.enb_files.sib_config.c_str()); + + args.enb.dl_earfcn = 3400; + args.enb.n_prb = 50; + TESTASSERT(srslte::string_to_mcc("001", &args.stack.s1ap.mcc)); + TESTASSERT(srslte::string_to_mnc("01", &args.stack.s1ap.mnc)); + args.enb.transmission_mode = 1; + args.enb.nof_ports = 1; + args.general.eia_pref_list = "EIA2, EIA1, EIA0"; + args.general.eea_pref_list = "EEA0, EEA2, EEA1"; + + phy_cfg_t phy_cfg; + + return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &phy_cfg); +} + +void copy_msg_to_buffer(srslte::unique_byte_buffer_t& pdu, uint8_t* msg, size_t nof_bytes) +{ + srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + pdu = srslte::allocate_unique_buffer(*pool, true); + memcpy(pdu->msg, msg, nof_bytes); + pdu->N_bytes = nof_bytes; +}; + +int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, uint16_t rnti) +{ + srslte::unique_byte_buffer_t pdu; + + // Send RRCConnectionRequest + uint8_t rrc_conn_request[] = {0x40, 0x12, 0xf6, 0xfb, 0xe2, 0xc6}; + copy_msg_to_buffer(pdu, rrc_conn_request, sizeof(rrc_conn_request)); + rrc.write_pdu(rnti, 0, std::move(pdu)); + timers.step_all(); + rrc.tti_clock(); + + // Send RRCConnectionSetupComplete + uint8_t rrc_conn_setup_complete[] = {0x20, 0x00, 0x40, 0x2e, 0x90, 0x50, 0x49, 0xe8, 0x06, 0x0e, 0x82, 0xa2, + 0x17, 0xec, 0x13, 0xe2, 0x0f, 0x00, 0x02, 0x02, 0x5e, 0xdf, 0x7c, 0x58, + 0x05, 0xc0, 0xc0, 0x00, 0x08, 0x04, 0x03, 0xa0, 0x23, 0x23, 0xc0}; + copy_msg_to_buffer(pdu, rrc_conn_setup_complete, sizeof(rrc_conn_setup_complete)); + rrc.write_pdu(rnti, 1, std::move(pdu)); + timers.step_all(); + rrc.tti_clock(); + + // S1AP receives InitialContextSetupRequest and forwards it to RRC + uint8_t s1ap_init_ctxt_setup_req[] = { + 0x00, 0x09, 0x00, 0x80, 0xc6, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x3b, 0x9a, 0xca, 0x00, 0x60, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x18, 0x00, 0x78, + 0x00, 0x00, 0x34, 0x00, 0x73, 0x45, 0x00, 0x09, 0x3c, 0x0f, 0x80, 0x0a, 0x00, 0x21, 0xf0, 0xb7, 0x36, 0x1c, 0x56, + 0x64, 0x27, 0x3e, 0x5b, 0x04, 0xb7, 0x02, 0x07, 0x42, 0x02, 0x3e, 0x06, 0x00, 0x09, 0xf1, 0x07, 0x00, 0x07, 0x00, + 0x37, 0x52, 0x66, 0xc1, 0x01, 0x09, 0x1b, 0x07, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33, 0x06, 0x6d, 0x6e, 0x63, + 0x30, 0x37, 0x30, 0x06, 0x6d, 0x63, 0x63, 0x39, 0x30, 0x31, 0x04, 0x67, 0x70, 0x72, 0x73, 0x05, 0x01, 0xc0, 0xa8, + 0x03, 0x02, 0x27, 0x0e, 0x80, 0x80, 0x21, 0x0a, 0x03, 0x00, 0x00, 0x0a, 0x81, 0x06, 0x08, 0x08, 0x08, 0x08, 0x50, + 0x0b, 0xf6, 0x09, 0xf1, 0x07, 0x80, 0x01, 0x01, 0xf6, 0x7e, 0x72, 0x69, 0x13, 0x09, 0xf1, 0x07, 0x00, 0x01, 0x23, + 0x05, 0xf4, 0xf6, 0x7e, 0x72, 0x69, 0x00, 0x6b, 0x00, 0x05, 0x18, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x49, 0x00, 0x20, + 0x45, 0x25, 0xe4, 0x9a, 0x77, 0xc8, 0xd5, 0xcf, 0x26, 0x33, 0x63, 0xeb, 0x5b, 0xb9, 0xc3, 0x43, 0x9b, 0x9e, 0xb3, + 0x86, 0x1f, 0xa8, 0xa7, 0xcf, 0x43, 0x54, 0x07, 0xae, 0x42, 0x2b, 0x63, 0xb9}; + LIBLTE_S1AP_S1AP_PDU_STRUCT s1ap_pdu; + LIBLTE_BYTE_MSG_STRUCT byte_buf; + byte_buf.N_bytes = sizeof(s1ap_init_ctxt_setup_req); + memcpy(byte_buf.msg, s1ap_init_ctxt_setup_req, byte_buf.N_bytes); + liblte_s1ap_unpack_s1ap_pdu(&byte_buf, &s1ap_pdu); + rrc.setup_ue_ctxt(rnti, &s1ap_pdu.choice.initiatingMessage.choice.InitialContextSetupRequest); + timers.step_all(); + rrc.tti_clock(); + + // Send SecurityModeComplete + uint8_t sec_mode_complete[] = {0x28, 0x00}; + copy_msg_to_buffer(pdu, sec_mode_complete, sizeof(sec_mode_complete)); + rrc.write_pdu(rnti, 1, std::move(pdu)); + timers.step_all(); + rrc.tti_clock(); + + return SRSLTE_SUCCESS; +} + +} // namespace test_helpers + +#endif // SRSENB_TEST_HELPERS_H \ No newline at end of file