From ea841f7b324d54c5700562a48f9a090eaccfb68f Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sun, 18 May 2025 09:34:56 +0200 Subject: [PATCH 1/5] Generate compile_commands.json from Bazel Make clangd work --- BUILD | 18 ++++++++++++++++++ MODULE.bazel | 9 +++++++++ 2 files changed, 27 insertions(+) diff --git a/BUILD b/BUILD index cc326d8..d80e152 100644 --- a/BUILD +++ b/BUILD @@ -282,3 +282,21 @@ cc_binary( # breaks the device registration # features = ["-thin_lto"], ) + +load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands") + +refresh_compile_commands( + name = "refresh_compile_commands", + + # Specify the targets of interest. + # For example, specify a dict of targets and any flags required to build. + targets = { + "//:rootcanal": "", + }, + # No need to add flags already in .bazelrc. They're automatically picked up. + # If you don't need flags, a list of targets is also okay, as is a single target string. + # Wildcard patterns, like //... for everything, *are* allowed here, just like a build. + # As are additional targets (+) and subtractions (-), like in bazel query https://docs.bazel.build/versions/main/query.html#expressions + # And if you're working on a header-only library, specify a test or binary target that compiles it. + exclude_external_sources = True, +) diff --git a/MODULE.bazel b/MODULE.bazel index acf896e..02cb7b2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -45,3 +45,12 @@ crate.spec(package = "bytes", version = "1.0.1") crate.from_specs() use_repo(crate, "crates") + +bazel_dep(name = "hedron_compile_commands", dev_dependency = True) +git_override( + module_name = "hedron_compile_commands", + remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git", + commit = "4f28899228fb3ad0126897876f147ca15026151e", + # Replace the commit hash (above) with the latest (https://github.com/hedronvision/bazel-compile-commands-extractor/commits/main). + # Even better, set up Renovate and let it do the work for you (see "Suggestion: Updates" in the README). +) From 9ecec7152db9903d6b6d33c17ac1811009f02a64 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Wed, 23 Jul 2025 22:07:08 +0200 Subject: [PATCH 2/5] Remove unsupported commands from the feature mask Remove some unsupported commands which confuse Zephyr samples and cause them to run into assertions. Sync status from model/controller/dual_mode_controller.cc to model/controller/controller_properties.cc, to prevent host sending commands that make controller assert. --- model/controller/controller_properties.cc | 64 +++++++++++++---------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/model/controller/controller_properties.cc b/model/controller/controller_properties.cc index 62240f4..f232771 100644 --- a/model/controller/controller_properties.cc +++ b/model/controller/controller_properties.cc @@ -143,7 +143,7 @@ static std::array SupportedCommands() { // OpCodeIndex::REMOTE_NAME_REQUEST_CANCEL, OpCodeIndex::READ_REMOTE_SUPPORTED_FEATURES, OpCodeIndex::READ_REMOTE_EXTENDED_FEATURES, OpCodeIndex::READ_REMOTE_VERSION_INFORMATION, OpCodeIndex::READ_CLOCK_OFFSET, - OpCodeIndex::READ_LMP_HANDLE, OpCodeIndex::SETUP_SYNCHRONOUS_CONNECTION, + // OpCodeIndex::READ_LMP_HANDLE, OpCodeIndex::SETUP_SYNCHRONOUS_CONNECTION, OpCodeIndex::ACCEPT_SYNCHRONOUS_CONNECTION, OpCodeIndex::REJECT_SYNCHRONOUS_CONNECTION, OpCodeIndex::IO_CAPABILITY_REQUEST_REPLY, OpCodeIndex::USER_CONFIRMATION_REQUEST_REPLY, OpCodeIndex::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, @@ -171,7 +171,7 @@ static std::array SupportedCommands() { // CONTROLLER_AND_BASEBAND OpCodeIndex::SET_EVENT_MASK, OpCodeIndex::RESET, OpCodeIndex::SET_EVENT_FILTER, - OpCodeIndex::FLUSH, + // OpCodeIndex::FLUSH, // OpCodeIndex::READ_PIN_TYPE, // OpCodeIndex::WRITE_PIN_TYPE, // OpCodeIndex::READ_STORED_LINK_KEY, @@ -185,34 +185,41 @@ static std::array SupportedCommands() { OpCodeIndex::WRITE_INQUIRY_SCAN_ACTIVITY, OpCodeIndex::READ_AUTHENTICATION_ENABLE, OpCodeIndex::WRITE_AUTHENTICATION_ENABLE, OpCodeIndex::READ_CLASS_OF_DEVICE, OpCodeIndex::WRITE_CLASS_OF_DEVICE, OpCodeIndex::READ_VOICE_SETTING, - OpCodeIndex::WRITE_VOICE_SETTING, OpCodeIndex::READ_AUTOMATIC_FLUSH_TIMEOUT, - OpCodeIndex::WRITE_AUTOMATIC_FLUSH_TIMEOUT, + OpCodeIndex::WRITE_VOICE_SETTING, + // OpCodeIndex::READ_AUTOMATIC_FLUSH_TIMEOUT, + // OpCodeIndex::WRITE_AUTOMATIC_FLUSH_TIMEOUT, // OpCodeIndex::READ_NUM_BROADCAST_RETRANSMITS, // OpCodeIndex::WRITE_NUM_BROADCAST_RETRANSMITS, - OpCodeIndex::READ_HOLD_MODE_ACTIVITY, OpCodeIndex::WRITE_HOLD_MODE_ACTIVITY, + // OpCodeIndex::READ_HOLD_MODE_ACTIVITY, OpCodeIndex::WRITE_HOLD_MODE_ACTIVITY, OpCodeIndex::READ_TRANSMIT_POWER_LEVEL, OpCodeIndex::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE, OpCodeIndex::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE, - OpCodeIndex::SET_CONTROLLER_TO_HOST_FLOW_CONTROL, OpCodeIndex::HOST_BUFFER_SIZE, - OpCodeIndex::HOST_NUMBER_OF_COMPLETED_PACKETS, OpCodeIndex::READ_LINK_SUPERVISION_TIMEOUT, + // OpCodeIndex::SET_CONTROLLER_TO_HOST_FLOW_CONTROL, + OpCodeIndex::HOST_BUFFER_SIZE, + // OpCodeIndex::HOST_NUMBER_OF_COMPLETED_PACKETS, OpCodeIndex::READ_LINK_SUPERVISION_TIMEOUT, OpCodeIndex::WRITE_LINK_SUPERVISION_TIMEOUT, OpCodeIndex::READ_NUMBER_OF_SUPPORTED_IAC, OpCodeIndex::READ_CURRENT_IAC_LAP, OpCodeIndex::WRITE_CURRENT_IAC_LAP, - OpCodeIndex::SET_AFH_HOST_CHANNEL_CLASSIFICATION, OpCodeIndex::READ_INQUIRY_SCAN_TYPE, + // OpCodeIndex::SET_AFH_HOST_CHANNEL_CLASSIFICATION, + OpCodeIndex::READ_INQUIRY_SCAN_TYPE, OpCodeIndex::WRITE_INQUIRY_SCAN_TYPE, OpCodeIndex::READ_INQUIRY_MODE, OpCodeIndex::WRITE_INQUIRY_MODE, OpCodeIndex::READ_PAGE_SCAN_TYPE, - OpCodeIndex::WRITE_PAGE_SCAN_TYPE, OpCodeIndex::READ_AFH_CHANNEL_ASSESSMENT_MODE, - OpCodeIndex::WRITE_AFH_CHANNEL_ASSESSMENT_MODE, - OpCodeIndex::READ_EXTENDED_INQUIRY_RESPONSE, OpCodeIndex::WRITE_EXTENDED_INQUIRY_RESPONSE, - OpCodeIndex::REFRESH_ENCRYPTION_KEY, OpCodeIndex::READ_SIMPLE_PAIRING_MODE, + OpCodeIndex::WRITE_PAGE_SCAN_TYPE, + // OpCodeIndex::READ_AFH_CHANNEL_ASSESSMENT_MODE, + // OpCodeIndex::WRITE_AFH_CHANNEL_ASSESSMENT_MODE, + // OpCodeIndex::READ_EXTENDED_INQUIRY_RESPONSE, + OpCodeIndex::WRITE_EXTENDED_INQUIRY_RESPONSE, + OpCodeIndex::REFRESH_ENCRYPTION_KEY, + // OpCodeIndex::READ_SIMPLE_PAIRING_MODE, OpCodeIndex::WRITE_SIMPLE_PAIRING_MODE, OpCodeIndex::READ_LOCAL_OOB_DATA, OpCodeIndex::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, - OpCodeIndex::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL, + // OpCodeIndex::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL, // OpCodeIndex::READ_DEFAULT_ERRONEOUS_DATA_REPORTING, // OpCodeIndex::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING, OpCodeIndex::ENHANCED_FLUSH, OpCodeIndex::SEND_KEYPRESS_NOTIFICATION, OpCodeIndex::SET_EVENT_MASK_PAGE_2, // OpCodeIndex::READ_FLOW_CONTROL_MODE, // OpCodeIndex::WRITE_FLOW_CONTROL_MODE, - OpCodeIndex::READ_ENHANCED_TRANSMIT_POWER_LEVEL, OpCodeIndex::READ_LE_HOST_SUPPORT, + OpCodeIndex::READ_ENHANCED_TRANSMIT_POWER_LEVEL, + // OpCodeIndex::READ_LE_HOST_SUPPORT, OpCodeIndex::WRITE_LE_HOST_SUPPORT, // OpCodeIndex::SET_MWS_CHANNEL_PARAMETERS, // OpCodeIndex::SET_EXTERNAL_FRAME_CONFIGURATION, @@ -225,10 +232,10 @@ static std::array SupportedCommands() { // OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA, // OpCodeIndex::READ_SYNCHRONIZATION_TRAIN_PARAMETERS, // OpCodeIndex::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS, - OpCodeIndex::READ_SECURE_CONNECTIONS_HOST_SUPPORT, + // OpCodeIndex::READ_SECURE_CONNECTIONS_HOST_SUPPORT, OpCodeIndex::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT, - OpCodeIndex::READ_AUTHENTICATED_PAYLOAD_TIMEOUT, - OpCodeIndex::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT, + // OpCodeIndex::READ_AUTHENTICATED_PAYLOAD_TIMEOUT, + // OpCodeIndex::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT, OpCodeIndex::READ_LOCAL_OOB_EXTENDED_DATA, // OpCodeIndex::READ_EXTENDED_PAGE_TIMEOUT, // OpCodeIndex::WRITE_EXTENDED_PAGE_TIMEOUT, @@ -236,7 +243,7 @@ static std::array SupportedCommands() { // OpCodeIndex::WRITE_EXTENDED_INQUIRY_LENGTH, // OpCodeIndex::SET_ECOSYSTEM_BASE_INTERVAL, // OpCodeIndex::CONFIGURE_DATA_PATH, - // OpCodeIndex::SET_MIN_ENCRYPTION_KEY_SIZE, + OpCodeIndex::SET_MIN_ENCRYPTION_KEY_SIZE, // INFORMATIONAL_PARAMETERS OpCodeIndex::READ_LOCAL_VERSION_INFORMATION, OpCodeIndex::READ_LOCAL_SUPPORTED_FEATURES, @@ -252,7 +259,8 @@ static std::array SupportedCommands() { // STATUS_PARAMETERS OpCodeIndex::READ_FAILED_CONTACT_COUNTER, OpCodeIndex::RESET_FAILED_CONTACT_COUNTER, // OpCodeIndex::READ_LINK_QUALITY, - OpCodeIndex::READ_RSSI, OpCodeIndex::READ_AFH_CHANNEL_MAP, + OpCodeIndex::READ_RSSI, + // OpCodeIndex::READ_AFH_CHANNEL_MAP, // OpCodeIndex::READ_CLOCK, OpCodeIndex::READ_ENCRYPTION_KEY_SIZE, // OpCodeIndex::GET_MWS_TRANSPORT_LAYER_CONFIGURATION, @@ -260,9 +268,9 @@ static std::array SupportedCommands() { // TESTING OpCodeIndex::READ_LOOPBACK_MODE, OpCodeIndex::WRITE_LOOPBACK_MODE, - OpCodeIndex::ENABLE_IMPLEMENTATION_UNDER_TEST_MODE, - OpCodeIndex::WRITE_SIMPLE_PAIRING_DEBUG_MODE, - OpCodeIndex::WRITE_SECURE_CONNECTIONS_TEST_MODE, + // OpCodeIndex::ENABLE_IMPLEMENTATION_UNDER_TEST_MODE, + // OpCodeIndex::WRITE_SIMPLE_PAIRING_DEBUG_MODE, + // OpCodeIndex::WRITE_SECURE_CONNECTIONS_TEST_MODE, // LE_CONTROLLER OpCodeIndex::LE_SET_EVENT_MASK, OpCodeIndex::LE_READ_BUFFER_SIZE_V1, @@ -276,13 +284,14 @@ static std::array SupportedCommands() { OpCodeIndex::LE_CLEAR_FILTER_ACCEPT_LIST, OpCodeIndex::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST, OpCodeIndex::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST, OpCodeIndex::LE_CONNECTION_UPDATE, - OpCodeIndex::LE_SET_HOST_CHANNEL_CLASSIFICATION, OpCodeIndex::LE_READ_CHANNEL_MAP, + // OpCodeIndex::LE_SET_HOST_CHANNEL_CLASSIFICATION, OpCodeIndex::LE_READ_CHANNEL_MAP, OpCodeIndex::LE_READ_REMOTE_FEATURES_PAGE_0, OpCodeIndex::LE_ENCRYPT, OpCodeIndex::LE_RAND, OpCodeIndex::LE_START_ENCRYPTION, OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_REPLY, OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY, - OpCodeIndex::LE_READ_SUPPORTED_STATES, OpCodeIndex::LE_RECEIVER_TEST_V1, - OpCodeIndex::LE_TRANSMITTER_TEST_V1, OpCodeIndex::LE_TEST_END, + OpCodeIndex::LE_READ_SUPPORTED_STATES, + // OpCodeIndex::LE_RECEIVER_TEST_V1, + // OpCodeIndex::LE_TRANSMITTER_TEST_V1, OpCodeIndex::LE_TEST_END, OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY, OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY, OpCodeIndex::LE_SET_DATA_LENGTH, @@ -321,8 +330,9 @@ static std::array SupportedCommands() { OpCodeIndex::LE_CLEAR_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE, // OpCodeIndex::LE_READ_TRANSMIT_POWER, - OpCodeIndex::LE_READ_RF_PATH_COMPENSATION_POWER, - OpCodeIndex::LE_WRITE_RF_PATH_COMPENSATION_POWER, OpCodeIndex::LE_SET_PRIVACY_MODE, + // OpCodeIndex::LE_READ_RF_PATH_COMPENSATION_POWER, + // OpCodeIndex::LE_WRITE_RF_PATH_COMPENSATION_POWER, + OpCodeIndex::LE_SET_PRIVACY_MODE, // OpCodeIndex::LE_RECEIVER_TEST_V3, // OpCodeIndex::LE_TRANSMITTER_TEST_V3, // OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS, From 1bd59f09f4ed43a319bbdfa452d7924afe77bb4e Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Wed, 23 Jul 2025 22:20:45 +0200 Subject: [PATCH 3/5] fixup! Generate compile_commands.json from Bazel --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6815989..ae5bdce 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ git submodule update --init bazel run :rootcanal ``` +### Creating compile_commands.json for IDE support + +`bazel run :refresh_compile_commands` + ### Python instructions ``` From 20ba9b4679bafaa8c235c270ec5aff2a6b3a8ae3 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Thu, 24 Jul 2025 11:02:08 +0200 Subject: [PATCH 4/5] Add an ideal PHY model and make it the default In many cases you want your devices to find connection strong enough and not avoid connecting --- desktop/test_environment.cc | 4 ++-- include/phy.h | 5 +++++ model/setup/test_command_handler.cc | 24 +++++++++++++++++++----- model/setup/test_model.cc | 24 ++++++++++++++++++++---- model/setup/test_model.h | 4 ++-- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/desktop/test_environment.cc b/desktop/test_environment.cc index f556b84..f55cc1f 100644 --- a/desktop/test_environment.cc +++ b/desktop/test_environment.cc @@ -232,8 +232,8 @@ void TestEnvironment::SetUpTestChannel() { return false; }); - test_channel_.AddPhy({"BR_EDR"}); - test_channel_.AddPhy({"LOW_ENERGY"}); + test_channel_.AddPhy({"BR_EDR", "IDEAL"}); + test_channel_.AddPhy({"LOW_ENERGY", "IDEAL"}); test_channel_.AddDevice({"beacon", "be:ac:01:55:00:01", "1000"}); test_channel_.AddDeviceToPhy({"0", "1"}); test_channel_.AddDevice({"beacon", "be:ac:01:55:00:02", "1000"}); diff --git a/include/phy.h b/include/phy.h index 5f25fa2..9ce1ea7 100644 --- a/include/phy.h +++ b/include/phy.h @@ -24,6 +24,11 @@ class Phy { LOW_ENERGY, BR_EDR, }; + + enum class Model { + PSEUDORANDOM, + IDEAL, + }; }; } // namespace rootcanal diff --git a/model/setup/test_command_handler.cc b/model/setup/test_command_handler.cc index 5907184..d7067e7 100644 --- a/model/setup/test_command_handler.cc +++ b/model/setup/test_command_handler.cc @@ -155,13 +155,27 @@ void TestCommandHandler::RemoveDevice(const vector& args) { } void TestCommandHandler::AddPhy(const vector& args) { - if (args.size() != 1) { - response_string_ = "TestCommandHandler 'add_phy' takes one argument"; - } else if (args[0] == "LOW_ENERGY") { - model_.AddPhy(Phy::Type::LOW_ENERGY); + if (args.size() < 1) { + response_string_ = "TestCommandHandler 'add_phy' takes at least one argument: type, and optional model"; + return send_response_(response_string_); + } + + Phy::Model phy_model = Phy::Model::PSEUDORANDOM; + + if (args.size() > 1) { + if (args[1] == "IDEAL") { + phy_model = Phy::Model::IDEAL; + } else { + response_string_ = "TestCommandHandler 'add_phy' unrecognized model " + args[1]; + return send_response_(response_string_); + } + } + + if (args[0] == "LOW_ENERGY") { + model_.AddPhy(Phy::Type::LOW_ENERGY, phy_model); response_string_ = "TestCommandHandler 'add_phy' called with LOW_ENERGY"; } else if (args[0] == "BR_EDR") { - model_.AddPhy(Phy::Type::BR_EDR); + model_.AddPhy(Phy::Type::BR_EDR, phy_model); response_string_ = "TestCommandHandler 'add_phy' called with BR_EDR"; } else { response_string_ = "TestCommandHandler 'add_phy' with unrecognized type " + args[0]; diff --git a/model/setup/test_model.cc b/model/setup/test_model.cc index eb590bd..b909fbf 100644 --- a/model/setup/test_model.cc +++ b/model/setup/test_model.cc @@ -81,8 +81,24 @@ void TestModel::StopTimer() { timer_tick_task_ = kInvalidTaskId; } -std::unique_ptr TestModel::CreatePhyLayer(PhyLayer::Identifier id, Phy::Type type) { - return std::make_unique(id, type); +class IdealPhyLayer : public PhyLayer { + public: + IdealPhyLayer(PhyLayer::Identifier id, Phy::Type type) : PhyLayer(id, type) {} + + int8_t ComputeRssi(PhyDevice::Identifier sender_id, PhyDevice::Identifier receiver_id, int8_t tx_power) { + return -30; + } +}; + +std::unique_ptr TestModel::CreatePhyLayer(PhyLayer::Identifier id, Phy::Type type, Phy::Model model) { + if (model == Phy::Model::IDEAL) { + return std::make_unique(id, type); + } else if (model == Phy::Model::PSEUDORANDOM) { + return std::make_unique(id, type); + } else { + ERROR("Unknown PHY model: {}, using pseudorandom", static_cast>(model)); + return std::make_unique(id, type); + } } std::shared_ptr TestModel::CreatePhyDevice(std::string type, @@ -133,9 +149,9 @@ void TestModel::RemoveDevice(PhyDevice::Identifier device_id) { } // Add a phy to the test model. -PhyLayer::Identifier TestModel::AddPhy(Phy::Type type) { +PhyLayer::Identifier TestModel::AddPhy(Phy::Type type, Phy::Model model) { static PhyLayer::Identifier next_id = 0; - std::shared_ptr phy_layer = CreatePhyLayer(next_id++, type); + std::shared_ptr phy_layer = CreatePhyLayer(next_id++, type, model); phy_layers_[phy_layer->id] = phy_layer; return phy_layer->id; } diff --git a/model/setup/test_model.h b/model/setup/test_model.h index 09996ca..049cd50 100644 --- a/model/setup/test_model.h +++ b/model/setup/test_model.h @@ -60,7 +60,7 @@ class TestModel { } // Allow derived classes to use custom phy layer. - virtual std::unique_ptr CreatePhyLayer(PhyLayer::Identifier id, Phy::Type type); + virtual std::unique_ptr CreatePhyLayer(PhyLayer::Identifier id, Phy::Type type, Phy::Model model); // Allow derived classes to use custom phy devices. virtual std::shared_ptr CreatePhyDevice(std::string type, @@ -70,7 +70,7 @@ class TestModel { PhyDevice::Identifier AddDevice(std::shared_ptr device); void RemoveDevice(PhyDevice::Identifier id); - PhyLayer::Identifier AddPhy(Phy::Type type); + PhyLayer::Identifier AddPhy(Phy::Type type, Phy::Model model); void RemovePhy(PhyLayer::Identifier id); void AddDeviceToPhy(PhyDevice::Identifier device_id, PhyLayer::Identifier phy_id); void RemoveDeviceFromPhy(PhyDevice::Identifier device_id, PhyLayer::Identifier phy_id); From f4c97c2bf5e3cf224bfb36b92d5406ba2e3fa466 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Thu, 24 Jul 2025 11:09:39 +0200 Subject: [PATCH 5/5] fixup! Add an ideal PHY model and make it the default --- model/setup/test_command_handler.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/model/setup/test_command_handler.cc b/model/setup/test_command_handler.cc index d7067e7..ebe5014 100644 --- a/model/setup/test_command_handler.cc +++ b/model/setup/test_command_handler.cc @@ -157,7 +157,8 @@ void TestCommandHandler::RemoveDevice(const vector& args) { void TestCommandHandler::AddPhy(const vector& args) { if (args.size() < 1) { response_string_ = "TestCommandHandler 'add_phy' takes at least one argument: type, and optional model"; - return send_response_(response_string_); + send_response_(response_string_); + return; } Phy::Model phy_model = Phy::Model::PSEUDORANDOM; @@ -165,9 +166,12 @@ void TestCommandHandler::AddPhy(const vector& args) { if (args.size() > 1) { if (args[1] == "IDEAL") { phy_model = Phy::Model::IDEAL; + } else if (args[1] == "PSEUDORANDOM") { + phy_model = Phy::Model::PSEUDORANDOM; } else { response_string_ = "TestCommandHandler 'add_phy' unrecognized model " + args[1]; - return send_response_(response_string_); + send_response_(response_string_); + return; } }