diff --git a/CMakeLists.txt b/CMakeLists.txt index 07edd7f9b..6db3040ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ if(BUILD_TESTING) include(cmake/include/unittest.cmake) endif() +include(cmake/include/clang-format.cmake) include(cmake/include/doxygen.cmake) # ############################################################################## diff --git a/applications/zpc/applications/zpc_database_tool/include/zpc_database_updater.hpp b/applications/zpc/applications/zpc_database_tool/include/zpc_database_updater.hpp index 74586347b..9b256d90f 100644 --- a/applications/zpc/applications/zpc_database_tool/include/zpc_database_updater.hpp +++ b/applications/zpc/applications/zpc_database_tool/include/zpc_database_updater.hpp @@ -24,7 +24,8 @@ #include "attribute.hpp" #include -namespace zpc_database_updater { +namespace zpc_database_updater +{ /** * @brief Update the datastore to the target version diff --git a/applications/zpc/applications/zpc_database_tool/src/zpc_database_helper.cpp b/applications/zpc/applications/zpc_database_tool/src/zpc_database_helper.cpp index 36fac456b..20ed6f234 100644 --- a/applications/zpc/applications/zpc_database_tool/src/zpc_database_helper.cpp +++ b/applications/zpc/applications/zpc_database_tool/src/zpc_database_helper.cpp @@ -38,14 +38,17 @@ std::vector endpoint_id_list() return endpoint_list; } -std::vector get_attribute_list(attribute_store_type_t attribute_type) { +std::vector get_attribute_list(attribute_store_type_t attribute_type) +{ std::vector attribute_list; auto endpoint_list = endpoint_id_list(); - for(auto endpoint: endpoint_list) { + for (auto endpoint: endpoint_list) { auto attributes = endpoint.children(attribute_type); - attribute_list.insert(attribute_list.end(), attributes.begin(), attributes.end()); + attribute_list.insert(attribute_list.end(), + attributes.begin(), + attributes.end()); } return attribute_list; diff --git a/applications/zpc/applications/zpc_database_tool/src/zpc_database_updater.cpp b/applications/zpc/applications/zpc_database_tool/src/zpc_database_updater.cpp index c717b0321..0491c6bf3 100644 --- a/applications/zpc/applications/zpc_database_tool/src/zpc_database_updater.cpp +++ b/applications/zpc/applications/zpc_database_tool/src/zpc_database_updater.cpp @@ -16,7 +16,7 @@ #include "zpc_datastore_fixt.h" #include "attribute_store_defined_attribute_types.h" -// Interface +// Interface #include "zpc_database_helper.hpp" // Unify components @@ -25,13 +25,14 @@ #include "attribute_store_type_registration.h" #include "sl_log.h" -// Datastore +// Datastore #include "datastore.h" using namespace attribute_store; constexpr const char *LOG_TAG = "zpc_database_updater"; -namespace zpc_database_updater { +namespace zpc_database_updater +{ /////////////////////////////////////////////////////////////////////////////// // Helper function /////////////////////////////////////////////////////////////////////////////// @@ -49,17 +50,16 @@ bool update_bitmask_attribute(attribute attribute_to_update) std::vector current_value = attribute_to_update.reported>(); - auto bitmask_length = current_value.size(); + auto bitmask_length = current_value.size(); uint32_t new_bitmask = 0; // Since we are using uint32_t we can't have more that 4 bit mask - if (bitmask_length > 4 || bitmask_length == 0) { + if (bitmask_length > 4 || bitmask_length == 0) { return false; } for (int i = bitmask_length - 1; i >= 0; i--) { - new_bitmask - = (new_bitmask << 8) | current_value[i]; + new_bitmask = (new_bitmask << 8) | current_value[i]; } attribute_to_update.set_reported(new_bitmask); @@ -76,7 +76,8 @@ bool update_bitmask_attribute(attribute attribute_to_update) void helper_convert_bitmask_to_new_format(attribute_store_type_t attribute_type) { auto attribute_list = get_attribute_list(attribute_type); - const std::string attribute_name = attribute_store_get_type_name(attribute_type); + const std::string attribute_name + = attribute_store_get_type_name(attribute_type); if (attribute_list.size() == 0) { sl_log_info(LOG_TAG, @@ -103,9 +104,6 @@ void helper_convert_bitmask_to_new_format(attribute_store_type_t attribute_type) } } - - - /////////////////////////////////////////////////////////////////////////////// // Conversion functions /////////////////////////////////////////////////////////////////////////////// @@ -210,7 +208,8 @@ sl_status_t convert_v1_datastore_to_v2() } // See zpc_datastore_version for details on the versioning -sl_status_t convert_v2_datastore_to_v3() { +sl_status_t convert_v2_datastore_to_v3() +{ // Update ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES helper_convert_bitmask_to_new_format( ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES); @@ -234,8 +233,7 @@ sl_status_t convert_v2_datastore_to_v3() { "Updating attribute(s) ID under %s...", attribute_name.c_str()); - - // WARNING : Do not use defined type value here. We need those specific ID's from + // WARNING : Do not use defined type value here. We need those specific ID's from // the v2 database and form the v3 database. // Specify ID's for the setpoint types since they have changed since v2 constexpr attribute_store_type_t OLD_MIN_VALUE_TYPE = 0x4306; @@ -253,18 +251,20 @@ sl_status_t convert_v2_datastore_to_v3() { // Default precision (keep same behavior as before) constexpr uint8_t DEFAULT_PRECISION = 3; - for(auto current_setpoint: setpoint_types_list) { + for (auto current_setpoint: setpoint_types_list) { // Update the scale for value (same ID) uint32_t old_value_scale = current_setpoint - .child_by_type(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE) + .child_by_type( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE) .reported(); // Those cases should NOT happen if (old_value_scale > 255) { sl_log_warning(LOG_TAG, "Value scale is too high. Setting it to 255."); old_value_scale = 255; } - current_setpoint.child_by_type(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE) + current_setpoint + .child_by_type(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE) .set_reported(old_value_scale); // First get old values @@ -283,12 +283,12 @@ sl_status_t convert_v2_datastore_to_v3() { if (old_min_value_scale > 255) { sl_log_warning(LOG_TAG, "Min value scale is too high. Setting it to 255."); - old_min_value_scale = 255; + old_min_value_scale = 255; } if (old_max_value_scale > 255) { sl_log_warning(LOG_TAG, "Max value scale is too high. Setting it to 255."); - old_max_value_scale = 255; + old_max_value_scale = 255; } // Then update current attribute tree @@ -304,23 +304,21 @@ sl_status_t convert_v2_datastore_to_v3() { // Create the missing ones current_setpoint.emplace_node(NEW_MAX_VALUE_TYPE, old_max_value); current_setpoint.emplace_node(NEW_MAX_VALUE_SCALE_TYPE, - old_max_value_scale); + old_max_value_scale); current_setpoint.emplace_node(NEW_MAX_VALUE_PRECISION_TYPE, 3); } sl_log_info(LOG_TAG, "Done."); } - + sl_log_info(LOG_TAG, "Successfully converted from version 2 to version 3.\n"); return datastore_store_int("version", DATASTORE_VERSION_V3); } - /////////////////////////////////////////////////////////////////////////////// // Exposed functions /////////////////////////////////////////////////////////////////////////////// -sl_status_t update_datastore(int64_t datastore_version, - int64_t target_version) +sl_status_t update_datastore(int64_t datastore_version, int64_t target_version) { while (datastore_version < target_version) { switch (datastore_version) { diff --git a/applications/zpc/applications/zpc_database_tool/test/zpc_database_upgrade_tool_test.cpp b/applications/zpc/applications/zpc_database_tool/test/zpc_database_upgrade_tool_test.cpp index 96ace88eb..0b726dc03 100644 --- a/applications/zpc/applications/zpc_database_tool/test/zpc_database_upgrade_tool_test.cpp +++ b/applications/zpc/applications/zpc_database_tool/test/zpc_database_upgrade_tool_test.cpp @@ -79,18 +79,14 @@ void suiteSetUp() /// Teardown the test suite (called once after all test_xxx functions are called) int suiteTearDown(int num_failures) { - return num_failures; + return num_failures; } /// Called before each and every test -void setUp() -{ - -} +void setUp() {} /// Called after each and every test -void tearDown() { -} +void tearDown() {} // WARNING : This test is here to cover the v1 to v2 function. // No test was done by the time, so we don't have a v1 database to test. @@ -98,11 +94,11 @@ void tearDown() { void test_migration_v1_v2_test() { // Current database version - constexpr int64_t BASE_VERSION = 1; + constexpr int64_t BASE_VERSION = 1; // New version constexpr int64_t DESTINATION_VERSION = 2; - // This test is here to + // This test is here to helper_setup_database(":memory:", 1); // Migrate the datastore @@ -116,13 +112,12 @@ void test_migration_v1_v2_test() void test_migration_v2_v3() { // Current database version - constexpr int64_t BASE_VERSION = 2; + constexpr int64_t BASE_VERSION = 2; // New version constexpr int64_t DESTINATION_VERSION = 3; helper_setup_database(TEST_DB_V2_BASE_NAME, BASE_VERSION); - attribute_store_log(); // Migrate the datastore @@ -142,40 +137,41 @@ void test_migration_v2_v3() // Test new attributes - // First of all get the correct endpoint - // attribute_store_log() extract : + // First of all get the correct endpoint + // attribute_store_log() extract : // // 59: 2024-Jul-09 14:20:25.685584 [attribute_store] ID: 1 - Root node - Reported (hex): [] // 59: 2024-Jul-09 14:20:25.685690 [attribute_store] ID: 55 - HomeID - Reported (hex): [DF AF 03 F7] // 59: 2024-Jul-09 14:20:25.685750 [attribute_store] ID: 56 - NodeID - Reported (hex): [01 00] // 59: 2024-Jul-09 14:20:25.687162 [attribute_store] ID: 73 - NodeID - Reported (hex): [02 00] // 59: 2024-Jul-09 14:20:25.687233 [attribute_store] ID: 74 - Endpoint ID - Reported (hex): [00] - // 59: 2024-Jul-09 14:29:39.847599 [attribute_store] ID: 75 - Unknown 0xFD020001 - Reported (hex): [00 00 00 00] - // 59: 2024-Jul-09 14:29:39.847676 [attribute_store] ID: 76 - Inclusion protocol - Reported (hex): [00 00 00 00] - // 59: 2024-Jul-09 14:29:39.847755 [attribute_store] ID: 79 - Granted keys - Reported (hex): [00] - // 59: 2024-Jul-09 14:29:39.847828 [attribute_store] ID: 80 - KEX Fail type - Reported (hex): [00 00 00 00] - // 59: 2024-Jul-09 14:29:39.847905 [attribute_store] ID: 81 - NIF: Protocol Listening byte - Reported (hex): [53] - // 59: 2024-Jul-09 14:29:39.847978 [attribute_store] ID: 82 - NIF: Optional Protocol byte - Reported (hex): [DC] - // 59: 2024-Jul-09 14:29:39.848061 [attribute_store] ID: 85 - Version CC is supported - Reported (hex): [01] - // 59: 2024-Jul-09 14:29:39.848135 [attribute_store] ID: 111 - Last Rx/Tx timestamp - Reported (hex): [AF 56 00 00 00 00 00 00] + // 59: 2024-Jul-09 14:29:39.847599 [attribute_store] ID: 75 - Unknown 0xFD020001 - Reported (hex): [00 00 00 00] + // 59: 2024-Jul-09 14:29:39.847676 [attribute_store] ID: 76 - Inclusion protocol - Reported (hex): [00 00 00 00] + // 59: 2024-Jul-09 14:29:39.847755 [attribute_store] ID: 79 - Granted keys - Reported (hex): [00] + // 59: 2024-Jul-09 14:29:39.847828 [attribute_store] ID: 80 - KEX Fail type - Reported (hex): [00 00 00 00] + // 59: 2024-Jul-09 14:29:39.847905 [attribute_store] ID: 81 - NIF: Protocol Listening byte - Reported (hex): [53] + // 59: 2024-Jul-09 14:29:39.847978 [attribute_store] ID: 82 - NIF: Optional Protocol byte - Reported (hex): [DC] + // 59: 2024-Jul-09 14:29:39.848061 [attribute_store] ID: 85 - Version CC is supported - Reported (hex): [01] + // 59: 2024-Jul-09 14:29:39.848135 [attribute_store] ID: 111 - Last Rx/Tx timestamp - Reported (hex): [AF 56 00 00 00 00 00 00] // 59: 2024-Jul-09 14:20:25.696159 [attribute_store] ID: 175 - Endpoint ID - Reported (hex): [01] << We want him - auto root_node = attribute_store_get_root(); + auto root_node = attribute_store_get_root(); auto home_id_node = attribute_store_get_node_child(root_node, 0); auto node_id_node = attribute_store_get_node_child(home_id_node, 1); const zwave_endpoint_id_t endpoint_id = 1; // Need to specify the endpoint ID here - auto endpoint_id_node = attribute_store_get_node_child_by_value(node_id_node, - ATTRIBUTE_ENDPOINT_ID, - REPORTED_ATTRIBUTE, - &endpoint_id, - sizeof(endpoint_id), - 0); + auto endpoint_id_node + = attribute_store_get_node_child_by_value(node_id_node, + ATTRIBUTE_ENDPOINT_ID, + REPORTED_ATTRIBUTE, + &endpoint_id, + sizeof(endpoint_id), + 0); // Test new bitmask values - const std::map bitmask_attributes = { - {ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES, 0x180F }, - {ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_SUPPORTED_SETPOINT_TYPES, 0x0186 } - }; + const std::map bitmask_attributes + = {{ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES, 0x180F}, + {ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_SUPPORTED_SETPOINT_TYPES, + 0x0186}}; for (const auto &[attribute_type, expected_value]: bitmask_attributes) { printf("Testing attribute %s\n", @@ -196,8 +192,6 @@ void test_migration_v2_v3() "New bitmask value mismatch."); } - - // Test new attribute ID values struct setpoint_value { int32_t value; @@ -206,7 +200,8 @@ void test_migration_v2_v3() }; // Expected value in each fields - const std::map> expected_setpoint_attributes + const std::map> + expected_setpoint_attributes = {{0x01, {{73000, 1, 3}, {-10000, 0, 3}, {100000, 0, 3}}}, {0x02, {{73000, 1, 3}, {-10000, 0, 3}, {100000, 0, 3}}}, {0x0B, {{62000, 1, 3}, {-10000, 0, 3}, {100000, 0, 3}}}, @@ -225,7 +220,8 @@ void test_migration_v2_v3() // MAX_VALUE_PRECISION_TYPE : 0x430C const attribute_store_type_t START_VALUE_TYPE = 0x4304; - for (const auto &[setpoint_type, expected_values]: expected_setpoint_attributes) { + for (const auto &[setpoint_type, expected_values]: + expected_setpoint_attributes) { printf("Testing setpoint type %d\n", setpoint_type); auto setpoint_type_node = attribute_store_get_node_child_by_value( @@ -262,14 +258,13 @@ void test_migration_v2_v3() reported_values.value, "New setpoint value mismatch."); - // Get scale // TODO : use defined offset in thermostat setpoint header when available - status - = attribute_store_get_child_reported(setpoint_type_node, - START_VALUE_TYPE + CURRENT_OFFSET + 1, - &reported_values.scale, - sizeof(reported_values.scale)); + status = attribute_store_get_child_reported( + setpoint_type_node, + START_VALUE_TYPE + CURRENT_OFFSET + 1, + &reported_values.scale, + sizeof(reported_values.scale)); TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_OK, status, "Failed to get new setpoint scale."); @@ -279,11 +274,11 @@ void test_migration_v2_v3() "New setpoint scale mismatch."); // Get precision - status - = attribute_store_get_child_reported(setpoint_type_node, - START_VALUE_TYPE + CURRENT_OFFSET + 2, - &reported_values.precision, - sizeof(reported_values.precision)); + status = attribute_store_get_child_reported( + setpoint_type_node, + START_VALUE_TYPE + CURRENT_OFFSET + 2, + &reported_values.precision, + sizeof(reported_values.precision)); TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_OK, status, "Failed to get new setpoint precision."); @@ -295,6 +290,4 @@ void test_migration_v2_v3() } } - - -} // extern "C" \ No newline at end of file +} // extern "C" \ No newline at end of file diff --git a/applications/zpc/applications/zpc_database_tool/zpc_database_tool.cpp b/applications/zpc/applications/zpc_database_tool/zpc_database_tool.cpp index cb2805a5b..15fd8bc49 100644 --- a/applications/zpc/applications/zpc_database_tool/zpc_database_tool.cpp +++ b/applications/zpc/applications/zpc_database_tool/zpc_database_tool.cpp @@ -146,8 +146,9 @@ static void import_data_store(attribute &parent, nlohmann::json &jsn) sl_log_error("zpc_database_tool", "Missing type attribute in json"); return; } - std::string type_str = jsn["type"].get(); - attribute_store_type_t type = attribute_store_get_type_by_name(type_str.c_str()); + std::string type_str = jsn["type"].get(); + attribute_store_type_t type + = attribute_store_get_type_by_name(type_str.c_str()); attribute node; if (type == ATTRIBUTE_TREE_ROOT) { diff --git a/applications/zpc/components/dotdot_mapper/src/basic_cluster_mapper.cpp b/applications/zpc/components/dotdot_mapper/src/basic_cluster_mapper.cpp index da7e41efb..7ed03cece 100644 --- a/applications/zpc/components/dotdot_mapper/src/basic_cluster_mapper.cpp +++ b/applications/zpc/components/dotdot_mapper/src/basic_cluster_mapper.cpp @@ -118,7 +118,8 @@ static void network_status_attribute_update(attribute_store_node_t updated_node, if (change != ATTRIBUTE_UPDATED) { return; } - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_get_reported(updated_node, &network_status, sizeof(network_status)); diff --git a/applications/zpc/components/dotdot_mapper/src/binding_cluster_mapper.c b/applications/zpc/components/dotdot_mapper/src/binding_cluster_mapper.c index 45e1c47cc..6dba9efee 100644 --- a/applications/zpc/components/dotdot_mapper/src/binding_cluster_mapper.c +++ b/applications/zpc/components/dotdot_mapper/src/binding_cluster_mapper.c @@ -28,7 +28,6 @@ // Interfaces - #define LOG_TAG "binding_cluster_mapper" /////////////////////////////////////////////////////////////////////////////// @@ -160,7 +159,8 @@ static void on_network_status_update(attribute_store_node_t network_status_node, return; } - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); @@ -202,9 +202,10 @@ bool binding_cluster_mapper_init(void) // Here we listen to AGI information to publish which commands are generated // by nodes, in case we have a binding/association towards them. - attribute_store_register_callback_by_type_and_state(&on_network_status_update, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - REPORTED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_network_status_update, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + REPORTED_ATTRIBUTE); return true; } diff --git a/applications/zpc/components/dotdot_mapper/test/basic_cluster_mapper_test.cpp b/applications/zpc/components/dotdot_mapper/test/basic_cluster_mapper_test.cpp index 867a06749..2278d7288 100644 --- a/applications/zpc/components/dotdot_mapper/test/basic_cluster_mapper_test.cpp +++ b/applications/zpc/components/dotdot_mapper/test/basic_cluster_mapper_test.cpp @@ -26,7 +26,6 @@ #include "zwave_generic_types.h" #include "zwave_command_class_version_types.h" - #include "workaround_basic_cluster_mapper_test.hpp" using namespace attribute_store; @@ -72,7 +71,8 @@ void test_manufacturer_id_to_name_mapper() attribute attr_node_id_node(node_id_node); attr_node_id_node.add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS) - .set_reported(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL); + .set_reported( + ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL); attribute basic_cluster_man_name_node = attr_ep_node.child_by_type(DOTDOT_ATTRIBUTE_ID_BASIC_MANUFACTURER_NAME); @@ -103,7 +103,8 @@ void test_serial_number_mapper() attribute attr_node_id_node(node_id_node); attr_node_id_node.add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS) - .set_reported(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL); + .set_reported( + ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL); attribute dotdot_serial_node = attribute(endpoint_id_node) diff --git a/applications/zpc/components/dotdot_mapper/test/binding_cluster_mapper_test.c b/applications/zpc/components/dotdot_mapper/test/binding_cluster_mapper_test.c index 8fac3cda1..57bb59607 100644 --- a/applications/zpc/components/dotdot_mapper/test/binding_cluster_mapper_test.c +++ b/applications/zpc/components/dotdot_mapper/test/binding_cluster_mapper_test.c @@ -221,10 +221,12 @@ void test_publish_commands_for_supporting_node() setup_groups_for_supporting_node(); attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // Nothing happens here as long as we are not online functional. - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -267,10 +269,12 @@ void test_publish_commands_for_supporting_node_cannot_read_unid() setup_groups_for_supporting_node(); attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // Nothing happens here as long as we are not online functional. - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -287,10 +291,12 @@ void test_publish_commands_for_supporting_node_cannot_read_unid() void test_no_publish_commands_for_zpc() { attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, zpc_node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + zpc_node_id_node); // Set to online functional, nothing should happen. - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -317,10 +323,12 @@ void test_publish_central_scene_commands_for_supporting_node() sizeof(command_list_1)); attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // Nothing happens here as long as we are not online functional. - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -375,10 +383,12 @@ void test_publish_on_off_commands_for_supporting_node() sizeof(command_list_1)); attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // Nothing happens here as long as we are not online functional. - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); diff --git a/applications/zpc/components/dotdot_mapper/test/on_off_cluster_mapper_test.c b/applications/zpc/components/dotdot_mapper/test/on_off_cluster_mapper_test.c index 13c0f7338..2bdc531a2 100644 --- a/applications/zpc/components/dotdot_mapper/test/on_off_cluster_mapper_test.c +++ b/applications/zpc/components/dotdot_mapper/test/on_off_cluster_mapper_test.c @@ -71,12 +71,15 @@ void test_on_onoff_attribute_created_due_to_basic_value() { // set the network status of attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus test_online_network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; - attribute_store_set_node_attribute_value(network_status_node, - REPORTED_ATTRIBUTE, - (uint8_t*)&test_online_network_status, - sizeof(test_online_network_status)); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus test_online_network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + attribute_store_set_node_attribute_value( + network_status_node, + REPORTED_ATTRIBUTE, + (uint8_t *)&test_online_network_status, + sizeof(test_online_network_status)); uic_mqtt_dotdot_publish_supported_commands_Expect(NULL, endpoint_id); uic_mqtt_dotdot_publish_supported_commands_IgnoreArg_unid(); attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_OFF, endpoint_id_node); diff --git a/applications/zpc/components/network_monitor/include/network_monitor_fixt.h b/applications/zpc/components/network_monitor/include/network_monitor_fixt.h index a269be1fc..7b4036eb3 100644 --- a/applications/zpc/components/network_monitor/include/network_monitor_fixt.h +++ b/applications/zpc/components/network_monitor/include/network_monitor_fixt.h @@ -43,4 +43,3 @@ sl_status_t network_monitor_setup_fixt(void); #endif //NETWORK_MONITOR_FIXT_H /** @} end network_monitor_fixt */ - diff --git a/applications/zpc/components/network_monitor/src/failing_node_monitor.cpp b/applications/zpc/components/network_monitor/src/failing_node_monitor.cpp index 8de28ede2..cb5c64e94 100644 --- a/applications/zpc/components/network_monitor/src/failing_node_monitor.cpp +++ b/applications/zpc/components/network_monitor/src/failing_node_monitor.cpp @@ -17,7 +17,6 @@ // Interfaces #include "attribute_store_defined_attribute_types.h" - // ZPC components #include "zwave_controller_utils.h" @@ -158,7 +157,8 @@ static void static bool is_node_failing(attribute_store_node_t network_status_node) { // Assume the node is just included if we cannot read the network status - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); @@ -262,7 +262,8 @@ void failing_node_monitor_init() nop_queued = false; // Register Attribute Store callbacks - attribute_store_register_callback_by_type_and_state(&on_network_status_update, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - REPORTED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_network_status_update, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + REPORTED_ATTRIBUTE); } diff --git a/applications/zpc/components/network_monitor/src/failing_node_monitor.h b/applications/zpc/components/network_monitor/src/failing_node_monitor.h index 34d22a8be..ca1d2cfd9 100644 --- a/applications/zpc/components/network_monitor/src/failing_node_monitor.h +++ b/applications/zpc/components/network_monitor/src/failing_node_monitor.h @@ -50,7 +50,7 @@ #define FL_NODE_PING_TIME_FACTOR 4 // Maximum time we settle on between ping intervals: -#define MAX_PING_TIME_INTERVAL (24 * 60 * 60 * CLOCK_SECOND) // 24 hours +#define MAX_PING_TIME_INTERVAL (24 * 60 * 60 * CLOCK_SECOND) // 24 hours #ifdef __cplusplus extern "C" { diff --git a/applications/zpc/components/network_monitor/src/network_monitor.cpp b/applications/zpc/components/network_monitor/src/network_monitor.cpp index 35011d80a..f7d82e386 100644 --- a/applications/zpc/components/network_monitor/src/network_monitor.cpp +++ b/applications/zpc/components/network_monitor/src/network_monitor.cpp @@ -547,8 +547,9 @@ static attribute network_monitor_add_attribute_store_node( sizeof(endpoint_id)); attribute_store_node_t network_status_node - = attribute_store_get_first_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + = attribute_store_get_first_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); if (network_status_node == ATTRIBUTE_STORE_INVALID_NODE) { attribute_store_set_child_reported(node_id_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, @@ -609,11 +610,13 @@ static void // Don't modify anything if the node is not offline. if (network_status != ZCL_NODE_STATE_NETWORK_STATUS_OFFLINE - && network_status != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL) { + && network_status + != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL) { return; } - NodeStateNetworkStatus new_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus new_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; if (network_status == ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL) { // If the network status was interviewing and the frame transmission failed // Set it to Failed interview, so we try again a ful interview when it responds again @@ -716,7 +719,8 @@ static void network_initialized = true; } -static void network_monitor_handle_event_network_ready(network_data const &event_data) +static void + network_monitor_handle_event_network_ready(network_data const &event_data) { // Make sure that UNID / ZPC UNID are configured correctly. zwave_unid_set_home_id(event_data.home_id); @@ -741,8 +745,8 @@ static void network_monitor_handle_event_node_id_assigned( event_data.inclusion_protocol); } -static void - network_monitor_handle_event_node_added(node_added_event_data const &event_data) +static void network_monitor_handle_event_node_added( + node_added_event_data const &event_data) { // Attribute store node should already exist, but in case NODE_ID_ASSIGNED_EVENT // did not happen before this event, we ensure the node exists in the attribute store. @@ -760,9 +764,11 @@ static void network_monitor_handle_event_node_interview_initiated( attribute_store_node_t node_id_node) { attribute_store_node_t network_status_node - = attribute_store_get_first_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + = attribute_store_get_first_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); @@ -792,7 +798,8 @@ static void network_monitor_handle_event_node_interview_done( node_id_node, network_monitor_node_id_resolution_listener); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_child_reported(node_id_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, &network_status, diff --git a/applications/zpc/components/network_monitor/src/network_monitor_utils.h b/applications/zpc/components/network_monitor/src/network_monitor_utils.h index 99b1e4f33..d2c6321e3 100644 --- a/applications/zpc/components/network_monitor/src/network_monitor_utils.h +++ b/applications/zpc/components/network_monitor/src/network_monitor_utils.h @@ -47,7 +47,8 @@ template void retain_recursive( Sequence &sequence, typename Sequence::iterator &begin, const typename Sequence::iterator &end, - const std::function predicate) + const std::function + predicate) { constexpr int delete_buffer_size = 16; typename Sequence::const_iterator to_delete[delete_buffer_size] = {}; @@ -81,9 +82,10 @@ template void retain_recursive( * std::vector * @param predicate function that defines the retain condition. */ -template static void retain( - Sequence &sequence, - const std::function predicate) +template static void + retain(Sequence &sequence, + const std::function + predicate) { auto begin = sequence.begin(); const auto end = sequence.end(); diff --git a/applications/zpc/components/network_monitor/test/container_retain_test.cpp b/applications/zpc/components/network_monitor/test/container_retain_test.cpp index ec77ba647..6f8cd1bbc 100644 --- a/applications/zpc/components/network_monitor/test/container_retain_test.cpp +++ b/applications/zpc/components/network_monitor/test/container_retain_test.cpp @@ -15,7 +15,7 @@ #ifdef __cplusplus extern "C" { -#endif // __cplusplus +#endif // __cplusplus #include "unity.h" void test_buffered_delete() @@ -34,5 +34,4 @@ void test_buffered_delete() } #ifdef __cplusplus } -#endif // __cplusplus - +#endif // __cplusplus diff --git a/applications/zpc/components/network_monitor/test/failing_node_monitor_test.c b/applications/zpc/components/network_monitor/test/failing_node_monitor_test.c index 9c2aec266..d8d203a4c 100644 --- a/applications/zpc/components/network_monitor/test/failing_node_monitor_test.c +++ b/applications/zpc/components/network_monitor/test/failing_node_monitor_test.c @@ -87,14 +87,17 @@ static attribute_store_node_t create_al_node(zwave_node_id_t node_id) sizeof(listening_protocol)); attribute_store_node_t network_status_node - = attribute_store_get_node_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - 0); + = attribute_store_get_node_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + 0); if (network_status_node == ATTRIBUTE_STORE_INVALID_NODE) { network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); } - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -162,7 +165,8 @@ void test_monitoring_failed_al_node_happy_case() // Set the node to just included attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_COMMISIONING_STARTED; attribute_store_set_reported(network_status_node, @@ -256,8 +260,10 @@ void test_monitoring_failed_fl_node_happy_case() // Set the node to interviewing attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -528,7 +534,8 @@ void test_monitoring_failed_unknown_operating_mode_not_monitored() { // Add a network status attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_COMMISIONING_STARTED; attribute_store_set_reported(network_status_node, diff --git a/applications/zpc/components/network_monitor/test/keep_sleeping_nodes_alive_test.cpp b/applications/zpc/components/network_monitor/test/keep_sleeping_nodes_alive_test.cpp index 5ccdeb9c8..46daad116 100644 --- a/applications/zpc/components/network_monitor/test/keep_sleeping_nodes_alive_test.cpp +++ b/applications/zpc/components/network_monitor/test/keep_sleeping_nodes_alive_test.cpp @@ -85,8 +85,10 @@ static void init_network(attribute &node_id_node, bool set_op_mode = true) .set_reported(optional_protocol); } - NodeStateNetworkStatus state = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; - attribute network_status = node_id_node.add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + NodeStateNetworkStatus state + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; + attribute network_status + = node_id_node.add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); network_status.set_reported(state); } @@ -159,7 +161,8 @@ void test_nodes_that_are_not_wake_up_are_ignored() attribute network_status = node_id_node.child_by_type(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); - NodeStateNetworkStatus state = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; + NodeStateNetworkStatus state + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; network_status.set_reported(state); diff --git a/applications/zpc/components/network_monitor/test/zwave_network_monitor_test.c b/applications/zpc/components/network_monitor/test/zwave_network_monitor_test.c index 7cff989ee..d4f24886b 100644 --- a/applications/zpc/components/network_monitor/test/zwave_network_monitor_test.c +++ b/applications/zpc/components/network_monitor/test/zwave_network_monitor_test.c @@ -31,7 +31,6 @@ #include "zwave_node_id_definitions.h" #include "zwave_command_class_wake_up_types.h" - // Mock includes #include "zwave_controller_callbacks_mock.h" #include "zwave_controller_storage_mock.h" @@ -140,8 +139,10 @@ void test_monitoring_failed_al_node() sizeof(listening_protocol)); // Set the node to Online Functional attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -156,7 +157,8 @@ void test_monitoring_failed_al_node() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); // Make a second transmit failure, that's it, you are offline my friend: zwave_callbacks->on_frame_transmission(false, NULL, node_id); @@ -174,7 +176,8 @@ void test_monitoring_failed_al_node() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); } void test_monitoring_failed_al_node_re_interview() @@ -193,8 +196,10 @@ void test_monitoring_failed_al_node_re_interview() sizeof(listening_protocol)); // Set the node to Interviewing attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -209,7 +214,8 @@ void test_monitoring_failed_al_node_re_interview() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, + network_status); // Make a second transmit failure, that's it, you are offline my friend: zwave_callbacks->on_frame_transmission(false, NULL, node_id); @@ -218,7 +224,8 @@ void test_monitoring_failed_al_node_re_interview() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, + network_status); // Make a second transmit success, back to interviewing zwave_callbacks->on_frame_transmission(true, NULL, node_id); @@ -227,7 +234,8 @@ void test_monitoring_failed_al_node_re_interview() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, + network_status); } void test_monitoring_failed_tx_with_nl_node() @@ -251,8 +259,10 @@ void test_monitoring_failed_tx_with_nl_node() // Set the node to Online Functional attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -275,7 +285,8 @@ void test_monitoring_failed_tx_with_nl_node() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); // Try to see if we consider the node asleep again if a Tx fail happens // more than 10s after the last tx/rx success. @@ -312,8 +323,10 @@ void test_monitoring_failed_nl_node() // Set the node to Online Functional attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -341,7 +354,8 @@ void test_monitoring_failed_nl_node() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); // Go to the deadline minus 1 ms contiki_test_helper_run(test_configuration.missing_wake_up_notification @@ -352,7 +366,8 @@ void test_monitoring_failed_nl_node() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); // Now it was too long without hearing from the node, mark it as failing: contiki_test_helper_run(2); @@ -369,7 +384,8 @@ void test_monitoring_failed_nl_node() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); } void test_monitoring_failed_nl_node_changing_wake_up_interval() @@ -394,8 +410,10 @@ void test_monitoring_failed_nl_node_changing_wake_up_interval() // Set the node to Online Functional attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -423,7 +441,8 @@ void test_monitoring_failed_nl_node_changing_wake_up_interval() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); // Go to the deadline minus 1 ms contiki_test_helper_run(test_configuration.missing_wake_up_notification @@ -442,15 +461,18 @@ void test_monitoring_failed_nl_node_changing_wake_up_interval() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); } void test_change_node_network_status_to_interviewing_on_nif_creation() { // Set the node to Online Functional attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -464,14 +486,16 @@ void test_change_node_network_status_to_interviewing_on_nif_creation() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, + network_status); } void test_change_node_network_status_to_interview_fail_on_nif_creation() { // Set the node to Online Functional attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_OFFLINE; attribute_store_set_reported(network_status_node, &network_status, @@ -486,14 +510,16 @@ void test_change_node_network_status_to_interview_fail_on_nif_creation() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, + network_status); } void test_change_node_network_status_to_interview_on_nif_creation_with_unknown_previous_value() { // Create a network status but leave it undefined. attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // Create a nif: attribute_store_add_node(ATTRIBUTE_ZWAVE_NIF, endpoint_id_node); @@ -504,7 +530,8 @@ void test_change_node_network_status_to_interview_on_nif_creation_with_unknown_p attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, + network_status); } void test_do_not_put_node_online_if_not_offline() @@ -515,9 +542,11 @@ void test_do_not_put_node_online_if_not_offline() // Create a network status but leave it undefined. attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // Set the network status to something not offline: - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_set_reported(network_status_node, &network_status, sizeof(network_status)); @@ -929,14 +958,16 @@ void test_on_nif_updated() // Now the node should be marked as interviewing: attribute_store_node_t network_status_node - = attribute_store_get_first_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + = attribute_store_get_first_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); NodeStateNetworkStatus network_status = 10000; attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING, + network_status); // At some point, the interview is over. In this case, the network // status will be moved to online functional. @@ -948,7 +979,8 @@ void test_on_nif_updated() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL, + network_status); } void test_on_nif_added_when_offline() @@ -960,8 +992,9 @@ void test_on_nif_added_when_offline() &network_status, sizeof(network_status)); attribute_store_node_t network_status_node - = attribute_store_get_first_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + = attribute_store_get_first_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); // Create a NIF under NodeID 4, endpoint 0 attribute_store_node_t nif_node @@ -972,7 +1005,8 @@ void test_on_nif_added_when_offline() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, + network_status); // Set the NIF to a value. It should not affect anything. attribute_store_set_reported(nif_node, @@ -981,14 +1015,16 @@ void test_on_nif_added_when_offline() attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, + network_status); // Delete the NIF to a value. It should not affect anything. attribute_store_delete_node(nif_node); attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); - TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, network_status); + TEST_ASSERT_EQUAL(ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_NON_FUNCTIONAL, + network_status); } void test_storage_callbacks_get_granted_keys() diff --git a/applications/zpc/components/ucl_mqtt/include/ucl_mqtt.h b/applications/zpc/components/ucl_mqtt/include/ucl_mqtt.h index 65cb7d11d..c421431c5 100644 --- a/applications/zpc/components/ucl_mqtt/include/ucl_mqtt.h +++ b/applications/zpc/components/ucl_mqtt/include/ucl_mqtt.h @@ -44,4 +44,4 @@ sl_status_t ucl_mqtt_setup_fixt(void); #endif #endif //UCL_MQTT_H -/** @} end ucl_mqtt */ \ No newline at end of file + /** @} end ucl_mqtt */ \ No newline at end of file diff --git a/applications/zpc/components/ucl_mqtt/src/ucl_nm_neighbor_discovery.cpp b/applications/zpc/components/ucl_mqtt/src/ucl_nm_neighbor_discovery.cpp index 6bcb2dbbf..16324e10d 100644 --- a/applications/zpc/components/ucl_mqtt/src/ucl_nm_neighbor_discovery.cpp +++ b/applications/zpc/components/ucl_mqtt/src/ucl_nm_neighbor_discovery.cpp @@ -115,13 +115,13 @@ static void ucl_nm_request_node_neighbor_on_node_resolution_resumed( { // TODO, may be reworked to avoid build errors #if defined(__GNUC__) && (__GNUC__ == 12) - zwave_node_id_t node_id = 0; + zwave_node_id_t node_id = 0; zwave_node_id_t node_id_tmp = 0; attribute_store_get_reported(node_id_node, &node_id_tmp, sizeof(node_id_tmp)); - node_id = node_id_tmp; + node_id = node_id_tmp; #else zwave_node_id_t node_id = 0; - attribute_store_get_reported(node_id_node, &node_id, sizeof(node_id)); + attribute_store_get_reported(node_id_node, &node_id, sizeof(node_id)); #endif if ((zwave_network_management_get_state() == NM_IDLE) diff --git a/applications/zpc/components/ucl_mqtt/src/zpc_node_state.cpp b/applications/zpc/components/ucl_mqtt/src/zpc_node_state.cpp index f4b151546..60bf7cb38 100644 --- a/applications/zpc/components/ucl_mqtt/src/zpc_node_state.cpp +++ b/applications/zpc/components/ucl_mqtt/src/zpc_node_state.cpp @@ -55,11 +55,11 @@ static sl_status_t ucl_node_state_discover_neighbors_command( if (UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK == callback_type) { // DiscoverNeighbors always supported unless the node is offline/unavailale - NodeStateNetworkStatus network_status = unify_attribute_store_node_state_get_status( - attribute_store_network_helper_get_node_id_node(unid) - ); + NodeStateNetworkStatus network_status + = unify_attribute_store_node_state_get_status( + attribute_store_network_helper_get_node_id_node(unid)); - sl_status_t support = SL_STATUS_OK; + sl_status_t support = SL_STATUS_OK; if ((network_status == ZCL_NODE_STATE_NETWORK_STATUS_OFFLINE) || (network_status == ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE)) { support = SL_STATUS_FAIL; @@ -96,11 +96,11 @@ static sl_status_t ucl_node_state_remove_offline_command( if (UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK == callback_type) { // RemoveOffline supported unless the node is unavailable - NodeStateNetworkStatus network_status = unify_attribute_store_node_state_get_status( - attribute_store_network_helper_get_node_id_node(unid) - ); + NodeStateNetworkStatus network_status + = unify_attribute_store_node_state_get_status( + attribute_store_network_helper_get_node_id_node(unid)); - sl_status_t support = SL_STATUS_OK; + sl_status_t support = SL_STATUS_OK; if (network_status == ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE) { support = SL_STATUS_FAIL; } @@ -137,12 +137,12 @@ static sl_status_t ucl_node_state_interview_command( } if (UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK == callback_type) { - NodeStateNetworkStatus network_status = unify_attribute_store_node_state_get_status( - attribute_store_network_helper_get_node_id_node(unid) - ); + NodeStateNetworkStatus network_status + = unify_attribute_store_node_state_get_status( + attribute_store_network_helper_get_node_id_node(unid)); // Interview always supported unless the node is offline/unavailable - sl_status_t support = SL_STATUS_OK; + sl_status_t support = SL_STATUS_OK; if ((network_status == ZCL_NODE_STATE_NETWORK_STATUS_OFFLINE) || (network_status == ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE)) { support = SL_STATUS_FAIL; @@ -222,9 +222,9 @@ static sl_status_t ucl_node_state_enable_nls_command( if (UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK == callback_type) { // Enable NLS always supported unless the node is offline/unavailable - NodeStateNetworkStatus network_status = unify_attribute_store_node_state_get_status( - attribute_store_network_helper_get_node_id_node(unid) - ); + NodeStateNetworkStatus network_status + = unify_attribute_store_node_state_get_status( + attribute_store_network_helper_get_node_id_node(unid)); sl_status_t support = SL_STATUS_OK; if ((network_status == ZCL_NODE_STATE_NETWORK_STATUS_OFFLINE) diff --git a/applications/zpc/components/ucl_mqtt/test/zpc_node_state_test.c b/applications/zpc/components/ucl_mqtt/test/zpc_node_state_test.c index 727eae581..fd575d7a1 100644 --- a/applications/zpc/components/ucl_mqtt/test/zpc_node_state_test.c +++ b/applications/zpc/components/ucl_mqtt/test/zpc_node_state_test.c @@ -48,9 +48,7 @@ static uic_mqtt_dotdot_state_interview_callback_t interview_command = NULL; static uic_mqtt_dotdot_state_discover_security_callback_t discover_security_command = NULL; -static uic_mqtt_dotdot_state_enable_nls_callback_t - enable_nls_command - = NULL; +static uic_mqtt_dotdot_state_enable_nls_callback_t enable_nls_command = NULL; // Stub functions static void uic_mqtt_dotdot_state_remove_offline_callback_set_stub( diff --git a/applications/zpc/components/zcl_cluster_servers/src/configuration_parameter_cluster_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/configuration_parameter_cluster_server.cpp index 5c57bd403..d22f35c35 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/configuration_parameter_cluster_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/configuration_parameter_cluster_server.cpp @@ -17,7 +17,6 @@ #include "zwave_command_class_version_types.h" #include "zwave_command_class_configuration_types.h" - // ZPC includes #include "zpc_attribute_store.h" #include "zpc_attribute_store_network_helper.h" @@ -610,7 +609,8 @@ void on_configuration_update(attribute_store_node_t updated_node, } // Read the network status, do not publish if it is not online functional: - if (unify_attribute_store_node_state_get_status(updated_node) != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { + if (unify_attribute_store_node_state_get_status(updated_node) + != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { return; } @@ -693,9 +693,10 @@ sl_status_t configuration_parameter_cluster_server_init(void) &configuration_parameter_discover_parameter_range_command); // Register attribute updates - attribute_store_register_callback_by_type_and_state(&on_network_status_update, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - REPORTED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_network_status_update, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + REPORTED_ATTRIBUTE); attribute_store_register_callback_by_type_to_array( &on_configuration_update, diff --git a/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c b/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c index cbd4c7f97..cc970be1a 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c +++ b/applications/zpc/components/zcl_cluster_servers/src/humidity_control_cluster_server.c @@ -72,7 +72,7 @@ sl_status_t unify_humidity_control_setpoint_set( // First check the call type. This command have too many requirements // so we support it by default if (call_type == UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK) { - return SL_STATUS_OK; + return SL_STATUS_OK; } attribute_store_node_t endpoint_node @@ -120,7 +120,8 @@ sl_status_t unify_humidity_control_setpoint_set( /////////////////////////////////////////////////////////////////////////////// sl_status_t humidity_control_cluster_server_init() { - sl_log_debug(LOG_TAG, "Humidity Control cluster (ZWave) server initialization"); + sl_log_debug(LOG_TAG, + "Humidity Control cluster (ZWave) server initialization"); // Listen to the BASIC Value attribute is created uic_mqtt_dotdot_unify_humidity_control_mode_set_callback_set( diff --git a/applications/zpc/components/zcl_cluster_servers/src/user_code_cluster_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/user_code_cluster_server.cpp index d3ffae180..3abd13e76 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/user_code_cluster_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/user_code_cluster_server.cpp @@ -291,7 +291,8 @@ sl_status_t user_code_cluster_server_init() // Register the callback for handling commands from IoT service uic_mqtt_dotdot_door_lock_set_pin_code_callback_set(&set_pin_code_command); uic_mqtt_dotdot_door_lock_get_pin_code_callback_set(&get_pin_code_command); - uic_mqtt_dotdot_door_lock_clear_pin_code_callback_set(&clear_pin_code_command); + uic_mqtt_dotdot_door_lock_clear_pin_code_callback_set( + &clear_pin_code_command); uic_mqtt_dotdot_door_lock_clear_all_pin_codes_callback_set( &clear_all_pin_codes_command); uic_mqtt_dotdot_door_lock_set_user_status_callback_set( diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_OTA_cluster_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_OTA_cluster_server.cpp index fe277e8db..cde1dc23d 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_OTA_cluster_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_OTA_cluster_server.cpp @@ -55,11 +55,12 @@ static int get_target_from_uiid(const std::string &uiid) for (size_t idx = 0; idx < uiid.size(); idx++) { if (uiid[idx] == '-') { last_2_dash = last_dash; - last_dash = idx; + last_dash = idx; } } if ((last_2_dash != 0) && (last_dash != 0)) { - std::string target_str = uiid.substr(last_2_dash + 1, last_dash - last_2_dash - 1); + std::string target_str + = uiid.substr(last_2_dash + 1, last_dash - last_2_dash - 1); return std::stoi(target_str); } else { sl_log_error(TAG, "Unable to resolve target from uiid"); @@ -82,8 +83,8 @@ static std::string get_target_version(attribute node, int fw_target_id) 0); attribute version_data = ep.child_by_type(ATTRIBUTE_CC_VERSION_VERSION_REPORT_DATA); - attribute fw_target = version_data.child_by_type( - ATTRIBUTE_CC_VERSION_FIRMWARE); + attribute fw_target + = version_data.child_by_type(ATTRIBUTE_CC_VERSION_FIRMWARE); int32_t fw_version = fw_target.child_by_type(ATTRIBUTE_CC_VERSION_FIRMWARE_VERSION) .reported(); diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_binding_cluster_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_binding_cluster_server.cpp index c0ae2fe8b..75124bb70 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_binding_cluster_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_binding_cluster_server.cpp @@ -20,7 +20,6 @@ // Interfaces #include "zwave_command_class_version_types.h" - // ZPC includes #include "binding_cluster_mapper_helper.h" #include "zpc_attribute_store.h" @@ -682,7 +681,8 @@ static void on_group_command_list_udpate(attribute_store_node_t updated_node, } // Read the network status, do not publish if it is not online functional: - if (unify_attribute_store_node_state_get_status(updated_node) != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { + if (unify_attribute_store_node_state_get_status(updated_node) + != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { return; } @@ -716,7 +716,8 @@ static void on_group_content_udpate(attribute_store_node_t updated_node, } // Read the network status, do not publish if it is not online functional: - if (unify_attribute_store_node_state_get_status(updated_node) != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { + if (unify_attribute_store_node_state_get_status(updated_node) + != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { return; } @@ -740,9 +741,10 @@ sl_status_t binding_cluster_server_init() &unbind_from_protocol_controller_callback); // Register attribute updates - attribute_store_register_callback_by_type_and_state(&on_network_status_update, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - REPORTED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_network_status_update, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + REPORTED_ATTRIBUTE); attribute_store_register_callback_by_type_and_state( &on_group_command_list_udpate, diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.cpp index b35112aa7..2c36d3e2e 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.cpp @@ -58,14 +58,16 @@ sl_status_t NodeStateNetworkStatus get_network_status(attribute_store_node_t node) { // Default to UNAVAILABLE if the value is undefined in the attribute store - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_node_t node_id_node = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_NODE_ID); attribute_store_node_t network_status_node - = attribute_store_get_first_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + = attribute_store_get_first_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.hpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.hpp index 51c463de5..6f675f00c 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.hpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_cluster_servers_helpers.hpp @@ -50,7 +50,6 @@ sl_status_t zwave_endpoint_id_t &endpoint_id, std::string &unid); - #ifdef __cplusplus } #endif diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_rf_telemetry_cluster_server.c b/applications/zpc/components/zcl_cluster_servers/src/zcl_rf_telemetry_cluster_server.c index e3383eba0..e2f26b54a 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_rf_telemetry_cluster_server.c +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_rf_telemetry_cluster_server.c @@ -265,10 +265,10 @@ static void fields.route_changed = (tx_report->route_scheme_state == ROUTINGSCHEME_CACHED_ROUTE) ? false : true; - fields.transmission_speed = transmission_speed; - fields.measured_noise_floord_bm = tx_report->measured_noise_floor; - fields.last_route_repeaters_count = tx_report->number_of_repeaters; - fields.last_route_repeaters = (const char **)repeaters_unid; + fields.transmission_speed = transmission_speed; + fields.measured_noise_floord_bm = tx_report->measured_noise_floor; + fields.last_route_repeaters_count = tx_report->number_of_repeaters; + fields.last_route_repeaters = (const char **)repeaters_unid; fields.incoming_rssi_repeaters_count = tx_report->number_of_repeaters; fields.incoming_rssi_repeaters = (const int8_t *)tx_report->rssi_values.incoming; diff --git a/applications/zpc/components/zcl_cluster_servers/src/zcl_scenes_cluster_server.cpp b/applications/zpc/components/zcl_cluster_servers/src/zcl_scenes_cluster_server.cpp index 9982fb648..7d6e7efde 100644 --- a/applications/zpc/components/zcl_cluster_servers/src/zcl_scenes_cluster_server.cpp +++ b/applications/zpc/components/zcl_cluster_servers/src/zcl_scenes_cluster_server.cpp @@ -406,7 +406,8 @@ static void publish_scene_table(attribute_store_node_t scene_table_node) "Publishing the Scene Table for Attribute ID %d", scene_table_node); // Read the network status, do not publish if it is not online functional: - if (unify_attribute_store_node_state_get_status(scene_table_node) != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { + if (unify_attribute_store_node_state_get_status(scene_table_node) + != ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL) { sl_log_debug(LOG_TAG, "Not online functional for Attribute ID %d", scene_table_node); @@ -1234,9 +1235,10 @@ sl_status_t zcl_scenes_cluster_server_init() COUNT_OF(scene_table_attributes)); // Make sure to publish the scene table when a node becomes available. - attribute_store_register_callback_by_type_and_state(&on_network_status_update, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - REPORTED_ATTRIBUTE); + attribute_store_register_callback_by_type_and_state( + &on_network_status_update, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + REPORTED_ATTRIBUTE); // Callback for Dotdot MQTT commands uic_mqtt_dotdot_scenes_add_scene_callback_set( diff --git a/applications/zpc/components/zcl_cluster_servers/test/configuration_parameter_cluster_server_test.c b/applications/zpc/components/zcl_cluster_servers/test/configuration_parameter_cluster_server_test.c index 99fc6fb51..2ac3712ec 100644 --- a/applications/zpc/components/zcl_cluster_servers/test/configuration_parameter_cluster_server_test.c +++ b/applications/zpc/components/zcl_cluster_servers/test/configuration_parameter_cluster_server_test.c @@ -449,7 +449,8 @@ void test_configuration_publishing_attributes_on_update_after_network_status_upd EXPECTED_BASE_TOPIC, 1); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_child_reported(node_id_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, &network_status, diff --git a/applications/zpc/components/zcl_cluster_servers/test/fan_control_cluster_server_test.c b/applications/zpc/components/zcl_cluster_servers/test/fan_control_cluster_server_test.c index 12ded94df..99e3ea939 100644 --- a/applications/zpc/components/zcl_cluster_servers/test/fan_control_cluster_server_test.c +++ b/applications/zpc/components/zcl_cluster_servers/test/fan_control_cluster_server_test.c @@ -104,7 +104,7 @@ void test_fan_control_command_mapping() SL_STATUS_OK, attribute_store_get_desired(off_node, &off_flag, sizeof(off_flag)), "Can't get Off flag value"); - + // Test value TEST_ASSERT_EQUAL(1, off_flag); } diff --git a/applications/zpc/components/zcl_cluster_servers/test/zcl_binding_cluster_server_test.c b/applications/zpc/components/zcl_cluster_servers/test/zcl_binding_cluster_server_test.c index a34ab9fe9..c12416774 100644 --- a/applications/zpc/components/zcl_cluster_servers/test/zcl_binding_cluster_server_test.c +++ b/applications/zpc/components/zcl_cluster_servers/test/zcl_binding_cluster_server_test.c @@ -18,7 +18,6 @@ #include "attribute_store_defined_attribute_types.h" #include "zwave_command_class_association_types.h" - // Test helpers #include "zpc_attribute_store_test_helper.h" @@ -175,7 +174,8 @@ void test_binding_cluster_server_test_publish_attributes_after_network_status_up UCL_MQTT_PUBLISH_TYPE_REPORTED, SL_STATUS_OK); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_child_reported(node_id_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, &network_status, @@ -281,7 +281,8 @@ void test_binding_cluster_server_no_publish_for_zpc() &group_count, sizeof(group_count)); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_child_reported(zpc_node_id_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, &network_status, @@ -317,7 +318,8 @@ void test_binding_cluster_server_no_valid_unid() &group_count, sizeof(group_count)); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_child_reported(root_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, &network_status, @@ -848,7 +850,8 @@ void test_binding_cluster_server_bind_multiple_groups_and_publish() UCL_MQTT_PUBLISH_TYPE_REPORTED, SL_STATUS_OK); - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL; attribute_store_set_child_reported(node_id_node, DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, &network_status, diff --git a/applications/zpc/components/zcl_cluster_servers/test/zcl_scenes_cluster_server_test.c b/applications/zpc/components/zcl_cluster_servers/test/zcl_scenes_cluster_server_test.c index f9b59cd97..78f76c656 100644 --- a/applications/zpc/components/zcl_cluster_servers/test/zcl_scenes_cluster_server_test.c +++ b/applications/zpc/components/zcl_cluster_servers/test/zcl_scenes_cluster_server_test.c @@ -26,7 +26,6 @@ // Interfaces/definitions - // ZPC Components #include "zwave_unid.h" #include "attribute_store_defined_attribute_types.h" diff --git a/applications/zpc/components/zpc_application_monitoring/test/zpc_application_monitoring_test.c b/applications/zpc/components/zpc_application_monitoring/test/zpc_application_monitoring_test.c index dba138d2d..522066e61 100644 --- a/applications/zpc/components/zpc_application_monitoring/test/zpc_application_monitoring_test.c +++ b/applications/zpc/components/zpc_application_monitoring/test/zpc_application_monitoring_test.c @@ -30,7 +30,8 @@ void setUp() {} void test_zpc_application_monitoring() { - unify_application_monitoring_set_application_name_Expect(ZPC_APPLICATION_NAME); + unify_application_monitoring_set_application_name_Expect( + ZPC_APPLICATION_NAME); unify_application_monitoring_set_application_version_Expect(UIC_VERSION); unify_application_monitoring_init_ExpectAndReturn(SL_STATUS_OK); TEST_ASSERT_EQUAL(SL_STATUS_OK, zpc_application_monitoring_init()); diff --git a/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_group.cpp b/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_group.cpp index 84324704e..f36eb5ea0 100644 --- a/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_group.cpp +++ b/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_group.cpp @@ -201,8 +201,7 @@ static sl_status_t assign_multicast_pool(attribute_store_node_t node) } bool use_supervision - = zwave_node_want_supervision_frame(node_id, - endpoint_id); + = zwave_node_want_supervision_frame(node_id, endpoint_id); // Node details validation. can this node be part of a multicast? if (protocol == PROTOCOL_UNKNOWN) { diff --git a/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_send.c b/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_send.c index cd390123d..c6943efa8 100644 --- a/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_send.c +++ b/applications/zpc/components/zpc_attribute_resolver/src/zpc_attribute_resolver_send.c @@ -82,9 +82,7 @@ sl_status_t attribute_resolver_send(attribute_store_node_t node, sl_status_t send_status = SL_STATUS_OK; zwave_tx_session_id_t tx_session_id = NULL; if (is_set == true - && true - == zwave_node_want_supervision_frame(node_id, - endpoint_id)) { + && true == zwave_node_want_supervision_frame(node_id, endpoint_id)) { // Send with Supervision send_status = zwave_command_class_supervision_send_data( &connection_info, diff --git a/applications/zpc/components/zpc_attribute_resolver/test/zpc_attribute_resolver_test.c b/applications/zpc/components/zpc_attribute_resolver/test/zpc_attribute_resolver_test.c index d3dece4d2..d30c84476 100644 --- a/applications/zpc/components/zpc_attribute_resolver/test/zpc_attribute_resolver_test.c +++ b/applications/zpc/components/zpc_attribute_resolver/test/zpc_attribute_resolver_test.c @@ -41,12 +41,12 @@ #include // Static test variables -static resolver_on_set_rule_registered_t set_rule_notification_function = NULL; +static resolver_on_set_rule_registered_t set_rule_notification_function = NULL; static attribute_store_node_changed_callback_t set_notification_function = NULL; -static attribute_resolver_config_t received_resolver_config = {}; -static on_zwave_tx_send_data_complete_t received_send_data_complete = NULL; -static uint8_t custom_handler_calls = 0; -static void *received_user = NULL; +static attribute_resolver_config_t received_resolver_config = {}; +static on_zwave_tx_send_data_complete_t received_send_data_complete = NULL; +static uint8_t custom_handler_calls = 0; +static void *received_user = NULL; // Stub functions. // Saving registration/init data to the Unify Attribute resolver. diff --git a/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h b/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h index 8d5e36adb..c2501bd20 100644 --- a/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h +++ b/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h @@ -578,8 +578,9 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_DEVICE_RESET_LOCALLY_VERSION, // Humidity Control Mode Command Class ///< This represents the version of the Humidity Control Mode Command class. /// zwave_cc_version_t -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION, - ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_MODE)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_VERSION, + ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_MODE)) // Supported mode DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES, @@ -593,47 +594,57 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_CURRENT_MODE, // Humidity Control Operating State Command Class ///< This represents the version of the Humidity Control Mode Command class. /// zwave_cc_version_t -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_VERSION, - ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_VERSION, + ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE)) // Current state -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE, - ((COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE << 8) | 0x02)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE_CURRENT_STATE, + ((COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE << 8) | 0x02)) ///////////////////////////////////////////////// // Humidity Control Setpoint Command Class ///< This represents the version of the Humidity Control Mode Command class. /// zwave_cc_version_t -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VERSION, - ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VERSION, + ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_TYPES, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x02)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_TYPES, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x02)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_TYPE, ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x03)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_SCALE, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x04)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_SUPPORTED_SCALE, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x04)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE, ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x05)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_SCALE, ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x06)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x07)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_VALUE_PRECISION, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x07)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE, ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x08)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_SCALE, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x09)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_PRECISION, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0A)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_SCALE, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x09)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MIN_VALUE_PRECISION, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0A)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE, ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0B)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_SCALE, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0C)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_PRECISION, - ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0D)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_SCALE, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0C)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT_MAX_VALUE_PRECISION, + ((COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT << 8) | 0x0D)) ///////////////////////////////////////////////// // Inclusion Controller Command Class @@ -720,8 +731,9 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_AGGREGATED_MEMBERS, ((COMMAND_CLASS_MULTI_CHANNEL_V3 << 8) | 0x06)) /** If set will send the endpoint Generic/Specific device class in ZW_MULTI_CHANNEL_END_POINT_FIND */ -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, - ((COMMAND_CLASS_MULTI_CHANNEL_V3 << 8) | 0x07)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + ((COMMAND_CLASS_MULTI_CHANNEL_V3 << 8) | 0x07)) ///////////////////////////////////////////////// // Notification Command Class @@ -803,32 +815,40 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE, // 0x05 DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_SCALE, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x04 + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) + | (0x04 + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) // 0x06 DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_VALUE_PRECISION, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x04 + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) + | (0x04 + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE, ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x07)) // 0x08 DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_SCALE, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x07 + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) + | (0x07 + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) // 0x09 -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_PRECISION, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x07 + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MIN_VALUE_PRECISION, + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) + | (0x07 + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE, ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x0A)) // 0x0B DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_SCALE, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x0A + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) -// 0x0C -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_PRECISION, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | (0x0A + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) - + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) + | (0x0A + SETPOINT_SCALE_ATTRIBUTE_ID_OFFSET))) +// 0x0C +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_MAX_VALUE_PRECISION, + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) + | (0x0A + SETPOINT_PRECISION_ATTRIBUTE_ID_OFFSET))) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_USE_B_INTERPRETATION, - ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x0D)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_USE_B_INTERPRETATION, + ((COMMAND_CLASS_THERMOSTAT_SETPOINT << 8) | 0x0D)) ///////////////////////////////////////////////// // Thermostat Fan Mode Command Class @@ -851,24 +871,28 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_OFF_FLAG, DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_VERSION, ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_THERMOSTAT_FAN_STATE)) /// Current Fan operating state -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE, - ((COMMAND_CLASS_THERMOSTAT_FAN_STATE << 8) | 0x02)) - +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE, + ((COMMAND_CLASS_THERMOSTAT_FAN_STATE << 8) | 0x02)) ///////////////////////////////////////////////// // Thermostat Operating State Command Class /// zwave_cc_version_t -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_VERSION, - ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_THERMOSTAT_OPERATING_STATE)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_VERSION, + ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_THERMOSTAT_OPERATING_STATE)) /// Current State -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_CURRENT_STATE, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x02)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_CURRENT_STATE, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x02)) /// Log supported count (v2) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_SUPPORTED_BITMASK, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x03)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_SUPPORTED_BITMASK, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x03)) /// Log supported (v2) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_SUPPORTED, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x04)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_SUPPORTED, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x04)) /// Log count (v2) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_BITMASK, ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x05)) @@ -876,17 +900,21 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_BITMASK, DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_STATE, ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x06)) /// Log Usage Today (hours) (v2) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_TODAY_HOURS, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x07)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_TODAY_HOURS, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x07)) /// Log Usage Today (min) (v2) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_TODAY_MIN, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x08)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_TODAY_MIN, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x08)) /// Log Usage Yesterday (hours) (v2) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_YESTERDAY_HOURS, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x09)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_YESTERDAY_HOURS, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x09)) /// Log Usage Yesterday (min) (v2) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_YESTERDAY_MIN, - ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x0A)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_LOG_USAGE_YESTERDAY_MIN, + ((COMMAND_CLASS_THERMOSTAT_OPERATING_STATE << 8) | 0x0A)) ///////////////////////////////////////////////// // Wakeup command class @@ -1105,8 +1133,9 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, ((COMMAND_CLASS_SOUND_SWITCH << 8) | 0x04)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER, ((COMMAND_CLASS_SOUND_SWITCH << 8) | 0x05)) -DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_DURATION_SECONDS, - ((COMMAND_CLASS_SOUND_SWITCH << 8) | 0x06)) +DEFINE_ATTRIBUTE( + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_DURATION_SECONDS, + ((COMMAND_CLASS_SOUND_SWITCH << 8) | 0x06)) DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_NAME, ((COMMAND_CLASS_SOUND_SWITCH << 8) | 0x07)) // Command is used to instruct a supporting node to play (or stop playing) a tone. diff --git a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_fan_types.h b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_fan_types.h index 091babfa9..d2694c574 100644 --- a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_fan_types.h +++ b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_fan_types.h @@ -31,7 +31,6 @@ #include - // Fan Mode CC ///> Off flag (version >= 2). uint8_t typedef uint8_t thermostat_fan_mode_off_flag_t; diff --git a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_setpoint_types.h b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_setpoint_types.h index 8a9870926..5e435110d 100644 --- a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_setpoint_types.h +++ b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_thermostat_setpoint_types.h @@ -37,6 +37,5 @@ typedef int32_t thermostat_setpoint_value_t; typedef uint8_t thermostat_setpoint_scale_t; typedef uint8_t thermostat_setpoint_precision_t; - #endif //ZWAVE_COMMAND_CLASS_THERMOSTAT_SETPOINT_TYPES_H /** @} end zwave_command_class_thermostat_setpoint_types */ diff --git a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_wake_up_types.h b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_wake_up_types.h index 473bc9a54..946f89ef7 100644 --- a/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_wake_up_types.h +++ b/applications/zpc/components/zpc_attribute_store/include/command_class_types/zwave_command_class_wake_up_types.h @@ -29,6 +29,5 @@ typedef uint32_t wake_up_interval_t; ///> bit 0 represents the Wake Up On demand capabilities. typedef uint8_t wake_up_bitmask_t; - #endif //ZWAVE_COMMAND_CLASS_WAKE_UP_TYPES_H /** @} end zwave_command_class_wake_up_types */ diff --git a/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store.h b/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store.h index 54a547b31..432c4ff38 100644 --- a/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store.h +++ b/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store.h @@ -72,7 +72,8 @@ attribute_store_node_t get_zpc_node_id_node(); * @returns The Endpoint ID attribute store node. ATTRIBUTE_STORE_INVALID_NODE if * the attribute store does not have our HomeID, NodeID or Endpoint ID node. */ -attribute_store_node_t get_zpc_endpoint_id_node(zwave_endpoint_id_t endpoint_id); +attribute_store_node_t + get_zpc_endpoint_id_node(zwave_endpoint_id_t endpoint_id); /** * @brief Initialize attribute store specifically for ZPC diff --git a/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store_network_helper.h b/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store_network_helper.h index 053343275..6543bfe24 100644 --- a/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store_network_helper.h +++ b/applications/zpc/components/zpc_attribute_store/include/zpc_attribute_store_network_helper.h @@ -22,7 +22,6 @@ #include "zwave_unid.h" #include "zwave_controller_types.h" // for zwave_endpoint_id_t - /** * @defgroup zpc_attribute_store_network_helpers ZPC Attribute Store Z-Wave Network Helpers * @ingroup zpc_attribute_store diff --git a/applications/zpc/components/zpc_attribute_store/include/zwave_frame_parser.hpp b/applications/zpc/components/zpc_attribute_store/include/zwave_frame_parser.hpp index e8163a19f..2ebd4dcf1 100644 --- a/applications/zpc/components/zpc_attribute_store/include/zwave_frame_parser.hpp +++ b/applications/zpc/components/zpc_attribute_store/include/zwave_frame_parser.hpp @@ -304,7 +304,7 @@ class zwave_frame_parser * @return The string read from the frame */ std::string read_string(); - /** + /** * @brief Convenience function to read a string (ASCII) from the frame and store in in the attribute store * * This helper function will read the first byte to determine the string length, then parse the @@ -326,7 +326,6 @@ class zwave_frame_parser */ std::string read_string(attribute_store_node_t node); - /** * @brief Read a sequence of bytes from the frame * diff --git a/applications/zpc/components/zpc_attribute_store/include/zwave_utils.h b/applications/zpc/components/zpc_attribute_store/include/zwave_utils.h index 7f49609d8..29136ccfc 100644 --- a/applications/zpc/components/zpc_attribute_store/include/zwave_utils.h +++ b/applications/zpc/components/zpc_attribute_store/include/zwave_utils.h @@ -62,7 +62,8 @@ extern "C" { * - true if the node/endpoint supports NLS * - false if the node/endpoint does not support NLS */ -bool zwave_get_nls_support(zwave_node_id_t node_id, attribute_store_node_value_state_t value_state); +bool zwave_get_nls_support(zwave_node_id_t node_id, + attribute_store_node_value_state_t value_state); /** * @brief Returns whether a node has Network Layer Security (NLS) enabled @@ -78,7 +79,8 @@ bool zwave_get_nls_support(zwave_node_id_t node_id, attribute_store_node_value_s * - true if the node/endpoint has NLS enabled * - false if the node/endpoint has NLS disabled */ -bool zwave_get_nls_state(zwave_node_id_t node_id, attribute_store_node_value_state_t value_state); +bool zwave_get_nls_state(zwave_node_id_t node_id, + attribute_store_node_value_state_t value_state); /** * @brief Stores Network Layer Security (NLS) support for a NodeID in the attribute store. @@ -90,9 +92,10 @@ bool zwave_get_nls_state(zwave_node_id_t node_id, attribute_store_node_value_sta * * @returns SL_STATUS_OK on success, any other code if not successful. */ -sl_status_t zwave_store_nls_support(zwave_node_id_t node_id, - bool is_nls_supported, - attribute_store_node_value_state_t value_state); +sl_status_t + zwave_store_nls_support(zwave_node_id_t node_id, + bool is_nls_supported, + attribute_store_node_value_state_t value_state); /** * @brief Stores Network Layer Security (NLS) state for a NodeID in the attribute store. @@ -104,9 +107,10 @@ sl_status_t zwave_store_nls_support(zwave_node_id_t node_id, * * @returns SL_STATUS_OK on success, any other code if not successful. */ -sl_status_t zwave_store_nls_state(zwave_node_id_t node_id, - bool is_nls_enabled, - attribute_store_node_value_state_t value_state); +sl_status_t + zwave_store_nls_state(zwave_node_id_t node_id, + bool is_nls_enabled, + attribute_store_node_value_state_t value_state); /** * @brief Returns the operating mode of a node @@ -234,13 +238,13 @@ zwave_cc_version_t */ attribute_store_node_t zwave_get_endpoint_node(zwave_node_id_t node_id, zwave_endpoint_id_t endpoint_id); - /** +/** * @brief Verify if we registered a node as supporting S2. * * @param node_id The NodeID that supports S2. * @returns True if the node has been registered to support S2, false otherwise */ - bool zwave_security_validation_is_node_s2_capable(zwave_node_id_t node_id); +bool zwave_security_validation_is_node_s2_capable(zwave_node_id_t node_id); /** * @brief Sets a node as S2 capable, meaning that we know it supports S2, diff --git a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store.c b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store.c index b14bfd677..bcba9f5b2 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store.c +++ b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store.c @@ -21,7 +21,6 @@ // Interfaces - // Includes from ZPC components #include "zwave_network_management.h" @@ -83,12 +82,13 @@ static void zpc_attribute_store_update_all_network_statuses( while (node_id_node != ATTRIBUTE_STORE_INVALID_NODE) { // Transition the network status from old value to new value: attribute_store_node_t network_status_node - = attribute_store_get_node_child_by_value(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, - REPORTED_ATTRIBUTE, - (uint8_t*)(&old_value), - sizeof(old_value), - 0); + = attribute_store_get_node_child_by_value( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + REPORTED_ATTRIBUTE, + (uint8_t *)(&old_value), + sizeof(old_value), + 0); attribute_store_set_reported(network_status_node, &new_value, sizeof(new_value)); @@ -186,7 +186,6 @@ static sl_status_t invoke_update_callbacks_in_network() return refresh; } - void disable_unsupported_ucl_commands() { // OnOff cluster @@ -214,9 +213,9 @@ sl_status_t zpc_attribute_store_init() // Configure the Unify DotDot Attribute Store component: unify_dotdot_attribute_store_set_configuration(&zpc_configuration); - // Mark some command as unsupported by ZPC + // Mark some command as unsupported by ZPC // We need to do that here because this component is called after the UCL cluster - // Clear the callbacks we don't need for ZPC only + // Clear the callbacks we don't need for ZPC only disable_unsupported_ucl_commands(); // Just simulate an update of the whole Attribute Store. diff --git a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_network_helper.c b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_network_helper.c index 86cf43768..65aabf2f7 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_network_helper.c +++ b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_network_helper.c @@ -422,14 +422,16 @@ NodeStateNetworkStatus attribute_store_network_helper_get_network_status(attribute_store_node_t node) { // Default to UNAVAILABLE if the value is undefined in the attribute store - NodeStateNetworkStatus network_status = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; + NodeStateNetworkStatus network_status + = ZCL_NODE_STATE_NETWORK_STATUS_UNAVAILABLE; attribute_store_node_t node_id_node = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_NODE_ID); attribute_store_node_t network_status_node - = attribute_store_get_first_child_by_type(node_id_node, - DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); + = attribute_store_get_first_child_by_type( + node_id_node, + DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS); attribute_store_get_reported(network_status_node, &network_status, sizeof(network_status)); diff --git a/applications/zpc/components/zpc_attribute_store/src/zwave_association_toolbox.cpp b/applications/zpc/components/zpc_attribute_store/src/zwave_association_toolbox.cpp index 6c37e7316..e010691c5 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zwave_association_toolbox.cpp +++ b/applications/zpc/components/zpc_attribute_store/src/zwave_association_toolbox.cpp @@ -170,13 +170,11 @@ void substract_association_lists(const association_set &set_1, } void merge_association_lists(const association_set &set_1, - const association_set &set_2, - association_set &result) + const association_set &set_2, + association_set &result) { - - result.insert(set_1.begin(),set_1.end()); - result.insert(set_2.begin(),set_2.end()); - + result.insert(set_1.begin(), set_1.end()); + result.insert(set_2.begin(), set_2.end()); } ////////////////////////////////////////////////////////////////////////////// diff --git a/applications/zpc/components/zpc_attribute_store/src/zwave_frame_generator.cpp b/applications/zpc/components/zpc_attribute_store/src/zwave_frame_generator.cpp index e26cd4ce0..98c2034c6 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zwave_frame_generator.cpp +++ b/applications/zpc/components/zpc_attribute_store/src/zwave_frame_generator.cpp @@ -20,7 +20,7 @@ // Cpp includes #include -#include // for ostringstream +#include // for ostringstream #include // for std::for_each constexpr char LOG_TAG[] = "zwave_frame_generator"; diff --git a/applications/zpc/components/zpc_attribute_store/src/zwave_frame_parser.cpp b/applications/zpc/components/zpc_attribute_store/src/zwave_frame_parser.cpp index 7a11ed1c9..e92388960 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zwave_frame_parser.cpp +++ b/applications/zpc/components/zpc_attribute_store/src/zwave_frame_parser.cpp @@ -77,10 +77,12 @@ zwave_report_bitmask_t zwave_frame_parser::read_bitmask(uint8_t bitmask_length) constexpr uint8_t BITMASK_SIZE = SUPPORT_BITMASK_SIZE * 8; if (bitmask_length > BITMASK_SIZE) { - sl_log_critical(LOG_TAG, - "Invalid bitmask size in read_bitmask, must be less than or equal to %d", - SUPPORT_BITMASK_SIZE); - throw std::runtime_error("Critical error in read_bitmask. This should not happen."); + sl_log_critical( + LOG_TAG, + "Invalid bitmask size in read_bitmask, must be less than or equal to %d", + SUPPORT_BITMASK_SIZE); + throw std::runtime_error( + "Critical error in read_bitmask. This should not happen."); } // Read the first byte if the length is not provided diff --git a/applications/zpc/components/zpc_attribute_store/src/zwave_utils.c b/applications/zpc/components/zpc_attribute_store/src/zwave_utils.c index 3102abf87..895c664da 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zwave_utils.c +++ b/applications/zpc/components/zpc_attribute_store/src/zwave_utils.c @@ -27,7 +27,8 @@ #include "sl_log.h" #define LOG_TAG "zwave_utils" -bool zwave_get_nls_support(zwave_node_id_t node_id, attribute_store_node_value_state_t value_state) +bool zwave_get_nls_support(zwave_node_id_t node_id, + attribute_store_node_value_state_t value_state) { attribute_store_node_t node_id_node = attribute_store_network_helper_get_zwave_node_id_node(node_id); @@ -78,9 +79,10 @@ bool zwave_get_nls_state(zwave_node_id_t node_id, return (bool)nls_enabled; } -sl_status_t zwave_store_nls_support(zwave_node_id_t node_id, - bool is_nls_supported, - attribute_store_node_value_state_t value_state) +sl_status_t + zwave_store_nls_support(zwave_node_id_t node_id, + bool is_nls_supported, + attribute_store_node_value_state_t value_state) { uint8_t value = (uint8_t)is_nls_supported; @@ -104,9 +106,10 @@ sl_status_t zwave_store_nls_support(zwave_node_id_t node_id, } } -sl_status_t zwave_store_nls_state(zwave_node_id_t node_id, - bool is_nls_enabled, - attribute_store_node_value_state_t value_state) +sl_status_t + zwave_store_nls_state(zwave_node_id_t node_id, + bool is_nls_enabled, + attribute_store_node_value_state_t value_state) { uint8_t value = (uint8_t)is_nls_enabled; @@ -402,7 +405,6 @@ attribute_store_node_t zwave_get_endpoint_node(zwave_node_id_t node_id, zwave_unid_from_node_id(node_id, node_unid); return attribute_store_network_helper_get_endpoint_node(node_unid, endpoint_id); - } bool zwave_security_validation_is_node_s2_capable(zwave_node_id_t node_id) diff --git a/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_network_helper_test.c b/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_network_helper_test.c index 7f495d4b2..340b44b7b 100644 --- a/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_network_helper_test.c +++ b/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_network_helper_test.c @@ -578,7 +578,8 @@ static void create_test_network() // set the network status of attribute_store_node_t network_status_node - = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_expected); + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_expected); uint8_t test_online_network_status = 0x01; attribute_store_set_node_attribute_value(network_status_node, REPORTED_ATTRIBUTE, diff --git a/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_test.c b/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_test.c index e1260af54..316ce521d 100644 --- a/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_test.c +++ b/applications/zpc/components/zpc_attribute_store/test/zpc_attribute_store_test.c @@ -51,7 +51,7 @@ int suiteTearDown(int num_failures) /// Called before each and every test void SetUp() {} -void callback_test(attribute_changed_event_t* change) +void callback_test(attribute_changed_event_t *change) { if (change->change == ATTRIBUTE_UPDATED) { callback_counter++; diff --git a/applications/zpc/components/zpc_attribute_store/test/zwave_utils_test.c b/applications/zpc/components/zpc_attribute_store/test/zwave_utils_test.c index b8c5d0646..9b6004d67 100644 --- a/applications/zpc/components/zpc_attribute_store/test/zwave_utils_test.c +++ b/applications/zpc/components/zpc_attribute_store/test/zwave_utils_test.c @@ -696,21 +696,21 @@ static const attribute_store_node_t test_secure_nif_node = 0x72; // Test constant static uint8_t test_nif[] = {0xD2, - 0x09, - 0xFB, - 0x01, - 0xBD, - 0xCB, - 0x92, - 0xA7, - 0xCA, - 0x1A, - 0xEA, - 0x99, - 0xC6, - 0x66, - 0x9F, - 0xFF}; + 0x09, + 0xFB, + 0x01, + 0xBD, + 0xCB, + 0x92, + 0xA7, + 0xCA, + 0x1A, + 0xEA, + 0x99, + 0xC6, + 0x66, + 0x9F, + 0xFF}; static uint8_t test_nif_length = sizeof(test_nif); static uint8_t test_nif_tricky_two_bytes[] = {0xD2, @@ -1200,9 +1200,9 @@ void test_is_command_in_array() is_command_in_array(0x9F, 0x12, command_list_4, sizeof(command_list_4))); } - -void zwave_node_supports_command_class_mock_helper() { - attribute_store_network_helper_get_endpoint_node_ExpectAndReturn( +void zwave_node_supports_command_class_mock_helper() +{ + attribute_store_network_helper_get_endpoint_node_ExpectAndReturn( test_unid, test_endpoint_id, test_endpoint_node); @@ -1232,7 +1232,8 @@ void zwave_node_supports_command_class_mock_helper() { 1); } -void test_zwave_node_want_supervision_frame_no_defined_flag_happy_case() { +void test_zwave_node_want_supervision_frame_no_defined_flag_happy_case() +{ // Set mock support of COMMAND_CLASS_SUPERVISION zwave_node_supports_command_class_mock_helper(); @@ -1243,14 +1244,16 @@ void test_zwave_node_want_supervision_frame_no_defined_flag_happy_case() { zwave_node_want_supervision_frame(test_node_id, test_endpoint_id)); } -void test_zwave_node_want_supervision_frame_flag_happy_case() { +void test_zwave_node_want_supervision_frame_flag_happy_case() +{ // Set mock support of COMMAND_CLASS_SUPERVISION zwave_node_supports_command_class_mock_helper(); // Simulate flag == 1 attribute_store_node_t endpoint_node = 12; - uint8_t supervision_flag = 1; - attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn(endpoint_node); + uint8_t supervision_flag = 1; + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + endpoint_node); attribute_store_get_child_reported_ExpectAndReturn( endpoint_node, ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, @@ -1264,14 +1267,16 @@ void test_zwave_node_want_supervision_frame_flag_happy_case() { zwave_node_want_supervision_frame(test_node_id, test_endpoint_id)); } -void test_zwave_node_want_supervision_frame_flag_false_happy_case() { +void test_zwave_node_want_supervision_frame_flag_false_happy_case() +{ // Set mock support of COMMAND_CLASS_SUPERVISION zwave_node_supports_command_class_mock_helper(); // Simulate flag == 0 attribute_store_node_t endpoint_node = 12; - uint8_t supervision_flag = 0; - attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn(endpoint_node); + uint8_t supervision_flag = 0; + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn( + endpoint_node); attribute_store_get_child_reported_ExpectAndReturn( endpoint_node, ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, @@ -1285,8 +1290,9 @@ void test_zwave_node_want_supervision_frame_flag_false_happy_case() { zwave_node_want_supervision_frame(test_node_id, test_endpoint_id)); } -void test_zwave_node_want_supervision_no_supervision_cc_in_nif_happy_case() { - attribute_store_network_helper_get_endpoint_node_ExpectAndReturn( +void test_zwave_node_want_supervision_no_supervision_cc_in_nif_happy_case() +{ + attribute_store_network_helper_get_endpoint_node_ExpectAndReturn( test_unid, test_endpoint_id, test_endpoint_node); @@ -1314,8 +1320,8 @@ void test_zwave_node_want_supervision_no_supervision_cc_in_nif_happy_case() { test_nif, test_nif_length, false); - attribute_store_get_node_child_by_type_IgnoreAndReturn(ATTRIBUTE_STORE_INVALID_NODE); - + attribute_store_get_node_child_by_type_IgnoreAndReturn( + ATTRIBUTE_STORE_INVALID_NODE); TEST_ASSERT_FALSE( zwave_node_want_supervision_frame(test_node_id, test_endpoint_id)); diff --git a/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.cpp b/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.cpp index 0683d7eb3..63c63cab0 100644 --- a/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.cpp +++ b/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.cpp @@ -25,9 +25,11 @@ namespace zpc_attribute_store_test_helper { -attribute_store::attribute cpp_endpoint_id_node = ATTRIBUTE_STORE_INVALID_NODE; //NOSONAR - false positive +attribute_store::attribute cpp_endpoint_id_node + = ATTRIBUTE_STORE_INVALID_NODE; //NOSONAR - false positive -void zpc_attribute_store_test_helper_init() { +void zpc_attribute_store_test_helper_init() +{ // Create base structure zpc_attribute_store_test_helper_create_network(); // Cpp wrapper for endpoint id node @@ -79,7 +81,6 @@ void helper_test_node_does_not_exists(attribute_store_type_t node_type, parent.name()); } - //////////////////////////////////////////////////////////////////////////////////// // Version helpers //////////////////////////////////////////////////////////////////////////////////// @@ -106,4 +107,4 @@ zwave_cc_version_t } } -} // namespace zpc_attribute_store_test_helper \ No newline at end of file +} // namespace zpc_attribute_store_test_helper \ No newline at end of file diff --git a/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.hpp b/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.hpp index 2bb174398..379db40d6 100644 --- a/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.hpp +++ b/applications/zpc/components/zpc_attribute_store/test_helper/cpp_wrapper/zpc_attribute_store_test_helper_cpp.hpp @@ -41,8 +41,8 @@ namespace zpc_attribute_store_test_helper // More information : https://stackoverflow.com/questions/11478152/how-to-work-with-variable-in-namespace //////////////////////////////////////////////////////////////////////////////////// // Endpoint id node wrapper -extern attribute_store::attribute cpp_endpoint_id_node; //NOSONAR - false positive - +extern attribute_store::attribute + cpp_endpoint_id_node; //NOSONAR - false positive /** * @brief Initialize the test helper diff --git a/applications/zpc/components/zpc_config/include/device_id.h b/applications/zpc/components/zpc_config/include/device_id.h index 07d5e25b9..4410a2f9c 100644 --- a/applications/zpc/components/zpc_config/include/device_id.h +++ b/applications/zpc/components/zpc_config/include/device_id.h @@ -24,6 +24,6 @@ * for e.g. in Device specific report Command class * */ -const char* get_device_id(); +const char *get_device_id(); #endif // ZWAPI_SERIAL_H diff --git a/applications/zpc/components/zpc_config/include/zpc_config_fixt.h b/applications/zpc/components/zpc_config/include/zpc_config_fixt.h index 332897a60..46064c965 100644 --- a/applications/zpc/components/zpc_config/include/zpc_config_fixt.h +++ b/applications/zpc/components/zpc_config/include/zpc_config_fixt.h @@ -37,4 +37,4 @@ sl_status_t zpc_config_fixt_setup(void); /** @} end of zpc_config */ -#endif // ZPC_CONFIG_FIXT_H +#endif // ZPC_CONFIG_FIXT_H diff --git a/applications/zpc/components/zpc_datastore/include/zpc_datastore_fixt.h b/applications/zpc/components/zpc_datastore/include/zpc_datastore_fixt.h index 02cefecef..1da54bdd5 100644 --- a/applications/zpc/components/zpc_datastore/include/zpc_datastore_fixt.h +++ b/applications/zpc/components/zpc_datastore/include/zpc_datastore_fixt.h @@ -46,7 +46,7 @@ typedef enum zpc_datastore_version { * uint8_t instead of uint32_t */ DATASTORE_VERSION_V2, - /** + /** * @brief Version 3 of datastore database. * Changes from v2: * - ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES & ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SETPOINT_SUPPORTED_SETPOINT_TYPES are now uint32_t instead of array to easier mapping to uam diff --git a/applications/zpc/components/zpc_stdin/src/zpc_stdin_command_handling.cpp b/applications/zpc/components/zpc_stdin/src/zpc_stdin_command_handling.cpp index 1cd7682c0..ebb972827 100644 --- a/applications/zpc/components/zpc_stdin/src/zpc_stdin_command_handling.cpp +++ b/applications/zpc/components/zpc_stdin/src/zpc_stdin_command_handling.cpp @@ -217,12 +217,10 @@ const std::map> commands = { {"zwave_cc_versions_log", {"Print the CC version table", &handle_cc_versions_log}}, {"zwave_enable_nls", - {COLOR_START "" COLOR_END - "Enable NLS on a given node.", + {COLOR_START "" COLOR_END "Enable NLS on a given node.", &handle_enable_nls}}, {"zwave_get_nls_state", - {COLOR_START "" COLOR_END - "Print the NLS state of the given nodeID", + {COLOR_START "" COLOR_END "Print the NLS state of the given nodeID", &handle_get_nls_state}}, }; @@ -856,7 +854,7 @@ static sl_status_t handle_enable_nls(const handle_args_t &arg) } try { zwave_node_id_t node_id - = static_cast(std::stoi(arg[1].c_str(), nullptr, 10)); + = static_cast(std::stoi(arg[1].c_str(), nullptr, 10)); return zwave_store_nls_state(node_id, true, DESIRED_ATTRIBUTE); } catch (const std::invalid_argument &e) { @@ -877,21 +875,26 @@ static sl_status_t handle_get_nls_state(const handle_args_t &arg) try { zwave_node_id_t node_id = static_cast(std::stoi(arg[1].c_str(), nullptr, 10)); - uint8_t nls_state = 0; + uint8_t nls_state = 0; uint8_t nls_support = 0; - sl_status_t status = zwapi_get_node_nls(node_id, &nls_state, &nls_support); - if (SL_STATUS_OK == status) - { - status = zwave_store_nls_state(node_id, nls_state, REPORTED_ATTRIBUTE) || zwave_store_nls_support(node_id, nls_support, REPORTED_ATTRIBUTE); + sl_status_t status = zwapi_get_node_nls(node_id, &nls_state, &nls_support); + if (SL_STATUS_OK == status) { + status + = zwave_store_nls_state(node_id, nls_state, REPORTED_ATTRIBUTE) + || zwave_store_nls_support(node_id, nls_support, REPORTED_ATTRIBUTE); if (SL_STATUS_OK != status) { - dprintf(out_stream, "Unable to store NLS state for Node ID: %d\n", node_id); + dprintf(out_stream, + "Unable to store NLS state for Node ID: %d\n", + node_id); return SL_STATUS_FAIL; } - dprintf(out_stream, "Node ID %d, NLS Support: %d, NLS state: %d\n", node_id, nls_support, nls_state); + dprintf(out_stream, + "Node ID %d, NLS Support: %d, NLS state: %d\n", + node_id, + nls_support, + nls_state); return SL_STATUS_OK; - } - else - { + } else { dprintf(out_stream, "Unable to read NLS state for Node ID: %d\n", node_id); diff --git a/applications/zpc/components/zpc_stdin/test/zpc_stdin_test.c b/applications/zpc/components/zpc_stdin/test/zpc_stdin_test.c index 32bea36bd..bbea94b57 100644 --- a/applications/zpc/components/zpc_stdin/test/zpc_stdin_test.c +++ b/applications/zpc/components/zpc_stdin/test/zpc_stdin_test.c @@ -75,21 +75,21 @@ void test_zwave_set_default() void test_callbacks() { zwave_dsk_t dsk = {0x00, - 0x00, - 0xad, - 0xde, - 0xef, - 0xbe, - 0x10, - 0x01, - 0xad, - 0xde, - 0xef, - 0xbe, - 0xee, - 0xff, - 0x01, - 0x00}; + 0x00, + 0xad, + 0xde, + 0xef, + 0xbe, + 0x10, + 0x01, + 0xad, + 0xde, + 0xef, + 0xbe, + 0xee, + 0xff, + 0x01, + 0x00}; const zwave_controller_callbacks_t nm_callbacks = get_zpc_stdin_callbacks(); nm_callbacks.on_keys_report(true, 0x87); nm_callbacks.on_dsk_report(2, dsk, 0x87); @@ -333,13 +333,16 @@ void test_handle_cc_versions_log() void test_handle_nls() { sl_status_t state; - uint8_t nls_state = 0; + uint8_t nls_state = 0; uint8_t nls_support = 0; state = uic_stdin_handle_command("zwave_enable_nls"); TEST_ASSERT_EQUAL(SL_STATUS_FAIL, state); - zwave_store_nls_state_ExpectAndReturn(2, true, DESIRED_ATTRIBUTE, SL_STATUS_OK); + zwave_store_nls_state_ExpectAndReturn(2, + true, + DESIRED_ATTRIBUTE, + SL_STATUS_OK); state = uic_stdin_handle_command("zwave_enable_nls 2"); TEST_ASSERT_EQUAL(SL_STATUS_OK, state); @@ -347,8 +350,14 @@ void test_handle_nls() TEST_ASSERT_EQUAL(SL_STATUS_FAIL, state); zwapi_get_node_nls_ExpectAndReturn(2, &nls_state, &nls_support, SL_STATUS_OK); - zwave_store_nls_state_ExpectAndReturn(2, nls_state, REPORTED_ATTRIBUTE, SL_STATUS_OK); - zwave_store_nls_support_ExpectAndReturn(2, nls_support, REPORTED_ATTRIBUTE, SL_STATUS_OK); + zwave_store_nls_state_ExpectAndReturn(2, + nls_state, + REPORTED_ATTRIBUTE, + SL_STATUS_OK); + zwave_store_nls_support_ExpectAndReturn(2, + nls_support, + REPORTED_ATTRIBUTE, + SL_STATUS_OK); state = uic_stdin_handle_command("zwave_get_nls_state 2"); TEST_ASSERT_EQUAL(SL_STATUS_OK, state); } @@ -544,4 +553,3 @@ void test_zwave_command_handler_dispatch() state = uic_stdin_handle_command("zwave_command_handler_dispatch deadbeef42"); TEST_ASSERT_EQUAL(SL_STATUS_OK, state); } - diff --git a/applications/zpc/components/zpc_utils/include/zpc_hex_to_int.h b/applications/zpc/components/zpc_utils/include/zpc_hex_to_int.h index 99b89d52d..eb0aa81f7 100644 --- a/applications/zpc/components/zpc_utils/include/zpc_hex_to_int.h +++ b/applications/zpc/components/zpc_utils/include/zpc_hex_to_int.h @@ -33,6 +33,5 @@ extern "C" { */ int zpc_hex2int(char c); -#endif //ZPC_HEX_TO_INT_Hf +#endif //ZPC_HEX_TO_INT_Hf /** @} end zpc_hex_to_int*/ - diff --git a/applications/zpc/components/zpc_utils/src/zpc_hex_to_int.c b/applications/zpc/components/zpc_utils/src/zpc_hex_to_int.c index 84a86a844..2d96e26d8 100644 --- a/applications/zpc/components/zpc_utils/src/zpc_hex_to_int.c +++ b/applications/zpc/components/zpc_utils/src/zpc_hex_to_int.c @@ -14,17 +14,16 @@ #define LOG_TAG "zpc_hex2int" #include "zpc_hex_to_int.h" -int zpc_hex2int(char c) { - if(c >= '0' && c <= '9') { - return c-'0'; - } else if(c >= 'a' && c <= 'f') { - return c-'a' + 0xa; - } else if(c >= 'A' && c <= 'F') { - return c-'A' + 0xa; +int zpc_hex2int(char c) +{ + if (c >= '0' && c <= '9') { + return c - '0'; + } else if (c >= 'a' && c <= 'f') { + return c - 'a' + 0xa; + } else if (c >= 'A' && c <= 'F') { + return c - 'A' + 0xa; } else { sl_log_error(LOG_TAG, "Trying to convert non hex character to hexi\n"); return 0; } } - - diff --git a/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_callbacks.h b/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_callbacks.h index eac6657cf..3d363fc97 100644 --- a/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_callbacks.h +++ b/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_callbacks.h @@ -184,7 +184,7 @@ typedef struct { /// @param frame_data Pointer to de-encapsulated data /// /// @param frame_length Length of data - /// + /// void (*on_protocol_frame_received)( const zwave_controller_connection_info_t *connection_info, const zwave_rx_receive_options_t *rx_options, diff --git a/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_storage.h b/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_storage.h index e12eba5a5..77e80e986 100644 --- a/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_storage.h +++ b/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_storage.h @@ -57,7 +57,6 @@ typedef struct { zwave_endpoint_id_t endpoint_id); } zwave_controller_storage_callback_t; - /** * @brief zwave_controller_storage callbacks register API * diff --git a/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_utils.h b/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_utils.h index 64c9e39d6..ae5dea704 100644 --- a/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_utils.h +++ b/applications/zpc/components/zwave/zwave_controller/include/zwave_controller_utils.h @@ -39,8 +39,9 @@ extern "C" { #endif -#define ZWAVE_CMD_CLASS_PROTOCOL 0x01 /* Z-Wave protocol class command */ -#define ZWAVE_CMD_CLASS_PROTOCOL_LR 0x04 /* Z-Wave Long Range protocol class command */ +#define ZWAVE_CMD_CLASS_PROTOCOL 0x01 /* Z-Wave protocol class command */ +#define ZWAVE_CMD_CLASS_PROTOCOL_LR \ + 0x04 /* Z-Wave Long Range protocol class command */ /** * @brief Send a Z-Wave NOP frame to Z-Wave NodeID diff --git a/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_callbacks.c b/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_callbacks.c index 9e70c941f..9f80879ef 100644 --- a/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_callbacks.c +++ b/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_callbacks.c @@ -314,15 +314,15 @@ void zwave_controller_on_frame_received( //If no transport plugins needs the frame parse it on to upper layers if (status == SL_STATUS_NOT_FOUND) { ZWAVE_CONTROLLER_DISPATCH_CALLBACKS(on_application_frame_received, - connection_info, - rx_options, - frame_data, - frame_length); + connection_info, + rx_options, + frame_data, + frame_length); } else if (status == SL_STATUS_INVALID_PARAMETER) { - sl_log_warning(LOG_TAG, - "zwave_controller_on_frame_received: Invalid params"); + sl_log_warning(LOG_TAG, + "zwave_controller_on_frame_received: Invalid params"); } -} +} void zwave_controller_on_protocol_cc_encryption_request_received( const zwave_node_id_t destination_node_id, diff --git a/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_transport_internal.h b/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_transport_internal.h index c726a91c5..5ce42ff6f 100644 --- a/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_transport_internal.h +++ b/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_transport_internal.h @@ -43,11 +43,10 @@ extern "C" { * Otherwise the status if the executed hander list returned */ sl_status_t zwave_controller_transport_on_frame_received( - const zwave_controller_connection_info_t *connection_info, - const zwave_rx_receive_options_t *rx_options, - const uint8_t *frame_data, - uint16_t frame_length); - + const zwave_controller_connection_info_t *connection_info, + const zwave_rx_receive_options_t *rx_options, + const uint8_t *frame_data, + uint16_t frame_length); #ifdef __cplusplus } diff --git a/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_utils.c b/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_utils.c index 33cd6724b..16912a3a2 100644 --- a/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_utils.c +++ b/applications/zpc/components/zwave/zwave_controller/src/zwave_controller_utils.c @@ -286,17 +286,17 @@ void zwave_command_class_list_unpack(zwave_node_info_t *node_info, && (i < ZWAVE_CONTROLLER_MAXIMUM_COMMAND_CLASS_LIST_LENGTH)) { // Check if it's extended CC format (2 bytes length). Check // CC:0000.00.00.11.001 for more details - if (nif[nif_index] >= 0xF1) { // Belong to extended range - if (nif_index < nif_length - 1) { // Prevent read beyond + if (nif[nif_index] >= 0xF1) { // Belong to extended range + if (nif_index < nif_length - 1) { // Prevent read beyond node_info->command_class_list[i] = ((nif[nif_index] & 0xFF) << 8) | nif[nif_index + 1]; i++; nif_index += 2; } else { - sl_log_warning( - LOG_TAG, - "warning: zwave_command_class_list_unpack: invalid input: skipping"); - assert(false); + sl_log_warning( + LOG_TAG, + "warning: zwave_command_class_list_unpack: invalid input: skipping"); + assert(false); } } else { node_info->command_class_list[i++] = nif[nif_index++]; diff --git a/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_test.c b/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_test.c index 032fd0cee..fdc77e7a0 100644 --- a/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_test.c +++ b/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_test.c @@ -73,9 +73,9 @@ void test_zwave_controller_set_secure_nif() void test_zwave_controller_request_protocol_cc_encryption_callback() { - uint8_t status = TRANSMIT_COMPLETE_VERIFIED; - zwapi_tx_report_t tx_info = {0}; - uint8_t session_id = 0; + uint8_t status = TRANSMIT_COMPLETE_VERIFIED; + zwapi_tx_report_t tx_info = {0}; + uint8_t session_id = 0; zwapi_request_protocol_cc_encryption_callback_ExpectAndReturn(status, &tx_info, diff --git a/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_utils_test.c b/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_utils_test.c index a96288d06..197d8a9d2 100644 --- a/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_utils_test.c +++ b/applications/zpc/components/zwave/zwave_controller/test/zwave_controller_utils_test.c @@ -137,21 +137,21 @@ void test_is_command_class_in_supported_list() { // Test constant static uint8_t test_nif[] = {0xD2, - 0x09, - 0xFB, - 0x01, - 0xBD, - 0xCB, - 0x92, - 0xA7, - 0xCA, - 0x1A, - 0xEA, - 0x99, - 0xC6, - 0x66, - 0x9F, - 0xFF}; + 0x09, + 0xFB, + 0x01, + 0xBD, + 0xCB, + 0x92, + 0xA7, + 0xCA, + 0x1A, + 0xEA, + 0x99, + 0xC6, + 0x66, + 0x9F, + 0xFF}; static uint8_t test_nif_length = sizeof(test_nif); TEST_ASSERT_TRUE( @@ -229,15 +229,14 @@ void test_zwave_command_class_list_pack() void test_zwave_command_class_list_pack_extended() { - zwave_node_info_t node_info = { - .listening_protocol = 2, - .optional_protocol = 3, - .basic_device_class = 4, - .generic_device_class = 5, - .specific_device_class = 6, - .command_class_list_length = 3 + 3, - .command_class_list = {0x20, 0xEF, 0xF0, 0xF100, 0xF101, 0xFFFF} - }; + zwave_node_info_t node_info + = {.listening_protocol = 2, + .optional_protocol = 3, + .basic_device_class = 4, + .generic_device_class = 5, + .specific_device_class = 6, + .command_class_list_length = 3 + 3, + .command_class_list = {0x20, 0xEF, 0xF0, 0xF100, 0xF101, 0xFFFF}}; uint8_t nif[ZWAVE_CONTROLLER_MAXIMUM_COMMAND_CLASS_LIST_LENGTH * 2] = {0}; uint8_t nif_length = 0; diff --git a/applications/zpc/components/zwave/zwave_definitions/include/ZW_typedefs.h b/applications/zpc/components/zwave/zwave_definitions/include/ZW_typedefs.h index 195a348a1..5c3b0a8d2 100644 --- a/applications/zpc/components/zwave/zwave_definitions/include/ZW_typedefs.h +++ b/applications/zpc/components/zwave/zwave_definitions/include/ZW_typedefs.h @@ -1,5 +1,5 @@ /* © 2018 Silicon Laboratories Inc. - */ + */ /******************************* ZW_typedefs.h ******************************* * ####### * ## ## @@ -31,42 +31,41 @@ * Revision: $Revision: 29359 $ * Last Changed: $Date: 2014-07-11 11:13:33 +0200 (fr, 11 jul 2014) $ * - ****************************************************************************/ -#ifndef _ZW_TYPEDEFS_H_ -#define _ZW_TYPEDEFS_H_ - -/****************************************************************************/ -/* INCLUDE FILES */ -/****************************************************************************/ -#include -#include -#include - -/****************************************************************************/ -/* MACROS */ -/****************************************************************************/ -/****************************************************************************/ -/* EXPORTED TYPES and DEFINITIONS */ -/****************************************************************************/ -#define code -#define xdata - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef bool BOOL; - -#define CODE /* Used for defining callback function which allways */ - /* resides in code space. */ - -#define TRUE true -#define FALSE false - -/* Define for making easy and consistent callback definitions */ -#define VOID_CALLBACKFUNC(completedFunc) void (CODE *completedFunc) - - -#define UNUSED(x) x = x; /* Hack to silence warning C280 Unreferenced local variable */ - - -#endif /* _ZW_TYPEDEFS_H_ */ + ****************************************************************************/ +#ifndef _ZW_TYPEDEFS_H_ +#define _ZW_TYPEDEFS_H_ + +/****************************************************************************/ +/* INCLUDE FILES */ +/****************************************************************************/ +#include +#include +#include + +/****************************************************************************/ +/* MACROS */ +/****************************************************************************/ +/****************************************************************************/ +/* EXPORTED TYPES and DEFINITIONS */ +/****************************************************************************/ +#define code +#define xdata + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef bool BOOL; + +#define CODE /* Used for defining callback function which allways */ + /* resides in code space. */ + +#define TRUE true +#define FALSE false + +/* Define for making easy and consistent callback definitions */ +#define VOID_CALLBACKFUNC(completedFunc) void(CODE * completedFunc) + +#define UNUSED(x) \ + x = x; /* Hack to silence warning C280 Unreferenced local variable */ + +#endif /* _ZW_TYPEDEFS_H_ */ diff --git a/applications/zpc/components/zwave/zwave_definitions/include/zwave_rf_region.h b/applications/zpc/components/zwave/zwave_definitions/include/zwave_rf_region.h index 5b1cb622f..ce8305c14 100644 --- a/applications/zpc/components/zwave/zwave_definitions/include/zwave_rf_region.h +++ b/applications/zpc/components/zwave/zwave_definitions/include/zwave_rf_region.h @@ -58,7 +58,11 @@ typedef enum { } zwave_rf_region_t; ///@} -static inline bool IS_RF_REGION_LR(zwave_rf_region_t rf_region) { return (rf_region == ZWAVE_RF_REGION_US_LR) || (rf_region == ZWAVE_RF_REGION_EU_LR); } +static inline bool IS_RF_REGION_LR(zwave_rf_region_t rf_region) +{ + return (rf_region == ZWAVE_RF_REGION_US_LR) + || (rf_region == ZWAVE_RF_REGION_EU_LR); +} #endif // ZWAVE_RF_REGION_H /** @} end zwave_rf_region */ diff --git a/applications/zpc/components/zwave/zwave_definitions/include/zwave_rx_definitions.h b/applications/zpc/components/zwave/zwave_definitions/include/zwave_rx_definitions.h index 3c094a15f..5dba9931e 100644 --- a/applications/zpc/components/zwave/zwave_definitions/include/zwave_rx_definitions.h +++ b/applications/zpc/components/zwave/zwave_definitions/include/zwave_rx_definitions.h @@ -14,7 +14,6 @@ #ifndef ZWAVE_RX_DEFINITIONS_H #define ZWAVE_RX_DEFINITIONS_H - /** * @defgroup zwave_rx_definitions Z-Wave Controller Connection Info type * @ingroup zwave_definitions diff --git a/applications/zpc/components/zwave/zwave_network_management/src/state_logging.h b/applications/zpc/components/zwave/zwave_network_management/src/state_logging.h index 230711a88..bde1e5e79 100644 --- a/applications/zpc/components/zwave/zwave_network_management/src/state_logging.h +++ b/applications/zpc/components/zwave/zwave_network_management/src/state_logging.h @@ -33,7 +33,7 @@ extern "C" { * @param state * @return const char* */ -const char* nm_state_name(zwave_network_management_state_t state); +const char *nm_state_name(zwave_network_management_state_t state); /** * @brief Return the name string of a network management event. @@ -41,9 +41,7 @@ const char* nm_state_name(zwave_network_management_state_t state); * @param ev * @return const char* */ -const char * nm_event_name(nm_event_t ev); - - +const char *nm_event_name(nm_event_t ev); #ifdef __cplusplus } diff --git a/applications/zpc/components/zwave/zwave_rx/src/zwave_rx_process.c b/applications/zpc/components/zwave/zwave_rx/src/zwave_rx_process.c index 437545fe0..daac55596 100644 --- a/applications/zpc/components/zwave/zwave_rx/src/zwave_rx_process.c +++ b/applications/zpc/components/zwave/zwave_rx/src/zwave_rx_process.c @@ -36,7 +36,6 @@ void zwave_rx_poll() } } - //////////////////////////////////////////////////////////////////////////////// // Contiki Process //////////////////////////////////////////////////////////////////////////////// diff --git a/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test.c b/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test.c index 3f89ee4a0..55392e141 100644 --- a/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test.c +++ b/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test.c @@ -335,7 +335,6 @@ void test_zwave_rx_init_failure_lr_max_power() TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_rx_fixt_setup()); } - /// Test of rx init for with failure to set tx power / reporting void test_zwave_rx_init_non_critical_failures() { diff --git a/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test_zpc_config_mock.c b/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test_zpc_config_mock.c index 7a2ce4ae7..bbc5f4cc6 100644 --- a/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test_zpc_config_mock.c +++ b/applications/zpc/components/zwave/zwave_rx/test/zwave_rx_test_zpc_config_mock.c @@ -18,13 +18,12 @@ * here because this is not a unity test case. */ -static zpc_config_t my_test_configuration = { - .serial_log_file = "", - .serial_port = ZWAVE_RX_TEST_SERIAL_PORT, - .zwave_normal_tx_power_dbm = ZWAVE_RX_TEST_MAXIMUM_POWER_DBM, - .zwave_measured_0dbm_power = ZWAVE_RX_TEST_MEASURED_0DBM_POWER, - .zwave_rf_region = ZWAVE_RX_TEST_RF_REGION_STRING -}; +static zpc_config_t my_test_configuration + = {.serial_log_file = "", + .serial_port = ZWAVE_RX_TEST_SERIAL_PORT, + .zwave_normal_tx_power_dbm = ZWAVE_RX_TEST_MAXIMUM_POWER_DBM, + .zwave_measured_0dbm_power = ZWAVE_RX_TEST_MEASURED_0DBM_POWER, + .zwave_rf_region = ZWAVE_RX_TEST_RF_REGION_STRING}; const zpc_config_t *zpc_get_config() { diff --git a/applications/zpc/components/zwave/zwave_security_validation/src/zwave_security_validation.c b/applications/zpc/components/zwave/zwave_security_validation/src/zwave_security_validation.c index 5179bd64a..092e354db 100644 --- a/applications/zpc/components/zwave/zwave_security_validation/src/zwave_security_validation.c +++ b/applications/zpc/components/zwave/zwave_security_validation/src/zwave_security_validation.c @@ -73,9 +73,9 @@ bool zwave_security_validation_is_security_valid_for_support( connection->remote.node_id, &remote_node_keys)) { sl_log_debug(LOG_TAG, - "Granted keys are unknown for NodeID %d, Rejecting " - "commands at all security levels", - connection->remote.node_id); + "Granted keys are unknown for NodeID %d, Rejecting " + "commands at all security levels", + connection->remote.node_id); return false; } @@ -102,9 +102,9 @@ bool zwave_security_validation_is_security_valid_for_control( == zwave_controller_storage_is_node_s2_capable( connection->remote.node_id)) { sl_log_debug(LOG_TAG, - "NodeID %d does not support S2, Accepting " - "commands at all security levels", - connection->remote.node_id); + "NodeID %d does not support S2, Accepting " + "commands at all security levels", + connection->remote.node_id); return true; } @@ -116,9 +116,9 @@ bool zwave_security_validation_is_security_valid_for_control( &remote_node_keys)) { // If granted keys are unknown (e.g. due to discovery, we accept anything) sl_log_debug(LOG_TAG, - "Granted keys are unknown for NodeID %d, Accepting " - "commands at all security levels", - connection->remote.node_id); + "Granted keys are unknown for NodeID %d, Accepting " + "commands at all security levels", + connection->remote.node_id); return true; } if (connection->encapsulation diff --git a/applications/zpc/components/zwave/zwave_security_validation/test/zwave_security_validation_test.c b/applications/zpc/components/zwave/zwave_security_validation/test/zwave_security_validation_test.c index db0f4fff7..4bad0729f 100644 --- a/applications/zpc/components/zwave/zwave_security_validation/test/zwave_security_validation_test.c +++ b/applications/zpc/components/zwave/zwave_security_validation/test/zwave_security_validation_test.c @@ -141,7 +141,6 @@ void test_zwave_security_validation_is_security_valid_for_support() TEST_ASSERT_FALSE( zwave_security_validation_is_security_valid_for_support(minimal_scheme, &connection)); - } void test_zwave_security_validation_is_security_valid_for_control() @@ -212,7 +211,6 @@ void test_zwave_security_validation_is_security_valid_for_control() &dummy_keyset); TEST_ASSERT_TRUE( zwave_security_validation_is_security_valid_for_control(&connection)); - } void test_zwave_security_validation_is_s2_nif_downgrade_attack_detected() diff --git a/applications/zpc/components/zwave/zwave_transports/crc16/include/zwave_crc16_transport.h b/applications/zpc/components/zwave/zwave_transports/crc16/include/zwave_crc16_transport.h index f714d4b05..7f7f0adb5 100644 --- a/applications/zpc/components/zwave/zwave_transports/crc16/include/zwave_crc16_transport.h +++ b/applications/zpc/components/zwave/zwave_transports/crc16/include/zwave_crc16_transport.h @@ -28,7 +28,8 @@ // We allow to encapsulate the maximum minus our encapsulation command overhead #define CRC_16_ENCAPSULATION_HEADER 2 #define CRC_16_ENCAPSULATION_FOOTER 2 -#define CRC_16_ENCAPSULATION_OVERHEAD (CRC_16_ENCAPSULATION_HEADER + CRC_16_ENCAPSULATION_FOOTER) +#define CRC_16_ENCAPSULATION_OVERHEAD \ + (CRC_16_ENCAPSULATION_HEADER + CRC_16_ENCAPSULATION_FOOTER) #define CRC_16_ENCAPSULATED_COMMAND_MAXIMUM_SIZE \ (ZWAVE_MAX_FRAME_SIZE - CRC_16_ENCAPSULATION_OVERHEAD) @@ -38,7 +39,7 @@ typedef struct zwave_crc16_encapsulation_frame { uint8_t command; /* The command */ uint8_t encapsulated_command [CRC_16_ENCAPSULATED_COMMAND_MAXIMUM_SIZE]; /* The checksum will be appended to the command*/ -/* Encapsulated command */ + /* Encapsulated command */ } zwave_crc16_encapsulation_frame_t; #ifdef __cplusplus diff --git a/applications/zpc/components/zwave/zwave_transports/crc16/src/zwave_crc16_transport.c b/applications/zpc/components/zwave/zwave_transports/crc16/src/zwave_crc16_transport.c index f5ba14e53..870c5223d 100644 --- a/applications/zpc/components/zwave/zwave_transports/crc16/src/zwave_crc16_transport.c +++ b/applications/zpc/components/zwave/zwave_transports/crc16/src/zwave_crc16_transport.c @@ -214,7 +214,7 @@ static sl_status_t zwave_command_class_crc16_send_data( // New frame will be a child of original frame zwave_tx_options_t multi_channel_tx_options; - + if (tx_options) { multi_channel_tx_options = *tx_options; } diff --git a/applications/zpc/components/zwave/zwave_transports/crc16/test/zwave_crc16_transport_test.c b/applications/zpc/components/zwave/zwave_transports/crc16/test/zwave_crc16_transport_test.c index df17007ff..54a2da3e6 100644 --- a/applications/zpc/components/zwave/zwave_transports/crc16/test/zwave_crc16_transport_test.c +++ b/applications/zpc/components/zwave/zwave_transports/crc16/test/zwave_crc16_transport_test.c @@ -253,7 +253,7 @@ void test_encapsulation_happy_case() zwave_controller_connection_info_t connection_info = {}; zwave_tx_options_t tx_options = {}; - tx_options.number_of_responses = 0; + tx_options.number_of_responses = 0; const uint8_t frame_data[] = {0x01, 0x02, 0x03}; connection_info.remote.endpoint_id = 2; connection_info.remote.node_id = 5; @@ -316,7 +316,7 @@ void test_encapsulation_happy_case() TEST_ASSERT_EQUAL(1, send_data_callback_counter); } -// Test if the number of responses is set to 1 we can +// Test if the number of responses is set to 1 we can // still send the frame void test_encapsulation_happy_case_with_number_of_response_1() { @@ -324,7 +324,7 @@ void test_encapsulation_happy_case_with_number_of_response_1() zwave_controller_connection_info_t connection_info = {}; zwave_tx_options_t tx_options = {}; - tx_options.number_of_responses = 1; + tx_options.number_of_responses = 1; const uint8_t frame_data[] = {0x01, 0x02, 0x03}; connection_info.remote.endpoint_id = 2; connection_info.remote.node_id = 5; @@ -383,7 +383,6 @@ void test_encapsulation_happy_case_with_number_of_response_1() TEST_ASSERT_EQUAL(1, send_data_callback_counter); } - void test_encapsulation_overflow() { TEST_ASSERT_NOT_NULL(crc_16_transport.send_data); @@ -453,8 +452,8 @@ void test_encapsulation_response_expected_no_crc16() connection_info.remote.endpoint_id, false); - zwave_tx_options_t tx_options = {}; - tx_options.number_of_responses = 0; + zwave_tx_options_t tx_options = {}; + tx_options.number_of_responses = 0; TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, crc_16_transport.send_data(&connection_info, sizeof(frame_data), diff --git a/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_network.h b/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_network.h index 13fb78728..4f413e49f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_network.h +++ b/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_network.h @@ -70,7 +70,6 @@ void zwave_s0_set_network_callbacks(const s0_on_bootstrapping_complete_cb cb); void zwave_s0_start_bootstrapping(zwave_node_id_t node_id, uint8_t is_controller); - /** * @brief Stop the S2 bootstrapping * diff --git a/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_sm.h b/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_sm.h index a7468af90..a96c821c9 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_sm.h +++ b/applications/zpc/components/zwave/zwave_transports/s0/include/zwave_s0_sm.h @@ -145,7 +145,7 @@ typedef enum { S0_AWAITING_KEY_VERIFY, S0_HANDLE_NET_KEY_VERIFY, S0_AWAITING_2SCHEME_REPORT -}s0_bootstrap_state_t; +} s0_bootstrap_state_t; /** * @brief Start the S0 add node process. diff --git a/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_network.c b/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_network.c index c54f5dffd..0b7843fb5 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_network.c +++ b/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_network.c @@ -54,13 +54,13 @@ void zwave_s0_set_network_callbacks(const s0_on_bootstrapping_complete_cb cb) s0_set_callback(cb); } - -void zwave_s0_stop_bootstrapping() { +void zwave_s0_stop_bootstrapping() +{ s0_bootstrapping_stop(); } - -void zwave_s0_start_learn_mode(zwave_node_id_t our_nodeid) { +void zwave_s0_start_learn_mode(zwave_node_id_t our_nodeid) +{ (void)(our_nodeid); - sl_log_warning(LOG_TAG,"S0 learn mode bootstrapping is not implemented "); + sl_log_warning(LOG_TAG, "S0 learn mode bootstrapping is not implemented "); } diff --git a/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_sm.c b/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_sm.c index e05339ccb..e0010043c 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_sm.c +++ b/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_sm.c @@ -28,7 +28,6 @@ #include "s2_classcmd.h" #include "zwave_helper_macros.h" - #define LOG_TAG "zwave_s0_sm" #define S0_INCLUSION_TIMER 10 * CLOCK_SECOND #define ELEM_COUNT(ARRAY) (sizeof(ARRAY) / (sizeof(ARRAY[0]))) @@ -492,6 +491,7 @@ s0_bootstrap_state_t get_s0_sm_state() return s0_sm.bootstrap_state; } -void s0_bootstrapping_stop() { +void s0_bootstrapping_stop() +{ reset_s0_sm(); } \ No newline at end of file diff --git a/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_transport.c b/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_transport.c index f419e02f8..d7ea25b58 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_transport.c +++ b/applications/zpc/components/zwave/zwave_transports/s0/src/zwave_s0_transport.c @@ -1014,7 +1014,8 @@ static uint8_t uint8_t frame_length; // Allocate a buffer that's large enough for the largest frame size that's valid // Maximum valid size is MAX_ENCRYPTED_MSG_SIZE + 20 bytes overhead + auth header size - uint8_t auth_buff[MAX_ENCRYPTED_MSG_SIZE + S0_ENCAP_HEADER_LEN + sizeof(auth_data_t)]; + uint8_t auth_buff[MAX_ENCRYPTED_MSG_SIZE + S0_ENCAP_HEADER_LEN + + sizeof(auth_data_t)]; frame_length = encrypted_frame_len & 0xff; //FIXME as GW S0 code can handle // only uint8_t len @@ -1076,7 +1077,9 @@ static uint8_t // When we get a session that's in progress, verify the size of the data we have and the data we're about // to add do not go over our total output buffer size. If it does, drop the frame and the session pool will free up the // invalid session in a little bit. - if(s->state != RX_INIT && (s->msg_len + frame_length - S0_ENCAP_HEADER_LEN) > decrypted_frame_len) { + if (s->state != RX_INIT + && (s->msg_len + frame_length - S0_ENCAP_HEADER_LEN) + > decrypted_frame_len) { sl_log_error(LOG_TAG, "Combined data for encrypted message is too long\n"); return 0; } @@ -1133,14 +1136,18 @@ static uint8_t s->state = RX_ENC2; } memcpy(decrypted_frame, s->msg, s->msg_len); - memcpy(decrypted_frame + s->msg_len, enc_payload + 1, frame_length - S0_ENCAP_HEADER_LEN); + memcpy(decrypted_frame + s->msg_len, + enc_payload + 1, + frame_length - S0_ENCAP_HEADER_LEN); free_rx_session(s); return (s->msg_len + frame_length - S0_ENCAP_HEADER_LEN); } } else { /* Single frame message */ - memcpy(decrypted_frame, enc_payload + 1, frame_length - S0_ENCAP_HEADER_LEN); + memcpy(decrypted_frame, + enc_payload + 1, + frame_length - S0_ENCAP_HEADER_LEN); free_rx_session(s); return (frame_length - S0_ENCAP_HEADER_LEN); } diff --git a/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_sm_test.c b/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_sm_test.c index d003fcb89..9844ee8e0 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_sm_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_sm_test.c @@ -204,7 +204,6 @@ void test_zwave_s0_sm_controller_with_wrong_scheme_report() TEST_ASSERT_EQUAL(S0_INC_IDLE, get_s0_sm_state()); } - void test_zwave_s0_sm_abort() { zwave_network_management_get_node_id_IgnoreAndReturn(1); diff --git a/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_transport_test.c b/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_transport_test.c index d1f6e251d..76fbda363 100644 --- a/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_transport_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s0/test/zwave_s0_transport_test.c @@ -327,14 +327,14 @@ void expect_to_ignore_nonce_report() void test_only_second_frame_in_combined() { - uint8_t msg2[] + uint8_t msg2[] = {0x98, 0x81, 0xFC, 0x98, 0x5F, 0x87, 0xBA, 0xF0, 0x9B, 0x92, 0x0f, 0x8B, 0xB5, 0xDF, 0x30, 0x3F, 0xA4, 0xBE, 0x90, 0xED, 0xF6, 0x2F, 0x69, 0x36, 0x05, 0x76, 0x2A, 0xF6, 0x2F, 0x70, 0xDA, 0xF5, 0x69, 0x36, 0x05, 0x76, 0x2A, 0xF6, 0x2F, 0x70, 0xDA, 0xF5, 0x69, 0x36, 0x05, 0x76, 0x2A, 0xA1, 0x21, 0x8B, 0x2D, 0x59, 0x3E, 0x4B, 0x18, 0x50, 0xC2, 0x84, 0xBF, 0x39, 0xEF, 0xBC, 0xD4, 0x7F, 0x2E, 0x16, - 0xE9, 0xA1, 0x1A, 0x02, 0xc4, 0xb7, 0x58, 0x40, 0xa3, 0x69, 0x86}; + 0xE9, 0xA1, 0x1A, 0x02, 0xc4, 0xb7, 0x58, 0x40, 0xa3, 0x69, 0x86}; ctr_drbg_run = 0; /* S0 key used * Please Refer UIC-674 JIRA attachment uic-674.zlf */ @@ -439,7 +439,6 @@ void test_combined_good_frame() zwave_controller_on_frame_received_IgnoreArg_rx_options(); zwave_controller_on_frame_received_IgnoreArg_connection_info(); - connection_info.encapsulation = ZWAVE_CONTROLLER_ENCAPSULATION_SECURITY_0; TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_s0_on_frame_received(&connection_info, diff --git a/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_fixt.h b/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_fixt.h index a0f83aa46..774009a51 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_fixt.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_fixt.h @@ -44,4 +44,3 @@ sl_status_t zwave_s2_fixt_setup(void); #endif //ZWAVE_S2_FIXT_H /** @} end zwave_s2_fixt */ - diff --git a/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_network.h b/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_network.h index 346cc7025..e03a65074 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_network.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/include/zwave_s2_network.h @@ -32,7 +32,6 @@ extern "C" { #endif #include "zwave_network_management.h" - typedef struct zwave_s2_network_callbacks { /// This event is triggered when the S2 inclusion process has started /// This can be use to stop e.g.,the S0 inclusion FSM. diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes-cmac/aes_cmac.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes-cmac/aes_cmac.c index fc2a8f086..7858469e6 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes-cmac/aes_cmac.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes-cmac/aes_cmac.c @@ -44,22 +44,20 @@ #include "aes.h" #include "aes_cmac.h" -static void xor_128(const uint8_t * a, const uint8_t * b, uint8_t * out) +static void xor_128(const uint8_t *a, const uint8_t *b, uint8_t *out) { uint8_t count; - for (count = 0; count < 16; count++) - { + for (count = 0; count < 16; count++) { out[count] = a[count] ^ b[count]; } } -static void leftshift_onebit(const uint8_t * input, uint8_t * output) +static void leftshift_onebit(const uint8_t *input, uint8_t *output) { int8_t count; uint8_t overflow = 0; - for (count = 15; count >= 0; count--) - { + for (count = 15; count >= 0; count--) { output[count] = input[count] << 1; output[count] |= overflow; overflow = (input[count] & 0x80) ? 1 : 0; @@ -72,76 +70,90 @@ static void leftshift_onebit(const uint8_t * input, uint8_t * output) * @param K1 128-bit first sub key. * @param K2 128-bit second sub key. */ -static void generate_subkey(const uint8_t * key, uint8_t * K1, uint8_t * K2) +static void generate_subkey(const uint8_t *key, uint8_t *K1, uint8_t *K2) { uint8_t L[16]; uint8_t tmp[16]; - const uint8_t const_Zero[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - const uint8_t const_Rb[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 - }; + const uint8_t const_Zero[16] = {0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; + + const uint8_t const_Rb[16] = {0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x87}; /* * L := AES-128(Key, const_Zero); */ AES128_ECB_encrypt((uint8_t *)const_Zero, key, L); - if (0 == (L[0] & 0x80)) // if MSB(L) is equal to 0 then K1 := L << 1; + if (0 == (L[0] & 0x80)) // if MSB(L) is equal to 0 then K1 := L << 1; { leftshift_onebit(L, K1); - } - else - { // else K1 := (L << 1) XOR const_Rb; + } else { // else K1 := (L << 1) XOR const_Rb; leftshift_onebit(L, tmp); - xor_128(tmp,const_Rb, K1); + xor_128(tmp, const_Rb, K1); } - if (0 == (K1[0] & 0x80)) // if MSB(K1) is equal to 0 then K2 := K1 << 1; + if (0 == (K1[0] & 0x80)) // if MSB(K1) is equal to 0 then K2 := K1 << 1; { leftshift_onebit(K1, K2); - } - else // else K2 := (K1 << 1) XOR const_Rb; + } else // else K2 := (K1 << 1) XOR const_Rb; { leftshift_onebit(K1, tmp); - xor_128(tmp,const_Rb, K2); + xor_128(tmp, const_Rb, K2); } } //void padding(unsigned char *lastb, unsigned char *pad, int length) -static void padding(const uint8_t * lastb, uint8_t * pad, const uint8_t length) +static void padding(const uint8_t *lastb, uint8_t *pad, const uint8_t length) { int j; /* original last block */ - for (j = 0; j < 16; j++) - { - if (j < length) - { + for (j = 0; j < 16; j++) { + if (j < length) { pad[j] = lastb[j]; - } - else if (j == length) - { + } else if (j == length) { pad[j] = 0x80; - } - else - { + } else { pad[j] = 0x00; } } } //void AES_CMAC ( unsigned char *key, unsigned char *input, int length, unsigned char *mac ) -void aes_cmac_calculate( - const uint8_t * key, - const uint8_t * message, - const uint16_t message_length, - uint8_t * mac) +void aes_cmac_calculate(const uint8_t *key, + const uint8_t *message, + const uint16_t message_length, + uint8_t *mac) { uint8_t X[16]; uint8_t Y[16]; @@ -150,26 +162,21 @@ void aes_cmac_calculate( uint8_t K1[16]; uint8_t K2[16]; uint8_t flag; - uint8_t n; //int n; - uint8_t i; //int i; + uint8_t n; //int n; + uint8_t i; //int i; generate_subkey(key, K1, K2); - n = (message_length + 15) / 16; // n is number of rounds + n = (message_length + 15) / 16; // n is number of rounds - if (0 == n) - { - n = 1; + if (0 == n) { + n = 1; flag = 0; - } - else - { - if (0 == (message_length % 16)) /* last block is a complete block */ + } else { + if (0 == (message_length % 16)) /* last block is a complete block */ { flag = 1; - } - else - { /* last block is not complete block */ + } else { /* last block is not complete block */ flag = 0; } } @@ -177,48 +184,40 @@ void aes_cmac_calculate( if (flag) /* last block is complete block */ { xor_128(&message[16 * (n - 1)], K1, M_last); - } - else - { + } else { padding(&message[16 * (n - 1)], padded, message_length % 16); xor_128(padded, K2, M_last); } - for (i = 0; i < 16; i++) - { + for (i = 0; i < 16; i++) { X[i] = 0; } - for (i = 0; i < (n-1); i++) - { + for (i = 0; i < (n - 1); i++) { xor_128(X, &message[16 * i], Y); /* Y := Mi (+) X */ - AES128_ECB_encrypt(Y, key, X); // X := AES-128(key, Y); + AES128_ECB_encrypt(Y, key, X); // X := AES-128(key, Y); } xor_128(X, M_last, Y); - AES128_ECB_encrypt(Y, key, X); // X := AES-128(key, Y); + AES128_ECB_encrypt(Y, key, X); // X := AES-128(key, Y); - for (i = 0; i < 16; i++) - { + for (i = 0; i < 16; i++) { mac[i] = X[i]; } } -CMAC_VERIFY_T aes_cmac_verify( - const uint8_t * key, - const uint8_t * message, - const uint16_t message_length, - const uint8_t * mac) +CMAC_VERIFY_T aes_cmac_verify(const uint8_t *key, + const uint8_t *message, + const uint16_t message_length, + const uint8_t *mac) { uint8_t calculated_mac[16]; uint8_t count; aes_cmac_calculate(key, message, message_length, calculated_mac); - for (count = 0; count < 16; count++) - { - if (mac[count] != calculated_mac[count]) - { + for (count = 0; count < 16; count++) { + if (mac[count] != calculated_mac[count]) { return CMAC_INVALID; } } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes/aes.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes/aes.c index 7bc3384ad..7c34c1c6a 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes/aes.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/aes/aes.c @@ -32,15 +32,13 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) */ - /*****************************************************************************/ /* Includes: */ /*****************************************************************************/ #include -#include // CBC mode, for memset +#include // CBC mode, for memset #include "aes.h" - /*****************************************************************************/ /* Defines: */ /*****************************************************************************/ @@ -53,94 +51,103 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) // The number of rounds in AES Cipher. #define Nr 10 -// jcallan@github points out that declaring Multiply as a function +// jcallan@github points out that declaring Multiply as a function // reduces code size considerably with the Keil ARM compiler. // See this link for more information: https://github.com/kokke/tiny-AES128-C/pull/3 #ifndef MULTIPLY_AS_A_FUNCTION - #define MULTIPLY_AS_A_FUNCTION 0 +#define MULTIPLY_AS_A_FUNCTION 0 #endif - /*****************************************************************************/ /* Private variables: */ /*****************************************************************************/ // state - array holding the intermediate results during decryption. typedef uint8_t state_t[4][4]; -static state_t* state; +static state_t *state; // The array that stores the round keys. static uint8_t RoundKey[176]; // The Key input to the AES Program -static const uint8_t* Key; +static const uint8_t *Key; #if defined(CBC) && CBC - // Initial Vector used only for CBC mode - static uint8_t* Iv; +// Initial Vector used only for CBC mode +static uint8_t *Iv; #endif // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM -// The numbers below can be computed dynamically trading ROM for RAM - +// The numbers below can be computed dynamically trading ROM for RAM - // This can be useful in (embedded) bootloader applications, where ROM is often limited. -static const uint8_t sbox[256] = { +static const uint8_t sbox[256] = { //0 1 2 3 4 5 6 7 8 9 A B C D E F - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; - -static const uint8_t rsbox[256] = -{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; - - -// The round constant word array, Rcon[i], contains the values given by + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, + 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, + 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, + 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, + 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, + 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, + 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, + 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, + 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, + 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, + 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, + 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, + 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, + 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, + 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, + 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, + 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +static const uint8_t rsbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, + 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, + 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, + 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, + 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, + 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, + 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, + 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, + 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, + 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, + 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, + 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, + 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, + 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, + 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, + 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, + 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; + +// The round constant word array, Rcon[i], contains the values given by // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) // Note that i starts at 1, not 0). static const uint8_t Rcon[255] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, - 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, - 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, - 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, - 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, - 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, - 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, - 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, - 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, - 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, - 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, - 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, - 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, - 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb }; - + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, + 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, + 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, + 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, + 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, + 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, + 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, + 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, + 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, + 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, + 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, + 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb}; /*****************************************************************************/ /* Private functions: */ @@ -155,15 +162,14 @@ static uint8_t getSBoxInvert(uint8_t num) return rsbox[num]; } -// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. +// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. static void KeyExpansion(void) { uint32_t i, j, k; - uint8_t tempa[4]; // Used for the column/row operations - + uint8_t tempa[4]; // Used for the column/row operations + // The first round key is the key itself. - for(i = 0; i < Nk; ++i) - { + for (i = 0; i < Nk; ++i) { RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; @@ -171,27 +177,24 @@ static void KeyExpansion(void) } // All other round keys are found from the previous round keys. - for(; (i < (Nb * (Nr + 1))); ++i) - { - for(j = 0; j < 4; ++j) - { - tempa[j]=RoundKey[(i-1) * 4 + j]; + for (; (i < (Nb * (Nr + 1))); ++i) { + for (j = 0; j < 4; ++j) { + tempa[j] = RoundKey[(i - 1) * 4 + j]; } - if (i % Nk == 0) - { + if (i % Nk == 0) { // This function rotates the 4 bytes in a word to the left once. // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] // Function RotWord() { - k = tempa[0]; + k = tempa[0]; tempa[0] = tempa[1]; tempa[1] = tempa[2]; tempa[2] = tempa[3]; tempa[3] = k; } - // SubWord() is a function that takes a four-byte input word and + // SubWord() is a function that takes a four-byte input word and // applies the S-box to each of the four bytes to produce an output word. // Function Subword() @@ -202,11 +205,10 @@ static void KeyExpansion(void) tempa[3] = getSBoxValue(tempa[3]); } - tempa[0] = tempa[0] ^ Rcon[i/Nk]; + tempa[0] = tempa[0] ^ Rcon[i / Nk]; } #if Nk > 6 - else if (Nk > 6 && i % Nk == 4) - { + else if (Nk > 6 && i % Nk == 4) { // Function Subword() { tempa[0] = getSBoxValue(tempa[0]); @@ -227,11 +229,9 @@ static void KeyExpansion(void) // The round key is added to the state by an XOR function. static void AddRoundKey(uint8_t round) { - uint8_t i,j; - for(i=0;i<4;++i) - { - for(j = 0; j < 4; ++j) - { + uint8_t i, j; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { (*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j]; } } @@ -242,10 +242,8 @@ static void AddRoundKey(uint8_t round) static void SubBytes(void) { uint8_t i, j; - for(i = 0; i < 4; ++i) - { - for(j = 0; j < 4; ++j) - { + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { (*state)[j][i] = getSBoxValue((*state)[j][i]); } } @@ -258,24 +256,24 @@ static void ShiftRows(void) { uint8_t temp; - // Rotate first row 1 columns to left + // Rotate first row 1 columns to left temp = (*state)[0][1]; (*state)[0][1] = (*state)[1][1]; (*state)[1][1] = (*state)[2][1]; (*state)[2][1] = (*state)[3][1]; (*state)[3][1] = temp; - // Rotate second row 2 columns to left + // Rotate second row 2 columns to left temp = (*state)[0][2]; (*state)[0][2] = (*state)[2][2]; (*state)[2][2] = temp; - temp = (*state)[1][2]; + temp = (*state)[1][2]; (*state)[1][2] = (*state)[3][2]; (*state)[3][2] = temp; // Rotate third row 3 columns to left - temp = (*state)[0][3]; + temp = (*state)[0][3]; (*state)[0][3] = (*state)[3][3]; (*state)[3][3] = (*state)[2][3]; (*state)[2][3] = (*state)[1][3]; @@ -284,22 +282,29 @@ static void ShiftRows(void) static uint8_t xtime(uint8_t x) { - return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); + return ((x << 1) ^ (((x >> 7) & 1) * 0x1b)); } // MixColumns function mixes the columns of the state matrix static void MixColumns(void) { uint8_t i; - uint8_t Tmp,Tm,t; - for(i = 0; i < 4; ++i) - { + uint8_t Tmp, Tm, t; + for (i = 0; i < 4; ++i) { t = (*state)[i][0]; - Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; - Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; - Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; - Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; - Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; + Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3]; + Tm = (*state)[i][0] ^ (*state)[i][1]; + Tm = xtime(Tm); + (*state)[i][0] ^= Tm ^ Tmp; + Tm = (*state)[i][1] ^ (*state)[i][2]; + Tm = xtime(Tm); + (*state)[i][1] ^= Tm ^ Tmp; + Tm = (*state)[i][2] ^ (*state)[i][3]; + Tm = xtime(Tm); + (*state)[i][2] ^= Tm ^ Tmp; + Tm = (*state)[i][3] ^ t; + Tm = xtime(Tm); + (*state)[i][3] ^= Tm ^ Tmp; } } @@ -307,19 +312,17 @@ static void MixColumns(void) #if MULTIPLY_AS_A_FUNCTION static uint8_t Multiply(uint8_t x, uint8_t y) { - return (((y & 1) * x) ^ - ((y>>1 & 1) * xtime(x)) ^ - ((y>>2 & 1) * xtime(xtime(x))) ^ - ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ - ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); - } + return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) + ^ ((y >> 2 & 1) * xtime(xtime(x))) + ^ ((y >> 3 & 1) * xtime(xtime(xtime(x)))) + ^ ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x)))))); +} #else -#define Multiply(x, y) \ - ( ((y & 1) * x) ^ \ - ((y>>1 & 1) * xtime(x)) ^ \ - ((y>>2 & 1) * xtime(xtime(x))) ^ \ - ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ - ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ +#define Multiply(x, y) \ + (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) \ + ^ ((y >> 2 & 1) * xtime(xtime(x))) \ + ^ ((y >> 3 & 1) * xtime(xtime(xtime(x)))) \ + ^ ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x)))))) #endif @@ -329,31 +332,31 @@ static uint8_t Multiply(uint8_t x, uint8_t y) static void InvMixColumns(void) { int i; - uint8_t a,b,c,d; - for(i=0;i<4;++i) - { + uint8_t a, b, c, d; + for (i = 0; i < 4; ++i) { a = (*state)[i][0]; b = (*state)[i][1]; c = (*state)[i][2]; d = (*state)[i][3]; - (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); - (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); - (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); - (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) + ^ Multiply(d, 0x09); + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) + ^ Multiply(d, 0x0d); + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) + ^ Multiply(d, 0x0b); + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) + ^ Multiply(d, 0x0e); } } - // The SubBytes Function Substitutes the values in the // state matrix with values in an S-box. static void InvSubBytes(void) { - uint8_t i,j; - for(i=0;i<4;++i) - { - for(j=0;j<4;++j) - { + uint8_t i, j; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { (*state)[j][i] = getSBoxInvert((*state)[j][i]); } } @@ -363,50 +366,48 @@ static void InvShiftRows(void) { uint8_t temp; - // Rotate first row 1 columns to right - temp=(*state)[3][1]; - (*state)[3][1]=(*state)[2][1]; - (*state)[2][1]=(*state)[1][1]; - (*state)[1][1]=(*state)[0][1]; - (*state)[0][1]=temp; + // Rotate first row 1 columns to right + temp = (*state)[3][1]; + (*state)[3][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[0][1]; + (*state)[0][1] = temp; - // Rotate second row 2 columns to right - temp=(*state)[0][2]; - (*state)[0][2]=(*state)[2][2]; - (*state)[2][2]=temp; + // Rotate second row 2 columns to right + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; - temp=(*state)[1][2]; - (*state)[1][2]=(*state)[3][2]; - (*state)[3][2]=temp; + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; // Rotate third row 3 columns to right - temp=(*state)[0][3]; - (*state)[0][3]=(*state)[1][3]; - (*state)[1][3]=(*state)[2][3]; - (*state)[2][3]=(*state)[3][3]; - (*state)[3][3]=temp; + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[1][3]; + (*state)[1][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[3][3]; + (*state)[3][3] = temp; } - // Cipher is the main function that encrypts the PlainText. static void Cipher(void) { uint8_t round = 0; // Add the First round key to the state before starting the rounds. - AddRoundKey(0); - + AddRoundKey(0); + // There will be Nr rounds. // The first Nr-1 rounds are identical. // These Nr-1 rounds are executed in the loop below. - for(round = 1; round < Nr; ++round) - { + for (round = 1; round < Nr; ++round) { SubBytes(); ShiftRows(); MixColumns(); AddRoundKey(round); } - + // The last round is given below. // The MixColumns function is not here in the last round. SubBytes(); @@ -416,22 +417,21 @@ static void Cipher(void) static void InvCipher(void) { - uint8_t round=0; + uint8_t round = 0; // Add the First round key to the state before starting the rounds. - AddRoundKey(Nr); + AddRoundKey(Nr); // There will be Nr rounds. // The first Nr-1 rounds are identical. // These Nr-1 rounds are executed in the loop below. - for(round=Nr-1;round>0;round--) - { + for (round = Nr - 1; round > 0; round--) { InvShiftRows(); InvSubBytes(); AddRoundKey(round); InvMixColumns(); } - + // The last round is given below. // The MixColumns function is not here in the last round. InvShiftRows(); @@ -439,28 +439,24 @@ static void InvCipher(void) AddRoundKey(0); } -static void BlockCopy(uint8_t* output, uint8_t* input) +static void BlockCopy(uint8_t *output, uint8_t *input) { uint8_t i; - for (i=0;i> 8; - bitmask = bitmask >> 8; - /* Fill last byte with remaining 8 LSBs of text_to_encrypt_len. + Q[i] = (text_to_encrypt_len & bitmask) >> 8; + bitmask = bitmask >> 8; + /* Fill last byte with remaining 8 LSBs of text_to_encrypt_len. for e.g. text_to_encrypt_len is 512 (00000010 00000000) then Q[i+1] is 00000000 */ - Q[i+1] = (text_to_encrypt_len & bitmask); + Q[i + 1] = (text_to_encrypt_len & bitmask); } /* See section A.2.1 in the document mentioned in header */ -static int format_b0(const uint8_t t, const uint16_t text_to_encrypt_len, - uint8_t *first_block, const uint8_t *nonce) +static int format_b0(const uint8_t t, + const uint16_t text_to_encrypt_len, + uint8_t *first_block, + const uint8_t *nonce) { uint8_t i; // The value 8 is the maximum value of q according to the NIST document. uint8_t Q[8]; + first_block[0] = 0; - first_block[0] = 0; + /* do not set resreved bit */ - /* do not set resreved bit */ + first_block[0] = first_block[0] | B0_AAD; /* set Adata bit. See A.2.1 */ + first_block[0] = first_block[0] | ((((t - 2) / 2) & 0x7) << 3); + first_block[0] = first_block[0] | ((q - 1) & 0x7); - first_block[0] = first_block[0] | B0_AAD; /* set Adata bit. See A.2.1 */ - first_block[0] = first_block[0] | ((((t - 2) / 2) & 0x7) << 3); - first_block[0] = first_block[0] | ((q - 1) & 0x7); + /* Copy the nonce from 1st byte (not 0th). See Table 2 in A.2.1 */ + for (i = 1; i < n + 1; i++) { + first_block[i] = nonce[i - 1]; + } - /* Copy the nonce from 1st byte (not 0th). See Table 2 in A.2.1 */ - for (i = 1; i < n + 1 ; i++) { - first_block[i] = nonce[i-1]; - } - - convert_to_octet_string(text_to_encrypt_len, Q, q); - - /* Copy the Q after nonce. See Table 2 in A.2.1 */ - memcpy(&first_block[i], Q, q); - return 1; + convert_to_octet_string(text_to_encrypt_len, Q, q); + /* Copy the Q after nonce. See Table 2 in A.2.1 */ + memcpy(&first_block[i], Q, q); + return 1; } static void ciph_block(uint8_t *blocks, const uint8_t *key) { - AES128_ECB_encrypt(blocks, key, blocks); + AES128_ECB_encrypt(blocks, key, blocks); } // TODO, may be reworked to avoid build errors @@ -104,234 +105,270 @@ static void ciph_block(uint8_t *blocks, const uint8_t *key) #endif static void bit_xor(const uint8_t *block, uint8_t *next_block, int size) { - int i; - for (i = 0; i < size; i++) - next_block[i] = block[i] ^ next_block[i]; + int i; + for (i = 0; i < size; i++) + next_block[i] = block[i] ^ next_block[i]; } #if defined(__GNUC__) && (__GNUC__ == 12) #pragma GCC diagnostic pop #endif /*See section A.2.2 in NIST pdf */ -static int format_aad(uint8_t blocks[2][BLOCK_SIZE], const uint8_t *aad, const uint32_t aad_len, const uint8_t *key) +static int format_aad(uint8_t blocks[2][BLOCK_SIZE], + const uint8_t *aad, + const uint32_t aad_len, + const uint8_t *key) { - int i; - int offset; - int new_aad_len; - int no_of_blocks_for_aad; - int aad_bytes_in_first_block; - int aad_start = 2; - - /* See more about this lenghth ranges in beginning of page 14 in the document mentioned in header */ - if (aad_len < 65280) { - blocks[1][0] = 0x0; - blocks[1][1] = aad_len; - aad_bytes_in_first_block = 14; - }else if (aad_len <= 0xffffffff) { /*TODO Check the limits */ - blocks[1][0] = 0xff; - blocks[1][1] = 0xfe; - blocks[1][2] = 0; - blocks[1][3] = 1; - blocks[1][4] = 0; - blocks[1][5] = 0; - aad_bytes_in_first_block = 10; - aad_start = 6; - } else { - return 0; - } - - memcpy(&blocks[1][aad_start], &aad[0], MIN(aad_len, aad_bytes_in_first_block));/* Fill the first block's 14 octets with first 14 octets of aad*/ - /* Copy first 14 octets of AAD to blocks[1] */ - if (aad_len < aad_bytes_in_first_block) { /* need to pad with zeroes if aad_len is less than 14*/ - memset(&blocks[1][aad_start] + aad_len, 0, aad_bytes_in_first_block - aad_len); - bit_xor(blocks[1], blocks[0], BLOCK_SIZE); - ciph_block(blocks[0], key); - } else if (aad_len > aad_bytes_in_first_block) { /* If aad_len is more than 14 we need more blocks */ - bit_xor(blocks[1], blocks[0], BLOCK_SIZE); - ciph_block(blocks[0], key); - new_aad_len = aad_len - aad_bytes_in_first_block ; - no_of_blocks_for_aad = new_aad_len / BLOCK_SIZE; /* Find the number of more blocks needed */ - if (new_aad_len % BLOCK_SIZE) - no_of_blocks_for_aad++; - - offset = aad_bytes_in_first_block; /* Start copying the octets from aad_bytes_in_first_block'th offset*/ - for (i = 0; i < no_of_blocks_for_aad; i++) { - - /* if its the last block and not aligned to BLOCK_SIZE bytes */ - if ((i == (no_of_blocks_for_aad - 1)) && (new_aad_len % BLOCK_SIZE)) { - memcpy(&blocks[1][0], &aad[offset], (new_aad_len % BLOCK_SIZE)); - /* pad with zeroes */ - memset(&blocks[1][0] + (new_aad_len % BLOCK_SIZE), 0, BLOCK_SIZE - (new_aad_len % BLOCK_SIZE)); - bit_xor(blocks[1], blocks[0], BLOCK_SIZE); - ciph_block(blocks[0], key); - break; - } - - memcpy(&blocks[1][0], &aad[offset], BLOCK_SIZE); - bit_xor(blocks[1], blocks[0], BLOCK_SIZE); - ciph_block(blocks[0], key); - offset += BLOCK_SIZE; - } - } else { + int i; + int offset; + int new_aad_len; + int no_of_blocks_for_aad; + int aad_bytes_in_first_block; + int aad_start = 2; + + /* See more about this lenghth ranges in beginning of page 14 in the document mentioned in header */ + if (aad_len < 65280) { + blocks[1][0] = 0x0; + blocks[1][1] = aad_len; + aad_bytes_in_first_block = 14; + } else if (aad_len <= 0xffffffff) { /*TODO Check the limits */ + blocks[1][0] = 0xff; + blocks[1][1] = 0xfe; + blocks[1][2] = 0; + blocks[1][3] = 1; + blocks[1][4] = 0; + blocks[1][5] = 0; + aad_bytes_in_first_block = 10; + aad_start = 6; + } else { + return 0; + } + + memcpy( + &blocks[1][aad_start], + &aad[0], + MIN( + aad_len, + aad_bytes_in_first_block)); /* Fill the first block's 14 octets with first 14 octets of aad*/ + /* Copy first 14 octets of AAD to blocks[1] */ + if ( + aad_len + < aad_bytes_in_first_block) { /* need to pad with zeroes if aad_len is less than 14*/ + memset(&blocks[1][aad_start] + aad_len, + 0, + aad_bytes_in_first_block - aad_len); + bit_xor(blocks[1], blocks[0], BLOCK_SIZE); + ciph_block(blocks[0], key); + } else if ( + aad_len + > aad_bytes_in_first_block) { /* If aad_len is more than 14 we need more blocks */ + bit_xor(blocks[1], blocks[0], BLOCK_SIZE); + ciph_block(blocks[0], key); + new_aad_len = aad_len - aad_bytes_in_first_block; + no_of_blocks_for_aad + = new_aad_len / BLOCK_SIZE; /* Find the number of more blocks needed */ + if (new_aad_len % BLOCK_SIZE) + no_of_blocks_for_aad++; + + offset + = aad_bytes_in_first_block; /* Start copying the octets from aad_bytes_in_first_block'th offset*/ + for (i = 0; i < no_of_blocks_for_aad; i++) { + /* if its the last block and not aligned to BLOCK_SIZE bytes */ + if ((i == (no_of_blocks_for_aad - 1)) && (new_aad_len % BLOCK_SIZE)) { + memcpy(&blocks[1][0], &aad[offset], (new_aad_len % BLOCK_SIZE)); + /* pad with zeroes */ + memset(&blocks[1][0] + (new_aad_len % BLOCK_SIZE), + 0, + BLOCK_SIZE - (new_aad_len % BLOCK_SIZE)); bit_xor(blocks[1], blocks[0], BLOCK_SIZE); ciph_block(blocks[0], key); + break; + } + + memcpy(&blocks[1][0], &aad[offset], BLOCK_SIZE); + bit_xor(blocks[1], blocks[0], BLOCK_SIZE); + ciph_block(blocks[0], key); + offset += BLOCK_SIZE; } - return 1; + } else { + bit_xor(blocks[1], blocks[0], BLOCK_SIZE); + ciph_block(blocks[0], key); + } + return 1; } -static void format_payload_block(uint8_t blocks[2][BLOCK_SIZE], const uint8_t *P, +static void format_payload_block(uint8_t blocks[2][BLOCK_SIZE], + const uint8_t *P, const uint16_t text_to_encrypt_len, const uint8_t *key) { - int i; - int no_blocks_payload = (text_to_encrypt_len / BLOCK_SIZE); - //int bytes_to_pad; - int offset = 0; - - if (text_to_encrypt_len % BLOCK_SIZE) - no_blocks_payload++; - - for (i = 0; i < no_blocks_payload; i++) { - if ((i == (no_blocks_payload - 1)) && (text_to_encrypt_len % BLOCK_SIZE)) { /* If its a last block and not aligned to BLOCK_SIZE */ - memcpy(&blocks[1][0], &P[offset], (text_to_encrypt_len % BLOCK_SIZE)); - /* pad with zeroes */ - memset(&blocks[1][0] + (text_to_encrypt_len % BLOCK_SIZE), 0, BLOCK_SIZE - (text_to_encrypt_len % BLOCK_SIZE)); - bit_xor(blocks[1], blocks[0], BLOCK_SIZE); - ciph_block(blocks[0], key); - break; - } - - memcpy(&blocks[1][0], &P[offset], BLOCK_SIZE); - bit_xor(blocks[1], blocks[0], BLOCK_SIZE); - ciph_block(blocks[0], key); - offset += BLOCK_SIZE; + int i; + int no_blocks_payload = (text_to_encrypt_len / BLOCK_SIZE); + //int bytes_to_pad; + int offset = 0; + + if (text_to_encrypt_len % BLOCK_SIZE) + no_blocks_payload++; + + for (i = 0; i < no_blocks_payload; i++) { + if ( + (i == (no_blocks_payload - 1)) + && (text_to_encrypt_len + % BLOCK_SIZE)) { /* If its a last block and not aligned to BLOCK_SIZE */ + memcpy(&blocks[1][0], &P[offset], (text_to_encrypt_len % BLOCK_SIZE)); + /* pad with zeroes */ + memset(&blocks[1][0] + (text_to_encrypt_len % BLOCK_SIZE), + 0, + BLOCK_SIZE - (text_to_encrypt_len % BLOCK_SIZE)); + bit_xor(blocks[1], blocks[0], BLOCK_SIZE); + ciph_block(blocks[0], key); + break; + } - } + memcpy(&blocks[1][0], &P[offset], BLOCK_SIZE); + bit_xor(blocks[1], blocks[0], BLOCK_SIZE); + ciph_block(blocks[0], key); + offset += BLOCK_SIZE; + } } /* FIXME see if one from "block" and "mac" can be used */ -static void encrypt_or_decrypt( - uint8_t *data_array, - uint16_t data_len, - uint16_t num_ctr_blks, - uint8_t *block, - const uint8_t *nonce, - int mac_len, - const uint8_t* key, - uint8_t *mac, - int mode) +static void encrypt_or_decrypt(uint8_t *data_array, + uint16_t data_len, + uint16_t num_ctr_blks, + uint8_t *block, + const uint8_t *nonce, + int mac_len, + const uint8_t *key, + uint8_t *mac, + int mode) { - uint16_t i; - uint8_t ctr[BLOCK_SIZE]; - uint16_t length = data_len; - - for (i = 0; i < num_ctr_blks; i++) { - memset(ctr, 0, BLOCK_SIZE); - ctr[0] = 0; - ctr[0] |= ((q-1) & 0x7); /* Add flag see table 4 in A.3 */ - memcpy(&ctr[1], nonce, n); /* Add N see table 2 in A.3 */ - - /* FIXME:as max payload length is 2 pow(16). Last two octets of counters is sufficient */ - ctr[14] = (i & 0xff00) >> 8; /*Add counter see table 2 in A.3 */ - ctr[15] = i & 0xff; - - ciph_block(ctr, key); - /*TODO there was bit_xor() here. What was it?*/ - if ((i == 0) && (mode == ENCRYPT)) { - bit_xor(ctr, mac, mac_len); - } else if ((i == 0) && (mode == DECRYPT)) { - memcpy(block, ctr, BLOCK_SIZE); /* We need this first block to decrypt MAC */ - } else { - if (length >= BLOCK_SIZE) { - bit_xor(ctr, &data_array[(i - 1) * BLOCK_SIZE], BLOCK_SIZE);/* step 7 in NIST pdf*/ - } else { - bit_xor(ctr, &data_array[(i - 1) * BLOCK_SIZE], length); - } - length = length - BLOCK_SIZE; - } + uint16_t i; + uint8_t ctr[BLOCK_SIZE]; + uint16_t length = data_len; + + for (i = 0; i < num_ctr_blks; i++) { + memset(ctr, 0, BLOCK_SIZE); + ctr[0] = 0; + ctr[0] |= ((q - 1) & 0x7); /* Add flag see table 4 in A.3 */ + memcpy(&ctr[1], nonce, n); /* Add N see table 2 in A.3 */ + + /* FIXME:as max payload length is 2 pow(16). Last two octets of counters is sufficient */ + ctr[14] = (i & 0xff00) >> 8; /*Add counter see table 2 in A.3 */ + ctr[15] = i & 0xff; + + ciph_block(ctr, key); + /*TODO there was bit_xor() here. What was it?*/ + if ((i == 0) && (mode == ENCRYPT)) { + bit_xor(ctr, mac, mac_len); + } else if ((i == 0) && (mode == DECRYPT)) { + memcpy(block, + ctr, + BLOCK_SIZE); /* We need this first block to decrypt MAC */ + } else { + if (length >= BLOCK_SIZE) { + bit_xor(ctr, + &data_array[(i - 1) * BLOCK_SIZE], + BLOCK_SIZE); /* step 7 in NIST pdf*/ + } else { + bit_xor(ctr, &data_array[(i - 1) * BLOCK_SIZE], length); + } + length = length - BLOCK_SIZE; } - + } } -uint32_t CCM_encrypt_and_auth( - const uint8_t *key, - const uint8_t *nonce, - const uint8_t *aad, - const uint32_t aad_len, - uint8_t *plain_ciphertext, - const uint16_t text_to_encrypt_len) +uint32_t CCM_encrypt_and_auth(const uint8_t *key, + const uint8_t *nonce, + const uint8_t *aad, + const uint32_t aad_len, + uint8_t *plain_ciphertext, + const uint16_t text_to_encrypt_len) { - uint8_t blocks[2][BLOCK_SIZE]; - int mac_len = t; - //uint8_t mac[BLOCK_SIZE]; /* see mac_len */ - //int i; - uint16_t counter_blocks = (text_to_encrypt_len / BLOCK_SIZE) + 1; - //unsigned int offset = 0; - //int ret; - - if (text_to_encrypt_len % BLOCK_SIZE) - counter_blocks++; - - format_b0(mac_len, text_to_encrypt_len, blocks[0], nonce); - ciph_block(blocks[0], key); - if(!format_aad(blocks, aad, aad_len, key)) { - return 0; - } - - format_payload_block(blocks, plain_ciphertext, text_to_encrypt_len, key); - - encrypt_or_decrypt(plain_ciphertext, text_to_encrypt_len, counter_blocks, blocks[0], nonce, mac_len, key, blocks[0], ENCRYPT); - memcpy(plain_ciphertext + text_to_encrypt_len, blocks[0], mac_len); - - return (uint32_t)(text_to_encrypt_len + mac_len); + uint8_t blocks[2][BLOCK_SIZE]; + int mac_len = t; + //uint8_t mac[BLOCK_SIZE]; /* see mac_len */ + //int i; + uint16_t counter_blocks = (text_to_encrypt_len / BLOCK_SIZE) + 1; + //unsigned int offset = 0; + //int ret; + + if (text_to_encrypt_len % BLOCK_SIZE) + counter_blocks++; + + format_b0(mac_len, text_to_encrypt_len, blocks[0], nonce); + ciph_block(blocks[0], key); + if (!format_aad(blocks, aad, aad_len, key)) { + return 0; + } + + format_payload_block(blocks, plain_ciphertext, text_to_encrypt_len, key); + + encrypt_or_decrypt(plain_ciphertext, + text_to_encrypt_len, + counter_blocks, + blocks[0], + nonce, + mac_len, + key, + blocks[0], + ENCRYPT); + memcpy(plain_ciphertext + text_to_encrypt_len, blocks[0], mac_len); + + return (uint32_t)(text_to_encrypt_len + mac_len); } /* ---------------------------- Decrypt part ---------------------------------*/ - -uint16_t CCM_decrypt_and_auth( - const uint8_t *key, - const uint8_t *nonce, - const uint8_t *aad, - const uint32_t aad_len, - uint8_t *cipher_plaintext, - const uint32_t ciphertext_len -) +uint16_t CCM_decrypt_and_auth(const uint8_t *key, + const uint8_t *nonce, + const uint8_t *aad, + const uint32_t aad_len, + uint8_t *cipher_plaintext, + const uint32_t ciphertext_len) { - uint8_t blocks[2][BLOCK_SIZE]; - unsigned int num_counter_blocks = (ciphertext_len - t) / BLOCK_SIZE + 1; - uint8_t mac[BLOCK_SIZE]; /* see mac_len */ - int mac_len = t; - //int i, j; - //uint8_t *first_block; - //unsigned int offset = 0; - //int ret; - - if ((ciphertext_len - t) % BLOCK_SIZE) - num_counter_blocks++; - - if (ciphertext_len < t) { - return 0; - } - encrypt_or_decrypt(cipher_plaintext, ciphertext_len - t, num_counter_blocks, blocks[0], nonce, mac_len, key, mac, DECRYPT); - - /* Decrypt the mac which is at the end of cyphertex */ - bit_xor(&cipher_plaintext[ciphertext_len - t], blocks[0], t); - memcpy(mac, blocks[0], t); - - format_b0(mac_len, ciphertext_len - t, blocks[0], nonce); - ciph_block(blocks[0], key); - if(!format_aad(blocks, aad, aad_len, key)) { - return 0; - } - - format_payload_block(blocks, cipher_plaintext, ciphertext_len - t, key); - - if (memcmp(blocks[0], mac, t) != 0) { - //memset(cipher_plaintext, 0, ciphertext_len - t); - return 0; - } - return ciphertext_len - t; + uint8_t blocks[2][BLOCK_SIZE]; + unsigned int num_counter_blocks = (ciphertext_len - t) / BLOCK_SIZE + 1; + uint8_t mac[BLOCK_SIZE]; /* see mac_len */ + int mac_len = t; + //int i, j; + //uint8_t *first_block; + //unsigned int offset = 0; + //int ret; + + if ((ciphertext_len - t) % BLOCK_SIZE) + num_counter_blocks++; + + if (ciphertext_len < t) { + return 0; + } + encrypt_or_decrypt(cipher_plaintext, + ciphertext_len - t, + num_counter_blocks, + blocks[0], + nonce, + mac_len, + key, + mac, + DECRYPT); + + /* Decrypt the mac which is at the end of cyphertex */ + bit_xor(&cipher_plaintext[ciphertext_len - t], blocks[0], t); + memcpy(mac, blocks[0], t); + + format_b0(mac_len, ciphertext_len - t, blocks[0], nonce); + ciph_block(blocks[0], key); + if (!format_aad(blocks, aad, aad_len, key)) { + return 0; + } + + format_payload_block(blocks, cipher_plaintext, ciphertext_len - t, key); + + if (memcmp(blocks[0], mac, t) != 0) { + //memset(cipher_plaintext, 0, ciphertext_len - t); + return 0; + } + return ciphertext_len - t; } #ifndef CCM_USE_PREDEFINED_VALUES @@ -343,14 +380,14 @@ void set_q_n_t(uint8_t q_in, uint8_t n_in, uint8_t t_in) } #endif -void get_q_n_t(uint8_t * q_out, uint8_t * n_out, uint8_t * t_out) +void get_q_n_t(uint8_t *q_out, uint8_t *n_out, uint8_t *t_out) { *q_out = q; *n_out = n; *t_out = t; } -void get_q(uint8_t * q_out) +void get_q(uint8_t *q_out) { *q_out = q; } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/ctr_drbg/ctr_drbg.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/ctr_drbg/ctr_drbg.c index aa8ed11d3..57065b8cc 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/ctr_drbg/ctr_drbg.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/ctr_drbg/ctr_drbg.c @@ -31,38 +31,37 @@ #ifdef ZWAVE_PSA_AES void AES128_ECB_encrypt(uint8_t *in, const uint8_t *key, uint8_t *out) { - uint32_t key_id = ZWAVE_ECB_TEMP_ENC_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, key, ZW_PSA_ALG_ECB_NO_PAD); - /* Import key into secure vault */ - zw_psa_aes_ecb_encrypt(key_id, in, out); - /* Remove key from vault */ - zw_psa_destroy_key(key_id); + uint32_t key_id = ZWAVE_ECB_TEMP_ENC_KEY_ID; + zw_wrap_aes_key_secure_vault(&key_id, key, ZW_PSA_ALG_ECB_NO_PAD); + /* Import key into secure vault */ + zw_psa_aes_ecb_encrypt(key_id, in, out); + /* Remove key from vault */ + zw_psa_destroy_key(key_id); } #endif -void AJ_AES_ECB_128_ENCRYPT(uint8_t* key, uint8_t* in, uint8_t* out) +void AJ_AES_ECB_128_ENCRYPT(uint8_t *key, uint8_t *in, uint8_t *out) { #ifdef ZWAVE_PSA_AES - uint32_t key_id = ZWAVE_ECB_TEMP_ENC_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, key, ZW_PSA_ALG_ECB_NO_PAD); - /* Import key into secure vault */ - zw_psa_aes_ecb_encrypt(key_id, in, out); - /* Remove key from vault */ - zw_psa_destroy_key(key_id); + uint32_t key_id = ZWAVE_ECB_TEMP_ENC_KEY_ID; + zw_wrap_aes_key_secure_vault(&key_id, key, ZW_PSA_ALG_ECB_NO_PAD); + /* Import key into secure vault */ + zw_psa_aes_ecb_encrypt(key_id, in, out); + /* Remove key from vault */ + zw_psa_destroy_key(key_id); #else - AES128_ECB_encrypt(in, key, out); + AES128_ECB_encrypt(in, key, out); #endif } - -static void AES_CTR_DRBG_Increment(uint8_t* __data, size_t size) +static void AES_CTR_DRBG_Increment(uint8_t *__data, size_t size) { - while (size--) { - __data[size]++; - if (__data[size]) { - break; - } + while (size--) { + __data[size]++; + if (__data[size]) { + break; } + } } /* CTR_DRBG_Update (provided_data, Key, V): @@ -77,90 +76,91 @@ provided_data in the instantiate, reseed and generate functions. 2.V: The new value for V. */ -static void AES_CTR_DRBG_Update(CTR_DRBG_CTX* ctx, uint8_t __data[SEEDLEN]) +static void AES_CTR_DRBG_Update(CTR_DRBG_CTX *ctx, uint8_t __data[SEEDLEN]) { - size_t i = 0; - uint8_t tmp[SEEDLEN] = { 0 }; - uint8_t* t = tmp; - - //AJ_AES_Enable(ctx->k); - for (i = 0; i < SEEDLEN; i += OUTLEN) { - AES_CTR_DRBG_Increment(ctx->v, OUTLEN); /*V= (V+ 1) mod 2 pow(outlen) */ - AJ_AES_ECB_128_ENCRYPT(ctx->k, ctx->v, t); /* output_block = Block_Encrypt(Key, V). */ - t += OUTLEN; /*temp = temp || ouput_block */ - } - - for (i = 0; i < SEEDLEN; i++) { - /* temp = Leftmost seedlen bits of temp. + size_t i = 0; + uint8_t tmp[SEEDLEN] = {0}; + uint8_t *t = tmp; + + //AJ_AES_Enable(ctx->k); + for (i = 0; i < SEEDLEN; i += OUTLEN) { + AES_CTR_DRBG_Increment(ctx->v, OUTLEN); /*V= (V+ 1) mod 2 pow(outlen) */ + AJ_AES_ECB_128_ENCRYPT(ctx->k, + ctx->v, + t); /* output_block = Block_Encrypt(Key, V). */ + t += OUTLEN; /*temp = temp || ouput_block */ + } + + for (i = 0; i < SEEDLEN; i++) { + /* temp = Leftmost seedlen bits of temp. temp = temp || provided_data; */ - tmp[i] ^= __data[i]; - } + tmp[i] ^= __data[i]; + } - memcpy(ctx->k, tmp, KEYLEN); - memcpy(ctx->v, tmp + KEYLEN, OUTLEN); + memcpy(ctx->k, tmp, KEYLEN); + memcpy(ctx->v, tmp + KEYLEN, OUTLEN); } - -void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX* ctx, uint8_t* seed) +void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX *ctx, uint8_t *seed) { - AES_CTR_DRBG_Update(ctx, seed); + AES_CTR_DRBG_Update(ctx, seed); } - -void AES_CTR_DRBG_Instantiate(CTR_DRBG_CTX* ctx, uint8_t* entropy, const uint8_t* personal) +void AES_CTR_DRBG_Instantiate(CTR_DRBG_CTX *ctx, + uint8_t *entropy, + const uint8_t *personal) { #if 1 - uint8_t i; + uint8_t i; #else - int i; + int i; #endif - if(personal != NULL) { - for (i = 0; i < SEEDLEN; i++) { - /* temp = Leftmost seedlen bits of temp. + if (personal != NULL) { + for (i = 0; i < SEEDLEN; i++) { + /* temp = Leftmost seedlen bits of temp. temp = temp || provided_data; */ - entropy[i] ^= personal[i]; - } + entropy[i] ^= personal[i]; } - else { - for (i = 0; i < SEEDLEN; i++) { - /* temp = Leftmost seedlen bits of temp. + } else { + for (i = 0; i < SEEDLEN; i++) { + /* temp = Leftmost seedlen bits of temp. temp = temp || provided_data; */ - entropy[i] ^= 0; - } + entropy[i] ^= 0; } + } - memset(ctx->k, 0, KEYLEN); - memset(ctx->v, 0, OUTLEN); - ctx->df = 0; - AES_CTR_DRBG_Reseed(ctx, entropy); + memset(ctx->k, 0, KEYLEN); + memset(ctx->v, 0, OUTLEN); + ctx->df = 0; + AES_CTR_DRBG_Reseed(ctx, entropy); } -void AES_CTR_DRBG_Generate(CTR_DRBG_CTX* ctx, uint8_t* rand) +void AES_CTR_DRBG_Generate(CTR_DRBG_CTX *ctx, uint8_t *rand) { - uint8_t __data[SEEDLEN] = { 0 }; - size_t copy; - size_t size = RANDLEN; - -// /* Needed?? Is uint8_t enough ??? */ -// uint16_t count = 0; - - // Reseed interval 2^32 (counter wraps to zero) - // See section 10.2.1.5.1. Step 1 in "CTR_DRBG Generate Proces" - //AJ_AES_Enable(ctx->k); - while (size) { - AES_CTR_DRBG_Increment(ctx->v, OUTLEN); - AJ_AES_ECB_128_ENCRYPT(ctx->k, ctx->v, __data); - copy = (size < OUTLEN) ? size : OUTLEN; - memcpy(rand, __data, copy); - rand += copy; - size -= copy; -// count+= copy; - } - - memset(__data, 0, SEEDLEN); - AES_CTR_DRBG_Update(ctx, __data); + uint8_t __data[SEEDLEN] = {0}; + size_t copy; + size_t size = RANDLEN; + + // /* Needed?? Is uint8_t enough ??? */ + // uint16_t count = 0; + + // Reseed interval 2^32 (counter wraps to zero) + // See section 10.2.1.5.1. Step 1 in "CTR_DRBG Generate Proces" + //AJ_AES_Enable(ctx->k); + while (size) { + AES_CTR_DRBG_Increment(ctx->v, OUTLEN); + AJ_AES_ECB_128_ENCRYPT(ctx->k, ctx->v, __data); + copy = (size < OUTLEN) ? size : OUTLEN; + memcpy(rand, __data, copy); + rand += copy; + size -= copy; + // count+= copy; + } + + memset(__data, 0, SEEDLEN); + AES_CTR_DRBG_Update(ctx, __data); } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/api.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/api.h index f5d6d03e7..d0001b0ae 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/api.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/api.h @@ -1,6 +1,6 @@ /* © 2017 Silicon Laboratories Inc. */ #ifndef ZWAVE_PSA_SECURE_VAULT -#define CRYPTO_BYTES 32 +#define CRYPTO_BYTES 32 #define CRYPTO_SCALARBYTES 32 #endif diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/base.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/base.c index c97f41edc..540756b22 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/base.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/base.c @@ -11,16 +11,16 @@ Derived from public domain code by D. J. Bernstein. */ //#include "crypto_scalarmult.h" -#if !defined(ZWAVE_PSA_SECURE_VAULT) || (defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZW_CONTROLLER)) +#if !defined(ZWAVE_PSA_SECURE_VAULT) \ + || (defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZW_CONTROLLER)) extern int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, const unsigned char *p); const unsigned char base[32] = {9}; -int crypto_scalarmult_curve25519_base(unsigned char *q, - const unsigned char *n) +int crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n) { - return crypto_scalarmult_curve25519(q,n,base); + return crypto_scalarmult_curve25519(q, n, base); } #endif diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/smult.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/smult.c index bca666562..dc700853a 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/smult.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/curve25519/smult.c @@ -11,29 +11,37 @@ Derived from public domain code by D. J. Bernstein. */ //#include "crypto_scalarmult.h" -#if !defined(ZWAVE_PSA_SECURE_VAULT) || (defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZW_CONTROLLER)) +#if !defined(ZWAVE_PSA_SECURE_VAULT) \ + || (defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZW_CONTROLLER)) #ifndef NDEBUG #ifdef EFR32ZG #pragma GCC push_options -#pragma GCC optimize ("Os") +#pragma GCC optimize("Os") #endif #endif -static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +static void + add(unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) { unsigned int j; unsigned int u; u = 0; - for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; } - u += a[31] + b[31]; out[31] = u; + for (j = 0; j < 31; ++j) { + u += a[j] + b[j]; + out[j] = u & 255; + u >>= 8; + } + u += a[31] + b[31]; + out[31] = u; } -static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +static void + sub(unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) { unsigned int j; unsigned int u; u = 218; - for (j = 0;j < 31;++j) { + for (j = 0; j < 31; ++j) { u += a[j] + 65280 - b[j]; out[j] = u & 255; u >>= 8; @@ -47,16 +55,26 @@ static void squeeze(unsigned int a[32]) unsigned int j; unsigned int u; u = 0; - for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } - u += a[31]; a[31] = u & 127; - u = 19 * (u >> 7); - for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } - u += a[31]; a[31] = u; + for (j = 0; j < 31; ++j) { + u += a[j]; + a[j] = u & 255; + u >>= 8; + } + u += a[31]; + a[31] = u & 127; + u = 19 * (u >> 7); + for (j = 0; j < 31; ++j) { + u += a[j]; + a[j] = u & 255; + u >>= 8; + } + u += a[31]; + a[31] = u; } -static const unsigned int minusp[32] = { - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 -} ; +static const unsigned int minusp[32] + = {19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128}; static void freeze(unsigned int a[32]) { @@ -64,50 +82,67 @@ static void freeze(unsigned int a[32]) unsigned int j; unsigned int negative; - for (j = 0;j < 32;++j) aorig[j] = a[j]; - add(a,a,minusp); + for (j = 0; j < 32; ++j) + aorig[j] = a[j]; + add(a, a, minusp); negative = -((a[31] >> 7) & 1); - for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]); + for (j = 0; j < 32; ++j) + a[j] ^= negative & (aorig[j] ^ a[j]); } -static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +static void + mult(unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) { unsigned int i; unsigned int j; unsigned int u; - for (i = 0;i < 32;++i) { + for (i = 0; i < 32; ++i) { u = 0; - for (j = 0;j <= i;++j) u += a[j] * b[i - j]; - for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j]; + for (j = 0; j <= i; ++j) + u += a[j] * b[i - j]; + for (j = i + 1; j < 32; ++j) + u += 38 * a[j] * b[i + 32 - j]; out[i] = u; } squeeze(out); } -static void mult121665(unsigned int out[32],const unsigned int a[32]) +static void mult121665(unsigned int out[32], const unsigned int a[32]) { unsigned int j; unsigned int u; u = 0; - for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; } - u += 121665 * a[31]; out[31] = u & 127; - u = 19 * (u >> 7); - for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; } - u += out[j]; out[j] = u; + for (j = 0; j < 31; ++j) { + u += 121665 * a[j]; + out[j] = u & 255; + u >>= 8; + } + u += 121665 * a[31]; + out[31] = u & 127; + u = 19 * (u >> 7); + for (j = 0; j < 31; ++j) { + u += out[j]; + out[j] = u & 255; + u >>= 8; + } + u += out[j]; + out[j] = u; } -static void square(unsigned int out[32],const unsigned int a[32]) +static void square(unsigned int out[32], const unsigned int a[32]) { unsigned int i; unsigned int j; unsigned int u; - for (i = 0;i < 32;++i) { + for (i = 0; i < 32; ++i) { u = 0; - for (j = 0;j < i - j;++j) u += a[j] * a[i - j]; - for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j]; + for (j = 0; j < i - j; ++j) + u += a[j] * a[i - j]; + for (j = i + 1; j < i + 32 - j; ++j) + u += 38 * a[j] * a[i + 32 - j]; u *= 2; if ((i & 1) == 0) { u += a[i / 2] * a[i / 2]; @@ -118,21 +153,25 @@ static void square(unsigned int out[32],const unsigned int a[32]) squeeze(out); } -static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b) +static void select(unsigned int p[64], + unsigned int q[64], + const unsigned int r[64], + const unsigned int s[64], + unsigned int b) { unsigned int j; unsigned int t; unsigned int bminus1; bminus1 = b - 1; - for (j = 0;j < 64;++j) { - t = bminus1 & (r[j] ^ s[j]); + for (j = 0; j < 64; ++j) { + t = bminus1 & (r[j] ^ s[j]); p[j] = s[j] ^ t; q[j] = r[j] ^ t; } } -static void mainloop(unsigned int work[64],const unsigned char e[32]) +static void mainloop(unsigned int work[64], const unsigned char e[32]) { unsigned int xzm1[64]; unsigned int xzm[64]; @@ -149,47 +188,51 @@ static void mainloop(unsigned int work[64],const unsigned char e[32]) unsigned int s[32]; unsigned int t[32]; unsigned int u[32]; -// unsigned int i; + // unsigned int i; unsigned int j; unsigned int b; int pos; - for (j = 0;j < 32;++j) xzm1[j] = work[j]; + for (j = 0; j < 32; ++j) + xzm1[j] = work[j]; xzm1[32] = 1; - for (j = 33;j < 64;++j) xzm1[j] = 0; + for (j = 33; j < 64; ++j) + xzm1[j] = 0; xzm[0] = 1; - for (j = 1;j < 64;++j) xzm[j] = 0; + for (j = 1; j < 64; ++j) + xzm[j] = 0; - for (pos = 254;pos >= 0;--pos) { + for (pos = 254; pos >= 0; --pos) { b = e[pos / 8] >> (pos & 7); b &= 1; - select(xzmb,xzm1b,xzm,xzm1,b); - add(a0,xzmb,xzmb + 32); - sub(a0 + 32,xzmb,xzmb + 32); - add(a1,xzm1b,xzm1b + 32); - sub(a1 + 32,xzm1b,xzm1b + 32); - square(b0,a0); - square(b0 + 32,a0 + 32); - mult(b1,a1,a0 + 32); - mult(b1 + 32,a1 + 32,a0); - add(c1,b1,b1 + 32); - sub(c1 + 32,b1,b1 + 32); - square(r,c1 + 32); - sub(s,b0,b0 + 32); - mult121665(t,s); - add(u,t,b0); - mult(xznb,b0,b0 + 32); - mult(xznb + 32,s,u); - square(xzn1b,c1); - mult(xzn1b + 32,r,work); - select(xzm,xzm1,xznb,xzn1b,b); + select(xzmb, xzm1b, xzm, xzm1, b); + add(a0, xzmb, xzmb + 32); + sub(a0 + 32, xzmb, xzmb + 32); + add(a1, xzm1b, xzm1b + 32); + sub(a1 + 32, xzm1b, xzm1b + 32); + square(b0, a0); + square(b0 + 32, a0 + 32); + mult(b1, a1, a0 + 32); + mult(b1 + 32, a1 + 32, a0); + add(c1, b1, b1 + 32); + sub(c1 + 32, b1, b1 + 32); + square(r, c1 + 32); + sub(s, b0, b0 + 32); + mult121665(t, s); + add(u, t, b0); + mult(xznb, b0, b0 + 32); + mult(xznb + 32, s, u); + square(xzn1b, c1); + mult(xzn1b + 32, r, work); + select(xzm, xzm1, xznb, xzn1b, b); } - for (j = 0;j < 64;++j) work[j] = xzm[j]; + for (j = 0; j < 64; ++j) + work[j] = xzm[j]; } -static void recip(unsigned int out[32],const unsigned int z[32]) +static void recip(unsigned int out[32], const unsigned int z[32]) { unsigned int z2[32]; unsigned int z9[32]; @@ -203,76 +246,97 @@ static void recip(unsigned int out[32],const unsigned int z[32]) unsigned int t1[32]; int i; - /* 2 */ square(z2,z); - /* 4 */ square(t1,z2); - /* 8 */ square(t0,t1); - /* 9 */ mult(z9,t0,z); - /* 11 */ mult(z11,z9,z2); - /* 22 */ square(t0,z11); - /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9); - - /* 2^6 - 2^1 */ square(t0,z2_5_0); - /* 2^7 - 2^2 */ square(t1,t0); - /* 2^8 - 2^3 */ square(t0,t1); - /* 2^9 - 2^4 */ square(t1,t0); - /* 2^10 - 2^5 */ square(t0,t1); - /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0); - - /* 2^11 - 2^1 */ square(t0,z2_10_0); - /* 2^12 - 2^2 */ square(t1,t0); - /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0); - - /* 2^21 - 2^1 */ square(t0,z2_20_0); - /* 2^22 - 2^2 */ square(t1,t0); - /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0); - - /* 2^41 - 2^1 */ square(t1,t0); - /* 2^42 - 2^2 */ square(t0,t1); - /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); } - /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0); - - /* 2^51 - 2^1 */ square(t0,z2_50_0); - /* 2^52 - 2^2 */ square(t1,t0); - /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0); - - /* 2^101 - 2^1 */ square(t1,z2_100_0); - /* 2^102 - 2^2 */ square(t0,t1); - /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); } - /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0); - - /* 2^201 - 2^1 */ square(t0,t1); - /* 2^202 - 2^2 */ square(t1,t0); - /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0); - - /* 2^251 - 2^1 */ square(t1,t0); - /* 2^252 - 2^2 */ square(t0,t1); - /* 2^253 - 2^3 */ square(t1,t0); - /* 2^254 - 2^4 */ square(t0,t1); - /* 2^255 - 2^5 */ square(t1,t0); - /* 2^255 - 21 */ mult(out,t1,z11); + /* 2 */ square(z2, z); + /* 4 */ square(t1, z2); + /* 8 */ square(t0, t1); + /* 9 */ mult(z9, t0, z); + /* 11 */ mult(z11, z9, z2); + /* 22 */ square(t0, z11); + /* 2^5 - 2^0 = 31 */ mult(z2_5_0, t0, z9); + + /* 2^6 - 2^1 */ square(t0, z2_5_0); + /* 2^7 - 2^2 */ square(t1, t0); + /* 2^8 - 2^3 */ square(t0, t1); + /* 2^9 - 2^4 */ square(t1, t0); + /* 2^10 - 2^5 */ square(t0, t1); + /* 2^10 - 2^0 */ mult(z2_10_0, t0, z2_5_0); + + /* 2^11 - 2^1 */ square(t0, z2_10_0); + /* 2^12 - 2^2 */ square(t1, t0); + /* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^20 - 2^0 */ mult(z2_20_0, t1, z2_10_0); + + /* 2^21 - 2^1 */ square(t0, z2_20_0); + /* 2^22 - 2^2 */ square(t1, t0); + /* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^40 - 2^0 */ mult(t0, t1, z2_20_0); + + /* 2^41 - 2^1 */ square(t1, t0); + /* 2^42 - 2^2 */ square(t0, t1); + /* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { + square(t1, t0); + square(t0, t1); + } + /* 2^50 - 2^0 */ mult(z2_50_0, t0, z2_10_0); + + /* 2^51 - 2^1 */ square(t0, z2_50_0); + /* 2^52 - 2^2 */ square(t1, t0); + /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^100 - 2^0 */ mult(z2_100_0, t1, z2_50_0); + + /* 2^101 - 2^1 */ square(t1, z2_100_0); + /* 2^102 - 2^2 */ square(t0, t1); + /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { + square(t1, t0); + square(t0, t1); + } + /* 2^200 - 2^0 */ mult(t1, t0, z2_100_0); + + /* 2^201 - 2^1 */ square(t0, t1); + /* 2^202 - 2^2 */ square(t1, t0); + /* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^250 - 2^0 */ mult(t0, t1, z2_50_0); + + /* 2^251 - 2^1 */ square(t1, t0); + /* 2^252 - 2^2 */ square(t0, t1); + /* 2^253 - 2^3 */ square(t1, t0); + /* 2^254 - 2^4 */ square(t0, t1); + /* 2^255 - 2^5 */ square(t1, t0); + /* 2^255 - 21 */ mult(out, t1, z11); } int crypto_scalarmult_curve25519(unsigned char *q, - const unsigned char *n, - const unsigned char *p) + const unsigned char *n, + const unsigned char *p) { unsigned int work[96]; unsigned char e[32]; unsigned int i; - for (i = 0;i < 32;++i) e[i] = n[i]; + for (i = 0; i < 32; ++i) + e[i] = n[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; - for (i = 0;i < 32;++i) work[i] = p[i]; - mainloop(work,e); - recip(work + 32,work + 32); - mult(work + 64,work,work + 32); + for (i = 0; i < 32; ++i) + work[i] = p[i]; + mainloop(work, e); + recip(work + 32, work + 32); + mult(work + 64, work, work + 32); freeze(work + 64); - for (i = 0;i < 32;++i) q[i] = work[64 + i]; + for (i = 0; i < 32; ++i) + q[i] = work[64 + i]; return 0; } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/kderiv/kderiv.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/kderiv/kderiv.c index 5fab18d8f..7a443491c 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/kderiv/kderiv.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/kderiv/kderiv.c @@ -13,112 +13,163 @@ #endif #define CONSTANT_NK_LEN 15 -static void zw_expand_aes_cmac(uint32_t key_id, const uint8_t *network_key, const uint8_t *input, uint16_t length, uint8_t *output) +static void zw_expand_aes_cmac(uint32_t key_id, + const uint8_t *network_key, + const uint8_t *input, + uint16_t length, + uint8_t *output) { #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - if (key_id) - { - if ((key_id >= ZWAVE_PSA_KEY_ID_MIN) && (key_id <= ZWAVE_PSA_KEY_ID_MAX)) - { - /* Use the key_id of the network key that is persistently + if (key_id) { + if ((key_id >= ZWAVE_PSA_KEY_ID_MIN) && (key_id <= ZWAVE_PSA_KEY_ID_MAX)) { + /* Use the key_id of the network key that is persistently * stored in Secure Element(SE) in wrapped form */ - zw_psa_aes_cmac(key_id, input, (size_t)length, output); - } - } - else - { - /* Use a temporary key, import to secure vault for this operation */ - key_id = ZWAVE_CMAC_TEMP_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, network_key, ZW_PSA_ALG_CMAC); zw_psa_aes_cmac(key_id, input, (size_t)length, output); - /* Destroy the temporarily imported key */ - zw_psa_destroy_key(key_id); } + } else { + /* Use a temporary key, import to secure vault for this operation */ + key_id = ZWAVE_CMAC_TEMP_KEY_ID; + zw_wrap_aes_key_secure_vault(&key_id, network_key, ZW_PSA_ALG_CMAC); + zw_psa_aes_cmac(key_id, input, (size_t)length, output); + /* Destroy the temporarily imported key */ + zw_psa_destroy_key(key_id); + } #else - assert(key_id == ZWAVE_KEY_ID_NONE); - aes_cmac_calculate(network_key, input, length, output); + assert(key_id == ZWAVE_KEY_ID_NONE); + aes_cmac_calculate(network_key, input, length, output); #endif } -void generic_expand( - uint32_t key_id, - const uint8_t *network_key, - const uint8_t *constant_nk, - uint8_t *ccm_key, - uint8_t *nonce_pstring, - uint8_t *mpan_key) +void generic_expand(uint32_t key_id, + const uint8_t *network_key, + const uint8_t *constant_nk, + uint8_t *ccm_key, + uint8_t *nonce_pstring, + uint8_t *mpan_key) { - uint8_t temp[32]; + uint8_t temp[32]; - /* ccm_key = CMAC(NetworkKey, temp) */ - memcpy(temp, constant_nk, 15); - temp[15] = 0x01; - zw_expand_aes_cmac(key_id, network_key, temp, 16, ccm_key); + /* ccm_key = CMAC(NetworkKey, temp) */ + memcpy(temp, constant_nk, 15); + temp[15] = 0x01; + zw_expand_aes_cmac(key_id, network_key, temp, 16, ccm_key); - /* nonce_pstring first half */ - memcpy(temp, ccm_key, 16); - memcpy(temp+16, constant_nk, 15); - temp[31] = 0x02; - zw_expand_aes_cmac(key_id, network_key, temp, 32, nonce_pstring); + /* nonce_pstring first half */ + memcpy(temp, ccm_key, 16); + memcpy(temp + 16, constant_nk, 15); + temp[31] = 0x02; + zw_expand_aes_cmac(key_id, network_key, temp, 32, nonce_pstring); - /* nonce_pstring is 32 bytes, fill out second half */ - memcpy(temp, nonce_pstring, 16); - memcpy(temp+16, constant_nk, 15); - temp[31] = 0x03; - zw_expand_aes_cmac(key_id, network_key, temp, 32, nonce_pstring+16); + /* nonce_pstring is 32 bytes, fill out second half */ + memcpy(temp, nonce_pstring, 16); + memcpy(temp + 16, constant_nk, 15); + temp[31] = 0x03; + zw_expand_aes_cmac(key_id, network_key, temp, 32, nonce_pstring + 16); - /* MPAN key */ - memcpy(temp, nonce_pstring+16, 16); - memcpy(temp+16, constant_nk, 15); - temp[31] = 0x04; - zw_expand_aes_cmac(key_id, network_key, temp, 32, mpan_key); + /* MPAN key */ + memcpy(temp, nonce_pstring + 16, 16); + memcpy(temp + 16, constant_nk, 15); + temp[31] = 0x04; + zw_expand_aes_cmac(key_id, network_key, temp, 32, mpan_key); - return; + return; } -void networkkey_expand( - uint32_t key_id, - const uint8_t *network_key, - uint8_t *ccm_key, - uint8_t *nonce_pstring, - uint8_t *mpan_key) +void networkkey_expand(uint32_t key_id, + const uint8_t *network_key, + uint8_t *ccm_key, + uint8_t *nonce_pstring, + uint8_t *mpan_key) { - uint8_t constant_nk[15] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55}; - generic_expand(key_id, network_key, constant_nk, ccm_key, nonce_pstring, mpan_key); + uint8_t constant_nk[15] = {0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55, + 0x55}; + generic_expand(key_id, + network_key, + constant_nk, + ccm_key, + nonce_pstring, + mpan_key); } -void tempkey_extract( - const uint8_t *const ecdh_share_secret, - const uint8_t *const auth_tag, - uint8_t *pseudo_random_keymat_output) +void tempkey_extract(const uint8_t *const ecdh_share_secret, + const uint8_t *const auth_tag, + uint8_t *pseudo_random_keymat_output) { - uint8_t temp[96]; - uint8_t constant_prk[16] = {0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33}; - - /* concatenate ecdh shared secret with auth_tag */ - memcpy(temp, ecdh_share_secret, 32); /*length of ecdh_share_secret is 32 byte */ - memcpy(temp+32, auth_tag, 64);/*length of auth_tag is 64 byte */ - /* cmac concatenation with constant_PRK as key */ + uint8_t temp[96]; + uint8_t constant_prk[16] = {0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33, + 0x33}; + + /* concatenate ecdh shared secret with auth_tag */ + memcpy(temp, + ecdh_share_secret, + 32); /*length of ecdh_share_secret is 32 byte */ + memcpy(temp + 32, auth_tag, 64); /*length of auth_tag is 64 byte */ + /* cmac concatenation with constant_PRK as key */ #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - uint32_t key_id = ZWAVE_CMAC_TEMP_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, constant_prk, ZW_PSA_ALG_CMAC); - zw_psa_aes_cmac(key_id, temp, 96, pseudo_random_keymat_output); - zw_psa_destroy_key(key_id); + uint32_t key_id = ZWAVE_CMAC_TEMP_KEY_ID; + zw_wrap_aes_key_secure_vault(&key_id, constant_prk, ZW_PSA_ALG_CMAC); + zw_psa_aes_cmac(key_id, temp, 96, pseudo_random_keymat_output); + zw_psa_destroy_key(key_id); #else - aes_cmac_calculate(constant_prk, temp, 96, pseudo_random_keymat_output); + aes_cmac_calculate(constant_prk, temp, 96, pseudo_random_keymat_output); #endif - /* return first 16 bytes as output */ - return; + /* return first 16 bytes as output */ + return; } -void tempkey_expand( - uint32_t key_id, - const uint8_t *prk, - uint8_t *temp_ccm_key, - uint8_t *temp_nonce_pstring, - uint8_t *temp_mpan_key) +void tempkey_expand(uint32_t key_id, + const uint8_t *prk, + uint8_t *temp_ccm_key, + uint8_t *temp_nonce_pstring, + uint8_t *temp_mpan_key) { - uint8_t constant_TE[15] = {0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88}; - generic_expand(key_id, prk, constant_TE, temp_ccm_key, temp_nonce_pstring, temp_mpan_key); + uint8_t constant_TE[15] = {0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88}; + generic_expand(key_id, + prk, + constant_TE, + temp_ccm_key, + temp_nonce_pstring, + temp_mpan_key); } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/curve25519_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/curve25519_mock.c index 757653925..3273a9fe4 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/curve25519_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/curve25519_mock.c @@ -3,24 +3,25 @@ * Defines a platform abstraction layer for the Z-Wave bootloader. * * @copyright 2022 Silicon Laboratories Inc. - */ -#include -#include "curve25519.h" -#include "mock_control.h" - -#define MOCK_FILE "curve25519_mock.c" - -void crypto_scalarmult_curve25519(uint8_t *r, const uint8_t *s, const uint8_t *p) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, r, s, p); - - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG1, 32, s, 32); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, 32, p, 32); - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, r, 32, uint8_t); -} - + */ +#include +#include "curve25519.h" +#include "mock_control.h" + +#define MOCK_FILE "curve25519_mock.c" + +void crypto_scalarmult_curve25519(uint8_t *r, + const uint8_t *s, + const uint8_t *p) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, r, s, p); + + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG1, 32, s, 32); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, 32, p, 32); + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, r, 32, uint8_t); +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/kderiv_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/kderiv_mock.c index ed9a76f52..c63d862b9 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/kderiv_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/mock/kderiv_mock.c @@ -2,22 +2,30 @@ * @file kderiv_mock.c * @copyright 2022 Silicon Laboratories Inc. */ -#include -#include "kderiv.h" -#include "mock_control.h" - -#define MOCK_FILE "kderiv_mock.c" - -void tempkey_extract(const uint8_t *const ecdh_share_secret, const uint8_t *const auth_tag, uint8_t *pseudo_random_keymat_output) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, ecdh_share_secret, auth_tag, pseudo_random_keymat_output); - - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG0, 32, ecdh_share_secret, 32); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG1, 64, auth_tag, 64); - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[2].pointer, pseudo_random_keymat_output, 32, uint8_t); -} +#include +#include "kderiv.h" +#include "mock_control.h" + +#define MOCK_FILE "kderiv_mock.c" + +void tempkey_extract(const uint8_t *const ecdh_share_secret, + const uint8_t *const auth_tag, + uint8_t *pseudo_random_keymat_output) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, + ecdh_share_secret, + auth_tag, + pseudo_random_keymat_output); + + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG0, 32, ecdh_share_secret, 32); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG1, 64, auth_tag, 64); + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[2].pointer, + pseudo_random_keymat_output, + 32, + uint8_t); +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/nextnonce/nextnonce.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/nextnonce/nextnonce.c index 9daeaef88..44067aea1 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/nextnonce/nextnonce.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/crypto/nextnonce/nextnonce.c @@ -15,72 +15,104 @@ */ static void ckdf_nonce0_expand(uint8_t *prk, uint8_t *mei) { - /*Constant(EI) = 0x88 repeated 15 times*/ - const uint8_t constant_ei[15] = {0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}; - uint8_t t0[32]; /* 15 plus 1 plus 1 */ - uint8_t t1[16] = { 0 }; - uint8_t t2[16] = { 0 }; + /*Constant(EI) = 0x88 repeated 15 times*/ + const uint8_t constant_ei[15] = {0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88, + 0x88}; + uint8_t t0[32]; /* 15 plus 1 plus 1 */ + uint8_t t1[16] = {0}; + uint8_t t2[16] = {0}; - /*T0 = Constant ei | 0x00*/ - /* TODO FIXME SPEC: spec says contant_nk. We think it should be constant_ei */ - memcpy(t0, constant_ei, 15); - t0[15] = 0; + /*T0 = Constant ei | 0x00*/ + /* TODO FIXME SPEC: spec says contant_nk. We think it should be constant_ei */ + memcpy(t0, constant_ei, 15); + t0[15] = 0; - /*T1 = CMAC(K NONCE , T0 | Constant NK | 0x01)*/ - memcpy(t0+16, constant_ei, 15); - t0[16+15] = 1; + /*T1 = CMAC(K NONCE , T0 | Constant NK | 0x01)*/ + memcpy(t0 + 16, constant_ei, 15); + t0[16 + 15] = 1; #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - uint32_t key_id = ZWAVE_CMAC_TEMP_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, prk, ZW_PSA_ALG_CMAC); - zw_psa_aes_cmac(key_id, t0, 32, t1); + uint32_t key_id = ZWAVE_CMAC_TEMP_KEY_ID; + zw_wrap_aes_key_secure_vault(&key_id, prk, ZW_PSA_ALG_CMAC); + zw_psa_aes_cmac(key_id, t0, 32, t1); #else - aes_cmac_calculate(prk, t0, 32, t1); /* TODO t1 will be 16 byte after this? */ + aes_cmac_calculate(prk, t0, 32, t1); /* TODO t1 will be 16 byte after this? */ #endif - /*T2 = CMAC(K NONCE , T1 | Constant NK | 0x02)*/ - memcpy(t0, t1, 16); // backup t1 inside t0 - memcpy(t0+16, constant_ei, 15); - t0[16+15] = 2; + /*T2 = CMAC(K NONCE , T1 | Constant NK | 0x02)*/ + memcpy(t0, t1, 16); // backup t1 inside t0 + memcpy(t0 + 16, constant_ei, 15); + t0[16 + 15] = 2; #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - zw_psa_aes_cmac(key_id, t0, 32, t2); - zw_psa_destroy_key(key_id); + zw_psa_aes_cmac(key_id, t0, 32, t2); + zw_psa_destroy_key(key_id); #else - aes_cmac_calculate(prk, t0, 32, t2); + aes_cmac_calculate(prk, t0, 32, t2); #endif - /* MEI = T1 | T2 */ - memcpy(mei, t1, 16); - memcpy(mei+16, t2, 16); + /* MEI = T1 | T2 */ + memcpy(mei, t1, 16); + memcpy(mei + 16, t2, 16); } -void next_nonce_instantiate(CTR_DRBG_CTX* ctx,const uint8_t* ei_sender,const uint8_t* ei_receiver , uint8_t *k_nonce) +void next_nonce_instantiate(CTR_DRBG_CTX *ctx, + const uint8_t *ei_sender, + const uint8_t *ei_receiver, + uint8_t *k_nonce) { - /* Constant(NONCE) = 0x26 repeated 16 times.*/ - const uint8_t constant_nonce[16] = {0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26}; - uint8_t temp[32]; - uint8_t X[16]; - uint8_t mei[32]; + /* Constant(NONCE) = 0x26 repeated 16 times.*/ + const uint8_t constant_nonce[16] = {0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26, + 0x26}; + uint8_t temp[32]; + uint8_t X[16]; + uint8_t mei[32]; - /* sender's EI | receiver's EI */ - memcpy(temp, ei_sender, 16); + /* sender's EI | receiver's EI */ + memcpy(temp, ei_sender, 16); - memcpy(temp+16, ei_receiver, 16); + memcpy(temp + 16, ei_receiver, 16); #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - uint32_t key_id = ZWAVE_CMAC_TEMP_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, constant_nonce, ZW_PSA_ALG_CMAC); - zw_psa_aes_cmac(key_id, temp, 32, X); - zw_psa_destroy_key(key_id); + uint32_t key_id = ZWAVE_CMAC_TEMP_KEY_ID; + zw_wrap_aes_key_secure_vault(&key_id, constant_nonce, ZW_PSA_ALG_CMAC); + zw_psa_aes_cmac(key_id, temp, 32, X); + zw_psa_destroy_key(key_id); #else - aes_cmac_calculate(constant_nonce, temp, 32, X); + aes_cmac_calculate(constant_nonce, temp, 32, X); #endif - ckdf_nonce0_expand(X, mei); + ckdf_nonce0_expand(X, mei); - AES_CTR_DRBG_Instantiate(ctx, mei, k_nonce); + AES_CTR_DRBG_Instantiate(ctx, mei, k_nonce); } -int next_nonce_generate(CTR_DRBG_CTX* ctx, uint8_t* rand) +int next_nonce_generate(CTR_DRBG_CTX *ctx, uint8_t *rand) { - AES_CTR_DRBG_Generate(ctx, rand); + AES_CTR_DRBG_Generate(ctx, rand); - return 1; + return 1; } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2.h index 5ce0948f6..d6676f7a9 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2.h @@ -11,8 +11,8 @@ #ifndef INCLUDE_S2_H_ #define INCLUDE_S2_H_ -#include -#include +#include +#include #ifndef DllExport #define DllExport extern @@ -22,23 +22,22 @@ //#include -#define S2_MSG_FLAG_EXT 0x1 -#define S2_MSG_FLAG_SEXT 0x2 +#define S2_MSG_FLAG_EXT 0x1 +#define S2_MSG_FLAG_SEXT 0x2 #define S2_NONCE_REPORT_SOS_FLAG 1 #define S2_NONCE_REPORT_MOS_FLAG 2 #define S2_MSG_EXTHDR_CRITICAL_FLAG 0x40 -#define S2_MSG_EXTHDR_MORE_FLAG 0x80 -#define S2_MSG_EXTHDR_TYPE_MASK 0x3F -#define S2_MSG_EXTHDR_TYPE_SN 1 -#define S2_MSG_EXTHDR_TYPE_MPAN 2 -#define S2_MSG_EXTHDR_TYPE_MGRP 3 -#define S2_MSG_EXTHDR_TYPE_MOS 4 +#define S2_MSG_EXTHDR_MORE_FLAG 0x80 +#define S2_MSG_EXTHDR_TYPE_MASK 0x3F +#define S2_MSG_EXTHDR_TYPE_SN 1 +#define S2_MSG_EXTHDR_TYPE_MPAN 2 +#define S2_MSG_EXTHDR_TYPE_MGRP 3 +#define S2_MSG_EXTHDR_TYPE_MOS 4 /* TODO move above into ZW_classcmd.h */ - /** * \defgroup S2trans S2 transport system * The S2 transport system defines all the interfaces which are needed for @@ -50,7 +49,6 @@ * @{ **/ - /** * This flag will activate frame delivery. * @@ -112,7 +110,6 @@ typedef enum { UNKNOWN_KEYSET = 0xFF, } zwave_s2_keyset_t; - /** * The structure holds information about the sender and receiver in a S2 * Transmission. @@ -121,7 +118,7 @@ typedef struct peer { /** * Local node, if sending this a the node sending the message, when receiving this is the node receiving the message. */ - node_t l_node; //local node + node_t l_node; //local node /** * Remote node, when sending this is the node that should receive the message. When receiving a message, this is the @@ -178,16 +175,15 @@ typedef enum { */ S2_TRANSMIT_COMPLETE_FAIL = 0x02, - /** * We are sure that the node has decrypted the frame, because it has sent a message * the other way which it would only be able to send if it could decrypt this frame */ - S2_TRANSMIT_COMPLETE_VERIFIED = 0x5, /*TODO allocate code in ZW_transport_api.h*/ + S2_TRANSMIT_COMPLETE_VERIFIED + = 0x5, /*TODO allocate code in ZW_transport_api.h*/ } s2_tx_status_t; - /** * Anonymous declaration of the S2 context, the data inside S2 context must not be * modified outside libs2 */ @@ -210,7 +206,10 @@ typedef uint8_t network_key_t[16]; * * */ -uint8_t S2_send_data(struct S2* ctxt, s2_connection_t* peer ,const uint8_t* buf, uint16_t len); +uint8_t S2_send_data(struct S2 *ctxt, + s2_connection_t *peer, + const uint8_t *buf, + uint16_t len); /** * Check if S2 is ready to receive a new frame for transmission @@ -219,7 +218,7 @@ uint8_t S2_send_data(struct S2* ctxt, s2_connection_t* peer ,const uint8_t* buf, * \param[in] ctxt The S2 context * \return False if the S2_send_data method will accept a new frame for transmission */ -uint8_t S2_is_send_data_busy(struct S2* ctxt); +uint8_t S2_is_send_data_busy(struct S2 *ctxt); /** * Send multicast security s2 encrypted frame. @@ -232,8 +231,10 @@ uint8_t S2_is_send_data_busy(struct S2* ctxt); * \param len length of data to be sent. * */ -uint8_t S2_send_data_multicast(struct S2* ctxt, const s2_connection_t* dst, const uint8_t* buf, uint16_t len); - +uint8_t S2_send_data_multicast(struct S2 *ctxt, + const s2_connection_t *dst, + const uint8_t *buf, + uint16_t len); /** * A new A new (improved) version of S2_send_data that allows to select a @@ -248,10 +249,10 @@ uint8_t S2_send_data_multicast(struct S2* ctxt, const s2_connection_t* dst, con * * \returns 1 on success, 0 on failure */ -uint8_t S2_send_data_singlecast_with_keyset(struct S2* ctxt, - s2_connection_t* connection, +uint8_t S2_send_data_singlecast_with_keyset(struct S2 *ctxt, + s2_connection_t *connection, zwave_s2_keyset_t keyset, - const uint8_t* payload, + const uint8_t *payload, uint16_t payload_length); /** @@ -269,13 +270,12 @@ uint8_t S2_send_data_singlecast_with_keyset(struct S2* ctxt, * * \returns 1 on success, 0 on failure */ -uint8_t S2_send_data_multicast_with_keyset(struct S2* ctxt, - s2_connection_t* connection, +uint8_t S2_send_data_multicast_with_keyset(struct S2 *ctxt, + s2_connection_t *connection, zwave_s2_keyset_t keyset, - const uint8_t* payload, + const uint8_t *payload, uint16_t payload_length); - /** * Send a singlecast follow-up frame where we selected the MGRP ID. * @@ -288,12 +288,12 @@ uint8_t S2_send_data_multicast_with_keyset(struct S2* ctxt, * * \returns 1 on success, 0 on failure */ -uint8_t S2_send_data_singlecast_follow_up_with_keyset( - struct S2* p_context, - s2_connection_t* connection, - zwave_s2_keyset_t keyset, - const uint8_t* payload, - uint16_t payload_length); +uint8_t + S2_send_data_singlecast_follow_up_with_keyset(struct S2 *p_context, + s2_connection_t *connection, + zwave_s2_keyset_t keyset, + const uint8_t *payload, + uint16_t payload_length); /** * Check if S2 is ready to receive a new multicast frame for transmission @@ -302,7 +302,7 @@ uint8_t S2_send_data_singlecast_follow_up_with_keyset( * \param[in] ctxt The S2 context * \return False if the S2_send_data_multicast method will accept a new frame for transmission */ -uint8_t S2_is_send_data_multicast_busy(struct S2* ctxt); +uint8_t S2_is_send_data_multicast_busy(struct S2 *ctxt); /** * Allocates and Initializes a context. This must be done on every power up, or when the homeID changes. @@ -316,16 +316,14 @@ uint8_t S2_is_send_data_multicast_busy(struct S2* ctxt); * \callgraph */ -struct S2* -S2_init_ctx(uint32_t home); - +struct S2 *S2_init_ctx(uint32_t home); /** * Free's resources associated with context, the context will be invalid after a call to this function * * \param ctxt the S2 context */ -void S2_destroy(struct S2* ctxt); +void S2_destroy(struct S2 *ctxt); /** * Command handler for all incoming COMMAND_CLASS_SECURITY2 frames. @@ -334,13 +332,16 @@ void S2_destroy(struct S2* ctxt); * \param buf pointing to the received data. The S2 machine may alter the data in this buffer. * \param len The length of the received data. */ -void S2_application_command_handler(struct S2* ctxt, s2_connection_t* peer , uint8_t* buf, uint16_t len); +void S2_application_command_handler(struct S2 *ctxt, + s2_connection_t *peer, + uint8_t *buf, + uint16_t len); /** * This must be called when the timer set by \ref S2_set_timeout has expired. * \param ctxt the S2 context */ -void S2_timeout_notify(struct S2* ctxt); +void S2_timeout_notify(struct S2 *ctxt); /** * Notify the security stack that sent with \ref S2_send_frame has completed. @@ -348,7 +349,9 @@ void S2_timeout_notify(struct S2* ctxt); * \param status status code of the transmission * \param tx_time the time used for this transmission i milliseconds. */ -void S2_send_frame_done_notify(struct S2* ctxt, s2_tx_status_t status,uint16_t tx_time); +void S2_send_frame_done_notify(struct S2 *ctxt, + s2_tx_status_t status, + uint16_t tx_time); /** * Check if the S2 FSM or inclusion FSM are busy. @@ -356,7 +359,7 @@ void S2_send_frame_done_notify(struct S2* ctxt, s2_tx_status_t status,uint16_t t * \param ctxt the S2 context * \return False if the FSM and inclusion FSM are both idle */ -uint8_t S2_is_busy(struct S2* ctxt); +uint8_t S2_is_busy(struct S2 *ctxt); /** * Free an MPAN entry. @@ -370,7 +373,7 @@ uint8_t S2_is_busy(struct S2* ctxt); * \param owner_id The Sendind NodeID for the Group ID * \param group_id The Group ID to erase. */ -void S2_free_mpan(struct S2* p_context, node_t owner_id, uint8_t group_id); +void S2_free_mpan(struct S2 *p_context, node_t owner_id, uint8_t group_id); #include "S2_external.h" #include "s2_inclusion.h" @@ -386,7 +389,6 @@ void S2_init_prng(void); */ extern CTR_DRBG_CTX s2_ctr_drbg; - /** * @} */ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2_external.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2_external.h index 06b6a77d6..12b2ea840 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2_external.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/S2_external.h @@ -27,7 +27,7 @@ * \param ctxt the S2 context * \param status The status of the S2 transmisison */ -void S2_send_done_event(struct S2* ctxt, s2_tx_status_t status); +void S2_send_done_event(struct S2 *ctxt, s2_tx_status_t status); /** * Emitted when a messages has been received and decrypted @@ -37,8 +37,10 @@ void S2_send_done_event(struct S2* ctxt, s2_tx_status_t status); * \param buf The received message * \param len The length of the received message */ -void S2_msg_received_event(struct S2* ctxt,s2_connection_t* peer , uint8_t* buf, uint16_t len); - +void S2_msg_received_event(struct S2 *ctxt, + s2_connection_t *peer, + uint8_t *buf, + uint16_t len); /** * Must be implemented elsewhere maps to ZW_SendData or ZW_SendDataBridge note that ctxt is @@ -50,8 +52,10 @@ void S2_msg_received_event(struct S2* ctxt,s2_connection_t* peer , uint8_t* buf, * \param len The length of the received message * */ -uint8_t S2_send_frame(struct S2* ctxt,const s2_connection_t* peer, uint8_t* buf, uint16_t len); - +uint8_t S2_send_frame(struct S2 *ctxt, + const s2_connection_t *peer, + uint8_t *buf, + uint16_t len); /** * Send without emitting a callback into S2 and by caching the buffer @@ -65,8 +69,10 @@ uint8_t S2_send_frame(struct S2* ctxt,const s2_connection_t* peer, uint8_t* buf, * \param len The length of the received message * */ -uint8_t S2_send_frame_no_cb(struct S2* ctxt,const s2_connection_t* peer, uint8_t* buf, uint16_t len); - +uint8_t S2_send_frame_no_cb(struct S2 *ctxt, + const s2_connection_t *peer, + uint8_t *buf, + uint16_t len); /** * This must send a broadcast frame. @@ -77,7 +83,10 @@ uint8_t S2_send_frame_no_cb(struct S2* ctxt,const s2_connection_t* peer, uint8_t * \param buf The received message * \param len The length of the received message */ -uint8_t S2_send_frame_multi(struct S2* ctxt,s2_connection_t* peer, uint8_t* buf, uint16_t len); +uint8_t S2_send_frame_multi(struct S2 *ctxt, + s2_connection_t *peer, + uint8_t *buf, + uint16_t len); /** * Must be implemented elsewhere maps to ZW_TimerStart. Note that this must start the same timer every time. @@ -86,14 +95,14 @@ uint8_t S2_send_frame_multi(struct S2* ctxt,s2_connection_t* peer, uint8_t* buf, * \param ctxt the S2 context * \param interval Timeout in milliseconds. */ -void S2_set_timeout(struct S2* ctxt, uint32_t interval); +void S2_set_timeout(struct S2 *ctxt, uint32_t interval); /** * @brief Stop the timer set with S2 set timeout. * * @param ctxt */ -void S2_stop_timeout(struct S2* ctxt); +void S2_stop_timeout(struct S2 *ctxt); /** * Get a number of bytes from a hardware random number generator @@ -110,8 +119,10 @@ void S2_get_hw_random(uint8_t *buf, uint8_t len); * \param cmdClasses points to the first command class * \param length the length of the command class list */ -void S2_get_commands_supported(node_t lnode, uint8_t class_id, const uint8_t ** cmdClasses, uint8_t* length); - +void S2_get_commands_supported(node_t lnode, + uint8_t class_id, + const uint8_t **cmdClasses, + uint8_t *length); /** * Notify the reception of a NLS STATE REPORT @@ -120,7 +131,10 @@ void S2_get_commands_supported(node_t lnode, uint8_t class_id, const uint8_t ** * \param nls_capability The NLS capability of the source node * \param nls_state The NLS state of the source node */ -void S2_notify_nls_state_report(node_t srcNode, uint8_t class_id, bool nls_capability, bool nls_state); +void S2_notify_nls_state_report(node_t srcNode, + uint8_t class_id, + bool nls_capability, + bool nls_state); /** * Get the NLS nodes list @@ -132,7 +146,12 @@ void S2_notify_nls_state_report(node_t srcNode, uint8_t class_id, bool nls_capab * \param nls_state out pointer to be filled by the host indicating the NLS state of the node in question * \return 0 in case of success or else in case of error */ -int8_t S2_get_nls_node_list(node_t srcNode, bool request, bool *is_last_node, uint16_t *node_id, uint8_t *granted_keys, bool *nls_state); +int8_t S2_get_nls_node_list(node_t srcNode, + bool request, + bool *is_last_node, + uint16_t *node_id, + uint8_t *granted_keys, + bool *nls_state); /** * Get the NLS node list report @@ -142,7 +161,10 @@ int8_t S2_get_nls_node_list(node_t srcNode, bool request, bool *is_last_node, ui * \param nls_state NLS state of the current node ID * \return 0 in case of success or else in case of error */ -int8_t S2_notify_nls_node_list_report(node_t srcNode, uint16_t id_of_node, uint8_t keys_node_bitmask, bool nls_state); +int8_t S2_notify_nls_node_list_report(node_t srcNode, + uint16_t id_of_node, + uint8_t keys_node_bitmask, + bool nls_state); /** * Makes time in ms available to LibS2 @@ -167,9 +189,8 @@ uint32_t clock_time(void); * */ typedef enum { - SOS_EVENT_REASON_UNANSWERED, ///< A Nonce Report with SOS=1 was received at an unexpected time and no response was sent. Application may use this information to abort Supervision Report timeout if the remote nodeid matches. -} -sos_event_reason_t; + SOS_EVENT_REASON_UNANSWERED, ///< A Nonce Report with SOS=1 was received at an unexpected time and no response was sent. Application may use this information to abort Supervision Report timeout if the remote nodeid matches. +} sos_event_reason_t; /** * Emitted when a Nonce Synchronization Event has happened. @@ -182,11 +203,10 @@ sos_event_reason_t; * \param seqno The S2 sequence number of the frame triggering the event. Useful for correlating with zniffer traces. * \param local_node The (possible virtual) nodeID of the local node. Useful for correlating with zniffer traces. */ -void S2_resynchronization_event( - node_t remote_node, - sos_event_reason_t reason, - uint8_t seqno, - node_t local_node); +void S2_resynchronization_event(node_t remote_node, + sos_event_reason_t reason, + uint8_t seqno, + node_t local_node); /** * Save NLS state stored in S2 context in device memory @@ -199,7 +219,7 @@ void S2_save_nls_state(void); * \param ctxt the S2 context * \param nls_state NLS state */ -void S2_load_nls_state(struct S2* ctxt, uint8_t nls_state); +void S2_load_nls_state(struct S2 *ctxt, uint8_t nls_state); /** * @} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes.h index e067a1131..fe60156f5 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes.h @@ -12,7 +12,6 @@ * @{ */ - // #define the macros below to 1/0 to enable/disable the mode of operation. // // CBC enables AES128 encryption in CBC-mode of operation and handles 0-padding. @@ -20,32 +19,39 @@ // The #ifndef-guard allows it to be configured before #include'ing or at compile time. #ifndef CBC - #define CBC 1 +#define CBC 1 #endif #ifndef ECB - #define ECB 1 +#define ECB 1 #endif - - #if defined(ECB) && ECB -DllExport void AES128_ECB_encrypt(uint8_t* input, const uint8_t* key, uint8_t *output); -DllExport void AES128_ECB_decrypt(uint8_t* input, const uint8_t* key, uint8_t *output); - -#endif // #if defined(ECB) && ECB +DllExport void + AES128_ECB_encrypt(uint8_t *input, const uint8_t *key, uint8_t *output); +DllExport void + AES128_ECB_decrypt(uint8_t *input, const uint8_t *key, uint8_t *output); +#endif // #if defined(ECB) && ECB #if defined(CBC) && CBC -void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); -void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); +void AES128_CBC_encrypt_buffer(uint8_t *output, + uint8_t *input, + uint32_t length, + const uint8_t *key, + const uint8_t *iv); +void AES128_CBC_decrypt_buffer(uint8_t *output, + uint8_t *input, + uint32_t length, + const uint8_t *key, + const uint8_t *iv); -#endif // #if defined(CBC) && CBC +#endif // #if defined(CBC) && CBC /** * @} */ -#endif //_AES_H_ +#endif //_AES_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes_cmac.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes_cmac.h index 3e64df5a2..9e06f0fb4 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes_cmac.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/aes_cmac.h @@ -43,7 +43,6 @@ #ifndef AES_CMAC_H_ #define AES_CMAC_H_ - #include /** @@ -51,16 +50,13 @@ * @{ */ - /** * Type defining the return values of a CMAC verification. */ -typedef enum -{ - CMAC_VALID = 0, //!< VALID - CMAC_INVALID = 1//!< INVALID -} -CMAC_VERIFY_T; +typedef enum { + CMAC_VALID = 0, //!< VALID + CMAC_INVALID = 1 //!< INVALID +} CMAC_VERIFY_T; /** * @brief Calculates an AES-CMAC from a given key, message and message length. @@ -69,11 +65,10 @@ CMAC_VERIFY_T; * @param message_length Length of the message in octets. * @param mac Pointer to an array where the calculated AES-CMAC can be stored. */ -void aes_cmac_calculate( - const uint8_t * key, - const uint8_t * message, - const uint16_t message_length, - uint8_t * mac); +void aes_cmac_calculate(const uint8_t *key, + const uint8_t *message, + const uint16_t message_length, + uint8_t *mac); /** * @brief Verifies a given AES-CMAC from a given key, message and message length. @@ -83,14 +78,13 @@ void aes_cmac_calculate( * @param mac Pointer to a MAC to verify against. * @return Returns CMAC_VALID if valid, or CMAC_INVALID if not. */ -CMAC_VERIFY_T aes_cmac_verify( - const uint8_t * key, - const uint8_t * message, - const uint16_t message_length, - const uint8_t * mac); +CMAC_VERIFY_T aes_cmac_verify(const uint8_t *key, + const uint8_t *message, + const uint16_t message_length, + const uint8_t *mac); /** * @} */ -#endif // AES_CMAC_H_ +#endif // AES_CMAC_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ccm.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ccm.h index 5dd49de5d..86a673134 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ccm.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ccm.h @@ -20,7 +20,7 @@ */ #ifdef CCM_USE_PREDEFINED_VALUES -#define KYO (2) +#define KYO (2) #define Q_DEF KYO #define N_DEF (15 - KYO) #define T_DEF (8) @@ -36,16 +36,12 @@ * \param plaintext_len Plaintext length * \return The total length of the cipher text (including MAC) */ -DllExport -uint32_t CCM_encrypt_and_auth( - const uint8_t *key, - const uint8_t *nonce, - const uint8_t *aad, - const uint32_t aad_len, - uint8_t *plain_ciphertext, - const uint16_t plaintext_len - ); - +DllExport uint32_t CCM_encrypt_and_auth(const uint8_t *key, + const uint8_t *nonce, + const uint8_t *aad, + const uint32_t aad_len, + uint8_t *plain_ciphertext, + const uint16_t plaintext_len); /** * Decrypt and authenticate received ciphertext and AAD. @@ -59,21 +55,18 @@ uint32_t CCM_encrypt_and_auth( * \param[inout] cipher_plaintext In-place buffer to decrypt ciphertext in * \param ciphertext_len length of cipher text. */ -DllExport -uint16_t CCM_decrypt_and_auth( - const uint8_t *key, - const uint8_t *nonce, - const uint8_t *aad, - const uint32_t aad_len, - uint8_t *cipher_plaintext, - const uint32_t ciphertext_len - ); +DllExport uint16_t CCM_decrypt_and_auth(const uint8_t *key, + const uint8_t *nonce, + const uint8_t *aad, + const uint32_t aad_len, + uint8_t *cipher_plaintext, + const uint32_t ciphertext_len); #ifndef CCM_USE_PREDEFINED_VALUES void set_q_n_t(uint8_t q_in, uint8_t n_in, uint8_t t_in); #endif -void get_q_n_t(uint8_t * q_out, uint8_t * n_out, uint8_t * t_out); -void get_q(uint8_t * q_out); +void get_q_n_t(uint8_t *q_out, uint8_t *n_out, uint8_t *t_out); +void get_q(uint8_t *q_out); /** * @} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ctr_drbg.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ctr_drbg.h index b5dad7e9a..80e902ef9 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ctr_drbg.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/ctr_drbg.h @@ -3,16 +3,15 @@ #ifndef CTR_DRBH_H #define CTR_DRBH_H -#include +#include /** * \ingroup crypto * @{ */ - -#define OUTLEN 16 -#define KEYLEN 16 +#define OUTLEN 16 +#define KEYLEN 16 #define SEEDLEN (OUTLEN + KEYLEN) #ifndef RANDLEN @@ -30,20 +29,18 @@ * Context for AES-128 CTR DRBG */ typedef struct _CTR_DRBG_CTX { - uint8_t df; /**< Use DF or not */ - uint8_t v[OUTLEN]; /**< Internal working state */ - uint8_t k[KEYLEN]; /**< Key working state */ + uint8_t df; /**< Use DF or not */ + uint8_t v[OUTLEN]; /**< Internal working state */ + uint8_t k[KEYLEN]; /**< Key working state */ } CTR_DRBG_CTX; - /* Generate 16 bytes of RNG output. * \param[inout] ctx The DBRG to reseed * \param[in] seed 32 bytes of reseed entropy * \return OK if reseed succeeded, FAIL otherwise. */ //void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX* ctx, uint8_t* seed, size_t size); -DllExport -void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX* ctx, uint8_t* seed); +DllExport void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX *ctx, uint8_t *seed); /* Instantiate a DRBG * \param[out] ctx The DBRG to instantiate and seed @@ -52,16 +49,15 @@ void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX* ctx, uint8_t* seed); * We don't use security strength parameters. * Returns nothing. This cannot fail because the HW RNG cannot fail. */ -DllExport -void AES_CTR_DRBG_Instantiate(CTR_DRBG_CTX* ctx, uint8_t* entropy_input,const uint8_t *personalization); +DllExport void AES_CTR_DRBG_Instantiate(CTR_DRBG_CTX *ctx, + uint8_t *entropy_input, + const uint8_t *personalization); /* Generate 64 bytes of RNG output. * \param[inout] ctx The DBRG to generate from * \param[out] rand The buffer of size RANDLEN to write random data to. By default RANDLEN is 16 bytes. */ -DllExport -void AES_CTR_DRBG_Generate(CTR_DRBG_CTX* ctx, uint8_t* rand); - +DllExport void AES_CTR_DRBG_Generate(CTR_DRBG_CTX *ctx, uint8_t *rand); /** * @} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/curve25519.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/curve25519.h index 6ee5cbd95..94508d3f2 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/curve25519.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/curve25519.h @@ -1,40 +1,32 @@ /* © 2017 Silicon Laboratories Inc. */ -#ifndef _CURVE_25519_H_ -#define _CURVE_25519_H_ - +#ifndef _CURVE_25519_H_ +#define _CURVE_25519_H_ + /** * \ingroup crypto * @{ - */ - + */ + /** * Calculate the public key corresponding to a random key. The random key is usually a random * number. Both keys are 32-byte integers. * \param[out] q The public key korresponding to n. * \param[in] n The private key. -*/ -DllExport -void crypto_scalarmult_curve25519_base( - uint8_t *q, - const uint8_t *n -); - +*/ +DllExport void crypto_scalarmult_curve25519_base(uint8_t *q, const uint8_t *n); + /** * Calculate an ECDH shared secret from a public and a private key. * \param[out] r The shared secret. * \param[in] s The private key. * \param[in] p The public key -*/ -DllExport -void crypto_scalarmult_curve25519( - uint8_t *r, - const uint8_t *s, - const uint8_t *p -); - +*/ +DllExport void + crypto_scalarmult_curve25519(uint8_t *r, const uint8_t *s, const uint8_t *p); + /** * @} - */ - -#endif /* _CURVE_25519_H_ */ + */ + +#endif /* _CURVE_25519_H_ */ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/kderiv.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/kderiv.h index 1ffc7ada1..1b5f92c5e 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/kderiv.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/kderiv.h @@ -10,7 +10,6 @@ * @{ */ - /* Input is defined by: - NetworkKey is obtained during the key exchange phase. @@ -29,14 +28,11 @@ Output is obtained by: * \param[out] nonce_pstring The 32-byte personalization string for instantiation of SPAN NextNonce functions. * \param[out] mpan_key 16 byte MPAN key. */ -DllExport -void networkkey_expand( - uint32_t key_id, - const uint8_t *network_key, - uint8_t *ccm_key, - uint8_t *nonce_pstring, - uint8_t *mpan_key - ); +DllExport void networkkey_expand(uint32_t key_id, + const uint8_t *network_key, + uint8_t *ccm_key, + uint8_t *nonce_pstring, + uint8_t *mpan_key); /** Input is defined by: @@ -46,12 +42,9 @@ void networkkey_expand( Output is obtained by: PRK = CMAC(ConstantPRK, ECDH Shared Secret | AuthTag) */ -DllExport -void tempkey_extract( - const uint8_t *const ecdh_share_secret, - const uint8_t *const auth_tag, - uint8_t *pseudo_random_keymat_output - ); +DllExport void tempkey_extract(const uint8_t *const ecdh_share_secret, + const uint8_t *const auth_tag, + uint8_t *pseudo_random_keymat_output); /* Input is defined by: @@ -66,15 +59,11 @@ void tempkey_extract( T3 = Nonce Personalization string 2, K(NONCE) = CMAC(PRK, T2 | Constant TE | Counter 0x03) T4 = MPAN Key, K(MPAN) = CMAC(PRK, T3 | Constant TE | Counter 0x04) */ -DllExport -void tempkey_expand( - uint32_t key_id, - const uint8_t *prk, - uint8_t *temp_ccm_key, - uint8_t *temp_nonce_pstring, - uint8_t *temp_mpan_key - ); - +DllExport void tempkey_expand(uint32_t key_id, + const uint8_t *prk, + uint8_t *temp_ccm_key, + uint8_t *temp_nonce_pstring, + uint8_t *temp_mpan_key); /** * @} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_extern_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_extern_mock.c index b327ec295..32e01936f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_extern_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_extern_mock.c @@ -1,163 +1,215 @@ /* © 2017 Silicon Laboratories Inc. - */ + */ /* * s2_extern_mock.c * * Created on: Aug 31, 2015 * Author: trasmussen - */ - -#include "s2_protocol.h" - -#include - -#include "S2.h" -#include "s2_protocol.h" -#include "mock_control.h" - -#define MOCK_FILE "s2_extern_mock.c" - - - -// TODO: Extend comparison of S2 struct on need to have basis. -#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_RECV_S2) do { \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT32(P_MOCK, ARGUMENT, P_RECV_S2, struct S2, my_home_id); \ - MOCK_CALL_COMPARE_STRUCT_ARRAY_LENGTH_UINT8(P_MOCK, ARGUMENT, P_RECV_S2, struct S2, sg[0].enc_key, 16); \ - } while (0) - -#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(P_MOCK, ARGUMENT, P_ACTUAL) do { \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, ARGUMENT, P_ACTUAL, s2_connection_t, l_node); \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, ARGUMENT, P_ACTUAL, s2_connection_t, r_node); \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT8(P_MOCK, ARGUMENT, P_ACTUAL, s2_connection_t, tx_options);\ - } while (0) - - + */ + +#include "s2_protocol.h" + +#include + +#include "S2.h" +#include "s2_protocol.h" +#include "mock_control.h" + +#define MOCK_FILE "s2_extern_mock.c" + +// TODO: Extend comparison of S2 struct on need to have basis. +#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_RECV_S2) \ + do { \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT32(P_MOCK, \ + ARGUMENT, \ + P_RECV_S2, \ + struct S2, \ + my_home_id); \ + MOCK_CALL_COMPARE_STRUCT_ARRAY_LENGTH_UINT8(P_MOCK, \ + ARGUMENT, \ + P_RECV_S2, \ + struct S2, \ + sg[0].enc_key, \ + 16); \ + } while (0) + +#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL) \ + do { \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + s2_connection_t, \ + l_node); \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + s2_connection_t, \ + r_node); \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT8(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + s2_connection_t, \ + tx_options); \ + } while (0) + /** * This section contains mocking of the functions that are expeted to be implemented externally of * the s2 library. - */ -void S2_send_done_event(struct S2* ctxt, s2_tx_status_t status) -{ - mock_t * p_mock; - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, ctxt, status); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); - - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG1, status); -} - -void S2_msg_received_event(struct S2* ctxt,s2_connection_t* src , uint8_t* buf, uint16_t len) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, ctxt, src, buf, len); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); - MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, src); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, p_mock->expect_arg[3].value, buf, len); -} - -uint8_t S2_send_frame(struct S2* ctxt,const s2_connection_t* conn, uint8_t* buf, uint16_t len) -{ - //printf("Sending %02x%02x%02x%02x len = %u\n", buf[0], buf[1], buf[2], buf[3], len); - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(0x01); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0x00); - - MOCK_CALL_ACTUAL(p_mock, ctxt, conn, buf, len); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); - MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, conn); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, p_mock->expect_arg[3].value, buf, len); - - MOCK_CALL_RETURN_VALUE(p_mock, uint8_t); -} - -void S2_notify_nls_state_report(node_t srcNode, uint8_t class_id, bool nls_capability, bool nls_state) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, srcNode, class_id, nls_capability, nls_state); -} - -int8_t S2_get_nls_node_list(node_t srcNode, bool request, bool *is_last_node, uint16_t *node_id, uint8_t *granted_keys, bool *nls_state) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(0); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, -1); - - MOCK_CALL_ACTUAL(p_mock, srcNode, request, is_last_node, node_id, granted_keys, nls_state); - - MOCK_CALL_RETURN_VALUE(p_mock, int8_t); -} - -int8_t S2_notify_nls_node_list_report(node_t srcNode, uint16_t id_of_node, uint8_t keys_node_bitmask, bool nls_state) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(0); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, -1); - - MOCK_CALL_ACTUAL(p_mock, srcNode, id_of_node, keys_node_bitmask, nls_state); - - MOCK_CALL_RETURN_VALUE(p_mock, int8_t); -} - -void S2_set_timeout(struct S2* ctxt, uint32_t interval) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, ctxt, interval); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); - MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG1, interval); -} - -void S2_stop_timeout(struct S2* ctxt) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, ctxt); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); -} - -void S2_get_hw_random(uint8_t *buf, uint8_t len) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, buf, len); - - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG1, len); - - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, buf, len, uint8_t); -} - - -void S2_save_nls_state(void) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + */ +void S2_send_done_event(struct S2 *ctxt, s2_tx_status_t status) +{ + mock_t *p_mock; + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, ctxt, status); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); + + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG1, status); +} + +void S2_msg_received_event(struct S2 *ctxt, + s2_connection_t *src, + uint8_t *buf, + uint16_t len) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, ctxt, src, buf, len); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); + MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, src); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, + ARG2, + p_mock->expect_arg[3].value, + buf, + len); +} + +uint8_t S2_send_frame(struct S2 *ctxt, + const s2_connection_t *conn, + uint8_t *buf, + uint16_t len) +{ + //printf("Sending %02x%02x%02x%02x len = %u\n", buf[0], buf[1], buf[2], buf[3], len); + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(0x01); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0x00); + + MOCK_CALL_ACTUAL(p_mock, ctxt, conn, buf, len); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); + MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, conn); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, + ARG2, + p_mock->expect_arg[3].value, + buf, + len); + + MOCK_CALL_RETURN_VALUE(p_mock, uint8_t); +} + +void S2_notify_nls_state_report(node_t srcNode, + uint8_t class_id, + bool nls_capability, + bool nls_state) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, srcNode, class_id, nls_capability, nls_state); +} + +int8_t S2_get_nls_node_list(node_t srcNode, + bool request, + bool *is_last_node, + uint16_t *node_id, + uint8_t *granted_keys, + bool *nls_state) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(0); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, -1); + + MOCK_CALL_ACTUAL(p_mock, + srcNode, + request, + is_last_node, + node_id, + granted_keys, + nls_state); + + MOCK_CALL_RETURN_VALUE(p_mock, int8_t); +} + +int8_t S2_notify_nls_node_list_report(node_t srcNode, + uint16_t id_of_node, + uint8_t keys_node_bitmask, + bool nls_state) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(0); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, -1); + + MOCK_CALL_ACTUAL(p_mock, srcNode, id_of_node, keys_node_bitmask, nls_state); + + MOCK_CALL_RETURN_VALUE(p_mock, int8_t); +} + +void S2_set_timeout(struct S2 *ctxt, uint32_t interval) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, ctxt, interval); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); + MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG1, interval); +} + +void S2_stop_timeout(struct S2 *ctxt) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, ctxt); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); +} + +void S2_get_hw_random(uint8_t *buf, uint8_t len) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, buf, len); + + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG1, len); + + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, buf, len, uint8_t); +} + +void S2_save_nls_state(void) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); } \ No newline at end of file diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_mock.c index 4bdd9f357..8b243275f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/s2_mock.c @@ -1,157 +1,210 @@ /* © 2017 Silicon Laboratories Inc. - */ + */ /* * s2_mock.c * * Created on: Sep 11, 2015 * Author: trasmussen - */ - -#include "s2_protocol.h" -#include - -//#include "../S2.h" -#include -#include -#include "mock_control.h" - -#define MOCK_FILE "s2_mock.c" - + */ + +#include "s2_protocol.h" +#include + +//#include "../S2.h" +#include +#include +#include "mock_control.h" + +#define MOCK_FILE "s2_mock.c" + /** * This section contains mocking of the functions for the s2 encapsulation library. - */ -// TODO: Extend comparison of S2 struct on need to have basis. -#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_RECV_S2) do { \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT32(P_MOCK, ARGUMENT, P_RECV_S2, struct S2, my_home_id); \ - MOCK_CALL_COMPARE_STRUCT_ARRAY_LENGTH_UINT8(P_MOCK, ARGUMENT, P_RECV_S2, struct S2, sg[0].enc_key, 16); \ - } while (0) - -#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(P_MOCK, ARGUMENT, P_ACTUAL) do { \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, ARGUMENT, P_ACTUAL, s2_connection_t, l_node); \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, ARGUMENT, P_ACTUAL, s2_connection_t, r_node); \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT8(P_MOCK, ARGUMENT, P_ACTUAL, s2_connection_t, tx_options);\ - } while (0) - - -uint8_t S2_send_data(struct S2* ctx, s2_connection_t* dst ,const uint8_t* buf, uint16_t len) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(0x01); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0xFF); - MOCK_CALL_ACTUAL(p_mock, ctx, dst, buf, len); - MOCK_CALL_RETURN_IF_ERROR_SET(p_mock, uint8_t); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctx); - MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, dst); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, p_mock->expect_arg[3].value, buf, len); - - MOCK_CALL_RETURN_VALUE(p_mock, uint8_t); -} - - -void S2_send_data_abort(void) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); -} - -uint8_t S2_is_send_data_busy(struct S2* p_context) -{ - return 0; -} - -void S2_init_prng(void) -{ - -} - -struct S2* S2_init_ctx(uint32_t home) -{ - mock_t * p_mock; - static struct S2 ctx; - memset(&ctx, 0, sizeof(ctx)); - - MOCK_CALL_RETURN_IF_USED_AS_STUB(&ctx); // - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, NULL); -/* + */ +// TODO: Extend comparison of S2 struct on need to have basis. +#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_RECV_S2) \ + do { \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT32(P_MOCK, \ + ARGUMENT, \ + P_RECV_S2, \ + struct S2, \ + my_home_id); \ + MOCK_CALL_COMPARE_STRUCT_ARRAY_LENGTH_UINT8(P_MOCK, \ + ARGUMENT, \ + P_RECV_S2, \ + struct S2, \ + sg[0].enc_key, \ + 16); \ + } while (0) + +#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL) \ + do { \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + s2_connection_t, \ + l_node); \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + s2_connection_t, \ + r_node); \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT8(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + s2_connection_t, \ + tx_options); \ + } while (0) + +uint8_t S2_send_data(struct S2 *ctx, + s2_connection_t *dst, + const uint8_t *buf, + uint16_t len) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(0x01); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0xFF); + MOCK_CALL_ACTUAL(p_mock, ctx, dst, buf, len); + MOCK_CALL_RETURN_IF_ERROR_SET(p_mock, uint8_t); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctx); + MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, dst); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, + ARG2, + p_mock->expect_arg[3].value, + buf, + len); + + MOCK_CALL_RETURN_VALUE(p_mock, uint8_t); +} + +void S2_send_data_abort(void) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); +} + +uint8_t S2_is_send_data_busy(struct S2 *p_context) +{ + return 0; +} + +void S2_init_prng(void) {} + +struct S2 *S2_init_ctx(uint32_t home) +{ + mock_t *p_mock; + static struct S2 ctx; + memset(&ctx, 0, sizeof(ctx)); + + MOCK_CALL_RETURN_IF_USED_AS_STUB(&ctx); // + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, NULL); + /* MOCK_CALL_ACTUAL(p_mock, net_key, s2_cmd_sup_frame, s2_cmd_sup_frame_size, home); MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock->compare_rule_arg[0], p_mock->expect_arg[0].pointer, sizeof(network_key_t), - net_key, sizeof(network_key_t));*/ -/* MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock->compare_rule_arg[1], p_mock->expect_arg[1].pointer, p_mock->expect_arg[2].value, - s2_cmd_sup_frame, s2_cmd_sup_frame_size);*/ - - MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG3, home); - - MOCK_CALL_RETURN_POINTER(p_mock, struct S2*); -} - -void S2_application_command_handler(struct S2* ctx, s2_connection_t* src , uint8_t* buf, uint16_t len) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - MOCK_CALL_ACTUAL(p_mock, ctx, src, buf, len); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctx); - MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, src); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, p_mock->expect_arg[3].value, buf, len); -} - -void S2_timeout_notify(struct S2* ctxt) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - MOCK_CALL_ACTUAL(p_mock, ctxt); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); -} - -void S2_send_frame_done_notify(struct S2* ctxt, s2_tx_status_t status, uint16_t tx_time) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - MOCK_CALL_ACTUAL(p_mock, ctxt, status); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); - MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG1, status); -} -#include -uint8_t S2_network_key_update(struct S2 *ctx, uint32_t key_id, security_class_t class_id,const network_key_t net_key, uint8_t temp_key_expand, bool make_keys_persist_se) -{ - mock_t * p_mock; - -// printf("%p Netkey %x class id %i\n",ctx,net_key[0],class_id); - MOCK_CALL_RETURN_IF_USED_AS_STUB(1); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock,0); - MOCK_CALL_ACTUAL(p_mock, ctx, class_id, net_key, temp_key_expand,make_keys_persist_se); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctx); - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG1, class_id); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG2, sizeof(network_key_t), net_key, sizeof(network_key_t)); - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG3, temp_key_expand); - return 1; -} - -uint8_t S2_send_data_multicast(struct S2* p_context, const s2_connection_t* con, const uint8_t* buf, uint16_t len) -{ - return 0; -} - -uint8_t S2_is_send_data_multicast_busy(struct S2* p_context) -{ - return 0; -} - -uint8_t S2_is_busy(struct S2* p_context) -{ - return 0; -} + net_key, sizeof(network_key_t));*/ + /* MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock->compare_rule_arg[1], p_mock->expect_arg[1].pointer, p_mock->expect_arg[2].value, + s2_cmd_sup_frame, s2_cmd_sup_frame_size);*/ + + MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG3, home); + + MOCK_CALL_RETURN_POINTER(p_mock, struct S2 *); +} + +void S2_application_command_handler(struct S2 *ctx, + s2_connection_t *src, + uint8_t *buf, + uint16_t len) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + MOCK_CALL_ACTUAL(p_mock, ctx, src, buf, len); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctx); + MOCK_CALL_COMPARE_INPUT_STRUCT_S2_CONNECTION(p_mock, ARG1, src); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, + ARG2, + p_mock->expect_arg[3].value, + buf, + len); +} + +void S2_timeout_notify(struct S2 *ctxt) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + MOCK_CALL_ACTUAL(p_mock, ctxt); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); +} + +void S2_send_frame_done_notify(struct S2 *ctxt, + s2_tx_status_t status, + uint16_t tx_time) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + MOCK_CALL_ACTUAL(p_mock, ctxt, status); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); + MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG1, status); +} +#include +uint8_t S2_network_key_update(struct S2 *ctx, + uint32_t key_id, + security_class_t class_id, + const network_key_t net_key, + uint8_t temp_key_expand, + bool make_keys_persist_se) +{ + mock_t *p_mock; + + // printf("%p Netkey %x class id %i\n",ctx,net_key[0],class_id); + MOCK_CALL_RETURN_IF_USED_AS_STUB(1); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0); + MOCK_CALL_ACTUAL(p_mock, + ctx, + class_id, + net_key, + temp_key_expand, + make_keys_persist_se); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctx); + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG1, class_id); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, + ARG2, + sizeof(network_key_t), + net_key, + sizeof(network_key_t)); + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG3, temp_key_expand); + return 1; +} + +uint8_t S2_send_data_multicast(struct S2 *p_context, + const s2_connection_t *con, + const uint8_t *buf, + uint16_t len) +{ + return 0; +} + +uint8_t S2_is_send_data_multicast_busy(struct S2 *p_context) +{ + return 0; +} + +uint8_t S2_is_busy(struct S2 *p_context) +{ + return 0; +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/transport_service2_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/transport_service2_mock.c index 37e473059..95b281dfd 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/transport_service2_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/mock/transport_service2_mock.c @@ -2,20 +2,23 @@ * @file transport_service2_mock.c * @copyright 2022 Silicon Laboratories Inc. */ -#include - -void TransportService_ApplicationCommandHandler(ts_param_t* p,uint8_t *pCmd, uint8_t cmdLength) -{ - -} - -bool ZW_TransportService_Is_Sending(void) -{ - return true; -} - -bool ZW_TransportService_SendData(ts_param_t* p, const uint8_t *pData, uint16_t dataLength, - void (*completedFunc)(uint8_t txStatus, void *)) -{ - return true; -} +#include + +void TransportService_ApplicationCommandHandler(ts_param_t *p, + uint8_t *pCmd, + uint8_t cmdLength) +{} + +bool ZW_TransportService_Is_Sending(void) +{ + return true; +} + +bool ZW_TransportService_SendData(ts_param_t *p, + const uint8_t *pData, + uint16_t dataLength, + void (*completedFunc)(uint8_t txStatus, + void *)) +{ + return true; +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/nextnonce.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/nextnonce.h index 7bec4118f..d7f40f78e 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/nextnonce.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/nextnonce.h @@ -19,16 +19,17 @@ * \param[in] An 32-byte fixed length personalization string * We dont use security strength parameters. No reseeding counter. */ -DllExport -void next_nonce_instantiate(CTR_DRBG_CTX* ctx, const uint8_t* ei_sender, const uint8_t* ei_receiver , uint8_t *k_nonce); +DllExport void next_nonce_instantiate(CTR_DRBG_CTX *ctx, + const uint8_t *ei_sender, + const uint8_t *ei_receiver, + uint8_t *k_nonce); /* Generate 16 bytes of RNG output. * \param[inout] The DBRG to generate from * \param[out] The 16 byte buffer to write random data to. * \return OK if random data was generated, FAIL otherwise. */ -DllExport -int next_nonce_generate(CTR_DRBG_CTX* ctx, uint8_t* rand); +DllExport int next_nonce_generate(CTR_DRBG_CTX *ctx, uint8_t *rand); /** * @} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_classcmd.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_classcmd.h index 16828e2f3..cda32e444 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_classcmd.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_classcmd.h @@ -6,7 +6,7 @@ * Created on: Oct 16, 2015 * Author: trasmussen */ - + #ifndef _S2_CLASSCMD_H_ #define _S2_CLASSCMD_H_ @@ -38,122 +38,167 @@ //#define SECURITY_2_TRANSFER_END_PROPERTIES1_RESERVED_MASK 0xFC //#define SECURITY_2_TRANSFER_END_PROPERTIES1_RESERVED_SHIFT 0x02 -#define SECURITY_2_SCHEME_1_SUPPORT 0x02 //< Value denoting support for scheme 1 in the sheme support field. -#define SECURITY_2_SCHEME_SUPPORT_MASK 0x02 //< Mask containing all schemes. - -#define SECURITY_2_SECURITY_2_CLASS_0 0x01 //< Value denoting support/request/grant for security 2 class 0 key. -#define SECURITY_2_SECURITY_2_CLASS_1 0x02 //< Value denoting support/request/grant for security 2 class 1 key. -#define SECURITY_2_SECURITY_2_CLASS_2 0x04 //< Value denoting support/request/grant for security 2 class 2 key. -#define SECURITY_2_SECURITY_2_CLASS_3 0x08 //< Value denoting support/request/grant for security 2 class 3 (KEY_CLASS_S2_AUTHENTICATED_LR) key. -#define SECURITY_2_SECURITY_2_CLASS_4 0x10 //< Value denoting support/request/grant for security 2 class 4 (KEY_CLASS_S2_ACCESS_LR) key. -#define SECURITY_2_SECURITY_0_NETWORK_KEY 0x80 //< Value denoting support/request/grant for security 0 network key. -#define SECURITY_2_KEY_S2_MASK 0x1F //< Mask containing all S2 LR and S2 non-LR keys, but not S0 -#define SECURITY_2_KEY_MASK 0x87 //< Mask containing all non-LR keys. -#define SECURITY_2_KEY_MASK_INCL_LR 0x9F //< Mask containing all keys. - -#define KEX_REPORT_CURVE_25519 0x01 //< Value denoting curve25519 used in ECDH. -#define KEX_REPORT_CURVE_MASK 0x01 //< Mask containing all curves. -#define KEX_REPORT_CURVE_RESERVED_MASK 0xFE -#define KEX_REPORT_CURVE_RESERVED_SHIFT 0x01 - -#define SECURITY_2_ECHO_OFF 0x00 //< Value denoting that this is not an echo frame. -#define SECURITY_2_ECHO_ON 0x01 //< Value denoting that this is an echo frame. - -#define SECURITY_2_CSA_ON 0x02 //< Value denoting that csa was requested -#define SECURITY_2_NLS_AVAILABLE 0x01 //< Value denoting that NLS is Available - - -#define SECURITY_2_JOINING_NODE 0x00 //< Value denoting that this frame originates from the joining node. -#define SECURITY_2_INCLUDING_NODE 0x01 //< Value denoting that this frame originates from the including node. - -#define SECURITY_2_KEY_REQ_CONTINUE 0x00 //< Value denoting that joining node has not received all keys. -#define SECURITY_2_KEY_REQ_COMPLETE 0x01 //< Value denoting that joining node has received all requested keys. -#define SECURITY_2_KEY_VERIFIED 0x02 //< Value denoting that the verify frame could be successfully decrypted using the exchanged network key. +#define SECURITY_2_SCHEME_1_SUPPORT \ + 0x02 //< Value denoting support for scheme 1 in the sheme support field. +#define SECURITY_2_SCHEME_SUPPORT_MASK 0x02 //< Mask containing all schemes. + +#define SECURITY_2_SECURITY_2_CLASS_0 \ + 0x01 //< Value denoting support/request/grant for security 2 class 0 key. +#define SECURITY_2_SECURITY_2_CLASS_1 \ + 0x02 //< Value denoting support/request/grant for security 2 class 1 key. +#define SECURITY_2_SECURITY_2_CLASS_2 \ + 0x04 //< Value denoting support/request/grant for security 2 class 2 key. +#define SECURITY_2_SECURITY_2_CLASS_3 \ + 0x08 //< Value denoting support/request/grant for security 2 class 3 (KEY_CLASS_S2_AUTHENTICATED_LR) key. +#define SECURITY_2_SECURITY_2_CLASS_4 \ + 0x10 //< Value denoting support/request/grant for security 2 class 4 (KEY_CLASS_S2_ACCESS_LR) key. +#define SECURITY_2_SECURITY_0_NETWORK_KEY \ + 0x80 //< Value denoting support/request/grant for security 0 network key. +#define SECURITY_2_KEY_S2_MASK \ + 0x1F //< Mask containing all S2 LR and S2 non-LR keys, but not S0 +#define SECURITY_2_KEY_MASK 0x87 //< Mask containing all non-LR keys. +#define SECURITY_2_KEY_MASK_INCL_LR 0x9F //< Mask containing all keys. + +#define KEX_REPORT_CURVE_25519 0x01 //< Value denoting curve25519 used in ECDH. +#define KEX_REPORT_CURVE_MASK 0x01 //< Mask containing all curves. +#define KEX_REPORT_CURVE_RESERVED_MASK 0xFE +#define KEX_REPORT_CURVE_RESERVED_SHIFT 0x01 + +#define SECURITY_2_ECHO_OFF \ + 0x00 //< Value denoting that this is not an echo frame. +#define SECURITY_2_ECHO_ON 0x01 //< Value denoting that this is an echo frame. + +#define SECURITY_2_CSA_ON 0x02 //< Value denoting that csa was requested +#define SECURITY_2_NLS_AVAILABLE 0x01 //< Value denoting that NLS is Available + +#define SECURITY_2_JOINING_NODE \ + 0x00 //< Value denoting that this frame originates from the joining node. +#define SECURITY_2_INCLUDING_NODE \ + 0x01 //< Value denoting that this frame originates from the including node. + +#define SECURITY_2_KEY_REQ_CONTINUE \ + 0x00 //< Value denoting that joining node has not received all keys. +#define SECURITY_2_KEY_REQ_COMPLETE \ + 0x01 //< Value denoting that joining node has received all requested keys. +#define SECURITY_2_KEY_VERIFIED \ + 0x02 //< Value denoting that the verify frame could be successfully decrypted using the exchanged network key. /** Following defines are related to security 2 command class frames. */ -#define SECURITY_2_COMMAND_CLASS_POS 0 //< Position of the command class byte. -#define SECURITY_2_COMMAND_POS 1 //< Position of the command byte identifying the security 2 command. +#define SECURITY_2_COMMAND_CLASS_POS 0 //< Position of the command class byte. +#define SECURITY_2_COMMAND_POS \ + 1 //< Position of the command byte identifying the security 2 command. /** Following defines are related to the KEX Set Frame. */ -#define SECURITY_2_KEX_SET_ECHO_POS 2 //< Position of the echo field in the KEX set frame. -#define SECURITY_2_KEX_SET_CSA_POS 2 //< Position of the echo field in the KEX set frame. -#define SECURITY_2_KEX_SET_SCHEME_POS 3 //< Position of the echo field in the KEX set frame. -#define SECURITY_2_KEX_SET_CURVE_POS 4 //< Position of the echo field in the KEX set frame. -#define SECURITY_2_KEX_SET_KEYS_POS 5 //< Position of the echo field in the KEX set frame. -#define SECURITY_2_KEX_REP_ECHO_MASK 0x01 //< Mask for the echo bit in KEX_REPORT -#define SECURITY_2_KEX_REP_CSA_MASK 0x02 //< Mask for the csa support bit in KEX_REPORT -#define SECURITY_2_KEX_REP_NLS_MASK 0x04 //< Mask for the nls support bit in KEX_REPORT +#define SECURITY_2_KEX_SET_ECHO_POS \ + 2 //< Position of the echo field in the KEX set frame. +#define SECURITY_2_KEX_SET_CSA_POS \ + 2 //< Position of the echo field in the KEX set frame. +#define SECURITY_2_KEX_SET_SCHEME_POS \ + 3 //< Position of the echo field in the KEX set frame. +#define SECURITY_2_KEX_SET_CURVE_POS \ + 4 //< Position of the echo field in the KEX set frame. +#define SECURITY_2_KEX_SET_KEYS_POS \ + 5 //< Position of the echo field in the KEX set frame. +#define SECURITY_2_KEX_REP_ECHO_MASK \ + 0x01 //< Mask for the echo bit in KEX_REPORT +#define SECURITY_2_KEX_REP_CSA_MASK \ + 0x02 //< Mask for the csa support bit in KEX_REPORT +#define SECURITY_2_KEX_REP_NLS_MASK \ + 0x04 //< Mask for the nls support bit in KEX_REPORT /** Following defines are related to the KEX Report Frame. Note: The KEX Report fields are identical to the KEX Set frame. */ -#define SECURITY_2_KEX_REP_ECHO_POS SECURITY_2_KEX_SET_ECHO_POS //< Position of the echo field in the KEX report frame. -#define SECURITY_2_KEX_REP_SCHEME_POS SECURITY_2_KEX_SET_SCHEME_POS //< Position of the echo field in the KEX report frame. -#define SECURITY_2_KEX_REP_CURVE_POS SECURITY_2_KEX_SET_CURVE_POS //< Position of the echo field in the KEX report frame. -#define SECURITY_2_KEX_REP_KEYS_POS SECURITY_2_KEX_SET_KEYS_POS //< Position of the echo field in the KEX report frame. - -#define SECURITY_2_KEX_REPORT_NLS_SUPPORT_BIT_POS 2 //< Position of the NLS support bit within the echo field in the KEX report frame. +#define SECURITY_2_KEX_REP_ECHO_POS \ + SECURITY_2_KEX_SET_ECHO_POS //< Position of the echo field in the KEX report frame. +#define SECURITY_2_KEX_REP_SCHEME_POS \ + SECURITY_2_KEX_SET_SCHEME_POS //< Position of the echo field in the KEX report frame. +#define SECURITY_2_KEX_REP_CURVE_POS \ + SECURITY_2_KEX_SET_CURVE_POS //< Position of the echo field in the KEX report frame. +#define SECURITY_2_KEX_REP_KEYS_POS \ + SECURITY_2_KEX_SET_KEYS_POS //< Position of the echo field in the KEX report frame. + +#define SECURITY_2_KEX_REPORT_NLS_SUPPORT_BIT_POS \ + 2 //< Position of the NLS support bit within the echo field in the KEX report frame. /** Following defines are related to the Public Key Frame set. */ -#define SECURITY_2_PUB_KEY_INC_FLAG_POS 2 //< Position of the including node flag in the public key exchange frame. -#define SECURITY_2_PUB_KEY_KEY_POS 3 //< Position of the key in the public key exchange frame. +#define SECURITY_2_PUB_KEY_INC_FLAG_POS \ + 2 //< Position of the including node flag in the public key exchange frame. +#define SECURITY_2_PUB_KEY_KEY_POS \ + 3 //< Position of the key in the public key exchange frame. /** Following define is related to the Network Key Get Frame. */ -#define SECURITY_2_NET_KEY_GET_REQ_KEY_POS 2 //< Position of the key requested field in the network key get frame. +#define SECURITY_2_NET_KEY_GET_REQ_KEY_POS \ + 2 //< Position of the key requested field in the network key get frame. /** Following defines are related to the network key report frame. */ -#define SECURITY_2_NET_KEY_REP_GRANT_KEY_POS 2 //< Position of the key granted field in the network key report frame. -#define SECURITY_2_NET_KEY_REP_KEY_POS 3 //< Position of the key in the network key report frame. +#define SECURITY_2_NET_KEY_REP_GRANT_KEY_POS \ + 2 //< Position of the key granted field in the network key report frame. +#define SECURITY_2_NET_KEY_REP_KEY_POS \ + 3 //< Position of the key in the network key report frame. /** Following define is related to the Network Transfer End Frame. */ -#define SECURITY_2_TRANSFER_END_FLAGS_POS 2 //< Position of the flag field in the transfer end frame. +#define SECURITY_2_TRANSFER_END_FLAGS_POS \ + 2 //< Position of the flag field in the transfer end frame. /** Following define is related to the KEX Fail frame. */ -#define SECURITY_2_KEX_FAIL_FAIL_TYPE_POS 2 //< Position of the fail type field in the KEX fail frame. +#define SECURITY_2_KEX_FAIL_FAIL_TYPE_POS \ + 2 //< Position of the fail type field in the KEX fail frame. /** Following define is related to the NLS State Set frame. */ -#define SECURITY_2_V2_NLS_STATE_SET_STATE_POS 2 //< Position of the state field +#define SECURITY_2_V2_NLS_STATE_SET_STATE_POS 2 //< Position of the state field /** Following defines are related to the NLS State Report frame. */ -#define SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD 0x01 //< Field denoting NLS capability of this node -#define SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD 0x02 //< Field denoting NLS state of this node -#define SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS 2 //< Position of the bitfield - +#define SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD \ + 0x01 //< Field denoting NLS capability of this node +#define SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD \ + 0x02 //< Field denoting NLS state of this node +#define SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS \ + 2 //< Position of the bitfield /** Following define is related to the NLS Node List Get frame. */ -#define SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS 2 //< Position of the request field +#define SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS \ + 2 //< Position of the request field /** Following define are related to the NLS Node List Report frame. */ -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_FIELD 0x01 //< Field denoting if its the last node of the list -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS 2 //< Position of last node field -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS 3 //< Position of MSB byte of NodeID -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS 4 //< Position of LSB byte of NodeID -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS 5 //< Position of granted keys byte of NodeID -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS 6 //< Position of NLS state byte of NodeID +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_FIELD \ + 0x01 //< Field denoting if its the last node of the list +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS \ + 2 //< Position of last node field +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS \ + 3 //< Position of MSB byte of NodeID +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS \ + 4 //< Position of LSB byte of NodeID +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS \ + 5 //< Position of granted keys byte of NodeID +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS \ + 6 //< Position of NLS state byte of NodeID /** Length definitions */ -#define SECURITY_2_NONCE_GET_LENGTH 3 -#define SECURITY_2_KEX_GET_LENGTH 2 -#define SECURITY_2_KEX_REPORT_LENGTH 6 -#define SECURITY_2_KEX_SET_LENGTH 6 -#define SECURITY_2_PUB_KEY_LENGTH 35 -#define SECURITY_2_NET_KEY_GET_LENGTH 3 -#define SECURITY_2_NET_KEY_REPORT_LENGTH 19 -#define SECURITY_2_NET_KEY_VERIFY_LENGTH 2 -#define SECURITY_2_TRANSFER_END_LENGTH 3 -#define SECURITY_2_KEX_FAIL_LENGTH 3 -#define SECURITY_2_V2_NLS_STATE_SET_LENGTH 3 -#define SECURITY_2_V2_NLS_STATE_GET_LENGTH 2 -#define SECURITY_2_V2_NLS_STATE_REPORT_LENGTH 3 -#define SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH 3 -#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH 7 - -#define SECURITY_2_EC_PUBLIC_KEY_LENGTH 32 - -#define SECURITY_2_KEX_SET_RESERVED_MASK 0xFC //< Bitmask of the reserved bits in Kex Set -#define ZW_LR_MAX_NODE_ID 4000 -#define ZW_LR_MIN_NODE_ID 256 -#define IS_LR_NODE(nodeid) (((nodeid) >= ZW_LR_MIN_NODE_ID) && ((nodeid) <= ZW_LR_MAX_NODE_ID)) +#define SECURITY_2_NONCE_GET_LENGTH 3 +#define SECURITY_2_KEX_GET_LENGTH 2 +#define SECURITY_2_KEX_REPORT_LENGTH 6 +#define SECURITY_2_KEX_SET_LENGTH 6 +#define SECURITY_2_PUB_KEY_LENGTH 35 +#define SECURITY_2_NET_KEY_GET_LENGTH 3 +#define SECURITY_2_NET_KEY_REPORT_LENGTH 19 +#define SECURITY_2_NET_KEY_VERIFY_LENGTH 2 +#define SECURITY_2_TRANSFER_END_LENGTH 3 +#define SECURITY_2_KEX_FAIL_LENGTH 3 +#define SECURITY_2_V2_NLS_STATE_SET_LENGTH 3 +#define SECURITY_2_V2_NLS_STATE_GET_LENGTH 2 +#define SECURITY_2_V2_NLS_STATE_REPORT_LENGTH 3 +#define SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH 3 +#define SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH 7 + +#define SECURITY_2_EC_PUBLIC_KEY_LENGTH 32 + +#define SECURITY_2_KEX_SET_RESERVED_MASK \ + 0xFC //< Bitmask of the reserved bits in Kex Set +#define ZW_LR_MAX_NODE_ID 4000 +#define ZW_LR_MIN_NODE_ID 256 +#define IS_LR_NODE(nodeid) \ + (((nodeid) >= ZW_LR_MIN_NODE_ID) && ((nodeid) <= ZW_LR_MAX_NODE_ID)) /** * @} */ -#endif // _S2_CLASSCMD_H_ +#endif // _S2_CLASSCMD_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_event.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_event.h index 876c70a21..167f1c56d 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_event.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_event.h @@ -1,83 +1,84 @@ /* © 2017 Silicon Laboratories Inc. - */ + */ /* * s2_event.h * * Created on: Oct 16, 2015 * Author: trasmussen - */ - -#ifndef _S2_EVENT_H_ -#define _S2_EVENT_H_ - + */ + +#ifndef _S2_EVENT_H_ +#define _S2_EVENT_H_ + /** * \defgroup s2_event libs2 inclusion events. * * @{ - */ - -#include "S2.h" -#include "platform.h" - + */ + +#include "S2.h" +#include "platform.h" + /** * This enum contains codes for all type of S2 events. - */ -typedef enum -{ - S2_NODE_INCLUSION_INITIATED_EVENT, ///< Security 2 event, a KEX Get has been received from including node, thus indicating that Security 2 inclusion is now in progress.. - S2_NODE_INCLUSION_KEX_REPORT_EVENT, ///< Security 2 event, a node is in progress of being included to the network. This event contains the requested key set from the KEX report. This event MUST be followed by a call to \ref s2_inclusion_key_grant. - S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT, ///< Security 2 event, a node is in progress of being included to the network. This event is a request to the system to verify the challenge and progress with inclusion. This event MUST be followed by a call to \ref s2_inclusion_challenge_response. - S2_NODE_INCLUSION_COMPLETE_EVENT, ///< Security 2 event, inclusion of the node to the network has been completed. - S2_NODE_JOINING_COMPLETE_EVENT, ///< Security 2 event, the node has completed its inclusion. - S2_NODE_INCLUSION_FAILED_EVENT, ///< Security 2 event, inclusion of the node to the network has failed. See the details - S2_JOINING_COMPLETE_NEVER_STARTED_EVENT, ///< Security2 event. Bootstrapping never started and the node is non-securely included. Emitted after timing out waiting for Kex Get from including controller. -} zwave_event_codes_t; - -typedef struct{ - struct S2 * s2_handle; ///< Handle reference to the S2 structure to which this event relates. - uint8_t security_keys; ///< Security keys requested by the joining node. - uint8_t csa; ///< Client side authentication was requested - uint8_t nls_available; -}s2_node_inclusion_request_t; - -typedef struct{ - struct S2 * s2_handle; ///< Handle reference to the S2 structure to which this event relates. - uint8_t granted_keys; ///< Security keys granted earlier in inclusion process. - uint8_t dsk_length; ///< Number of missing bytes in the DSK which is requested by the protocol and must be returned with \ref s2_inclusion_challenge_response. - uint16_t length; ///< Length of public key following below. - uint8_t public_key[1]; ///< Public key, length of key is describe in length field. -}s2_node_inclusion_challenge_t; - -typedef struct{ - uint8_t exchanged_keys; ///< Keys actually given/granted by/to node -} s2_node_inclusion_complete_t; - -typedef struct{ - uint8_t kex_fail_type; -} s2_node_inclusion_fail_t; - -typedef struct -{ - s2_connection_t peer; - union { - s2_node_inclusion_request_t kex_report; - s2_node_inclusion_challenge_t challenge_req; - s2_node_inclusion_complete_t inclusion_complete; - s2_node_inclusion_fail_t inclusion_fail; - } s2_data; - -// uint16_t length; -// uint8_t buffer[1]; // Variable byte array at end to allow for different packets. How to free the memory ? -}s2_event_t; - - -typedef struct __attribute__((__packed__)) -{ - uint32_t event_type; - // The below struct is inspired from SKB in Linux. Do we need it ? - // Discussed with Anders. We should be concerned not to expose the linked list externally, but - // maybe just keep it internally so that app cannot mess up/invalidate the list. - // This also means the app must call an event_get every time we have sent a notification. + */ +typedef enum { + S2_NODE_INCLUSION_INITIATED_EVENT, ///< Security 2 event, a KEX Get has been received from including node, thus indicating that Security 2 inclusion is now in progress.. + S2_NODE_INCLUSION_KEX_REPORT_EVENT, ///< Security 2 event, a node is in progress of being included to the network. This event contains the requested key set from the KEX report. This event MUST be followed by a call to \ref s2_inclusion_key_grant. + S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT, ///< Security 2 event, a node is in progress of being included to the network. This event is a request to the system to verify the challenge and progress with inclusion. This event MUST be followed by a call to \ref s2_inclusion_challenge_response. + S2_NODE_INCLUSION_COMPLETE_EVENT, ///< Security 2 event, inclusion of the node to the network has been completed. + S2_NODE_JOINING_COMPLETE_EVENT, ///< Security 2 event, the node has completed its inclusion. + S2_NODE_INCLUSION_FAILED_EVENT, ///< Security 2 event, inclusion of the node to the network has failed. See the details + S2_JOINING_COMPLETE_NEVER_STARTED_EVENT, ///< Security2 event. Bootstrapping never started and the node is non-securely included. Emitted after timing out waiting for Kex Get from including controller. +} zwave_event_codes_t; + +typedef struct { + struct S2 * + s2_handle; ///< Handle reference to the S2 structure to which this event relates. + uint8_t security_keys; ///< Security keys requested by the joining node. + uint8_t csa; ///< Client side authentication was requested + uint8_t nls_available; +} s2_node_inclusion_request_t; + +typedef struct { + struct S2 * + s2_handle; ///< Handle reference to the S2 structure to which this event relates. + uint8_t + granted_keys; ///< Security keys granted earlier in inclusion process. + uint8_t + dsk_length; ///< Number of missing bytes in the DSK which is requested by the protocol and must be returned with \ref s2_inclusion_challenge_response. + uint16_t length; ///< Length of public key following below. + uint8_t + public_key[1]; ///< Public key, length of key is describe in length field. +} s2_node_inclusion_challenge_t; + +typedef struct { + uint8_t exchanged_keys; ///< Keys actually given/granted by/to node +} s2_node_inclusion_complete_t; + +typedef struct { + uint8_t kex_fail_type; +} s2_node_inclusion_fail_t; + +typedef struct { + s2_connection_t peer; + union { + s2_node_inclusion_request_t kex_report; + s2_node_inclusion_challenge_t challenge_req; + s2_node_inclusion_complete_t inclusion_complete; + s2_node_inclusion_fail_t inclusion_fail; + } s2_data; + + // uint16_t length; + // uint8_t buffer[1]; // Variable byte array at end to allow for different packets. How to free the memory ? +} s2_event_t; + +typedef struct __attribute__((__packed__)) { + uint32_t event_type; + // The below struct is inspired from SKB in Linux. Do we need it ? + // Discussed with Anders. We should be concerned not to expose the linked list externally, but + // maybe just keep it internally so that app cannot mess up/invalidate the list. + // This also means the app must call an event_get every time we have sent a notification. /* struct { @@ -85,18 +86,17 @@ typedef struct __attribute__((__packed__)) struct event_t * prev; uint32_t timestamp; }; - */ - union - { - s2_event_t s2_event; - }evt; - // TODO: should we put the buffer here ? - // Some events may not need a buffer, or at least a small one, in which case having the variable - // buffer at end of struct in union allow dynamic growth. - // Linux has a bit more flexibility for free form data, but in z-wave we might decide that we - // know all supported form to ensure better name checking. -} zwave_event_t; // TODO: Should this be named zwave_event_t ? - + */ + union { + s2_event_t s2_event; + } evt; + // TODO: should we put the buffer here ? + // Some events may not need a buffer, or at least a small one, in which case having the variable + // buffer at end of struct in union allow dynamic growth. + // Linux has a bit more flexibility for free form data, but in z-wave we might decide that we + // know all supported form to ensure better name checking. +} zwave_event_t; // TODO: Should this be named zwave_event_t ? + /** @brief S2 event handler. * * @details The event handler is used for notifying upper layers about events from S2 securoity layers. @@ -104,10 +104,10 @@ typedef struct __attribute__((__packed__)) * transmission reports. * * @param[in] zwave_event_t Z-Wave event identifying the event and associated data. - */ -typedef void (*s2_event_handler_t)(zwave_event_t *); - + */ +typedef void (*s2_event_handler_t)(zwave_event_t *); + /** * @} - */ -#endif // _S2_EVENT_H_ + */ +#endif // _S2_EVENT_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_inclusion.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_inclusion.h index 86b329d6c..d919889d5 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_inclusion.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_inclusion.h @@ -1,19 +1,19 @@ /* © 2017 Silicon Laboratories Inc. - */ + */ /* * s2_inclusion.h * * Created on: Aug 28, 2015 * Author: trasmussen - */ - -#ifndef _S2_INCLUSION_H_ -#define _S2_INCLUSION_H_ - -#include "S2.h" -#include "s2_event.h" -#include - + */ + +#ifndef _S2_INCLUSION_H_ +#define _S2_INCLUSION_H_ + +#include "S2.h" +#include "s2_event.h" +#include + /** * @defgroup s2incl S2 inclusion * Hooks to start the S2 inclusion state machine. This state machine will handle both @@ -160,17 +160,17 @@ * Transitions colored in red indicates that the upper layer will also be notified with an \ref s2_event_t. * * @{ - */ - + */ + /** @brief Function for setting event handler in S2 inclusion module. * * @details The @ref s2_inclusion_event_handler is used for notifying the applications of any * event related to S2 inclusion security. * * @param[in] evt_handler Event handler to which events should be sent. - */ -void s2_inclusion_set_event_handler(s2_event_handler_t evt_handler); - + */ +void s2_inclusion_set_event_handler(s2_event_handler_t evt_handler); + /** @brief This function handles the acceptance and response of the user/system supplied DSK. * * @details This function must be called as a response to the @@ -184,10 +184,13 @@ void s2_inclusion_set_event_handler(s2_event_handler_t evt_handler); * 0 = reject node from inclusion, 1 = accept inclusion of node. * @param[in] p_response Pointer to response value to the challenge, that is the first n bytes of the DSK. * @param[in] responseLength Number of bytes contained in the response to the challenge. - */ -void s2_inclusion_challenge_response(struct S2 *p_context, uint8_t include, const uint8_t* p_response, uint8_t responseLength); - -#ifdef ZW_CONTROLLER + */ +void s2_inclusion_challenge_response(struct S2 *p_context, + uint8_t include, + const uint8_t *p_response, + uint8_t responseLength); + +#ifdef ZW_CONTROLLER /** @brief This function handles the acceptance and key granting for a joining node. * * @details This function must be called as a response to the @@ -201,9 +204,12 @@ void s2_inclusion_challenge_response(struct S2 *p_context, uint8_t include, cons * 0 = reject node from inclusion, 1 = accept inclusion of node. * @param[in] csa Boolean, true is allow client side authentication. * @param[in] keys Granted keys. - */ -void s2_inclusion_key_grant(struct S2 *p_context, uint8_t include, uint8_t keys,uint8_t csa); - + */ +void s2_inclusion_key_grant(struct S2 *p_context, + uint8_t include, + uint8_t keys, + uint8_t csa); + /** @brief This function requests a controller as including node to setup a secure relationship * with a joining node. * @@ -236,10 +242,11 @@ void s2_inclusion_key_grant(struct S2 *p_context, uint8_t include, uint8_t keys, * * @param[in] p_context Pointer to the context with information of peer to include. * @param[in] p_peer The peer to include - */ -void s2_inclusion_including_start(struct S2 *p_context, const s2_connection_t * p_peer); -#endif - + */ +void s2_inclusion_including_start(struct S2 *p_context, + const s2_connection_t *p_peer); +#endif + /** @brief This function requests a controller/slave to continue a secure inclusion as joining * node. * @@ -268,15 +275,17 @@ void s2_inclusion_including_start(struct S2 *p_context, const s2_connection_t * * @param[in] p_connection Reference to including node for controllers. Set to NULL in slaves * and call S2_set_inclusion_peer() later. * @param[in] csa If true client side authentication will be used. - */ -void s2_inclusion_joining_start(struct S2 *p_context,s2_connection_t *p_connection, uint8_t csa); - + */ +void s2_inclusion_joining_start(struct S2 *p_context, + s2_connection_t *p_connection, + uint8_t csa); + /** @brief This function notifies a joining node that neighbor discovering is complete. * * @param[in] p_context Pointer to the context with information of peer to join. - */ -void s2_inclusion_neighbor_discovery_complete(struct S2 *p_context); - + */ +void s2_inclusion_neighbor_discovery_complete(struct S2 *p_context); + /** @brief This function aborts current inclusion process. * * @details On nodes supporting both Security 0 and Security 2 secure learn mode, both secure @@ -285,16 +294,15 @@ void s2_inclusion_neighbor_discovery_complete(struct S2 *p_context); * inclusion. * * @param[in] p_context Pointer to the context with information of peer to join. - */ -void s2_inclusion_abort(struct S2 *p_context); - + */ +void s2_inclusion_abort(struct S2 *p_context); + /**@brief Function for handling timeouts from the timer. * * @param[in] ctxt Structure identifying the context for current inclusion. - */ -void s2_inclusion_notify_timeout(struct S2* ctxt); - - + */ +void s2_inclusion_notify_timeout(struct S2 *ctxt); + /** Function for initializing the S2 inclusion state machine with supported schemes/curves/keys. * * @details All bit fields used in the parameter list are fully described in the SDS11274 document. @@ -321,15 +329,16 @@ void s2_inclusion_notify_timeout(struct S2* ctxt); * @retval KEX_FAIL_SCHEME If the value for schemes is invalid. * @retval KEX_FAIL_CURVES If the value for curves is invalid. * @retval KEX_FAIL_KEYS If the value for keys is invalid. - */ -uint8_t s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys_to_request); - + */ +uint8_t + s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys_to_request); + /************************************************************************************************* * Below are functions defined which is used be S2 inclusion but must be implemented (wrapped) * * outside S2 library depending on the platform for which the S2 library is being compiled. * * An example is the ZW_timer API on embedded nodes. * - *************************************************************************************************/ - + *************************************************************************************************/ + /**@brief Function to set a timeout value from the S2 inclusion handling. * * @details Must be implemented elsewhere maps to ZW_TimerStart. Note that this must start the same @@ -341,26 +350,24 @@ uint8_t s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys_to_reque * timeout of 500 ms (50 * 10 ms). * * @return handle of timer which must be used for cancellation of timer. - */ -extern uint8_t s2_inclusion_set_timeout(struct S2* ctxt, uint32_t timeout); - + */ +extern uint8_t s2_inclusion_set_timeout(struct S2 *ctxt, uint32_t timeout); + /* Stop the S2 inclusion timer * - */ -extern void s2_inclusion_stop_timeout(void); - + */ +extern void s2_inclusion_stop_timeout(void); + /** * @return the number of network keys the keystore is required to hold. * * The keystore must have storage space for the number of keys returned here. * Note: Includes the S0 key that can also be bootstrapped by libs2. - */ -uint8_t s2_get_key_count(void); - - + */ +uint8_t s2_get_key_count(void); + /** * @} - */ - -#endif // _S2_INCLUSION_H_ - + */ + +#endif // _S2_INCLUSION_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_keystore.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_keystore.h index 92ba8a65a..e82b3a20f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_keystore.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_keystore.h @@ -1,36 +1,35 @@ /* © 2017 Silicon Laboratories Inc. - */ + */ /* * s2_keystore.h * * Created on: Sep 29, 2015 * Author: trasmussen - */ - -#ifndef _S2_KEYSTORE_H_ -#define _S2_KEYSTORE_H_ - -#include -#include -#include - -#define KEY_CLASS_S0 0x80 -#define KEY_CLASS_S2_UNAUTHENTICATED 0x01 -#define KEY_CLASS_S2_AUTHENTICATED 0x02 -#define KEY_CLASS_S2_ACCESS 0x04 -#define KEY_CLASS_S2_AUTHENTICATED_LR 0x08 -#define KEY_CLASS_S2_ACCESS_LR 0x10 -#define KEY_CLASS_S2_NOT_VALID 0x60 - -#define KEY_CLASS_ALL 0xFF - + */ + +#ifndef _S2_KEYSTORE_H_ +#define _S2_KEYSTORE_H_ + +#include +#include +#include + +#define KEY_CLASS_S0 0x80 +#define KEY_CLASS_S2_UNAUTHENTICATED 0x01 +#define KEY_CLASS_S2_AUTHENTICATED 0x02 +#define KEY_CLASS_S2_ACCESS 0x04 +#define KEY_CLASS_S2_AUTHENTICATED_LR 0x08 +#define KEY_CLASS_S2_ACCESS_LR 0x10 +#define KEY_CLASS_S2_NOT_VALID 0x60 + +#define KEY_CLASS_ALL 0xFF + /* Flag used in common wrapper functions * to differentiate whether the crypto * function is PSA based or otherwise. - */ -#define ZWAVE_KEY_ID_NONE 0 - - + */ +#define ZWAVE_KEY_ID_NONE 0 + /** * \defgroup keystore S2 Keystore * @@ -40,16 +39,16 @@ * to/from non volatile memory. This functionality must be implemented outside of * libs2 * @{ - */ - + */ + /** * Fetches public Curve25519 key from persistent storage and copies it to buf * This public key must match the private key returned by \ref keystore_private_key_read. * \param[out] buf Public key - */ -void keystore_public_key_read(uint8_t *buf); - - /** + */ +void keystore_public_key_read(uint8_t *buf); + +/** * Fetches the dynamic public Curve25519 key and copies it to buf * * The dynamic public key is used for no grant and unauthenticated key exchanges, where the @@ -57,34 +56,34 @@ void keystore_public_key_read(uint8_t *buf); * It must match the private key returned by \ref keystore_dynamic_private_key_read. * NOTE: It is expected that this component can decide to return either the dynamic or the persisted public key * \param[out] buf Public key - */ -void keystore_dynamic_public_key_read(uint8_t *buf); - -#ifdef ZWAVE_PSA_SECURE_VAULT - + */ +void keystore_dynamic_public_key_read(uint8_t *buf); + +#ifdef ZWAVE_PSA_SECURE_VAULT + /** * Fetches psa keyid on the persisted Curve25519 keypair and copies it to keyid * * \param[out] keyid psa keyid on persisted keypair - */ -void keystore_keyid_read(uint32_t *keyid); - + */ +void keystore_keyid_read(uint32_t *keyid); + /** * Fetches psa keyid on the dynamic Curve25519 keypair and copies it to keyid * NOTE: It is expected that this component can decide to return either the dynamic or the persisted keypair keyid * \param[out] keyid - */ -void keystore_dynamic_keyid_read(uint32_t *keyid); - -#else - + */ +void keystore_dynamic_keyid_read(uint32_t *keyid); + +#else + /** * Fetches private Curve25519 key from persistent storage and copies it to buf * This private key must match the public key returned by \ref keystore_public_key_read. * \param[out] buf Private key - */ -void keystore_private_key_read(uint8_t *buf); - + */ +void keystore_private_key_read(uint8_t *buf); + /** * Fetches the dynamic private Curve25519 key and copies it to buf * @@ -93,11 +92,11 @@ void keystore_private_key_read(uint8_t *buf); * It must match the public key returned by \ref keystore_dynamic_public_key_read. * NOTE: It is expected that this component can decide to return either the dynamic or the persisted private key * \param[out] buf Private key - */ -void keystore_dynamic_private_key_read(uint8_t *buf); - -#endif - + */ +void keystore_dynamic_private_key_read(uint8_t *buf); + +#endif + /** * Fetches network key from NVM and copies it to buf * \param[in] keyclass Value denoting which keyclass is requested, see \ref s2_keystore.h for values. @@ -106,9 +105,9 @@ void keystore_dynamic_private_key_read(uint8_t *buf); * * \retval true If network key was successfully read from the keystore and placed in buf. * \retval false If network key could not be retrieved. - */ -bool keystore_network_key_read(uint8_t keyclass, uint8_t *buf); - + */ +bool keystore_network_key_read(uint8_t keyclass, uint8_t *buf); + /** * Writes Network key to NVM. * \return true if keyclass valid -> key written @@ -116,9 +115,9 @@ bool keystore_network_key_read(uint8_t keyclass, uint8_t *buf); * \param[in] keyclass Value denoting which keyclass is is contained in keybuf, see \ref s2_keystore.h * for key class values. * \param[in] keybuf Network key - */ -bool keystore_network_key_write(uint8_t keyclass,const uint8_t *keybuf); - + */ +bool keystore_network_key_write(uint8_t keyclass, const uint8_t *keybuf); + /** * Clears the specified keyclasses in NVM keystore * \return true if keyclass cleared @@ -130,24 +129,24 @@ bool keystore_network_key_write(uint8_t keyclass,const uint8_t *keybuf); * - KEY_CLASS_S2_ACCESS - S2_ACCESS keyclass cleared * - KEY_CLASS_S0 - S0 keyclass cleared * - KEY_CLASS_ALL - ALL keyclasses are cleared -*/ -bool keystore_network_key_clear(uint8_t keyclass); - +*/ +bool keystore_network_key_clear(uint8_t keyclass); + /** * @brief Backs up the non-scrambled network key in the NVM. * @details This function MUST be called prior to a firmware upgrade because the * key used to scramble is based on the binary in flash. This binary is likely * to change upon a firmware upgrade. - */ -void ZW_s2_keystore_backup_keys(void); - + */ +void ZW_s2_keystore_backup_keys(void); + /** * @brief Restores the scrambled network keys in the NVM. * @details This function MUST be called after a firmware upgrade. - */ -void ZW_s2_keystore_restore_keys(void); - + */ +void ZW_s2_keystore_restore_keys(void); + /** * @} - */ -#endif // _S2_KEYSTORE_H_ + */ +#endif // _S2_KEYSTORE_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_protocol.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_protocol.h index df0c62ce2..b248dd6ed 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_protocol.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_protocol.h @@ -52,8 +52,7 @@ typedef uint8_t nonce_t[16]; typedef uint8_t public_key_t[32]; -typedef enum -{ +typedef enum { SPAN_NOT_USED, SPAN_NO_SEQ, SPAN_SOS, @@ -63,8 +62,7 @@ typedef enum SPAN_NEGOTIATED } span_state_t; - -typedef enum{ +typedef enum { S2_INC_IDLE, S2_AWAITING_KEX_GET, S2_AWAITING_KEX_REPORT, @@ -86,41 +84,36 @@ typedef enum{ S2_SENDING_FINAL_TRANSFER_END, S2_ERROR_SENT, S2_INC_STATE_ANY, -}s2_inclusion_state_t; +} s2_inclusion_state_t; - -struct SPAN -{ - union - { +struct SPAN { + union { CTR_DRBG_CTX rng; uint8_t r_nonce[16]; } d; node_t lnode; node_t rnode; - uint8_t rx_seq; // sequence number of last received message - uint8_t tx_seq; // sequence number of last sent message + uint8_t rx_seq; // sequence number of last received message + uint8_t tx_seq; // sequence number of last sent message - security_class_t class_id; //The id of the security group in which this span is negotiated. + security_class_t + class_id; //The id of the security group in which this span is negotiated. span_state_t state; }; -struct MPAN -{ - node_t owner_id; //this is the node id of the node maintaining mcast group members - uint8_t group_id; //a unique id generated by the group maintainer(sender) - uint8_t inner_state[16]; //The Multicast pre-agreed nonce inner state +struct MPAN { + node_t + owner_id; //this is the node id of the node maintaining mcast group members + uint8_t group_id; //a unique id generated by the group maintainer(sender) + uint8_t inner_state[16]; //The Multicast pre-agreed nonce inner state security_class_t class_id; - enum - { - MPAN_NOT_USED, MPAN_SET, MPAN_MOS - } state; //State of this entry + enum { MPAN_NOT_USED, MPAN_SET, MPAN_MOS } state; //State of this entry }; struct MOS_LIST { - node_t node_id; //node_id if reserved to "not used" + node_t node_id; //node_id if reserved to "not used" uint8_t group_id; }; @@ -130,14 +123,14 @@ typedef enum { SENDING_MSG, SENDING_MULTICAST, VERIFYING_DELIVERY, - IS_MOS_WAIT_REPLY, //Wait for reply from application layer... + IS_MOS_WAIT_REPLY, //Wait for reply from application layer... } states_t; typedef struct { const s2_connection_t *con; union { struct { - const uint8_t* buffer; + const uint8_t *buffer; uint16_t len; } buf; struct { @@ -162,26 +155,26 @@ typedef enum { } event_t; typedef enum { - AUTH_OK, - PARSE_FAIL, - AUTH_FAIL, - SEQUENCE_FAIL, + AUTH_OK, + PARSE_FAIL, + AUTH_FAIL, + SEQUENCE_FAIL, } decrypt_return_code_t; //#define S2_MULTICAST -struct S2 -{ +struct S2 { struct sec_group { - network_key_t enc_key; //Ke 16 bytes - network_key_t mpan_key; //Ke 16 bytes - uint8_t nonce_key[32]; //Knonce 32 bytes + network_key_t enc_key; //Ke 16 bytes + network_key_t mpan_key; //Ke 16 bytes + uint8_t nonce_key[32]; //Knonce 32 bytes } sg[N_SEC_CLASS]; uint8_t csa_support; uint8_t kex_set_byte2; uint8_t scheme_support; uint8_t curve_support; - uint8_t key_granted; // The granted keys bitmask. Including the LR bits if bootstrapping a controller only. + uint8_t + key_granted; // The granted keys bitmask. Including the LR bits if bootstrapping a controller only. /* The key_exchange field works a little differently on joining and inclusind side. * In joining side it has a single bit being left-shifted through all positions. Each * bit corresponds to an S2 key. If that key has been granted and is @@ -189,25 +182,27 @@ struct S2 * In including side, it is a bitmask of all keys exchanged so far. * This field includes the LR key bits. */ /* TODO: Seperate key_exchange into separate variables (or union) for joining and including side*/ - uint8_t key_exchange; // Single bit rolling across bitmask of all keys to keep track of which keys have been exchanged so far. - uint8_t key_requested; // A single bit identifying the key that has been requested most recently in a Network Key Get frame. - uint8_t kex_report_keys; // The unmodified keys from the incoming Kex Report. Used for echoing back. No filtering for LR etc. - - uint8_t loaded_keys; //Bit mask of S2 keys in use + uint8_t + key_exchange; // Single bit rolling across bitmask of all keys to keep track of which keys have been exchanged so far. + uint8_t + key_requested; // A single bit identifying the key that has been requested most recently in a Network Key Get frame. + uint8_t + kex_report_keys; // The unmodified keys from the incoming Kex Report. Used for echoing back. No filtering for LR etc. + + uint8_t loaded_keys; //Bit mask of S2 keys in use uint32_t my_home_id; - const uint8_t* sec_commands_supported_frame; + const uint8_t *sec_commands_supported_frame; uint8_t sec_commands_supported_frame_size; s2_connection_t peer; s2_connection_t inclusion_peer; - const uint8_t * buf; + const uint8_t *buf; uint16_t length; - struct SPAN *span; //The current span - struct MPAN *mpan; //The current mpan - + struct SPAN *span; //The current span + struct MPAN *mpan; //The current mpan struct SPAN span_table[SPAN_TABLE_SIZE]; #ifdef S2_MULTICAST @@ -217,7 +212,7 @@ struct S2 states_t fsm; uint8_t retry; s2_inclusion_state_t inclusion_state; - enum {INCLUSION_MODE_CSA, INCLUSION_MODE_SSA} inclusion_mode; + enum { INCLUSION_MODE_CSA, INCLUSION_MODE_SSA } inclusion_mode; uint8_t kex_fail_code; uint8_t workbuf[WORKBUF_SIZE + 10 + 8 + 4]; union { @@ -235,9 +230,9 @@ struct S2 commands that are used to retransmit the frames that cannot be sent due to the S2 state machine not being IDLE. */ struct { - uint8_t send_nls_node_list_get: 1; - uint8_t send_nls_node_list_report: 1; - uint8_t reserved: 6; + uint8_t send_nls_node_list_get : 1; + uint8_t send_nls_node_list_report : 1; + uint8_t reserved : 6; } delayed_transmission_flags; /* This union stores some parameters that are associated to some NLS related @@ -251,7 +246,7 @@ struct S2 uint8_t nls_state; } nls_node_report; struct { - uint8_t request; // 0: first node, 1: next node + uint8_t request; // 0: first node, 1: next node } get_nls_node_list; } delayed_transmission_cache; #endif @@ -260,7 +255,7 @@ struct S2 }; #ifdef SINGLE_CONTEXT -#define s2_inclusion_post_event_peer(a, b) s2_inclusion_post_event(b) +#define s2_inclusion_post_event_peer(a, b) s2_inclusion_post_event(b) #endif /** @@ -282,21 +277,20 @@ void s2_inclusion_send_done(struct S2 *p_context, uint8_t status); * @param[in] p_context Structure identifying the context for current inclusion. * @param[in] src Defining the source and destination pair, where the failed decryption occured. */ -void s2_inclusion_decryption_failure(struct S2 *p_context,s2_connection_t* src); +void s2_inclusion_decryption_failure(struct S2 *p_context, + s2_connection_t *src); /** * @breif This function handles events received during secure inclusion of a node, but also check if \ref src * matches the current inclusion peer. */ -void s2_inclusion_post_event(struct S2 *p_context,s2_connection_t* src); - +void s2_inclusion_post_event(struct S2 *p_context, s2_connection_t *src); /** * Load all keys from keystore */ void s2_restore_keys(struct S2 *p_context, bool make_keys_persist_se); - /** Update the network key of a context * A context is unique to a node id, ie a bridge module will have multiple contexts. * @@ -313,7 +307,11 @@ void s2_restore_keys(struct S2 *p_context, bool make_keys_persist_se); * \param make_keys_persist_se Set to true if the key should be saved in as a persistent key. * */ -uint8_t -S2_network_key_update(struct S2 *ctxt, uint32_t key_id, security_class_t class_id, const network_key_t net_key, uint8_t temp_key_expand, bool make_keys_persist_se); +uint8_t S2_network_key_update(struct S2 *ctxt, + uint32_t key_id, + security_class_t class_id, + const network_key_t net_key, + uint8_t temp_key_expand, + bool make_keys_persist_se); #endif /* PROTOCOL_S2_PROTOCOL_H_ */ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_psa.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_psa.h index 6e4752cf1..857550af3 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_psa.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/s2_psa.h @@ -11,46 +11,45 @@ #include #include -#define ZWAVE_ECDH_SECRET_LENGTH 32 +#define ZWAVE_ECDH_SECRET_LENGTH 32 /* * \brief Key-Id range reserved for z-wave, * for storing keys persistently in secure vault */ -#define ZWAVE_PSA_KEY_ID_MIN 0x00070000 -#define ZWAVE_PSA_KEY_ID_MAX 0x0007FFFF -#define ZWAVE_PSA_KEY_ID_MARKER 0x00070012 -#define ZWAVE_NET_KEY_SPAN_INDEX 01 -#define ZWAVE_NET_KEY_MPAN_INDEX 02 +#define ZWAVE_PSA_KEY_ID_MIN 0x00070000 +#define ZWAVE_PSA_KEY_ID_MAX 0x0007FFFF +#define ZWAVE_PSA_KEY_ID_MARKER 0x00070012 +#define ZWAVE_NET_KEY_SPAN_INDEX 01 +#define ZWAVE_NET_KEY_MPAN_INDEX 02 -#define ZW_PSA_ALG_CCM 0x05500100 -#define ZW_PSA_ALG_CMAC 0x03c00200 -#define ZW_PSA_ALG_ECB_NO_PAD 0x04404400 +#define ZW_PSA_ALG_CCM 0x05500100 +#define ZW_PSA_ALG_CMAC 0x03c00200 +#define ZW_PSA_ALG_ECB_NO_PAD 0x04404400 -#define ZWAVE_PSA_AES_MAC_LENGTH 8 -#define ZWAVE_PSA_AES_NONCE_LENGTH 13 +#define ZWAVE_PSA_AES_MAC_LENGTH 8 +#define ZWAVE_PSA_AES_NONCE_LENGTH 13 /* Temporary key_ids for volatile AES keys for in-place usage */ -#define ZWAVE_CCM_TEMP_ENC_KEY_ID 3 -#define ZWAVE_CCM_TEMP_DEC_KEY_ID 4 -#define ZWAVE_ECB_TEMP_ENC_KEY_ID 5 -#define ZWAVE_CMAC_TEMP_KEY_ID 6 +#define ZWAVE_CCM_TEMP_ENC_KEY_ID 3 +#define ZWAVE_CCM_TEMP_DEC_KEY_ID 4 +#define ZWAVE_ECB_TEMP_ENC_KEY_ID 5 +#define ZWAVE_CMAC_TEMP_KEY_ID 6 /** * \brief Mapping to PSA error code types. */ typedef enum { - ZW_PSA_SUCCESS = 0, - ZW_PSA_ERROR_ALREADY_EXISTS = -139, + ZW_PSA_SUCCESS = 0, + ZW_PSA_ERROR_ALREADY_EXISTS = -139, ZW_PSA_ERROR_INVALID_SIGNATURE = -149, - ZW_PSA_STATUS_INVALID = 200 /* Refine this */ + ZW_PSA_STATUS_INVALID = 200 /* Refine this */ } zw_status_t; /** * \brief KeyType derived from network key * Used to define keyid */ -typedef enum -{ +typedef enum { ZWAVE_KEY_TYPE_SINGLE_CAST = 0x01, ZWAVE_KEY_TYPE_MULTI_CAST, ZWAVE_KEY_TYPE_NONCE @@ -59,16 +58,17 @@ typedef enum /** * \brief Convert PSA error code types to zwave error types. */ -extern zw_status_t convert_psa_to_zw_status (int psa_status); +extern zw_status_t convert_psa_to_zw_status(int psa_status); /** * \brief PSA wrapper for ecdh shared secret computation. */ -extern zw_status_t zw_compute_ecdh_shared_secret(const uint8_t *remote_public_key, - uint32_t keyid, - uint8_t *result); +extern zw_status_t zw_compute_ecdh_shared_secret( + const uint8_t *remote_public_key, uint32_t keyid, uint8_t *result); -extern zw_status_t zw_compute_inclusion_ecdh_shared_secret(const uint8_t *remote_public_key, uint8_t *result); +extern zw_status_t + zw_compute_inclusion_ecdh_shared_secret(const uint8_t *remote_public_key, + uint8_t *result); /** * \brief Convert s2 key class to key ids for accessing keys in secure vault. @@ -79,42 +79,66 @@ extern uint32_t convert_key_class_to_psa_key_id(uint8_t key_class); /** * \brief Store/import network key sent by controller, into secure vault. */ -extern zw_status_t zw_wrap_aes_key_secure_vault(uint32_t *key_id, const uint8_t *aes_key, uint32_t key_algorithm); +extern zw_status_t zw_wrap_aes_key_secure_vault(uint32_t *key_id, + const uint8_t *aes_key, + uint32_t key_algorithm); /** * \brief Export/Read key stored in secure vault. */ -extern zw_status_t zw_read_vault_network_key_aes_cmac(uint32_t key_id, uint8_t *buff, size_t buff_size, size_t *out_len); +extern zw_status_t zw_read_vault_network_key_aes_cmac(uint32_t key_id, + uint8_t *buff, + size_t buff_size, + size_t *out_len); /** * \brief PSA wrapper AES CMAC computation. */ -extern zw_status_t zw_psa_aes_cmac(uint32_t key_id, const uint8_t *input, size_t length, uint8_t *output); +extern zw_status_t zw_psa_aes_cmac(uint32_t key_id, + const uint8_t *input, + size_t length, + uint8_t *output); /** * \brief PSA wrapper for Authenticated Encryption with Associated Data (AEAD) - PSA_ALG_CCM. */ -extern zw_status_t zw_psa_aead_encrypt_ccm(uint32_t key_id, const uint8_t *nonce, size_t nonce_len, - const uint8_t *ad, size_t ad_len, const uint8_t *plain_text, - size_t plain_text_len, uint8_t *cipher_text, size_t cipher_text_len, - size_t *cipher_len); +extern zw_status_t zw_psa_aead_encrypt_ccm(uint32_t key_id, + const uint8_t *nonce, + size_t nonce_len, + const uint8_t *ad, + size_t ad_len, + const uint8_t *plain_text, + size_t plain_text_len, + uint8_t *cipher_text, + size_t cipher_text_len, + size_t *cipher_len); /** * \brief PSA wrapper for Authenticated Decryption with Associated Data (AEAD) - PSA_ALG_CCM. */ -extern zw_status_t zw_psa_aead_decrypt_ccm(uint32_t key_id, const uint8_t *nonce, size_t nonce_len, - const uint8_t *ad, size_t ad_len, const uint8_t *plain_text, - size_t plain_text_len, uint8_t *cipher_text, size_t cipher_text_len, - size_t *cipher_len); +extern zw_status_t zw_psa_aead_decrypt_ccm(uint32_t key_id, + const uint8_t *nonce, + size_t nonce_len, + const uint8_t *ad, + size_t ad_len, + const uint8_t *plain_text, + size_t plain_text_len, + uint8_t *cipher_text, + size_t cipher_text_len, + size_t *cipher_len); /** * \brief PSA wrapper for AES ECB encryption */ -extern zw_status_t zw_psa_aes_ecb_encrypt(uint32_t key_id, const uint8_t *input, uint8_t *output); +extern zw_status_t zw_psa_aes_ecb_encrypt(uint32_t key_id, + const uint8_t *input, + uint8_t *output); /** * \brief PSA wrapper for storing a key in secure vault either as peristent or volatile. */ -extern zw_status_t zw_wrap_aes_key_secure_vault_test(uint32_t *key_id, const uint8_t *aes_key, uint32_t key_algorithm); +extern zw_status_t zw_wrap_aes_key_secure_vault_test(uint32_t *key_id, + const uint8_t *aes_key, + uint32_t key_algorithm); #endif /* defined(ZWAVE_PSA_AES) */ @@ -122,14 +146,15 @@ extern zw_status_t zw_wrap_aes_key_secure_vault_test(uint32_t *key_id, const uin * \brief Mapping between key slots to PSA key ids. */ -extern uint8_t convert_keyslot_to_key_class_id (uint8_t key_slot); +extern uint8_t convert_keyslot_to_key_class_id(uint8_t key_slot); /** * \brief Mapping between derived keys (encryption/decryption CCM keys) to PSA key IDs. */ -extern uint32_t convert_keyclass_to_derived_key_id (uint32_t key_class, zwave_derived_key_type_t key_type); - +extern uint32_t + convert_keyclass_to_derived_key_id(uint32_t key_class, + zwave_derived_key_type_t key_type); /** * \brief PSA wrapper to destroy a key stored in secure vault. @@ -138,4 +163,4 @@ extern zw_status_t zw_psa_destroy_key(uint32_t key_id); extern void zw_security_error(zw_status_t error); -#endif // _S2_PSA_H_ +#endif // _S2_PSA_H_ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/transport_service2_external.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/transport_service2_external.h index 5f38ea526..6685a606a 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/transport_service2_external.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/include/transport_service2_external.h @@ -1,21 +1,20 @@ /** * @file transport_service2_external.h * @copyright 2022 Silicon Laboratories Inc. - */ -#ifndef TRANSPORT_SERVICE2_EXTERNAL_H_ -#define TRANSPORT_SERVICE2_EXTERNAL_H_ - -#include "stdbool.h" -/* Transport Sevice 2 command class version */ -#define TRANSPORT_SERVICE2_SUPPORTED_VERSION TRANSPORT_SERVICE_VERSION_V2 - -typedef struct ts_CommandHandler -{ - ts_param_t *pParam; - ZW_APPLICATION_TX_BUFFER *pCmd; - uint16_t wCmdLength; -} ts_CommandHandler_t; - + */ +#ifndef TRANSPORT_SERVICE2_EXTERNAL_H_ +#define TRANSPORT_SERVICE2_EXTERNAL_H_ + +#include "stdbool.h" +/* Transport Sevice 2 command class version */ +#define TRANSPORT_SERVICE2_SUPPORTED_VERSION TRANSPORT_SERVICE_VERSION_V2 + +typedef struct ts_CommandHandler { + ts_param_t *pParam; + ZW_APPLICATION_TX_BUFFER *pCmd; + uint16_t wCmdLength; +} ts_CommandHandler_t; + /** * \defgroup TransportService Transport service module * \{ @@ -23,9 +22,8 @@ typedef struct ts_CommandHandler * This module handles the Z-Wave Transport Service command class version 2. * The module is able handle a single TX session to a node, and able to handle * a number of RX session for some nodes. - */ - - + */ + /** * Send a large frame from srcNodeID to dstNodeID using TRANSPORT_SERVICE V2. Only one * transmit session is allowed at any time. @@ -40,15 +38,21 @@ typedef struct ts_CommandHandler * - true if the transmission is started, and callback will be called when the transmission is done. * - false Transmission is not started, because another transmission is already on progress. * The callback function will not be called. - */ -#if defined(ZIPGW) || defined(EFR32ZG) || defined(ZWAVE_ON_LINUX) -bool ZW_TransportService_SendData(ts_param_t* p, const uint8_t *pData, uint16_t dataLength, - void (*completedFunc)(uint8_t txStatus, void *)); -#else -bool ZW_TransportService_SendData(ts_param_t* p, uint8_t *pData, uint16_t dataLength, - void (*completedFunc)(uint8_t txStatus, void *)); -#endif - + */ +#if defined(ZIPGW) || defined(EFR32ZG) || defined(ZWAVE_ON_LINUX) +bool ZW_TransportService_SendData(ts_param_t *p, + const uint8_t *pData, + uint16_t dataLength, + void (*completedFunc)(uint8_t txStatus, + void *)); +#else +bool ZW_TransportService_SendData(ts_param_t *p, + uint8_t *pData, + uint16_t dataLength, + void (*completedFunc)(uint8_t txStatus, + void *)); +#endif + /** * Input function for the transport service module, this must be called when we receive a frame * of type COMMAND_CLASS_TRANSPORT_SERVICE. @@ -57,53 +61,59 @@ bool ZW_TransportService_SendData(ts_param_t* p, uint8_t *pData, uint16_t dataLe * p structure containing the parameters of the transmission, like source node and destination node. * pCmd pointer to the received frame. * mdLength Length of the received frame. - */ -void TransportService_ApplicationCommandHandler(ts_param_t* p,uint8_t *pCmd, uint8_t cmdLength); - + */ +void TransportService_ApplicationCommandHandler(ts_param_t *p, + uint8_t *pCmd, + uint8_t cmdLength); + /** * Abort the current transmission, and cause the callback of \ref ZW_TransportService_SendData to * be sent as soon as possible. * \note the transmission is not aborted immediately. - */ -void ZW_TransportService_SendDataAbort(); - + */ +void ZW_TransportService_SendDataAbort(); + /** * Initialize the Transport service state machine. * \param commandHandler Application command handler to be called when a full datagram has been received. * - */ -void -ZW_TransportService_Init(void (*commandHandler)(ts_param_t* p, ZW_APPLICATION_TX_BUFFER *pCmd, -uint16_t cmdLength)); - + */ +void ZW_TransportService_Init(void (*commandHandler)( + ts_param_t *p, ZW_APPLICATION_TX_BUFFER *pCmd, uint16_t cmdLength)); + /** * Return true if at least one RX session is in progress. - */ -bool ZW_TransportService_Is_Receving(); - - + */ +bool ZW_TransportService_Is_Receving(); + /** * Return true if a TX session is in progress. - */ -bool ZW_TransportService_Is_Sending(); - - + */ +bool ZW_TransportService_Is_Sending(); + /** * Output function of the Transport Service module. * This function is called whenever a message has been reassembled and is ready for processing * at the client layer. - */ -void TransportService_msg_received_event(unsigned char *pCmd, unsigned char cmdLen, unsigned char srcNode); - + */ +void TransportService_msg_received_event(unsigned char *pCmd, + unsigned char cmdLen, + unsigned char srcNode); + /** * \} - */ - -#if (defined (EFR32ZG) || defined(ZWAVE_ON_LINUX)) && !defined(NEW_TEST_T2) + */ + +#if (defined(EFR32ZG) || defined(ZWAVE_ON_LINUX)) && !defined(NEW_TEST_T2) /** * Sending function called by the transport service module when a frame is ready to be sent by the lower layer. - */ -bool TS_SendRaw(uint16_t dst, uint8_t *buf, uint8_t buflen, uint8_t txopt, VOID_CALLBACKFUNC(cb)(unsigned char status, TX_STATUS_TYPE* txS)); -#endif - -#endif /* TRANSPORT_SERVICE2_EXTERNAL_H_ */ + */ +bool TS_SendRaw(uint16_t dst, + uint8_t *buf, + uint8_t buflen, + uint8_t txopt, + VOID_CALLBACKFUNC(cb)(unsigned char status, + TX_STATUS_TYPE *txS)); +#endif + +#endif /* TRANSPORT_SERVICE2_EXTERNAL_H_ */ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_dbg_printf.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_dbg_printf.c index 23af80858..c4256118a 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_dbg_printf.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_dbg_printf.c @@ -34,10 +34,9 @@ void S2_dbg_printf(const char *format, ...) { - va_list argptr; - - va_start(argptr, format); - vfprintf(stdout, format, argptr); - va_end(argptr); + va_list argptr; + va_start(argptr, format); + vfprintf(stdout, format, argptr); + va_end(argptr); } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_event_handler_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_event_handler_mock.c index 12aebd966..75e9bdf0f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_event_handler_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_event_handler_mock.c @@ -1,81 +1,147 @@ /* © 2015 Silicon Laboratories Inc. - */ + */ /* * s2_extern_mock.c * * Created on: Aug 31, 2015 * Author: trasmussen - */ - -#include -#include "S2.h" -#include "mock_control.h" - -#define MOCK_FILE "s2_event_handler_mock.c" - -#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_ACTUAL) do { \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, ARGUMENT, P_ACTUAL, zwave_event_t, evt.s2_event.peer.l_node); \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, ARGUMENT, P_ACTUAL, zwave_event_t, evt.s2_event.peer.r_node); \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT8(P_MOCK, ARGUMENT, P_ACTUAL, zwave_event_t, evt.s2_event.peer.tx_options);\ - } while (0) - - + */ + +#include +#include "S2.h" +#include "mock_control.h" + +#define MOCK_FILE "s2_event_handler_mock.c" + +#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_ACTUAL) \ + do { \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + zwave_event_t, \ + evt.s2_event.peer.l_node); \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT16(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + zwave_event_t, \ + evt.s2_event.peer.r_node); \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT8(P_MOCK, \ + ARGUMENT, \ + P_ACTUAL, \ + zwave_event_t, \ + evt.s2_event.peer.tx_options); \ + } while (0) + /** * This section contains mocking of the functions that are expeted to be implemented externally of * the s2 library. - */ -void s2_event_handler(zwave_event_t *p_actual_evt) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, p_actual_evt); - - if (p_mock->compare_rule_arg[0] == COMPARE_STRICT) - { - TEST_ASSERT_EQUAL_UINT32(((zwave_event_t *)p_mock->expect_arg[0].pointer)->event_type, p_actual_evt->event_type); - - //MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, p_actual_evt); // TODO: Forcing COMPARE_ANY for temporary development. - - switch (((zwave_event_t *)p_mock->expect_arg[0].pointer)->event_type) - { - case S2_NODE_INCLUSION_KEX_REPORT_EVENT: - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.kex_report.security_keys, UINT8); - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.kex_report.csa, UINT8); - break; - - case S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT: - MOCK_CALL_COMPARE_STRUCT_ARRAY_UINT8(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.challenge_req.public_key, evt.s2_event.s2_data.challenge_req.length); - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.challenge_req.granted_keys, UINT8); - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.challenge_req.dsk_length, UINT8); - break; - - case S2_NODE_INCLUSION_COMPLETE_EVENT: - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.inclusion_complete.exchanged_keys, UINT8); - break; - - case S2_NODE_JOINING_COMPLETE_EVENT: - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.inclusion_complete.exchanged_keys, UINT8); - break; - - case S2_JOINING_COMPLETE_NEVER_STARTED_EVENT: - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.inclusion_complete.exchanged_keys, UINT8); - break; - - case S2_NODE_INCLUSION_FAILED_EVENT: - MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, ARG0, p_actual_evt, zwave_event_t, evt.s2_event.s2_data.inclusion_fail.kex_fail_type, UINT8); - break; - - case S2_NODE_INCLUSION_INITIATED_EVENT: - // Event type match already done, no further data to verify on this event. - break; - - default: - TEST_FAIL_MESSAGE("Unsupported event type expected on this mock in " TO_STR_MACRO(__FILE__) ":" TO_STR_MACRO(__LINE__)); - break; - } - - } -} + */ +void s2_event_handler(zwave_event_t *p_actual_evt) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, p_actual_evt); + + if (p_mock->compare_rule_arg[0] == COMPARE_STRICT) { + TEST_ASSERT_EQUAL_UINT32( + ((zwave_event_t *)p_mock->expect_arg[0].pointer)->event_type, + p_actual_evt->event_type); + + //MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, p_actual_evt); // TODO: Forcing COMPARE_ANY for temporary development. + + switch (((zwave_event_t *)p_mock->expect_arg[0].pointer)->event_type) { + case S2_NODE_INCLUSION_KEX_REPORT_EVENT: + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.kex_report.security_keys, + UINT8); + MOCK_CALL_COMPARE_STRUCT_MEMBER(p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.kex_report.csa, + UINT8); + break; + + case S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT: + MOCK_CALL_COMPARE_STRUCT_ARRAY_UINT8( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.challenge_req.public_key, + evt.s2_event.s2_data.challenge_req.length); + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.challenge_req.granted_keys, + UINT8); + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.challenge_req.dsk_length, + UINT8); + break; + + case S2_NODE_INCLUSION_COMPLETE_EVENT: + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.inclusion_complete.exchanged_keys, + UINT8); + break; + + case S2_NODE_JOINING_COMPLETE_EVENT: + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.inclusion_complete.exchanged_keys, + UINT8); + break; + + case S2_JOINING_COMPLETE_NEVER_STARTED_EVENT: + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.inclusion_complete.exchanged_keys, + UINT8); + break; + + case S2_NODE_INCLUSION_FAILED_EVENT: + MOCK_CALL_COMPARE_STRUCT_MEMBER( + p_mock, + ARG0, + p_actual_evt, + zwave_event_t, + evt.s2_event.s2_data.inclusion_fail.kex_fail_type, + UINT8); + break; + + case S2_NODE_INCLUSION_INITIATED_EVENT: + // Event type match already done, no further data to verify on this event. + break; + + default: + TEST_FAIL_MESSAGE( + "Unsupported event type expected on this mock in " TO_STR_MACRO( + __FILE__) ":" TO_STR_MACRO(__LINE__)); + break; + } + } +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_extern_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_extern_mock.c index e402ae056..ba4152e6c 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_extern_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_extern_mock.c @@ -1,45 +1,54 @@ -/* © 2014 Silicon Laboratories Inc. */ +/* © 2014 Silicon Laboratories Inc. */ /* * s2_inclusion_extern_mock.c * * Created on: Sep 10, 2015 * Author: trasmussen - */ - -#include "s2_inclusion.h" - -#include -#include "s2_protocol.h" -#include "mock_control.h" - -#define MOCK_FILE "s2_inclusion_extern_mock.c" - -// TODO: Extend comparison of S2 struct on need to have basis. -#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_RECV_S2) do { \ - MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT32(P_MOCK, ARGUMENT, P_RECV_S2, struct S2, my_home_id); \ - MOCK_CALL_COMPARE_STRUCT_ARRAY_LENGTH_UINT8(P_MOCK, ARGUMENT, P_RECV_S2, struct S2, sg[0].enc_key, 16); \ - } while (0) - -uint8_t s2_inclusion_set_timeout(struct S2* ctxt, uint32_t interval) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(0x00); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0xFF); - - MOCK_CALL_ACTUAL(p_mock, ctxt, interval); - - MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); - MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG1, interval); - - MOCK_CALL_RETURN_VALUE(p_mock, uint8_t); -} - -void s2_inclusion_stop_timeout(void) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); -} - + */ + +#include "s2_inclusion.h" + +#include +#include "s2_protocol.h" +#include "mock_control.h" + +#define MOCK_FILE "s2_inclusion_extern_mock.c" + +// TODO: Extend comparison of S2 struct on need to have basis. +#define MOCK_CALL_COMPARE_INPUT_STRUCT_S2(P_MOCK, ARGUMENT, P_RECV_S2) \ + do { \ + MOCK_CALL_COMPARE_STRUCT_MEMBER_UINT32(P_MOCK, \ + ARGUMENT, \ + P_RECV_S2, \ + struct S2, \ + my_home_id); \ + MOCK_CALL_COMPARE_STRUCT_ARRAY_LENGTH_UINT8(P_MOCK, \ + ARGUMENT, \ + P_RECV_S2, \ + struct S2, \ + sg[0].enc_key, \ + 16); \ + } while (0) + +uint8_t s2_inclusion_set_timeout(struct S2 *ctxt, uint32_t interval) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(0x00); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, 0xFF); + + MOCK_CALL_ACTUAL(p_mock, ctxt, interval); + + MOCK_CALL_COMPARE_INPUT_STRUCT_S2(p_mock, ARG0, ctxt); + MOCK_CALL_COMPARE_INPUT_UINT32(p_mock, ARG1, interval); + + MOCK_CALL_RETURN_VALUE(p_mock, uint8_t); +} + +void s2_inclusion_stop_timeout(void) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_mock.c index d863ddb1a..5998fa923 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_inclusion_mock.c @@ -2,39 +2,28 @@ * @file s2_inclusion_mock.c * @copyright 2022 Silicon Laboratories Inc. */ -#include - -void s2_inclusion_challenge_response(struct S2 *p_context, uint8_t include, const uint8_t* p_response, uint8_t responseLength) -{ - -} - -void s2_inclusion_notify_timeout(struct S2 *p_context) -{ - -} - -void s2_inclusion_joining_start(struct S2 *p_context, s2_connection_t *p_connection, uint8_t csa) -{ - -} - -void s2_inclusion_abort(struct S2 *p_context) -{ - -} - -uint8_t s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys) -{ - return 1; -} - -void s2_inclusion_set_event_handler(s2_event_handler_t evt_handler) -{ - -} - -void s2_inclusion_neighbor_discovery_complete(struct S2 *p_context) -{ - -} +#include + +void s2_inclusion_challenge_response(struct S2 *p_context, + uint8_t include, + const uint8_t *p_response, + uint8_t responseLength) +{} + +void s2_inclusion_notify_timeout(struct S2 *p_context) {} + +void s2_inclusion_joining_start(struct S2 *p_context, + s2_connection_t *p_connection, + uint8_t csa) +{} + +void s2_inclusion_abort(struct S2 *p_context) {} + +uint8_t s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys) +{ + return 1; +} + +void s2_inclusion_set_event_handler(s2_event_handler_t evt_handler) {} + +void s2_inclusion_neighbor_discovery_complete(struct S2 *p_context) {} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_keystore_mock.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_keystore_mock.c index 522f377cc..dcc5d8274 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_keystore_mock.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/mock/s2_keystore_mock.c @@ -1,109 +1,108 @@ -/* © 2014 Silicon Laboratories Inc. */ +/* © 2014 Silicon Laboratories Inc. */ /* * s2_keystore_mock.c * * Created on: Sep 29, 2015 * Author: trasmussen - */ - -#include "s2_keystore.h" - -#include -#include -#include "mock_control.h" - -#define MOCK_FILE "s2_keystore_mock.c" - - -void keystore_public_key_read(uint8_t *buf) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, buf); - - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, buf, 32, uint8_t); -} - -void keystore_dynamic_public_key_read(uint8_t *buf) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, buf); - - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].p, buf, 32, uint8_t); -} - -void keystore_private_key_read(uint8_t *buf) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, buf); - - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, buf, 32, uint8_t); -} - -void keystore_dynamic_private_key_read(uint8_t *buf) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); - MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); - - MOCK_CALL_ACTUAL(p_mock, buf); - - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].p, buf, 32, uint8_t); -} - -bool keystore_network_key_read(uint8_t keyclass, uint8_t *buf) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(true); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, true); - - MOCK_CALL_ACTUAL(p_mock, keyclass, buf); - - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG0, keyclass); - - MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[1].pointer, buf, 16, uint8_t); - - MOCK_CALL_RETURN_VALUE(p_mock, bool); -} - -bool keystore_network_key_write(uint8_t keyclass,const uint8_t *buf) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(true); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, true); - - MOCK_CALL_ACTUAL(p_mock, keyclass, buf); - - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG0, keyclass); - MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG1, 16, buf, 16); - - MOCK_CALL_RETURN_VALUE(p_mock, bool); -} - -bool keystore_network_key_clear(uint8_t keyclass) -{ - mock_t * p_mock; - - MOCK_CALL_RETURN_IF_USED_AS_STUB(true); - MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, true); - - MOCK_CALL_ACTUAL(p_mock, keyclass); - - MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG0, keyclass); - - MOCK_CALL_RETURN_VALUE(p_mock, bool); -} + */ + +#include "s2_keystore.h" + +#include +#include +#include "mock_control.h" + +#define MOCK_FILE "s2_keystore_mock.c" + +void keystore_public_key_read(uint8_t *buf) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, buf); + + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, buf, 32, uint8_t); +} + +void keystore_dynamic_public_key_read(uint8_t *buf) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, buf); + + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].p, buf, 32, uint8_t); +} + +void keystore_private_key_read(uint8_t *buf) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, buf); + + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].pointer, buf, 32, uint8_t); +} + +void keystore_dynamic_private_key_read(uint8_t *buf) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_VOID_IF_USED_AS_STUB(); + MOCK_CALL_FIND_RETURN_VOID_ON_FAILURE(p_mock); + + MOCK_CALL_ACTUAL(p_mock, buf); + + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[0].p, buf, 32, uint8_t); +} + +bool keystore_network_key_read(uint8_t keyclass, uint8_t *buf) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(true); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, true); + + MOCK_CALL_ACTUAL(p_mock, keyclass, buf); + + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG0, keyclass); + + MOCK_CALL_SET_OUTPUT_ARRAY(p_mock->output_arg[1].pointer, buf, 16, uint8_t); + + MOCK_CALL_RETURN_VALUE(p_mock, bool); +} + +bool keystore_network_key_write(uint8_t keyclass, const uint8_t *buf) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(true); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, true); + + MOCK_CALL_ACTUAL(p_mock, keyclass, buf); + + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG0, keyclass); + MOCK_CALL_COMPARE_INPUT_UINT8_ARRAY(p_mock, ARG1, 16, buf, 16); + + MOCK_CALL_RETURN_VALUE(p_mock, bool); +} + +bool keystore_network_key_clear(uint8_t keyclass) +{ + mock_t *p_mock; + + MOCK_CALL_RETURN_IF_USED_AS_STUB(true); + MOCK_CALL_FIND_RETURN_ON_FAILURE(p_mock, true); + + MOCK_CALL_ACTUAL(p_mock, keyclass); + + MOCK_CALL_COMPARE_INPUT_UINT8(p_mock, ARG0, keyclass); + + MOCK_CALL_RETURN_VALUE(p_mock, bool); +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion.c index b0ad646fe..97f513a14 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion.c @@ -21,15 +21,17 @@ #include "s2_psa.h" #endif -#define CHECK_AND_FAIL(CHECK, FAILURE) if ((CHECK)){ return (FAILURE); } - +#define CHECK_AND_FAIL(CHECK, FAILURE) \ + if ((CHECK)) { \ + return (FAILURE); \ + } /** Forward declarations of transition actions to be able to define the state machine flow. * Look in bottom of file for actual implementation of actions. */ -#ifdef ZW_CONTROLLER // Those functions used during transistions are only supported by a controller. +#ifdef ZW_CONTROLLER // Those functions used during transistions are only supported by a controller. void execute_action_controller(uint8_t action); -#endif // ZW_CONTROLLER +#endif // ZW_CONTROLLER static void s2_joining_start(void); static void s2_send_kex_report(void); static void s2_send_pub_key_b(void); @@ -62,7 +64,7 @@ static void s2_inclusion_post_event_internal(struct S2 *p_context); /** Default event handler which silently will discard events in case no handler is configured. */ -static void s2_dummy_evt_handler(zwave_event_t * evt); +static void s2_dummy_evt_handler(zwave_event_t *evt); /** TODO: We should ensure the events in this enum matches the COMMANDS in COMMAND_CLASS_S2 to * make it easier to understand the flow and avoid unneccesary translation of codes. @@ -77,70 +79,169 @@ extern const size_t s2_transition_table_controller_length; #endif static const s2_transition_t s2_transition_table[] = { - {S2_INC_IDLE, S2_JOINING_START, S2_JOINING_START_ACTION, S2_AWAITING_KEX_GET}, - {S2_AWAITING_KEX_GET, S2_DISCOVERY_COMPLETE, S2_TIMEOUT_TB1_SET_ACTION, S2_AWAITING_KEX_GET}, - {S2_AWAITING_KEX_GET, S2_KEX_GET_RECV, S2_SEND_KEX_REPORT_ACTION, S2_AWAITING_KEX_SET}, - {S2_AWAITING_KEX_GET, S2_INCLUDING_REJECT, S2_NO_ACTION, S2_INC_IDLE}, - {S2_AWAITING_KEX_GET, S2_INCLUSION_TIMEOUT, S2_JOINING_NEVER_STARTED_ACTION, S2_INC_IDLE}, - {S2_AWAITING_KEX_SET, S2_KEX_SET_RECV, S2_SEND_PUB_KEY_B_ACTION, S2_AWAITING_PUB_KEY_A}, - {S2_AWAITING_KEX_SET, S2_INCLUSION_RETRY, S2_RESEND_FRAME_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_KEX_SET, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_PUB_KEY_A, S2_PUB_KEY_RECV_A, S2_PUB_KEY_A_RECV_ACTION, S2_AWAITING_USER_A_ACCEPT}, - {S2_AWAITING_PUB_KEY_A, S2_INCLUSION_RETRY, S2_RESEND_FRAME_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_PUB_KEY_A, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_PUB_KEY_A, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_USER_A_ACCEPT, S2_INCLUDING_ACCEPT, S2_DO_ECDH_CALC_B_ACTION, S2_ECHO_KEX_SET_SENDING}, - {S2_AWAITING_USER_A_ACCEPT, S2_INCLUDING_REJECT, S2_ABORT_ACTION, S2_INC_IDLE}, - {S2_AWAITING_USER_A_ACCEPT, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_USER_A_ACCEPT, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_USER_A_ACCEPT, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_ECHO_KEX_SET_SENDING, S2_INCLUSION_SEND_FAILED, S2_NO_ACTION, S2_ECHO_KEX_SET_SENDING}, - {S2_ECHO_KEX_SET_SENDING, S2_INCLUSION_SEND_DONE, S2_NO_ACTION, S2_ECHO_KEX_SET_SENDING}, - {S2_ECHO_KEX_SET_SENDING, S2_INCLUSION_RETRY, S2_SEND_ECHO_KEX_SET_ACTION, S2_ECHO_KEX_SET_SENDING}, - {S2_ECHO_KEX_SET_SENDING, S2_ECHO_KEX_REPORT_RECV, S2_SEND_NET_KEY_GET_ACTION, S2_AWAITING_NET_KEY_REPORT}, - {S2_ECHO_KEX_SET_SENDING, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_ECHO_KEX_SET_SENDING, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_ECHO_KEX_SET_SENDING, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, - - {S2_AWAITING_NET_KEY_REPORT, S2_NET_KEY_REPORT_RECV, S2_SEND_NET_KEY_VERIFY_ACTION, S2_KEY_EXCHANGED}, - {S2_AWAITING_NET_KEY_REPORT, S2_INCLUSION_RETRY, S2_RESEND_DATA_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_REPORT, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_REPORT, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_REPORT, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_REPORT, S2_ECHO_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_REPORT, S2_NO_KEYS_GRANTED, S2_SEND_FINAL_TRANSFER_END_ACTION, S2_SENDING_FINAL_TRANSFER_END}, - - {S2_KEY_EXCHANGED, S2_TRANSFER_END_RECV, S2_SEND_NET_KEY_GET_ACTION, S2_AWAITING_NET_KEY_REPORT}, - {S2_KEY_EXCHANGED, S2_INCLUSION_RETRY, S2_RESEND_DATA_ACTION, S2_INC_STATE_ANY}, - {S2_KEY_EXCHANGED, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_KEY_EXCHANGED, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_KEY_EXCHANGED, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_KEY_EXCHANGED, S2_ECHO_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_KEY_EXCHANGED, S2_NET_KEY_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - - {S2_KEY_EXCHANGED, S2_SEND_FINAL_TRANSFER_END, S2_SEND_FINAL_TRANSFER_END_ACTION, S2_SENDING_FINAL_TRANSFER_END}, - {S2_SENDING_FINAL_TRANSFER_END, S2_INCLUSION_RETRY, S2_RESEND_DATA_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_INCLUSION_SEND_DONE, S2_JOINING_COMPLETE_ACTION, S2_INC_IDLE}, - {S2_SENDING_FINAL_TRANSFER_END, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_ECHO_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_NET_KEY_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_SEND_FINAL_TRANSFER_END, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_SENDING_FINAL_TRANSFER_END, S2_TRANSFER_END_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - - {S2_ERROR_SENT, S2_INCLUSION_SEND_DONE, S2_ABORT_ACTION, S2_INC_IDLE}, - {S2_INC_IDLE, S2_INCLUSION_TIMEOUT, S2_NO_ACTION, S2_INC_IDLE}, - {S2_INC_IDLE, S2_EVT_ANY, S2_NO_ACTION, S2_INC_IDLE}, - {S2_INC_STATE_ANY, S2_INCLUSION_TIMEOUT, S2_ABORT_ACTION, S2_INC_IDLE}, - {S2_INC_STATE_ANY, S2_INCLUSION_ERROR_SENT, S2_NO_ACTION, S2_ERROR_SENT}, - {S2_INC_STATE_ANY, S2_INCLUSION_ERROR_RECV, S2_REMOTE_ERROR_ACTION, S2_INC_IDLE}, - {S2_INC_STATE_ANY, S2_INCLUSION_ERROR, S2_ABORT_ACTION, S2_INC_IDLE}, - {S2_INC_STATE_ANY, S2_INCLUDING_DECRYPT_FAILED, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_INC_STATE_ANY, S2_INCLUSION_SEND_DONE, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_INC_STATE_ANY, S2_INCLUSION_SEND_FAILED, S2_ABORT_ACTION, S2_INC_IDLE}, - {S2_INC_STATE_ANY, S2_DISCOVERY_COMPLETE, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_INC_STATE_ANY, S2_EVT_ANY, S2_ABORT_ACTION, S2_INC_IDLE}, + {S2_INC_IDLE, S2_JOINING_START, S2_JOINING_START_ACTION, S2_AWAITING_KEX_GET}, + {S2_AWAITING_KEX_GET, + S2_DISCOVERY_COMPLETE, + S2_TIMEOUT_TB1_SET_ACTION, + S2_AWAITING_KEX_GET}, + {S2_AWAITING_KEX_GET, + S2_KEX_GET_RECV, + S2_SEND_KEX_REPORT_ACTION, + S2_AWAITING_KEX_SET}, + {S2_AWAITING_KEX_GET, S2_INCLUDING_REJECT, S2_NO_ACTION, S2_INC_IDLE}, + {S2_AWAITING_KEX_GET, + S2_INCLUSION_TIMEOUT, + S2_JOINING_NEVER_STARTED_ACTION, + S2_INC_IDLE}, + {S2_AWAITING_KEX_SET, + S2_KEX_SET_RECV, + S2_SEND_PUB_KEY_B_ACTION, + S2_AWAITING_PUB_KEY_A}, + {S2_AWAITING_KEX_SET, + S2_INCLUSION_RETRY, + S2_RESEND_FRAME_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_KEX_SET, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_PUB_KEY_A, + S2_PUB_KEY_RECV_A, + S2_PUB_KEY_A_RECV_ACTION, + S2_AWAITING_USER_A_ACCEPT}, + {S2_AWAITING_PUB_KEY_A, + S2_INCLUSION_RETRY, + S2_RESEND_FRAME_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_PUB_KEY_A, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_PUB_KEY_A, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_USER_A_ACCEPT, + S2_INCLUDING_ACCEPT, + S2_DO_ECDH_CALC_B_ACTION, + S2_ECHO_KEX_SET_SENDING}, + {S2_AWAITING_USER_A_ACCEPT, + S2_INCLUDING_REJECT, + S2_ABORT_ACTION, + S2_INC_IDLE}, + {S2_AWAITING_USER_A_ACCEPT, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_USER_A_ACCEPT, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_USER_A_ACCEPT, + S2_PUB_KEY_RECV_A, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_ECHO_KEX_SET_SENDING, + S2_INCLUSION_SEND_FAILED, + S2_NO_ACTION, + S2_ECHO_KEX_SET_SENDING}, + {S2_ECHO_KEX_SET_SENDING, + S2_INCLUSION_SEND_DONE, + S2_NO_ACTION, + S2_ECHO_KEX_SET_SENDING}, + {S2_ECHO_KEX_SET_SENDING, + S2_INCLUSION_RETRY, + S2_SEND_ECHO_KEX_SET_ACTION, + S2_ECHO_KEX_SET_SENDING}, + {S2_ECHO_KEX_SET_SENDING, + S2_ECHO_KEX_REPORT_RECV, + S2_SEND_NET_KEY_GET_ACTION, + S2_AWAITING_NET_KEY_REPORT}, + {S2_ECHO_KEX_SET_SENDING, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_ECHO_KEX_SET_SENDING, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_ECHO_KEX_SET_SENDING, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, + + {S2_AWAITING_NET_KEY_REPORT, + S2_NET_KEY_REPORT_RECV, + S2_SEND_NET_KEY_VERIFY_ACTION, + S2_KEY_EXCHANGED}, + {S2_AWAITING_NET_KEY_REPORT, + S2_INCLUSION_RETRY, + S2_RESEND_DATA_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_REPORT, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_REPORT, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_REPORT, + S2_PUB_KEY_RECV_A, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_REPORT, + S2_ECHO_KEX_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_REPORT, + S2_NO_KEYS_GRANTED, + S2_SEND_FINAL_TRANSFER_END_ACTION, + S2_SENDING_FINAL_TRANSFER_END}, + + {S2_KEY_EXCHANGED, + S2_TRANSFER_END_RECV, + S2_SEND_NET_KEY_GET_ACTION, + S2_AWAITING_NET_KEY_REPORT}, + {S2_KEY_EXCHANGED, + S2_INCLUSION_RETRY, + S2_RESEND_DATA_ACTION, + S2_INC_STATE_ANY}, + {S2_KEY_EXCHANGED, S2_KEX_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_KEY_EXCHANGED, S2_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_KEY_EXCHANGED, S2_PUB_KEY_RECV_A, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_KEY_EXCHANGED, S2_ECHO_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_KEY_EXCHANGED, S2_NET_KEY_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + + {S2_KEY_EXCHANGED, + S2_SEND_FINAL_TRANSFER_END, + S2_SEND_FINAL_TRANSFER_END_ACTION, + S2_SENDING_FINAL_TRANSFER_END}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_INCLUSION_RETRY, + S2_RESEND_DATA_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_INCLUSION_SEND_DONE, + S2_JOINING_COMPLETE_ACTION, + S2_INC_IDLE}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_KEX_GET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_KEX_SET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_PUB_KEY_RECV_A, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_ECHO_KEX_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_NET_KEY_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_SEND_FINAL_TRANSFER_END, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_SENDING_FINAL_TRANSFER_END, + S2_TRANSFER_END_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + + {S2_ERROR_SENT, S2_INCLUSION_SEND_DONE, S2_ABORT_ACTION, S2_INC_IDLE}, + {S2_INC_IDLE, S2_INCLUSION_TIMEOUT, S2_NO_ACTION, S2_INC_IDLE}, + {S2_INC_IDLE, S2_EVT_ANY, S2_NO_ACTION, S2_INC_IDLE}, + {S2_INC_STATE_ANY, S2_INCLUSION_TIMEOUT, S2_ABORT_ACTION, S2_INC_IDLE}, + {S2_INC_STATE_ANY, S2_INCLUSION_ERROR_SENT, S2_NO_ACTION, S2_ERROR_SENT}, + {S2_INC_STATE_ANY, + S2_INCLUSION_ERROR_RECV, + S2_REMOTE_ERROR_ACTION, + S2_INC_IDLE}, + {S2_INC_STATE_ANY, S2_INCLUSION_ERROR, S2_ABORT_ACTION, S2_INC_IDLE}, + {S2_INC_STATE_ANY, + S2_INCLUDING_DECRYPT_FAILED, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_INC_STATE_ANY, S2_INCLUSION_SEND_DONE, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_INC_STATE_ANY, S2_INCLUSION_SEND_FAILED, S2_ABORT_ACTION, S2_INC_IDLE}, + {S2_INC_STATE_ANY, S2_DISCOVERY_COMPLETE, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_INC_STATE_ANY, S2_EVT_ANY, S2_ABORT_ACTION, S2_INC_IDLE}, }; /** Double array containing rules for frame processing. @@ -150,24 +251,51 @@ static const s2_transition_t s2_transition_table[] = { * - Second rule is frame encryption, non-encrypted, temp key encrypted, network key encrypted. */ static const uint8_t m_frame_rules[][4] = { - {SECURITY_2_KEX_GET_LENGTH , SINGLE_RULE_SUPPORT, NON_SECURE, NON_SECURE}, // Kex get frame rules. - {SECURITY_2_KEX_REPORT_LENGTH , ECHO_SUPPORT, NON_SECURE, TEMP_KEY_SECURE}, // Kex report frame rules. - {SECURITY_2_KEX_SET_LENGTH , ECHO_SUPPORT, NON_SECURE, TEMP_KEY_SECURE}, // Kex set frame rules. - {SECURITY_2_KEX_FAIL_LENGTH , DUAL_RULE_SUPPORT, NON_SECURE, TEMP_KEY_SECURE}, // KEX_GET frame rules. - {SECURITY_2_PUB_KEY_LENGTH , SINGLE_RULE_SUPPORT, NON_SECURE, NON_SECURE}, // public key frame rules. - {SECURITY_2_NET_KEY_GET_LENGTH , SINGLE_RULE_SUPPORT, TEMP_KEY_SECURE, TEMP_KEY_SECURE}, // Network key get frame rules. - {SECURITY_2_NET_KEY_REPORT_LENGTH, SINGLE_RULE_SUPPORT, TEMP_KEY_SECURE, TEMP_KEY_SECURE}, // Network key report frame rules. - {SECURITY_2_NET_KEY_VERIFY_LENGTH, SINGLE_RULE_SUPPORT, NETWORK_KEY_SECURE, NETWORK_KEY_SECURE}, // Network key verify frame rules. - {SECURITY_2_TRANSFER_END_LENGTH , SINGLE_RULE_SUPPORT, TEMP_KEY_SECURE, TEMP_KEY_SECURE}, // Transfer end frame rules. + {SECURITY_2_KEX_GET_LENGTH, + SINGLE_RULE_SUPPORT, + NON_SECURE, + NON_SECURE}, // Kex get frame rules. + {SECURITY_2_KEX_REPORT_LENGTH, + ECHO_SUPPORT, + NON_SECURE, + TEMP_KEY_SECURE}, // Kex report frame rules. + {SECURITY_2_KEX_SET_LENGTH, + ECHO_SUPPORT, + NON_SECURE, + TEMP_KEY_SECURE}, // Kex set frame rules. + {SECURITY_2_KEX_FAIL_LENGTH, + DUAL_RULE_SUPPORT, + NON_SECURE, + TEMP_KEY_SECURE}, // KEX_GET frame rules. + {SECURITY_2_PUB_KEY_LENGTH, + SINGLE_RULE_SUPPORT, + NON_SECURE, + NON_SECURE}, // public key frame rules. + {SECURITY_2_NET_KEY_GET_LENGTH, + SINGLE_RULE_SUPPORT, + TEMP_KEY_SECURE, + TEMP_KEY_SECURE}, // Network key get frame rules. + {SECURITY_2_NET_KEY_REPORT_LENGTH, + SINGLE_RULE_SUPPORT, + TEMP_KEY_SECURE, + TEMP_KEY_SECURE}, // Network key report frame rules. + {SECURITY_2_NET_KEY_VERIFY_LENGTH, + SINGLE_RULE_SUPPORT, + NETWORK_KEY_SECURE, + NETWORK_KEY_SECURE}, // Network key verify frame rules. + {SECURITY_2_TRANSFER_END_LENGTH, + SINGLE_RULE_SUPPORT, + TEMP_KEY_SECURE, + TEMP_KEY_SECURE}, // Transfer end frame rules. }; static const uint8_t m_key_slot_pair[][2] = { - {KEY_CLASS_S2_UNAUTHENTICATED , UNAUTHENTICATED_KEY_SLOT}, - {KEY_CLASS_S2_AUTHENTICATED , AUTHENTICATED_KEY_SLOT}, - {KEY_CLASS_S2_ACCESS , ACCESS_KEY_SLOT}, + {KEY_CLASS_S2_UNAUTHENTICATED, UNAUTHENTICATED_KEY_SLOT}, + {KEY_CLASS_S2_AUTHENTICATED, AUTHENTICATED_KEY_SLOT}, + {KEY_CLASS_S2_ACCESS, ACCESS_KEY_SLOT}, #ifdef ZW_CONTROLLER {KEY_CLASS_S2_AUTHENTICATED_LR, LR_AUTHENTICATED_KEY_SLOT}, - {KEY_CLASS_S2_ACCESS_LR , LR_ACCESS_KEY_SLOT}, + {KEY_CLASS_S2_ACCESS_LR, LR_ACCESS_KEY_SLOT}, #endif }; @@ -178,23 +306,25 @@ static const uint8_t m_key_slot_pair[][2] = { */ static const uint8_t m_key_slot_key_class_pair[] = { KEY_CLASS_S2_UNAUTHENTICATED, // UNAUTHENTICATED_KEY_SLOT is class id 0 = index 0 in array. - KEY_CLASS_S2_AUTHENTICATED, // AUTHENTICATED_KEY_SLOT is class id 1 = index 1 in array. - KEY_CLASS_S2_ACCESS, // ACCESS_KEY_SLOT is class id 2 = index 2 in array. + KEY_CLASS_S2_AUTHENTICATED, // AUTHENTICATED_KEY_SLOT is class id 1 = index 1 in array. + KEY_CLASS_S2_ACCESS, // ACCESS_KEY_SLOT is class id 2 = index 2 in array. // Class id 3 is actually the LR Auth keyslot, but it identifies as "normal" Auth - KEY_CLASS_S2_AUTHENTICATED, // LR_AUTHENTICATED_KEY_SLOT is class id 3 = index 3 in array. + KEY_CLASS_S2_AUTHENTICATED, // LR_AUTHENTICATED_KEY_SLOT is class id 3 = index 3 in array. // Class id 4 is actually the LR Auth keyslot, but it identifies as "normal" Auth - KEY_CLASS_S2_ACCESS, // LR_ACCESS_KEY_SLOT is class id 4 = index 4 in array. - 0x00, // TEMP_KEY_SECURE is class id 5 = index 5 in array, which is not a valid value for network key exchange, hence 0x00. - KEY_CLASS_S0 // S0 key is class id 6 = index 6 in array. Index only used temporary to exchange S0 key + KEY_CLASS_S2_ACCESS, // LR_ACCESS_KEY_SLOT is class id 4 = index 4 in array. + 0x00, // TEMP_KEY_SECURE is class id 5 = index 5 in array, which is not a valid value for network key exchange, hence 0x00. + KEY_CLASS_S0 // S0 key is class id 6 = index 6 in array. Index only used temporary to exchange S0 key }; s2_event_handler_t m_evt_handler = s2_dummy_evt_handler; -uint32_t m_event_buffer[S2_EVT_BUFFER_SIZE]; +uint32_t m_event_buffer[S2_EVT_BUFFER_SIZE]; static uint8_t m_schemes; static uint8_t m_curves; -static uint8_t m_keys; //< Bitmask of keys this node should request when joining. +static uint8_t + m_keys; //< Bitmask of keys this node should request when joining. uint8_t shared_secret[32]; -uint8_t shared_key_mem[64]; //< Shared memory array for handling of keys/auth tag during inclusion. +uint8_t shared_key_mem + [64]; //< Shared memory array for handling of keys/auth tag during inclusion. struct S2 *mp_context; @@ -202,96 +332,94 @@ uint8_t m_retry_counter; static void execute_action(uint8_t action) { - switch (action) - { + switch (action) { case S2_REMOTE_ERROR_ACTION: remote_inclusion_failed_evt_push(); - break; + break; case S2_ABORT_ACTION: inclusion_failed_evt_push(mp_context->kex_fail_code); - break; + break; case S2_JOINING_START_ACTION: s2_joining_start(); - break; + break; case S2_TIMEOUT_TB1_SET_ACTION: s2_inclusion_stop_timeout(); s2_inclusion_set_timeout(mp_context, TB1_TIMEOUT); - break; + break; case S2_SEND_KEX_REPORT_ACTION: s2_send_kex_report(); - break; + break; case S2_SEND_PUB_KEY_B_ACTION: s2_send_pub_key_b(); - break; + break; case S2_PUB_KEY_A_RECV_ACTION: s2_pub_key_a_recv(); - break; + break; case S2_DO_ECDH_CALC_B_ACTION: s2_do_ecdh_calc_b(); - break; + break; case S2_SEND_ECHO_KEX_SET_ACTION: s2_send_echo_kex_set(); - break; + break; case S2_SEND_NET_KEY_GET_ACTION: s2_send_net_key_get(); - break; + break; case S2_SEND_NET_KEY_VERIFY_ACTION: s2_send_net_key_verify(); - break; + break; case S2_SEND_FINAL_TRANSFER_END_ACTION: s2_send_final_transfer_end(); - break; + break; case S2_JOINING_COMPLETE_ACTION: s2_joining_complete(S2_NODE_JOINING_COMPLETE_EVENT); - break; + break; case S2_JOINING_NEVER_STARTED_ACTION: s2_joining_complete(S2_JOINING_COMPLETE_NEVER_STARTED_EVENT); - break; + break; case S2_RESEND_FRAME_ACTION: s2_inclusion_send_frame(); - break; + break; case S2_RESEND_DATA_ACTION: s2_inclusion_send_data(); - break; + break; case S2_NO_ACTION: - break; + break; default: #ifdef ZW_CONTROLLER execute_action_controller(action); -#endif // ZW_CONTROLLER - break; +#endif // ZW_CONTROLLER + break; } } -static bool process_s2_inclusion_event(s2_inclusion_event_t event, const s2_transition_t * table, size_t table_length) +static bool process_s2_inclusion_event(s2_inclusion_event_t event, + const s2_transition_t *table, + size_t table_length) { - for (uint8_t i = 0; i < table_length; i++) - { - if (mp_context->inclusion_state == table[i].state || S2_INC_STATE_ANY == table[i].state) - { - if ((event == table[i].event) || (S2_EVT_ANY == table[i].event)) - { + for (uint8_t i = 0; i < table_length; i++) { + if (mp_context->inclusion_state == table[i].state + || S2_INC_STATE_ANY == table[i].state) { + if ((event == table[i].event) || (S2_EVT_ANY == table[i].event)) { // Found a match. Execute action and update state if new state is different from S2_INC_STATE_ANY. if ((S2_INC_STATE_ANY != table[i].new_state) - && (mp_context->inclusion_state != table[i].new_state)) - { + && (mp_context->inclusion_state != table[i].new_state)) { mp_context->inclusion_state = table[i].new_state; } @@ -304,27 +432,29 @@ static bool process_s2_inclusion_event(s2_inclusion_event_t event, const s2_tran return false; } -static void s2_dummy_evt_handler(__attribute__((unused)) zwave_event_t *evt) -{ -} +static void s2_dummy_evt_handler(__attribute__((unused)) zwave_event_t *evt) {} /** Member function for internal event handling. * This function is intended to be called when the event type is known, that is when a frame is * decoded or an event is triggered by a function call. */ void process_event(uint16_t evt) { - bool event_handled = false; + bool event_handled = false; s2_inclusion_event_t event = (s2_inclusion_event_t)evt; #ifdef ZW_CONTROLLER - event_handled = process_s2_inclusion_event(event, s2_transition_table_controller, s2_transition_table_controller_length); + event_handled + = process_s2_inclusion_event(event, + s2_transition_table_controller, + s2_transition_table_controller_length); #endif - if (!event_handled) - { - process_s2_inclusion_event(event, s2_transition_table, ELEM_COUNT(s2_transition_table)); + if (!event_handled) { + process_s2_inclusion_event(event, + s2_transition_table, + ELEM_COUNT(s2_transition_table)); } -// ZW_DEBs2_joining_complete, UG_SEND_BYTE(')'); + // ZW_DEBs2_joining_complete, UG_SEND_BYTE(')'); } /** Restore all keys. @@ -334,24 +464,33 @@ void process_event(uint16_t evt) * and S2_ACCESS in index 2, LR_AUTH in 3 and LR_ACCESS in 4. * This defines the API between the S2 module and the glue layer around it. * */ -void s2_restore_keys(struct S2 *p_context, __attribute__((unused)) bool make_keys_persist_se) +void s2_restore_keys(struct S2 *p_context, + __attribute__((unused)) bool make_keys_persist_se) { uint8_t i; - bool ret_val; + bool ret_val; MP_CTX_DEF mp_context->loaded_keys = 0; - for (i = 0; i < ELEM_COUNT(m_key_slot_pair); i++) - { + for (i = 0; i < ELEM_COUNT(m_key_slot_pair); i++) { ret_val = keystore_network_key_read(m_key_slot_pair[i][0], shared_key_mem); - if (true == ret_val) - { + if (true == ret_val) { #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - S2_network_key_update(mp_context, convert_key_class_to_psa_key_id(m_key_slot_pair[i][0]), - m_key_slot_pair[i][1], shared_key_mem, 0, make_keys_persist_se); + S2_network_key_update( + mp_context, + convert_key_class_to_psa_key_id(m_key_slot_pair[i][0]), + m_key_slot_pair[i][1], + shared_key_mem, + 0, + make_keys_persist_se); #else - S2_network_key_update(mp_context, ZWAVE_KEY_ID_NONE, m_key_slot_pair[i][1], shared_key_mem, 0, false); + S2_network_key_update(mp_context, + ZWAVE_KEY_ID_NONE, + m_key_slot_pair[i][1], + shared_key_mem, + 0, + false); #endif } } @@ -365,13 +504,13 @@ void s2_restore_keys(struct S2 *p_context, __attribute__((unused)) bool make_key */ void inclusion_failed_evt_push(uint8_t fail_type) { - zwave_event_t * p_s2_event = (zwave_event_t *)m_event_buffer; + zwave_event_t *p_s2_event = (zwave_event_t *)m_event_buffer; s2_inclusion_stop_timeout(); s2_restore_keys(mp_context, false); // Post event upwards to inform that inclusion of node A has failed. - p_s2_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_s2_event->evt.s2_event.peer = mp_context->inclusion_peer; + p_s2_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_s2_event->evt.s2_event.peer = mp_context->inclusion_peer; p_s2_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = fail_type; m_evt_handler(p_s2_event); } @@ -394,20 +533,18 @@ static void remote_inclusion_failed_evt_push(void) void inclusion_failed_frame_send(uint8_t error, uint8_t secure) { mp_context->kex_fail_code = error; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_FAIL; mp_context->u.inclusion_buf[SECURITY_2_KEX_FAIL_FAIL_TYPE_POS] = error; - mp_context->inclusion_buf_length = SECURITY_2_KEX_FAIL_LENGTH; + mp_context->inclusion_buf_length = SECURITY_2_KEX_FAIL_LENGTH; m_retry_counter = MAX_RETRY_COUNT; - if (TEMP_KEY_SECURE == secure) - { - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + if (TEMP_KEY_SECURE == secure) { + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; mp_context->inclusion_peer.tx_options = 0; s2_inclusion_send_data(); - } - else - { + } else { s2_inclusion_send_frame(); } } @@ -417,11 +554,13 @@ void inclusion_failed_frame_send(uint8_t error, uint8_t secure) static uint8_t validate_echo_kex_report(void) { - if ((m_schemes == mp_context->buf[SECURITY_2_KEX_REP_SCHEME_POS]) && - (m_curves == mp_context->buf[SECURITY_2_KEX_REP_CURVE_POS]) && - (m_keys == mp_context->buf[SECURITY_2_KEX_REP_KEYS_POS]) && - (((SECURITY_2_NLS_AVAILABLE << SECURITY_2_KEX_REPORT_NLS_SUPPORT_BIT_POS) | (mp_context->csa_support) | SECURITY_2_ECHO_ON) == mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS])) - { + if ((m_schemes == mp_context->buf[SECURITY_2_KEX_REP_SCHEME_POS]) + && (m_curves == mp_context->buf[SECURITY_2_KEX_REP_CURVE_POS]) + && (m_keys == mp_context->buf[SECURITY_2_KEX_REP_KEYS_POS]) + && (((SECURITY_2_NLS_AVAILABLE + << SECURITY_2_KEX_REPORT_NLS_SUPPORT_BIT_POS) + | (mp_context->csa_support) | SECURITY_2_ECHO_ON) + == mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS])) { return 0; } @@ -438,34 +577,34 @@ void s2_inclusion_set_event_handler(s2_event_handler_t evt_handler) m_evt_handler = evt_handler; } -void s2_inclusion_challenge_response(struct S2 *p_context, uint8_t include, const uint8_t* p_response, uint8_t responseLength) +void s2_inclusion_challenge_response(struct S2 *p_context, + uint8_t include, + const uint8_t *p_response, + uint8_t responseLength) { MP_CTX_DEF - if (ACCEPT_INCLUSION == include) - { + if (ACCEPT_INCLUSION == include) { // The caller is internal protocol code, thus it is trusted and should keep within the buffer // limit of public key size. - while(responseLength--) - { + while (responseLength--) { mp_context->public_key[responseLength] = p_response[responseLength]; } process_event(S2_INCLUDING_ACCEPT); - } - else - { + } else { process_event(S2_INCLUDING_REJECT); } } - -void s2_inclusion_joining_start(struct S2 *p_context, s2_connection_t *p_connection, uint8_t csa) +void s2_inclusion_joining_start(struct S2 *p_context, + s2_connection_t *p_connection, + uint8_t csa) { MP_CTX_DEF mp_context->inclusion_peer = *p_connection; mp_context->inclusion_mode = csa ? INCLUSION_MODE_CSA : INCLUSION_MODE_SSA; - mp_context->kex_fail_code = 0; + mp_context->kex_fail_code = 0; /* In case of LR inclusion, strip keys that are invalid in LR */ if (IS_LR_NODE(mp_context->inclusion_peer.l_node)) { @@ -489,19 +628,19 @@ void s2_inclusion_abort(struct S2 *p_context) process_event(S2_INCLUDING_REJECT); } - -void s2_inclusion_post_event(struct S2 *p_context,s2_connection_t* src) { +void s2_inclusion_post_event(struct S2 *p_context, s2_connection_t *src) +{ MP_CTX_DEF - if((src->rx_options & S2_RXOPTION_MULTICAST) == S2_RXOPTION_MULTICAST) { + if ((src->rx_options & S2_RXOPTION_MULTICAST) == S2_RXOPTION_MULTICAST) { return; } - if(mp_context->inclusion_state == S2_AWAITING_KEX_GET) { - mp_context->inclusion_peer=*src; + if (mp_context->inclusion_state == S2_AWAITING_KEX_GET) { + mp_context->inclusion_peer = *src; } - if(mp_context->inclusion_peer.r_node == src->r_node) { + if (mp_context->inclusion_peer.r_node == src->r_node) { mp_context->inclusion_peer.class_id = src->class_id; s2_inclusion_post_event_internal(mp_context); } @@ -510,71 +649,74 @@ void s2_inclusion_post_event(struct S2 *p_context,s2_connection_t* src) { static void s2_inclusion_post_event_internal(struct S2 *p_context) { // Command byte in S2 frame is used to identify the event. - uint8_t crypt_rule; + uint8_t crypt_rule; uint16_t event; - uint8_t event_rule_index; + uint8_t event_rule_index; MP_CTX_DEF - event = mp_context->buf[SECURITY_2_COMMAND_POS]; - event_rule_index = mp_context->buf[SECURITY_2_COMMAND_POS] - S2_INCLUSION_COMMAND_OFFSET; + event = mp_context->buf[SECURITY_2_COMMAND_POS]; + event_rule_index + = mp_context->buf[SECURITY_2_COMMAND_POS] - S2_INCLUSION_COMMAND_OFFSET; - if ((ELEM_COUNT(m_frame_rules) < event_rule_index) || - (mp_context->inclusion_state == S2_INC_IDLE)) - { + if ((ELEM_COUNT(m_frame_rules) < event_rule_index) + || (mp_context->inclusion_state == S2_INC_IDLE)) { // Not an inclusion event. Just return. return; } - if(m_frame_rules[event_rule_index][LENGTH_RULE_INDEX] > mp_context->length) - { + if (m_frame_rules[event_rule_index][LENGTH_RULE_INDEX] > mp_context->length) { process_event(S2_INCLUSION_ERROR); return; } - if ((ECHO_SUPPORT == m_frame_rules[event_rule_index][ENCRYPTION_SUPPORT_INDEX]) - && (mp_context->buf[SECURITY_2_KEX_SET_ECHO_POS] & SECURITY_2_ECHO_ON)) - { + if ((ECHO_SUPPORT + == m_frame_rules[event_rule_index][ENCRYPTION_SUPPORT_INDEX]) + && (mp_context->buf[SECURITY_2_KEX_SET_ECHO_POS] & SECURITY_2_ECHO_ON)) { crypt_rule = m_frame_rules[event_rule_index][ENCRYPTION_RULE_INDEX_B]; - } - else - { + } else { crypt_rule = m_frame_rules[event_rule_index][ENCRYPTION_RULE_INDEX_A]; } - if (NETWORK_KEY_SECURE == crypt_rule) - { - if ((mp_context->inclusion_peer.class_id >= sizeof(m_key_slot_key_class_pair)) || - ((mp_context->key_requested != m_key_slot_key_class_pair[mp_context->inclusion_peer.class_id]) && // If this happens, it could either mean we have an invalid request or an late ariving repeated frame. - ((mp_context->key_exchange & m_key_slot_key_class_pair[mp_context->inclusion_peer.class_id]) == 0))) // Hence, we check if the class id matches and already received key. + if (NETWORK_KEY_SECURE == crypt_rule) { + if ( + (mp_context->inclusion_peer.class_id >= sizeof(m_key_slot_key_class_pair)) + || ((mp_context->key_requested + != m_key_slot_key_class_pair[mp_context->inclusion_peer.class_id]) + && // If this happens, it could either mean we have an invalid request or an late ariving repeated frame. + ((mp_context->key_exchange + & m_key_slot_key_class_pair[mp_context->inclusion_peer.class_id]) + == 0))) // Hence, we check if the class id matches and already received key. { inclusion_failed_frame_send(KEX_FAIL_AUTH, NON_SECURE); process_event(S2_INCLUSION_ERROR_SENT); return; } - } - else if (crypt_rule != mp_context->inclusion_peer.class_id) - { - if ((DUAL_RULE_SUPPORT != m_frame_rules[event_rule_index][ENCRYPTION_SUPPORT_INDEX]) - || (mp_context->inclusion_peer.class_id != m_frame_rules[event_rule_index][ENCRYPTION_RULE_INDEX_B])) - { + } else if (crypt_rule != mp_context->inclusion_peer.class_id) { + if ((DUAL_RULE_SUPPORT + != m_frame_rules[event_rule_index][ENCRYPTION_SUPPORT_INDEX]) + || (mp_context->inclusion_peer.class_id + != m_frame_rules[event_rule_index][ENCRYPTION_RULE_INDEX_B])) { inclusion_failed_frame_send(KEX_FAIL_AUTH, NON_SECURE); process_event(S2_INCLUSION_ERROR_SENT); return; } } - switch (event) - { + switch (event) { case KEX_SET: case KEX_REPORT: // KEX_SET and KEX_REPORT frames can be with/without echo bit. // To differentiate in state machine the echo bit is shifted to first byte in event to either // denote an S2_KEX_SET_RECV or S2_ECHO_KEX_SET_RECV event respectively. - event |= ((mp_context->buf[SECURITY_2_KEX_SET_ECHO_POS] & SECURITY_2_ECHO_ON) << KEX_ECHO_BIT_POS); + event + |= ((mp_context->buf[SECURITY_2_KEX_SET_ECHO_POS] & SECURITY_2_ECHO_ON) + << KEX_ECHO_BIT_POS); break; case PUBLIC_KEY_REPORT: - event |= ((mp_context->buf[SECURITY_2_PUB_KEY_INC_FLAG_POS] & SECURITY_2_INCLUDING_NODE) << PUBLIC_KEY_INCLUDING_NODE_BIT_POS); + event |= ((mp_context->buf[SECURITY_2_PUB_KEY_INC_FLAG_POS] + & SECURITY_2_INCLUDING_NODE) + << PUBLIC_KEY_INCLUDING_NODE_BIT_POS); break; case SECURITY_2_NETWORK_KEY_VERIFY: @@ -582,7 +724,9 @@ static void s2_inclusion_post_event_internal(struct S2 *p_context) // Taking the negative value, results in all upper bits set and thus it can be evaluated if more keys should be exchanged. // Example: 0x04 -> 0xFC, which indicates that keys denoted by bit 0 and 1 are already exchanged. // This event is only triggered in the including side. - event = (mp_context->key_exchange == mp_context->key_granted) ? S2_NET_KEY_VERIFY_FINAL_RECV : S2_NET_KEY_VERIFY_RECV; + event = (mp_context->key_exchange == mp_context->key_granted) + ? S2_NET_KEY_VERIFY_FINAL_RECV + : S2_NET_KEY_VERIFY_RECV; break; case SECURITY_2_TRANSFER_END: @@ -591,7 +735,9 @@ static void s2_inclusion_post_event_internal(struct S2 *p_context) // Example: 0x04 -> 0xFC, which indicates that keys denoted by bit 0 and 1 are already exchanged. // The minus trick only works when a single bit is set, and hence only on the joining side. // This event is only posted on the joining side AND on the including side for final transfer end. - event = ((-mp_context->key_exchange) & mp_context->key_granted) ? S2_TRANSFER_END_RECV : S2_SEND_FINAL_TRANSFER_END; + event = ((-mp_context->key_exchange) & mp_context->key_granted) + ? S2_TRANSFER_END_RECV + : S2_SEND_FINAL_TRANSFER_END; break; default: @@ -606,8 +752,14 @@ void s2_inclusion_notify_timeout(struct S2 *p_context) { MP_CTX_DEF - if (S2_ECHO_KEX_SET_SENDING == mp_context->inclusion_state) // Hack by checking current state too early as we are debugging ring issue. - process_event((NO_RETRIES == m_retry_counter) || (QUEUE_FULL == m_retry_counter) ? S2_INCLUSION_TIMEOUT : S2_INCLUSION_RETRY); + if ( + S2_ECHO_KEX_SET_SENDING + == mp_context + ->inclusion_state) // Hack by checking current state too early as we are debugging ring issue. + process_event((NO_RETRIES == m_retry_counter) + || (QUEUE_FULL == m_retry_counter) + ? S2_INCLUSION_TIMEOUT + : S2_INCLUSION_RETRY); else process_event(S2_INCLUSION_TIMEOUT); } @@ -616,42 +768,45 @@ void s2_inclusion_send_done(struct S2 *p_context, uint8_t status) { MP_CTX_DEF - if (QUEUE_FULL == m_retry_counter) - { + if (QUEUE_FULL == m_retry_counter) { m_retry_counter = MAX_RETRY_COUNT; process_event(S2_INCLUSION_RETRY); - } - else if ((m_retry_counter > NO_RETRIES) && (S2_ECHO_KEX_SET_SENDING != mp_context->inclusion_state)) // Hack by checking current state too early as we are debugging ring issue. + } else if ( + (m_retry_counter > NO_RETRIES) + && (S2_ECHO_KEX_SET_SENDING + != mp_context + ->inclusion_state)) // Hack by checking current state too early as we are debugging ring issue. { process_event(status ? S2_INCLUSION_SEND_DONE : S2_INCLUSION_RETRY); - } - else - { + } else { process_event(status ? S2_INCLUSION_SEND_DONE : S2_INCLUSION_SEND_FAILED); } } -void s2_inclusion_decryption_failure(struct S2 *p_context,s2_connection_t* src) +void s2_inclusion_decryption_failure(struct S2 *p_context, s2_connection_t *src) { MP_CTX_DEF - if(src->r_node == mp_context->inclusion_peer.r_node) { + if (src->r_node == mp_context->inclusion_peer.r_node) { process_event(S2_INCLUDING_DECRYPT_FAILED); } } - -uint8_t s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys_to_request) +uint8_t + s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys_to_request) { - CHECK_AND_FAIL((SECURITY_2_SCHEME_SUPPORT_MASK != schemes), KEX_FAIL_KEX_SCHEME); + CHECK_AND_FAIL((SECURITY_2_SCHEME_SUPPORT_MASK != schemes), + KEX_FAIL_KEX_SCHEME); CHECK_AND_FAIL((KEX_REPORT_CURVE_25519 != curves), KEX_FAIL_KEX_CURVES); - CHECK_AND_FAIL(((~SECURITY_2_KEY_MASK & keys_to_request) || - ((SECURITY_2_KEY_MASK & keys_to_request) == 0)), KEX_FAIL_KEX_KEY); + CHECK_AND_FAIL(((~SECURITY_2_KEY_MASK & keys_to_request) + || ((SECURITY_2_KEY_MASK & keys_to_request) == 0)), + KEX_FAIL_KEX_KEY); m_schemes = schemes; m_curves = curves; - m_keys = keys_to_request; // m_keys should include all the keys to request when being bootstrapped - // LR keys are so far excluded + m_keys + = keys_to_request; // m_keys should include all the keys to request when being bootstrapped + // LR keys are so far excluded return 0; } @@ -659,7 +814,7 @@ uint8_t s2_inclusion_init(uint8_t schemes, uint8_t curves, uint8_t keys_to_reque */ static void s2_send_kex_report(void) { - zwave_event_t * p_s2_event; + zwave_event_t *p_s2_event; s2_inclusion_stop_timeout(); @@ -669,21 +824,27 @@ static void s2_send_kex_report(void) */ keystore_network_key_clear(0xFF); - p_s2_event = (zwave_event_t *)m_event_buffer; + p_s2_event = (zwave_event_t *)m_event_buffer; p_s2_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; p_s2_event->evt.s2_event.peer = mp_context->inclusion_peer; m_evt_handler(p_s2_event); - mp_context->csa_support = (mp_context->inclusion_mode == INCLUSION_MODE_CSA ? SECURITY_2_CSA_ON : 0); - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_REPORT; - mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_ECHO_POS] = mp_context->csa_support | (SECURITY_2_NLS_AVAILABLE << SECURITY_2_KEX_REPORT_NLS_SUPPORT_BIT_POS) | SECURITY_2_ECHO_OFF; + mp_context->csa_support + = (mp_context->inclusion_mode == INCLUSION_MODE_CSA ? SECURITY_2_CSA_ON + : 0); + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_REPORT; + mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_ECHO_POS] + = mp_context->csa_support + | (SECURITY_2_NLS_AVAILABLE << SECURITY_2_KEX_REPORT_NLS_SUPPORT_BIT_POS) + | SECURITY_2_ECHO_OFF; mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_SCHEME_POS] = m_schemes; mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_CURVE_POS] = m_curves; mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_KEYS_POS] = m_keys; - mp_context->inclusion_buf_length = SECURITY_2_KEX_REPORT_LENGTH; - mp_context->is_keys_restored = false; - m_retry_counter = MAX_RETRY_COUNT; + mp_context->inclusion_buf_length = SECURITY_2_KEX_REPORT_LENGTH; + mp_context->is_keys_restored = false; + m_retry_counter = MAX_RETRY_COUNT; s2_inclusion_send_frame(); // While waiting for KEX SET set s2 inclucion timeout TB2_TIMEOUT s2_inclusion_set_timeout(mp_context, TB2_TIMEOUT); @@ -691,30 +852,25 @@ static void s2_send_kex_report(void) static void s2_send_pub_key_b(void) { - uint8_t support; // Helper variable, being reused purely for code optimization reasons on memory constrained targets + uint8_t + support; // Helper variable, being reused purely for code optimization reasons on memory constrained targets s2_inclusion_stop_timeout(); support = mp_context->buf[SECURITY_2_KEX_SET_SCHEME_POS]; // Check only single scheme is selected and that the selected bit matches a supported scheme. - if ((0 == (support & (support - 1))) && (support & m_schemes)) - { + if ((0 == (support & (support - 1))) && (support & m_schemes)) { mp_context->scheme_support = support; - } - else - { + } else { support = KEX_FAIL_KEX_SCHEME; goto error_handling; } support = mp_context->buf[SECURITY_2_KEX_SET_CURVE_POS]; // Check only single scheme is selected and that the selected bit matches a supported scheme. - if ((0 == (support & (support - 1))) && (support & m_curves)) - { + if ((0 == (support & (support - 1))) && (support & m_curves)) { mp_context->curve_support = support; - } - else - { + } else { support = KEX_FAIL_KEX_CURVES; goto error_handling; } @@ -725,7 +881,7 @@ static void s2_send_pub_key_b(void) support = KEX_FAIL_KEX_KEY; goto error_handling; } else if (0 == (~m_keys & support)) { - // Check if granted key/s are supported - no keys granted are also ok when nmode is classic + // Check if granted key/s are supported - no keys granted are also ok when nmode is classic mp_context->key_granted = support; } else { // We have been granted keys we don't support, this is an error @@ -733,37 +889,37 @@ static void s2_send_pub_key_b(void) goto error_handling; } - if(mp_context->buf[SECURITY_2_KEX_SET_CSA_POS] & SECURITY_2_CSA_ON) - { - if(mp_context->inclusion_mode!= INCLUSION_MODE_CSA) //We did not ask for this + if (mp_context->buf[SECURITY_2_KEX_SET_CSA_POS] & SECURITY_2_CSA_ON) { + if (mp_context->inclusion_mode + != INCLUSION_MODE_CSA) //We did not ask for this { support = KEX_FAIL_KEX_KEY; goto error_handling; } - } - else - { + } else { /** * Should we be able to reject here if we are not granted CSA */ mp_context->inclusion_mode = INCLUSION_MODE_SSA; } - mp_context->key_granted = mp_context->buf[SECURITY_2_KEX_SET_KEYS_POS]; - mp_context->key_exchange = 0x01; + mp_context->key_granted = mp_context->buf[SECURITY_2_KEX_SET_KEYS_POS]; + mp_context->key_exchange = 0x01; mp_context->kex_set_byte2 = mp_context->buf[SECURITY_2_KEX_SET_CSA_POS]; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = PUBLIC_KEY_REPORT; - mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_INC_FLAG_POS] = SECURITY_2_JOINING_NODE; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = PUBLIC_KEY_REPORT; + mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_INC_FLAG_POS] + = SECURITY_2_JOINING_NODE; s2_public_key_read(&mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS]); // If any bit besides the KEY_CLASS_S0 or KEY_CLASS_S2_UNAUTHENTICATED is set, // then the first two bytes of the public key must be cleared. - if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) && - (mp_context->key_granted & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) + && (mp_context->key_granted + & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) { mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS] = 0x00; mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS + 1] = 0x00; } @@ -790,20 +946,28 @@ static void s2_send_echo_kex_set(void) m_retry_counter--; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_SET; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_ECHO_POS] = mp_context->kex_set_byte2 | SECURITY_2_ECHO_ON; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_SCHEME_POS] = mp_context->scheme_support; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_CURVE_POS] = mp_context->curve_support; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_KEYS_POS] = mp_context->key_granted; - mp_context->inclusion_buf_length = SECURITY_2_KEX_SET_LENGTH; - - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; - mp_context->inclusion_peer.tx_options = S2_TXOPTION_VERIFY_DELIVERY; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_SET; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_ECHO_POS] + = mp_context->kex_set_byte2 | SECURITY_2_ECHO_ON; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_SCHEME_POS] + = mp_context->scheme_support; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_CURVE_POS] + = mp_context->curve_support; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_KEYS_POS] + = mp_context->key_granted; + mp_context->inclusion_buf_length = SECURITY_2_KEX_SET_LENGTH; + + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + mp_context->inclusion_peer.tx_options = S2_TXOPTION_VERIFY_DELIVERY; // Return value is ignored as the retransmission of ECHO frames is based on callback from timer // due to unknown user repsonse time and lenghty ECDH calc on remote end. - S2_send_data(mp_context, &mp_context->inclusion_peer, mp_context->u.inclusion_buf, mp_context->inclusion_buf_length); + S2_send_data(mp_context, + &mp_context->inclusion_peer, + mp_context->u.inclusion_buf, + mp_context->inclusion_buf_length); s2_inclusion_set_timeout(mp_context, TB5_TIMEOUT); } @@ -812,7 +976,7 @@ static void s2_pub_key_a_recv(void) { // Post event upwards to inform that a public key is received and the user should confirm the // inclusion of the node. - zwave_event_t * s2_event; + zwave_event_t *s2_event; s2_inclusion_stop_timeout(); @@ -821,71 +985,73 @@ static void s2_pub_key_a_recv(void) s2_inclusion_set_timeout(mp_context, TBI1_TIMEOUT); // Public key receive. memcpy(mp_context->public_key, - &mp_context->buf[SECURITY_2_PUB_KEY_KEY_POS],sizeof(public_key_t)); + &mp_context->buf[SECURITY_2_PUB_KEY_KEY_POS], + sizeof(public_key_t)); - s2_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + s2_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; s2_event->evt.s2_event.peer = mp_context->inclusion_peer; // For now, do a raw copy. Design should be cleaned up to ensure proper use of buffers. // Remember to strip away the frame header. memcpy(s2_event->evt.s2_event.s2_data.challenge_req.public_key, - &mp_context->buf[SECURITY_2_PUB_KEY_KEY_POS], sizeof(public_key_t)); - s2_event->evt.s2_event.s2_data.challenge_req.length = sizeof(public_key_t); - s2_event->evt.s2_event.s2_data.challenge_req.granted_keys = mp_context->key_granted; + &mp_context->buf[SECURITY_2_PUB_KEY_KEY_POS], + sizeof(public_key_t)); + s2_event->evt.s2_event.s2_data.challenge_req.length = sizeof(public_key_t); + s2_event->evt.s2_event.s2_data.challenge_req.granted_keys + = mp_context->key_granted; // We do not support Client Side Auth for LR. There are no non-S2 devices to support on LR. - if ((mp_context->key_granted & (SECURITY_2_SECURITY_2_CLASS_1 | SECURITY_2_SECURITY_2_CLASS_2)) && - (mp_context->inclusion_mode == INCLUSION_MODE_CSA)) - { - s2_event->evt.s2_event.s2_data.challenge_req.dsk_length = DSK_CSA_CHALLENGE_LENGTH; - } - else - { + if ((mp_context->key_granted + & (SECURITY_2_SECURITY_2_CLASS_1 | SECURITY_2_SECURITY_2_CLASS_2)) + && (mp_context->inclusion_mode == INCLUSION_MODE_CSA)) { + s2_event->evt.s2_event.s2_data.challenge_req.dsk_length + = DSK_CSA_CHALLENGE_LENGTH; + } else { s2_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; } m_evt_handler(s2_event); - } static void s2_send_net_key_get(void) { s2_inclusion_stop_timeout(); - if ((KEX_REPORT == mp_context->buf[SECURITY_2_COMMAND_POS]) && - (validate_echo_kex_report() != 0)) - { + if ((KEX_REPORT == mp_context->buf[SECURITY_2_COMMAND_POS]) + && (validate_echo_kex_report() != 0)) { process_event(S2_INCLUSION_ERROR_SENT); return; } // If a transfer end is received then it must be ensured that the KEY was verified // and that including side has set KeyRequestComplete to '0'. - else if ((SECURITY_2_TRANSFER_END == mp_context->buf[SECURITY_2_COMMAND_POS]) && - (SECURITY_2_KEY_VERIFIED != (mp_context->buf[SECURITY_2_TRANSFER_END_FLAGS_POS] & - (SECURITY_2_KEY_REQ_COMPLETE | SECURITY_2_KEY_VERIFIED)))) - { + else if ((SECURITY_2_TRANSFER_END == mp_context->buf[SECURITY_2_COMMAND_POS]) + && (SECURITY_2_KEY_VERIFIED + != (mp_context->buf[SECURITY_2_TRANSFER_END_FLAGS_POS] + & (SECURITY_2_KEY_REQ_COMPLETE + | SECURITY_2_KEY_VERIFIED)))) { inclusion_failed_frame_send(KEX_FAIL_KEY_VERIFY, NON_SECURE); process_event(S2_INCLUSION_ERROR); return; } - if (0 == mp_context->key_granted) - { + if (0 == mp_context->key_granted) { // No keys granted process_event(S2_NO_KEYS_GRANTED); return; } - while (0 == (mp_context->key_exchange & mp_context->key_granted)) - { + while (0 == (mp_context->key_exchange & mp_context->key_granted)) { mp_context->key_exchange <<= 1; } - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_NETWORK_KEY_GET; - mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS] = mp_context->key_exchange; - mp_context->inclusion_buf_length = SECURITY_2_NET_KEY_GET_LENGTH; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] + = SECURITY_2_NETWORK_KEY_GET; + mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS] + = mp_context->key_exchange; + mp_context->inclusion_buf_length = SECURITY_2_NET_KEY_GET_LENGTH; - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; - mp_context->inclusion_peer.tx_options = S2_TXOPTION_VERIFY_DELIVERY; + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + mp_context->inclusion_peer.tx_options = S2_TXOPTION_VERIFY_DELIVERY; m_retry_counter = MAX_RETRY_COUNT; s2_inclusion_send_data(); @@ -903,36 +1069,46 @@ static void s2_send_net_key_verify(void) received_key = mp_context->buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS]; - if (received_key != mp_context->key_exchange) - { - goto error_handling; + if (received_key != mp_context->key_exchange) { + goto error_handling; } - keystore_network_key_write(received_key, &mp_context->buf[SECURITY_2_NET_KEY_REP_KEY_POS]); + keystore_network_key_write(received_key, + &mp_context->buf[SECURITY_2_NET_KEY_REP_KEY_POS]); mp_context->key_exchange <<= 1; // Update context with new key. #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) uint32_t net_key_id; - net_key_id = convert_key_class_to_psa_key_id(received_key); + net_key_id = convert_key_class_to_psa_key_id(received_key); network_key = (uint8_t *)&mp_context->buf[SECURITY_2_NET_KEY_REP_KEY_POS]; - S2_network_key_update(mp_context, net_key_id, NETWORK_KEY_SECURE, - network_key, 0, false); + S2_network_key_update(mp_context, + net_key_id, + NETWORK_KEY_SECURE, + network_key, + 0, + false); #if !defined(ZW_CONTROLLER) /* Do not let key material linger around, clear them from memory */ memset(network_key, 0, 16); network_key = NULL; #endif #else - S2_network_key_update(mp_context, ZWAVE_KEY_ID_NONE, NETWORK_KEY_SECURE, - &mp_context->buf[SECURITY_2_NET_KEY_REP_KEY_POS], 0, false); + S2_network_key_update(mp_context, + ZWAVE_KEY_ID_NONE, + NETWORK_KEY_SECURE, + &mp_context->buf[SECURITY_2_NET_KEY_REP_KEY_POS], + 0, + false); #endif - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_NETWORK_KEY_VERIFY; - mp_context->inclusion_buf_length = SECURITY_2_NET_KEY_VERIFY_LENGTH; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] + = SECURITY_2_NETWORK_KEY_VERIFY; + mp_context->inclusion_buf_length = SECURITY_2_NET_KEY_VERIFY_LENGTH; - mp_context->inclusion_peer.class_id = NETWORK_KEY_SECURE; + mp_context->inclusion_peer.class_id = NETWORK_KEY_SECURE; mp_context->inclusion_peer.tx_options = 0; m_retry_counter = MAX_RETRY_COUNT; @@ -950,21 +1126,23 @@ static void s2_send_final_transfer_end(void) s2_inclusion_stop_timeout(); // If a transfer end is received then it must be ensured that the KEY was verified // and that including side has set KeyRequestComplete to '0'. - if ((SECURITY_2_TRANSFER_END == mp_context->buf[SECURITY_2_COMMAND_POS]) && - (SECURITY_2_KEY_VERIFIED != (mp_context->buf[SECURITY_2_TRANSFER_END_FLAGS_POS] & - (SECURITY_2_KEY_REQ_COMPLETE | SECURITY_2_KEY_VERIFIED)))) - { + if ((SECURITY_2_TRANSFER_END == mp_context->buf[SECURITY_2_COMMAND_POS]) + && (SECURITY_2_KEY_VERIFIED + != (mp_context->buf[SECURITY_2_TRANSFER_END_FLAGS_POS] + & (SECURITY_2_KEY_REQ_COMPLETE | SECURITY_2_KEY_VERIFIED)))) { inclusion_failed_frame_send(KEX_FAIL_KEY_VERIFY, NON_SECURE); process_event(S2_INCLUSION_ERROR); return; } - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_TRANSFER_END; - mp_context->u.inclusion_buf[SECURITY_2_TRANSFER_END_FLAGS_POS] = SECURITY_2_KEY_REQ_COMPLETE; - mp_context->inclusion_buf_length = SECURITY_2_TRANSFER_END_LENGTH; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_TRANSFER_END; + mp_context->u.inclusion_buf[SECURITY_2_TRANSFER_END_FLAGS_POS] + = SECURITY_2_KEY_REQ_COMPLETE; + mp_context->inclusion_buf_length = SECURITY_2_TRANSFER_END_LENGTH; - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; mp_context->inclusion_peer.tx_options = 0; m_retry_counter = MAX_RETRY_COUNT; @@ -973,14 +1151,15 @@ static void s2_send_final_transfer_end(void) static void s2_joining_complete(zwave_event_codes_t complete_type) { - /* Restore the real network key (note: Perhaps postpone until next senddata?) */ - zwave_event_t * s2_event = (zwave_event_t *)m_event_buffer; + /* Restore the real network key (note: Perhaps postpone until next senddata?) */ + zwave_event_t *s2_event = (zwave_event_t *)m_event_buffer; s2_restore_keys(mp_context, true); s2_event->event_type = complete_type; s2_event->evt.s2_event.peer = mp_context->inclusion_peer; - s2_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = mp_context->key_granted; + s2_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys + = mp_context->key_granted; m_evt_handler(s2_event); } @@ -988,18 +1167,17 @@ static void s2_joining_complete(zwave_event_codes_t complete_type) #ifdef ZWAVE_PSA_SECURE_VAULT static void s2_keypair_keyid_read(uint32_t *keyid) { - if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) && - (mp_context->key_granted & ~(KEY_CLASS_S2_NOT_VALID | KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) + && (mp_context->key_granted + & ~(KEY_CLASS_S2_NOT_VALID | KEY_CLASS_S0 + | KEY_CLASS_S2_UNAUTHENTICATED))) { keystore_keyid_read(keyid); - } - else - { + } else { keystore_dynamic_keyid_read(keyid); } } -#else // #ifdef ZWAVE_PSA_SECURE_VAULT +#else // #ifdef ZWAVE_PSA_SECURE_VAULT /** * Read the correct private key depending on granted keys. @@ -1012,18 +1190,17 @@ static void s2_keypair_keyid_read(uint32_t *keyid) */ static void s2_private_key_read(uint8_t *buf) { - if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) && - (mp_context->key_granted & ~(KEY_CLASS_S2_NOT_VALID | KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) + && (mp_context->key_granted + & ~(KEY_CLASS_S2_NOT_VALID | KEY_CLASS_S0 + | KEY_CLASS_S2_UNAUTHENTICATED))) { keystore_private_key_read(buf); - } - else - { + } else { // keystore will return persisted private key if secure bootstrapping was initiated through SmartStart keystore_dynamic_private_key_read(buf); } } -#endif // #ifdef ZWAVE_PSA_SECURE_VAULT +#endif // #ifdef ZWAVE_PSA_SECURE_VAULT /** * Read the correct public key depending on granted keys. @@ -1036,13 +1213,12 @@ static void s2_private_key_read(uint8_t *buf) */ static void s2_public_key_read(uint8_t *buf) { - if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) && - (mp_context->key_granted & ~(KEY_CLASS_S2_NOT_VALID | KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if ((mp_context->inclusion_mode == INCLUSION_MODE_SSA) + && (mp_context->key_granted + & ~(KEY_CLASS_S2_NOT_VALID | KEY_CLASS_S0 + | KEY_CLASS_S2_UNAUTHENTICATED))) { keystore_public_key_read(buf); - } - else - { + } else { // keystore will return persisted public key if secure bootstrapping was initiated through SmartStart keystore_dynamic_public_key_read(buf); } @@ -1053,20 +1229,29 @@ static void s2_do_ecdh_calc_b(void) #ifdef ZWAVE_PSA_SECURE_VAULT uint32_t keyid; s2_keypair_keyid_read(&keyid); - zw_status_t status = zw_compute_ecdh_shared_secret(mp_context->public_key, keyid, zwave_shared_secret); + zw_status_t status = zw_compute_ecdh_shared_secret(mp_context->public_key, + keyid, + zwave_shared_secret); if (status != ZW_PSA_SUCCESS) { zw_security_error(status); } memcpy(shared_secret, zwave_shared_secret, ZWAVE_ECDH_SECRET_LENGTH); #else s2_private_key_read(&shared_key_mem[LOCAL_PRIVATE_KEY_INDEX]); - crypto_scalarmult_curve25519(shared_secret, &shared_key_mem[LOCAL_PRIVATE_KEY_INDEX], mp_context->public_key); + crypto_scalarmult_curve25519(shared_secret, + &shared_key_mem[LOCAL_PRIVATE_KEY_INDEX], + mp_context->public_key); #endif memcpy(&shared_key_mem[PUBLIC_KEY_A_INDEX], mp_context->public_key, 32); s2_public_key_read(&shared_key_mem[PUBLIC_KEY_B_INDEX]); tempkey_extract(shared_secret, shared_key_mem, mp_context->public_key); - S2_network_key_update(mp_context, ZWAVE_KEY_ID_NONE, TEMP_KEY_SECURE, mp_context->public_key, 1, false); + S2_network_key_update(mp_context, + ZWAVE_KEY_ID_NONE, + TEMP_KEY_SECURE, + mp_context->public_key, + 1, + false); m_retry_counter = TBI1_TIMEOUT / TB5_TIMEOUT; s2_send_echo_kex_set(); @@ -1074,36 +1259,33 @@ static void s2_do_ecdh_calc_b(void) void s2_inclusion_send_frame(void) { - if (0 == S2_send_frame(mp_context, - &mp_context->inclusion_peer, - mp_context->u.inclusion_buf, - mp_context->inclusion_buf_length)) - { + if (0 + == S2_send_frame(mp_context, + &mp_context->inclusion_peer, + mp_context->u.inclusion_buf, + mp_context->inclusion_buf_length)) { m_retry_counter = QUEUE_FULL; - } - else - { + } else { m_retry_counter--; } } void s2_inclusion_send_data(void) { - if (0 == S2_send_data(mp_context, - &mp_context->inclusion_peer, - mp_context->u.inclusion_buf, - mp_context->inclusion_buf_length)) - { + if (0 + == S2_send_data(mp_context, + &mp_context->inclusion_peer, + mp_context->u.inclusion_buf, + mp_context->inclusion_buf_length)) { m_retry_counter = QUEUE_FULL; - } - else - { + } else { m_retry_counter--; } } -uint8_t s2_get_key_count(void) { - return ELEM_COUNT(m_key_slot_pair) + 1; +uint8_t s2_get_key_count(void) +{ + return ELEM_COUNT(m_key_slot_pair) + 1; } /** Section defining including node functions for state transistion actions - End. diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion_internal.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion_internal.h index da9c09386..c0f992a7f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion_internal.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/s2_inclusion_internal.h @@ -9,82 +9,130 @@ * These define the key slots used for the various S2 keys. * This information is shared between S2.c and s2_inclusion.c. */ -#define UNAUTHENTICATED_KEY_SLOT 0 //< Slot for unauthenticated key. This value matches the ordering of security_key_t in ZW_security_api.h - do not change -#define AUTHENTICATED_KEY_SLOT 1 //< Slot for authenticated key. This value matches the ordering of security_key_t in ZW_security_api.h - do not change -#define ACCESS_KEY_SLOT 2 //< Slot for access key. This value matches the class_id returned by S2.c when decrypting with this key. -#define LR_AUTHENTICATED_KEY_SLOT 3 //< Slot for LR authenticated key. This value matches the class_id returned by S2.c when decrypting with this key. -#define LR_ACCESS_KEY_SLOT 4 //< Slot for LR access key. This value matches the ordering of security_key_t in ZW_security_api.h - do not change +#define UNAUTHENTICATED_KEY_SLOT \ + 0 //< Slot for unauthenticated key. This value matches the ordering of security_key_t in ZW_security_api.h - do not change +#define AUTHENTICATED_KEY_SLOT \ + 1 //< Slot for authenticated key. This value matches the ordering of security_key_t in ZW_security_api.h - do not change +#define ACCESS_KEY_SLOT \ + 2 //< Slot for access key. This value matches the class_id returned by S2.c when decrypting with this key. +#define LR_AUTHENTICATED_KEY_SLOT \ + 3 //< Slot for LR authenticated key. This value matches the class_id returned by S2.c when decrypting with this key. +#define LR_ACCESS_KEY_SLOT \ + 4 //< Slot for LR access key. This value matches the ordering of security_key_t in ZW_security_api.h - do not change #ifdef ZW_CONTROLLER -#define TEMP_KEY_SECURE 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. -#define NETWORK_KEY_SECURE 6 //< Value identifying index for the current network key in S2 network key when transmitting secure frames. +#define TEMP_KEY_SECURE \ + 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define NETWORK_KEY_SECURE \ + 6 //< Value identifying index for the current network key in S2 network key when transmitting secure frames. #else -#define TEMP_KEY_SECURE 0 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. -#define NETWORK_KEY_SECURE 1 //< Value identifying index for the current network key in S2 network key when transmitting secure frames. +#define TEMP_KEY_SECURE \ + 0 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define NETWORK_KEY_SECURE \ + 1 //< Value identifying index for the current network key in S2 network key when transmitting secure frames. #endif /** Following defines are specified in SDS11274 for node inclusion. */ -#define SECONDS_10 1000 //< Definition of 10 Seconds in 10ms resolution. -#define SECONDS_30 3000 //< Definition of 30 Seconds in 10ms resolution. -#define SECONDS_60 6000 //< Definition of 60 Seconds in 10ms resolution. -#define SECONDS_240 24000 //< Definition of 240 Seconds in 10ms resolution. -#define TA1_TIMEOUT SECONDS_10 //< Timeout TA1 is used after sending KEX Get and is the time until KEX Report must be received from the joining node. -#define TA2_TIMEOUT SECONDS_10 //< Timeout TA2 is used after sending KEX Set and is the time until Public Key B must be received from the joining node. -#define TA3_TIMEOUT SECONDS_30 //< Timeout TA3 is used after sending Public Key A and is the time until Echo(KEX Get) must be received from the joining node. -#define TA4_TIMEOUT SECONDS_10 //< Timeout TA4 is used after sending Echo(KEX Report) and is the time until Network Key Get must be received from the joining node. -#define TA5_TIMEOUT SECONDS_10 //< Timeout TA5 is used after sending Network Key Set and is the time until Network Key Verify must be received from the joining node. -#define TA6_TIMEOUT SECONDS_10 //< Timeout TA6 is used after sending Transfer End and is the time until Transfer End or second key exchange round is initiated by a Network Key Get has been received from the joining node. -#define TAI1_TIMEOUT SECONDS_240 //< Timeout TI1 is used after receiving public key and this the time in wich the user must accept/reject secure inclusion of the node. -#define TAI2_TIMEOUT SECONDS_240 //< Timeout TA6 is used after receiving public key B and this is the time in wich the user must provide/reject the missing part of the DSK. -#define TB1_TIMEOUT SECONDS_30 //< Timeout TB1 is used after neighbor discovery has completed and the time until KEX Get must be received from the including node. -#define TB2_TIMEOUT SECONDS_240 //< Timeout TB2 is used after sending KEX Report and is the time until KEX Set must be received from the including node. -#define TB3_TIMEOUT SECONDS_10 //< Timeout TB3 is used after sending Public Key B and is the time until Public Key A must be received from the including node. -#define TB5_TIMEOUT SECONDS_10 //< Timeout TB5 is used after sending Echo(KEX Set) and is the time until Echo(KEX Report) must be received from the including node. -#define TB6_TIMEOUT SECONDS_10 //< Timeout TB6 is used after sending Network Key Get and is the time until Network key report must be received from the including node. -#define TB7_TIMEOUT SECONDS_10 //< Timeout TB7 is used after sending Network Key Verify and is the time until Transfer End must be received from the including node. -#define TBI1_TIMEOUT SECONDS_240 //< Timeout TI1 is after receiving public key and tis the time in wich the user must accept/reject secure inclusion of the node. +#define SECONDS_10 1000 //< Definition of 10 Seconds in 10ms resolution. +#define SECONDS_30 3000 //< Definition of 30 Seconds in 10ms resolution. +#define SECONDS_60 6000 //< Definition of 60 Seconds in 10ms resolution. +#define SECONDS_240 24000 //< Definition of 240 Seconds in 10ms resolution. +#define TA1_TIMEOUT \ + SECONDS_10 //< Timeout TA1 is used after sending KEX Get and is the time until KEX Report must be received from the joining node. +#define TA2_TIMEOUT \ + SECONDS_10 //< Timeout TA2 is used after sending KEX Set and is the time until Public Key B must be received from the joining node. +#define TA3_TIMEOUT \ + SECONDS_30 //< Timeout TA3 is used after sending Public Key A and is the time until Echo(KEX Get) must be received from the joining node. +#define TA4_TIMEOUT \ + SECONDS_10 //< Timeout TA4 is used after sending Echo(KEX Report) and is the time until Network Key Get must be received from the joining node. +#define TA5_TIMEOUT \ + SECONDS_10 //< Timeout TA5 is used after sending Network Key Set and is the time until Network Key Verify must be received from the joining node. +#define TA6_TIMEOUT \ + SECONDS_10 //< Timeout TA6 is used after sending Transfer End and is the time until Transfer End or second key exchange round is initiated by a Network Key Get has been received from the joining node. +#define TAI1_TIMEOUT \ + SECONDS_240 //< Timeout TI1 is used after receiving public key and this the time in wich the user must accept/reject secure inclusion of the node. +#define TAI2_TIMEOUT \ + SECONDS_240 //< Timeout TA6 is used after receiving public key B and this is the time in wich the user must provide/reject the missing part of the DSK. +#define TB1_TIMEOUT \ + SECONDS_30 //< Timeout TB1 is used after neighbor discovery has completed and the time until KEX Get must be received from the including node. +#define TB2_TIMEOUT \ + SECONDS_240 //< Timeout TB2 is used after sending KEX Report and is the time until KEX Set must be received from the including node. +#define TB3_TIMEOUT \ + SECONDS_10 //< Timeout TB3 is used after sending Public Key B and is the time until Public Key A must be received from the including node. +#define TB5_TIMEOUT \ + SECONDS_10 //< Timeout TB5 is used after sending Echo(KEX Set) and is the time until Echo(KEX Report) must be received from the including node. +#define TB6_TIMEOUT \ + SECONDS_10 //< Timeout TB6 is used after sending Network Key Get and is the time until Network key report must be received from the including node. +#define TB7_TIMEOUT \ + SECONDS_10 //< Timeout TB7 is used after sending Network Key Verify and is the time until Transfer End must be received from the including node. +#define TBI1_TIMEOUT \ + SECONDS_240 //< Timeout TI1 is after receiving public key and tis the time in wich the user must accept/reject secure inclusion of the node. /** TODO: Investigate if there is/should be a common header for util functions as this. */ -#define ELEM_COUNT(ARRAY) (sizeof(ARRAY)/(sizeof(ARRAY[0]))) +#define ELEM_COUNT(ARRAY) (sizeof(ARRAY) / (sizeof(ARRAY[0]))) -#define S2_EVT_BUFFER_SIZE (128 / 4) //< Max event buffer in s2 inclusion model. Buffer is uint32_t to ensure proper alignment therefor size is divided by 4. +#define S2_EVT_BUFFER_SIZE \ + (128 \ + / 4) //< Max event buffer in s2 inclusion model. Buffer is uint32_t to ensure proper alignment therefor size is divided by 4. -#define MAX_PUBLIC_KEY_LENGTH 32 //< Maximum length of supported public key. Currently only curve 25519 for ECDH is supported, thus key length is fixed to 32 bytes. -#define KEX_ECHO_BIT_POS 8 //< Bit position in event enumeration when identifying an echo frame event. -#define PUBLIC_KEY_INCLUDING_NODE_BIT_POS 8 //< Bit position in event enumeration when identifying including node in public key frame event. +#define MAX_PUBLIC_KEY_LENGTH \ + 32 //< Maximum length of supported public key. Currently only curve 25519 for ECDH is supported, thus key length is fixed to 32 bytes. +#define KEX_ECHO_BIT_POS \ + 8 //< Bit position in event enumeration when identifying an echo frame event. +#define PUBLIC_KEY_INCLUDING_NODE_BIT_POS \ + 8 //< Bit position in event enumeration when identifying including node in public key frame event. -#define LOCAL_PUSH 0xFE //< Value identifying that the frame should be sent non-secure. -#define NON_SECURE 0xFF //< Value identifying that the frame should be sent non-secure. -#define SINGLE_RULE_SUPPORT 0 //< Only a single encryption rule applies to this frametype. -#define DUAL_RULE_SUPPORT 1 //< Two encryption rules applies to this frametype. -#define ECHO_SUPPORT 2 //< This frame type support echo frames, where the encryption rule depends on whether the frame is an echo. -#define LOCAL_PRIVATE_KEY_INDEX 0 //< Index in auth tag array for local private key. -#define PUBLIC_KEY_A_INDEX 0 //< Index in auth tag array for public key A. -#define PUBLIC_KEY_B_INDEX 32 //< Index in auth tag array for public key B. -#define ECDH_PUBLIC_KEY_SIZE 32 //< Size of an ECDH public key. -#define NETWORK_KEY_SIZE 16 //< Size of a Z-Wave network key. -#define ACCEPT_INCLUSION 1 //< Value defining inclusion acceptance. -#define S2_INCLUSION_COMMAND_OFFSET KEX_GET //< Offset from zero where the numbering of inclusion related commands begin. Kex get is the first valid command and hence defines the offset. -#define LENGTH_RULE_INDEX 0 //< Index in frame rules array where minimum length of the received frame type. -#define ENCRYPTION_SUPPORT_INDEX 1 //< Index in frame rules array where rules on how a received packet should be encrypted in order to be accepted. -#define ENCRYPTION_RULE_INDEX_A 2 //< Encryption rule index for first rule. Index rule A is also used for non-echo frames. -#define ENCRYPTION_RULE_INDEX_B 3 //< Encryption rule index for second rule. Index rule B is also used for echo frames. -#define NO_RETRIES 0x00 //< Indication that state has changed and retries are disabled. States supporting retries must set the retry counter accordingly. -#define QUEUE_FULL 0xFF //< Indication that a frame could not be transmitted and that a send done/failed should result in retry event. -#define MAX_RETRY_COUNT 0x03 +#define LOCAL_PUSH \ + 0xFE //< Value identifying that the frame should be sent non-secure. +#define NON_SECURE \ + 0xFF //< Value identifying that the frame should be sent non-secure. +#define SINGLE_RULE_SUPPORT \ + 0 //< Only a single encryption rule applies to this frametype. +#define DUAL_RULE_SUPPORT 1 //< Two encryption rules applies to this frametype. +#define ECHO_SUPPORT \ + 2 //< This frame type support echo frames, where the encryption rule depends on whether the frame is an echo. +#define LOCAL_PRIVATE_KEY_INDEX \ + 0 //< Index in auth tag array for local private key. +#define PUBLIC_KEY_A_INDEX 0 //< Index in auth tag array for public key A. +#define PUBLIC_KEY_B_INDEX 32 //< Index in auth tag array for public key B. +#define ECDH_PUBLIC_KEY_SIZE 32 //< Size of an ECDH public key. +#define NETWORK_KEY_SIZE 16 //< Size of a Z-Wave network key. +#define ACCEPT_INCLUSION 1 //< Value defining inclusion acceptance. +#define S2_INCLUSION_COMMAND_OFFSET \ + KEX_GET //< Offset from zero where the numbering of inclusion related commands begin. Kex get is the first valid command and hence defines the offset. +#define LENGTH_RULE_INDEX \ + 0 //< Index in frame rules array where minimum length of the received frame type. +#define ENCRYPTION_SUPPORT_INDEX \ + 1 //< Index in frame rules array where rules on how a received packet should be encrypted in order to be accepted. +#define ENCRYPTION_RULE_INDEX_A \ + 2 //< Encryption rule index for first rule. Index rule A is also used for non-echo frames. +#define ENCRYPTION_RULE_INDEX_B \ + 3 //< Encryption rule index for second rule. Index rule B is also used for echo frames. +#define NO_RETRIES \ + 0x00 //< Indication that state has changed and retries are disabled. States supporting retries must set the retry counter accordingly. +#define QUEUE_FULL \ + 0xFF //< Indication that a frame could not be transmitted and that a send done/failed should result in retry event. +#define MAX_RETRY_COUNT 0x03 -typedef enum{ - S2_KEX_REPORT_RECV = KEX_REPORT, - S2_PUB_KEY_RECV_B = PUBLIC_KEY_REPORT | (SECURITY_2_JOINING_NODE << PUBLIC_KEY_INCLUDING_NODE_BIT_POS), - S2_PUB_KEY_RECV_A = PUBLIC_KEY_REPORT | (SECURITY_2_INCLUDING_NODE << PUBLIC_KEY_INCLUDING_NODE_BIT_POS), +typedef enum { + S2_KEX_REPORT_RECV = KEX_REPORT, + S2_PUB_KEY_RECV_B + = PUBLIC_KEY_REPORT + | (SECURITY_2_JOINING_NODE << PUBLIC_KEY_INCLUDING_NODE_BIT_POS), + S2_PUB_KEY_RECV_A + = PUBLIC_KEY_REPORT + | (SECURITY_2_INCLUDING_NODE << PUBLIC_KEY_INCLUDING_NODE_BIT_POS), // Slave side - S2_KEX_GET_RECV = KEX_GET, - S2_KEX_SET_RECV = KEX_SET, - S2_ECHO_KEX_REPORT_RECV = (SECURITY_2_ECHO_ON << KEX_ECHO_BIT_POS) | KEX_REPORT, - S2_NET_KEY_REPORT_RECV = SECURITY_2_NETWORK_KEY_REPORT, + S2_KEX_GET_RECV = KEX_GET, + S2_KEX_SET_RECV = KEX_SET, + S2_ECHO_KEX_REPORT_RECV + = (SECURITY_2_ECHO_ON << KEX_ECHO_BIT_POS) | KEX_REPORT, + S2_NET_KEY_REPORT_RECV = SECURITY_2_NETWORK_KEY_REPORT, // Slave side - done - S2_ECHO_KEX_SET_RECV = (SECURITY_2_ECHO_ON << KEX_ECHO_BIT_POS) | KEX_SET, //< KEX_SET frames can be with/without echo bit. To differentiate in state machine the echo bit is shifted to first byte in event. + S2_ECHO_KEX_SET_RECV + = (SECURITY_2_ECHO_ON << KEX_ECHO_BIT_POS) + | KEX_SET, //< KEX_SET frames can be with/without echo bit. To differentiate in state machine the echo bit is shifted to first byte in event. S2_NET_KEY_GET_RECV = SECURITY_2_NETWORK_KEY_GET, S2_NET_KEY_VERIFY_RECV = SECURITY_2_NETWORK_KEY_VERIFY, S2_TRANSFER_END_RECV = SECURITY_2_TRANSFER_END, @@ -96,7 +144,7 @@ typedef enum{ S2_INCLUDING_DECRYPT_FAILED, // Slave side S2_SEND_FINAL_TRANSFER_END, - S2_INCLUSION_TX_QUEUED, // Outgoing frame has been queued for transmission + S2_INCLUSION_TX_QUEUED, // Outgoing frame has been queued for transmission // Slave side - done S2_NET_KEY_VERIFY_FINAL_RECV, S2_INCLUSION_RETRY, @@ -108,9 +156,9 @@ typedef enum{ S2_DISCOVERY_COMPLETE, S2_NO_KEYS_GRANTED, S2_EVT_ANY, -}s2_inclusion_event_t; +} s2_inclusion_event_t; -typedef enum{ +typedef enum { S2_NO_ACTION, S2_ABORT_ACTION, S2_TIMEOUT_ACTION, @@ -130,14 +178,14 @@ typedef enum{ S2_REMOTE_ERROR_ACTION, S2_JOINING_NEVER_STARTED_ACTION, S2_ACTION_LAST -}s2_action_t; +} s2_action_t; -typedef struct{ - s2_inclusion_state_t state; - s2_inclusion_event_t event; - uint8_t action; // ID of an action (s2_action_t or s2_action_controller_t). - s2_inclusion_state_t new_state; -}s2_transition_t; +typedef struct { + s2_inclusion_state_t state; + s2_inclusion_event_t event; + uint8_t action; // ID of an action (s2_action_t or s2_action_controller_t). + s2_inclusion_state_t new_state; +} s2_transition_t; extern struct S2 *mp_context; #define MP_CTX_DEF mp_context = p_context; diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/test/test_inclusion_joining_node.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/test/test_inclusion_joining_node.c index 56ca9a70e..64db9cfba 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/test/test_inclusion_joining_node.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/inclusion/test/test_inclusion_joining_node.c @@ -20,21 +20,21 @@ #include "s2_classcmd.h" #include "s2_keystore.h" -void setUpSuite(void) { +void setUpSuite(void) {} -} - -void tearDownSuite(void) { - -} +void tearDownSuite(void) {} -#define ELEM_COUNT(ARRAY) (sizeof(ARRAY)/(sizeof(ARRAY[0]))) +#define ELEM_COUNT(ARRAY) (sizeof(ARRAY) / (sizeof(ARRAY[0]))) #ifdef ZW_CONTROLLER -#define UNIT_TEST_TEMP_KEY_SECURE 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. -#define UNIT_TEST_NETWORK_KEY 6 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define UNIT_TEST_TEMP_KEY_SECURE \ + 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define UNIT_TEST_NETWORK_KEY \ + 6 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. #else -#define UNIT_TEST_TEMP_KEY_SECURE 0 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. -#define UNIT_TEST_NETWORK_KEY 1 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define UNIT_TEST_TEMP_KEY_SECURE \ + 0 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define UNIT_TEST_NETWORK_KEY \ + 1 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. #endif /** Overview of behavior which should be implemented: @@ -71,35 +71,106 @@ void tearDownSuite(void) { * - Key Verify failure. * */ -#define UNIT_TEST_BUF_SIZE 256 - - -static uint8_t m_test_mem_pool[4][256]; // Statically allocated chunks of memory that can be freely used during the test. - -static uint8_t m_test_public_key_a[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, - 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; - -static uint8_t m_test_obfuscated_public_key_a[] = {0x00, 0x00, 0x00, 0x00, 0x55, 0x66, 0x77, 0x88, - 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, - 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; - -static uint8_t m_temp_key[] = {0x7E, 0xFE, 0x12, 0x32, 0x45, 0x65, 0x78, 0x98, - 0x7E, 0xFE, 0x12, 0x32, 0x45, 0x65, 0x78, 0x98}; - -static uint8_t m_test_network_key_s2_class_0[] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - -static uint8_t m_test_network_key_s2_class_1[] = {0xAA, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - -static uint8_t m_test_network_key_s2_class_2[] = {0xBB, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - -static uint8_t m_test_network_key_s0[] = {0xCA, 0xFE, 0xBA, 0xBE, 0x44, 0x33, 0x22, 0x11, - 0xCA, 0xFE, 0xBA, 0xBE, 0xCC, 0xBB, 0xAA, 0x99}; +#define UNIT_TEST_BUF_SIZE 256 + +static uint8_t m_test_mem_pool + [4] + [256]; // Statically allocated chunks of memory that can be freely used during the test. + +static uint8_t m_test_public_key_a[] + = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, + 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; + +static uint8_t m_test_obfuscated_public_key_a[] + = {0x00, 0x00, 0x00, 0x00, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, + 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; + +static uint8_t m_temp_key[] = {0x7E, + 0xFE, + 0x12, + 0x32, + 0x45, + 0x65, + 0x78, + 0x98, + 0x7E, + 0xFE, + 0x12, + 0x32, + 0x45, + 0x65, + 0x78, + 0x98}; + +static uint8_t m_test_network_key_s2_class_0[] = {0x88, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s2_class_1[] = {0xAA, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s2_class_2[] = {0xBB, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s0[] = {0xCA, + 0xFE, + 0xBA, + 0xBE, + 0x44, + 0x33, + 0x22, + 0x11, + 0xCA, + 0xFE, + 0xBA, + 0xBE, + 0xCC, + 0xBB, + 0xAA, + 0x99}; static s2_connection_t s2_con; /** Event listener for S2 inclusion. @@ -111,26 +182,33 @@ static s2_connection_t s2_con; * * This forward declares the mock funtion used, because the callback is a function pointer with no named declaration. */ -void s2_event_handler(zwave_event_t * p_zwave_evt); +void s2_event_handler(zwave_event_t *p_zwave_evt); /** Forward declaration of helper classes. * All helper classes are implemented in buttom of file to easily keep them seperated from the test cases. */ -void helper_func_kex_report_frame_expect(uint8_t scheme, uint8_t curve, uint8_t keys); +void helper_func_kex_report_frame_expect(uint8_t scheme, + uint8_t curve, + uint8_t keys); void helper_func_kex_get_frame(struct S2 *p_context); -void helper_func_kex_set_frame(struct S2 *p_context, uint8_t scheme, uint8_t keys); +void helper_func_kex_set_frame(struct S2 *p_context, + uint8_t scheme, + uint8_t keys); void helper_func_pub_key_frame(struct S2 *p_context); -void helper_func_echo_kex_report_frame(struct S2 *p_context, uint8_t scheme, uint8_t curve, uint8_t keys); +void helper_func_echo_kex_report_frame(struct S2 *p_context, + uint8_t scheme, + uint8_t curve, + uint8_t keys); void helper_func_net_key_report_frame(struct S2 *p_context, uint8_t key); void helper_func_transfer_end_frame(struct S2 *p_context); -void helper_func_verify_idle_state(struct S2 *p_context, uint8_t scheme, uint8_t keys); +void helper_func_verify_idle_state(struct S2 *p_context, + uint8_t scheme, + uint8_t keys); void helper_func_idle_state(struct S2 *p_context); void helper_func_inclusion_initiated_event(void); static void helper_func_init_s2_conn(void); static void helper_func_init_s2_conn_lr(void); - - /** Verification that the normal flow succeeds in inclusion of a new node when using CSA. * * It verifies the behavior as seen from an including node (Controller node) as described in SDS11274. @@ -138,19 +216,19 @@ static void helper_func_init_s2_conn_lr(void); * When a node is to be included securely it is expected that a ZW_SendData is send. * For this the common S2_send_frame(...) defined in s2.h is used, which will be implemented elsewhere. */ -void test_kex_joining_node_state_machine_csa(void) { +void test_kex_joining_node_state_machine_csa(void) +{ int test_flavour; - for (test_flavour = 0; test_flavour < 2; test_flavour++) - { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + for (test_flavour = 0; test_flavour < 2; test_flavour++) { + uint8_t public_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -193,24 +271,29 @@ void test_kex_joining_node_state_machine_csa(void) { * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x06, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. + uint8_t S2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x06, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -219,23 +302,38 @@ void test_kex_joining_node_state_machine_csa(void) { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[3], &public_key_b[0], sizeof(public_key_b)); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_obfuscated_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0x04; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_obfuscated_public_key_a, sizeof(m_test_obfuscated_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_obfuscated_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length + = 0x04; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_obfuscated_public_key_a, + sizeof(m_test_obfuscated_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -245,10 +343,14 @@ void test_kex_joining_node_state_machine_csa(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x03, 0x02, 0x01, 0x82}; // Note: Echo flag set. - - if (test_flavour == 1) - { + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x03, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. + + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ /* Expect the reserved bit 0x10 to be set in the KEX_SET_ECHO */ @@ -256,79 +358,108 @@ void test_kex_joining_node_state_machine_csa(void) { } mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; - // // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; + // // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); + p_mock->return_code.value = 1; - // // After transmitting Net key verify, we switch back to the tempporary key. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_temp_key; + // // After transmitting Net key verify, we switch back to the tempporary key. + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_temp_key; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_test_network_key_s0; + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s0; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // After transmitting Net key verify, we switch back to the tempporary key. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_temp_key; + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_temp_key; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -346,9 +477,9 @@ void test_kex_joining_node_state_machine_csa(void) { // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expeted to be transmitted. Let's make the s2_send_frame a success. @@ -359,30 +490,40 @@ void test_kex_joining_node_state_machine_csa(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x02, 0x02, 0x01, 0x82}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x02, 0x02, 0x01, 0x82}; - if (test_flavour == 1) - { + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ s2_kex_set_frame[2] |= 0x10; } s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_obfuscated_public_key_a, sizeof(m_test_obfuscated_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_obfuscated_public_key_a, + sizeof(m_test_obfuscated_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. // The challenge response should result in correct pub key being set on the context. - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, DSK_CSA_CHALLENGE_LENGTH); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + s2_inclusion_challenge_response(&s2_context, + 1, + m_test_public_key_a, + DSK_CSA_CHALLENGE_LENGTH); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); // After receiving public key from joining node, the upper layer must specify our public key to be send. (This can also be done on initialization, but must happen no later than the received event). @@ -391,37 +532,52 @@ void test_kex_joining_node_state_machine_csa(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x82}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x82}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] + = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); + uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); s2_context.buf = s2_net_key_report_0_frame; s2_context.length = sizeof(s2_net_key_report_0_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. @@ -430,7 +586,7 @@ void test_kex_joining_node_state_machine_csa(void) { // bit2-7: Reserved. s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, true); @@ -439,20 +595,19 @@ void test_kex_joining_node_state_machine_csa(void) { } /* for(test_flavour) */ } - -void test_kex_joining_node_state_machine_authenticated_lr(void) { +void test_kex_joining_node_state_machine_authenticated_lr(void) +{ int test_flavour; - for (test_flavour = 0; test_flavour < 2; test_flavour++) - { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + for (test_flavour = 0; test_flavour < 2; test_flavour++) { + uint8_t public_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -495,24 +650,29 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x04, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x02};// Requested keys bits. Security 2 class 3 (Long Range Authenticated uses normal Authenticated bit on the radio) + uint8_t S2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x04, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x02}; // Requested keys bits. Security 2 class 3 (Long Range Authenticated uses normal Authenticated bit on the radio) mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -521,23 +681,37 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[5], &public_key_b[2], sizeof(public_key_b) - 2); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x02; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x02; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -547,10 +721,14 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x02}; // Note: Echo flag set. - - if (test_flavour == 1) - { + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x02}; // Note: Echo flag set. + + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ /* Expect the reserved bit 0x10 to be set in the KEX_SET_ECHO */ @@ -558,53 +736,72 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { } mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 3 + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 3 mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_test_network_key_s0; + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s0; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // After transmitting Net key verify, we switch back to the tempporary key. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_temp_key; + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_temp_key; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x02; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x02; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -622,9 +819,9 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expeted to be transmitted. Let's make the s2_send_frame a success. @@ -635,30 +832,37 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 3 (Long Range Authenticated) - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x02}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x02}; - if (test_flavour == 1) - { + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ s2_kex_set_frame[2] |= 0x10; } s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. // The challenge response should result in correct pub key being set on the context. s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); // After receiving public key from joining node, the upper layer must specify our public key to be send. (This can also be done on initialization, but must happen no later than the received event). @@ -667,50 +871,58 @@ void test_kex_joining_node_state_machine_authenticated_lr(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 3 (Long Range Authenticated) - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x02}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x02}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; // Keys requested, Security2, class 3 using non-LR bits even for LR - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] + = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; // Keys requested, Security2, class 3 using non-LR bits even for LR + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, true); mock_calls_verify(); } /* for(test_flavour) */ - } -void test_kex_joining_node_state_machine_ssa(void) { +void test_kex_joining_node_state_machine_ssa(void) +{ int test_flavour; - for (test_flavour = 0; test_flavour < 2; test_flavour++) - { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + for (test_flavour = 0; test_flavour < 2; test_flavour++) { + uint8_t public_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -753,24 +965,29 @@ void test_kex_joining_node_state_machine_ssa(void) { * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x04, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. + uint8_t S2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x04, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -779,23 +996,37 @@ void test_kex_joining_node_state_machine_ssa(void) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[5], &public_key_b[2], sizeof(public_key_b) - 2); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -805,10 +1036,14 @@ void test_kex_joining_node_state_machine_ssa(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; // Note: Echo flag set. - - if (test_flavour == 1) - { + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. + + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ /* Expect the reserved bit 0x10 to be set in the KEX_SET_ECHO */ @@ -816,79 +1051,108 @@ void test_kex_joining_node_state_machine_ssa(void) { } mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; - // // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; + // // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); + p_mock->return_code.value = 1; - // // After transmitting Net key verify, we switch back to the tempporary key. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_temp_key; + // // After transmitting Net key verify, we switch back to the tempporary key. + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_temp_key; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_test_network_key_s0; + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s0; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // After transmitting Net key verify, we switch back to the tempporary key. - // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - // p_mock->expect_arg[1].pointer = m_temp_key; + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_temp_key; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -906,9 +1170,9 @@ void test_kex_joining_node_state_machine_ssa(void) { // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expeted to be transmitted. Let's make the s2_send_frame a success. @@ -919,30 +1183,37 @@ void test_kex_joining_node_state_machine_ssa(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - if (test_flavour == 1) - { + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ s2_kex_set_frame[2] |= 0x10; } s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. // The challenge response should result in correct pub key being set on the context. s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); // After receiving public key from joining node, the upper layer must specify our public key to be send. (This can also be done on initialization, but must happen no later than the received event). @@ -951,37 +1222,52 @@ void test_kex_joining_node_state_machine_ssa(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x82}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x82}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] + = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); + uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); s2_context.buf = s2_net_key_report_0_frame; s2_context.length = sizeof(s2_net_key_report_0_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. @@ -990,7 +1276,7 @@ void test_kex_joining_node_state_machine_ssa(void) { // bit2-7: Reserved. s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, true); @@ -1007,16 +1293,17 @@ void test_kex_joining_node_state_machine_ssa(void) { * When a node is to be included securely it is expected that a ZW_SendData is send. * For this the common S2_send_frame(...) defined in s2.h is used, which will be implemented elsewhere. */ -void test_kex_joining_node_state_machine_unauthenticated(void) { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_joining_node_state_machine_unauthenticated(void) +{ + uint8_t public_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -1059,23 +1346,28 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x04, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x01};// Requested keys bits. Security 2 class 0 key. + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x04, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x01}; // Requested keys bits. Security 2 class 0 key. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -1084,22 +1376,33 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. memcpy(&s2_public_key_frame[3], public_key_b, sizeof(public_key_b)); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x01; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x01; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -1109,50 +1412,74 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x01}; // Note: Echo flag set. + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x01}; // Note: Echo flag set. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x01}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; -// // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. -// mock_call_expect(TO_STR(S2_network_key_update), &p_mock); -// p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. -// p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; + // // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); + p_mock->return_code.value = 1; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x01; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x01; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -1166,13 +1493,13 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { s2_inclusion_set_event_handler(s2_event_handler); helper_func_init_s2_conn(); - s2_inclusion_joining_start(&s2_context, &s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expeted to be transmitted. Let's make the s2_send_frame a success. @@ -1183,17 +1510,23 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x01}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x01}; s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); @@ -1205,38 +1538,46 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x01}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x01}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x01, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_0)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x01, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_0)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); -// // S2 Transfer end frame received. -// // bit0: Key request complete not set, -// // bit1: Key verified set, -// // bit2-7: Reserved. -// s2_context.buf = s2_transfer_end_frame; -// s2_context.length = sizeof(s2_transfer_end_frame); -// s2_con.class_id = 0x00; -// s2_inclusion_post_event_peer(&s2_context, &s2_con); + // // S2 Transfer end frame received. + // // bit0: Key request complete not set, + // // bit1: Key verified set, + // // bit2-7: Reserved. + // s2_context.buf = s2_transfer_end_frame; + // s2_context.length = sizeof(s2_transfer_end_frame); + // s2_con.class_id = 0x00; + // s2_inclusion_post_event_peer(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, true); @@ -1254,10 +1595,11 @@ void test_kex_joining_node_state_machine_unauthenticated(void) { * relevant for this test as they are verified in: test_kex_joining_node_state_machine() * NOTE: messages related to Timeout will be verified in this test. */ -void test_kex_joining_timer_handling(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; +void test_kex_joining_timer_handling(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; mock_calls_clear(); mock_call_use_as_stub(TO_STR(S2_send_frame)); @@ -1369,10 +1711,9 @@ void test_kex_joining_timer_handling(void) { // When receiving send done as confirmation of the final transfer end, we expect the timer to be stopped. mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); s2_inclusion_neighbor_discovery_complete(&s2_context); @@ -1434,21 +1775,24 @@ void test_kex_joining_timer_handling(void) { * As this test case must covers timeout in ANY state, it will loop over the expectations and * decrement a counter to go one step further on each loop. */ - #define NO_OF_STATES 6 -void test_kex_inclusion_timeout_all_states(void) { - mock_t * p_mock; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +#define NO_OF_STATES 6 +void test_kex_inclusion_timeout_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -1467,52 +1811,54 @@ void test_kex_inclusion_timeout_all_states(void) { s2_inclusion_init(0x02, 0x01, 0x82); /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < NO_OF_STATES; i++) - { + for (i = 0; i < NO_OF_STATES; i++) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); /* State is now S2_AWAITING_KEX_GET */ - if (i == 0){ + if (i == 0) { // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_JOINING_COMPLETE_NEVER_STARTED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_JOINING_COMPLETE_NEVER_STARTED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys + = 0; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; - p_mock->compare_rule_arg[0] = COMPARE_STRICT; + p_mock->compare_rule_arg[0] = COMPARE_STRICT; // Trigger a timeout. s2_inclusion_notify_timeout(&s2_context); - continue; // if first iteration, continue here to test timeout for timeout. + continue; // if first iteration, continue here to test timeout for timeout. } helper_func_inclusion_initiated_event(); /* State is now S2_AWAITING_KEX_SET */ // Expect a S2 KEX Report to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 1) - { + if (i == 1) { // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Trigger a timeout. s2_inclusion_notify_timeout(&s2_context); - continue; // if second iteration, break here to test timeout for timeout. + continue; // if second iteration, break here to test timeout for timeout. } // When the KEX Set is received, we expect a call to the keystore in order to obtain our public key. @@ -1520,41 +1866,81 @@ void test_kex_inclusion_timeout_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); helper_func_kex_set_frame(&s2_context, 0x02, 0x82); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 2){ + if (i == 2) { // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Trigger a timeout. s2_inclusion_notify_timeout(&s2_context); - continue; // if third iteration, break here to test timeout for timeout. + continue; // if third iteration, break here to test timeout for timeout. } // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -1566,30 +1952,37 @@ void test_kex_inclusion_timeout_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); helper_func_pub_key_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - if (i == 3){ + if (i == 3) { uint8_t i; // The ECHO Kex Set is a special case where both a send done/failed can be returned but packet is dropped by remote side in case it waits for user input. // Each timeoyt/time between retry is 10 seconds. User input timeout is 240 seconds, thus the system should not abort inclusion until 240s/10s = 24 timeouts has occured. - for (i = 0; i < 23; i++) - { + for (i = 0; i < 23; i++) { // When timeout occurs we expect a retry of the echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); // Trigger a timeout. s2_inclusion_notify_timeout(&s2_context); @@ -1597,60 +1990,66 @@ void test_kex_inclusion_timeout_all_states(void) { // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Trigger the final timeout. s2_inclusion_notify_timeout(&s2_context); - continue; // if fourth iteration, break here to test timeout for timeout. + continue; // if fourth iteration, break here to test timeout for timeout. } // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); helper_func_echo_kex_report_frame(&s2_context, 0x02, 0x01, 0x82); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 4){ + if (i == 4) { // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Trigger a timeout. s2_inclusion_notify_timeout(&s2_context); - continue; // if fifth iteration, break here to test timeout for timeout. + continue; // if fifth iteration, break here to test timeout for timeout. } // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); helper_func_net_key_report_frame(&s2_context, 0x02); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 5){ + if (i == 5) { // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Trigger a timeout. s2_inclusion_notify_timeout(&s2_context); - continue; // if sixth iteration, break here to test timeout for timeout. + continue; // if sixth iteration, break here to test timeout for timeout. } } @@ -1667,20 +2066,23 @@ void test_kex_inclusion_timeout_all_states(void) { * * An error should still be returned upwards to the application. */ -void test_kex_inclusion_invalid_frame_order_all_states(void) { - mock_t * p_mock; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_invalid_frame_order_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -1698,59 +2100,62 @@ void test_kex_inclusion_invalid_frame_order_all_states(void) { s2_inclusion_init(0x02, 0x01, 0x82); /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < 5; i++) - { + for (i = 0; i < 5; i++) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); - if (i == 0){ - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x01}; + s2_inclusion_joining_start(&s2_context, &s2_con, 0); + if (i == 0) { + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x01}; // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Let's try to directly got to KEX Set. memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); s2_context.length = sizeof(s2_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - continue; // if first iteration, continue here to test timeout for timeout. + continue; // if first iteration, continue here to test timeout for timeout. } helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 1) - { + if (i == 1) { // The invalid frame - Let's send a KEX Report the opposite direction. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x03}; + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x03}; // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Send the invalid frame. memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); s2_context.length = sizeof(s2_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - continue; // if second iteration, break here to test timeout for timeout. + continue; // if second iteration, break here to test timeout for timeout. } // When the KEX Set is received, we expect a call to the keystore in order to obtain our public key. @@ -1758,46 +2163,87 @@ void test_kex_inclusion_invalid_frame_order_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); helper_func_kex_set_frame(&s2_context, 0x02, 0x82); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 2){ + if (i == 2) { // In case including node has for unknown reason (could be timeout) has restarted the // inclusion, we could experience an unexpected KEX Get. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Send the invalid frame. memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); s2_context.length = sizeof(s2_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); - continue; // if third iteration, break here to test timeout for timeout. + continue; // if third iteration, break here to test timeout for timeout. } // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data + .challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -1809,11 +2255,14 @@ void test_kex_inclusion_invalid_frame_order_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); @@ -1821,57 +2270,67 @@ void test_kex_inclusion_invalid_frame_order_all_states(void) { s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - if (i == 3){ - uint8_t s2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; + if (i == 3) { + uint8_t s2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Send the invalid frame. memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); s2_context.length = sizeof(s2_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); continue; } // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); helper_func_echo_kex_report_frame(&s2_context, 0x02, 0x01, 0x82); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 4){ + if (i == 4) { uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END}; // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; // Send the invalid frame. memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); s2_context.length = sizeof(s2_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); continue; } // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); @@ -1889,20 +2348,23 @@ void test_kex_inclusion_invalid_frame_order_all_states(void) { /** Test case for ensuring that the inclusion state machine will not abort if an older inclusion * frame is received multiple times, as example due to retransmission or routing. */ -void test_kex_inclusion_duplicate_frame_all_states(void) { - mock_t * p_mock; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_duplicate_frame_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -1928,10 +2390,13 @@ void test_kex_inclusion_duplicate_frame_all_states(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -1941,27 +2406,66 @@ void test_kex_inclusion_duplicate_frame_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); p_mock->return_code.value = 1; // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req + .public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -1973,62 +2477,88 @@ void test_kex_inclusion_duplicate_frame_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); p_mock->return_code.value = 1; // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); p_mock->return_code.value = 1; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_complete_event; @@ -2038,12 +2568,11 @@ void test_kex_inclusion_duplicate_frame_all_states(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); - /** The loop which will set up the expectation based on the round. */ -// for (i = 4; i < NO_OF_STATES; i++) - for (i = 0; i < 7; i++) - { + /** The loop which will set up the expectation based on the round. */ + // for (i = 4; i < NO_OF_STATES; i++) + for (i = 0; i < 7; i++) { helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -2059,8 +2588,7 @@ void test_kex_inclusion_duplicate_frame_all_states(void) { helper_func_pub_key_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); - if (i == 2) - { + if (i == 2) { // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); @@ -2110,22 +2638,44 @@ void test_kex_inclusion_duplicate_frame_all_states(void) { * schemes supported by both inclusion and joining node. If this cannot be established * between the node, then it must be ensured that appropriate failure is returned. */ -void test_kex_inclusion_error_schemes(void) { - mock_t * p_mock; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6]; - uint8_t s2_kex_set_frame[6]; - struct S2 s2_context; +void test_kex_inclusion_error_schemes(void) +{ + mock_t *p_mock; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6]; + uint8_t s2_kex_set_frame[6]; + struct S2 s2_context; uint8_t scheme_scheme_fail_test_vector[][4] = { - {0x02, 0x01, 0x00, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. - {0x02, 0x01, 0x01, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. - {0x02, 0x01, 0x03, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. - {0x02, 0x01, 0x04, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. - {0x02, 0x01, 0x06, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. - {0x02, 0x01, 0x80, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. - {0x02, 0x01, 0xFF, 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0x00, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0x01, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0x03, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0x04, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0x06, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0x80, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. + {0x02, + 0x01, + 0xFF, + 0x01}, // Requested Scheme 1 = true, key request don't care. Invalid scheme in Set, This should return FAIL_KEY_REPORT. }; mock_calls_clear(); @@ -2139,39 +2689,49 @@ void test_kex_inclusion_error_schemes(void) { s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - for (i = 0; i < ELEM_COUNT(scheme_scheme_fail_test_vector); i++) - { - + for (i = 0; i < ELEM_COUNT(scheme_scheme_fail_test_vector); i++) { /**************************** * Mock expectation section * ****************************/ - s2_inclusion_init(scheme_scheme_fail_test_vector[i][0], 0x01, scheme_scheme_fail_test_vector[i][1]); + s2_inclusion_init(scheme_scheme_fail_test_vector[i][0], + 0x01, + scheme_scheme_fail_test_vector[i][1]); helper_func_inclusion_initiated_event(); // After including node has sent a KEX Get, a response with above settings is expected. s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x04, // reserved | NLS support | Request CSA | Echo - s2_kex_report_frame[3] = scheme_scheme_fail_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = scheme_scheme_fail_test_vector[i][1]; // Requested keys bit. + s2_kex_report_frame[2] + = 0x04, // reserved | NLS support | Request CSA | Echo + s2_kex_report_frame[3] + = scheme_scheme_fail_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] + = scheme_scheme_fail_test_vector[i][1]; // Requested keys bit. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_report_frame); // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. - uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x02}; // KEX_FAIL_KEX_SCHEME = 0x02 + uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_FAIL, + 0x02}; // KEX_FAIL_KEX_SCHEME = 0x02 mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x02; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; @@ -2182,7 +2742,7 @@ void test_kex_inclusion_error_schemes(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. helper_func_kex_get_frame(&s2_context); @@ -2191,14 +2751,17 @@ void test_kex_inclusion_error_schemes(void) { // KEX Set frame received - With an unsupported/not requested scheme set. s2_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; s2_kex_set_frame[1] = KEX_SET; - s2_kex_set_frame[2] = 0x04, // reserved | NLS support | Request CSA | Echo - s2_kex_set_frame[3] = scheme_scheme_fail_test_vector[i][2]; // Supported schemes. - s2_kex_set_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_set_frame[5] = scheme_scheme_fail_test_vector[i][3]; // Requested keys bit. + s2_kex_set_frame[2] = 0x04, // reserved | NLS support | Request CSA | Echo + s2_kex_set_frame[3] + = scheme_scheme_fail_test_vector[i][2]; // Supported schemes. + s2_kex_set_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_set_frame[5] + = scheme_scheme_fail_test_vector[i][3]; // Requested keys bit. - s2_context.buf = s2_kex_set_frame; - s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_context.buf = s2_kex_set_frame; + s2_context.length = sizeof(s2_kex_set_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, 1); @@ -2208,7 +2771,7 @@ void test_kex_inclusion_error_schemes(void) { helper_func_verify_idle_state(&s2_context, 0x02, 0x01); mock_calls_verify(); -// s2_kex_set_frame[0] = s2_kex_set_frame[0]; + // s2_kex_set_frame[0] = s2_kex_set_frame[0]; } /** Test case for ensuring that a proper error message is returned in case the inclusion state @@ -2218,54 +2781,43 @@ void test_kex_inclusion_init_errors(void) { uint8_t ret_val; - uint8_t valid_schemes_bits = 0x02; // Scheme 1 supported. - uint8_t valid_curve_bits = 0x01; // Curve25519 supported. - uint8_t valid_keys_bits = SECURITY_2_KEY_MASK; // Security 2, class 0, 1, 2, 3(LR), 4(LR) keys and Security 0 network key. + uint8_t valid_schemes_bits = 0x02; // Scheme 1 supported. + uint8_t valid_curve_bits = 0x01; // Curve25519 supported. + uint8_t valid_keys_bits + = SECURITY_2_KEY_MASK; // Security 2, class 0, 1, 2, 3(LR), 4(LR) keys and Security 0 network key. uint8_t i; - for (i = 0; i < 255; i++) - { - if ((~valid_schemes_bits & i) || (i == 0)) - { + for (i = 0; i < 255; i++) { + if ((~valid_schemes_bits & i) || (i == 0)) { ret_val = s2_inclusion_init(i, 0x01, 0x81); TEST_ASSERT_EQUAL_UINT8(0x02, ret_val); } - if (((~valid_schemes_bits & i) == 0) && - (valid_schemes_bits & i)) - { + if (((~valid_schemes_bits & i) == 0) && (valid_schemes_bits & i)) { ret_val = s2_inclusion_init(i, 0x01, 0x81); TEST_ASSERT_EQUAL_UINT8(0x00, ret_val); } } - for (i = 0; i < 255; i++) - { - if ((~valid_curve_bits & i) || (i == 0)) - { + for (i = 0; i < 255; i++) { + if ((~valid_curve_bits & i) || (i == 0)) { ret_val = s2_inclusion_init(0x02, i, 0x81); TEST_ASSERT_EQUAL_UINT8(0x03, ret_val); } - if ((~valid_curve_bits & i) == 0 && - (valid_curve_bits & i)) - { + if ((~valid_curve_bits & i) == 0 && (valid_curve_bits & i)) { ret_val = s2_inclusion_init(0x02, i, 0x81); TEST_ASSERT_EQUAL_UINT8(0x00, ret_val); } } - for (i = 0; i < 255; i++) - { - if ((~valid_keys_bits & i) || (i == 0)) - { + for (i = 0; i < 255; i++) { + if ((~valid_keys_bits & i) || (i == 0)) { ret_val = s2_inclusion_init(0x02, 0x01, i); TEST_ASSERT_EQUAL_UINT8(0x01, ret_val); } - if ((~valid_keys_bits & i) == 0 && - (valid_keys_bits & i)) - { + if ((~valid_keys_bits & i) == 0 && (valid_keys_bits & i)) { ret_val = s2_inclusion_init(0x02, 0x01, i); TEST_ASSERT_EQUAL_UINT8(0x00, ret_val); } @@ -2281,20 +2833,25 @@ void test_kex_inclusion_init_errors(void) * * Test: This test case will a KEX_FAIL_CURVES is returned when invalid set of schemes is requested. */ -void test_kex_inclusion_error_curves(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t i; - struct S2 s2_context; - - uint8_t s2_kex_report_frame[6]; - uint8_t s2_kex_set_frame[6]; +void test_kex_inclusion_error_curves(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t i; + struct S2 s2_context; + + uint8_t s2_kex_report_frame[6]; + uint8_t s2_kex_set_frame[6]; uint8_t curves_fail_test_vector[][2] = { - {0x01, 0x00}, // Supported curve25519 = true, No curves selected, This should return FAIL_KEY_CURVES. - {0x01, 0x02}, // Supported curve25519 = true, Unknown/unsupported curve selected, This should return FAIL_KEY_CURVES. - {0x01, 0xF0}, // Supported curve25519 = true, Multiple unknown/unsupported curve selected, This should return FAIL_KEY_CURVES. - {0x01, 0x11}, // Supported curve25519 = true, Multiple unknown/unsupported but also a supported curve selected, This should return FAIL_KEY_CURVES. + {0x01, + 0x00}, // Supported curve25519 = true, No curves selected, This should return FAIL_KEY_CURVES. + {0x01, + 0x02}, // Supported curve25519 = true, Unknown/unsupported curve selected, This should return FAIL_KEY_CURVES. + {0x01, + 0xF0}, // Supported curve25519 = true, Multiple unknown/unsupported curve selected, This should return FAIL_KEY_CURVES. + {0x01, + 0x11}, // Supported curve25519 = true, Multiple unknown/unsupported but also a supported curve selected, This should return FAIL_KEY_CURVES. }; mock_calls_clear(); @@ -2308,9 +2865,7 @@ void test_kex_inclusion_error_curves(void) { s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - for (i = 0; i < ELEM_COUNT(curves_fail_test_vector); i++) - { - + for (i = 0; i < ELEM_COUNT(curves_fail_test_vector); i++) { /**************************** * Mock expectation section * ****************************/ @@ -2321,25 +2876,33 @@ void test_kex_inclusion_error_curves(void) { // After including node has sent a KEX Get, a response with above settings is expected. s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x04, // reserved | NLS support | Request CSA | Echo - s2_kex_report_frame[3] = 0x02; // Supported schemes. - s2_kex_report_frame[4] = curves_fail_test_vector[i][0], // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = 0x01; // Requested keys bit, Class1. + s2_kex_report_frame[2] + = 0x04, // reserved | NLS support | Request CSA | Echo + s2_kex_report_frame[3] = 0x02; // Supported schemes. + s2_kex_report_frame[4] = curves_fail_test_vector + [i][0], // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] = 0x01; // Requested keys bit, Class1. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_report_frame); // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. - uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x03}; // KEX_FAIL_KEX_CURVES = 0x03 + uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_FAIL, + 0x03}; // KEX_FAIL_KEX_CURVES = 0x03 mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x03; mock_call_expect(TO_STR(s2_event_handler), &p_mock); @@ -2351,23 +2914,24 @@ void test_kex_inclusion_error_curves(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); // KEX Set frame received - With an unsupported/not requested scheme set. - s2_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; - s2_kex_set_frame[1] = KEX_SET; - s2_kex_set_frame[2] = 0x00, // bit 0 is echo field, rest are reserved - s2_kex_set_frame[3] = 0x02; // Supported schemes. - s2_kex_set_frame[4] = curves_fail_test_vector[i][1], // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_set_frame[5] = 0x01; // Requested keys bit. + s2_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; + s2_kex_set_frame[1] = KEX_SET; + s2_kex_set_frame[2] = 0x00, // bit 0 is echo field, rest are reserved + s2_kex_set_frame[3] = 0x02; // Supported schemes. + s2_kex_set_frame[4] = curves_fail_test_vector + [i][1], // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_set_frame[5] = 0x01; // Requested keys bit. - s2_context.buf = s2_kex_set_frame; - s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_context.buf = s2_kex_set_frame; + s2_context.length = sizeof(s2_kex_set_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); @@ -2378,7 +2942,7 @@ void test_kex_inclusion_error_curves(void) { helper_func_verify_idle_state(&s2_context, 0x02, 0x01); mock_calls_verify(); -// s2_kex_set_frame[0] = s2_kex_set_frame[0]; + // s2_kex_set_frame[0] = s2_kex_set_frame[0]; mock_calls_verify(); } @@ -2391,26 +2955,37 @@ void test_kex_inclusion_error_curves(void) { * * Test: This test case will a KEX_FAIL_KEY is returned when invalid set of schemes/keys is requested. */ -void test_kex_inclusion_error_keys(void) { - uint32_t i; - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6]; - uint8_t s2_kex_set_frame[6]; - struct S2 s2_context; - - uint8_t s2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x01}; // KEX_FAIL_KEX_KEY = 0x01 - uint8_t key_request_fail_test_vector[][2] = { - {0x80, 0x83}, // Key request S2 = no, key request S0 = yes. Keys granted, S2 = yes, S0 = yes. This should return FAIL_KEY_REPORT. - {0x01, 0x03}, // Key request S2 = some, key request S0 = no. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. - {0x02, 0x03}, // Key request S2 = some, key request S0 = no. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. - {0x81, 0x03}, // Key request S2 = some, key request S0 = yes. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. - {0x82, 0x03}, // Key request S2 = some, key request S0 = yes. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. - {0x83, 0x04}, // Key request S2 = yes, key request S0 = yes. Keys granted, Sx = yes, S0 = no. This should return FAIL_KEY_REPORT. }; - {0x83, 0xFF}, // Key request S2 = yes, key request S0 = yes. Keys granted, Sx = yes, S0 = no. This should return FAIL_KEY_REPORT. }; - {0x83, 0x7C}, // Key request S2 = yes, key request S0 = yes. Keys granted, Sx = yes, S0 = no. This should return FAIL_KEY_REPORT. }; - {0x03, 0x07}, // Key request S2 = yes , key request S0 = no. Keys granted, S2 = yes, Sx = yes. This should return FAIL_KEY_REPORT. +void test_kex_inclusion_error_keys(void) +{ + uint32_t i; + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6]; + uint8_t s2_kex_set_frame[6]; + struct S2 s2_context; + + uint8_t s2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x01}; // KEX_FAIL_KEX_KEY = 0x01 + uint8_t key_request_fail_test_vector[][2] = { + {0x80, + 0x83}, // Key request S2 = no, key request S0 = yes. Keys granted, S2 = yes, S0 = yes. This should return FAIL_KEY_REPORT. + {0x01, + 0x03}, // Key request S2 = some, key request S0 = no. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. + {0x02, + 0x03}, // Key request S2 = some, key request S0 = no. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. + {0x81, + 0x03}, // Key request S2 = some, key request S0 = yes. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. + {0x82, + 0x03}, // Key request S2 = some, key request S0 = yes. Keys granted, S2 = all, S0 = no. This should return FAIL_KEY_REPORT. + {0x83, + 0x04}, // Key request S2 = yes, key request S0 = yes. Keys granted, Sx = yes, S0 = no. This should return FAIL_KEY_REPORT. }; + {0x83, + 0xFF}, // Key request S2 = yes, key request S0 = yes. Keys granted, Sx = yes, S0 = no. This should return FAIL_KEY_REPORT. }; + {0x83, + 0x7C}, // Key request S2 = yes, key request S0 = yes. Keys granted, Sx = yes, S0 = no. This should return FAIL_KEY_REPORT. }; + {0x03, + 0x07}, // Key request S2 = yes , key request S0 = no. Keys granted, S2 = yes, Sx = yes. This should return FAIL_KEY_REPORT. }; mock_calls_clear(); @@ -2424,9 +2999,7 @@ void test_kex_inclusion_error_keys(void) { s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - for (i = 0; i < ELEM_COUNT(key_request_fail_test_vector); i++) - { - + for (i = 0; i < ELEM_COUNT(key_request_fail_test_vector); i++) { /**************************** * Mock expectation section * ****************************/ @@ -2437,24 +3010,31 @@ void test_kex_inclusion_error_keys(void) { // After including node has sent a KEX Get, a response with above settings is expected. s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x04, // reserved | NLS support | Request CSA | Echo - s2_kex_report_frame[3] = 0x02; // Supported schemes. - s2_kex_report_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = key_request_fail_test_vector[i][0]; // Requested keys bit. + s2_kex_report_frame[2] + = 0x04, // reserved | NLS support | Request CSA | Echo + s2_kex_report_frame[3] = 0x02; // Supported schemes. + s2_kex_report_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] + = key_request_fail_test_vector[i][0]; // Requested keys bit. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_report_frame); // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_error_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_error_frame); - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x01; mock_call_expect(TO_STR(s2_event_handler), &p_mock); @@ -2466,23 +3046,25 @@ void test_kex_inclusion_error_keys(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); // KEX Set frame received - With an unsupported/not requested scheme set. - s2_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; - s2_kex_set_frame[1] = KEX_SET; - s2_kex_set_frame[2] = 0x00, // bit 0 is echo field, rest are reserved - s2_kex_set_frame[3] = 0x02; // Supported schemes. - s2_kex_set_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_set_frame[5] = key_request_fail_test_vector[i][1]; // Granted keys bit. + s2_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; + s2_kex_set_frame[1] = KEX_SET; + s2_kex_set_frame[2] = 0x00, // bit 0 is echo field, rest are reserved + s2_kex_set_frame[3] = 0x02; // Supported schemes. + s2_kex_set_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_set_frame[5] + = key_request_fail_test_vector[i][1]; // Granted keys bit. - s2_context.buf = s2_kex_set_frame; - s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_context.buf = s2_kex_set_frame; + s2_context.length = sizeof(s2_kex_set_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, 1); @@ -2492,7 +3074,7 @@ void test_kex_inclusion_error_keys(void) { helper_func_verify_idle_state(&s2_context, 0x02, 0x03); mock_calls_verify(); -// s2_kex_set_frame[0] = s2_kex_set_frame[0]; + // s2_kex_set_frame[0] = s2_kex_set_frame[0]; } /** Test case for ensuring correct handling of node inclusion in case the including node is @@ -2504,15 +3086,18 @@ void test_kex_inclusion_error_keys(void) { * Test: This test case will ensure that the state machine returns to idle as the wrong including * bit is identical to a unexpected frame at this stages in the state machine. */ -void test_kex_inclusion_error_public_key_including_bit(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_error_public_key_including_bit(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -2536,10 +3121,13 @@ void test_kex_inclusion_error_public_key_including_bit(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - static uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x83}; + static uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x83}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); @@ -2548,21 +3136,53 @@ void test_kex_inclusion_error_public_key_including_bit(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - static uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + static uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; // If the node uses only unauthenticated keys, then full public key is expected, else the first two bytes are zero'ed out. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0; mock_call_expect(TO_STR(s2_event_handler), &p_mock); @@ -2574,7 +3194,7 @@ void test_kex_inclusion_error_public_key_including_bit(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -2586,11 +3206,10 @@ void test_kex_inclusion_error_public_key_including_bit(void) { frame_buffer[1] = PUBLIC_KEY_REPORT; frame_buffer[2] = 0x00; memcpy(&frame_buffer[3], m_test_public_key_a, sizeof(m_test_public_key_a)); - s2_context.length = 3 + sizeof(m_test_public_key_a); - s2_con.class_id = 0xFF; + s2_context.length = 3 + sizeof(m_test_public_key_a); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - helper_func_verify_idle_state(&s2_context, 0x02, 0x83); mock_calls_verify(); @@ -2599,19 +3218,22 @@ void test_kex_inclusion_error_public_key_including_bit(void) { /** Test case for ensuring correct handling of node inclusion in case the including node is * transmitting frames with reserved bits set (which should be ignored). */ -void test_kex_inclusion_public_key_reserved_bits(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_public_key_reserved_bits(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -2637,10 +3259,13 @@ void test_kex_inclusion_public_key_reserved_bits(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -2650,27 +3275,66 @@ void test_kex_inclusion_public_key_reserved_bits(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); p_mock->return_code.value = 1; // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req + .public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -2682,62 +3346,88 @@ void test_kex_inclusion_public_key_reserved_bits(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); p_mock->return_code.value = 1; // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); p_mock->return_code.value = 1; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_complete_event; @@ -2747,7 +3437,7 @@ void test_kex_inclusion_public_key_reserved_bits(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -2757,11 +3447,12 @@ void test_kex_inclusion_public_key_reserved_bits(void) { frame_buffer[0] = COMMAND_CLASS_SECURITY_2; frame_buffer[1] = PUBLIC_KEY_REPORT; - frame_buffer[2] = 0xA5; // Setting a couple of reserved bits which should be ignored on remote side. + frame_buffer[2] + = 0xA5; // Setting a couple of reserved bits which should be ignored on remote side. memcpy(&frame_buffer[3], m_test_public_key_a, sizeof(m_test_public_key_a)); - s2_context.buf = frame_buffer; - s2_context.length = 3 + sizeof(m_test_public_key_a); - s2_con.class_id = 0xFF; + s2_context.buf = frame_buffer; + s2_context.length = 3 + sizeof(m_test_public_key_a); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. @@ -2795,113 +3486,356 @@ void test_kex_inclusion_public_key_reserved_bits(void) { * * Test: This test case will verify that a KEX_FAIL_AUTH is returned if the echo'ed KEX Report dod not match. */ -void test_kex_inclusion_error_echo_kex_report(void) { - uint32_t i; - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t echo_kex_report_fail_test_vector[][4] = { +void test_kex_inclusion_error_echo_kex_report(void) +{ + uint32_t i; + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t echo_kex_report_fail_test_vector[][4] = { // Scheme errors. - {0x83, 0x00, 0x01, 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x01, 0x01, 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x03, 0x01, 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x80, 0x01, 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0xFF, 0x01, 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x00, + 0x01, + 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x01, + 0x01, + 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x03, + 0x01, + 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x80, + 0x01, + 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0xFF, + 0x01, + 0x83}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=unknown/mixed, curve=curve25519, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. // Curve errors. - {0x83, 0x02, 0x00, 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x02, 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x03, 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x80, 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0xFF, 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x00, + 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x02, + 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x03, + 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x80, + 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0xFF, + 0x82}, // Key request S2 = yes, key request S0 = yes. Echo report, scheme=1, curve=unknown/mixed, keys=S2 - class 0/1, S0. This should return KEX_FAIL_AUTH. // Key errors. - {0x83, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x83, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - - {0x81, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x81, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - - {0x82, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x82, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - - {0x80, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x80, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - - {0x01, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x01, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - - {0x02, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x02, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - - {0x03, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. - {0x03, 0x02, 0x01, 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x83, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + + {0x81, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x81, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + + {0x82, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x82, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + + {0x80, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x80, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + + {0x01, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x01, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + + {0x02, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x03}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x02, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + + {0x03, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x80}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x81}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x82}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x83}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x01}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x02}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0xFF}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x00}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. + {0x03, + 0x02, + 0x01, + 0x7C}, // ECHO KEX Report - Error in key field. This should return KEX_FAIL_AUTH. }; mock_calls_clear(); @@ -2919,9 +3853,7 @@ void test_kex_inclusion_error_echo_kex_report(void) { s2_inclusion_set_event_handler(s2_event_handler); /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < ELEM_COUNT(echo_kex_report_fail_test_vector); i++) - { - + for (i = 0; i < ELEM_COUNT(echo_kex_report_fail_test_vector); i++) { /**************************** * Mock expectation section * ****************************/ @@ -2930,104 +3862,148 @@ void test_kex_inclusion_error_echo_kex_report(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - static uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x00}; + static uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x00}; S2_kex_report_frame[5] = echo_kex_report_fail_test_vector[i][0]; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); // When the KEX Set is received, we expect a call to the keystore in order to obtain our public key. // Use dynamic keypair if only S0 and/or S2 unauthenticated are requested - if(0 != (echo_kex_report_fail_test_vector[i][0] & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if (0 + != (echo_kex_report_fail_test_vector[i][0] + & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); } p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - static uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + static uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; // If the node uses only unauthenticated keys, then full public key is expected, else the first two bytes are zero'ed out. - if (0x06 & echo_kex_report_fail_test_vector[i][0]) - { + if (0x06 & echo_kex_report_fail_test_vector[i][0]) { S2_pub_key_B_frame[3] = 0x00; S2_pub_key_B_frame[4] = 0x00; - } - else - { + } else { S2_pub_key_B_frame[3] = 0xAA; S2_pub_key_B_frame[4] = 0xBB; } mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; -// p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = echo_kex_report_fail_test_vector[i][0]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = echo_kex_report_fail_test_vector[i][0]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = echo_kex_report_fail_test_vector[i][0]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = echo_kex_report_fail_test_vector[i][0]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; // When receiving public key A, then we expect that both our public and private keys are requested from the keystore. // Use dynamic keypair if only S0 and/or S2 unauthenticated are requested - if(0 != (echo_kex_report_fail_test_vector[i][0] & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if (0 + != (echo_kex_report_fail_test_vector[i][0] + & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) { mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_private_key_read), &p_mock); } p_mock->output_arg[0].pointer = private_key_b; // Use dynamic keypair if only S0 and/or S2 unauthenticated are requested - if(0 != (echo_kex_report_fail_test_vector[i][0] & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + if (0 + != (echo_kex_report_fail_test_vector[i][0] + & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); } p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - static uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x00}; + static uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x00}; S2_echo_kex_set_frame[5] = echo_kex_report_fail_test_vector[i][0]; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); // Expect a S2 KEX Fail as the including node received an Key Set command. - uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_AUTH = 0x07 + uint8_t S2_kex_set_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_AUTH = 0x07 mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x07; mock_call_expect(TO_STR(s2_event_handler), &p_mock); @@ -3039,12 +4015,14 @@ void test_kex_inclusion_error_echo_kex_report(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); - helper_func_kex_set_frame(&s2_context, 0x02, echo_kex_report_fail_test_vector[i][0]); + helper_func_kex_set_frame(&s2_context, + 0x02, + echo_kex_report_fail_test_vector[i][0]); s2_inclusion_post_event(&s2_context, &s2_con); helper_func_pub_key_frame(&s2_context); @@ -3052,9 +4030,10 @@ void test_kex_inclusion_error_echo_kex_report(void) { s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - helper_func_echo_kex_report_frame(&s2_context, echo_kex_report_fail_test_vector[i][1], - echo_kex_report_fail_test_vector[i][2], - echo_kex_report_fail_test_vector[i][3]); + helper_func_echo_kex_report_frame(&s2_context, + echo_kex_report_fail_test_vector[i][1], + echo_kex_report_fail_test_vector[i][2], + echo_kex_report_fail_test_vector[i][3]); s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, 1); @@ -3062,42 +4041,57 @@ void test_kex_inclusion_error_echo_kex_report(void) { // After receiving a timeout it is expected that the inclusion state machine is back in idle and // that we can initiate a new inclusion which will also trigger a new set timeout call. -// helper_func_verify_idle_state(&s2_context, 0x02, 0x82); + // helper_func_verify_idle_state(&s2_context, 0x02, 0x82); mock_calls_verify(); } /** */ -void test_kex_inclusion_invalid_key_report_set(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_invalid_key_report_set(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; uint8_t key_report_fail_test_vector[][2] = { - {0x80, 0x83}, // Key request S0. Key report multiple. This should return KEX_FAIL_KEY_SET. - {0x80, 0x01}, // Key request S0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. - {0x80, 0x02}, // Key request S0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. - {0x80, 0x08}, // Key request S0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. - {0x01, 0x83}, // Key request S2 - class 0. Key report multiple. This should return KEX_FAIL_KEY_SET. - {0x01, 0x02}, // Key request S2 - class 0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. - {0x01, 0x03}, // Key request S2 - class 0. Key report multiple. This should return KEX_FAIL_KEY_SET. - {0x01, 0x80}, // Key request S2 - class 0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. - {0x02, 0x83}, // Key request S2 - class 1. Key report multiple. This should return KEX_FAIL_KEY_SET. - {0x02, 0x01}, // Key request S2 - class 1. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. - {0x02, 0x03}, // Key request S2 - class 1. Key report multiple. This should return KEX_FAIL_KEY_SET. - {0x02, 0x80}, // Key request S2 - class 1. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x80, + 0x83}, // Key request S0. Key report multiple. This should return KEX_FAIL_KEY_SET. + {0x80, + 0x01}, // Key request S0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x80, + 0x02}, // Key request S0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x80, + 0x08}, // Key request S0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x01, + 0x83}, // Key request S2 - class 0. Key report multiple. This should return KEX_FAIL_KEY_SET. + {0x01, + 0x02}, // Key request S2 - class 0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x01, + 0x03}, // Key request S2 - class 0. Key report multiple. This should return KEX_FAIL_KEY_SET. + {0x01, + 0x80}, // Key request S2 - class 0. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x02, + 0x83}, // Key request S2 - class 1. Key report multiple. This should return KEX_FAIL_KEY_SET. + {0x02, + 0x01}, // Key request S2 - class 1. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. + {0x02, + 0x03}, // Key request S2 - class 1. Key report multiple. This should return KEX_FAIL_KEY_SET. + {0x02, + 0x80}, // Key request S2 - class 1. Key report single, wrong key. This should return KEX_FAIL_KEY_SET. }; mock_calls_clear(); @@ -3114,9 +4108,7 @@ void test_kex_inclusion_invalid_key_report_set(void) { s2_inclusion_set_event_handler(s2_event_handler); /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < ELEM_COUNT(key_report_fail_test_vector); i++) - { - + for (i = 0; i < ELEM_COUNT(key_report_fail_test_vector); i++) { /**************************** * Mock expectation section * ****************************/ @@ -3125,111 +4117,157 @@ void test_kex_inclusion_invalid_key_report_set(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - static uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x00}; + static uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x00}; S2_kex_report_frame[5] = key_report_fail_test_vector[i][0]; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); // When the KEX Set is received, we expect a call to the keystore in order to obtain our public key. // If any of the authenticated keys are requested, we expect the primary keypair to be used. Otherwise // the dynamic keypair. - if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) & key_report_fail_test_vector[i][0]) - { + if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) + & key_report_fail_test_vector[i][0]) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); } p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - static uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + static uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; // If the node uses only unauthenticated keys, then full public key is expected, else the first two bytes are zero'ed out. - if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) & key_report_fail_test_vector[i][0]) - { + if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) + & key_report_fail_test_vector[i][0]) { S2_pub_key_B_frame[3] = 0x00; S2_pub_key_B_frame[4] = 0x00; - } - else - { + } else { S2_pub_key_B_frame[3] = 0xAA; S2_pub_key_B_frame[4] = 0xBB; } mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = key_report_fail_test_vector[i][0]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = key_report_fail_test_vector[i][0]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; // When receiving public key A, then we expect that both our public and private keys are requested from the keystore. - if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) & key_report_fail_test_vector[i][0]) - { + if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) + & key_report_fail_test_vector[i][0]) { mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_private_key_read), &p_mock); } p_mock->output_arg[0].pointer = private_key_b; - if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) & key_report_fail_test_vector[i][0]) - { + if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) + & key_report_fail_test_vector[i][0]) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); } p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - static uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x00}; + static uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x00}; S2_echo_kex_set_frame[5] = key_report_fail_test_vector[i][0]; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); // Expect Net Key Get to be sent. - static uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x00}; + static uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x00}; S2_net_key_get_frame[2] = key_report_fail_test_vector[i][0]; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); // Expect a S2 KEX Fail as the including node received an Key Set command. - uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x0A}; // KEX_FAIL_KEY_REPORT = 0x0A + uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_FAIL, + 0x0A}; // KEX_FAIL_KEY_REPORT = 0x0A mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); // This event is not expected, until a send frame done (or failed) is received. - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x0A; mock_call_expect(TO_STR(s2_event_handler), &p_mock); @@ -3241,12 +4279,14 @@ void test_kex_inclusion_invalid_key_report_set(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); - helper_func_kex_set_frame(&s2_context, 0x02, key_report_fail_test_vector[i][0]); + helper_func_kex_set_frame(&s2_context, + 0x02, + key_report_fail_test_vector[i][0]); s2_inclusion_post_event(&s2_context, &s2_con); helper_func_pub_key_frame(&s2_context); @@ -3254,10 +4294,14 @@ void test_kex_inclusion_invalid_key_report_set(void) { s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - helper_func_echo_kex_report_frame(&s2_context, 0x02, 0x01, key_report_fail_test_vector[i][0]); + helper_func_echo_kex_report_frame(&s2_context, + 0x02, + 0x01, + key_report_fail_test_vector[i][0]); s2_inclusion_post_event(&s2_context, &s2_con); - helper_func_net_key_report_frame(&s2_context, key_report_fail_test_vector[i][1]); + helper_func_net_key_report_frame(&s2_context, + key_report_fail_test_vector[i][1]); s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, 1); @@ -3265,12 +4309,11 @@ void test_kex_inclusion_invalid_key_report_set(void) { // After receiving a timeout it is expected that the inclusion state machine is back in idle and // that we can initiate a new inclusion which will also trigger a new set timeout call. -// helper_func_verify_idle_state(&s2_context, 0x02, 0x82); + // helper_func_verify_idle_state(&s2_context, 0x02, 0x82); mock_calls_verify(); } - /** Test case for ensuring correct handling of node inclusion in all cases when there is a valid combination * of scheme support and key request. * @@ -3279,41 +4322,101 @@ void test_kex_inclusion_invalid_key_report_set(void) { * * Test: This test case will ensure a KEX Set is transmitted when a valid set of schemes/keys is requested. */ -void test_kex_inclusion_valid_keys(void) { - uint32_t i; - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6]; - uint8_t s2_kex_set_frame[6]; - struct S2 s2_context; - -// uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x03, 0x01, 0x84}; // Scheme 0 and 2, curve25519, S2, key 2, and S0 network key. - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_valid_keys(void) +{ + uint32_t i; + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6]; + uint8_t s2_kex_set_frame[6]; + struct S2 s2_context; + + // uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x03, 0x01, 0x84}; // Scheme 0 and 2, curve25519, S2, key 2, and S0 network key. + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; uint8_t key_request_pass_test_vector[][4] = { - {0x02, 0x01, 0x02, 0x01}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x02, 0x02, 0x02}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x03, 0x02, 0x03}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x80, 0x02, 0x80}, // Scheme 1 = true, key request S2 = no, key request S0 = yes. Valid request. - {0x02, 0x81, 0x02, 0x81}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x82, 0x02, 0x82}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x83, 0x02, 0x83}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x01, + 0x02, + 0x01}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x02, + 0x02, + 0x02}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x03, + 0x02, + 0x03}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x80, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = no, key request S0 = yes. Valid request. + {0x02, + 0x81, + 0x02, + 0x81}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x82, + 0x02, + 0x82}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x83, + 0x02, + 0x83}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. // Subset only granted - {0x02, 0x03, 0x02, 0x01}, // Key request S2 = yes, key request S0 = no. Granted S2 = yes, S0 = no. Valid request. - {0x02, 0x03, 0x02, 0x02}, // Key request S2 = yes, key request S0 = no. Granted S2 = yes, S0 = no. Valid request. - {0x02, 0x81, 0x02, 0x80}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = yes. Valid request. - {0x02, 0x82, 0x02, 0x80}, // Key request S2 = yes, key request S0 = yes. Granted S2 = no, S0 = yes. Valid request. - {0x02, 0x81, 0x02, 0x01}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. - {0x02, 0x82, 0x02, 0x02}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. - {0x02, 0x83, 0x02, 0x81}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = yes. Valid request. - {0x02, 0x83, 0x02, 0x82}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = yes. Valid request. - {0x02, 0x83, 0x02, 0x03}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. - {0x02, 0x83, 0x02, 0x80}, // Key request S2 = yes, key request S0 = yes. Granted S2 = no, S0 = yes. Valid request. - {0x02, 0x83, 0x02, 0x01}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. - {0x02, 0x83, 0x02, 0x02}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x03, + 0x02, + 0x01}, // Key request S2 = yes, key request S0 = no. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x03, + 0x02, + 0x02}, // Key request S2 = yes, key request S0 = no. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x81, + 0x02, + 0x80}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = yes. Valid request. + {0x02, + 0x82, + 0x02, + 0x80}, // Key request S2 = yes, key request S0 = yes. Granted S2 = no, S0 = yes. Valid request. + {0x02, + 0x81, + 0x02, + 0x01}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x82, + 0x02, + 0x02}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x83, + 0x02, + 0x81}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = yes. Valid request. + {0x02, + 0x83, + 0x02, + 0x82}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = yes. Valid request. + {0x02, + 0x83, + 0x02, + 0x03}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x83, + 0x02, + 0x80}, // Key request S2 = yes, key request S0 = yes. Granted S2 = no, S0 = yes. Valid request. + {0x02, + 0x83, + 0x02, + 0x01}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. + {0x02, + 0x83, + 0x02, + 0x02}, // Key request S2 = yes, key request S0 = yes. Granted S2 = yes, S0 = no. Valid request. }; mock_calls_clear(); @@ -3328,52 +4431,61 @@ void test_kex_inclusion_valid_keys(void) { s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - for (i = 0; i < ELEM_COUNT(key_request_pass_test_vector); i++) - { - + for (i = 0; i < ELEM_COUNT(key_request_pass_test_vector); i++) { /**************************** * Mock expectation section * ****************************/ - s2_inclusion_init( key_request_pass_test_vector[i][0], 0x01, key_request_pass_test_vector[i][1]); + s2_inclusion_init(key_request_pass_test_vector[i][0], + 0x01, + key_request_pass_test_vector[i][1]); // After including node has sent a KEX Get, a response with above settings is expected. s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x04, // reserved | NLS support | Request CSA | Echo - s2_kex_report_frame[3] = key_request_pass_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = key_request_pass_test_vector[i][1]; // Requested keys bit. + s2_kex_report_frame[2] + = 0x04, // reserved | NLS support | Request CSA | Echo + s2_kex_report_frame[3] + = key_request_pass_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] + = key_request_pass_test_vector[i][1]; // Requested keys bit. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_report_frame); // Before exchange of public keys, then we expect that our public key is requested from the keystore. // If any of the authenticated keys are requested, we expect the primary keypair to be used. Otherwise // the dynamic keypair. - if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) & key_request_pass_test_vector[i][3]) - { + if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) + & key_request_pass_test_vector[i][3]) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - } - else - { + } else { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); } p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. memcpy(&s2_public_key_frame[3], public_key_b, sizeof(public_key_b)); // If the node uses only unauthenticated keys, then full public key is expected, else the first two bytes are zero'ed out. - if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) & key_request_pass_test_vector[i][3]) - { + if ((KEY_CLASS_S2_ACCESS | KEY_CLASS_S2_AUTHENTICATED) + & key_request_pass_test_vector[i][3]) { s2_public_key_frame[3] = 0x00; s2_public_key_frame[4] = 0x00; } mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); @@ -3383,7 +4495,7 @@ void test_kex_inclusion_valid_keys(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. helper_func_kex_get_frame(&s2_context); @@ -3392,14 +4504,17 @@ void test_kex_inclusion_valid_keys(void) { // KEX Set frame received - With an unsupported/not requested scheme set. s2_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; s2_kex_set_frame[1] = KEX_SET; - s2_kex_set_frame[2] = 0x00, // bit 0 is echo field, rest are reserved - s2_kex_set_frame[3] = key_request_pass_test_vector[i][2]; // Supported schemes. - s2_kex_set_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_set_frame[5] = key_request_pass_test_vector[i][3]; // Granted keys bit. + s2_kex_set_frame[2] = 0x00, // bit 0 is echo field, rest are reserved + s2_kex_set_frame[3] + = key_request_pass_test_vector[i][2]; // Supported schemes. + s2_kex_set_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_set_frame[5] + = key_request_pass_test_vector[i][3]; // Granted keys bit. - s2_context.buf = s2_kex_set_frame; - s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_context.buf = s2_kex_set_frame; + s2_context.length = sizeof(s2_kex_set_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); helper_func_idle_state(&s2_context); @@ -3408,9 +4523,10 @@ void test_kex_inclusion_valid_keys(void) { /** Test case for ensuring correct timer handling on timeout while in idle. */ -void test_kex_inclusion_timeout_when_idle(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; +void test_kex_inclusion_timeout_when_idle(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; struct S2 s2_context; mock_calls_clear(); @@ -3430,10 +4546,13 @@ void test_kex_inclusion_timeout_when_idle(void) { // After timeout we will issue a node inclusion just to insure we were in idle and that a node // may be included after timeout. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04,0x02, 0x01, 0x01}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x01}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); @@ -3446,7 +4565,7 @@ void test_kex_inclusion_timeout_when_idle(void) { // Node id (first step in inclusion) has been assigned. // Let's initiate a secure inclusion after the timeout to verify the state of the system. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. helper_func_kex_get_frame(&s2_context); @@ -3460,12 +4579,14 @@ void test_kex_inclusion_timeout_when_idle(void) { * * Such frame should be silently ignored. */ -void test_kex_inclusion_invalid_frame_idle(void) { - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; +void test_kex_inclusion_invalid_frame_idle(void) +{ + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; // Invalid joining start frame. - uint8_t s2_invalid_joining_frame[] = {COMMAND_CLASS_SECURITY_2, 0x02, 0x01, 0x00, 0x00, 0x00}; + uint8_t s2_invalid_joining_frame[] + = {COMMAND_CLASS_SECURITY_2, 0x02, 0x01, 0x00, 0x00, 0x00}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -3476,9 +4597,11 @@ void test_kex_inclusion_invalid_frame_idle(void) { s2_inclusion_set_event_handler(s2_event_handler); s2_inclusion_init(0x02, 0x01, 0x82); - memcpy((uint8_t *)s2_context.buf, s2_invalid_joining_frame, sizeof(s2_invalid_joining_frame)); + memcpy((uint8_t *)s2_context.buf, + s2_invalid_joining_frame, + sizeof(s2_invalid_joining_frame)); s2_context.length = sizeof(s2_invalid_joining_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // Let's try to see if we can get the system to join us (should not be possible). @@ -3491,22 +4614,26 @@ void test_kex_inclusion_invalid_frame_idle(void) { /** This test case ensure that the system continues to send ECHO KEX Set until a ECHO KEX Report is received regardless if send done fails or succeeds. * When ECHO KEX Report is received the state machine continues. */ -void test_kex_inclusion_echo_kex_set_retry(void) { - mock_t * p_mock; -// zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; +void test_kex_inclusion_echo_kex_set_retry(void) +{ + mock_t *p_mock; + // zwave_event_t * p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -3521,7 +4648,6 @@ void test_kex_inclusion_echo_kex_set_retry(void) { s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - /**************************** * Mock expectation section * ****************************/ @@ -3530,10 +4656,13 @@ void test_kex_inclusion_echo_kex_set_retry(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - static uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x81}; + static uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x81}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); @@ -3542,26 +4671,65 @@ void test_kex_inclusion_echo_kex_set_retry(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - static uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + static uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x81; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x81; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -3574,41 +4742,57 @@ void test_kex_inclusion_echo_kex_set_retry(void) { // When public key is received we expect an echo(KEX Set) to be sent. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); // First echo succeeds but as no ECHO KEX Report is received we still expect an second echo(KEX Set) to be sent. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); // Second echo fails (other side is probably busy calculating)so we expect an third echo(KEX Set) to be sent. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); // Expect Net Key Get to be sent. - static uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; + static uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); // Second echo fails so we expect an third echo(KEX Set) to be sent. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->compare_rule_arg[2] = COMPARE_ANY; // This shall be updated once excact frame is defined for S2 frames. - p_mock->compare_rule_arg[3] = COMPARE_ANY; // This shall be updated once excact frame is defined for S2 frames. -// p_mock->expect_arg[2].pointer = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. -// p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[2] + = COMPARE_ANY; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[3] + = COMPARE_ANY; // This shall be updated once excact frame is defined for S2 frames. + // p_mock->expect_arg[2].pointer = s2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + // p_mock->expect_arg[3].value = sizeof(s2_echo_kex_set_frame); /******************* * Testing section * @@ -3616,7 +4800,7 @@ void test_kex_inclusion_echo_kex_set_retry(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -3649,7 +4833,7 @@ void test_kex_inclusion_echo_kex_set_retry(void) { // After receiving a timeout it is expected that the inclusion state machine is back in idle and // that we can initiate a new inclusion which will also trigger a new set timeout call. -// helper_func_verify_idle_state(&s2_context, 0x02, 0x82); + // helper_func_verify_idle_state(&s2_context, 0x02, 0x82); mock_calls_verify(); } @@ -3662,25 +4846,28 @@ void test_kex_inclusion_echo_kex_set_retry(void) { * - Writing of network keys to keystore when receiving them. * - Restore of all keys when inclusion is complete. */ -void test_inclusion_keystore_handling(void) { - mock_t * p_mock; -// zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t shared_secret[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x0F, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21, - 0x10, 0x29, 0x38, 0x47, 0x56, 0x65, 0x74, 0x83, - 0x38, 0x63, 0x97, 0x47, 0x82, 0x12, 0x53, 0xc4}; +void test_inclusion_keystore_handling(void) +{ + mock_t *p_mock; + // zwave_event_t * p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t shared_secret[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x0F, 0xED, 0xCB, + 0xA9, 0x87, 0x65, 0x43, 0x21, 0x10, 0x29, 0x38, 0x47, 0x56, 0x65, + 0x74, 0x83, 0x38, 0x63, 0x97, 0x47, 0x82, 0x12, 0x53, 0xc4}; uint8_t expected_auth_tag[64]; @@ -3689,18 +4876,17 @@ void test_inclusion_keystore_handling(void) { mock_call_use_as_stub(TO_STR(S2_send_frame)); mock_call_use_as_stub(TO_STR(S2_send_data)); mock_call_use_as_stub(TO_STR(s2_event_handler)); -// mock_call_use_as_stub(TO_STR(S2_network_key_update)); -// mock_call_use_as_stub(TO_STR(crypto_scalarmult_curve25519)); -// mock_call_use_as_stub(TO_STR(tempkey_extract)); -// mock_call_use_as_stub(TO_STR(keystore_network_key_clear)); -// mock_call_use_as_stub(TO_STR(keystore_network_key_write)); + // mock_call_use_as_stub(TO_STR(S2_network_key_update)); + // mock_call_use_as_stub(TO_STR(crypto_scalarmult_curve25519)); + // mock_call_use_as_stub(TO_STR(tempkey_extract)); + // mock_call_use_as_stub(TO_STR(keystore_network_key_clear)); + // mock_call_use_as_stub(TO_STR(keystore_network_key_write)); memset(&s2_context, 0, sizeof(s2_context)); s2_context.inclusion_state = S2_INC_IDLE; s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - /**************************** * Mock expectation section * ****************************/ @@ -3737,8 +4923,9 @@ void test_inclusion_keystore_handling(void) { // S2 protocol should be updated with the temporary key. mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = UNIT_TEST_TEMP_KEY_SECURE; // Temp key is expected to be stored @0 on slave and @3 on a controller index. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = UNIT_TEST_TEMP_KEY_SECURE; // Temp key is expected to be stored @0 on slave and @3 on a controller index. p_mock->expect_arg[2].pointer = m_temp_key; p_mock->expect_arg[3].value = 1; // Temp key expansion. @@ -3748,8 +4935,9 @@ void test_inclusion_keystore_handling(void) { p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_0; mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. p_mock->expect_arg[2].pointer = m_test_network_key_s2_class_0; p_mock->expect_arg[3].value = 0; // No network key expansion. @@ -3759,8 +4947,9 @@ void test_inclusion_keystore_handling(void) { p_mock->expect_arg[1].pointer = m_test_network_key_s0; mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. p_mock->expect_arg[2].pointer = m_test_network_key_s0; p_mock->expect_arg[3].value = 0; // No network key expansion. @@ -3771,44 +4960,44 @@ void test_inclusion_keystore_handling(void) { mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x01; p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - p_mock->return_code.value = true; + p_mock->return_code.value = true; mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 0; // Network key 0x01 is expected to be stored @0 index. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = 0; // Network key 0x01 is expected to be stored @0 index. p_mock->expect_arg[2].pointer = m_test_network_key_s2_class_0; p_mock->expect_arg[3].value = 0; // No network key expansion. mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x02; p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x04; p_mock->output_arg[1].pointer = m_test_mem_pool[1]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; #ifdef ZW_CONTROLLER mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x08; p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x10; p_mock->output_arg[1].pointer = m_test_mem_pool[1]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; #endif - /******************* * Testing section * *******************/ // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -3849,14 +5038,17 @@ void test_inclusion_keystore_handling(void) { * * Test: This test case will a KEX_FAIL_KEY is returned when invalid set of schemes/keys is requested. */ -void test_kex_inclusion_received_kex_fail_frame(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; +void test_kex_inclusion_received_kex_fail_frame(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x84}; - uint8_t s2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x01}; // KEX_FAIL_KEX_KEY = 0x01 + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x84}; + uint8_t s2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x01}; // KEX_FAIL_KEX_KEY = 0x01 mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -3878,12 +5070,14 @@ void test_kex_inclusion_received_kex_fail_frame(void) { // After including node has sent a KEX Get, a response is expected. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_report_frame); - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x01; mock_call_expect(TO_STR(s2_event_handler), &p_mock); @@ -3895,15 +5089,15 @@ void test_kex_inclusion_received_kex_fail_frame(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); - s2_context.buf = s2_kex_error_frame; - s2_context.length = sizeof(s2_kex_error_frame); - s2_con.class_id = 0xFF; + s2_context.buf = s2_kex_error_frame; + s2_context.length = sizeof(s2_kex_error_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // Retry node inclusion. @@ -3916,9 +5110,10 @@ void test_kex_inclusion_received_kex_fail_frame(void) { * This feature is requested on nodes that might support both Security 0 and security 2, but where * it is unknown which inclusion mode will be activated. */ -void test_kex_inclusion_abort(void) { - struct S2 s2_context; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; +void test_kex_inclusion_abort(void) +{ + struct S2 s2_context; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -3936,14 +5131,13 @@ void test_kex_inclusion_abort(void) { ****************************/ s2_inclusion_init(0x02, 0x01, 0x84); - /******************* * Testing section * *******************/ // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // Security 0 learn mode was initiated, abort current inclusion. s2_inclusion_abort(&s2_context); @@ -3962,16 +5156,17 @@ void test_kex_inclusion_abort(void) { * * This failure should result in a KEX Fail - TBD to be transmitted to the inclusion_peer. */ -void test_kex_joining_node_wrong_dsk_input(void) { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_joining_node_wrong_dsk_input(void) +{ + uint8_t public_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -3985,7 +5180,7 @@ void test_kex_joining_node_wrong_dsk_input(void) { /** * Test expectation setup. */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. helper_func_inclusion_initiated_event(); @@ -3997,22 +5192,35 @@ void test_kex_joining_node_wrong_dsk_input(void) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[5], &public_key_b[2], sizeof(public_key_b) - 2); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -4022,17 +5230,27 @@ void test_kex_joining_node_wrong_dsk_input(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; // Note: Echo flag set. + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); // When a KEX Fail decrypt is received, then inclusion should be aborted. - zwave_event_t * p_expected_inc_fail_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_inc_fail_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_inc_fail_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_inc_fail_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x05; + p_expected_inc_fail_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x05; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_fail_event; @@ -4047,13 +5265,13 @@ void test_kex_joining_node_wrong_dsk_input(void) { s2_inclusion_init(0x02, 0x01, 0x82); s2_inclusion_set_event_handler(s2_event_handler); - s2_inclusion_joining_start(&s2_context, &s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expeted to be transmitted. Let's make the s2_send_frame a success. @@ -4064,26 +5282,32 @@ void test_kex_joining_node_wrong_dsk_input(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); // If wrong DSK is provided by end-user, then it is expected that a KEX Fail event is received. uint8_t s2_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x05}; - s2_context.buf = s2_kex_fail_frame; - s2_context.length = sizeof(s2_kex_fail_frame); - s2_con.class_id = 0xFF; + s2_context.buf = s2_kex_fail_frame; + s2_context.length = sizeof(s2_kex_fail_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); helper_func_verify_idle_state(&s2_context, 0x02, 0x82); @@ -4101,25 +5325,28 @@ void test_kex_joining_node_wrong_dsk_input(void) { * - Writing of network keys to keystore when receiving them. * - Restore of all keys when inclusion is complete. */ -void test_keystore_doorlock(void) { - mock_t * p_mock; -// zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t shared_secret[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x0F, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21, - 0x10, 0x29, 0x38, 0x47, 0x56, 0x65, 0x74, 0x83, - 0x38, 0x63, 0x97, 0x47, 0x82, 0x12, 0x53, 0xc4}; +void test_keystore_doorlock(void) +{ + mock_t *p_mock; + // zwave_event_t * p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + static uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t shared_secret[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x0F, 0xED, 0xCB, + 0xA9, 0x87, 0x65, 0x43, 0x21, 0x10, 0x29, 0x38, 0x47, 0x56, 0x65, + 0x74, 0x83, 0x38, 0x63, 0x97, 0x47, 0x82, 0x12, 0x53, 0xc4}; uint8_t expected_auth_tag[64]; @@ -4134,7 +5361,6 @@ void test_keystore_doorlock(void) { s2_context.buf = frame_buffer; s2_inclusion_set_event_handler(s2_event_handler); - /**************************** * Mock expectation section * ****************************/ @@ -4171,8 +5397,9 @@ void test_keystore_doorlock(void) { // S2 protocol should be updated with the temporary key. mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = UNIT_TEST_TEMP_KEY_SECURE; // Temp key is expected to be stored index @0 on slave and index @3 on controller.. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = UNIT_TEST_TEMP_KEY_SECURE; // Temp key is expected to be stored index @0 on slave and index @3 on controller.. p_mock->expect_arg[2].pointer = m_temp_key; p_mock->expect_arg[3].value = 1; // Temp key expansion. @@ -4182,8 +5409,9 @@ void test_keystore_doorlock(void) { p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_2; mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. p_mock->expect_arg[2].pointer = m_test_network_key_s2_class_2; p_mock->expect_arg[3].value = 0; // No network key expansion. @@ -4193,8 +5421,9 @@ void test_keystore_doorlock(void) { p_mock->expect_arg[1].pointer = m_test_network_key_s0; mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = UNIT_TEST_NETWORK_KEY; // Network key is expected to be stored index @1 on slave and index @4 on controller. p_mock->expect_arg[2].pointer = m_test_network_key_s0; p_mock->expect_arg[3].value = 0; // No network key expansion. @@ -4205,34 +5434,34 @@ void test_keystore_doorlock(void) { mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x01; p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x02; p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x04; p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - p_mock->return_code.value = true; + p_mock->return_code.value = true; #ifdef ZW_CONTROLLER mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x08; p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); p_mock->expect_arg[0].value = 0x10; p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - p_mock->return_code.value = false; + p_mock->return_code.value = false; #endif - mock_call_expect(TO_STR(S2_network_key_update), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 2; // Network key 0x04 is expected to be stored @2 index. + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value + = 2; // Network key 0x04 is expected to be stored @2 index. p_mock->expect_arg[2].pointer = m_test_network_key_s2_class_2; p_mock->expect_arg[3].value = 0; // No network key expansion. @@ -4242,7 +5471,7 @@ void test_keystore_doorlock(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -4282,8 +5511,8 @@ void test_keystore_doorlock(void) { /** Verification that in case the inclusion state machine is in idle, then AUTH Failed should not * be returned for an invalid encrypted frame. TO#06510 */ -void test_kex_invalid_crypt_frame_idle(void) { - +void test_kex_invalid_crypt_frame_idle(void) +{ mock_calls_clear(); /** @@ -4293,7 +5522,7 @@ void test_kex_invalid_crypt_frame_idle(void) { /** * Test execution. */ - struct S2 s2_context; + struct S2 s2_context; memset(&s2_context, 0, sizeof(s2_context)); s2_context.inclusion_state = S2_INC_IDLE; @@ -4303,10 +5532,11 @@ void test_kex_invalid_crypt_frame_idle(void) { // bit0: Key request complete set, // bit1: Key verified not set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); mock_calls_verify(); @@ -4315,19 +5545,22 @@ void test_kex_invalid_crypt_frame_idle(void) { /** Test case for ensuring that the inclusion state machine will not abort if an older inclusion * frame is received multiple times, as example due to retransmission or routing. */ -void test_kex_inclusion_tx_queue_full(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_tx_queue_full(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -4353,19 +5586,25 @@ void test_kex_inclusion_tx_queue_full(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. Calls fails as TX is full. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 0; // After send done / failed is received the inclusion shoud retry sending the frame and succeed. - uint8_t S2_kex_report_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame_retry[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame_retry; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame_retry); p_mock->return_code.value = 1; @@ -4375,32 +5614,72 @@ void test_kex_inclusion_tx_queue_full(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); p_mock->return_code.value = 0; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); p_mock->return_code.value = 1; // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req + .public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -4412,105 +5691,146 @@ void test_kex_inclusion_tx_queue_full(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 0; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 0; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); p_mock->return_code.value = 0; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); p_mock->return_code.value = 1; // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); p_mock->return_code.value = 0; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); p_mock->return_code.value = 1; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 0; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 0; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 0; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 0; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 0; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_complete_event; @@ -4520,7 +5840,7 @@ void test_kex_inclusion_tx_queue_full(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); helper_func_kex_get_frame(&s2_context); s2_inclusion_post_event(&s2_context, &s2_con); @@ -4572,7 +5892,6 @@ void test_kex_inclusion_tx_queue_full(void) { s2_inclusion_send_done(&s2_context, 1); s2_inclusion_send_done(&s2_context, true); - mock_calls_verify(); } @@ -4580,19 +5899,22 @@ void test_kex_inclusion_tx_queue_full(void) { * SECURITY_2_TRANSFER_END is returned but KeyVerified bit is set to 0. * TO#7507 */ -void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -4618,10 +5940,13 @@ void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -4631,27 +5956,66 @@ void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); p_mock->return_code.value = 1; // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req + .public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -4663,47 +6027,61 @@ void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); p_mock->return_code.value = 1; // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); p_mock->return_code.value = 1; // Expect KEX FAIL to be sent. - uint8_t S2_network_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_VERIFY}; + uint8_t S2_network_kex_fail_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_kex_fail_frame; p_mock->expect_arg[3].value = sizeof(S2_network_kex_fail_frame); p_mock->return_code.value = 1; - // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_inc_fail_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_inc_fail_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_inc_fail_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_inc_fail_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = KEX_FAIL_KEY_VERIFY; + p_expected_inc_fail_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = KEX_FAIL_KEY_VERIFY; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_fail_event; @@ -4713,7 +6091,7 @@ void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); /** The loop which will set up the expectation based on the round. */ helper_func_kex_get_frame(&s2_context); @@ -4737,9 +6115,10 @@ void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { // silently abort (push error internally). frame_buffer[0] = COMMAND_CLASS_SECURITY_2; frame_buffer[1] = SECURITY_2_TRANSFER_END; - frame_buffer[2] = 0x00; // Verify bit not set. Normally this packet will look as 0x02. + frame_buffer[2] + = 0x00; // Verify bit not set. Normally this packet will look as 0x02. s2_context.length = 3; - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); mock_calls_verify(); @@ -4748,19 +6127,22 @@ void test_kex_inclusion_transfer_end_key_not_verified_TO7507(void) { /** Test case for ensuring that in the (including node misbehaving) event where a * SECURITY_2_TRANSFER_END is returned by including node with KeyRequestComplete bit is set to 1. */ -void test_kex_inclusion_transfer_end_key_request_complete_error(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from the keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_inclusion_transfer_end_key_request_complete_error(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being fetch from the keystore. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -4786,10 +6168,13 @@ void test_kex_inclusion_transfer_end_key_request_complete_error(void) { helper_func_inclusion_initiated_event(); // Expect a S2 KEX Report to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x02, 0x01, 0x82}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -4799,27 +6184,66 @@ void test_kex_inclusion_transfer_end_key_request_complete_error(void) { p_mock->output_arg[0].pointer = public_key_b; // When the KEX Set is received, we expect public keys to be exchanges. - uint8_t S2_pub_key_B_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, // Including node bit not set - 0x00, 0x00, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being fetch from keystore. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t S2_pub_key_B_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, // Including node bit not set + 0x00, + 0x00, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being fetch from keystore. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_pub_key_B_frame; p_mock->expect_arg[3].value = sizeof(S2_pub_key_B_frame); p_mock->return_code.value = 1; // When the public key A is received, we expect that the event from libs2 contains the key in order to present it for the operator. // Therefore we copy the key minus header frame into expected data and push an event upwards. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy((uint8_t *)p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req + .public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -4831,47 +6255,61 @@ void test_kex_inclusion_transfer_end_key_request_complete_error(void) { p_mock->output_arg[0].pointer = public_key_b; // When public key is received we expect an echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + uint8_t S2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; S2_echo_kex_set_frame[0] = COMMAND_CLASS_SECURITY_2; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; // Expect Net Key Get to be sent. - uint8_t S2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + uint8_t S2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_net_key_get_frame; p_mock->expect_arg[3].value = sizeof(S2_net_key_get_frame); p_mock->return_code.value = 1; // Expect Net Key Verify to be sent. - uint8_t S2_network_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t S2_network_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_key_verify_frame; p_mock->expect_arg[3].value = sizeof(S2_network_key_verify_frame); p_mock->return_code.value = 1; // Expect KEX FAIL to be sent. - uint8_t S2_network_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_VERIFY}; + uint8_t S2_network_kex_fail_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_kex_fail_frame; p_mock->expect_arg[3].value = sizeof(S2_network_kex_fail_frame); p_mock->return_code.value = 1; - // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_inc_fail_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_inc_fail_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_inc_fail_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_inc_fail_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = KEX_FAIL_KEY_VERIFY; + p_expected_inc_fail_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = KEX_FAIL_KEY_VERIFY; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_fail_event; @@ -4881,7 +6319,7 @@ void test_kex_inclusion_transfer_end_key_request_complete_error(void) { // Node id (first step in inclusion) has been assigned. // Continue with secure inclusion. - s2_inclusion_joining_start(&s2_context,&s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); /** The loop which will set up the expectation based on the round. */ helper_func_kex_get_frame(&s2_context); @@ -4905,9 +6343,10 @@ void test_kex_inclusion_transfer_end_key_request_complete_error(void) { // silently abort (push error internally). frame_buffer[0] = COMMAND_CLASS_SECURITY_2; frame_buffer[1] = SECURITY_2_TRANSFER_END; - frame_buffer[2] = 0x03; // Verify bit not set. Normally this packet will look as 0x02. + frame_buffer[2] + = 0x03; // Verify bit not set. Normally this packet will look as 0x02. s2_context.length = 3; - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); mock_calls_verify(); @@ -4919,16 +6358,17 @@ void test_kex_inclusion_transfer_end_key_request_complete_error(void) { * The joining node sends its full public key * CSA is disabled on the S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT event. */ -void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) +{ + uint8_t public_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -4971,24 +6411,29 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x06, // bit 0 is echo field, bit 1 is CSA, rest are reserved - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x87};// Requested keys bits. Security 2 class 0, 1, 2, Security 0 network key. + uint8_t S2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x06, // bit 0 is echo field, bit 1 is CSA, rest are reserved + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x87}; // Requested keys bits. Security 2 class 0, 1, 2, Security 0 network key. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -4997,23 +6442,37 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[3], &public_key_b[0], sizeof(public_key_b)); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x81; // Only S2 unauthenticated and S0 keys were granted - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; // CSA was disabled by including node. - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x81; // Only S2 unauthenticated and S0 keys were granted + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length + = 0; // CSA was disabled by including node. + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -5023,62 +6482,96 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; // Note: Echo flag set. + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x81}; // Note: Echo flag set. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x01}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x81; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x81; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -5095,9 +6588,9 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expected to be transmitted. Let's make the s2_send_frame a success. @@ -5108,25 +6601,33 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) // Selected schemes: scheme 0. // Selected curve25519 // Keys to exchange, Security2, class 1 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x81}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x81}; s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // As CSA was disabled, we expected that full public key was received. - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. // The challenge response should result in correct pub key being set on the context. s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); // After receiving public key from joining node, the upper layer must specify our public key to be send. (This can also be done on initialization, but must happen no later than the received event). @@ -5135,37 +6636,51 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x87}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x87}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x01, }; // Keys requested, Security2, class 1 - Security0, network key. - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x01, + }; // Keys requested, Security2, class 1 - Security0, network key. + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); + uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); s2_context.buf = s2_net_key_report_0_frame; s2_context.length = sizeof(s2_net_key_report_0_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. @@ -5174,7 +6689,7 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) // bit2-7: Reserved. s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_send_done(&s2_context, true); @@ -5186,17 +6701,18 @@ void test_kex_joining_node_state_machine_csa_rejected_S2_unauth_S0_TO7654(void) * is received by the S2 layer which should result in a retransmission of the frame. * */ -void test_kex_joining_node_state_machine_retry_all_states(void) { +void test_kex_joining_node_state_machine_retry_all_states(void) +{ uint32_t send_frame_tries; - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t public_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); @@ -5240,25 +6756,29 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; - for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) - { + for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) { // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x04, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x01};// Requested keys bits. Security 2 class 0 key. + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x04, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x01}; // Requested keys bits. Security 2 class 0 key. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -5268,25 +6788,35 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. memcpy(&s2_public_key_frame[3], public_key_b, sizeof(public_key_b)); - for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) - { + for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) { mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; } // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x01; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x01; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -5296,61 +6826,81 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Set) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x01}; // Note: Echo flag set. - for (send_frame_tries = 0; send_frame_tries < 3; send_frame_tries++) - { + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x01}; // Note: Echo flag set. + for (send_frame_tries = 0; send_frame_tries < 3; send_frame_tries++) { mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; } - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; // Keys requested, Security2, class 2 - Security0, network key. - for (send_frame_tries = 0; send_frame_tries < 3; send_frame_tries++) - { + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x01}; // Keys requested, Security2, class 2 - Security0, network key. + for (send_frame_tries = 0; send_frame_tries < 3; send_frame_tries++) { mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; } -// // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. -// mock_call_expect(TO_STR(S2_network_key_update), &p_mock); -// p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. -// p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; - - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) - { + // // After receiving the network key, we expect to get a call to update the context to use the new key when transmitting Net key verify. + // mock_call_expect(TO_STR(S2_network_key_update), &p_mock); + // p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + // p_mock->expect_arg[1].pointer = m_test_network_key_s2_class_1; + + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) { mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); + p_mock->return_code.value = 1; } // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) - { + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + for (send_frame_tries = 0; send_frame_tries < 2; send_frame_tries++) { mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); p_mock->return_code.value = 1; } // When S2 Transfer End is received, we expect a corresponding Node inclusion complete event from libs2. - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_JOINING_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x01; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x01; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -5363,15 +6913,14 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { s2_inclusion_init(0x02, 0x01, 0x01); s2_inclusion_set_event_handler(s2_event_handler); - s2_inclusion_joining_start(&s2_context, &s2_con,0); + s2_inclusion_joining_start(&s2_context, &s2_con, 0); // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; - s2_inclusion_post_event(&s2_context,&s2_con); - + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expected to be transmitted. Let's make the the first frame fail to verify a resent is transmitted. s2_inclusion_send_done(&s2_context, 0); @@ -5384,21 +6933,27 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x01}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x01}; s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; - s2_inclusion_post_event(&s2_context,&s2_con); + s2_con.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expected to be transmitted. Let's make the the first frame fail to verify a resent is transmitted. s2_inclusion_send_done(&s2_context, 0); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; - s2_inclusion_post_event(&s2_context,&s2_con); + s2_con.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_con); s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); @@ -5407,7 +6962,7 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { // After exchanging the keys, the other side might wait for user acceptance. // Therefore frames are retried per timeout basis instead send frame basis. // So a send done shoud not do any thing, only the timeout shoud result in retry. - s2_inclusion_send_done(&s2_context, 0); // Should do nothing + s2_inclusion_send_done(&s2_context, 0); // Should do nothing s2_inclusion_notify_timeout(&s2_context); // Successful transmission, however, retries are expected until ECHO KEX Report is received (or 'n' retries due to timeouts). @@ -5422,12 +6977,12 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x01}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x01}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context,&s2_con); - + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_con); // KEY get is expected to be transmitted. Let's make the the first two frames fail to verify that resents are transmitted. s2_inclusion_send_done(&s2_context, 0); @@ -5435,12 +6990,18 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { s2_inclusion_send_done(&s2_context, 1); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x01, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_0)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x01, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_0)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context,&s2_con); + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_con); // KEY verify is expected to be transmitted. Let's make the first frame fail to verify that a resent is transmitted. s2_inclusion_send_done(&s2_context, 0); @@ -5450,11 +7011,12 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context,&s2_con); + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_con); // Transfer end complete is expected to be transmitted. Let's make the first frame fail to verify that a resent is transmitted. s2_inclusion_send_done(&s2_context, 0); @@ -5465,43 +7027,45 @@ void test_kex_joining_node_state_machine_retry_all_states(void) { mock_calls_verify(); } - /** Test that S2_inclusion_init() rejects LR key bits as it should. */ void test_setting_LR_key_bits_in_init(void) { - uint8_t retval = s2_inclusion_init(0x02, 0x01, 0x9F); - TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 + uint8_t retval = s2_inclusion_init(0x02, 0x01, 0x9F); + TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 - retval = s2_inclusion_init(0x02, 0x01, 0x0F); - TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 + retval = s2_inclusion_init(0x02, 0x01, 0x0F); + TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 - retval = s2_inclusion_init(0x02, 0x01, 0x097); - TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 + retval = s2_inclusion_init(0x02, 0x01, 0x097); + TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 - retval = s2_inclusion_init(0x02, 0x01, 0x0F); - TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 + retval = s2_inclusion_init(0x02, 0x01, 0x0F); + TEST_ASSERT_EQUAL_INT8(1, retval); // KEX_FAIL_KEX_KEY = 1 - /* Clean up global m_keys and friends so subsequent test cases that don't call s2_inclusion_init continue to work */ - s2_inclusion_init(0x02, 0x01, 0x87); + /* Clean up global m_keys and friends so subsequent test cases that don't call s2_inclusion_init continue to work */ + s2_inclusion_init(0x02, 0x01, 0x87); } - - ///** Helper function sections - Start */ // /** This helper function set up an expected KEX get frame to be send (through the mock). */ -void helper_func_kex_report_frame_expect(uint8_t scheme, uint8_t curve, uint8_t keys) +void helper_func_kex_report_frame_expect(uint8_t scheme, + uint8_t curve, + uint8_t keys) { - mock_t * p_mock; + mock_t *p_mock; // Static to keep in scope for complete test. - static uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x00, 0x00, 0x00}; + static uint8_t s2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x00, 0x00, 0x00}; s2_kex_report_frame[3] = scheme; s2_kex_report_frame[4] = curve; s2_kex_report_frame[5] = keys; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(s2_kex_report_frame); p_mock->return_code.value = 1; @@ -5513,76 +7077,84 @@ void helper_func_kex_get_frame(struct S2 *p_context) uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); p_context->length = sizeof(s2_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; } /** This helper function constructs a KEX Set frame and update p_context */ -void helper_func_kex_set_frame(struct S2 *p_context, uint8_t scheme, uint8_t keys) +void helper_func_kex_set_frame(struct S2 *p_context, + uint8_t scheme, + uint8_t keys) { - uint8_t * p_tmp = (uint8_t *)p_context->buf; - p_tmp[0] = COMMAND_CLASS_SECURITY_2; - p_tmp[1] = KEX_SET; - p_tmp[2] = 0x00; - p_tmp[3] = scheme; - p_tmp[4] = 0x01; - p_tmp[5] = keys; + uint8_t *p_tmp = (uint8_t *)p_context->buf; + p_tmp[0] = COMMAND_CLASS_SECURITY_2; + p_tmp[1] = KEX_SET; + p_tmp[2] = 0x00; + p_tmp[3] = scheme; + p_tmp[4] = 0x01; + p_tmp[5] = keys; p_context->length = 6; - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; } void helper_func_pub_key_frame(struct S2 *p_context) { - uint8_t * p_tmp = (uint8_t *)p_context->buf; - p_tmp[0] = COMMAND_CLASS_SECURITY_2; - p_tmp[1] = PUBLIC_KEY_REPORT; - p_tmp[2] = 0x01; + uint8_t *p_tmp = (uint8_t *)p_context->buf; + p_tmp[0] = COMMAND_CLASS_SECURITY_2; + p_tmp[1] = PUBLIC_KEY_REPORT; + p_tmp[2] = 0x01; memcpy(&p_tmp[3], m_test_public_key_a, sizeof(m_test_public_key_a)); - p_context->length = 3 + sizeof(m_test_public_key_a); - s2_con.class_id = 0xFF; + p_context->length = 3 + sizeof(m_test_public_key_a); + s2_con.class_id = 0xFF; } -void helper_func_echo_kex_report_frame(struct S2 *p_context, uint8_t scheme, uint8_t curve, uint8_t keys) +void helper_func_echo_kex_report_frame(struct S2 *p_context, + uint8_t scheme, + uint8_t curve, + uint8_t keys) { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x00, 0x00, 0x00}; // This data must be compared to earlier sent data. As long as frames are not defined, this data is unknown. + uint8_t s2_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x05, + 0x00, + 0x00, + 0x00}; // This data must be compared to earlier sent data. As long as frames are not defined, this data is unknown. s2_frame[3] = scheme; s2_frame[4] = curve; s2_frame[5] = keys; memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); p_context->length = sizeof(s2_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; } void helper_func_net_key_report_frame(struct S2 *p_context, uint8_t key) { -// uint8_t s2_frame[3]; - uint8_t * p_tmp = (uint8_t *)p_context->buf; - p_tmp[0] = COMMAND_CLASS_SECURITY_2; - p_tmp[1] = SECURITY_2_NETWORK_KEY_REPORT; - p_tmp[2] = key; - if (key & 0x01) - { - memcpy(&p_tmp[3], m_test_network_key_s2_class_0, sizeof(m_test_network_key_s2_class_0)); + // uint8_t s2_frame[3]; + uint8_t *p_tmp = (uint8_t *)p_context->buf; + p_tmp[0] = COMMAND_CLASS_SECURITY_2; + p_tmp[1] = SECURITY_2_NETWORK_KEY_REPORT; + p_tmp[2] = key; + if (key & 0x01) { + memcpy(&p_tmp[3], + m_test_network_key_s2_class_0, + sizeof(m_test_network_key_s2_class_0)); p_context->length = 3 + sizeof(m_test_network_key_s2_class_0); - } - else if (key & 0x02) - { - memcpy(&p_tmp[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); + } else if (key & 0x02) { + memcpy(&p_tmp[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); p_context->length = 3 + sizeof(m_test_network_key_s2_class_1); - } - else if (key & 0x04) - { - memcpy(&p_tmp[3], m_test_network_key_s2_class_2, sizeof(m_test_network_key_s2_class_2)); + } else if (key & 0x04) { + memcpy(&p_tmp[3], + m_test_network_key_s2_class_2, + sizeof(m_test_network_key_s2_class_2)); p_context->length = 3 + sizeof(m_test_network_key_s2_class_2); - } - else if (key & 0x80) - { + } else if (key & 0x80) { memcpy(&p_tmp[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); p_context->length = 3 + sizeof(m_test_network_key_s0); - } - else - { + } else { memcpy(&p_tmp[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); p_context->length = 3 + sizeof(m_test_network_key_s0); } @@ -5591,20 +7163,21 @@ void helper_func_net_key_report_frame(struct S2 *p_context, uint8_t key) void helper_func_transfer_end_frame(struct S2 *p_context) { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); p_context->length = sizeof(s2_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; } void helper_func_idle_state(struct S2 *p_context) { - mock_t * p_mock; + mock_t *p_mock; // This test will trigger a timeout to the inclusion module after which we expect to receive a // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_event; @@ -5612,33 +7185,38 @@ void helper_func_idle_state(struct S2 *p_context) s2_inclusion_notify_timeout(p_context); } -void helper_func_verify_idle_state(struct S2 *p_context, uint8_t scheme, uint8_t keys) +void helper_func_verify_idle_state(struct S2 *p_context, + uint8_t scheme, + uint8_t keys) { - mock_t * p_mock; + mock_t *p_mock; - if (!mock_call_used_as_stub(TO_STR(s2_event_handler), "s2_event_handler_mock.c")) - { + if (!mock_call_used_as_stub(TO_STR(s2_event_handler), + "s2_event_handler_mock.c")) { // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[3]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[3]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; } - if (!mock_call_used_as_stub(TO_STR(S2_send_frame), "s2_extern_mock.c")) - { - static uint8_t S2_kex_report_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x00, 0x01, 0x00}; + if (!mock_call_used_as_stub(TO_STR(S2_send_frame), "s2_extern_mock.c")) { + static uint8_t S2_kex_report_frame_retry[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x04, 0x00, 0x01, 0x00}; S2_kex_report_frame_retry[3] = scheme; S2_kex_report_frame_retry[5] = keys; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame_retry; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame_retry); } - if (!mock_call_used_as_stub(TO_STR(s2_inclusion_set_timeout), "s2_inclusion_extern_mock.c")) - { + if (!mock_call_used_as_stub(TO_STR(s2_inclusion_set_timeout), + "s2_inclusion_extern_mock.c")) { mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); p_mock->compare_rule_arg[0] = COMPARE_ANY; p_mock->expect_arg[1].value = 1000; @@ -5646,7 +7224,7 @@ void helper_func_verify_idle_state(struct S2 *p_context, uint8_t scheme, uint8_t } // At final stage retry node inclusion to ensure we are in idle stage. - s2_inclusion_joining_start(p_context,&s2_con,0); + s2_inclusion_joining_start(p_context, &s2_con, 0); helper_func_kex_get_frame(p_context); s2_inclusion_post_event(p_context, &s2_con); @@ -5654,10 +7232,11 @@ void helper_func_verify_idle_state(struct S2 *p_context, uint8_t scheme, uint8_t void helper_func_inclusion_initiated_event(void) { - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[3]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[3]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; @@ -5665,36 +7244,34 @@ void helper_func_inclusion_initiated_event(void) static void helper_func_init_s2_conn(void) { - s2_con.l_node = 2; - s2_con.r_node = 1; - s2_con.class_id = 0xFF; + s2_con.l_node = 2; + s2_con.r_node = 1; + s2_con.class_id = 0xFF; s2_con.rx_options = 0x00; } static void helper_func_init_s2_conn_lr(void) { - s2_con.l_node = 2; - s2_con.r_node = 0x101; - s2_con.class_id = 0xFF; + s2_con.l_node = 2; + s2_con.r_node = 0x101; + s2_con.class_id = 0xFF; s2_con.rx_options = 0x00; } - /* The node(libs2 here) will be initialized s2_inclusion_init(0x87) will all the keys * but as the node id is LR, libs2 will send only 0x06 (LR keys) in kex report */ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) { int test_flavour; - for (test_flavour = 0; test_flavour < 2; test_flavour++) - { - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + for (test_flavour = 0; test_flavour < 2; test_flavour++) { + uint8_t public_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_b[] = { + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -5737,34 +7314,41 @@ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; + mock_t *p_mock; struct S2 s2_context; s2_context.inclusion_state = S2_INC_IDLE; //memcpy(s2_context.temp_network_key, m_temp_key, sizeof(s2_context.temp_network_key)); - s2_inclusion_init(0x02, 0x01, 0x87); //libs2 is joining node and its initialized with all keys + s2_inclusion_init( + 0x02, + 0x01, + 0x87); //libs2 is joining node and its initialized with all keys s2_inclusion_set_event_handler(s2_event_handler); - s2_con.l_node = 0x101; //libs2 node id - s2_con.r_node = 1; //unit test node id + s2_con.l_node = 0x101; //libs2 node id + s2_con.r_node = 1; //unit test node id s2_con.class_id = 0xFF; - // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX report frame (libs2 will send it) - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x04, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x06};// Requested keys bits. Authenticated and Acess keys + uint8_t S2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x04, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x06}; // Requested keys bits. Authenticated and Acess keys mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -5772,22 +7356,28 @@ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) s2_inclusion_joining_start(&s2_context, &s2_con, 0x00); // Inject KEX Get frame uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - // Before exchange of public keys, then we expect that our public key is requested from the keystore. mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[5], &public_key_b[2], sizeof(public_key_b) - 2); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; @@ -5799,26 +7389,32 @@ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x06}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x06}; - if (test_flavour == 1) - { + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ s2_kex_set_frame[2] |= 0x10; } s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x06; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x06; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -5828,44 +7424,62 @@ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) p_mock->output_arg[0].pointer = public_key_b; //Inject Public key report frame - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - // Expect Echo(KEX Report) (libs2 will send it) - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x06}; // Note: Echo flag set. - if (test_flavour == 1) - { + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x06}; // Note: Echo flag set. + if (test_flavour == 1) { /* Test the special case where a reserved bit is set in the KEX_SET */ /* Expect the reserved bit 0x10 to be set in the KEX_SET_ECHO */ S2_echo_kex_set_frame[2] |= 0x10; } mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; // Expect Network Key get (libs2 will send it) - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; - + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. // The challenge response should result in correct pub key being set on the context. s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); // After receiving public key from joining node, the upper layer must specify our public key to be send. (This can also be done on initialization, but must happen no later than the received event). @@ -5874,14 +7488,20 @@ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x06}; // this is being sent from unit test to libs2 + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x05, + 0x02, + 0x01, + 0x06}; // this is being sent from unit test to libs2 s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); - } /* for(test_flavour) */ + } /* for(test_flavour) */ } /** @@ -5889,17 +7509,17 @@ void test_kex_joining_node_state_machine_lr_requeesting_classic_keys(void) * except that in this test, last S2 Transfer End received by joining node, * has Verify Key flag set to 0, which should stop the inclusion */ -void test_kex_joining_node_error_transfer_end(void) { - - uint8_t public_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; +void test_kex_joining_node_error_transfer_end(void) +{ + uint8_t public_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - uint8_t private_key_b[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + uint8_t private_key_b[] + = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Private key. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; mock_calls_clear(); mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); @@ -5942,24 +7562,29 @@ void test_kex_joining_node_error_transfer_end(void) { * e) Joining node aborts inclusion process. * */ - mock_t * p_mock; + mock_t *p_mock; // When secure learn mode is started then the following event is expected when the joining node receives a KEX Get from including node. - zwave_event_t * p_expected_inc_init_event = (zwave_event_t *)m_test_mem_pool[2]; + zwave_event_t *p_expected_inc_init_event + = (zwave_event_t *)m_test_mem_pool[2]; p_expected_inc_init_event->event_type = S2_NODE_INCLUSION_INITIATED_EVENT; mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_init_event; // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x04, // reserved | NLS support | Request CSA | Echo - 0x02, // Supported schemes. Scheme 0 and 2. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. + uint8_t S2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x04, // reserved | NLS support | Request CSA | Echo + 0x02, // Supported schemes. Scheme 0 and 2. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_kex_report_frame; p_mock->expect_arg[3].value = sizeof(S2_kex_report_frame); p_mock->return_code.value = 1; @@ -5968,23 +7593,36 @@ void test_kex_joining_node_error_transfer_end(void) { mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); p_mock->output_arg[0].pointer = public_key_b; - uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. + uint8_t s2_public_key_frame[3 + sizeof(public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. Note the first two bytes should not be transmitted on authenticated/access keys. memcpy(&s2_public_key_frame[5], &public_key_b[2], sizeof(public_key_b) - 2); mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = s2_public_key_frame; p_mock->expect_arg[3].value = sizeof(s2_public_key_frame); p_mock->return_code.value = 1; // When receiving public key A, then we expect an event to be pushed up and both our public and private keys are requested from the keystore. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_a); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_a); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); mock_call_expect(TO_STR(s2_event_handler), &p_mock); p_mock->expect_arg[0].pointer = p_expected_inc_req_event; @@ -5994,54 +7632,86 @@ void test_kex_joining_node_error_transfer_end(void) { p_mock->output_arg[0].pointer = public_key_b; // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; // Note: Echo flag set. + uint8_t S2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_set_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_set_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_2_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_2_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_2_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_get_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_get_0_frame); + p_mock->return_code.value = 1; - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. - p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); - p_mock->return_code.value = 1; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = s2_net_key_verify_0_frame; // Ideally, this should be updated to be identically to replayed received KEX Report. + p_mock->expect_arg[3].value = sizeof(s2_net_key_verify_0_frame); + p_mock->return_code.value = 1; // When S2 Transfer End with Key Verify set to 0 is received, we expect a joining node to abort inclusion - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[1]; + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[1]; p_expected_complete_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x0; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = KEX_FAIL_KEY_VERIFY; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x0; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = KEX_FAIL_KEY_VERIFY; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; + p_mock->expect_arg[0].pointer = p_expected_complete_event; /** * Test execution. @@ -6057,9 +7727,9 @@ void test_kex_joining_node_error_transfer_end(void) { // KEX Get frame received. uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - s2_context.buf = S2_kex_get_frame; - s2_context.length = sizeof(S2_kex_get_frame); - s2_con.class_id = 0xFF; + s2_context.buf = S2_kex_get_frame; + s2_context.length = sizeof(S2_kex_get_frame); + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // KEX report is expeted to be transmitted. Let's make the s2_send_frame a success. @@ -6070,24 +7740,32 @@ void test_kex_joining_node_error_transfer_end(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + uint8_t s2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; s2_context.buf = s2_kex_set_frame; s2_context.length = sizeof(s2_kex_set_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); - uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_a, sizeof(m_test_public_key_a)); + uint8_t public_key_frame[3 + sizeof(m_test_public_key_a)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_a, + sizeof(m_test_public_key_a)); s2_context.buf = public_key_frame; s2_context.length = sizeof(public_key_frame); - s2_con.class_id = 0xFF; + s2_con.class_id = 0xFF; s2_inclusion_post_event(&s2_context, &s2_con); // After the received public key is pushed upwards in the system, then it is expected to receive a challenge response from the upper level. // The challenge response should result in correct pub key being set on the context. s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 0); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_a, sizeof(m_test_public_key_a)); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_a, + sizeof(m_test_public_key_a)); // After receiving public key from joining node, the upper layer must specify our public key to be send. (This can also be done on initialization, but must happen no later than the received event). @@ -6096,44 +7774,61 @@ void test_kex_joining_node_error_transfer_end(void) { // Selected schemes: scheme 0 and scheme 2. // Selected curve25519 // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x82}; + uint8_t s2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x05, 0x02, 0x01, 0x82}; s2_context.buf = s2_echo_kex_report_frame; s2_context.length = sizeof(s2_echo_kex_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); + uint8_t s2_net_key_report_frame[3 + sizeof(m_test_network_key_s2_class_1)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); s2_context.buf = s2_net_key_report_frame; s2_context.length = sizeof(s2_net_key_report_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 Transfer end frame received. // bit0: Key request complete not set, // bit1: Key verified set, // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Network Key Report frame received. - uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; // Keys requested, Security2, class 2 - Security0, network key. - memcpy(&s2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); + uint8_t s2_net_key_report_0_frame[3 + sizeof(m_test_network_key_s0)] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; // Keys requested, Security2, class 2 - Security0, network key. + memcpy(&s2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); s2_context.buf = s2_net_key_report_0_frame; s2_context.length = sizeof(s2_net_key_report_0_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // Expect KEX FAIL to be sent. - uint8_t S2_network_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_VERIFY}; + uint8_t S2_network_kex_fail_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_VERIFY}; mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. p_mock->expect_arg[2].pointer = S2_network_kex_fail_frame; p_mock->expect_arg[3].value = sizeof(S2_network_kex_fail_frame); p_mock->return_code.value = 1; @@ -6144,10 +7839,11 @@ void test_kex_joining_node_error_transfer_end(void) { // bit0: Key request complete not set, // bit1: Key verified not set, // bit2-7: Reserved. - s2_transfer_end_frame[2] = 0x00; // {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x00} + s2_transfer_end_frame[2] + = 0x00; // {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x00} s2_context.buf = s2_transfer_end_frame; s2_context.length = sizeof(s2_transfer_end_frame); - s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_con.class_id = UNIT_TEST_TEMP_KEY_SECURE; s2_inclusion_post_event(&s2_context, &s2_con); // S2 inclusion is aborted now diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/protocol/S2.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/protocol/S2.c index be7d09a4e..3ae7f0445 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/protocol/S2.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/protocol/S2.c @@ -10,7 +10,7 @@ #include "s2_protocol.h" #include "s2_classcmd.h" #include "../inclusion/s2_inclusion_internal.h" -#include +#include #include "ccm.h" #include "aes_cmac.h" #include "nextnonce.h" @@ -28,12 +28,13 @@ struct S2 the_context; #endif -#define CTX_DEF struct S2* ctxt = p_context; +#define CTX_DEF struct S2 *ctxt = p_context; CTR_DRBG_CTX s2_ctr_drbg; #ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wunused-function" //TODO: Remove after merging in complete multicast support +#pragma GCC diagnostic ignored \ + "-Wunused-function" //TODO: Remove after merging in complete multicast support #endif #define AUTH_TAG_LEN 8 @@ -44,52 +45,72 @@ transmission a success, so we dont block forever."*/ #define SEND_DATA_TIMEOUT 65000 //Forwards -static void -S2_fsm_post_event(struct S2* p_context, event_t e, event_data_t* d); +static void S2_fsm_post_event(struct S2 *p_context, event_t e, event_data_t *d); -static void -S2_set_peer(struct S2* p_context, const s2_connection_t* peer, const uint8_t* buf, uint16_t len); -static int -S2_span_ok(struct S2* p_context, const s2_connection_t* con); +static void S2_set_peer(struct S2 *p_context, + const s2_connection_t *peer, + const uint8_t *buf, + uint16_t len); +static int S2_span_ok(struct S2 *p_context, const s2_connection_t *con); static uint8_t -S2_register_nonce(struct S2* p_context, const uint8_t* buf, uint16_t len); -static void -S2_send_nonce_get(struct S2* p_context); -static int -S2_verify_seq(struct S2* p_context, const s2_connection_t* peer, uint8_t seq); -static void -S2_encrypt_and_send(struct S2* p_context); -static void -S2_send_nonce_report(struct S2* p_context, const s2_connection_t* conn, uint8_t flags); + S2_register_nonce(struct S2 *p_context, const uint8_t *buf, uint16_t len); +static void S2_send_nonce_get(struct S2 *p_context); static int -S2_is_peernode(struct S2* p_context, const s2_connection_t* peer); + S2_verify_seq(struct S2 *p_context, const s2_connection_t *peer, uint8_t seq); +static void S2_encrypt_and_send(struct S2 *p_context); +static void S2_send_nonce_report(struct S2 *p_context, + const s2_connection_t *conn, + uint8_t flags); +static int S2_is_peernode(struct S2 *p_context, const s2_connection_t *peer); #ifdef ZW_CONTROLLER -static void S2_send_nls_state_set(struct S2* p_context, s2_connection_t* con, bool nls_active); -static void S2_send_nls_state_get(struct S2* p_context, s2_connection_t* con); +static void S2_send_nls_state_set(struct S2 *p_context, + s2_connection_t *con, + bool nls_active); +static void S2_send_nls_state_get(struct S2 *p_context, s2_connection_t *con); static void S2_prepare_nls_node_list_get(uint8_t *buf, bool request); -static void S2_send_nls_node_list_get(struct S2* p_context, s2_connection_t* con, bool request); -static void S2_prepare_nls_node_list_report(uint8_t *buf, bool is_last_node, uint16_t node_id, uint8_t granted_keys, uint8_t nls_state); -static void S2_send_nls_node_list_report(struct S2* p_context, s2_connection_t* con, bool is_last_node, uint16_t node_id, uint8_t granted_keys, uint8_t nls_state); +static void S2_send_nls_node_list_get(struct S2 *p_context, + s2_connection_t *con, + bool request); +static void S2_prepare_nls_node_list_report(uint8_t *buf, + bool is_last_node, + uint16_t node_id, + uint8_t granted_keys, + uint8_t nls_state); +static void S2_send_nls_node_list_report(struct S2 *p_context, + s2_connection_t *con, + bool is_last_node, + uint16_t node_id, + uint8_t granted_keys, + uint8_t nls_state); #endif /* ZW_CONTROLLER */ -static void S2_send_nls_state_report(struct S2* p_context, s2_connection_t* con); -static void S2_command_handler(struct S2* p_context, s2_connection_t* src, uint8_t* cmd, uint16_t cmd_length); - -static void -next_mpan_state(struct MPAN* mpan); - -static decrypt_return_code_t -S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, uint8_t* msg, uint16_t msg_len, uint8_t** plain_text, - uint16_t* plain_text_len); -static struct SPAN* -find_span_by_node(struct S2* p_context, const s2_connection_t* con); -static int -S2_make_aad(struct S2* p_context, node_t sender, node_t receiver, uint8_t* msg, uint16_t hdr_len, uint16_t msg_len, - uint8_t* aad, uint16_t max_size); - -static void -S2_send_raw(struct S2* p_context, uint8_t* buf, uint16_t len); -static uint8_t -S2_is_mos(struct S2* p_context, node_t node_id, uint8_t clear); +static void S2_send_nls_state_report(struct S2 *p_context, + s2_connection_t *con); +static void S2_command_handler(struct S2 *p_context, + s2_connection_t *src, + uint8_t *cmd, + uint16_t cmd_length); + +static void next_mpan_state(struct MPAN *mpan); + +static decrypt_return_code_t S2_decrypt_msg(struct S2 *p_context, + s2_connection_t *conn, + uint8_t *msg, + uint16_t msg_len, + uint8_t **plain_text, + uint16_t *plain_text_len); +static struct SPAN *find_span_by_node(struct S2 *p_context, + const s2_connection_t *con); +static int S2_make_aad(struct S2 *p_context, + node_t sender, + node_t receiver, + uint8_t *msg, + uint16_t hdr_len, + uint16_t msg_len, + uint8_t *aad, + uint16_t max_size); + +static void S2_send_raw(struct S2 *p_context, uint8_t *buf, uint16_t len); +static uint8_t S2_is_mos(struct S2 *p_context, node_t node_id, uint8_t clear); static void convert_normal_to_lr_keyclass(s2_connection_t *con); static void convert_lr_to_normal_keyclass(s2_connection_t *con); @@ -100,8 +121,11 @@ static void convert_lr_to_normal_keyclass(s2_connection_t *con); * * \return 1 if send succeeds. 0 if send fails due to S2 busy or parameter errors. */ -static uint8_t -S2_send_data_all_cast(struct S2* p_context, const s2_connection_t* con, const uint8_t* buf, uint16_t len, event_t ev); +static uint8_t S2_send_data_all_cast(struct S2 *p_context, + const s2_connection_t *con, + const uint8_t *buf, + uint16_t len, + event_t ev); #ifdef ZWAVE_PSA_SECURE_VAULT static uint32_t convert_key_slot_to_keyid(uint8_t slot_id) @@ -135,33 +159,32 @@ static uint32_t convert_key_slot_to_keyid(uint8_t slot_id) * Find or allocate an mpan by group_id id no match can be found * we use a new entry. */ -static struct MPAN* -find_mpan_by_group_id(struct S2* p_context, node_t owner_id, uint8_t group_id, uint8_t create_new) +static struct MPAN *find_mpan_by_group_id(struct S2 *p_context, + node_t owner_id, + uint8_t group_id, + uint8_t create_new) { CTX_DEF uint8_t rnd[RANDLEN]; int i; - for (i = 0; i < MPAN_TABLE_SIZE; i++) - { - if ((ctxt->mpan_table[i].state != MPAN_NOT_USED) && (ctxt->mpan_table[i].group_id == group_id) - && (ctxt->mpan_table[i].owner_id == owner_id) && ((1 << ctxt->mpan_table[i].class_id) & ctxt->loaded_keys)) - { + for (i = 0; i < MPAN_TABLE_SIZE; i++) { + if ((ctxt->mpan_table[i].state != MPAN_NOT_USED) + && (ctxt->mpan_table[i].group_id == group_id) + && (ctxt->mpan_table[i].owner_id == owner_id) + && ((1 << ctxt->mpan_table[i].class_id) & ctxt->loaded_keys)) { return &ctxt->mpan_table[i]; } } - if (!create_new) - { + if (!create_new) { return 0; } /*We need to be find an unused group handle */ AES_CTR_DRBG_Generate(&s2_ctr_drbg, rnd); /*Allocate new entry if possible */ - for (i = 0; i < MPAN_TABLE_SIZE; i++) - { - if (ctxt->mpan_table[i].state == MPAN_NOT_USED) - { + for (i = 0; i < MPAN_TABLE_SIZE; i++) { + if (ctxt->mpan_table[i].state == MPAN_NOT_USED) { break; } } @@ -169,16 +192,16 @@ find_mpan_by_group_id(struct S2* p_context, node_t owner_id, uint8_t group_id, u /*Just select a random entry Note this will overwrite existing entries * TODO we should really select the oldest entry * */ - if (i == MPAN_TABLE_SIZE) - { + if (i == MPAN_TABLE_SIZE) { // dropping random span entry i = rnd[0] % MPAN_TABLE_SIZE; } - ctxt->mpan_table[i].state = owner_id ? MPAN_MOS : MPAN_SET; + ctxt->mpan_table[i].state = owner_id ? MPAN_MOS : MPAN_SET; ctxt->mpan_table[i].group_id = group_id; ctxt->mpan_table[i].owner_id = owner_id; - ctxt->mpan_table[i].class_id = ctxt->peer.class_id; //Here we assume that peer is set... + ctxt->mpan_table[i].class_id + = ctxt->peer.class_id; //Here we assume that peer is set... AES_CTR_DRBG_Generate(&s2_ctr_drbg, ctxt->mpan_table[i].inner_state); ; @@ -186,18 +209,17 @@ find_mpan_by_group_id(struct S2* p_context, node_t owner_id, uint8_t group_id, u return &ctxt->mpan_table[i]; } -static struct SPAN * -find_span_by_node(struct S2* p_context, const s2_connection_t* con) +static struct SPAN *find_span_by_node(struct S2 *p_context, + const s2_connection_t *con) { CTX_DEF uint8_t rnd[RANDLEN]; int i; /* Locate existing entry */ - for (i = 0; i < SPAN_TABLE_SIZE; i++) - { - if (ctxt->span_table[i].state != SPAN_NOT_USED && (ctxt->span_table[i].lnode == con->l_node) - && (ctxt->span_table[i].rnode == con->r_node)) - { + for (i = 0; i < SPAN_TABLE_SIZE; i++) { + if (ctxt->span_table[i].state != SPAN_NOT_USED + && (ctxt->span_table[i].lnode == con->l_node) + && (ctxt->span_table[i].rnode == con->r_node)) { return &ctxt->span_table[i]; } } @@ -205,24 +227,21 @@ find_span_by_node(struct S2* p_context, const s2_connection_t* con) AES_CTR_DRBG_Generate(&s2_ctr_drbg, rnd); /*Allocate new entry if possible */ - for (i = 0; i < SPAN_TABLE_SIZE; i++) - { - if (ctxt->span_table[i].state == SPAN_NOT_USED) - { + for (i = 0; i < SPAN_TABLE_SIZE; i++) { + if (ctxt->span_table[i].state == SPAN_NOT_USED) { break; } } /*Just select a random entry Note this will overwrite existing entries*/ - if (i == SPAN_TABLE_SIZE) - { + if (i == SPAN_TABLE_SIZE) { // dropping random span entry i = rnd[0] % SPAN_TABLE_SIZE; } - ctxt->span_table[i].state = SPAN_NO_SEQ; - ctxt->span_table[i].lnode = con->l_node; - ctxt->span_table[i].rnode = con->r_node; + ctxt->span_table[i].state = SPAN_NO_SEQ; + ctxt->span_table[i].lnode = con->l_node; + ctxt->span_table[i].rnode = con->r_node; ctxt->span_table[i].tx_seq = rnd[1]; return &ctxt->span_table[i]; @@ -231,20 +250,17 @@ find_span_by_node(struct S2* p_context, const s2_connection_t* con) /** * Check if the span is synchronized. */ -static int -S2_span_ok(struct S2* p_context, const s2_connection_t* con) +static int S2_span_ok(struct S2 *p_context, const s2_connection_t *con) { CTX_DEF - const struct SPAN *span = find_span_by_node(ctxt, con); + const struct SPAN *span = find_span_by_node(ctxt, con); - if (span) - { - return ((span->state == SPAN_NEGOTIATED) || (span->state == SPAN_SOS_REMOTE_NONCE)) - && (span->class_id == con->class_id); - } - else - { + if (span) { + return ((span->state == SPAN_NEGOTIATED) + || (span->state == SPAN_SOS_REMOTE_NONCE)) + && (span->class_id == con->class_id); + } else { return 0; } } @@ -252,14 +268,13 @@ S2_span_ok(struct S2* p_context, const s2_connection_t* con) /* * Send nonce get to ctxt->peer */ -static void -S2_send_nonce_get(struct S2* p_context) +static void S2_send_nonce_get(struct S2 *p_context) { CTX_DEF - static uint8_t nonce_get[] = - { COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_GET, 0 }; + static uint8_t nonce_get[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_GET, 0}; - const struct SPAN *span = find_span_by_node(ctxt, &ctxt->peer); + const struct SPAN *span = find_span_by_node(ctxt, &ctxt->peer); assert(span); @@ -271,22 +286,19 @@ S2_send_nonce_get(struct S2* p_context) * Verify the sequence of the received frame. */ static int -S2_verify_seq(struct S2* p_context, const s2_connection_t* peer, uint8_t seq) + S2_verify_seq(struct S2 *p_context, const s2_connection_t *peer, uint8_t seq) { CTX_DEF - struct SPAN *span = find_span_by_node(ctxt, peer); + struct SPAN *span = find_span_by_node(ctxt, peer); /* If this is a completely new entry, we will just copy seq number and accept it. To allow detection of old frames in the network, we use a window with more than one frame in the duplicate check. */ if (span->state == SPAN_NO_SEQ - || (uint8_t)(span->rx_seq - seq) >= S2_SEQ_DUPL_WINDOW_SIZE) - { + || (uint8_t)(span->rx_seq - seq) >= S2_SEQ_DUPL_WINDOW_SIZE) { span->rx_seq = seq; return 1; - } - else - { + } else { // Duplicate frame dropped return 0; } @@ -313,61 +325,52 @@ S2_verify_seq(struct S2* p_context, const s2_connection_t* peer, uint8_t seq) /** * Return node if the node in question has reported MOS */ -static uint8_t -S2_is_node_mos(struct S2* p_context, node_t nodeid) +static uint8_t S2_is_node_mos(struct S2 *p_context, node_t nodeid) { CTX_DEF uint8_t i; - for (i = 0; i < MOS_LIST_LENGTH; i++) - { - if (ctxt->mos_list[i].node_id == nodeid) - { + for (i = 0; i < MOS_LIST_LENGTH; i++) { + if (ctxt->mos_list[i].node_id == nodeid) { return 1; } } return 0; - } /* Add MPAN extensions for the current ctxt->peer by checks our mpan table * for nodes who is reported MOS. * * */ -static uint16_t -S2_add_mpan_extensions(struct S2* p_context, uint8_t* ext_data) +static uint16_t S2_add_mpan_extensions(struct S2 *p_context, uint8_t *ext_data) { CTX_DEF uint8_t i, k; uint8_t *p; - struct MPAN* mpan; + struct MPAN *mpan; p = ext_data; k = 0; - for (i = 0; i < MOS_LIST_LENGTH; i++) - { - if (ctxt->mos_list[i].node_id == ctxt->peer.r_node) - { + for (i = 0; i < MOS_LIST_LENGTH; i++) { + if (ctxt->mos_list[i].node_id == ctxt->peer.r_node) { mpan = find_mpan_by_group_id(ctxt, 0, ctxt->mos_list[i].group_id, 0); - if (!mpan) - { + if (!mpan) { // could not find MPAN continue; } k++; *p++ = 19; - *p++ = S2_MSG_EXTHDR_TYPE_MPAN | S2_MSG_EXTHDR_MORE_FLAG | S2_MSG_EXTHDR_CRITICAL_FLAG; + *p++ = S2_MSG_EXTHDR_TYPE_MPAN | S2_MSG_EXTHDR_MORE_FLAG + | S2_MSG_EXTHDR_CRITICAL_FLAG; *p++ = ctxt->mos_list[i].group_id; memcpy(p, mpan->inner_state, 16); //Remove the node from the mos list ctxt->mos_list[i].node_id = 0; - } } /*Clear the more flag for the last extension, FIXME this does not quite work * if we append extensions after this one */ - if (k) - { + if (k) { ext_data[(k - 1) * 19 + 1] &= ~S2_MSG_EXTHDR_MORE_FLAG; } return k * 19; @@ -376,28 +379,28 @@ S2_add_mpan_extensions(struct S2* p_context, uint8_t* ext_data) /** * Encrypt a single cast message stored in ctxt and send it */ -void -S2_encrypt_and_send(struct S2* p_context) +void S2_encrypt_and_send(struct S2 *p_context) { CTX_DEF uint8_t aad[64]; uint16_t aad_len; - uint8_t ei_sender[RANDLEN]; //Note we are actually only using the first 16 bytes + uint8_t + ei_sender[RANDLEN]; //Note we are actually only using the first 16 bytes uint8_t ei_receiver[16]; uint8_t nonce[16]; - uint8_t* ciphertext; + uint8_t *ciphertext; - uint8_t* ext_data; - uint16_t hdr_len; //Length of unencrypted data - uint16_t shdr_len; //Length of encrypted header - uint8_t* msg; + uint8_t *ext_data; + uint16_t hdr_len; //Length of unencrypted data + uint16_t shdr_len; //Length of encrypted header + uint8_t *msg; uint8_t n_ext; uint16_t msg_len; - struct SPAN *span = find_span_by_node(ctxt, &ctxt->peer); + struct SPAN *span = find_span_by_node(ctxt, &ctxt->peer); - msg = ctxt->workbuf; + msg = ctxt->workbuf; msg[0] = COMMAND_CLASS_SECURITY_2; msg[1] = SECURITY_2_MESSAGE_ENCAPSULATION; msg[2] = span->tx_seq; @@ -405,22 +408,25 @@ S2_encrypt_and_send(struct S2* p_context) msg[3] = 0; hdr_len = 4; - n_ext = 0; + n_ext = 0; /*If span is not negotiated, include senders nonce (SN) */ ext_data = &msg[4]; - if (span->state == SPAN_SOS_REMOTE_NONCE) - { + if (span->state == SPAN_SOS_REMOTE_NONCE) { AES_CTR_DRBG_Generate(&s2_ctr_drbg, ei_sender); memcpy(ei_receiver, span->d.r_nonce, sizeof(ei_receiver)); - next_nonce_instantiate(&span->d.rng, ei_sender, ei_receiver, ctxt->sg[ctxt->peer.class_id].nonce_key); + next_nonce_instantiate(&span->d.rng, + ei_sender, + ei_receiver, + ctxt->sg[ctxt->peer.class_id].nonce_key); span->class_id = ctxt->peer.class_id; - span->state = SPAN_NEGOTIATED; //TODO is it better to set this on send_data complete? + span->state + = SPAN_NEGOTIATED; //TODO is it better to set this on send_data complete? - *ext_data++ = 2 + sizeof(span->d.r_nonce); //Extension length + *ext_data++ = 2 + sizeof(span->d.r_nonce); //Extension length *ext_data++ = S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN; memcpy(ext_data, ei_sender, 16); hdr_len += 2 + 16; @@ -428,13 +434,12 @@ S2_encrypt_and_send(struct S2* p_context) n_ext++; } - if ((ctxt->peer.tx_options & (S2_TXOPTION_SINGLECAST_FOLLOWUP | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP)) && ctxt->mpan) - { - + if ((ctxt->peer.tx_options + & (S2_TXOPTION_SINGLECAST_FOLLOWUP + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP)) + && ctxt->mpan) { /* If the destination is mos, then we will add the MPAN extension instead */ - if (!S2_is_node_mos(ctxt, ctxt->peer.r_node)) - { - + if (!S2_is_node_mos(ctxt, ctxt->peer.r_node)) { /* Add the MGRP header extension */ *ext_data++ = 3; *ext_data++ = S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_MGRP; @@ -443,30 +448,27 @@ S2_encrypt_and_send(struct S2* p_context) n_ext++; } - if ((ctxt->peer.tx_options & S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP) && ctxt->retry == 2) - { + if ((ctxt->peer.tx_options & S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP) + && ctxt->retry == 2) { next_mpan_state(ctxt->mpan); } } /*Add MOS extension */ - if (ctxt->mpan && ctxt->mpan->state == MPAN_MOS) - { + if (ctxt->mpan && ctxt->mpan->state == MPAN_MOS) { ctxt->mpan->state = MPAN_NOT_USED; - ctxt->mpan = 0; - *ext_data++ = 2; - *ext_data++ = S2_MSG_EXTHDR_TYPE_MOS; + ctxt->mpan = 0; + *ext_data++ = 2; + *ext_data++ = S2_MSG_EXTHDR_TYPE_MOS; hdr_len += 2; n_ext++; } /*Insert more flag*/ - if (n_ext) - { + if (n_ext) { msg[3] |= SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK; ext_data = &msg[4]; - while (--n_ext) - { + while (--n_ext) { ext_data[1] |= S2_MSG_EXTHDR_MORE_FLAG; } ext_data += *ext_data; @@ -476,33 +478,48 @@ S2_encrypt_and_send(struct S2* p_context) /* Add the secure extensions */ shdr_len = S2_add_mpan_extensions(ctxt, ciphertext); - if (shdr_len) - { - msg[3] |= - SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_ENCRYPTED_EXTENSION_BIT_MASK; + if (shdr_len) { + msg[3] + |= SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_ENCRYPTED_EXTENSION_BIT_MASK; } memcpy(ciphertext + shdr_len, ctxt->buf, ctxt->length); - aad_len = (uint16_t) S2_make_aad(ctxt, ctxt->peer.l_node, ctxt->peer.r_node, msg, hdr_len, - ctxt->length + shdr_len + hdr_len + AUTH_TAG_LEN, aad, sizeof(aad)); + aad_len + = (uint16_t)S2_make_aad(ctxt, + ctxt->peer.l_node, + ctxt->peer.r_node, + msg, + hdr_len, + ctxt->length + shdr_len + hdr_len + AUTH_TAG_LEN, + aad, + sizeof(aad)); /*TODO we should consider to roll the nonce when we have recevied in ACK*/ - next_nonce_generate(&span->d.rng, nonce); //Create the new nonce + next_nonce_generate(&span->d.rng, nonce); //Create the new nonce #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - size_t out_len = 0; + size_t out_len = 0; uint32_t ccm_key_id = ZWAVE_CCM_TEMP_ENC_KEY_ID; - if (ctxt->is_keys_restored == false) - { - /* Import key into secure vault */ - zw_wrap_aes_key_secure_vault(&ccm_key_id, ctxt->sg[ctxt->peer.class_id].enc_key, ZW_PSA_ALG_CCM); - } - else - { + if (ctxt->is_keys_restored == false) { + /* Import key into secure vault */ + zw_wrap_aes_key_secure_vault(&ccm_key_id, + ctxt->sg[ctxt->peer.class_id].enc_key, + ZW_PSA_ALG_CCM); + } else { /* Use secure vault for encryption using PSA APIs */ - ccm_key_id = convert_keyclass_to_derived_key_id(convert_key_slot_to_keyid(ctxt->peer.class_id), ZWAVE_KEY_TYPE_SINGLE_CAST); - } - zw_psa_aead_encrypt_ccm(ccm_key_id, nonce, ZWAVE_PSA_AES_NONCE_LENGTH, aad, aad_len, ciphertext, - ctxt->length + shdr_len, ciphertext, ctxt->length+shdr_len+ZWAVE_PSA_AES_MAC_LENGTH, &out_len); + ccm_key_id = convert_keyclass_to_derived_key_id( + convert_key_slot_to_keyid(ctxt->peer.class_id), + ZWAVE_KEY_TYPE_SINGLE_CAST); + } + zw_psa_aead_encrypt_ccm(ccm_key_id, + nonce, + ZWAVE_PSA_AES_NONCE_LENGTH, + aad, + aad_len, + ciphertext, + ctxt->length + shdr_len, + ciphertext, + ctxt->length + shdr_len + ZWAVE_PSA_AES_MAC_LENGTH, + &out_len); msg_len = out_len; assert(msg_len == (ctxt->length + shdr_len + ZWAVE_PSA_AES_MAC_LENGTH)); /* Remove key from vault */ @@ -510,8 +527,13 @@ S2_encrypt_and_send(struct S2* p_context) zw_psa_destroy_key(ccm_key_id); } #else - msg_len = (uint16_t) CCM_encrypt_and_auth(ctxt->sg[ctxt->peer.class_id].enc_key, nonce, aad, aad_len, ciphertext, - ctxt->length + shdr_len); + msg_len + = (uint16_t)CCM_encrypt_and_auth(ctxt->sg[ctxt->peer.class_id].enc_key, + nonce, + aad, + aad_len, + ciphertext, + ctxt->length + shdr_len); #endif assert(msg_len > 0); @@ -519,44 +541,40 @@ S2_encrypt_and_send(struct S2* p_context) } static inline uint8_t -bigint_add(uint8_t *r, const uint8_t *a, const uint8_t *b, uint16_t len) + bigint_add(uint8_t *r, const uint8_t *a, const uint8_t *b, uint16_t len) { uint16_t i; uint16_t tmp = 0; - for (i=0; i>= 8; } return (uint8_t)tmp; } -static void -next_mpan_state(struct MPAN * mpan) +static void next_mpan_state(struct MPAN *mpan) { - static const uint8_t one[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + static const uint8_t one[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; //TODO check that it will roll around bigint_add(mpan->inner_state, mpan->inner_state, one, 16); } -void -S2_encrypt_and_send_multi(struct S2* p_context) +void S2_encrypt_and_send_multi(struct S2 *p_context) { CTX_DEF uint8_t aad[64]; uint16_t aad_len; uint8_t nonce[16]; - uint8_t* ciphertext; + uint8_t *ciphertext; uint16_t hdr_len; - uint8_t* msg; + uint8_t *msg; uint16_t msg_len; event_data_t e; - msg = ctxt->workbuf; + msg = ctxt->workbuf; msg[0] = COMMAND_CLASS_SECURITY_2; msg[1] = SECURITY_2_MESSAGE_ENCAPSULATION; - msg[2] = 0xFF; //TODO + msg[2] = 0xFF; //TODO msg[3] = SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK; /* Add the encrypted header extension */ @@ -570,18 +588,28 @@ S2_encrypt_and_send_multi(struct S2* p_context) memcpy(ciphertext, ctxt->buf, ctxt->length); - aad_len = (uint16_t) S2_make_aad(ctxt, ctxt->peer.l_node, ctxt->peer.r_node, msg, hdr_len, ctxt->length + hdr_len + AUTH_TAG_LEN, - aad, sizeof(aad)); + aad_len = (uint16_t)S2_make_aad(ctxt, + ctxt->peer.l_node, + ctxt->peer.r_node, + msg, + hdr_len, + ctxt->length + hdr_len + AUTH_TAG_LEN, + aad, + sizeof(aad)); #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - uint32_t key_id = ZWAVE_ECB_TEMP_ENC_KEY_ID; - /* Import key into secure vault */ - zw_wrap_aes_key_secure_vault(&key_id, ctxt->sg[ctxt->mpan->class_id].mpan_key, ZW_PSA_ALG_ECB_NO_PAD); - zw_psa_aes_ecb_encrypt(key_id, ctxt->mpan->inner_state, nonce); - /* Remove key from vault */ - zw_psa_destroy_key(key_id); + uint32_t key_id = ZWAVE_ECB_TEMP_ENC_KEY_ID; + /* Import key into secure vault */ + zw_wrap_aes_key_secure_vault(&key_id, + ctxt->sg[ctxt->mpan->class_id].mpan_key, + ZW_PSA_ALG_ECB_NO_PAD); + zw_psa_aes_ecb_encrypt(key_id, ctxt->mpan->inner_state, nonce); + /* Remove key from vault */ + zw_psa_destroy_key(key_id); #else - AES128_ECB_encrypt(ctxt->mpan->inner_state, ctxt->sg[ctxt->mpan->class_id].mpan_key, nonce); + AES128_ECB_encrypt(ctxt->mpan->inner_state, + ctxt->sg[ctxt->mpan->class_id].mpan_key, + nonce); #endif next_mpan_state(ctxt->mpan); @@ -589,19 +617,28 @@ S2_encrypt_and_send_multi(struct S2* p_context) #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) ////////////////////////////////////////////// size_t out_len = 0; - key_id = ZWAVE_CCM_TEMP_ENC_KEY_ID; - if (ctxt->is_keys_restored == false) - { - /* Import key into secure vault */ - zw_wrap_aes_key_secure_vault(&key_id, ctxt->sg[ctxt->mpan->class_id].enc_key, ZW_PSA_ALG_CCM); - } - else - { + key_id = ZWAVE_CCM_TEMP_ENC_KEY_ID; + if (ctxt->is_keys_restored == false) { + /* Import key into secure vault */ + zw_wrap_aes_key_secure_vault(&key_id, + ctxt->sg[ctxt->mpan->class_id].enc_key, + ZW_PSA_ALG_CCM); + } else { /* Use secure vault for encryption using PSA APIs */ - key_id = convert_keyclass_to_derived_key_id(convert_key_slot_to_keyid(ctxt->mpan->class_id), ZWAVE_KEY_TYPE_SINGLE_CAST); - } - zw_psa_aead_encrypt_ccm(key_id, nonce, ZWAVE_PSA_AES_NONCE_LENGTH, aad, aad_len, ciphertext, - ctxt->length, ciphertext, ctxt->length+ZWAVE_PSA_AES_MAC_LENGTH, &out_len); + key_id = convert_keyclass_to_derived_key_id( + convert_key_slot_to_keyid(ctxt->mpan->class_id), + ZWAVE_KEY_TYPE_SINGLE_CAST); + } + zw_psa_aead_encrypt_ccm(key_id, + nonce, + ZWAVE_PSA_AES_NONCE_LENGTH, + aad, + aad_len, + ciphertext, + ctxt->length, + ciphertext, + ctxt->length + ZWAVE_PSA_AES_MAC_LENGTH, + &out_len); msg_len = out_len; assert(msg_len == (ctxt->length + ZWAVE_PSA_AES_MAC_LENGTH)); /* Remove key from vault */ @@ -609,49 +646,52 @@ S2_encrypt_and_send_multi(struct S2* p_context) zw_psa_destroy_key(key_id); } #else - msg_len = (uint16_t) CCM_encrypt_and_auth(ctxt->sg[ctxt->mpan->class_id].enc_key, nonce, aad, aad_len, ciphertext, ctxt->length); + msg_len + = (uint16_t)CCM_encrypt_and_auth(ctxt->sg[ctxt->mpan->class_id].enc_key, + nonce, + aad, + aad_len, + ciphertext, + ctxt->length); #endif assert(msg_len > 0); - if (S2_send_frame_multi(ctxt, &ctxt->peer, msg, msg_len + hdr_len)) - { + if (S2_send_frame_multi(ctxt, &ctxt->peer, msg, msg_len + hdr_len)) { //TX seq? - } - else - { + } else { e.d.tx.status = S2_TRANSMIT_COMPLETE_FAIL; S2_fsm_post_event(ctxt, SEND_DONE, &e); } } -void -S2_send_frame_done_notify(struct S2* p_context, s2_tx_status_t status, uint16_t tx_time) +void S2_send_frame_done_notify(struct S2 *p_context, + s2_tx_status_t status, + uint16_t tx_time) { CTX_DEF event_data_t e; e.d.tx.status = status; - e.d.tx.time = tx_time; + e.d.tx.time = tx_time; S2_fsm_post_event(ctxt, SEND_DONE, &e); } -uint8_t S2_is_busy(struct S2* p_context) +uint8_t S2_is_busy(struct S2 *p_context) { CTX_DEF - if(ctxt->inclusion_state != S2_INC_IDLE) - { + if (ctxt->inclusion_state != S2_INC_IDLE) { return 1; } - if( (ctxt->fsm != IDLE) && (ctxt->fsm != IS_MOS_WAIT_REPLY) ) - { + if ((ctxt->fsm != IDLE) && (ctxt->fsm != IS_MOS_WAIT_REPLY)) { return 1; } return 0; } -void S2_free_mpan(struct S2* p_context, node_t owner_id, uint8_t group_id) { +void S2_free_mpan(struct S2 *p_context, node_t owner_id, uint8_t group_id) +{ CTX_DEF // Search for a MPAN with the Group ID / owner ID, and if found, set it back to NOT USED. for (uint8_t i = 0; i < MPAN_TABLE_SIZE; i++) { @@ -667,19 +707,15 @@ void S2_free_mpan(struct S2* p_context, node_t owner_id, uint8_t group_id) { * Wrapper function to send_data, which increases tx_seq and guarantees a * SendDone event. */ -static void -S2_send_raw(struct S2* p_context, uint8_t* buf, uint16_t len) +static void S2_send_raw(struct S2 *p_context, uint8_t *buf, uint16_t len) { CTX_DEF event_data_t e; - if (S2_send_frame(ctxt, &ctxt->peer, buf, len)) - { - struct SPAN *span = find_span_by_node(ctxt, &ctxt->peer); + if (S2_send_frame(ctxt, &ctxt->peer, buf, len)) { + struct SPAN *span = find_span_by_node(ctxt, &ctxt->peer); span->tx_seq++; - } - else - { + } else { e.d.tx.status = S2_TRANSMIT_COMPLETE_FAIL; S2_fsm_post_event(ctxt, SEND_DONE, &e); } @@ -690,20 +726,18 @@ S2_send_raw(struct S2* p_context, uint8_t* buf, uint16_t len) * \param clear if set the mos state will be * cleared */ -static uint8_t -S2_is_mos(struct S2* p_context, node_t node_id, uint8_t clear) +static uint8_t S2_is_mos(struct S2 *p_context, node_t node_id, uint8_t clear) { CTX_DEF uint8_t i; - for (i = 0; i < MPAN_TABLE_SIZE; i++) - { - if ((ctxt->mpan_table[i].owner_id == node_id) && (ctxt->mpan_table[i].state == MPAN_MOS)) - { - if (clear) - { + for (i = 0; i < MPAN_TABLE_SIZE; i++) { + if ((ctxt->mpan_table[i].owner_id == node_id) + && (ctxt->mpan_table[i].state == MPAN_MOS)) { + if (clear) { ctxt->mpan_table[i].state = MPAN_NOT_USED; } - return 1;; + return 1; + ; } } return 0; @@ -716,23 +750,23 @@ S2_is_mos(struct S2* p_context, node_t node_id, uint8_t clear) * flags 1 : force_new_nonce * flags 2 : mos */ -static void -S2_send_nonce_report(struct S2* p_context, const s2_connection_t* conn, uint8_t flags) +static void S2_send_nonce_report(struct S2 *p_context, + const s2_connection_t *conn, + uint8_t flags) { CTX_DEF - struct SPAN *span; + struct SPAN *span; uint8_t rnd[RANDLEN]; static uint8_t nonce_report[2 + 2 + sizeof(span->d.r_nonce)]; - span = find_span_by_node(ctxt, conn); + span = find_span_by_node(ctxt, conn); nonce_report[0] = COMMAND_CLASS_SECURITY_2; nonce_report[1] = SECURITY_2_NONCE_REPORT; nonce_report[3] = flags; nonce_report[2] = span->tx_seq; - if (flags & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK) - { + if (flags & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK) { span->state = SPAN_SOS_LOCAL_NONCE; AES_CTR_DRBG_Generate(&s2_ctr_drbg, rnd); memcpy(span->d.r_nonce, rnd, 16); @@ -741,24 +775,27 @@ S2_send_nonce_report(struct S2* p_context, const s2_connection_t* conn, uint8_t span->tx_seq++; /*Return code is ignored here */ - S2_send_frame_no_cb(ctxt, conn, nonce_report, nonce_report[3] & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK ? 20 : 4); + S2_send_frame_no_cb( + ctxt, + conn, + nonce_report, + nonce_report[3] & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK ? 20 + : 4); } -static void -S2_set_node_mos(struct S2* p_context, node_t node) +static void S2_set_node_mos(struct S2 *p_context, node_t node) { CTX_DEF uint8_t i; if ((ctxt->fsm == VERIFYING_DELIVERY || ctxt->fsm == SENDING_MSG) - && (ctxt->peer.tx_options & (S2_TXOPTION_SINGLECAST_FOLLOWUP | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP)) - && ctxt->mpan) - { - for (i = 0; i < MOS_LIST_LENGTH; i++) - { - if (ctxt->mos_list[i].node_id == 0) - { + && (ctxt->peer.tx_options + & (S2_TXOPTION_SINGLECAST_FOLLOWUP + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP)) + && ctxt->mpan) { + for (i = 0; i < MOS_LIST_LENGTH; i++) { + if (ctxt->mos_list[i].node_id == 0) { ctxt->mos_list[i].group_id = ctxt->mpan->group_id; - ctxt->mos_list[i].node_id = node; + ctxt->mos_list[i].node_id = node; break; } } @@ -766,34 +803,34 @@ S2_set_node_mos(struct S2* p_context, node_t node) } static uint8_t -S2_register_nonce(struct S2* p_context, const uint8_t* buf, uint16_t len) + S2_register_nonce(struct S2 *p_context, const uint8_t *buf, uint16_t len) { CTX_DEF - struct SPAN *span; + struct SPAN *span; - if(!S2_verify_seq(ctxt, &ctxt->peer, buf[2])) { + if (!S2_verify_seq(ctxt, &ctxt->peer, buf[2])) { return 0; } span = find_span_by_node(ctxt, &ctxt->peer); - if (len >= (4 + 16) && (buf[3] & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK)) - { + if (len >= (4 + 16) + && (buf[3] & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK)) { memcpy(span->d.r_nonce, &buf[4], sizeof(span->d.r_nonce)); span->state = SPAN_SOS_REMOTE_NONCE; } /*Register MOS, but only if we are expecting it */ - if ((buf[3] & SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK) && (len >= 3)) - { - S2_set_node_mos(ctxt,ctxt->peer.r_node); + if ((buf[3] & SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK) + && (len >= 3)) { + S2_set_node_mos(ctxt, ctxt->peer.r_node); } return buf[3]; } //Todo: Get this macro from ZW_transport_api.h once we have updated gateway -#define LOWEST_LONG_RANGE_NODE_ID 0x0100 +#define LOWEST_LONG_RANGE_NODE_ID 0x0100 /* * Generate Additional authentication data (AAD) @@ -804,28 +841,30 @@ S2_register_nonce(struct S2* p_context, const uint8_t* buf, uint16_t len) * \param max_size the size of the aad buffer. * \return the number of bytes written into the AAD. 0 indicates that the buffer was not big enough. */ -static int -S2_make_aad(struct S2* p_context, node_t sender, node_t receiver, uint8_t* msg, uint16_t hdr_len, uint16_t msg_len, - uint8_t* aad, uint16_t max_size) +static int S2_make_aad(struct S2 *p_context, + node_t sender, + node_t receiver, + uint8_t *msg, + uint16_t hdr_len, + uint16_t msg_len, + uint8_t *aad, + uint16_t max_size) { CTX_DEF - if (max_size < (hdr_len - 2 + 8)) - { + if (max_size < (hdr_len - 2 + 8)) { return 0; } uint32_t i = 0; - if((LOWEST_LONG_RANGE_NODE_ID <= sender) || (LOWEST_LONG_RANGE_NODE_ID <= receiver)) - { + if ((LOWEST_LONG_RANGE_NODE_ID <= sender) + || (LOWEST_LONG_RANGE_NODE_ID <= receiver)) { //Use 16-bit nodeIDs for long range communication aad[i++] = (sender >> 8) & 0xFF; aad[i++] = (sender >> 0) & 0xFF; aad[i++] = (receiver >> 8) & 0xFF; aad[i++] = (receiver >> 0) & 0xFF; - } - else - { + } else { //Keep 8-bit nodeIDs for Classic communication so //all legacy products can be supported. aad[i++] = sender & 0xFF; @@ -835,8 +874,8 @@ S2_make_aad(struct S2* p_context, node_t sender, node_t receiver, uint8_t* msg, /* Convert from platform byte order to big endian */ aad[i++] = (ctxt->my_home_id >> 24) & 0xFF; aad[i++] = (ctxt->my_home_id >> 16) & 0xFF; - aad[i++] = (ctxt->my_home_id >> 8) & 0xFF; - aad[i++] = (ctxt->my_home_id >> 0) & 0xFF; + aad[i++] = (ctxt->my_home_id >> 8) & 0xFF; + aad[i++] = (ctxt->my_home_id >> 0) & 0xFF; aad[i++] = (msg_len >> 8) & 0xFF; aad[i++] = (msg_len >> 0) & 0xFF; @@ -844,55 +883,51 @@ S2_make_aad(struct S2* p_context, node_t sender, node_t receiver, uint8_t* msg, return i + hdr_len - 2; } - /* Decrypt message * emits AuthOK or auth fail * */ -static decrypt_return_code_t -S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, - uint8_t* msg, uint16_t msg_len, uint8_t** plain_text, - uint16_t* plain_text_len) +static decrypt_return_code_t S2_decrypt_msg(struct S2 *p_context, + s2_connection_t *conn, + uint8_t *msg, + uint16_t msg_len, + uint8_t **plain_text, + uint16_t *plain_text_len) { CTX_DEF - uint8_t aad_buf[64]; //We could reduce this spec says min 30 bytes + uint8_t aad_buf[64]; //We could reduce this spec says min 30 bytes uint8_t nonce[16]; - uint8_t* aad; + uint8_t *aad; uint16_t aad_len; uint8_t flags; - uint8_t* ciphertext; + uint8_t *ciphertext; uint16_t ciphertext_len; uint16_t decrypt_len; - uint8_t* ext_data; + uint8_t *ext_data; uint8_t ext_len; uint16_t hdr_len; - struct SPAN* span; - struct MPAN* mpan; - uint8_t r_nonce[16] = { 0 }; - uint8_t s_nonce[16] = { 0 }; + struct SPAN *span; + struct MPAN *mpan; + uint8_t r_nonce[16] = {0}; + uint8_t s_nonce[16] = {0}; uint8_t i; - hdr_len = 4; - decrypt_len = 0; - *plain_text = 0; + hdr_len = 4; + decrypt_len = 0; + *plain_text = 0; *plain_text_len = 0; flags = msg[3]; - if (msg_len < (hdr_len + AUTH_TAG_LEN)) - { + if (msg_len < (hdr_len + AUTH_TAG_LEN)) { goto parse_fail; } mpan = 0; - if (conn->rx_options & S2_RXOPTION_MULTICAST) - { + if (conn->rx_options & S2_RXOPTION_MULTICAST) { span = 0; - } - else - { + } else { /* Verify sequence */ - if (!S2_verify_seq(ctxt, conn, msg[2])) - { + if (!S2_verify_seq(ctxt, conn, msg[2])) { return SEQUENCE_FAIL; } @@ -900,124 +935,134 @@ S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, } /* Parse clear text extensions */ - if (flags & SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK) - { + if (flags & SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK) { ext_data = &msg[4]; - do - { + do { ext_len = ext_data[0]; hdr_len += ext_len; - if (msg_len < (hdr_len + AUTH_TAG_LEN) - || 0 == ext_len) - { + if (msg_len < (hdr_len + AUTH_TAG_LEN) || 0 == ext_len) { goto parse_fail; } - switch (ext_data[1] & S2_MSG_EXTHDR_TYPE_MASK) - { - case S2_MSG_EXTHDR_TYPE_SN: - /*We only update SPAN if we expect an update */ - if (span && span->state == SPAN_SOS_LOCAL_NONCE && (ext_len == (2 + sizeof(span->d.r_nonce)))) - { /*Save the nonces */ - memcpy(s_nonce, &ext_data[2], 16); - memcpy(r_nonce, span->d.r_nonce, 16); - span->state = SPAN_INSTANTIATE; - - next_nonce_instantiate(&span->d.rng, s_nonce, r_nonce, ctxt->sg[span->class_id].nonce_key); - } - break; - case S2_MSG_EXTHDR_TYPE_MGRP: - if (ext_len != 3) - { - goto parse_fail; - } - /*Only create new MPAN if this was a single cast followup*/ - mpan = find_mpan_by_group_id(ctxt, conn->r_node, ext_data[2], (conn->rx_options & S2_RXOPTION_MULTICAST) == 0); - break; - case S2_MSG_EXTHDR_TYPE_MOS: - if (ext_len != 2) - { - goto parse_fail; - } - S2_set_node_mos(ctxt,conn->r_node); - break; - default: - if (ext_data[1] & S2_MSG_EXTHDR_CRITICAL_FLAG) - { //Unsupported critical option - goto parse_fail; - } + switch (ext_data[1] & S2_MSG_EXTHDR_TYPE_MASK) { + case S2_MSG_EXTHDR_TYPE_SN: + /*We only update SPAN if we expect an update */ + if (span && span->state == SPAN_SOS_LOCAL_NONCE + && (ext_len + == (2 + sizeof(span->d.r_nonce)))) { /*Save the nonces */ + memcpy(s_nonce, &ext_data[2], 16); + memcpy(r_nonce, span->d.r_nonce, 16); + span->state = SPAN_INSTANTIATE; + + next_nonce_instantiate(&span->d.rng, + s_nonce, + r_nonce, + ctxt->sg[span->class_id].nonce_key); + } + break; + case S2_MSG_EXTHDR_TYPE_MGRP: + if (ext_len != 3) { + goto parse_fail; + } + /*Only create new MPAN if this was a single cast followup*/ + mpan = find_mpan_by_group_id( + ctxt, + conn->r_node, + ext_data[2], + (conn->rx_options & S2_RXOPTION_MULTICAST) == 0); + break; + case S2_MSG_EXTHDR_TYPE_MOS: + if (ext_len != 2) { + goto parse_fail; + } + S2_set_node_mos(ctxt, conn->r_node); + break; + default: + if (ext_data[1] + & S2_MSG_EXTHDR_CRITICAL_FLAG) { //Unsupported critical option + goto parse_fail; + } } - if (ext_data[1] & S2_MSG_EXTHDR_MORE_FLAG) - { + if (ext_data[1] & S2_MSG_EXTHDR_MORE_FLAG) { ext_data += ext_len; - } - else - { + } else { break; } - } - while (1); + } while (1); } - if (conn->rx_options & S2_RXOPTION_MULTICAST) - { - if (mpan == 0 || mpan->state != MPAN_SET) - { + if (conn->rx_options & S2_RXOPTION_MULTICAST) { + if (mpan == 0 || mpan->state != MPAN_SET) { goto auth_fail; } - conn->l_node = mpan->group_id; //Used to form the aad - } - else - { - if (!span || (span->state != SPAN_NEGOTIATED && span->state != SPAN_INSTANTIATE)) - { + conn->l_node = mpan->group_id; //Used to form the aad + } else { + if (!span + || (span->state != SPAN_NEGOTIATED + && span->state != SPAN_INSTANTIATE)) { // Unexpected span state goto auth_fail; } } - ciphertext = &msg[hdr_len]; + ciphertext = &msg[hdr_len]; ciphertext_len = msg_len - hdr_len; aad = &aad_buf[0]; - aad_len = (uint16_t) S2_make_aad(ctxt, conn->r_node, conn->l_node, msg, hdr_len, msg_len, aad, sizeof(aad_buf)); + aad_len = (uint16_t)S2_make_aad(ctxt, + conn->r_node, + conn->l_node, + msg, + hdr_len, + msg_len, + aad, + sizeof(aad_buf)); - if (span) - { + if (span) { /*Single cast decryption */ /*In this state we don't know which class_id was used to encrypt the frame, so * we will try de-crypting with all our classes */ /*Check the fsm before using the workbuf */ - if (ctxt->fsm == IDLE && span->state == SPAN_INSTANTIATE) - { + if (ctxt->fsm == IDLE && span->state == SPAN_INSTANTIATE) { memcpy(ctxt->workbuf, ciphertext, ciphertext_len); } - for (i = 0; i < N_SEC_CLASS; i++) - { + for (i = 0; i < N_SEC_CLASS; i++) { /*Only decrypt with a key which is loaded */ - if (ctxt->loaded_keys & (1 << span->class_id)) - { + if (ctxt->loaded_keys & (1 << span->class_id)) { next_nonce_generate(&span->d.rng, nonce); #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - size_t out_len; - zw_status_t status; - uint32_t ccm_key_id = ZWAVE_CCM_TEMP_DEC_KEY_ID; - if (ctxt->is_keys_restored == false) { - /* Import key into secure vault */ - zw_wrap_aes_key_secure_vault(&ccm_key_id, ctxt->sg[span->class_id].enc_key, ZW_PSA_ALG_CCM); - } else { - /* Use secure vault for encryption using PSA APIs */ - ccm_key_id = convert_keyclass_to_derived_key_id(convert_key_slot_to_keyid(span->class_id), ZWAVE_KEY_TYPE_SINGLE_CAST); - } - status = zw_psa_aead_decrypt_ccm(ccm_key_id, nonce, ZWAVE_PSA_AES_NONCE_LENGTH, aad, aad_len, - ciphertext, ciphertext_len, ciphertext, ciphertext_len+ZWAVE_PSA_AES_MAC_LENGTH, &out_len); + size_t out_len; + zw_status_t status; + uint32_t ccm_key_id = ZWAVE_CCM_TEMP_DEC_KEY_ID; + if (ctxt->is_keys_restored == false) { + /* Import key into secure vault */ + zw_wrap_aes_key_secure_vault(&ccm_key_id, + ctxt->sg[span->class_id].enc_key, + ZW_PSA_ALG_CCM); + } else { + /* Use secure vault for encryption using PSA APIs */ + ccm_key_id = convert_keyclass_to_derived_key_id( + convert_key_slot_to_keyid(span->class_id), + ZWAVE_KEY_TYPE_SINGLE_CAST); + } + status + = zw_psa_aead_decrypt_ccm(ccm_key_id, + nonce, + ZWAVE_PSA_AES_NONCE_LENGTH, + aad, + aad_len, + ciphertext, + ciphertext_len, + ciphertext, + ciphertext_len + ZWAVE_PSA_AES_MAC_LENGTH, + &out_len); if (status == ZW_PSA_ERROR_INVALID_SIGNATURE) { decrypt_len = 0; } else { @@ -1028,30 +1073,30 @@ S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, zw_psa_destroy_key(ccm_key_id); } #else - decrypt_len = CCM_decrypt_and_auth(ctxt->sg[span->class_id].enc_key, nonce, aad, aad_len, ciphertext, - ciphertext_len); + decrypt_len = CCM_decrypt_and_auth(ctxt->sg[span->class_id].enc_key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); #endif - if (decrypt_len) - { - span->state = SPAN_NEGOTIATED; + if (decrypt_len) { + span->state = SPAN_NEGOTIATED; conn->class_id = span->class_id; - if (mpan) - { //This means that a MGRP extension was included in the message + if ( + mpan) { //This means that a MGRP extension was included in the message /* If it was a multicast followup, set rx option */ conn->rx_options |= S2_RXOPTION_FOLLOWUP; - if (mpan->state == MPAN_MOS) - { + if (mpan->state == MPAN_MOS) { event_data_t e; - e.con = conn; + e.con = conn; ctxt->mpan = mpan; - S2_fsm_post_event(ctxt, GOT_ENC_MSG_MOS,&e); + S2_fsm_post_event(ctxt, GOT_ENC_MSG_MOS, &e); //S2_send_nonce_report(ctxt, conn, SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK); - } - else - { + } else { next_mpan_state(mpan); } } @@ -1059,16 +1104,14 @@ S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, } } - if (ctxt->fsm != IDLE || span->state == SPAN_NEGOTIATED) - { + if (ctxt->fsm != IDLE || span->state == SPAN_NEGOTIATED) { /*We were not able to backup the cipher-text so we will not be able to decrypt the message*/ goto auth_fail; } /*try the next security class */ span->class_id++; - if (span->class_id >= N_SEC_CLASS) - { + if (span->class_id >= N_SEC_CLASS) { span->class_id = 0; } @@ -1076,110 +1119,118 @@ S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, memcpy(ciphertext, ctxt->workbuf, ciphertext_len); /*reset prng to the negotiated state with the right new test key */ - next_nonce_instantiate(&span->d.rng, s_nonce, r_nonce, ctxt->sg[span->class_id].nonce_key); + next_nonce_instantiate(&span->d.rng, + s_nonce, + r_nonce, + ctxt->sg[span->class_id].nonce_key); } - } - else - { + } else { /*Multicast decryption*/ #ifdef ZWAVE_PSA_AES uint32_t key_id = ZWAVE_CCM_TEMP_ENC_KEY_ID; - zw_wrap_aes_key_secure_vault(&key_id, ctxt->sg[mpan->class_id].mpan_key, ZW_PSA_ALG_ECB_NO_PAD); + zw_wrap_aes_key_secure_vault(&key_id, + ctxt->sg[mpan->class_id].mpan_key, + ZW_PSA_ALG_ECB_NO_PAD); /* Import key into secure vault */ zw_psa_aes_ecb_encrypt(key_id, mpan->inner_state, nonce); /* Remove key from vault */ zw_psa_destroy_key(key_id); #else - AES128_ECB_encrypt(mpan->inner_state, ctxt->sg[mpan->class_id].mpan_key, nonce); + AES128_ECB_encrypt(mpan->inner_state, + ctxt->sg[mpan->class_id].mpan_key, + nonce); #endif next_mpan_state(mpan); #if defined(ZWAVE_PSA_SECURE_VAULT) && defined(ZWAVE_PSA_AES) - size_t out_len = 0; - key_id = ZWAVE_CCM_TEMP_DEC_KEY_ID; - zw_status_t status; - /* Import key into secure vault */ - zw_wrap_aes_key_secure_vault(&key_id, ctxt->sg[mpan->class_id].enc_key, ZW_PSA_ALG_CCM); - /* Use secure vault for decryption using PSA APIs */ - status = zw_psa_aead_decrypt_ccm(key_id, nonce, ZWAVE_PSA_AES_NONCE_LENGTH, aad, aad_len, - ciphertext, ciphertext_len, ciphertext, ciphertext_len+ZWAVE_PSA_AES_MAC_LENGTH, &out_len); - if (status == ZW_PSA_ERROR_INVALID_SIGNATURE) { - decrypt_len = 0; - } else { - decrypt_len = out_len; - } - /* Remove key from vault */ - zw_psa_destroy_key(key_id); + size_t out_len = 0; + key_id = ZWAVE_CCM_TEMP_DEC_KEY_ID; + zw_status_t status; + /* Import key into secure vault */ + zw_wrap_aes_key_secure_vault(&key_id, + ctxt->sg[mpan->class_id].enc_key, + ZW_PSA_ALG_CCM); + /* Use secure vault for decryption using PSA APIs */ + status = zw_psa_aead_decrypt_ccm(key_id, + nonce, + ZWAVE_PSA_AES_NONCE_LENGTH, + aad, + aad_len, + ciphertext, + ciphertext_len, + ciphertext, + ciphertext_len + ZWAVE_PSA_AES_MAC_LENGTH, + &out_len); + if (status == ZW_PSA_ERROR_INVALID_SIGNATURE) { + decrypt_len = 0; + } else { + decrypt_len = out_len; + } + /* Remove key from vault */ + zw_psa_destroy_key(key_id); #else - decrypt_len = CCM_decrypt_and_auth(ctxt->sg[mpan->class_id].enc_key, nonce, aad, aad_len, ciphertext, - ciphertext_len); + decrypt_len = CCM_decrypt_and_auth(ctxt->sg[mpan->class_id].enc_key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); #endif conn->class_id = mpan->class_id; } - if (decrypt_len == 0 || aad_len == 0) - { + if (decrypt_len == 0 || aad_len == 0) { goto auth_fail; } hdr_len = 0; /* Parse encrypted extensions */ - if (flags & SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_ENCRYPTED_EXTENSION_BIT_MASK) - { + if ( + flags + & SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_ENCRYPTED_EXTENSION_BIT_MASK) { ext_data = ciphertext; - do - { + do { ext_len = ext_data[0]; hdr_len += ext_len; - if (hdr_len > decrypt_len - || 0 == ext_len) - { + if (hdr_len > decrypt_len || 0 == ext_len) { goto parse_fail; } - switch (ext_data[1] & S2_MSG_EXTHDR_TYPE_MASK) - { - case S2_MSG_EXTHDR_TYPE_MPAN: - if (conn->rx_options & S2_RXOPTION_MULTICAST) - { - /* This extension is only allowed in singlecast messages, drop it */ - goto parse_fail; - } - if (ext_len != 19) - { - goto parse_fail; - } - mpan = find_mpan_by_group_id(ctxt, conn->r_node, ext_data[2],1); - memcpy(mpan->inner_state, &ext_data[3], 16); - mpan->state = MPAN_SET; - mpan->class_id = span->class_id; - /* If a new mpan was created and it wasn't a multicast, then it was a multicast followup */ - if ((conn->rx_options & S2_RXOPTION_MULTICAST) == 0) - { - conn->rx_options |= S2_RXOPTION_FOLLOWUP; - } - break; - default: - if (ext_data[1] & S2_MSG_EXTHDR_CRITICAL_FLAG) - { //Unsupported critical option - goto parse_fail; - } + switch (ext_data[1] & S2_MSG_EXTHDR_TYPE_MASK) { + case S2_MSG_EXTHDR_TYPE_MPAN: + if (conn->rx_options & S2_RXOPTION_MULTICAST) { + /* This extension is only allowed in singlecast messages, drop it */ + goto parse_fail; + } + if (ext_len != 19) { + goto parse_fail; + } + mpan = find_mpan_by_group_id(ctxt, conn->r_node, ext_data[2], 1); + memcpy(mpan->inner_state, &ext_data[3], 16); + mpan->state = MPAN_SET; + mpan->class_id = span->class_id; + /* If a new mpan was created and it wasn't a multicast, then it was a multicast followup */ + if ((conn->rx_options & S2_RXOPTION_MULTICAST) == 0) { + conn->rx_options |= S2_RXOPTION_FOLLOWUP; + } + break; + default: + if (ext_data[1] + & S2_MSG_EXTHDR_CRITICAL_FLAG) { //Unsupported critical option + goto parse_fail; + } } - if (ext_data[1] & S2_MSG_EXTHDR_MORE_FLAG) - { + if (ext_data[1] & S2_MSG_EXTHDR_MORE_FLAG) { ext_data += ext_len; - } - else - { + } else { break; } - } - while (1); + } while (1); } - *plain_text = ciphertext + hdr_len; + *plain_text = ciphertext + hdr_len; *plain_text_len = decrypt_len - hdr_len; return AUTH_OK; @@ -1188,32 +1239,29 @@ S2_decrypt_msg(struct S2* p_context, s2_connection_t* conn, return PARSE_FAIL; auth_fail: - if (mpan) - { + if (mpan) { mpan->state = MPAN_MOS; } - if (span) - { - span->state = SPAN_SOS; //Just invalidate the span + if (span) { + span->state = SPAN_SOS; //Just invalidate the span } /*Send nonce report if this is not a multicast*/ - if ((conn->rx_options & S2_RXOPTION_MULTICAST) == 0) - { - S2_send_nonce_report(ctxt, conn, - mpan ? - (SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK | SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK) : - SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK); + if ((conn->rx_options & S2_RXOPTION_MULTICAST) == 0) { + S2_send_nonce_report( + ctxt, + conn, + mpan ? (SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK + | SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK) + : SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK); } return AUTH_FAIL; - } /*Return true if the node is the same node as we are currently handling*/ -int -S2_is_peernode(struct S2* p_context, const s2_connection_t* peer) +int S2_is_peernode(struct S2 *p_context, const s2_connection_t *peer) { CTX_DEF return peer->l_node == ctxt->peer.l_node && peer->r_node == ctxt->peer.r_node; @@ -1222,12 +1270,14 @@ S2_is_peernode(struct S2* p_context, const s2_connection_t* peer) /* * Set the peer and message data */ -static void -S2_set_peer(struct S2* p_context, const s2_connection_t* peer, const uint8_t* buf, uint16_t len) +static void S2_set_peer(struct S2 *p_context, + const s2_connection_t *peer, + const uint8_t *buf, + uint16_t len) { CTX_DEF - ctxt->peer = *peer; - ctxt->buf = buf; //TODO decide if we want a local copy? + ctxt->peer = *peer; + ctxt->buf = buf; //TODO decide if we want a local copy? ctxt->length = len; } @@ -1236,86 +1286,101 @@ S2_set_peer(struct S2* p_context, const s2_connection_t* peer, const uint8_t* bu * \param dst Destination nodeid. Security scheme as 0=UNAUTH, 1=AUTH, 2=ACCES, (3=Sec0, not allowed here) * */ -uint8_t -S2_send_data(struct S2* p_context, s2_connection_t* dst, const uint8_t* buf, uint16_t len) +uint8_t S2_send_data(struct S2 *p_context, + s2_connection_t *dst, + const uint8_t *buf, + uint16_t len) { CTX_DEF - #ifdef ZW_CONTROLLER +#ifdef ZW_CONTROLLER if (IS_LR_NODE(dst->r_node)) { convert_normal_to_lr_keyclass(dst); } - #endif +#endif return S2_send_data_all_cast(ctxt, dst, buf, len, SEND_MSG); } -uint8_t -S2_is_send_data_busy(struct S2* p_context) +uint8_t S2_is_send_data_busy(struct S2 *p_context) { CTX_DEF return (ctxt->fsm != IDLE) && (ctxt->fsm != IS_MOS_WAIT_REPLY); } -void -S2_init_prng(void) +void S2_init_prng(void) { - uint8_t entropy[32] = { 0}; + uint8_t entropy[32] = {0}; S2_get_hw_random(entropy, sizeof(entropy)); AES_CTR_DRBG_Instantiate(&s2_ctr_drbg, entropy, NULL); } -struct S2* -S2_init_ctx(uint32_t home) +struct S2 *S2_init_ctx(uint32_t home) { - struct S2* ctx; + struct S2 *ctx; #ifdef SINGLE_CONTEXT ctx = &the_context; #else ctx = malloc(sizeof(struct S2)); - if (!ctx) - { + if (!ctx) { return 0; } #endif memset(ctx, 0, sizeof(struct S2)); - ctx->my_home_id = home; + ctx->my_home_id = home; ctx->loaded_keys = 0; - ctx->fsm = IDLE; + ctx->fsm = IDLE; ctx->is_keys_restored = false; s2_restore_keys(ctx, false); return ctx; } -uint8_t -S2_network_key_update(struct S2 *p_context, uint32_t key_id, security_class_t class_id, const network_key_t net_key, - uint8_t temp_key_expand, __attribute__((unused)) bool make_keys_persist_se) +uint8_t S2_network_key_update(struct S2 *p_context, + uint32_t key_id, + security_class_t class_id, + const network_key_t net_key, + uint8_t temp_key_expand, + __attribute__((unused)) bool make_keys_persist_se) { CTX_DEF - if (class_id >= N_SEC_CLASS) - { + if (class_id >= N_SEC_CLASS) { return 0; } - if (temp_key_expand) - { - tempkey_expand(key_id, net_key, ctxt->sg[class_id].enc_key, ctxt->sg[class_id].nonce_key, ctxt->sg[class_id].mpan_key); - } - else - { - networkkey_expand(key_id, net_key, ctxt->sg[class_id].enc_key, ctxt->sg[class_id].nonce_key, ctxt->sg[class_id].mpan_key); + if (temp_key_expand) { + tempkey_expand(key_id, + net_key, + ctxt->sg[class_id].enc_key, + ctxt->sg[class_id].nonce_key, + ctxt->sg[class_id].mpan_key); + } else { + networkkey_expand(key_id, + net_key, + ctxt->sg[class_id].enc_key, + ctxt->sg[class_id].nonce_key, + ctxt->sg[class_id].mpan_key); #ifdef ZWAVE_PSA_SECURE_VAULT if (make_keys_persist_se) { - uint32_t ccm_key_id = convert_keyclass_to_derived_key_id(convert_key_slot_to_keyid(class_id), ZWAVE_KEY_TYPE_SINGLE_CAST); - assert((ccm_key_id >= ZWAVE_PSA_KEY_ID_MIN) && (ccm_key_id <= ZWAVE_PSA_KEY_ID_MAX)); - zw_wrap_aes_key_secure_vault(&ccm_key_id, ctxt->sg[class_id].enc_key, ZW_PSA_ALG_CCM); - - ccm_key_id = convert_keyclass_to_derived_key_id(convert_key_slot_to_keyid(class_id), ZWAVE_KEY_TYPE_MULTI_CAST); - assert((ccm_key_id >= ZWAVE_PSA_KEY_ID_MIN) && (ccm_key_id <= ZWAVE_PSA_KEY_ID_MAX)); - zw_wrap_aes_key_secure_vault(&ccm_key_id, ctxt->sg[class_id].mpan_key, ZW_PSA_ALG_CCM); + uint32_t ccm_key_id = convert_keyclass_to_derived_key_id( + convert_key_slot_to_keyid(class_id), + ZWAVE_KEY_TYPE_SINGLE_CAST); + assert((ccm_key_id >= ZWAVE_PSA_KEY_ID_MIN) + && (ccm_key_id <= ZWAVE_PSA_KEY_ID_MAX)); + zw_wrap_aes_key_secure_vault(&ccm_key_id, + ctxt->sg[class_id].enc_key, + ZW_PSA_ALG_CCM); + + ccm_key_id = convert_keyclass_to_derived_key_id( + convert_key_slot_to_keyid(class_id), + ZWAVE_KEY_TYPE_MULTI_CAST); + assert((ccm_key_id >= ZWAVE_PSA_KEY_ID_MIN) + && (ccm_key_id <= ZWAVE_PSA_KEY_ID_MAX)); + zw_wrap_aes_key_secure_vault(&ccm_key_id, + ctxt->sg[class_id].mpan_key, + ZW_PSA_ALG_CCM); ctxt->is_keys_restored = true; } #endif /*#ifdef ZWAVE_PSA_SECURE_VAULT*/ @@ -1325,8 +1390,7 @@ S2_network_key_update(struct S2 *p_context, uint32_t key_id, security_class_t cl return 1; } -void -S2_destroy(struct S2* p_context) +void S2_destroy(struct S2 *p_context) { CTX_DEF memset(ctxt, 0, sizeof(struct S2)); @@ -1335,9 +1399,10 @@ S2_destroy(struct S2* p_context) #endif } - -void -S2_application_command_handler(struct S2* p_context, s2_connection_t* src, uint8_t* buf, uint16_t len) +void S2_application_command_handler(struct S2 *p_context, + s2_connection_t *src, + uint8_t *buf, + uint16_t len) { CTX_DEF uint8_t *plain_text; @@ -1346,180 +1411,215 @@ S2_application_command_handler(struct S2* p_context, s2_connection_t* src, uint8 event_data_t d; d.d.buf.buffer = buf; - d.d.buf.len = len; - d.con = src; - - switch (buf[1]) - { - case SECURITY_2_NONCE_GET: - if ((src->rx_options & S2_RXOPTION_MULTICAST) != S2_RXOPTION_MULTICAST - && ((len >=SECURITY_2_NONCE_GET_LENGTH) && S2_verify_seq(ctxt, src,buf[2]))) - { - S2_send_nonce_report(ctxt,src,SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK); - } - break; - case SECURITY_2_NONCE_REPORT: - S2_fsm_post_event(ctxt, GOT_NONCE_REPORT, &d); - ; - break; - case SECURITY_2_MESSAGE_ENCAPSULATION: - rc = S2_decrypt_msg(ctxt, src, buf, len, &plain_text, &plain_text_len); - if (rc == AUTH_OK) - { - S2_fsm_post_event(ctxt, GOT_ENC_MSG, &d); - if(plain_text_len) - { - S2_command_handler(ctxt, src, plain_text, plain_text_len); + d.d.buf.len = len; + d.con = src; + + switch (buf[1]) { + case SECURITY_2_NONCE_GET: + if ((src->rx_options & S2_RXOPTION_MULTICAST) != S2_RXOPTION_MULTICAST + && ((len >= SECURITY_2_NONCE_GET_LENGTH) + && S2_verify_seq(ctxt, src, buf[2]))) { + S2_send_nonce_report(ctxt, + src, + SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK); } - } - else if (rc == AUTH_FAIL) - { - S2_fsm_post_event(ctxt, GOT_BAD_ENC_MSG, &d); - s2_inclusion_decryption_failure(ctxt,src); - } - else - { - assert(rc == SEQUENCE_FAIL || rc == PARSE_FAIL); // decrypt error - } - break; - default: - /* + break; + case SECURITY_2_NONCE_REPORT: + S2_fsm_post_event(ctxt, GOT_NONCE_REPORT, &d); + ; + break; + case SECURITY_2_MESSAGE_ENCAPSULATION: + rc = S2_decrypt_msg(ctxt, src, buf, len, &plain_text, &plain_text_len); + if (rc == AUTH_OK) { + S2_fsm_post_event(ctxt, GOT_ENC_MSG, &d); + if (plain_text_len) { + S2_command_handler(ctxt, src, plain_text, plain_text_len); + } + } else if (rc == AUTH_FAIL) { + S2_fsm_post_event(ctxt, GOT_BAD_ENC_MSG, &d); + s2_inclusion_decryption_failure(ctxt, src); + } else { + assert(rc == SEQUENCE_FAIL || rc == PARSE_FAIL); // decrypt error + } + break; + default: + /* * If S2 is busy, ctxt->buf may be in use for sending an encrypted message. * KEX_FAIL is an exception. Must be passed to the inclusion fsm to abort all S2 action. */ - if((ctxt->fsm != IDLE) && (buf[1] != KEX_FAIL)) return; + if ((ctxt->fsm != IDLE) && (buf[1] != KEX_FAIL)) + return; - if ((src->rx_options & S2_RXOPTION_MULTICAST) != S2_RXOPTION_MULTICAST) - { - ctxt->buf = buf; //TODO is this a good idea? - ctxt->length = len; - src->class_id = UNENCRYPTED_CLASS; - s2_inclusion_post_event(ctxt,src); - } + if ((src->rx_options & S2_RXOPTION_MULTICAST) != S2_RXOPTION_MULTICAST) { + ctxt->buf = buf; //TODO is this a good idea? + ctxt->length = len; + src->class_id = UNENCRYPTED_CLASS; + s2_inclusion_post_event(ctxt, src); + } } - } -static void S2_command_handler(struct S2* p_context, s2_connection_t* src, uint8_t* cmd, uint16_t cmd_length) +static void S2_command_handler(struct S2 *p_context, + s2_connection_t *src, + uint8_t *cmd, + uint16_t cmd_length) { CTX_DEF uint8_t n_commands_supported; - const uint8_t* classes; + const uint8_t *classes; - if (cmd[0] == COMMAND_CLASS_SECURITY_2 && - (cmd[1] != SECURITY_2_COMMANDS_SUPPORTED_REPORT)) - { - if(src->rx_options & S2_RXOPTION_MULTICAST) - { + if (cmd[0] == COMMAND_CLASS_SECURITY_2 + && (cmd[1] != SECURITY_2_COMMANDS_SUPPORTED_REPORT)) { + if (src->rx_options & S2_RXOPTION_MULTICAST) { //S2 encrypted multi-cast frames shouln't exist. return; } - switch(cmd[1]) - { - case SECURITY_2_COMMANDS_SUPPORTED_GET_V2: + switch (cmd[1]) { + case SECURITY_2_COMMANDS_SUPPORTED_GET_V2: ctxt->u.commands_sup_report_buf[0] = COMMAND_CLASS_SECURITY_2; - ctxt->u.commands_sup_report_buf[1] = SECURITY_2_COMMANDS_SUPPORTED_REPORT; + ctxt->u.commands_sup_report_buf[1] + = SECURITY_2_COMMANDS_SUPPORTED_REPORT; - S2_get_commands_supported(src->l_node,src->class_id, &classes, &n_commands_supported); + S2_get_commands_supported(src->l_node, + src->class_id, + &classes, + &n_commands_supported); - if (n_commands_supported + 2 > sizeof(ctxt->u.commands_sup_report_buf)) - { + if (n_commands_supported + 2 + > sizeof(ctxt->u.commands_sup_report_buf)) { return; } - memcpy(&ctxt->u.commands_sup_report_buf[2], classes, n_commands_supported); + memcpy(&ctxt->u.commands_sup_report_buf[2], + classes, + n_commands_supported); /*TODO If ctxt->fsm is busy the report is not going to be sent*/ - S2_send_data(ctxt, src, ctxt->u.commands_sup_report_buf, n_commands_supported + 2); + S2_send_data(ctxt, + src, + ctxt->u.commands_sup_report_buf, + n_commands_supported + 2); break; case NLS_STATE_GET_V2: - if (cmd_length == SECURITY_2_V2_NLS_STATE_GET_LENGTH) - { + if (cmd_length == SECURITY_2_V2_NLS_STATE_GET_LENGTH) { S2_send_nls_state_report(ctxt, src); #ifdef ZW_CONTROLLER ctxt->delayed_transmission_flags.send_nls_node_list_get = 1; - ctxt->delayed_transmission_cache.get_nls_node_list.request = 0; // request first node + ctxt->delayed_transmission_cache.get_nls_node_list.request + = 0; // request first node #endif } break; case NLS_STATE_SET_V2: - if (cmd_length == SECURITY_2_V2_NLS_STATE_SET_LENGTH) - { + if (cmd_length == SECURITY_2_V2_NLS_STATE_SET_LENGTH) { ctxt->nls_state = cmd[SECURITY_2_V2_NLS_STATE_SET_STATE_POS]; S2_save_nls_state(); } break; #ifdef ZW_CONTROLLER case NLS_STATE_REPORT_V2: - if (cmd_length == SECURITY_2_V2_NLS_STATE_REPORT_LENGTH) - { - bool capability = (cmd[SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS] & SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD) ? true : false; - bool state = (cmd[SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS] & SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD) ? true : false; + if (cmd_length == SECURITY_2_V2_NLS_STATE_REPORT_LENGTH) { + bool capability = (cmd[SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS] + & SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD) + ? true + : false; + bool state = (cmd[SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS] + & SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD) + ? true + : false; if (state) { - ctxt->nls_state = 1; // There is at least one an NLS-enabled node in the network + ctxt->nls_state + = 1; // There is at least one an NLS-enabled node in the network } S2_save_nls_state(); - S2_notify_nls_state_report(src->r_node, src->class_id, capability, state); + S2_notify_nls_state_report(src->r_node, + src->class_id, + capability, + state); } break; case NLS_NODE_LIST_GET_V2: - if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH) - { - bool is_last_node = false; - uint16_t node_id = 0; + if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH) { + bool is_last_node = false; + uint16_t node_id = 0; uint8_t granted_keys = 0; - bool nls_state = false; + bool nls_state = false; uint8_t retval; - bool request = (cmd[SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS] == 1) ? true : false; - - retval = S2_get_nls_node_list(src->r_node, request, &is_last_node, &node_id, &granted_keys, &nls_state); + bool request = (cmd[SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS] == 1) + ? true + : false; + + retval = S2_get_nls_node_list(src->r_node, + request, + &is_last_node, + &node_id, + &granted_keys, + &nls_state); if (nls_state && retval == 0) { if (S2_is_send_data_busy(ctxt)) { ctxt->delayed_transmission_flags.send_nls_node_list_report = 1; - ctxt->delayed_transmission_cache.nls_node_report.is_last_node = (uint8_t)is_last_node; - ctxt->delayed_transmission_cache.nls_node_report.node_id = node_id; - ctxt->delayed_transmission_cache.nls_node_report.granted_keys = granted_keys; - ctxt->delayed_transmission_cache.nls_node_report.nls_state = (uint8_t)nls_state; + ctxt->delayed_transmission_cache.nls_node_report.is_last_node + = (uint8_t)is_last_node; + ctxt->delayed_transmission_cache.nls_node_report.node_id + = node_id; + ctxt->delayed_transmission_cache.nls_node_report.granted_keys + = granted_keys; + ctxt->delayed_transmission_cache.nls_node_report.nls_state + = (uint8_t)nls_state; } else { - S2_send_nls_node_list_report(ctxt, src, is_last_node, node_id, granted_keys, nls_state); + S2_send_nls_node_list_report(ctxt, + src, + is_last_node, + node_id, + granted_keys, + nls_state); } } } break; case NLS_NODE_LIST_REPORT_V2: - if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH) - { - bool is_last_node = (cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS] & SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_FIELD) ? true : false; - bool nls_state = (cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS] != 0) ? true : false; - - int8_t retval = S2_notify_nls_node_list_report(src->r_node, - (uint16_t)(cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS] << 8 | cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS]), - cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS], - nls_state); + if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH) { + bool is_last_node + = (cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS] + & SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_FIELD) + ? true + : false; + bool nls_state + = (cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS] != 0) + ? true + : false; + + int8_t retval = S2_notify_nls_node_list_report( + src->r_node, + (uint16_t)(cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS] + << 8 + | cmd + [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS]), + cmd[SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS], + nls_state); if (!is_last_node && retval == 0) { if (S2_is_send_data_busy(ctxt)) { ctxt->delayed_transmission_flags.send_nls_node_list_get = 1; - ctxt->delayed_transmission_cache.get_nls_node_list.request = 1; // request next node + ctxt->delayed_transmission_cache.get_nls_node_list.request + = 1; // request next node } else { S2_send_nls_node_list_get(ctxt, src, true); } } } break; -#endif // ZW_CONTROLLER +#endif // ZW_CONTROLLER default: /* Don't validate inclusion_peer.l_node as it may not be initialized yet due to early start */ - ctxt->buf = cmd; + ctxt->buf = cmd; ctxt->length = cmd_length; //Default just send the command to the inclusion fsm - s2_inclusion_post_event(ctxt,src); + s2_inclusion_post_event(ctxt, src); break; } - } - else - { + } else { #ifdef ZW_CONTROLLER /* Convert LR key classes to normal before passing out via external API */ if (IS_LR_NODE(src->r_node)) { convert_lr_to_normal_keyclass(src); @@ -1529,210 +1629,192 @@ static void S2_command_handler(struct S2* p_context, s2_connection_t* src, uint8 } } -void -S2_timeout_notify(struct S2* p_context) +void S2_timeout_notify(struct S2 *p_context) { CTX_DEF S2_fsm_post_event(ctxt, TIMEOUT, NULL); } -static void -S2_post_send_done_event(struct S2* p_context, s2_tx_status_t status) +static void S2_post_send_done_event(struct S2 *p_context, s2_tx_status_t status) { CTX_DEF - s2_inclusion_send_done(ctxt, (status == S2_TRANSMIT_COMPLETE_OK) || (status == S2_TRANSMIT_COMPLETE_VERIFIED)); + s2_inclusion_send_done(ctxt, + (status == S2_TRANSMIT_COMPLETE_OK) + || (status == S2_TRANSMIT_COMPLETE_VERIFIED)); S2_send_done_event(ctxt, status); } -static void emit_S2_synchronization_event(sos_event_reason_t reason, event_data_t* d) +static void emit_S2_synchronization_event(sos_event_reason_t reason, + event_data_t *d) { - S2_resynchronization_event(d->con->r_node, reason, d->d.buf.buffer[2], d->con->l_node); + S2_resynchronization_event(d->con->r_node, + reason, + d->d.buf.buffer[2], + d->con->l_node); } /** * Update state machine */ -void -S2_fsm_post_event(struct S2* p_context, event_t e, event_data_t* d) +void S2_fsm_post_event(struct S2 *p_context, event_t e, event_data_t *d) { CTX_DEF uint8_t nr_flag; - switch (ctxt->fsm) - { - case IS_MOS_WAIT_REPLY: - case IDLE: - //S2_set_peer(ctxt, d->con, d->buffer, d->len); - if (e == SEND_MSG && S2_span_ok(ctxt, d->con)) - { - S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); - ctxt->retry = 2; - - goto send_msg_state_enter; - } - else if (e == SEND_MSG) - { - ctxt->fsm = WAIT_NONCE_RAPORT; - ctxt->retry = 2; + switch (ctxt->fsm) { + case IS_MOS_WAIT_REPLY: + case IDLE: + //S2_set_peer(ctxt, d->con, d->buffer, d->len); + if (e == SEND_MSG && S2_span_ok(ctxt, d->con)) { + S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); + ctxt->retry = 2; - S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); - S2_send_nonce_get(ctxt); - S2_set_timeout(ctxt, SEND_DATA_TIMEOUT); - } - else if (e == GOT_NONCE_GET && (d->d.buf.len >= 3) && S2_verify_seq(ctxt, d->con, d->d.buf.buffer[2])) - { - S2_send_nonce_report(ctxt, d->con, SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK); - } - else if (e == GOT_NONCE_REPORT ) - { - S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); - S2_register_nonce(ctxt, d->d.buf.buffer, d->d.buf.len); - emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); - } - else if (e == SEND_MULTICAST) - { - S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); - //For Multicast: 8-bit group_id is stored in d->con->r_node - ctxt->mpan = find_mpan_by_group_id(ctxt, 0, (uint8_t) d->con->r_node, 1); - ctxt->fsm = SENDING_MSG; - S2_encrypt_and_send_multi(ctxt); - } - else if (e == SEND_DONE) - { - /* pass message to the inclusion FSM */ - s2_inclusion_send_done(ctxt, d->d.tx.status == S2_TRANSMIT_COMPLETE_OK); - } - else if (e == GOT_ENC_MSG_MOS) - { - S2_set_timeout(ctxt, 10); - S2_set_peer(ctxt,d->con,0,0); - ctxt->fsm = IS_MOS_WAIT_REPLY; - } - else if (e == TIMEOUT && ctxt->fsm == IS_MOS_WAIT_REPLY) - { - ctxt->mpan = 0; - ctxt->fsm = IDLE; - S2_send_nonce_report(ctxt, &ctxt->peer, SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK); - } - break; - case WAIT_NONCE_RAPORT: - if ((e == SEND_DONE) && (d->d.tx.status == S2_TRANSMIT_COMPLETE_NO_ACK)) - { - ctxt->fsm = IDLE; - S2_stop_timeout(ctxt); - S2_post_send_done_event(ctxt, d->d.tx.status); // forward status to upper layer, S2_TRANSMIT_COMPLETE_FAIL happens only on timeout - } - else if ((e == SEND_DONE) && (d->d.tx.status == S2_TRANSMIT_COMPLETE_OK)) - { - S2_set_timeout(ctxt, d->d.tx.time); //Just shorten timer but stay in this state - } - else if ((e == SEND_DONE) || (e == TIMEOUT)) - { - ctxt->fsm = IDLE; - if (e == TIMEOUT) { + goto send_msg_state_enter; + } else if (e == SEND_MSG) { + ctxt->fsm = WAIT_NONCE_RAPORT; + ctxt->retry = 2; + + S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); + S2_send_nonce_get(ctxt); + S2_set_timeout(ctxt, SEND_DATA_TIMEOUT); + } else if (e == GOT_NONCE_GET && (d->d.buf.len >= 3) + && S2_verify_seq(ctxt, d->con, d->d.buf.buffer[2])) { + S2_send_nonce_report(ctxt, + d->con, + SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK); + } else if (e == GOT_NONCE_REPORT) { + S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); + S2_register_nonce(ctxt, d->d.buf.buffer, d->d.buf.len); + emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); + } else if (e == SEND_MULTICAST) { + S2_set_peer(ctxt, d->con, d->d.buf.buffer, d->d.buf.len); + //For Multicast: 8-bit group_id is stored in d->con->r_node + ctxt->mpan = find_mpan_by_group_id(ctxt, 0, (uint8_t)d->con->r_node, 1); + ctxt->fsm = SENDING_MSG; + S2_encrypt_and_send_multi(ctxt); + } else if (e == SEND_DONE) { + /* pass message to the inclusion FSM */ + s2_inclusion_send_done(ctxt, d->d.tx.status == S2_TRANSMIT_COMPLETE_OK); + } else if (e == GOT_ENC_MSG_MOS) { + S2_set_timeout(ctxt, 10); + S2_set_peer(ctxt, d->con, 0, 0); + ctxt->fsm = IS_MOS_WAIT_REPLY; + } else if (e == TIMEOUT && ctxt->fsm == IS_MOS_WAIT_REPLY) { + ctxt->mpan = 0; + ctxt->fsm = IDLE; + S2_send_nonce_report(ctxt, + &ctxt->peer, + SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK); + } + break; + case WAIT_NONCE_RAPORT: + if ((e == SEND_DONE) && (d->d.tx.status == S2_TRANSMIT_COMPLETE_NO_ACK)) { + ctxt->fsm = IDLE; + S2_stop_timeout(ctxt); + S2_post_send_done_event( + ctxt, + d->d.tx + .status); // forward status to upper layer, S2_TRANSMIT_COMPLETE_FAIL happens only on timeout + } else if ((e == SEND_DONE) + && (d->d.tx.status == S2_TRANSMIT_COMPLETE_OK)) { + S2_set_timeout( + ctxt, + d->d.tx.time); //Just shorten timer but stay in this state + } else if ((e == SEND_DONE) || (e == TIMEOUT)) { + ctxt->fsm = IDLE; + if (e == TIMEOUT) { S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_FAIL); - } else { + } else { S2_post_send_done_event(ctxt, d->d.tx.status); + } + } else if ((e == GOT_NONCE_REPORT) && S2_is_peernode(ctxt, d->con)) { + if (S2_register_nonce(ctxt, d->d.buf.buffer, d->d.buf.len) + & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK) { + goto send_msg_state_enter; + } + } else if ((e == GOT_NONCE_REPORT) && !S2_is_peernode(ctxt, d->con)) { + emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); } - } - else if ((e == GOT_NONCE_REPORT) && S2_is_peernode(ctxt, d->con)) - { - if (S2_register_nonce(ctxt, d->d.buf.buffer, d->d.buf.len) & SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK) - { - goto send_msg_state_enter; - } - } - else if ((e == GOT_NONCE_REPORT) && !S2_is_peernode(ctxt, d->con)) - { - emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); - } - break; - case SENDING_MSG: - if (e == SEND_DONE) - { - ctxt->fsm = IDLE; - S2_post_send_done_event(ctxt, d->d.tx.status); + break; + case SENDING_MSG: + if (e == SEND_DONE) { + ctxt->fsm = IDLE; + S2_post_send_done_event(ctxt, d->d.tx.status); #ifdef ZW_CONTROLLER - if (ctxt->delayed_transmission_flags.send_nls_node_list_get && ctxt->nls_state) - { - ctxt->delayed_transmission_flags.send_nls_node_list_get = 0; + if (ctxt->delayed_transmission_flags.send_nls_node_list_get + && ctxt->nls_state) { + ctxt->delayed_transmission_flags.send_nls_node_list_get = 0; - uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH] = { 0 }; + uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH] = {0}; - S2_prepare_nls_node_list_get( - buf, - ctxt->delayed_transmission_cache.get_nls_node_list.request); + S2_prepare_nls_node_list_get( + buf, + ctxt->delayed_transmission_cache.get_nls_node_list.request); - ctxt->buf = buf; - ctxt->length = sizeof(buf); + ctxt->buf = buf; + ctxt->length = sizeof(buf); - // Clear cache - ctxt->delayed_transmission_cache.get_nls_node_list.request = 0; + // Clear cache + ctxt->delayed_transmission_cache.get_nls_node_list.request = 0; - goto send_msg_state_enter; - } + goto send_msg_state_enter; + } - if (ctxt->delayed_transmission_flags.send_nls_node_list_report && ctxt->nls_state) - { - ctxt->delayed_transmission_flags.send_nls_node_list_report = 0; + if (ctxt->delayed_transmission_flags.send_nls_node_list_report + && ctxt->nls_state) { + ctxt->delayed_transmission_flags.send_nls_node_list_report = 0; - uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH] = { 0 }; + uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH] = {0}; - S2_prepare_nls_node_list_report( - buf, - ctxt->delayed_transmission_cache.nls_node_report.is_last_node, - ctxt->delayed_transmission_cache.nls_node_report.node_id, - ctxt->delayed_transmission_cache.nls_node_report.granted_keys, - ctxt->delayed_transmission_cache.nls_node_report.nls_state); + S2_prepare_nls_node_list_report( + buf, + ctxt->delayed_transmission_cache.nls_node_report.is_last_node, + ctxt->delayed_transmission_cache.nls_node_report.node_id, + ctxt->delayed_transmission_cache.nls_node_report.granted_keys, + ctxt->delayed_transmission_cache.nls_node_report.nls_state); - ctxt->buf = buf; - ctxt->length = sizeof(buf); + ctxt->buf = buf; + ctxt->length = sizeof(buf); - // Clear cache - ctxt->delayed_transmission_cache.nls_node_report.is_last_node = 0; - ctxt->delayed_transmission_cache.nls_node_report.node_id = 0; - ctxt->delayed_transmission_cache.nls_node_report.granted_keys = 0; - ctxt->delayed_transmission_cache.nls_node_report.nls_state = 0; + // Clear cache + ctxt->delayed_transmission_cache.nls_node_report.is_last_node = 0; + ctxt->delayed_transmission_cache.nls_node_report.node_id = 0; + ctxt->delayed_transmission_cache.nls_node_report.granted_keys = 0; + ctxt->delayed_transmission_cache.nls_node_report.nls_state = 0; - goto send_msg_state_enter; - } + goto send_msg_state_enter; + } #endif - } - else if (e == GOT_NONCE_REPORT && !S2_is_peernode(ctxt, d->con)) - { - emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); - } - // else: Unexpected event while in state SENDING_MSG - break; - case VERIFYING_DELIVERY: - if (e == SEND_DONE) - { /* shorten timer on ACK */ - if (d->d.tx.status == S2_TRANSMIT_COMPLETE_OK) - { - S2_set_timeout(ctxt, d->d.tx.time); //Just shorten timer but stay in this state - } - else - { /* bail out */ - ctxt->fsm = IDLE; - S2_post_send_done_event(ctxt, d->d.tx.status); + } else if (e == GOT_NONCE_REPORT && !S2_is_peernode(ctxt, d->con)) { + emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); } - } - else if (e == GOT_ENC_MSG && S2_is_peernode(ctxt, d->con)) - { - if(S2_is_node_mos(ctxt,d->con->r_node) && (ctxt->retry > 0)) { - ctxt->length = 0; - ctxt->peer.tx_options &= ~S2_TXOPTION_VERIFY_DELIVERY; - goto send_msg_state_enter; - } else { - ctxt->fsm = IDLE; - /* Stop S2 timer when we have verified delivery so ZW protocol can go back to sleep */ - S2_stop_timeout(ctxt); - S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_VERIFIED); + // else: Unexpected event while in state SENDING_MSG + break; + case VERIFYING_DELIVERY: + if (e == SEND_DONE) { /* shorten timer on ACK */ + if (d->d.tx.status == S2_TRANSMIT_COMPLETE_OK) { + S2_set_timeout( + ctxt, + d->d.tx.time); //Just shorten timer but stay in this state + } else { /* bail out */ + ctxt->fsm = IDLE; + S2_post_send_done_event(ctxt, d->d.tx.status); + } + } else if (e == GOT_ENC_MSG && S2_is_peernode(ctxt, d->con)) { + if (S2_is_node_mos(ctxt, d->con->r_node) && (ctxt->retry > 0)) { + ctxt->length = 0; + ctxt->peer.tx_options &= ~S2_TXOPTION_VERIFY_DELIVERY; + goto send_msg_state_enter; + } else { + ctxt->fsm = IDLE; + /* Stop S2 timer when we have verified delivery so ZW protocol can go back to sleep */ + S2_stop_timeout(ctxt); + S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_VERIFIED); + } } - } - /* + /* * As we know there will a nonce report under way, it is better to * wait for the NONCE_REPORT for the sake of keeping synchronization. * @@ -1741,53 +1823,43 @@ S2_fsm_post_event(struct S2* p_context, event_t e, event_data_t* d) ctxt->fsm = IDLE; //No more retries S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_FAIL); }*/ - else if (e == TIMEOUT) - { - ctxt->fsm = IDLE; //The frame seems to be handled but we don't know for sure - S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_OK); - } - else if (e == GOT_NONCE_REPORT && S2_is_peernode(ctxt, d->con)) - { - nr_flag = S2_register_nonce(ctxt, d->d.buf.buffer, d->d.buf.len); - if (nr_flag == 0) - { - return; - } - else if (nr_flag == SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK) - { - /* if we only get a MOS flag back, set the payload length to 0, + else if (e == TIMEOUT) { + ctxt->fsm + = IDLE; //The frame seems to be handled but we don't know for sure + S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_OK); + } else if (e == GOT_NONCE_REPORT && S2_is_peernode(ctxt, d->con)) { + nr_flag = S2_register_nonce(ctxt, d->d.buf.buffer, d->d.buf.len); + if (nr_flag == 0) { + return; + } else if (nr_flag + == SECURITY_2_NONCE_REPORT_PROPERTIES1_MOS_BIT_MASK) { + /* if we only get a MOS flag back, set the payload length to 0, * as we don't need to retransmit the payload, we should only * send the MPAN*/ - ctxt->length = 0; - } + ctxt->length = 0; + } - if (ctxt->retry == 0) - { - ctxt->fsm = IDLE; //No more retries - S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_FAIL); - } - else - { - goto send_msg_state_enter; - // send again + if (ctxt->retry == 0) { + ctxt->fsm = IDLE; //No more retries + S2_post_send_done_event(ctxt, S2_TRANSMIT_COMPLETE_FAIL); + } else { + goto send_msg_state_enter; + // send again + } + } else if (e == GOT_NONCE_REPORT && !S2_is_peernode(ctxt, d->con)) { + emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); } - } - else if (e == GOT_NONCE_REPORT && !S2_is_peernode(ctxt, d->con)) - { - emit_S2_synchronization_event(SOS_EVENT_REASON_UNANSWERED, d); - } - // else: Unexpected event while in state VERIFYING_DELIVERY - break; - default: - assert(0); + // else: Unexpected event while in state VERIFYING_DELIVERY + break; + default: + assert(0); } return; send_msg_state_enter: ctxt->fsm = SENDING_MSG; - if (ctxt->peer.tx_options & S2_TXOPTION_VERIFY_DELIVERY) - { + if (ctxt->peer.tx_options & S2_TXOPTION_VERIFY_DELIVERY) { ctxt->fsm = VERIFYING_DELIVERY; S2_set_timeout(ctxt, SEND_DATA_TIMEOUT); } @@ -1795,12 +1867,13 @@ S2_fsm_post_event(struct S2* p_context, event_t e, event_data_t* d) S2_encrypt_and_send(ctxt); ctxt->retry--; - return; } -uint8_t -S2_send_data_multicast(struct S2* p_context, const s2_connection_t* con, const uint8_t* buf, uint16_t len) +uint8_t S2_send_data_multicast(struct S2 *p_context, + const s2_connection_t *con, + const uint8_t *buf, + uint16_t len) { CTX_DEF // No key conversion here, because we get a Group ID and we cannot know @@ -1809,11 +1882,11 @@ S2_send_data_multicast(struct S2* p_context, const s2_connection_t* con, const u } uint8_t -S2_send_data_singlecast_follow_up_with_keyset(struct S2* ctxt, - s2_connection_t* connection, - zwave_s2_keyset_t keyset, - const uint8_t* payload, - uint16_t payload_length) + S2_send_data_singlecast_follow_up_with_keyset(struct S2 *ctxt, + s2_connection_t *connection, + zwave_s2_keyset_t keyset, + const uint8_t *payload, + uint16_t payload_length) { if (keyset == ZWAVE_KEYSET) { return S2_send_data_all_cast(ctxt, @@ -1835,10 +1908,10 @@ S2_send_data_singlecast_follow_up_with_keyset(struct S2* ctxt, return 0; } -uint8_t S2_send_data_multicast_with_keyset(struct S2* ctxt, - s2_connection_t* connection, +uint8_t S2_send_data_multicast_with_keyset(struct S2 *ctxt, + s2_connection_t *connection, zwave_s2_keyset_t keyset, - const uint8_t* payload, + const uint8_t *payload, uint16_t payload_length) { if (keyset == ZWAVE_KEYSET) { @@ -1861,10 +1934,10 @@ uint8_t S2_send_data_multicast_with_keyset(struct S2* ctxt, return 0; } -uint8_t S2_send_data_singlecast_with_keyset(struct S2* ctxt, - s2_connection_t* connection, +uint8_t S2_send_data_singlecast_with_keyset(struct S2 *ctxt, + s2_connection_t *connection, zwave_s2_keyset_t keyset, - const uint8_t* payload, + const uint8_t *payload, uint16_t payload_length) { if (keyset == ZWAVE_KEYSET) { @@ -1887,7 +1960,6 @@ uint8_t S2_send_data_singlecast_with_keyset(struct S2* ctxt, return 0; } - /* * Converts the class_id of a s2_connection_t object for a * ZWAVE_KEYSET to ZWAVE_LONG_RANGE_KEYSET @@ -1898,9 +1970,9 @@ uint8_t S2_send_data_singlecast_with_keyset(struct S2* ctxt, */ static void convert_normal_to_lr_keyclass(s2_connection_t *con) { - if(con->class_id == ACCESS_KEY_SLOT) { + if (con->class_id == ACCESS_KEY_SLOT) { con->class_id = LR_ACCESS_KEY_SLOT; - } else if(con->class_id == AUTHENTICATED_KEY_SLOT) { + } else if (con->class_id == AUTHENTICATED_KEY_SLOT) { con->class_id = LR_AUTHENTICATED_KEY_SLOT; } // Ideally if we ask an impossible conversion @@ -1908,7 +1980,6 @@ static void convert_normal_to_lr_keyclass(s2_connection_t *con) // we should fall back on an invalid class_id. } - /* * Converts the class_id of a s2_connection_t object for a * ZWAVE_LONG_RANGE_KEYSET keyset to a ZWAVE_KEYSET. @@ -1917,9 +1988,9 @@ static void convert_normal_to_lr_keyclass(s2_connection_t *con) */ static void convert_lr_to_normal_keyclass(s2_connection_t *con) { - if(con->class_id == LR_ACCESS_KEY_SLOT) { + if (con->class_id == LR_ACCESS_KEY_SLOT) { con->class_id = ACCESS_KEY_SLOT; - } else if(con->class_id == LR_AUTHENTICATED_KEY_SLOT) { + } else if (con->class_id == LR_AUTHENTICATED_KEY_SLOT) { con->class_id = AUTHENTICATED_KEY_SLOT; } // Ideally if we ask an impossible conversion @@ -1927,20 +1998,23 @@ static void convert_lr_to_normal_keyclass(s2_connection_t *con) // we should fall back on an invalid class_id. } -static uint8_t -S2_send_data_all_cast(struct S2* p_context, const s2_connection_t* con, const uint8_t* buf, uint16_t len, event_t ev) +static uint8_t S2_send_data_all_cast(struct S2 *p_context, + const s2_connection_t *con, + const uint8_t *buf, + uint16_t len, + event_t ev) { CTX_DEF event_data_t e; - if (len == 0 || len > WORKBUF_SIZE || buf == 0 || S2_is_send_data_busy(ctxt)) - { + if (len == 0 || len > WORKBUF_SIZE || buf == 0 + || S2_is_send_data_busy(ctxt)) { return 0; } e.d.buf.buffer = buf; - e.d.buf.len = len; - e.con = con; + e.d.buf.len = len; + e.con = con; if (ev == SEND_MULTICAST) { S2_fsm_post_event(ctxt, SEND_MULTICAST, &e); @@ -1951,7 +2025,8 @@ S2_send_data_all_cast(struct S2* p_context, const s2_connection_t* con, const ui } else if (ev == SEND_FOLLOW_UP) { // Here the user has selected a MGRP Group ID for sending. // Make a context MPAN switch, if we can find it - struct MPAN *new_mpan = find_mpan_by_group_id(ctxt, 0, con->mgrp_group_id, 0); + struct MPAN *new_mpan + = find_mpan_by_group_id(ctxt, 0, con->mgrp_group_id, 0); if (new_mpan) { ctxt->mpan = new_mpan; } @@ -1962,28 +2037,31 @@ S2_send_data_all_cast(struct S2* p_context, const s2_connection_t* con, const ui return 1; } -uint8_t -S2_is_send_data_multicast_busy(struct S2* p_context) +uint8_t S2_is_send_data_multicast_busy(struct S2 *p_context) { CTX_DEF return ctxt->fsm != IDLE; } -void S2_load_nls_state(struct S2* p_context, uint8_t nls_state) +void S2_load_nls_state(struct S2 *p_context, uint8_t nls_state) { CTX_DEF ctxt->nls_state = nls_state; } -static void S2_send_nls_state_report(struct S2* p_context, s2_connection_t* con) +static void S2_send_nls_state_report(struct S2 *p_context, s2_connection_t *con) { CTX_DEF - uint8_t plain_text[SECURITY_2_V2_NLS_STATE_REPORT_LENGTH] = { 0 }; + uint8_t plain_text[SECURITY_2_V2_NLS_STATE_REPORT_LENGTH] = {0}; uint8_t nls_bitfield; - nls_bitfield = SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD | (ctxt->nls_state ? SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD : 0); // A node sending this frame will always support NLS - plain_text[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; - plain_text[SECURITY_2_COMMAND_POS] = NLS_STATE_REPORT_V2; + nls_bitfield + = SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD + | (ctxt->nls_state + ? SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD + : 0); // A node sending this frame will always support NLS + plain_text[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; + plain_text[SECURITY_2_COMMAND_POS] = NLS_STATE_REPORT_V2; plain_text[SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS] = nls_bitfield; S2_send_data(ctxt, con, plain_text, SECURITY_2_V2_NLS_STATE_REPORT_LENGTH); @@ -1991,65 +2069,84 @@ static void S2_send_nls_state_report(struct S2* p_context, s2_connection_t* con) #ifdef ZW_CONTROLLER -static void S2_send_nls_state_set(struct S2* p_context, s2_connection_t* con, bool nls_active) +static void S2_send_nls_state_set(struct S2 *p_context, + s2_connection_t *con, + bool nls_active) { CTX_DEF - uint8_t plain_text[SECURITY_2_V2_NLS_STATE_SET_LENGTH] = { 0 }; - plain_text[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; - plain_text[SECURITY_2_COMMAND_POS] = NLS_STATE_SET_V2; - plain_text[SECURITY_2_V2_NLS_STATE_SET_STATE_POS] = nls_active; + uint8_t plain_text[SECURITY_2_V2_NLS_STATE_SET_LENGTH] = {0}; + plain_text[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; + plain_text[SECURITY_2_COMMAND_POS] = NLS_STATE_SET_V2; + plain_text[SECURITY_2_V2_NLS_STATE_SET_STATE_POS] = nls_active; S2_send_data(ctxt, con, plain_text, SECURITY_2_V2_NLS_STATE_SET_LENGTH); } -static void S2_send_nls_state_get(struct S2* p_context, s2_connection_t* con) +static void S2_send_nls_state_get(struct S2 *p_context, s2_connection_t *con) { CTX_DEF - uint8_t plain_text[SECURITY_2_V2_NLS_STATE_GET_LENGTH] = { 0 }; - plain_text[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; - plain_text[SECURITY_2_COMMAND_POS] = NLS_STATE_GET_V2; + uint8_t plain_text[SECURITY_2_V2_NLS_STATE_GET_LENGTH] = {0}; + plain_text[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; + plain_text[SECURITY_2_COMMAND_POS] = NLS_STATE_GET_V2; S2_send_data(ctxt, con, plain_text, SECURITY_2_V2_NLS_STATE_GET_LENGTH); } static void S2_prepare_nls_node_list_get(uint8_t *buf, bool request) { - buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; - buf[SECURITY_2_COMMAND_POS] = NLS_NODE_LIST_GET_V2; + buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; + buf[SECURITY_2_COMMAND_POS] = NLS_NODE_LIST_GET_V2; buf[SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS] = (uint8_t)request; } -static void S2_send_nls_node_list_get(struct S2* p_context, s2_connection_t* con, bool request) +static void S2_send_nls_node_list_get(struct S2 *p_context, + s2_connection_t *con, + bool request) { CTX_DEF - uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH] = { 0 }; + uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH] = {0}; S2_prepare_nls_node_list_get(buf, request); S2_send_data(ctxt, con, buf, SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH); } -static void S2_prepare_nls_node_list_report(uint8_t *buf, bool is_last_node, uint16_t node_id, uint8_t granted_keys, uint8_t nls_state) +static void S2_prepare_nls_node_list_report(uint8_t *buf, + bool is_last_node, + uint16_t node_id, + uint8_t granted_keys, + uint8_t nls_state) { - buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; - buf[SECURITY_2_COMMAND_POS] = NLS_NODE_LIST_REPORT_V2; - buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS] = (uint8_t)is_last_node; - buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS] = (node_id >> 8) & 0xFF; - buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS] = (node_id >> 0) & 0xFF; + buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2_V2; + buf[SECURITY_2_COMMAND_POS] = NLS_NODE_LIST_REPORT_V2; + buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS] = (uint8_t)is_last_node; + buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS] + = (node_id >> 8) & 0xFF; + buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS] + = (node_id >> 0) & 0xFF; buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS] = granted_keys; buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS] = nls_state; } -static void S2_send_nls_node_list_report(struct S2* p_context, s2_connection_t* con, bool is_last_node, uint16_t node_id, uint8_t granted_keys, uint8_t nls_state) +static void S2_send_nls_node_list_report(struct S2 *p_context, + s2_connection_t *con, + bool is_last_node, + uint16_t node_id, + uint8_t granted_keys, + uint8_t nls_state) { CTX_DEF - uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH] = { 0 }; + uint8_t buf[SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH] = {0}; - S2_prepare_nls_node_list_report(buf, is_last_node, node_id, granted_keys, nls_state); + S2_prepare_nls_node_list_report(buf, + is_last_node, + node_id, + granted_keys, + nls_state); S2_send_data(ctxt, con, buf, SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH); } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/aes_test.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/aes_test.c index 34891cbab..23baddc1c 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/aes_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/aes_test.c @@ -11,7 +11,7 @@ #include "aes.h" -static void phex(uint8_t* str); +static void phex(uint8_t *str); /* int main(void) @@ -27,72 +27,136 @@ int main(void) */ // prints string as hex -static void phex(uint8_t* str) +static void phex(uint8_t *str) { - unsigned char i; - for(i = 0; i < 16; ++i) - printf("%.2x", str[i]); - printf("\n"); + unsigned char i; + for (i = 0; i < 16; ++i) + printf("%.2x", str[i]); + printf("\n"); } void test_encrypt_ecb_verbose(void) { - // Example of more verbose verification - - uint8_t i, buf[64], buf2[64]; - - // 128bit key - uint8_t key[16] = { (uint8_t) 0x2b, (uint8_t) 0x7e, (uint8_t) 0x15, (uint8_t) 0x16, (uint8_t) 0x28, (uint8_t) 0xae, (uint8_t) 0xd2, (uint8_t) 0xa6, (uint8_t) 0xab, (uint8_t) 0xf7, (uint8_t) 0x15, (uint8_t) 0x88, (uint8_t) 0x09, (uint8_t) 0xcf, (uint8_t) 0x4f, (uint8_t) 0x3c }; - // 512bit text - uint8_t plain_text[64] = { (uint8_t) 0x6b, (uint8_t) 0xc1, (uint8_t) 0xbe, (uint8_t) 0xe2, (uint8_t) 0x2e, (uint8_t) 0x40, (uint8_t) 0x9f, (uint8_t) 0x96, (uint8_t) 0xe9, (uint8_t) 0x3d, (uint8_t) 0x7e, (uint8_t) 0x11, (uint8_t) 0x73, (uint8_t) 0x93, (uint8_t) 0x17, (uint8_t) 0x2a, - (uint8_t) 0xae, (uint8_t) 0x2d, (uint8_t) 0x8a, (uint8_t) 0x57, (uint8_t) 0x1e, (uint8_t) 0x03, (uint8_t) 0xac, (uint8_t) 0x9c, (uint8_t) 0x9e, (uint8_t) 0xb7, (uint8_t) 0x6f, (uint8_t) 0xac, (uint8_t) 0x45, (uint8_t) 0xaf, (uint8_t) 0x8e, (uint8_t) 0x51, - (uint8_t) 0x30, (uint8_t) 0xc8, (uint8_t) 0x1c, (uint8_t) 0x46, (uint8_t) 0xa3, (uint8_t) 0x5c, (uint8_t) 0xe4, (uint8_t) 0x11, (uint8_t) 0xe5, (uint8_t) 0xfb, (uint8_t) 0xc1, (uint8_t) 0x19, (uint8_t) 0x1a, (uint8_t) 0x0a, (uint8_t) 0x52, (uint8_t) 0xef, - (uint8_t) 0xf6, (uint8_t) 0x9f, (uint8_t) 0x24, (uint8_t) 0x45, (uint8_t) 0xdf, (uint8_t) 0x4f, (uint8_t) 0x9b, (uint8_t) 0x17, (uint8_t) 0xad, (uint8_t) 0x2b, (uint8_t) 0x41, (uint8_t) 0x7b, (uint8_t) 0xe6, (uint8_t) 0x6c, (uint8_t) 0x37, (uint8_t) 0x10 }; - - memset(buf, 0, 64); - memset(buf2, 0, 64); - - // print text to encrypt, key and IV - printf("ECB encrypt verbose:\n\n"); - printf("plain text:\n"); - for(i = (uint8_t) 0; i < (uint8_t) 4; ++i) - { - phex(plain_text + i * (uint8_t) 16); - } - printf("\n"); - - printf("key:\n"); - phex(key); - printf("\n"); - - // print the resulting cipher as 4 x 16 byte strings - printf("ciphertext:\n"); - for(i = 0; i < 4; ++i) - { - AES128_ECB_encrypt(plain_text + (i*16), key, buf+(i*16)); - phex(buf + (i*16)); - } - printf("\n"); -} + // Example of more verbose verification + + uint8_t i, buf[64], buf2[64]; + + // 128bit key + uint8_t key[16] = {(uint8_t)0x2b, + (uint8_t)0x7e, + (uint8_t)0x15, + (uint8_t)0x16, + (uint8_t)0x28, + (uint8_t)0xae, + (uint8_t)0xd2, + (uint8_t)0xa6, + (uint8_t)0xab, + (uint8_t)0xf7, + (uint8_t)0x15, + (uint8_t)0x88, + (uint8_t)0x09, + (uint8_t)0xcf, + (uint8_t)0x4f, + (uint8_t)0x3c}; + // 512bit text + uint8_t plain_text[64] = { + (uint8_t)0x6b, (uint8_t)0xc1, (uint8_t)0xbe, (uint8_t)0xe2, (uint8_t)0x2e, + (uint8_t)0x40, (uint8_t)0x9f, (uint8_t)0x96, (uint8_t)0xe9, (uint8_t)0x3d, + (uint8_t)0x7e, (uint8_t)0x11, (uint8_t)0x73, (uint8_t)0x93, (uint8_t)0x17, + (uint8_t)0x2a, (uint8_t)0xae, (uint8_t)0x2d, (uint8_t)0x8a, (uint8_t)0x57, + (uint8_t)0x1e, (uint8_t)0x03, (uint8_t)0xac, (uint8_t)0x9c, (uint8_t)0x9e, + (uint8_t)0xb7, (uint8_t)0x6f, (uint8_t)0xac, (uint8_t)0x45, (uint8_t)0xaf, + (uint8_t)0x8e, (uint8_t)0x51, (uint8_t)0x30, (uint8_t)0xc8, (uint8_t)0x1c, + (uint8_t)0x46, (uint8_t)0xa3, (uint8_t)0x5c, (uint8_t)0xe4, (uint8_t)0x11, + (uint8_t)0xe5, (uint8_t)0xfb, (uint8_t)0xc1, (uint8_t)0x19, (uint8_t)0x1a, + (uint8_t)0x0a, (uint8_t)0x52, (uint8_t)0xef, (uint8_t)0xf6, (uint8_t)0x9f, + (uint8_t)0x24, (uint8_t)0x45, (uint8_t)0xdf, (uint8_t)0x4f, (uint8_t)0x9b, + (uint8_t)0x17, (uint8_t)0xad, (uint8_t)0x2b, (uint8_t)0x41, (uint8_t)0x7b, + (uint8_t)0xe6, (uint8_t)0x6c, (uint8_t)0x37, (uint8_t)0x10}; + + memset(buf, 0, 64); + memset(buf2, 0, 64); + + // print text to encrypt, key and IV + printf("ECB encrypt verbose:\n\n"); + printf("plain text:\n"); + for (i = (uint8_t)0; i < (uint8_t)4; ++i) { + phex(plain_text + i * (uint8_t)16); + } + printf("\n"); + + printf("key:\n"); + phex(key); + printf("\n"); + // print the resulting cipher as 4 x 16 byte strings + printf("ciphertext:\n"); + for (i = 0; i < 4; ++i) { + AES128_ECB_encrypt(plain_text + (i * 16), key, buf + (i * 16)); + phex(buf + (i * 16)); + } + printf("\n"); +} void test_encrypt_ecb(void) { - uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; - uint8_t in[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; - uint8_t out[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97}; + uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; + uint8_t in[] = {0x6b, + 0xc1, + 0xbe, + 0xe2, + 0x2e, + 0x40, + 0x9f, + 0x96, + 0xe9, + 0x3d, + 0x7e, + 0x11, + 0x73, + 0x93, + 0x17, + 0x2a}; + uint8_t out[] = {0x3a, + 0xd7, + 0x7b, + 0xb4, + 0x0d, + 0x7a, + 0x36, + 0x60, + 0xa8, + 0x9e, + 0xca, + 0xf3, + 0x24, + 0x66, + 0xef, + 0x97}; uint8_t buffer[16]; AES128_ECB_encrypt(in, key, buffer); printf("ECB decrypt: "); - if(0 == strncmp((char*) out, (char*) buffer, 16)) - { + if (0 == strncmp((char *)out, (char *)buffer, 16)) { printf("SUCCESS!\n"); - } - else - { + } else { printf("FAILURE!\n"); } } @@ -101,83 +165,188 @@ void test_decrypt_cbc(void) { // Example "simulating" a smaller buffer... - uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; - uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - uint8_t in[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, - 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, - 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, - 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 }; - uint8_t out[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }; + uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; + uint8_t iv[] = {0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f}; + uint8_t in[] + = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, + 0x9b, 0x12, 0xe9, 0x19, 0x7d, 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, + 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, 0x73, + 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, + 0x22, 0x22, 0x95, 0x16, 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, + 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7}; + uint8_t out[] + = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; uint8_t buffer[64]; - AES128_CBC_decrypt_buffer(buffer+0, in+0, 16, key, iv); - AES128_CBC_decrypt_buffer(buffer+16, in+16, 16, 0, 0); - AES128_CBC_decrypt_buffer(buffer+32, in+32, 16, 0, 0); - AES128_CBC_decrypt_buffer(buffer+48, in+48, 16, 0, 0); + AES128_CBC_decrypt_buffer(buffer + 0, in + 0, 16, key, iv); + AES128_CBC_decrypt_buffer(buffer + 16, in + 16, 16, 0, 0); + AES128_CBC_decrypt_buffer(buffer + 32, in + 32, 16, 0, 0); + AES128_CBC_decrypt_buffer(buffer + 48, in + 48, 16, 0, 0); printf("CBC decrypt: "); - if(0 == strncmp((char*) out, (char*) buffer, 64)) - { + if (0 == strncmp((char *)out, (char *)buffer, 64)) { printf("SUCCESS!\n"); - } - else - { + } else { printf("FAILURE!\n"); } } void test_encrypt_cbc(void) { - uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; - uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - uint8_t in[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }; - uint8_t out[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, - 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, - 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, - 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 }; + uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; + uint8_t iv[] = {0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f}; + uint8_t in[] + = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; + uint8_t out[] + = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, + 0x9b, 0x12, 0xe9, 0x19, 0x7d, 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, + 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, 0x73, + 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, + 0x22, 0x22, 0x95, 0x16, 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, + 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7}; uint8_t buffer[64]; AES128_CBC_encrypt_buffer(buffer, in, 64, key, iv); printf("CBC encrypt: "); - if(0 == strncmp((char*) out, (char*) buffer, 64)) - { + if (0 == strncmp((char *)out, (char *)buffer, 64)) { printf("SUCCESS!\n"); - } - else - { + } else { printf("FAILURE!\n"); } } - void test_decrypt_ecb(void) { - uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; - uint8_t in[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97}; - uint8_t out[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; + uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; + uint8_t in[] = {0x3a, + 0xd7, + 0x7b, + 0xb4, + 0x0d, + 0x7a, + 0x36, + 0x60, + 0xa8, + 0x9e, + 0xca, + 0xf3, + 0x24, + 0x66, + 0xef, + 0x97}; + uint8_t out[] = {0x6b, + 0xc1, + 0xbe, + 0xe2, + 0x2e, + 0x40, + 0x9f, + 0x96, + 0xe9, + 0x3d, + 0x7e, + 0x11, + 0x73, + 0x93, + 0x17, + 0x2a}; uint8_t buffer[16]; AES128_ECB_decrypt(in, key, buffer); printf("ECB decrypt: "); - if(0 == strncmp((char*) out, (char*) buffer, 16)) - { + if (0 == strncmp((char *)out, (char *)buffer, 16)) { printf("SUCCESS!\n"); - } - else - { + } else { printf("FAILURE!\n"); } } - - diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/clock_time.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/clock_time.c index e582e0d04..69ff0f7b1 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/clock_time.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/clock_time.c @@ -2,15 +2,15 @@ * @file clock_time.c * @copyright 2022 Silicon Laboratories Inc. */ -#include - +#include + /** * Makes a fake System time available to LibS2. -*/ -uint32_t clock_time(void) -{ - static uint16_t iTime; - - iTime++; - return iTime; -} +*/ +uint32_t clock_time(void) +{ + static uint16_t iTime; + + iTime++; + return iTime; +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/new_test_t2.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/new_test_t2.c index d2511f5f3..e15d0a848 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/new_test_t2.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/new_test_t2.c @@ -1,179 +1,393 @@ /* © 2017 Silicon Laboratories Inc. */ #include -#include /* For s2_tx_status_t */ +#include /* For s2_tx_status_t */ #include ts_param_t p; //#define DEBUG #ifdef DEBUG -#define v_printf(format, args...) printf(format, ## args); +#define v_printf(format, args...) printf(format, ##args); #else #define v_printf(format, args...) #endif -#define fail_if_nonzero(ret) if (ret) \ - goto fail; +#define fail_if_nonzero(ret) \ + if (ret) \ + goto fail; // This is the complete datagagram (payload of fragments 1, 2 & 3) -unsigned char test_complete_datagram[] = -{ +unsigned char test_complete_datagram[] = { // frag1 - 0x20, 0x01, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x20, + 0x01, + 0x00, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, // frag2 - 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x20, 0x01, - 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, - 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x20, + 0x01, + 0x00, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, // frag3 - 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0x34, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, }; -unsigned char test_first_frag1[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xc0, // COMMAND_FIRST_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) - 0x6a, // datagram_size_2 (size bits 7..0 = 106) - 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), Reserved[2..0] - +unsigned char test_first_frag1[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xc0, // COMMAND_FIRST_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) + 0x6a, // datagram_size_2 (size bits 7..0 = 106) + 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), Reserved[2..0] + // ----- Payload from here (first 47 bytes) - 0x20, 0x01, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, - // ----- Payload to here + 0x20, + 0x01, + 0x00, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + // ----- Payload to here // Last two bytes are CRC-16-CCITT // (can be calculated with https://crccalc.com/ for test purposes // - use the "CRC-16/AUG-CCITT" value) - 0x04, 0xa5 -}; + 0x04, + 0xa5}; + +unsigned char test_subseq_frag2[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) + 0x6a, // datagram_size_2 (size bits 7..0 = 106) + 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) + 0x2f, // datagram_offset_2 (size bits 7..0 = 47) -unsigned char test_subseq_frag2[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) - 0x6a, // datagram_size_2 (size bits 7..0 = 106) - 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) - 0x2f, // datagram_offset_2 (size bits 7..0 = 47) - // ----- Payload from here (next 47 bytes) - 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x20, 0x01, - 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, - 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - // ----- Payload to here - + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x20, + 0x01, + 0x00, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + // ----- Payload to here + // Last two bytes are CRC-16-CCITT - 0x1d, 0x69 -}; + 0x1d, + 0x69}; // test_subseq_frag2a and 2b are test_subseq_frag2 split into two different-sized fragments -unsigned char test_subseq_frag2a[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) - 0x6a, // datagram_size_2 (size bits 7..0 = 106) - 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) - 0x2f, // datagram_offset_2 (size bits 7..0 = 47) - +unsigned char test_subseq_frag2a[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) + 0x6a, // datagram_size_2 (size bits 7..0 = 106) + 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) + 0x2f, // datagram_offset_2 (size bits 7..0 = 47) + // ----- Payload from here (next 20 bytes) - 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x20, 0x01, - 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, - // ----- Payload to here - + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x20, + 0x01, + 0x00, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + // ----- Payload to here + // Last two bytes are CRC-16-CCITT - 0x8c, 0x4b -}; + 0x8c, + 0x4b}; + +unsigned char test_subseq_frag2b[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) + 0x6a, // datagram_size_2 (size bits 7..0 = 106) + 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) + 0x43, // datagram_offset_2 (size bits 7..0 = 67) -unsigned char test_subseq_frag2b[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) - 0x6a, // datagram_size_2 (size bits 7..0 = 106) - 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) - 0x43, // datagram_offset_2 (size bits 7..0 = 67) - // ----- Payload from here (next 27 bytes) - 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x26, 0x27, 0x28, - // ----- Payload to here - + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + // ----- Payload to here + // Last two bytes are CRC-16-CCITT - 0x6b, 0x5a -}; + 0x6b, + 0x5a}; + +unsigned char test_subseq_frag3[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) + 0x6a, // datagram_size_2 (size bits 7..0 = 106) + 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) + 0x5e, // datagram_offset_2 (size bits 7..0 = 94) -unsigned char test_subseq_frag3[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xe0, // COMMAND_SUBSEQUENT_FRAGMENT[7..3], datagram_size_1[2..0] (size bits 10..8 = 0) - 0x6a, // datagram_size_2 (size bits 7..0 = 106) - 0x00, // session_ID [7..4], Ext[3] (=0 i.e. no ext header), datagram_offset_1[2..0] (size bits 10..8 = 0) - 0x5e, // datagram_offset_2 (size bits 7..0 = 94) - // ----- Payload from here (last 12 bytes) - 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0x34, - // ----- Payload to here - + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + // ----- Payload to here + // Last two bytes are CRC-16-CCITT - 0x05, 0xd6 -}; + 0x05, + 0xd6}; -unsigned char test_frag_compl[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xE8, // COMMAND_FRAGMENT_COMPLETE - 0x00 // SessionID[7..4], Reserved[3..0] +unsigned char test_frag_compl[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xE8, // COMMAND_FRAGMENT_COMPLETE + 0x00 // SessionID[7..4], Reserved[3..0] }; -unsigned char test_frag_req[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xC8, // COMMAND_FRAGMENT_REQUEST - 0x00, // SessionID[7..4], Reserved[3], datagram_offset_1[2..0] (size bits 10..8 = 0) +unsigned char test_frag_req[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xC8, // COMMAND_FRAGMENT_REQUEST + 0x00, // SessionID[7..4], Reserved[3], datagram_offset_1[2..0] (size bits 10..8 = 0) 0x2f // datagram_offset_2 = 47 }; -unsigned char test_frag_req1[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xC8, // COMMAND_FRAGMENT_REQUEST - 0x00, // SessionID[7..4], Reserved[3], datagram_offset_1[2..0] (size bits 10..8 = 0) +unsigned char test_frag_req1[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xC8, // COMMAND_FRAGMENT_REQUEST + 0x00, // SessionID[7..4], Reserved[3], datagram_offset_1[2..0] (size bits 10..8 = 0) 0x43 // datagram_offset_2 = 67 }; - -unsigned char test_frag_req2[] = -{ - 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 - 0xC8, // COMMAND_FRAGMENT_REQUEST - 0x00, // SessionID[7..4], Reserved[3], datagram_offset_1[2..0] (size bits 10..8 = 0) +unsigned char test_frag_req2[] = { + 0x55, // COMMAND_CLASS_TRANSPORT_SERVICE_V2 + 0xC8, // COMMAND_FRAGMENT_REQUEST + 0x00, // SessionID[7..4], Reserved[3], datagram_offset_1[2..0] (size bits 10..8 = 0) 0x5e // datagram_offset_2 = 94 }; -unsigned char test_frag_wait_zero_pending[] = {0x55, 0xF0, 0x00}; -unsigned char test_frag_wait[] = {0x55, 0xF0, 0x01}; -unsigned char test_frag_wait_two_pending[] = {0x55, 0xF0, 0x02}; +unsigned char test_frag_wait_zero_pending[] = {0x55, 0xF0, 0x00}; +unsigned char test_frag_wait[] = {0x55, 0xF0, 0x01}; +unsigned char test_frag_wait_two_pending[] = {0x55, 0xF0, 0x02}; unsigned char test_frag_wait_three_pending[] = {0x55, 0xF0, 0x03}; unsigned char output[1024]; -void ZCB_ts_senddata_cb(unsigned char status_send, TX_STATUS_TYPE* txStatus); +void ZCB_ts_senddata_cb(unsigned char status_send, TX_STATUS_TYPE *txStatus); void fire_rx_timer(); void fire_fc_timer(); @@ -189,7 +403,8 @@ extern int check_scb_current_dnode(); extern int compare_received_datagram(const uint8_t *data, uint16_t len); extern int get_current_scb_cmn_session_id(); -extern uint16_t ZW_CheckCrc16(uint16_t crc, uint8_t *pDataAddr, uint16_t bDataLen); +extern uint16_t + ZW_CheckCrc16(uint16_t crc, uint8_t *pDataAddr, uint16_t bDataLen); extern int call_with_large_value; /* Should be s2_tx_status_t */ @@ -202,13 +417,27 @@ void status_callback(uint8_t txStatus, TX_STATUS_TYPE *t) void status_callback(uint8_t txStatus, void *t) #endif { - global_status = txStatus; + global_status = txStatus; } -unsigned char raw_data [] = {0x20, 0x01, 0x00 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07 ,0x08 ,0x09 ,0x0A ,0x0B ,0x0C ,0x0D ,0x0E ,0x0F ,0x10 ,0x11 ,0x12 ,0x13 ,0x14 ,0x15 ,0x16 ,0x17 ,0x18 ,0x19 ,0x1A ,0x1B ,0x1C ,0x1D ,0x1E ,0x1F ,0x20 ,0x21 ,0x22 ,0x23 ,0x24 ,0x25 ,0x26 ,0x27 ,0x28 ,0x29 ,0x2A ,0x2B ,0x2C ,0x2D ,0x2E, 0x2F ,0x30 ,0x31 ,0x32 ,0x33 ,0x34}; -unsigned char raw_data2 [] = {0x20, 0x01, 0x00 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07 ,0x08 ,0x09 ,0x0A ,0x0B ,0x0C ,0x0D ,0x0E ,0x0F ,0x10 ,0x11 ,0x12 ,0x13 ,0x14 ,0x15 ,0x16 ,0x17 ,0x18 ,0x19 ,0x1A ,0x1B ,0x1C ,0x1D ,0x1E ,0x1F ,0x20 ,0x21 ,0x22 ,0x23 ,0x24 ,0x25 ,0x26 ,0x27 ,0x28 ,0x29 ,0x2A ,0x2B ,0x2C ,0x2D ,0x2E, 0x2F ,0x30 ,0x31 ,0x32 ,0x33 ,0x34, 0x20, 0x01, 0x00 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07 ,0x08 ,0x09 ,0x0A ,0x0B ,0x0C ,0x0D ,0x0E ,0x0F ,0x10 ,0x11 ,0x12 ,0x13 ,0x14 ,0x15 ,0x16 ,0x17 ,0x18 ,0x19 ,0x1A ,0x1B ,0x1C ,0x1D ,0x1E ,0x1F ,0x20 ,0x21 ,0x22 ,0x23 ,0x24 ,0x25 ,0x26 ,0x27 ,0x28 ,0x29 ,0x2A ,0x2B ,0x2C ,0x2D ,0x2E, 0x2F ,0x30 ,0x31 ,0x32 ,0x33 ,0x34}; - -#define CRC_POLY 0x1021 +unsigned char raw_data[] + = {0x20, 0x01, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, + 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34}; +unsigned char raw_data2[] + = {0x20, 0x01, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x20, 0x01, 0x00, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, + 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, + 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34}; + +#define CRC_POLY 0x1021 uint16_t zgw_crc16(uint16_t crc16, uint8_t *data_buf, unsigned long data_len) { @@ -216,16 +445,13 @@ uint16_t zgw_crc16(uint16_t crc16, uint8_t *data_buf, unsigned long data_len) uint8_t bitMask; uint8_t NewBit; //printf("ZW_CheckCrc16: bDataLen = %u\r\n", bDataLen); - while (data_len--) - { + while (data_len--) { WorkData = *data_buf++; - for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) - { + for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) { /* Align test bit with next bit of the message byte, starting with msb. */ NewBit = ((WorkData & bitMask) != 0) ^ ((crc16 & 0x8000) != 0); crc16 <<= 1; - if (NewBit) - { + if (NewBit) { crc16 ^= CRC_POLY; } } /* for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) */ @@ -234,9 +460,14 @@ uint16_t zgw_crc16(uint16_t crc16, uint8_t *data_buf, unsigned long data_len) } extern unsigned char output[]; -bool TS_SEND_RAW(node_t snode, node_t dnode, uint8_t *cmd, uint8_t len, uint8_t flags, VOID_CALLBACKFUNC(completedFunc)(uint8_t, TX_STATUS_TYPE*)) +bool TS_SEND_RAW(node_t snode, + node_t dnode, + uint8_t *cmd, + uint8_t len, + uint8_t flags, + VOID_CALLBACKFUNC(completedFunc)(uint8_t, TX_STATUS_TYPE *)) { - memcpy(output, cmd, len); + memcpy(output, cmd, len); #if 0 int i; @@ -245,74 +476,78 @@ bool TS_SEND_RAW(node_t snode, node_t dnode, uint8_t *cmd, uint8_t len, uint8_t printf("\n"); #endif -/* + /* if (completedFunc) completedFunc(S2_TRANSMIT_COMPLETE_OK, NULL); */ - return 1; + return 1; } typedef uint16_t clock_time_t; struct ctimer { - struct ctimer *next; - clock_time_t tickCounts; - clock_time_t startValue; - VOID_CALLBACKFUNC(f)(void *); - void *ptr; + struct ctimer *next; + clock_time_t tickCounts; + clock_time_t startValue; + VOID_CALLBACKFUNC(f)(void *); + void *ptr; }; -void ctimer_set(struct ctimer *c, clock_time_t t, - void (*f)(void *), void *ptr) +void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr) { - return; + return; } int fc_timer_counter = 0; void ctimer_stop(struct ctimer *c) { - fc_timer_counter++; + fc_timer_counter++; } -void fire_timer_btwn_2_frags(int test_type) { +void fire_timer_btwn_2_frags(int test_type) +{ #ifdef ZIPGW - TX_STATUS_TYPE t; - memset(&t, 0, sizeof(TX_STATUS_TYPE)); - ZCB_ts_senddata_cb(0, &t); + TX_STATUS_TYPE t; + memset(&t, 0, sizeof(TX_STATUS_TYPE)); + ZCB_ts_senddata_cb(0, &t); #else - ZCB_ts_senddata_cb(0, NULL); + ZCB_ts_senddata_cb(0, NULL); #endif } extern void fc_timer_expired(void *nthing); void fire_fc_timer(void) { - fc_timer_expired(NULL); + fc_timer_expired(NULL); } extern void test_rx_timer_expired(void *); -void fire_rx_timer(){ - test_rx_timer_expired(0); +void fire_rx_timer() +{ + test_rx_timer_expired(0); } void ask_TS_to_send(void) { - ZW_TransportService_SendData(&p, raw_data2, sizeof(raw_data2), status_callback); + ZW_TransportService_SendData(&p, + raw_data2, + sizeof(raw_data2), + status_callback); } void ask_TS_to_receive(unsigned char *cmd, unsigned int len) { - TransportService_ApplicationCommandHandler(&p, cmd, len); + TransportService_ApplicationCommandHandler(&p, cmd, len); } int print_failed_if_nonzero(int ret, const char *test_name) -{ - if( ret != 0) { - v_printf("\t%s failed <-------------\n", test_name); - return 1; - } else { - v_printf("\t%s passed\n", test_name); - return 0; - } +{ + if (ret != 0) { + v_printf("\t%s failed <-------------\n", test_name); + return 1; + } else { + v_printf("\t%s passed\n", test_name); + return 0; + } } /* -------------- Test transport service's Receiving functionality ---------------------------------------*/ @@ -324,31 +559,32 @@ int print_failed_if_nonzero(int ret, const char *test_name) */ int simple_test(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("simple_test\n"); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - - // Did the fragments get "glued" together into the expected datagram? - ret = compare_received_datagram(test_complete_datagram, sizeof(test_complete_datagram)); - ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); - - // Did the transport service module respond with COMMAND_FRAGMENT_COMPLETE? - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "FRAGMENT_COMPLETE response sent:"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("simple_test\n"); + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + + // Did the fragments get "glued" together into the expected datagram? + ret = compare_received_datagram(test_complete_datagram, + sizeof(test_complete_datagram)); + ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); + + // Did the transport service module respond with COMMAND_FRAGMENT_COMPLETE? + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "FRAGMENT_COMPLETE response sent:"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } /* @@ -359,32 +595,33 @@ int simple_test(void) */ int simple_test_non_uniform_fragment_sizes(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("simple_test_non_uniform_fragment_sizes\n"); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - ask_TS_to_receive(test_subseq_frag2a, sizeof(test_subseq_frag2a)); - ask_TS_to_receive(test_subseq_frag2b, sizeof(test_subseq_frag2b)); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - - // Did the fragments get "glued" together into the expected datagram? - ret = compare_received_datagram(test_complete_datagram, sizeof(test_complete_datagram)); - ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); - - // Did the transport service module respond with COMMAND_FRAGMENT_COMPLETE? - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "FRAGMENT_COMPLETE response sent:"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("simple_test_non_uniform_fragment_sizes\n"); + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + ask_TS_to_receive(test_subseq_frag2a, sizeof(test_subseq_frag2a)); + ask_TS_to_receive(test_subseq_frag2b, sizeof(test_subseq_frag2b)); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + + // Did the fragments get "glued" together into the expected datagram? + ret = compare_received_datagram(test_complete_datagram, + sizeof(test_complete_datagram)); + ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); + + // Did the transport service module respond with COMMAND_FRAGMENT_COMPLETE? + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "FRAGMENT_COMPLETE response sent:"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } /* @@ -395,32 +632,33 @@ int simple_test_non_uniform_fragment_sizes(void) */ int simple_test_non_sequential_fragments(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("simple_test_non_sequential_fragments\n"); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - ask_TS_to_receive(test_subseq_frag2b, sizeof(test_subseq_frag2b)); - ask_TS_to_receive(test_subseq_frag2a, sizeof(test_subseq_frag2a)); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - - // Did the fragments get "glued" together into the expected datagram? - ret = compare_received_datagram(test_complete_datagram, sizeof(test_complete_datagram)); - ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); - - // Did the transport service module respond with COMMAND_FRAGMENT_COMPLETE? - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "FRAGMENT_COMPLETE response sent:"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("simple_test_non_sequential_fragments\n"); + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + ask_TS_to_receive(test_subseq_frag2b, sizeof(test_subseq_frag2b)); + ask_TS_to_receive(test_subseq_frag2a, sizeof(test_subseq_frag2a)); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + + // Did the fragments get "glued" together into the expected datagram? + ret = compare_received_datagram(test_complete_datagram, + sizeof(test_complete_datagram)); + ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); + + // Did the transport service module respond with COMMAND_FRAGMENT_COMPLETE? + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "FRAGMENT_COMPLETE response sent:"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } /* @@ -428,34 +666,36 @@ int simple_test_non_sequential_fragments(void) */ int miss_one_frag(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - printf("miss_one_frag\n"); - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - fire_rx_timer(); - - ret = memcmp(output, test_frag_req, sizeof(test_frag_req)); - ret = print_failed_if_nonzero(ret, "miss_one_frag frag_req check"); - fail_if_nonzero(ret); - - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); - - ret = compare_received_datagram(test_complete_datagram, sizeof(test_complete_datagram)); - ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); - - fire_rx_timer(); - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "miss_one_frag rag_compl check"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + printf("miss_one_frag\n"); + + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + fire_rx_timer(); + + ret = memcmp(output, test_frag_req, sizeof(test_frag_req)); + ret = print_failed_if_nonzero(ret, "miss_one_frag frag_req check"); + fail_if_nonzero(ret); + + ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); + + ret = compare_received_datagram(test_complete_datagram, + sizeof(test_complete_datagram)); + ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); + + fire_rx_timer(); + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "miss_one_frag rag_compl check"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } /* @@ -463,35 +703,37 @@ int miss_one_frag(void) */ int miss_one_frag1(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - printf("miss_one_frag1\n"); - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - ask_TS_to_receive(test_subseq_frag2a, sizeof(test_subseq_frag2a)); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - fire_rx_timer(); - - ret = memcmp(output, test_frag_req1, sizeof(test_frag_req1)); - ret = print_failed_if_nonzero(ret, "miss_one_frag frag_req check"); - fail_if_nonzero(ret); - - ask_TS_to_receive(test_subseq_frag2b, sizeof(test_subseq_frag2b)); - - ret = compare_received_datagram(test_complete_datagram, sizeof(test_complete_datagram)); - ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); - - fire_rx_timer(); - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "miss_one_frag rag_compl check"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + printf("miss_one_frag1\n"); + + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + ask_TS_to_receive(test_subseq_frag2a, sizeof(test_subseq_frag2a)); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + fire_rx_timer(); + + ret = memcmp(output, test_frag_req1, sizeof(test_frag_req1)); + ret = print_failed_if_nonzero(ret, "miss_one_frag frag_req check"); + fail_if_nonzero(ret); + + ask_TS_to_receive(test_subseq_frag2b, sizeof(test_subseq_frag2b)); + + ret = compare_received_datagram(test_complete_datagram, + sizeof(test_complete_datagram)); + ret = print_failed_if_nonzero(ret, "Datagram re-assembly from fragments:"); + + fire_rx_timer(); + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "miss_one_frag rag_compl check"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } /* 1. send first fragment @@ -503,30 +745,31 @@ int miss_one_frag1(void) */ int dont_send_one_frag(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("dont_send_one_frag\n"); - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - fire_rx_timer(); - - ret = memcmp(output, test_frag_req, sizeof(test_frag_req)); - ret = print_failed_if_nonzero(ret, "dont_send_one_frag frag_req check"); - fail_if_nonzero(ret); - - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "dont_send_one_frag frag_compl check"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("dont_send_one_frag\n"); + + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + fire_rx_timer(); + + ret = memcmp(output, test_frag_req, sizeof(test_frag_req)); + ret = print_failed_if_nonzero(ret, "dont_send_one_frag frag_req check"); + fail_if_nonzero(ret); + + ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "dont_send_one_frag frag_compl check"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } /* 1. send subseq fragment @@ -534,24 +777,31 @@ int dont_send_one_frag(void) */ int test_dont_send_first_frag(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_dont_send_first_frag\n"); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); /* Skip sending first frag and send subseq frag instead */ - - ret = memcmp(output, test_frag_wait_zero_pending, sizeof(test_frag_wait_zero_pending)); /* Check if we get fragment wait */ - ret = print_failed_if_nonzero(ret, "test_dont_send_first_frag frag_wait"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_dont_send_first_frag\n"); + ask_TS_to_receive( + test_subseq_frag2, + sizeof( + test_subseq_frag2)); /* Skip sending first frag and send subseq frag instead */ + + ret = memcmp( + output, + test_frag_wait_zero_pending, + sizeof(test_frag_wait_zero_pending)); /* Check if we get fragment wait */ + ret = print_failed_if_nonzero(ret, "test_dont_send_first_frag frag_wait"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } /* 1. Send first fragment @@ -564,35 +814,48 @@ int test_dont_send_first_frag(void) int test_frag_wait_fn(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_frag_wait_fn\n"); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); /* Send first frag */ - - p.snode = 0xf1; - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); /* Send subseq frag from different source node */ - p.snode = 0xff; - - ret = memcmp(output, test_frag_wait_three_pending, sizeof(test_frag_wait_two_pending)); - ret = print_failed_if_nonzero(ret, "test_frag_wait receive check "); - fail_if_nonzero(ret); - - memset(output, 0, sizeof(test_frag_compl)); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); /* Send correct second subseq frag */ - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); /* Send correct third subseq frag */ - - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); /* Check if we recive fragment complete */ - ret = print_failed_if_nonzero(ret, "frag_complete receive check"); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_frag_wait_fn\n"); + ask_TS_to_receive(test_first_frag1, + sizeof(test_first_frag1)); /* Send first frag */ + + p.snode = 0xf1; + ask_TS_to_receive( + test_subseq_frag2, + sizeof( + test_subseq_frag2)); /* Send subseq frag from different source node */ + p.snode = 0xff; + + ret = memcmp(output, + test_frag_wait_three_pending, + sizeof(test_frag_wait_two_pending)); + ret = print_failed_if_nonzero(ret, "test_frag_wait receive check "); + fail_if_nonzero(ret); + + memset(output, 0, sizeof(test_frag_compl)); + ask_TS_to_receive( + test_subseq_frag2, + sizeof(test_subseq_frag2)); /* Send correct second subseq frag */ + ask_TS_to_receive( + test_subseq_frag3, + sizeof(test_subseq_frag3)); /* Send correct third subseq frag */ + + ret = memcmp( + output, + test_frag_compl, + sizeof(test_frag_compl)); /* Check if we recive fragment complete */ + ret = print_failed_if_nonzero(ret, "frag_complete receive check"); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } /* -------------- Test transport service's Sending functionality ---------------------------------------*/ @@ -607,43 +870,52 @@ extern TRANSPORT2_ST_T current_state; */ int test_send_whole_datagram(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_send_whole_datagram\n"); - ask_TS_to_send(); - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - ret = print_failed_if_nonzero(ret, "tets_send_whole_data_gram first fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "tets_send_whole_data_gram first subseq fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "tets_send_whole_data_gram second subseq fragment"); - fail_if_nonzero(ret); - - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); - p.snode = 0xff; - p.dnode = 0xfe; - - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(check_scb_current_dnode(), "tets_send_whole_data_gram frag_compl processing"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_send_whole_datagram\n"); + ask_TS_to_send(); + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + ret + = print_failed_if_nonzero(ret, "tets_send_whole_data_gram first fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero( + ret, + "tets_send_whole_data_gram first subseq fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero( + ret, + "tets_send_whole_data_gram second subseq fragment"); + fail_if_nonzero(ret); + + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); + p.snode = 0xff; + p.dnode = 0xfe; + + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero( + check_scb_current_dnode(), + "tets_send_whole_data_gram frag_compl processing"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } /* Purpose of this test is to send fragment request frame with different session ID, @@ -660,54 +932,62 @@ int test_send_whole_datagram(void) int test_jakob(void) { - int ret = 0; - unsigned backup_byte; - memset(output, 0, sizeof(output)); - - printf("test_jakob\n"); - ask_TS_to_send(); - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - ret = print_failed_if_nonzero(ret, "test_jakob first fragment"); - fail_if_nonzero(ret); - - backup_byte = test_frag_req[2]; /*Change the session ID of frag_req cmd */ - test_frag_req[2] = 0xA0; - fc_timer_counter = 0; - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_req, sizeof(test_frag_req)); /* <-- Send fragment request with different session id */ - ret = print_failed_if_nonzero(fc_timer_counter, "test_send_frag_req_with_diff_session_id(jakob)"); - fail_if_nonzero(ret); - test_frag_req[2] = backup_byte; - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_jakob first subseq fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_jakob second subseq fragment"); - fail_if_nonzero(ret); - - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); /* <-- Send fragment request with different session id */ - - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - printf("passed\n"); - return 0; + int ret = 0; + unsigned backup_byte; + memset(output, 0, sizeof(output)); + + printf("test_jakob\n"); + ask_TS_to_send(); + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + ret = print_failed_if_nonzero(ret, "test_jakob first fragment"); + fail_if_nonzero(ret); + + backup_byte = test_frag_req[2]; /*Change the session ID of frag_req cmd */ + test_frag_req[2] = 0xA0; + fc_timer_counter = 0; + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive( + test_frag_req, + sizeof( + test_frag_req)); /* <-- Send fragment request with different session id */ + ret + = print_failed_if_nonzero(fc_timer_counter, + "test_send_frag_req_with_diff_session_id(jakob)"); + fail_if_nonzero(ret); + test_frag_req[2] = backup_byte; + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero(ret, "test_jakob first subseq fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero(ret, "test_jakob second subseq fragment"); + fail_if_nonzero(ret); + + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive( + test_frag_compl, + sizeof( + test_frag_compl)); /* <-- Send fragment request with different session id */ + + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - - + printf("failed\n"); + return 1; } /* Purpose of this test is to see if the sending side tie breaks on receival of segment @@ -726,39 +1006,44 @@ int test_jakob(void) */ int test_tie_break(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_tie_break\n"); - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_send(); - p.snode = 0xff; - p.dnode = 0xfe; - MyNodeID = 0xfe; - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); /* <-- ask to receive*/ - ret = print_failed_if_nonzero(!check_flag_tie_broken(), "Flag tie broken"); - fail_if_nonzero(ret); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2));/* <-- ask to receive*/ - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3));/* <-- ask to receive*/ -// fire_rx_timer(); - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(ret, "test_tie_break"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_tie_break\n"); + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_send(); + p.snode = 0xff; + p.dnode = 0xfe; + MyNodeID = 0xfe; + + ask_TS_to_receive(test_first_frag1, + sizeof(test_first_frag1)); /* <-- ask to receive*/ + ret = print_failed_if_nonzero(!check_flag_tie_broken(), "Flag tie broken"); + fail_if_nonzero(ret); + ask_TS_to_receive(test_subseq_frag2, + sizeof(test_subseq_frag2)); /* <-- ask to receive*/ + ask_TS_to_receive(test_subseq_frag3, + sizeof(test_subseq_frag3)); /* <-- ask to receive*/ + // fire_rx_timer(); + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(ret, "test_tie_break"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } /* Purpose of this test is to check if the on timeout of fc_timer does transport service @@ -771,509 +1056,588 @@ int test_tie_break(void) */ int test_two_last_fragments(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_two_last_fragments\n"); - ask_TS_to_send(); - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - print_failed_if_nonzero(ret, "test_two_last_fragments first fragment"); - - fire_timer_btwn_2_frags(0);/* <-- ask to send second frag */ - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_two_last_fragments second fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0);/* <-- ask to send second frag */ - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_two_last_fragments second fragment"); - fail_if_nonzero(ret); - - memset(output, 0, sizeof(test_subseq_frag3)); - fire_fc_timer(); /*Tell transport service that we did not receive the last fragment */ - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_two_last_fragments second fragment again"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!check_flag_fc_timer_expired_once(), "fc_timer_expired_flag_check"); - fail_if_nonzero(ret); - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - p.snode = 0xff; - p.dnode = 0xfe; - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_two_last_fragments\n"); + ask_TS_to_send(); + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + print_failed_if_nonzero(ret, "test_two_last_fragments first fragment"); + + fire_timer_btwn_2_frags(0); /* <-- ask to send second frag */ + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero(ret, "test_two_last_fragments second fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); /* <-- ask to send second frag */ + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero(ret, "test_two_last_fragments second fragment"); + fail_if_nonzero(ret); + + memset(output, 0, sizeof(test_subseq_frag3)); + fire_fc_timer(); /*Tell transport service that we did not receive the last fragment */ + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret + = print_failed_if_nonzero(ret, + "test_two_last_fragments second fragment again"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!check_flag_fc_timer_expired_once(), + "fc_timer_expired_flag_check"); + fail_if_nonzero(ret); + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + p.snode = 0xff; + p.dnode = 0xfe; + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } int test_send_frag_compl_from_diff_session(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - unsigned backup_byte; - - printf("test_send_frag_compl_from_diff_session\n"); - ask_TS_to_send(); /* <-- Start sending session */ - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - ret = print_failed_if_nonzero(ret, "test_send_frag_compl_from_diff_session first fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_send_frag_compl_from_diff_session second fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_send_frag_compl_from_diff_session second fragment"); - fail_if_nonzero(ret); - - backup_byte = test_frag_compl[2]; - test_frag_compl[2] = 0xA0; - fc_timer_counter = 0; - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); /* <-- Send fragment request with different session id */ - ret = print_failed_if_nonzero(fc_timer_counter, "test_send_frag_compl_from_diff_session fc_timer"); - fail_if_nonzero(ret); - test_frag_compl[2] = backup_byte; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); - p.snode = 0xff; - p.dnode = 0xfe; - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(check_scb_current_dnode(), "test_send_frag_compl_from_diff_session frag_compl processing"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + unsigned backup_byte; + + printf("test_send_frag_compl_from_diff_session\n"); + ask_TS_to_send(); /* <-- Start sending session */ + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + ret = print_failed_if_nonzero( + ret, + "test_send_frag_compl_from_diff_session first fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero( + ret, + "test_send_frag_compl_from_diff_session second fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero( + ret, + "test_send_frag_compl_from_diff_session second fragment"); + fail_if_nonzero(ret); + + backup_byte = test_frag_compl[2]; + test_frag_compl[2] = 0xA0; + fc_timer_counter = 0; + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive( + test_frag_compl, + sizeof( + test_frag_compl)); /* <-- Send fragment request with different session id */ + ret = print_failed_if_nonzero( + fc_timer_counter, + "test_send_frag_compl_from_diff_session fc_timer"); + fail_if_nonzero(ret); + test_frag_compl[2] = backup_byte; + ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); + p.snode = 0xff; + p.dnode = 0xfe; + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero( + check_scb_current_dnode(), + "test_send_frag_compl_from_diff_session frag_compl processing"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } static void test_add_crc(uint8_t *buf, uint8_t len) { - uint8_t *tmp_buf = buf; + uint8_t *tmp_buf = buf; #ifdef ZGW - uint16_t crc = ZW_CheckCrc16(0x1D0F, tmp_buf, len); + uint16_t crc = ZW_CheckCrc16(0x1D0F, tmp_buf, len); #else - uint16_t crc = zgw_crc16(0x1D0F, tmp_buf, len); + uint16_t crc = zgw_crc16(0x1D0F, tmp_buf, len); #endif - tmp_buf+=len; - *tmp_buf++ = (crc>>8)&0xff; - *tmp_buf=(crc)&0xff; + tmp_buf += len; + *tmp_buf++ = (crc >> 8) & 0xff; + *tmp_buf = (crc)&0xff; } void regenerate_crc(unsigned char *array, unsigned int len, unsigned char *crc) { - crc[0] = array[len-2]; - crc[1] = array[len-1]; - test_add_crc(array, len - 2); + crc[0] = array[len - 2]; + crc[1] = array[len - 1]; + test_add_crc(array, len - 2); } void restore_crc(unsigned char *array, unsigned int len, unsigned char *crc) { - array[len-2] = crc[0]; - array[len-1] = crc[1]; + array[len - 2] = crc[0]; + array[len - 1] = crc[1]; } int test_abort_transmission(void) { - int ret = 0; - unsigned char backup_byte; - unsigned char crc[2]; - - printf("test_abort_transmission\n"); - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_send(); /* <-- Start sending session */ - p.snode = 0xff; - p.dnode = 0xfe; - MyNodeID = 0xfe; - backup_byte = test_first_frag1[3]; - test_first_frag1[3] = 0xA0; - - regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); /* <-- ask to receive*/ - restore_crc(test_first_frag1, sizeof(test_first_frag1), crc); - test_first_frag1[3] = backup_byte; - - ret = print_failed_if_nonzero(!check_flag_tie_broken(), "Flag tie broken"); - fail_if_nonzero(ret); - - fc_timer_counter = 0; - ask_TS_to_receive(test_frag_req, sizeof(test_frag_req)); /* <-- Send fragment request with different session id */ - ret = print_failed_if_nonzero(fc_timer_counter, "test_abort_transmission frag_req should be ignored"); - - test_subseq_frag2[3] = 0xA0; - regenerate_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2));/* <-- ask to receive*/ - restore_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); - test_subseq_frag2[3] = backup_byte; - - test_subseq_frag3[3] = 0xA0; - regenerate_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3));/* <-- ask to receive*/ - restore_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); - test_subseq_frag3[3] = backup_byte; - - backup_byte = test_frag_compl[2]; - test_frag_compl[2] = 0xA0; - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "frag_complete receive check"); - test_frag_compl[2] = backup_byte; - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + unsigned char backup_byte; + unsigned char crc[2]; + + printf("test_abort_transmission\n"); + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_send(); /* <-- Start sending session */ + p.snode = 0xff; + p.dnode = 0xfe; + MyNodeID = 0xfe; + backup_byte = test_first_frag1[3]; + test_first_frag1[3] = 0xA0; + + regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); + ask_TS_to_receive(test_first_frag1, + sizeof(test_first_frag1)); /* <-- ask to receive*/ + restore_crc(test_first_frag1, sizeof(test_first_frag1), crc); + test_first_frag1[3] = backup_byte; + + ret = print_failed_if_nonzero(!check_flag_tie_broken(), "Flag tie broken"); + fail_if_nonzero(ret); + + fc_timer_counter = 0; + ask_TS_to_receive( + test_frag_req, + sizeof( + test_frag_req)); /* <-- Send fragment request with different session id */ + ret = print_failed_if_nonzero( + fc_timer_counter, + "test_abort_transmission frag_req should be ignored"); + + test_subseq_frag2[3] = 0xA0; + regenerate_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); + ask_TS_to_receive(test_subseq_frag2, + sizeof(test_subseq_frag2)); /* <-- ask to receive*/ + restore_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); + test_subseq_frag2[3] = backup_byte; + + test_subseq_frag3[3] = 0xA0; + regenerate_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); + ask_TS_to_receive(test_subseq_frag3, + sizeof(test_subseq_frag3)); /* <-- ask to receive*/ + restore_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); + test_subseq_frag3[3] = backup_byte; + + backup_byte = test_frag_compl[2]; + test_frag_compl[2] = 0xA0; + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "frag_complete receive check"); + test_frag_compl[2] = backup_byte; + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } int test_fc_timer_after_frag_req(void) -{ - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_fc_timer_after_frag_req\n"); - ask_TS_to_send(); /* <-- ask to send first frag */ - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - print_failed_if_nonzero(ret, "test_fc_timer_after_frag_req first fragment"); - - fire_timer_btwn_2_frags(0);/* <-- ask to send second frag */ - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_frag_req second fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0);/* <-- ask to send second frag */ - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_frag_req second fragment"); - fail_if_nonzero(ret); - - memset(output, 0, sizeof(test_subseq_frag3)); - - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_req, sizeof(test_frag_req)); - fire_fc_timer(); - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_FAIL), "Did transmissino fail..."); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - printf("passed\n"); - return 0; +{ + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_fc_timer_after_frag_req\n"); + ask_TS_to_send(); /* <-- ask to send first frag */ + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + print_failed_if_nonzero(ret, "test_fc_timer_after_frag_req first fragment"); + + fire_timer_btwn_2_frags(0); /* <-- ask to send second frag */ + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero(ret, + "test_fc_timer_after_frag_req second fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); /* <-- ask to send second frag */ + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero(ret, + "test_fc_timer_after_frag_req second fragment"); + fail_if_nonzero(ret); + + memset(output, 0, sizeof(test_subseq_frag3)); + + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive(test_frag_req, sizeof(test_frag_req)); + fire_fc_timer(); + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_FAIL), + "Did transmissino fail..."); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - - + printf("failed\n"); + return 1; } int test_fc_timer_after_frag_compl_of_aborted_transmission(void) { - int ret = 0; - unsigned char backup_byte; - unsigned char crc[2]; - memset(output, 0, sizeof(output)); - - printf("test_fc_timer_after_frag_compl_of_aborted_transmission\n"); - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_send(); /* <-- ask to send */ - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_frag_compl_of_aborted_transmission first fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); /* ask to send subseq frag */ - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_frag_compl_of_aborted_transmission second fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); /* ask to send subseq frag */ - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_frag_compl_of_aborted_transmission second fragment"); - fail_if_nonzero(ret); - - p.snode = 0xff; /* setup to do tie break */ - p.dnode = 0xfe; - MyNodeID = 0xfe; - - backup_byte = test_first_frag1[3]; - test_first_frag1[3] = 0xA0; - regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); /* <-- ask to receive with session id:10 */ - restore_crc(test_first_frag1, sizeof(test_first_frag1), crc); - test_first_frag1[3] = backup_byte; - - ret = print_failed_if_nonzero(!check_flag_tie_broken(), "Flag tie broken"); - fail_if_nonzero(ret); - - fire_fc_timer(); - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_FAIL), "Did transmissino fail for sending session..."); - fail_if_nonzero(ret); - - test_subseq_frag2[3] = 0xA0; - regenerate_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2));/* <-- ask to receive subseq frag with session id:10 */ - restore_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); - test_subseq_frag2[3] = backup_byte; - - test_subseq_frag3[3] = 0xA0; - regenerate_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3));/* <-- ask to receive subseq frag with session id:10 */ - restore_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); - test_subseq_frag3[3] = backup_byte; - - backup_byte = test_frag_compl[2]; /* Check if frag compl received for session id:10 */ - test_frag_compl[2] = 0xA0; - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_frag_compl_of_aborted_transmission frag_compl received check"); - test_frag_compl[2] = backup_byte; - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - p.snode = 0xff; - p.dnode = 0xfe; - printf("passed\n"); - return 0; + int ret = 0; + unsigned char backup_byte; + unsigned char crc[2]; + memset(output, 0, sizeof(output)); + + printf("test_fc_timer_after_frag_compl_of_aborted_transmission\n"); + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_send(); /* <-- ask to send */ + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + ret = print_failed_if_nonzero( + ret, + "test_fc_timer_after_frag_compl_of_aborted_transmission first fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); /* ask to send subseq frag */ + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero( + ret, + "test_fc_timer_after_frag_compl_of_aborted_transmission second fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); /* ask to send subseq frag */ + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero( + ret, + "test_fc_timer_after_frag_compl_of_aborted_transmission second fragment"); + fail_if_nonzero(ret); + + p.snode = 0xff; /* setup to do tie break */ + p.dnode = 0xfe; + MyNodeID = 0xfe; + + backup_byte = test_first_frag1[3]; + test_first_frag1[3] = 0xA0; + regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); + ask_TS_to_receive( + test_first_frag1, + sizeof(test_first_frag1)); /* <-- ask to receive with session id:10 */ + restore_crc(test_first_frag1, sizeof(test_first_frag1), crc); + test_first_frag1[3] = backup_byte; + + ret = print_failed_if_nonzero(!check_flag_tie_broken(), "Flag tie broken"); + fail_if_nonzero(ret); + + fire_fc_timer(); + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_FAIL), + "Did transmissino fail for sending session..."); + fail_if_nonzero(ret); + + test_subseq_frag2[3] = 0xA0; + regenerate_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); + ask_TS_to_receive( + test_subseq_frag2, + sizeof( + test_subseq_frag2)); /* <-- ask to receive subseq frag with session id:10 */ + restore_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); + test_subseq_frag2[3] = backup_byte; + + test_subseq_frag3[3] = 0xA0; + regenerate_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); + ask_TS_to_receive( + test_subseq_frag3, + sizeof( + test_subseq_frag3)); /* <-- ask to receive subseq frag with session id:10 */ + restore_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); + test_subseq_frag3[3] = backup_byte; + + backup_byte + = test_frag_compl[2]; /* Check if frag compl received for session id:10 */ + test_frag_compl[2] = 0xA0; + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, + "test_fc_timer_after_frag_compl_of_aborted_" + "transmission frag_compl received check"); + test_frag_compl[2] = backup_byte; + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + p.snode = 0xff; + p.dnode = 0xfe; + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } int test_fc_timer_after_last_frag_twice(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_fc_timer_after_last_frag_twice\n"); - ask_TS_to_send(); /* <-- ask to send first frag */ - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - print_failed_if_nonzero(ret, "test_fc_timer_after_last_frag_twice first fragment"); - - fire_timer_btwn_2_frags(0);/* <-- ask to send second frag */ - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_last_frag_twice second fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0);/* <-- ask to send second frag */ - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_last_frag_twice second fragment"); - fail_if_nonzero(ret); - - memset(output, 0, sizeof(test_subseq_frag3)); - - fire_fc_timer(); /*Tell transport service that we did not receive the last fragment */ - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_fc_timer_after_last_frag_twice second fragment again"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!check_flag_fc_timer_expired_once(), "fc_timer_expired_flag_check"); - fail_if_nonzero(ret); - - fire_fc_timer(); /*Tell transport service that we did not receive the last fragment */ - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_FAIL), "Did transmissino fail for sending session..."); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(check_scb_current_dnode(), "current_dnode is set to 0 check"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_fc_timer_after_last_frag_twice\n"); + ask_TS_to_send(); /* <-- ask to send first frag */ + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + print_failed_if_nonzero(ret, + "test_fc_timer_after_last_frag_twice first fragment"); + + fire_timer_btwn_2_frags(0); /* <-- ask to send second frag */ + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero( + ret, + "test_fc_timer_after_last_frag_twice second fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); /* <-- ask to send second frag */ + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero( + ret, + "test_fc_timer_after_last_frag_twice second fragment"); + fail_if_nonzero(ret); + + memset(output, 0, sizeof(test_subseq_frag3)); + + fire_fc_timer(); /*Tell transport service that we did not receive the last fragment */ + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero( + ret, + "test_fc_timer_after_last_frag_twice second fragment again"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!check_flag_fc_timer_expired_once(), + "fc_timer_expired_flag_check"); + fail_if_nonzero(ret); + + fire_fc_timer(); /*Tell transport service that we did not receive the last fragment */ + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_FAIL), + "Did transmissino fail for sending session..."); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(check_scb_current_dnode(), + "current_dnode is set to 0 check"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } int test_frag_wait_for_completed_session(void) { - int ret = 0; - memset(output, 0, sizeof(output)); - - printf("test_frag_wait_for_completed_session\n"); - ask_TS_to_send(); - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - ret = print_failed_if_nonzero(ret, "test_frag_wait_for_completed_session first fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "test_frag_wait_for_completed_session second fragment"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "test_frag_wait_for_completed_session second fragment"); - fail_if_nonzero(ret); - - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); - ask_TS_to_receive(test_frag_wait, sizeof(test_frag_wait)); - p.snode = 0xff; - p.dnode = 0xfe; - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(check_scb_current_dnode(), "tets_send_whole_data_gram frag_compl processing"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + memset(output, 0, sizeof(output)); + + printf("test_frag_wait_for_completed_session\n"); + ask_TS_to_send(); + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + ret = print_failed_if_nonzero( + ret, + "test_frag_wait_for_completed_session first fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero( + ret, + "test_frag_wait_for_completed_session second fragment"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero( + ret, + "test_frag_wait_for_completed_session second fragment"); + fail_if_nonzero(ret); + + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); + ask_TS_to_receive(test_frag_wait, sizeof(test_frag_wait)); + p.snode = 0xff; + p.dnode = 0xfe; + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero( + check_scb_current_dnode(), + "tets_send_whole_data_gram frag_compl processing"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } int three_node_test(void) { - int ret = 0; - global_status = 0xff; - memset(output, 0, sizeof(output)); - - printf("three_node_stress_test\n"); - ask_TS_to_send(); - - ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); - ret = print_failed_if_nonzero(ret, "first fragment"); - fail_if_nonzero(ret); - - p.snode = 0xf1; - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_frag_wait_two_pending, sizeof(test_frag_wait_two_pending)); /* Check if we get fragment wait */ - ret = print_failed_if_nonzero(ret, "received fragment_wait check"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = print_failed_if_nonzero(ret, "first subseq fragment"); - fail_if_nonzero(ret); - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_frag_wait, sizeof(test_frag_wait)); /* Check if we get fragment wait */ - ret = print_failed_if_nonzero(ret, "received fragment_wait again check"); - fail_if_nonzero(ret); - - fire_timer_btwn_2_frags(0); - ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = print_failed_if_nonzero(ret, "second subseq fragment"); - fail_if_nonzero(ret); - - p.snode = 0xfe; - p.dnode = 0xff; - ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), "Did transmissino OK for sending session..."); - fail_if_nonzero(ret); - p.snode = 0xf1; - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); /* <-- ask to receive*/ - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2));/* <-- ask to receive*/ - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3));/* <-- ask to receive*/ -// fire_rx_timer(); - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "fragment complete"); - fail_if_nonzero(ret); - - return 0; + int ret = 0; + global_status = 0xff; + memset(output, 0, sizeof(output)); + + printf("three_node_stress_test\n"); + ask_TS_to_send(); + + ret = memcmp(output, test_first_frag1, sizeof(test_first_frag1)); + ret = print_failed_if_nonzero(ret, "first fragment"); + fail_if_nonzero(ret); + + p.snode = 0xf1; + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + + fire_timer_btwn_2_frags(0); + ret = memcmp( + output, + test_frag_wait_two_pending, + sizeof(test_frag_wait_two_pending)); /* Check if we get fragment wait */ + ret = print_failed_if_nonzero(ret, "received fragment_wait check"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = print_failed_if_nonzero(ret, "first subseq fragment"); + fail_if_nonzero(ret); + + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, + test_frag_wait, + sizeof(test_frag_wait)); /* Check if we get fragment wait */ + ret = print_failed_if_nonzero(ret, "received fragment_wait again check"); + fail_if_nonzero(ret); + + fire_timer_btwn_2_frags(0); + ret = memcmp(output, test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = print_failed_if_nonzero(ret, "second subseq fragment"); + fail_if_nonzero(ret); + + p.snode = 0xfe; + p.dnode = 0xff; + ask_TS_to_receive(test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(!(global_status == S2_TRANSMIT_COMPLETE_OK), + "Did transmissino OK for sending session..."); + fail_if_nonzero(ret); + p.snode = 0xf1; + + ask_TS_to_receive(test_first_frag1, + sizeof(test_first_frag1)); /* <-- ask to receive*/ + ask_TS_to_receive(test_subseq_frag2, + sizeof(test_subseq_frag2)); /* <-- ask to receive*/ + ask_TS_to_receive(test_subseq_frag3, + sizeof(test_subseq_frag3)); /* <-- ask to receive*/ + // fire_rx_timer(); + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "fragment complete"); + fail_if_nonzero(ret); + + return 0; fail: - return 1; + return 1; } int send_big_datagram(void) { - int ret = 0; - unsigned char backup[2]; - unsigned char crc[2]; - memset(output, 0, sizeof(output)); - - printf("send_big_datagram\n"); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); - backup[0] = test_subseq_frag3[3]; - backup[1] = test_subseq_frag3[4]; - - test_subseq_frag3[3] = ((DATAGRAM_SIZE_MAX+1) & 0x700) >> 8; - test_subseq_frag3[4] = ((DATAGRAM_SIZE_MAX+1) & 0xff); - - regenerate_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - restore_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); - test_subseq_frag3[3] = backup[0]; - test_subseq_frag3[4] = backup[1]; - fire_rx_timer(); - - ret = memcmp(output, test_frag_req2, sizeof(test_frag_req2)); - ret = print_failed_if_nonzero(ret, "send_big_datagram frag_req received"); - fail_if_nonzero(ret); - - ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); - ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); - ret = print_failed_if_nonzero(ret, "send_big_datagram frag_compl"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + unsigned char backup[2]; + unsigned char crc[2]; + memset(output, 0, sizeof(output)); + + printf("send_big_datagram\n"); + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); + backup[0] = test_subseq_frag3[3]; + backup[1] = test_subseq_frag3[4]; + + test_subseq_frag3[3] = ((DATAGRAM_SIZE_MAX + 1) & 0x700) >> 8; + test_subseq_frag3[4] = ((DATAGRAM_SIZE_MAX + 1) & 0xff); + + regenerate_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + restore_crc(test_subseq_frag3, sizeof(test_subseq_frag3), crc); + test_subseq_frag3[3] = backup[0]; + test_subseq_frag3[4] = backup[1]; + fire_rx_timer(); + + ret = memcmp(output, test_frag_req2, sizeof(test_frag_req2)); + ret = print_failed_if_nonzero(ret, "send_big_datagram frag_req received"); + fail_if_nonzero(ret); + + ask_TS_to_receive(test_subseq_frag3, sizeof(test_subseq_frag3)); + ret = memcmp(output, test_frag_compl, sizeof(test_frag_compl)); + ret = print_failed_if_nonzero(ret, "send_big_datagram frag_compl"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } int send_big_datagram2(void) { - int ret = 0; - unsigned char backup[2]; - unsigned char crc[2]; - memset(output, 0, sizeof(output)); - - printf("send_big_datagram2\n"); - backup[0] = test_first_frag1[1]; - backup[1] = test_first_frag1[2]; - test_first_frag1[1] = 0xC0 + (((DATAGRAM_SIZE_MAX+1) & 0x700) >> 8); - test_first_frag1[2] = ((DATAGRAM_SIZE_MAX+1) & 0xff); - regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - restore_crc(test_first_frag1, sizeof(test_first_frag1), crc); - test_first_frag1[1] = backup[0]; - test_first_frag1[2] = backup[1]; - - backup[0] = test_subseq_frag2[1]; - backup[1] = test_subseq_frag2[2]; - test_subseq_frag2[1] = 0xE0 + (((DATAGRAM_SIZE_MAX+1) & 0x700) >> 8); - test_subseq_frag2[2] = ((DATAGRAM_SIZE_MAX+1) & 0xff); - regenerate_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); - restore_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); - test_subseq_frag2[1] = backup[0]; - test_subseq_frag2[2] = backup[1]; + int ret = 0; + unsigned char backup[2]; + unsigned char crc[2]; + memset(output, 0, sizeof(output)); + + printf("send_big_datagram2\n"); + backup[0] = test_first_frag1[1]; + backup[1] = test_first_frag1[2]; + test_first_frag1[1] = 0xC0 + (((DATAGRAM_SIZE_MAX + 1) & 0x700) >> 8); + test_first_frag1[2] = ((DATAGRAM_SIZE_MAX + 1) & 0xff); + regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + restore_crc(test_first_frag1, sizeof(test_first_frag1), crc); + test_first_frag1[1] = backup[0]; + test_first_frag1[2] = backup[1]; + + backup[0] = test_subseq_frag2[1]; + backup[1] = test_subseq_frag2[2]; + test_subseq_frag2[1] = 0xE0 + (((DATAGRAM_SIZE_MAX + 1) & 0x700) >> 8); + test_subseq_frag2[2] = ((DATAGRAM_SIZE_MAX + 1) & 0xff); + regenerate_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); + ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); + restore_crc(test_subseq_frag2, sizeof(test_subseq_frag2), crc); + test_subseq_frag2[1] = backup[0]; + test_subseq_frag2[2] = backup[1]; #if 0 backup[0] = test_subseq_frag3[3]; @@ -1298,14 +1662,14 @@ int send_big_datagram2(void) ret = print_failed_if_nonzero(ret, "test_frag_wait_zero_pending"); fail_if_nonzero(ret); #endif - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - + printf("failed\n"); + return 1; } int check_output_generated(void) /* Verify no output has been generated. @@ -1321,10 +1685,8 @@ int check_output_generated(void) * */ { int i; - for (i=0; i> 8; - test_first_frag1[2] = ((DATAGRAM_SIZE_MAX+1) & 0xff); - regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); - - ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); - - test_first_frag1[1] = backup[0]; - test_first_frag1[2] = backup[1]; - regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - memset(output, 0, sizeof(output)); - fire_rx_timer(); - - ret = check_output_generated(); - ret = print_failed_if_nonzero(ret, "sending segment request after too long first segment"); - fail_if_nonzero(ret); - - memset(output, 0, sizeof(output)); - ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); - ret = memcmp(output, test_frag_wait_zero_pending, sizeof(test_frag_wait_zero_pending)); /* Check if we get fragment wait */ - ret = print_failed_if_nonzero(ret, "correct subsequent without first triggers data"); - fail_if_nonzero(ret); - - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - - printf("passed\n"); - return 0; + int ret = 0; + unsigned char backup[2]; + unsigned char crc[2]; + + printf("send_first_frag_with_big_size\n"); + backup[0] = test_first_frag1[1]; + backup[1] = test_first_frag1[2]; + test_first_frag1[1] + = COMMAND_FIRST_FRAGMENT | ((DATAGRAM_SIZE_MAX + 1) & 0x700) >> 8; + test_first_frag1[2] = ((DATAGRAM_SIZE_MAX + 1) & 0xff); + regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); + + ask_TS_to_receive(test_first_frag1, sizeof(test_first_frag1)); + + test_first_frag1[1] = backup[0]; + test_first_frag1[2] = backup[1]; + regenerate_crc(test_first_frag1, sizeof(test_first_frag1), crc); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + memset(output, 0, sizeof(output)); + fire_rx_timer(); + + ret = check_output_generated(); + ret = print_failed_if_nonzero( + ret, + "sending segment request after too long first segment"); + fail_if_nonzero(ret); + + memset(output, 0, sizeof(output)); + ask_TS_to_receive(test_subseq_frag2, sizeof(test_subseq_frag2)); + ret = memcmp( + output, + test_frag_wait_zero_pending, + sizeof(test_frag_wait_zero_pending)); /* Check if we get fragment wait */ + ret + = print_failed_if_nonzero(ret, + "correct subsequent without first triggers data"); + fail_if_nonzero(ret); + + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; - - + printf("failed\n"); + return 1; } int call_ask_TS_to_receive_with_large_size(void) { - int ret = 0; - - printf("call_ask_TS_to_receive_with_large_size\n"); - ask_TS_to_receive(test_first_frag1, DATAGRAM_SIZE_MAX+1); - ret = print_failed_if_nonzero(!call_with_large_value, "call_ask_TS_to_receive_with_large_size"); - fail_if_nonzero(ret); - ret = print_failed_if_nonzero(!(current_state == ST_IDLE), "current state has to be ST_IDLE..."); - fail_if_nonzero(ret); - printf("passed\n"); - return 0; + int ret = 0; + + printf("call_ask_TS_to_receive_with_large_size\n"); + ask_TS_to_receive(test_first_frag1, DATAGRAM_SIZE_MAX + 1); + ret = print_failed_if_nonzero(!call_with_large_value, + "call_ask_TS_to_receive_with_large_size"); + fail_if_nonzero(ret); + ret = print_failed_if_nonzero(!(current_state == ST_IDLE), + "current state has to be ST_IDLE..."); + fail_if_nonzero(ret); + printf("passed\n"); + return 0; fail: - printf("failed\n"); - return 1; + printf("failed\n"); + return 1; } int main(void) { - memset(&p, 0, sizeof(ts_param_t)); - p.snode = 0xff; - p.dnode = 0xfe; - fail_if_nonzero(simple_test()); - fail_if_nonzero(simple_test_non_uniform_fragment_sizes()); - fail_if_nonzero(simple_test_non_sequential_fragments()); - fail_if_nonzero(dont_send_one_frag()); - fail_if_nonzero(miss_one_frag()); - fail_if_nonzero(miss_one_frag1()); - fail_if_nonzero(test_dont_send_first_frag()); - - fail_if_nonzero(test_frag_wait_fn()); - fail_if_nonzero(test_send_whole_datagram()); - fail_if_nonzero(test_jakob()); - - fail_if_nonzero(test_tie_break()); - fail_if_nonzero(test_two_last_fragments()); - fail_if_nonzero(test_send_frag_compl_from_diff_session()); - fail_if_nonzero(test_abort_transmission()); - fail_if_nonzero(test_fc_timer_after_frag_req()); - fail_if_nonzero(test_fc_timer_after_frag_compl_of_aborted_transmission()); - fail_if_nonzero(test_fc_timer_after_last_frag_twice()); - fail_if_nonzero(test_frag_wait_for_completed_session()); - - fail_if_nonzero(three_node_test()); - fail_if_nonzero(send_big_datagram()); - fail_if_nonzero(send_first_frag_with_big_size()); - fail_if_nonzero(call_ask_TS_to_receive_with_large_size()); - fail_if_nonzero(send_big_datagram2()); - - printf("All test passed\n"); - return 0; + memset(&p, 0, sizeof(ts_param_t)); + p.snode = 0xff; + p.dnode = 0xfe; + fail_if_nonzero(simple_test()); + fail_if_nonzero(simple_test_non_uniform_fragment_sizes()); + fail_if_nonzero(simple_test_non_sequential_fragments()); + fail_if_nonzero(dont_send_one_frag()); + fail_if_nonzero(miss_one_frag()); + fail_if_nonzero(miss_one_frag1()); + fail_if_nonzero(test_dont_send_first_frag()); + + fail_if_nonzero(test_frag_wait_fn()); + fail_if_nonzero(test_send_whole_datagram()); + fail_if_nonzero(test_jakob()); + + fail_if_nonzero(test_tie_break()); + fail_if_nonzero(test_two_last_fragments()); + fail_if_nonzero(test_send_frag_compl_from_diff_session()); + fail_if_nonzero(test_abort_transmission()); + fail_if_nonzero(test_fc_timer_after_frag_req()); + fail_if_nonzero(test_fc_timer_after_frag_compl_of_aborted_transmission()); + fail_if_nonzero(test_fc_timer_after_last_frag_twice()); + fail_if_nonzero(test_frag_wait_for_completed_session()); + + fail_if_nonzero(three_node_test()); + fail_if_nonzero(send_big_datagram()); + fail_if_nonzero(send_first_frag_with_big_size()); + fail_if_nonzero(call_ask_TS_to_receive_with_large_size()); + fail_if_nonzero(send_big_datagram2()); + + printf("All test passed\n"); + return 0; fail: - printf("Above test failed\n"); - return 1; + printf("Above test failed\n"); + return 1; } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/prng_test.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/prng_test.c index edbaa7763..2caa32460 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/prng_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/prng_test.c @@ -4,23 +4,25 @@ * Check that prng has a random value on initalization. * */ -void test_random_init(void) { +void test_random_init(void) +{ uint128_t r1; uint128_t r2; - + prng_init(); r1 = prng_rand(); - + prng_init(); r2 = prng_rand(); - assert(r1!=r2); + assert(r1 != r2); } /** * Check that prng produces random numbers */ -void test_random_rand(void) { +void test_random_rand(void) +{ /*TODO should be use a NIST standard check?*/ } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_aes_cmac.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_aes_cmac.c index 17d3b07ae..fa109b4b7 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_aes_cmac.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_aes_cmac.c @@ -5,152 +5,519 @@ * * Created on: 25/06/2015 * Author: COlsen - */ -#include -#include -#include "unity.h" -#include "../crypto/aes-cmac/aes_cmac.c" - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - -void test_subkey_generation(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; - const uint8_t subkey1[] = {0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde}; - const uint8_t subkey2[] = {0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b}; - uint8_t out1[16]; - uint8_t out2[16]; - - generate_subkey(key, out1, out2); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(subkey1, out1, 16, __LINE__, ""); - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(subkey2, out2, 16, __LINE__, ""); -} - -void test_cmac_ietf_rfc4493_test_vectors_example_1(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; // Valid - - const uint8_t expaected_mac[] = {0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46}; - uint8_t calculated_mac[16]; - aes_cmac_calculate(key, NULL, 0, calculated_mac); - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expaected_mac, calculated_mac, 16, __LINE__, ""); -} - -void test_cmac_ietf_rfc4493_test_vectors_example_2(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; // Valid - - const uint8_t message[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; - uint8_t calculated_mac[16]; - const uint8_t expected_mac[] = {0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c}; - aes_cmac_calculate(key, message, sizeof(message), calculated_mac); - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac, calculated_mac, 16, __LINE__, ""); -} - -void test_cmac_ietf_rfc4493_test_vectors_example_3(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; // Valid - - const uint8_t message[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11}; - uint8_t calculated_mac[16]; - const uint8_t expected_mac[] = {0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27}; - aes_cmac_calculate(key, message, sizeof(message), calculated_mac); - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac, calculated_mac, 16, __LINE__, ""); -} - -void test_cmac_ietf_rfc4493_test_vectors_example_4(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; // Valid - - const uint8_t message[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; - uint8_t calculated_mac[16]; - const uint8_t expected_mac[] = {0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe}; - aes_cmac_calculate(key, message, sizeof(message), calculated_mac); - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac, calculated_mac, 16, __LINE__, ""); -} - -void test_cmac_ietf_rfc4493_test_vectors_example_4_verify(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; // Valid - const uint8_t in[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; - const uint8_t mac[] = {0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe}; - CMAC_VERIFY_T cmac_verify_result; - - cmac_verify_result = aes_cmac_verify(key, in, sizeof(in), mac); - - //printf("%z", sizeof(CMAC_VERIFY_T)); - - UNITY_TEST_ASSERT_EQUAL_UINT8(CMAC_VALID, cmac_verify_result, __LINE__, ""); -} - -void test_cmac_ietf_rfc4493_test_vectors_example_4_verify_negative(void) -{ - const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; // Valid - const uint8_t in[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; - const uint8_t mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - CMAC_VERIFY_T cmac_verify_result; - - cmac_verify_result = aes_cmac_verify(key, in, sizeof(in), mac); - - UNITY_TEST_ASSERT_EQUAL_UINT8(CMAC_INVALID, cmac_verify_result, __LINE__, ""); -} - -void test_cmac_xor_120(void) -{ - const uint8_t value1[] = {0xaa, 0x51, 0x58, 0xb2, 0x58, 0x99, 0x80, 0x0b, 0x61, 0xaa, 0xa0, 0x42, 0x98, 0xf8, 0x38, 0xd0}; - const uint8_t value2[] = {0x0f, 0xe7, 0x09, 0x20, 0x26, 0x45, 0x76, 0xa4, 0xc7, 0xc7, 0xc2, 0xd2, 0x9b, 0x7a, 0x46, 0xb8}; - uint8_t output[16]; - const uint8_t expected[] = {0xa5, 0xb6, 0x51, 0x92, 0x7e, 0xdc, 0xf6, 0xaf, 0xa6, 0x6d, 0x62, 0x90, 0x3, 0x82, 0x7e, 0x68}; - - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(value1), __LINE__, ""); - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(value2), __LINE__, ""); - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(expected), __LINE__, ""); - - xor_128(value1, value2, output); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, output, sizeof(expected), __LINE__, ""); -} - -void test_cmac_leftshift_onebit(void) -{ - const uint8_t value[] = {0xaa, 0x51, 0x58, 0xb2, 0x58, 0x99, 0x80, 0x0b, 0x61, 0xaa, 0xa0, 0x42, 0x98, 0xf8, 0x38, 0xd0}; - uint8_t output[16]; - const uint8_t expected[] = {0x54, 0xa2, 0xb1, 0x64, 0xb1, 0x33, 0x0, 0x16, 0xc3, 0x55, 0x40, 0x85, 0x31, 0xf0, 0x71, 0xa0}; - - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(value), __LINE__, ""); - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(expected), __LINE__, ""); - - leftshift_onebit(value, output); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, output, sizeof(expected), __LINE__, ""); -} - - -void test_cmac_padding(void) -{ - uint8_t output[16]; - const uint8_t value[] = {0x38, 0xd0}; - const uint8_t expected[] = {0x38, 0xd0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(output), __LINE__, ""); - UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(expected), __LINE__, ""); - - padding(value, output, sizeof(value)); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, output, sizeof(expected), __LINE__, ""); -} + */ +#include +#include +#include "unity.h" +#include "../crypto/aes-cmac/aes_cmac.c" + +#ifndef NULL +#define NULL ((void *)0) +#endif + +void test_subkey_generation(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; + const uint8_t subkey1[] = {0xfb, + 0xee, + 0xd6, + 0x18, + 0x35, + 0x71, + 0x33, + 0x66, + 0x7c, + 0x85, + 0xe0, + 0x8f, + 0x72, + 0x36, + 0xa8, + 0xde}; + const uint8_t subkey2[] = {0xf7, + 0xdd, + 0xac, + 0x30, + 0x6a, + 0xe2, + 0x66, + 0xcc, + 0xf9, + 0x0b, + 0xc1, + 0x1e, + 0xe4, + 0x6d, + 0x51, + 0x3b}; + uint8_t out1[16]; + uint8_t out2[16]; + + generate_subkey(key, out1, out2); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(subkey1, out1, 16, __LINE__, ""); + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(subkey2, out2, 16, __LINE__, ""); +} + +void test_cmac_ietf_rfc4493_test_vectors_example_1(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; // Valid + + const uint8_t expaected_mac[] = {0xbb, + 0x1d, + 0x69, + 0x29, + 0xe9, + 0x59, + 0x37, + 0x28, + 0x7f, + 0xa3, + 0x7d, + 0x12, + 0x9b, + 0x75, + 0x67, + 0x46}; + uint8_t calculated_mac[16]; + aes_cmac_calculate(key, NULL, 0, calculated_mac); + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expaected_mac, + calculated_mac, + 16, + __LINE__, + ""); +} + +void test_cmac_ietf_rfc4493_test_vectors_example_2(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; // Valid + + const uint8_t message[] = {0x6b, + 0xc1, + 0xbe, + 0xe2, + 0x2e, + 0x40, + 0x9f, + 0x96, + 0xe9, + 0x3d, + 0x7e, + 0x11, + 0x73, + 0x93, + 0x17, + 0x2a}; + uint8_t calculated_mac[16]; + const uint8_t expected_mac[] = {0x07, + 0x0a, + 0x16, + 0xb4, + 0x6b, + 0x4d, + 0x41, + 0x44, + 0xf7, + 0x9b, + 0xdd, + 0x9d, + 0xd0, + 0x4a, + 0x28, + 0x7c}; + aes_cmac_calculate(key, message, sizeof(message), calculated_mac); + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac, + calculated_mac, + 16, + __LINE__, + ""); +} + +void test_cmac_ietf_rfc4493_test_vectors_example_3(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; // Valid + + const uint8_t message[] + = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, + 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, + 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, + 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11}; + uint8_t calculated_mac[16]; + const uint8_t expected_mac[] = {0xdf, + 0xa6, + 0x67, + 0x47, + 0xde, + 0x9a, + 0xe6, + 0x30, + 0x30, + 0xca, + 0x32, + 0x61, + 0x14, + 0x97, + 0xc8, + 0x27}; + aes_cmac_calculate(key, message, sizeof(message), calculated_mac); + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac, + calculated_mac, + 16, + __LINE__, + ""); +} + +void test_cmac_ietf_rfc4493_test_vectors_example_4(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; // Valid + + const uint8_t message[] + = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; + uint8_t calculated_mac[16]; + const uint8_t expected_mac[] = {0x51, + 0xf0, + 0xbe, + 0xbf, + 0x7e, + 0x3b, + 0x9d, + 0x92, + 0xfc, + 0x49, + 0x74, + 0x17, + 0x79, + 0x36, + 0x3c, + 0xfe}; + aes_cmac_calculate(key, message, sizeof(message), calculated_mac); + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac, + calculated_mac, + 16, + __LINE__, + ""); +} + +void test_cmac_ietf_rfc4493_test_vectors_example_4_verify(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; // Valid + const uint8_t in[] + = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; + const uint8_t mac[] = {0x51, + 0xf0, + 0xbe, + 0xbf, + 0x7e, + 0x3b, + 0x9d, + 0x92, + 0xfc, + 0x49, + 0x74, + 0x17, + 0x79, + 0x36, + 0x3c, + 0xfe}; + CMAC_VERIFY_T cmac_verify_result; + + cmac_verify_result = aes_cmac_verify(key, in, sizeof(in), mac); + + //printf("%z", sizeof(CMAC_VERIFY_T)); + + UNITY_TEST_ASSERT_EQUAL_UINT8(CMAC_VALID, cmac_verify_result, __LINE__, ""); +} + +void test_cmac_ietf_rfc4493_test_vectors_example_4_verify_negative(void) +{ + const uint8_t key[] = {0x2b, + 0x7e, + 0x15, + 0x16, + 0x28, + 0xae, + 0xd2, + 0xa6, + 0xab, + 0xf7, + 0x15, + 0x88, + 0x09, + 0xcf, + 0x4f, + 0x3c}; // Valid + const uint8_t in[] + = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; + const uint8_t mac[] = {0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; + CMAC_VERIFY_T cmac_verify_result; + + cmac_verify_result = aes_cmac_verify(key, in, sizeof(in), mac); + + UNITY_TEST_ASSERT_EQUAL_UINT8(CMAC_INVALID, cmac_verify_result, __LINE__, ""); +} + +void test_cmac_xor_120(void) +{ + const uint8_t value1[] = {0xaa, + 0x51, + 0x58, + 0xb2, + 0x58, + 0x99, + 0x80, + 0x0b, + 0x61, + 0xaa, + 0xa0, + 0x42, + 0x98, + 0xf8, + 0x38, + 0xd0}; + const uint8_t value2[] = {0x0f, + 0xe7, + 0x09, + 0x20, + 0x26, + 0x45, + 0x76, + 0xa4, + 0xc7, + 0xc7, + 0xc2, + 0xd2, + 0x9b, + 0x7a, + 0x46, + 0xb8}; + uint8_t output[16]; + const uint8_t expected[] = {0xa5, + 0xb6, + 0x51, + 0x92, + 0x7e, + 0xdc, + 0xf6, + 0xaf, + 0xa6, + 0x6d, + 0x62, + 0x90, + 0x3, + 0x82, + 0x7e, + 0x68}; + + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(value1), __LINE__, ""); + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(value2), __LINE__, ""); + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(expected), __LINE__, ""); + + xor_128(value1, value2, output); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, + output, + sizeof(expected), + __LINE__, + ""); +} + +void test_cmac_leftshift_onebit(void) +{ + const uint8_t value[] = {0xaa, + 0x51, + 0x58, + 0xb2, + 0x58, + 0x99, + 0x80, + 0x0b, + 0x61, + 0xaa, + 0xa0, + 0x42, + 0x98, + 0xf8, + 0x38, + 0xd0}; + uint8_t output[16]; + const uint8_t expected[] = {0x54, + 0xa2, + 0xb1, + 0x64, + 0xb1, + 0x33, + 0x0, + 0x16, + 0xc3, + 0x55, + 0x40, + 0x85, + 0x31, + 0xf0, + 0x71, + 0xa0}; + + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(value), __LINE__, ""); + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(expected), __LINE__, ""); + + leftshift_onebit(value, output); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, + output, + sizeof(expected), + __LINE__, + ""); +} + +void test_cmac_padding(void) +{ + uint8_t output[16]; + const uint8_t value[] = {0x38, 0xd0}; + const uint8_t expected[] = {0x38, + 0xd0, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; + + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(output), __LINE__, ""); + UNITY_TEST_ASSERT_EQUAL_UINT8(16, sizeof(expected), __LINE__, ""); + + padding(value, output, sizeof(value)); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, + output, + sizeof(expected), + __LINE__, + ""); +} diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ccm.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ccm.c index 7234fec8e..558ad222f 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ccm.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ccm.c @@ -9,186 +9,285 @@ void test_verify_handful_payload_lengths(void) { - uint8_t key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t nonce[15-7] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17}; - uint32_t aad_len = 16; - uint8_t aad[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f} ; - uint8_t *plaintext; - uint16_t plaintext_len; - uint8_t *ciphertext; - uint32_t ciphertext_len; - uint8_t *text_to_encrypt; - uint8_t *text_to_encrypt_bkup; - uint16_t text_to_encrypt_len = 16; - int i, j; - int ret; - int lengths[6] = {0, 10, 22, 54, 1279, 1280}; // Makes no sense to test for length 0 since the compare function will compare zero characters. - //int lengths[6] = {1, 10, 22, 54, 1279, 1280}; - uint8_t q; - uint8_t n; - uint8_t t; - set_q_n_t(7, 8, 6); - get_q_n_t(&q, &n, &t); - - for(i = 0; i < 6; i++) { - plaintext_len = text_to_encrypt_len = lengths[i]; - ciphertext_len = text_to_encrypt_len + t; - ciphertext = malloc(ciphertext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - //return; - //goto out3; - } - text_to_encrypt = malloc(text_to_encrypt_len); - if (text_to_encrypt == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out2; - } - text_to_encrypt_bkup = malloc(text_to_encrypt_len); - if (text_to_encrypt_bkup == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out1; - } - - plaintext = malloc(plaintext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out4; - } - for (j = 0; j < lengths[i]; j++) { - text_to_encrypt[j] = j; - text_to_encrypt_bkup[j] = j; - } - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - if (ret == 0) { - printf("verify_handful_payload_lengths TEST FAILED in encryption\n"); - goto out; - } else { - ciphertext_len = ret; - } + uint8_t key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t nonce[15 - 7] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; + uint32_t aad_len = 16; + uint8_t aad[16] = {0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f}; + uint8_t *plaintext; + uint16_t plaintext_len; + uint8_t *ciphertext; + uint32_t ciphertext_len; + uint8_t *text_to_encrypt; + uint8_t *text_to_encrypt_bkup; + uint16_t text_to_encrypt_len = 16; + int i, j; + int ret; + int lengths[6] = { + 0, + 10, + 22, + 54, + 1279, + 1280}; // Makes no sense to test for length 0 since the compare function will compare zero characters. + //int lengths[6] = {1, 10, 22, 54, 1279, 1280}; + uint8_t q; + uint8_t n; + uint8_t t; + set_q_n_t(7, 8, 6); + get_q_n_t(&q, &n, &t); + + for (i = 0; i < 6; i++) { + plaintext_len = text_to_encrypt_len = lengths[i]; + ciphertext_len = text_to_encrypt_len + t; + ciphertext = malloc(ciphertext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + //return; + //goto out3; + } + text_to_encrypt = malloc(text_to_encrypt_len); + if (text_to_encrypt == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out2; + } + text_to_encrypt_bkup = malloc(text_to_encrypt_len); + if (text_to_encrypt_bkup == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out1; + } - ret = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - if ((ret == 0) && (lengths[i] != 0)) { - printf("verify_handlful_payload_lengths TEST FAILED in decryption\n"); - ret = 1; - goto out; - } else { - plaintext_len = ret; - } + plaintext = malloc(plaintext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out4; + } + for (j = 0; j < lengths[i]; j++) { + text_to_encrypt[j] = j; + text_to_encrypt_bkup[j] = j; + } + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + if (ret == 0) { + printf("verify_handful_payload_lengths TEST FAILED in encryption\n"); + goto out; + } else { + ciphertext_len = ret; + } - //UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, ciphertext, plaintext_len, __LINE__, ""); + ret = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + if ((ret == 0) && (lengths[i] != 0)) { + printf("verify_handlful_payload_lengths TEST FAILED in decryption\n"); + ret = 1; + goto out; + } else { + plaintext_len = ret; + } - if(memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len)) { - printf("verify_handful_payload_lengths TEST FAILED at %dth iteration\n", i); - ret = 1; - goto out; - } - printf("verify_handful_payload_lengths TEST PASSSED for plaintext length: %d\n", lengths[i]); + //UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, ciphertext, plaintext_len, __LINE__, ""); - free(plaintext); - free(text_to_encrypt); - free(text_to_encrypt_bkup); - free(ciphertext); + if (memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len)) { + printf("verify_handful_payload_lengths TEST FAILED at %dth iteration\n", + i); + ret = 1; + goto out; } - printf("verify_handful_payload_lengths TEST PASSSED\n"); - return; -out: + printf( + "verify_handful_payload_lengths TEST PASSSED for plaintext length: %d\n", + lengths[i]); + free(plaintext); -out4: + free(text_to_encrypt); free(text_to_encrypt_bkup); + free(ciphertext); + } + printf("verify_handful_payload_lengths TEST PASSSED\n"); + return; +out: + free(plaintext); +out4: + free(text_to_encrypt_bkup); out1: - free(text_to_encrypt); + free(text_to_encrypt); out2: - free(ciphertext); + free(ciphertext); - return; + return; } void ignore_test_verify_all_payload_lengths(void) { - uint8_t key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t nonce[15-7] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17}; - uint32_t aad_len = 16; - uint8_t aad[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f} ; - uint8_t *plaintext; - uint16_t plaintext_len; - uint8_t *ciphertext; - uint32_t ciphertext_len; - uint8_t *text_to_encrypt; - uint8_t *text_to_encrypt_bkup; - uint16_t text_to_encrypt_len = 16; - int i, j; - int ret; - - uint8_t q; - uint8_t n; - uint8_t t; - set_q_n_t(7, 8, 6); - get_q_n_t(&q, &n, &t); - /* + uint8_t key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t nonce[15 - 7] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; + uint32_t aad_len = 16; + uint8_t aad[16] = {0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f}; + uint8_t *plaintext; + uint16_t plaintext_len; + uint8_t *ciphertext; + uint32_t ciphertext_len; + uint8_t *text_to_encrypt; + uint8_t *text_to_encrypt_bkup; + uint16_t text_to_encrypt_len = 16; + int i, j; + int ret; + + uint8_t q; + uint8_t n; + uint8_t t; + set_q_n_t(7, 8, 6); + get_q_n_t(&q, &n, &t); + /* q = 7; t = 6; n = 8; */ - for(i = 1; i < 0xffff; i++) { - plaintext_len = text_to_encrypt_len = i; - ciphertext_len = text_to_encrypt_len + t; - ciphertext = malloc(ciphertext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out3; - } - text_to_encrypt = malloc(text_to_encrypt_len); - if (text_to_encrypt == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out2; - } - text_to_encrypt_bkup = malloc(text_to_encrypt_len); - if (text_to_encrypt_bkup == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out2; - } + for (i = 1; i < 0xffff; i++) { + plaintext_len = text_to_encrypt_len = i; + ciphertext_len = text_to_encrypt_len + t; + ciphertext = malloc(ciphertext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out3; + } + text_to_encrypt = malloc(text_to_encrypt_len); + if (text_to_encrypt == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out2; + } + text_to_encrypt_bkup = malloc(text_to_encrypt_len); + if (text_to_encrypt_bkup == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out2; + } - plaintext = malloc(plaintext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto out1; - } - for (j = 0; j < i; j++) { - text_to_encrypt[j] = j; - text_to_encrypt_bkup[j] = j; - } - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - if (ret == 0) { - printf("verify_all_payload_lengths TEST FAILED in encryption\n"); - goto out; - } else { - ciphertext_len = ret; - } + plaintext = malloc(plaintext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto out1; + } + for (j = 0; j < i; j++) { + text_to_encrypt[j] = j; + text_to_encrypt_bkup[j] = j; + } + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + if (ret == 0) { + printf("verify_all_payload_lengths TEST FAILED in encryption\n"); + goto out; + } else { + ciphertext_len = ret; + } - ret = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - if (ret == 0) { - printf("verify_all_payload_lengths TEST FAILED in decryption\n"); - ret = 1; - goto out; - } else { - plaintext_len = ret; - } + ret = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + if (ret == 0) { + printf("verify_all_payload_lengths TEST FAILED in decryption\n"); + ret = 1; + goto out; + } else { + plaintext_len = ret; + } - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, ciphertext, plaintext_len, __LINE__, ""); + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, + ciphertext, + plaintext_len, + __LINE__, + ""); - /* + /* if(memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len)) { printf("verify_all_payload_lengths TEST FAILED at %dth iteration\n", i); ret = 1; @@ -196,149 +295,292 @@ void ignore_test_verify_all_payload_lengths(void) } printf("verify_all_payload_lengths TEST PASSSED for plaintext length: %d\n", i); */ - free(plaintext); - free(text_to_encrypt); - free(text_to_encrypt_bkup); - free(ciphertext); - } - printf("verify_all_payload_lengths TEST PASSSED\n"); - return; -out: free(plaintext); -out1: free(text_to_encrypt); -out2: + free(text_to_encrypt_bkup); free(ciphertext); + } + printf("verify_all_payload_lengths TEST PASSSED\n"); + return; +out: + free(plaintext); +out1: + free(text_to_encrypt); +out2: + free(ciphertext); out3: - return; + return; } void test_example1(void) { - uint8_t key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - /* 7 is valie of q below */ - uint8_t nonce[15-7] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17}; - uint32_t aad_len = 16; - uint8_t aad[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f} ; - uint8_t text_to_encrypt[16]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}; - const uint8_t text_to_encrypt_bkup[16]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}; + uint8_t key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + /* 7 is valie of q below */ + uint8_t nonce[15 - 7] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; + uint32_t aad_len = 16; + uint8_t aad[16] = {0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f}; + uint8_t text_to_encrypt[16] = {0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f}; + const uint8_t text_to_encrypt_bkup[16] = {0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f}; #define TEXT_TO_ENCRYPT_LEN_DEF (16) - uint16_t text_to_encrypt_len = TEXT_TO_ENCRYPT_LEN_DEF; - uint16_t plaintext_len = 16; -#define T_DEF (6) + uint16_t text_to_encrypt_len = TEXT_TO_ENCRYPT_LEN_DEF; + uint16_t plaintext_len = 16; +#define T_DEF (6) #define CIPHERTEXT_LEN_DEF (TEXT_TO_ENCRYPT_LEN_DEF + T_DEF) - //uint8_t *ciphertext; - uint8_t ciphertext[CIPHERTEXT_LEN_DEF]; - uint32_t ciphertext_len = CIPHERTEXT_LEN_DEF; - int ret; - uint8_t nist_cipher_and_auth_tag[16 + 6] = {0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd}; - uint8_t q; - uint8_t n; - uint8_t t; - - set_q_n_t(7, 8, T_DEF); - get_q_n_t(&q, &n, &t); - - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - printf("Refer to http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf page 17 Example 2\n"); - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - - UNITY_TEST_ASSERT((0 != ret), __LINE__, "Could not encrypt :("); - - ciphertext_len = ret; - - UNITY_TEST_ASSERT_EQUAL_UINT32(sizeof(nist_cipher_and_auth_tag), ciphertext_len, __LINE__, "Ciphertext length does not match with NIST document."); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(nist_cipher_and_auth_tag, ciphertext, ciphertext_len, __LINE__, "Ciphertext does not match with NIST document."); - - ret = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - - UNITY_TEST_ASSERT((0 != ret), __LINE__, "Could not decrypt :("); - - plaintext_len = ret; - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, ciphertext, plaintext_len, __LINE__, ""); + //uint8_t *ciphertext; + uint8_t ciphertext[CIPHERTEXT_LEN_DEF]; + uint32_t ciphertext_len = CIPHERTEXT_LEN_DEF; + int ret; + uint8_t nist_cipher_and_auth_tag[16 + 6] + = {0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, 0x08, 0x1a, 0x77, + 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd}; + uint8_t q; + uint8_t n; + uint8_t t; + + set_q_n_t(7, 8, T_DEF); + get_q_n_t(&q, &n, &t); + + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + printf("Refer to " + "http://csrc.nist.gov/publications/nistpubs/800-38C/" + "SP800-38C_updated-July20_2007.pdf page 17 Example 2\n"); + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + + UNITY_TEST_ASSERT((0 != ret), __LINE__, "Could not encrypt :("); + + ciphertext_len = ret; + + UNITY_TEST_ASSERT_EQUAL_UINT32( + sizeof(nist_cipher_and_auth_tag), + ciphertext_len, + __LINE__, + "Ciphertext length does not match with NIST document."); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY( + nist_cipher_and_auth_tag, + ciphertext, + ciphertext_len, + __LINE__, + "Ciphertext does not match with NIST document."); + + ret = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + + UNITY_TEST_ASSERT((0 != ret), __LINE__, "Could not decrypt :("); + + plaintext_len = ret; + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, + ciphertext, + plaintext_len, + __LINE__, + ""); } void test_big_aad_example(void) { - uint8_t key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t nonce[13] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c}; - uint8_t *aad; - uint8_t text_to_encrypt[32]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; - uint8_t text_to_encrypt_bkup[32]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; - uint16_t text_to_encrypt_len = 32; - uint16_t plaintext_len = 32; - int i, j = 0; - int aad_len = 524288 / 8; - uint8_t *ciphertext; - uint32_t ciphertext_len; - int ret; - uint8_t nist_cipher_and_auth_tag[32 + 14] = {0x69,0x91,0x5d,0xad,0x1e,0x84,0xc6,0x37,0x6a,0x68,0xc2,0x96,0x7e,0x4d,0xab,0x61,0x5a,0xe0, - 0xfd,0x1f,0xae,0xc4,0x4c,0xc4,0x84,0x82,0x85,0x29,0x46,0x3c,0xcf,0x72,0xb4,0xac,0x6b,0xec,0x93,0xe8,0x59,0x8e,0x7f,0x0d,0xad,0xbc,0xea,0x5b}; - - uint8_t q; - uint8_t n; - uint8_t t; - set_q_n_t(2, 13, 14); - get_q_n_t(&q, &n, &t); - /* + uint8_t key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t nonce[13] = {0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c}; + uint8_t *aad; + uint8_t text_to_encrypt[32] + = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + uint8_t text_to_encrypt_bkup[32] + = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + uint16_t text_to_encrypt_len = 32; + uint16_t plaintext_len = 32; + int i, j = 0; + int aad_len = 524288 / 8; + uint8_t *ciphertext; + uint32_t ciphertext_len; + int ret; + uint8_t nist_cipher_and_auth_tag[32 + 14] + = {0x69, 0x91, 0x5d, 0xad, 0x1e, 0x84, 0xc6, 0x37, 0x6a, 0x68, 0xc2, 0x96, + 0x7e, 0x4d, 0xab, 0x61, 0x5a, 0xe0, 0xfd, 0x1f, 0xae, 0xc4, 0x4c, 0xc4, + 0x84, 0x82, 0x85, 0x29, 0x46, 0x3c, 0xcf, 0x72, 0xb4, 0xac, 0x6b, 0xec, + 0x93, 0xe8, 0x59, 0x8e, 0x7f, 0x0d, 0xad, 0xbc, 0xea, 0x5b}; + + uint8_t q; + uint8_t n; + uint8_t t; + set_q_n_t(2, 13, 14); + get_q_n_t(&q, &n, &t); + /* q = 2; t = 14; n = 13; */ - /*the for loop below writes 1 byte more than aad_len, so just to be secure alloc 2 more bytes*/ - aad = malloc(aad_len + 2); + /*the for loop below writes 1 byte more than aad_len, so just to be secure alloc 2 more bytes*/ + aad = malloc(aad_len + 2); - UNITY_TEST_ASSERT_NOT_NULL(aad, __LINE__, "malloc failed for aad."); + UNITY_TEST_ASSERT_NOT_NULL(aad, __LINE__, "malloc failed for aad."); #ifdef NOT_USED - if (aad == NULL) { - printf("malloc failed for aad\n"); - return; - } + if (aad == NULL) { + printf("malloc failed for aad\n"); + return; + } #endif - ciphertext_len = text_to_encrypt_len + t; - ciphertext = malloc(ciphertext_len); - - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto free_aad; - } - - for (j = 0; j <= aad_len; j++) { - i = j; - if (i > 0xff) - i = i % 0x100; - aad[j] = i; - } - - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - if (ret == 0) { - printf("EXAMPLE4 TEST FAILED in encryption\n"); - goto out; - } else { - ciphertext_len = ret; - } - - if(memcmp(ciphertext, nist_cipher_and_auth_tag, ciphertext_len) != 0) { - printf("EXAMPLE4 ENCRYPTION TEST FAILED\n"); - ret = 1; - goto out; - } - ret = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - if (ret == 0) { - printf("test_big_aad_example TEST FAILED in decryption\n"); - ret = 1; - goto out; - } - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, ciphertext, plaintext_len, __LINE__, ""); - - /* + ciphertext_len = text_to_encrypt_len + t; + ciphertext = malloc(ciphertext_len); + + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto free_aad; + } + + for (j = 0; j <= aad_len; j++) { + i = j; + if (i > 0xff) + i = i % 0x100; + aad[j] = i; + } + + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + if (ret == 0) { + printf("EXAMPLE4 TEST FAILED in encryption\n"); + goto out; + } else { + ciphertext_len = ret; + } + + if (memcmp(ciphertext, nist_cipher_and_auth_tag, ciphertext_len) != 0) { + printf("EXAMPLE4 ENCRYPTION TEST FAILED\n"); + ret = 1; + goto out; + } + ret = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + if (ret == 0) { + printf("test_big_aad_example TEST FAILED in decryption\n"); + ret = 1; + goto out; + } + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, + ciphertext, + plaintext_len, + __LINE__, + ""); + + /* if(memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len)) { printf("test_big_aad_example ENCRYPTION test FAILED\n"); ret = 1; @@ -346,79 +588,129 @@ void test_big_aad_example(void) } printf("test_big_aad_example test PASSSED\n"); */ - ret = 0; + ret = 0; out: - free(ciphertext); + free(ciphertext); free_aad: - free(aad); - return; + free(aad); + return; } void test_handful_aad_lengths(void) { - uint8_t key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t nonce[13] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c}; - uint8_t *aad; - uint8_t text_to_encrypt[32]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; - uint8_t text_to_encrypt_bkup[32]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; - uint16_t text_to_encrypt_len = 32; - uint16_t plaintext_len = 32; - int i, j; - int aad_len; - uint8_t *ciphertext; - uint32_t ciphertext_len; - int ret; - - int lengths[] = {0, 1, 10, 11, 12, 21, 22, 300}; - - uint8_t q; - uint8_t n; - uint8_t t; - set_q_n_t(2, 13, 8); - get_q_n_t(&q, &n, &t); - /* + uint8_t key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t nonce[13] = {0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c}; + uint8_t *aad; + uint8_t text_to_encrypt[32] + = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + uint8_t text_to_encrypt_bkup[32] + = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + uint16_t text_to_encrypt_len = 32; + uint16_t plaintext_len = 32; + int i, j; + int aad_len; + uint8_t *ciphertext; + uint32_t ciphertext_len; + int ret; + + int lengths[] = {0, 1, 10, 11, 12, 21, 22, 300}; + + uint8_t q; + uint8_t n; + uint8_t t; + set_q_n_t(2, 13, 8); + get_q_n_t(&q, &n, &t); + /* q = 2; t = 8; n = 13; */ - for(i = 0; i < sizeof(lengths)/sizeof(*lengths); i++) { - aad_len = lengths[i]; - aad = malloc(aad_len); - for (j = 0; j < lengths[i]; j++) { - aad[j] = j; - } - if (aad == NULL) { - printf("malloc failed for aad\n"); - return; - } - ciphertext_len = text_to_encrypt_len + t; - ciphertext = malloc(ciphertext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto free_aad; - } + for (i = 0; i < sizeof(lengths) / sizeof(*lengths); i++) { + aad_len = lengths[i]; + aad = malloc(aad_len); + for (j = 0; j < lengths[i]; j++) { + aad[j] = j; + } + if (aad == NULL) { + printf("malloc failed for aad\n"); + return; + } + ciphertext_len = text_to_encrypt_len + t; + ciphertext = malloc(ciphertext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto free_aad; + } - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - if (ret == 0) { - printf("test_all_aad_lengths TEST FAILED in encryption\n"); - goto out; - } else { - ciphertext_len = ret; - } + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + if (ret == 0) { + printf("test_all_aad_lengths TEST FAILED in encryption\n"); + goto out; + } else { + ciphertext_len = ret; + } - plaintext_len = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - if (plaintext_len == 0) { - printf("test_all_aad_lengths TEST FAILED in decryption\n"); - ret = 1; - goto out; - } - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, ciphertext, plaintext_len, __LINE__, ""); + plaintext_len = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + if (plaintext_len == 0) { + printf("test_all_aad_lengths TEST FAILED in decryption\n"); + ret = 1; + goto out; + } + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(text_to_encrypt_bkup, + ciphertext, + plaintext_len, + __LINE__, + ""); - /* + /* if(memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len) != 0) { printf("test_all_aad_lengths ENCRYPTION test FAILED\n"); ret = 1; @@ -427,191 +719,286 @@ void test_handful_aad_lengths(void) memcpy(text_to_encrypt, text_to_encrypt_bkup, text_to_encrypt_len); printf("test_all_aad_lengths test PASSSED for aad length: %d\n", lengths[i]); */ - free(aad); - free(ciphertext); - } - return; -out: + free(aad); free(ciphertext); + } + return; +out: + free(ciphertext); free_aad: - free(aad); - return; + free(aad); + return; } #ifdef NOT_USED static int test_all_aad_lengths(void) { - uint8_t key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t nonce[13] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c}; - uint8_t *aad; - uint8_t text_to_encrypt[32]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; - uint8_t text_to_encrypt_bkup[32]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; - uint16_t text_to_encrypt_len = 32; - uint16_t plaintext_len = 32; - int i, j; - int aad_len; - uint8_t *ciphertext; - uint32_t ciphertext_len; - int ret; - - uint8_t q; - uint8_t n; - uint8_t t; - set_q_n_t(2, 13, 8); - get_q_n_t(&q, &n, &t); - - /* + uint8_t key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t nonce[13] = {0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c}; + uint8_t *aad; + uint8_t text_to_encrypt[32] + = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + uint8_t text_to_encrypt_bkup[32] + = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + uint16_t text_to_encrypt_len = 32; + uint16_t plaintext_len = 32; + int i, j; + int aad_len; + uint8_t *ciphertext; + uint32_t ciphertext_len; + int ret; + + uint8_t q; + uint8_t n; + uint8_t t; + set_q_n_t(2, 13, 8); + get_q_n_t(&q, &n, &t); + + /* q = 2; t = 8; n = 13; */ - for(i = 0; i < 0xffff; i++) { - aad_len = i; - aad = malloc(aad_len); - for (j = 0; j < i; j++) { - aad[j] = j; - } - if (aad == NULL) { - printf("malloc failed for aad\n"); - return 1; - } - ciphertext_len = text_to_encrypt_len + t; - ciphertext = malloc(ciphertext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - ret = 1; - goto free_aad; - } + for (i = 0; i < 0xffff; i++) { + aad_len = i; + aad = malloc(aad_len); + for (j = 0; j < i; j++) { + aad[j] = j; + } + if (aad == NULL) { + printf("malloc failed for aad\n"); + return 1; + } + ciphertext_len = text_to_encrypt_len + t; + ciphertext = malloc(ciphertext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + ret = 1; + goto free_aad; + } - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - if (ret == 0) { - printf("test_all_aad_lengths TEST FAILED in encryption\n"); - goto out; - } else { - ciphertext_len = ret; - } + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + if (ret == 0) { + printf("test_all_aad_lengths TEST FAILED in encryption\n"); + goto out; + } else { + ciphertext_len = ret; + } - plaintext_len = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - if (plaintext_len == 0) { - printf("test_all_aad_lengths TEST FAILED in decryption\n"); - ret = 1; - goto out; - } - - if(memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len) != 0) { - printf("test_all_aad_lengths ENCRYPTION test FAILED\n"); - ret = 1; - goto out; - } - memcpy(text_to_encrypt, text_to_encrypt_bkup, text_to_encrypt_len); - printf("test_all_aad_lengths test PASSSED for aad length: %d\n", i); - free(ciphertext); - free(aad); + plaintext_len = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + if (plaintext_len == 0) { + printf("test_all_aad_lengths TEST FAILED in decryption\n"); + ret = 1; + goto out; } - return 0; -out: + + if (memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len) != 0) { + printf("test_all_aad_lengths ENCRYPTION test FAILED\n"); + ret = 1; + goto out; + } + memcpy(text_to_encrypt, text_to_encrypt_bkup, text_to_encrypt_len); + printf("test_all_aad_lengths test PASSSED for aad length: %d\n", i); free(ciphertext); -free_aad: free(aad); - return ret; + } + return 0; +out: + free(ciphertext); +free_aad: + free(aad); + return ret; } static int test_aad_len_smaller_than_12(void) { - uint8_t key[16]= {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; - uint8_t nonce[16] = {0x8E,0x14,0xD0,0x87,0xEA,0xF6,0x32,0xE1,0xDF,0x8A,0x36,0xC5,0x40,0x25,0xF4,0xB8}; - uint32_t aad_len = 8; - uint8_t aad[8] = {0x02, 0x01, 0xaa, 0xbb, 0xcc, 0xdd, 0x02, 0x00}; - uint8_t text_to_encrypt[24]={0x48,0x65,0x6c,0x6c,0x6f,0x57,0x6f,0x72,0x6c,0x64, 0x20, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x00}; - uint16_t text_to_encrypt_len = 24; - uint16_t plaintext_len = 8; - uint8_t *ciphertext; - uint32_t ciphertext_len; - uint8_t text_to_encrypt_bkup[24]; - int ret; - - uint8_t q; - uint8_t n; - uint8_t t; - set_q_n_t(2, 13, 8); - get_q_n_t(&q, &n, &t); - - /* + uint8_t key[16] = {0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0}; + uint8_t nonce[16] = {0x8E, + 0x14, + 0xD0, + 0x87, + 0xEA, + 0xF6, + 0x32, + 0xE1, + 0xDF, + 0x8A, + 0x36, + 0xC5, + 0x40, + 0x25, + 0xF4, + 0xB8}; + uint32_t aad_len = 8; + uint8_t aad[8] = {0x02, 0x01, 0xaa, 0xbb, 0xcc, 0xdd, 0x02, 0x00}; + uint8_t text_to_encrypt[24] + = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x53, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x00}; + uint16_t text_to_encrypt_len = 24; + uint16_t plaintext_len = 8; + uint8_t *ciphertext; + uint32_t ciphertext_len; + uint8_t text_to_encrypt_bkup[24]; + int ret; + + uint8_t q; + uint8_t n; + uint8_t t; + set_q_n_t(2, 13, 8); + get_q_n_t(&q, &n, &t); + + /* q = 2; t = 8; n = 13; */ - ciphertext_len = text_to_encrypt_len + t; - ciphertext = malloc(ciphertext_len); - if (ciphertext == NULL) { - printf("malloc failed for ciphertext\n"); - return 1; - } - - memcpy(ciphertext, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - memcpy(text_to_encrypt_bkup, text_to_encrypt, text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" - ret = CCM_encrypt_and_auth(key, nonce, aad, aad_len, ciphertext, text_to_encrypt_len); - if (ret == 0) { - printf("test_aad_len_smaller_than_12 TEST FAILED in encryption\n"); - goto out; - } else { - ciphertext_len = ret; - } - - ret = CCM_decrypt_and_auth(key, nonce, aad, aad_len, ciphertext, ciphertext_len); - if (ret == 0) { - printf("test_aad_len_smaller_than_12 TEST FAILED in decryption\n"); - ret = 1; - goto out; - } else { - plaintext_len = ret; - } - - if(memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len) != 0) { - printf("test_aad_len_smaller_than_12 ENCRYPTION TEST FAILED\n"); - ret = 1; - goto out; - } - printf("test_aad_len_smaller_than_12 TEST PASSSED\n"); - ret = 0; + ciphertext_len = text_to_encrypt_len + t; + ciphertext = malloc(ciphertext_len); + if (ciphertext == NULL) { + printf("malloc failed for ciphertext\n"); + return 1; + } + + memcpy( + ciphertext, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + memcpy( + text_to_encrypt_bkup, + text_to_encrypt, + text_to_encrypt_len); //in-place encryption, so pass ciphertext which is of size "text_to_encrypt_len + t" + ret = CCM_encrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + text_to_encrypt_len); + if (ret == 0) { + printf("test_aad_len_smaller_than_12 TEST FAILED in encryption\n"); + goto out; + } else { + ciphertext_len = ret; + } + + ret = CCM_decrypt_and_auth(key, + nonce, + aad, + aad_len, + ciphertext, + ciphertext_len); + if (ret == 0) { + printf("test_aad_len_smaller_than_12 TEST FAILED in decryption\n"); + ret = 1; + goto out; + } else { + plaintext_len = ret; + } + + if (memcmp(ciphertext, text_to_encrypt_bkup, plaintext_len) != 0) { + printf("test_aad_len_smaller_than_12 ENCRYPTION TEST FAILED\n"); + ret = 1; + goto out; + } + printf("test_aad_len_smaller_than_12 TEST PASSSED\n"); + ret = 0; out: - free(ciphertext); - return ret; + free(ciphertext); + return ret; } int main(int argc, char *argv[]) { - if ((argc == 2) && (strncmp(argv[1], "-h", 2) == 0)) { - printf("./test_ccm -s for verifying all payload lengths and aad lengths and standard tests\n"); - printf("./test_ccm for standard tests\n"); - printf("./test_ccm -h for help\n"); - return 0; - } else if ((argc == 2) && (strncmp(argv[1], "-s", 2) == 0)) { - /* Following test takes almost an hour */ - if(test_verify_all_payload_lengths()) - return 1; - - if(test_all_aad_lengths()) - return 1; - } + if ((argc == 2) && (strncmp(argv[1], "-h", 2) == 0)) { + printf("./test_ccm -s for verifying all payload lengths and aad lengths " + "and standard tests\n"); + printf("./test_ccm for standard tests\n"); + printf("./test_ccm -h for help\n"); + return 0; + } else if ((argc == 2) && (strncmp(argv[1], "-s", 2) == 0)) { + /* Following test takes almost an hour */ + if (test_verify_all_payload_lengths()) + return 1; - if(test_example1()) - return 1; + if (test_all_aad_lengths()) + return 1; + } - if(test_big_aad_example()) - return 1; + if (test_example1()) + return 1; - if(test_verify_handful_payload_lengths()) - return 1; + if (test_big_aad_example()) + return 1; - if(test_handful_aad_lengths()) - return 1; + if (test_verify_handful_payload_lengths()) + return 1; - if (test_aad_len_smaller_than_12()) - return 1; + if (test_handful_aad_lengths()) + return 1; - return 0; + if (test_aad_len_smaller_than_12()) + return 1; + + return 0; } #endif /* NOT_USED */ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ctr_dbrg.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ctr_dbrg.c index 78b672b94..7fc187546 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ctr_dbrg.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_ctr_dbrg.c @@ -27,12 +27,12 @@ uint8_t dbgCTRDRBG = 0; typedef struct { - uint8_t df; /* Use DF or not */ - const char* entropy; /* Entropy input */ - const char* nonce; /* Nonce */ - const char* personal; /* Personalization string */ - const char* reseed; /* Reseed input */ - const char* rand; /* Output */ + uint8_t df; /* Use DF or not */ + const char *entropy; /* Entropy input */ + const char *nonce; /* Nonce */ + const char *personal; /* Personalization string */ + const char *reseed; /* Reseed input */ + const char *rand; /* Output */ } TEST_CASE; //static CTR_DRBG_CTX drbgctx; @@ -44,126 +44,141 @@ typedef struct { * AES-128 use df, no predication resisitance, no reseed */ static TEST_CASE const testVector[] = { - { - 0, - "cee23de86a69c7ef57f6e1e12bd16e35e51624226fa19597bf93ec476a44b0f2", - "", - "a2ef16f226ea324f23abd59d5e3c660561c25e73638fe21c87566e86a9e04c3e", - "", - "2a76d71b329f449c98dc08fff1d205a2fbd9e4ade120c7611c225c984eac8531288dd3049f3dc3bb3671501ab8fbf9ad49c86cce307653bd8caf29cb0cf07764", - }, - { - 0, - "b09eb4a82a39066ec945bb7c6aef6a0682a62c3e674bd900297d4271a5f25b49", - "", - "a3b768adcfe76d61c972d900da8dffeeb2a42e740247aa719ed1c924d2d10bd4", - "", - "5a1c26803f3ffd4daf32042fdcc32c3812bb5ef13bc208cef82ea047d2890a6f5dcecf32bcc32a2585775ac5e1ffaa8de00664c54fe00a7674b985619e953c3a", - }, - { - 0, - "0bbc898f8daf3f12fc009c846fe2cea22f683a432eea297257312d5a44bac131", - "", - "8d34be9d8110b84b02a60508deae773c1a808f4e2a0ec81747ae2ec923fe99a9", - "", - "da49e24a6cb1d9e51b98ea6103627d9ad035770b7bdc760606e2b5f35afd13b7a61a4a18fac25258985fa1fb2b88a7cc17278b0539d7cf74f940f008ee2cf4cd", - }, - { - 0, - "3ea1f3fb153636c33982464f0e5b0daeba59c3f1ee91a612c4f6a9dcfcd0a978", - "", - "ea8671fc9c02584d69af91de2adacec1408d91d512718945ed1e7dc0b620b323", - "", - "2429e7d817cfd4f8500948d2ec2dec02b7d035b4bb986144bb918a31bfd2269e6907c34ac8beab69508869a4f04bc3c23ccfbae5d59eab857ece000d554b273a", - }, - { - 0, - "b6b2033e382decd21e4eabd8f1177761d06a12bae1cfed0059b7e16bd9bab8d7", - "", - "c99a49132543fce49b804e9f417d22e49c460bc4e60a6d36701fea561b93203d", - "", - "63626608b446c7d02212209d0a3888e40534864d8f5cd28aaff09505ee5e894751e5cb8467a5d85d87a675b7852724deb0d12038035400c3405fafb1a47f88c8", - }, - { - 0, - "acc465d1bf94ccdeec06c74c812db3a993c408b5c2ef7ebe9bdeb6a1a51976a7", - "", - "77278d47a169c559518d46ffb23aa594efdaebb067c48d4a392f60b94cc15b36", - "", - "e0e6e417de8fc5d212bdda4c026a13d6eae402874d62c30577ee4c3445ace85479cbc3b55bbbe1573c13f9b0242d7e3f6e7e91d932b3d5a6dca8df43c188ae5e", - }, - { - 0, - "14b33415d2321fbb10a768ced712c8999ff2f19b63264a81adc2fdc16370b185", - "", - "029b48805285349c292a99ee68fcefda1f61dd60a09f4616cb2efe4f8b140056", - "", - "8a69feb26be025a3849bb0b60959717daa59c889c383593d1f8debf58051eb463d07c659cfbe47e94224ba18833b71d95905e0cde785364a87706e31297fb323", - }, - { - 0, - "5a83af23cafb30e3a18e28651b3c1bd01813c44216e7e44b790d6664e2c3839a", - "", - "d0f108ae7c65e16cfa13e5582204eb8cd6ebb08f1f6a5d476c275247c1a83eb5", - "", - "e64397f0eea0d33d9715bcef2ee7eec22a86e8d066a25e44706dc688c499bd7ef08172c8cf36e3bddf79f2bec136a01aad844930e48a16fe1800d69fb0f4e163", - }, - { - 0, - "1dc24dd9d6a405a007bd082cfbdbd863185e072b67d663b14d7e8f16900cfce6", - "", - "0eca85ddcb6f38ff3683968ef98b52408428dcae2ec3b0fa4c68906c1b6481cd", - "", - "156938566fc25d493c1c60d8925819a6e59a2479d75f3efff16d46aada68403140407955c1fd9d2a890bcf67ac9b3b82d1d6cf788fd863da3d41ac6e34f217a0", - }, - { - 0, - "ecb7e61a4792a2115213d141d20710e8a3212d7847dd53dfa5d4d7777d10d97e", - "", - "bf09235d30cd69ada285948fe1be2e0c4e145ac8485d12ca7b8239136da1c638", - "", - "868db5832b2e9c3d2c9794b174b328ed2cc86e41017863eabc4a7c096a487bfe4d67ccf93a5e2c67d88dbd8f1419b2a9f1293e7a70e8e8fe93e2156496b0fa54", - }, - { - 0, - "e55727c590ec3ac108f4e5fec39a2d34bf89aee4e215dcc970db8ae8f6a0e4a8", - "", - "ade3d28a8e43aab8fd31dec8bdbe5c41c0b3f7f69a2d0aada5608ab0e57c8bb0", - "", - "198742299feecf6083e3a0bef75ac2b93de2defa6525883a55f88247dc6902279f792402faffe4a81213e40facb873cd499e4b0f7f0ff592bc06699db773b899", - }, - { - 0, - "c380dafd84f2782b7539ca1c3ad9715fe6b1805310a578afcffc9210ac127ded", - "", - "b298533d9c74a0d9b9aa0d82edc434002b4d1372318c2865b7700a5b7ebeabf0", - "", - "9aec7a5ba3e091e6a6c99e04395af2ab2eeaa1ef089baa51dc23ea31603b899ea298317603354f38fd9c36c2a53a05c1e468c6ae32fe4c3b0056ec0d5eff22b6", - }, - { - 0, - "f158210535a404f6cb4f9550b3f26e3f777a9faa164774749f48ef4a8ce09449", - "", - "d56fa873cc762f64b3ab31b6291e247efca71fca90453cfff1f2b0b3e265c475", - "", - "034b41b2a9a6764e5ed1edb00aea3185fe43eb81b4253e7cade97956fccd9fc5782328fada8ed5208f1d46b1f872e333b9e2f036a51746ccaf39e1a85af8eb23", - }, - { - 0, - "973a99b7e03b393ef689af8cb90d7436cae10e4814814aed342dd38e2a7346e3", - "", - "300d3d2adbac6d7ddadde07e08b0d72b5b39ff36031e81d8303958242e3cf03f", - "", - "62012842991fe3220f1d961045f028a3b6a729f5a451b8c2ec90e1c1e2b1e4042e97267e1bfa1782a10c3c29509bc8f2adffd3d695861e1594da91702830faf7", - }, - { - 0, - "22d1d8c8bde76a239d032804717face16d77b51170d0f53ccbcca4eaff4fb315", - "", - "5d3a7d40fdf95b98454bca03c6fcbf6abf3807de75171b55bab2db5a3f5f12f2", - "", - "1007e11f48e3c4813fddd67310db56d67a49fe93e45e61b37ba81485df6a62ee57ca41fa1d987f467c2939790a20421c2b4f70b28fb0b90bbeab1ac0ae884f1a", - }, + { + 0, + "cee23de86a69c7ef57f6e1e12bd16e35e51624226fa19597bf93ec476a44b0f2", + "", + "a2ef16f226ea324f23abd59d5e3c660561c25e73638fe21c87566e86a9e04c3e", + "", + "2a76d71b329f449c98dc08fff1d205a2fbd9e4ade120c7611c225c984eac8531288dd3049f" + "3dc3bb3671501ab8fbf9ad49c86cce307653bd8caf29cb0cf07764", + }, + { + 0, + "b09eb4a82a39066ec945bb7c6aef6a0682a62c3e674bd900297d4271a5f25b49", + "", + "a3b768adcfe76d61c972d900da8dffeeb2a42e740247aa719ed1c924d2d10bd4", + "", + "5a1c26803f3ffd4daf32042fdcc32c3812bb5ef13bc208cef82ea047d2890a6f5dcecf32bc" + "c32a2585775ac5e1ffaa8de00664c54fe00a7674b985619e953c3a", + }, + { + 0, + "0bbc898f8daf3f12fc009c846fe2cea22f683a432eea297257312d5a44bac131", + "", + "8d34be9d8110b84b02a60508deae773c1a808f4e2a0ec81747ae2ec923fe99a9", + "", + "da49e24a6cb1d9e51b98ea6103627d9ad035770b7bdc760606e2b5f35afd13b7a61a4a18fa" + "c25258985fa1fb2b88a7cc17278b0539d7cf74f940f008ee2cf4cd", + }, + { + 0, + "3ea1f3fb153636c33982464f0e5b0daeba59c3f1ee91a612c4f6a9dcfcd0a978", + "", + "ea8671fc9c02584d69af91de2adacec1408d91d512718945ed1e7dc0b620b323", + "", + "2429e7d817cfd4f8500948d2ec2dec02b7d035b4bb986144bb918a31bfd2269e6907c34ac8" + "beab69508869a4f04bc3c23ccfbae5d59eab857ece000d554b273a", + }, + { + 0, + "b6b2033e382decd21e4eabd8f1177761d06a12bae1cfed0059b7e16bd9bab8d7", + "", + "c99a49132543fce49b804e9f417d22e49c460bc4e60a6d36701fea561b93203d", + "", + "63626608b446c7d02212209d0a3888e40534864d8f5cd28aaff09505ee5e894751e5cb8467" + "a5d85d87a675b7852724deb0d12038035400c3405fafb1a47f88c8", + }, + { + 0, + "acc465d1bf94ccdeec06c74c812db3a993c408b5c2ef7ebe9bdeb6a1a51976a7", + "", + "77278d47a169c559518d46ffb23aa594efdaebb067c48d4a392f60b94cc15b36", + "", + "e0e6e417de8fc5d212bdda4c026a13d6eae402874d62c30577ee4c3445ace85479cbc3b55b" + "bbe1573c13f9b0242d7e3f6e7e91d932b3d5a6dca8df43c188ae5e", + }, + { + 0, + "14b33415d2321fbb10a768ced712c8999ff2f19b63264a81adc2fdc16370b185", + "", + "029b48805285349c292a99ee68fcefda1f61dd60a09f4616cb2efe4f8b140056", + "", + "8a69feb26be025a3849bb0b60959717daa59c889c383593d1f8debf58051eb463d07c659cf" + "be47e94224ba18833b71d95905e0cde785364a87706e31297fb323", + }, + { + 0, + "5a83af23cafb30e3a18e28651b3c1bd01813c44216e7e44b790d6664e2c3839a", + "", + "d0f108ae7c65e16cfa13e5582204eb8cd6ebb08f1f6a5d476c275247c1a83eb5", + "", + "e64397f0eea0d33d9715bcef2ee7eec22a86e8d066a25e44706dc688c499bd7ef08172c8cf" + "36e3bddf79f2bec136a01aad844930e48a16fe1800d69fb0f4e163", + }, + { + 0, + "1dc24dd9d6a405a007bd082cfbdbd863185e072b67d663b14d7e8f16900cfce6", + "", + "0eca85ddcb6f38ff3683968ef98b52408428dcae2ec3b0fa4c68906c1b6481cd", + "", + "156938566fc25d493c1c60d8925819a6e59a2479d75f3efff16d46aada68403140407955c1" + "fd9d2a890bcf67ac9b3b82d1d6cf788fd863da3d41ac6e34f217a0", + }, + { + 0, + "ecb7e61a4792a2115213d141d20710e8a3212d7847dd53dfa5d4d7777d10d97e", + "", + "bf09235d30cd69ada285948fe1be2e0c4e145ac8485d12ca7b8239136da1c638", + "", + "868db5832b2e9c3d2c9794b174b328ed2cc86e41017863eabc4a7c096a487bfe4d67ccf93a" + "5e2c67d88dbd8f1419b2a9f1293e7a70e8e8fe93e2156496b0fa54", + }, + { + 0, + "e55727c590ec3ac108f4e5fec39a2d34bf89aee4e215dcc970db8ae8f6a0e4a8", + "", + "ade3d28a8e43aab8fd31dec8bdbe5c41c0b3f7f69a2d0aada5608ab0e57c8bb0", + "", + "198742299feecf6083e3a0bef75ac2b93de2defa6525883a55f88247dc6902279f792402fa" + "ffe4a81213e40facb873cd499e4b0f7f0ff592bc06699db773b899", + }, + { + 0, + "c380dafd84f2782b7539ca1c3ad9715fe6b1805310a578afcffc9210ac127ded", + "", + "b298533d9c74a0d9b9aa0d82edc434002b4d1372318c2865b7700a5b7ebeabf0", + "", + "9aec7a5ba3e091e6a6c99e04395af2ab2eeaa1ef089baa51dc23ea31603b899ea298317603" + "354f38fd9c36c2a53a05c1e468c6ae32fe4c3b0056ec0d5eff22b6", + }, + { + 0, + "f158210535a404f6cb4f9550b3f26e3f777a9faa164774749f48ef4a8ce09449", + "", + "d56fa873cc762f64b3ab31b6291e247efca71fca90453cfff1f2b0b3e265c475", + "", + "034b41b2a9a6764e5ed1edb00aea3185fe43eb81b4253e7cade97956fccd9fc5782328fada" + "8ed5208f1d46b1f872e333b9e2f036a51746ccaf39e1a85af8eb23", + }, + { + 0, + "973a99b7e03b393ef689af8cb90d7436cae10e4814814aed342dd38e2a7346e3", + "", + "300d3d2adbac6d7ddadde07e08b0d72b5b39ff36031e81d8303958242e3cf03f", + "", + "62012842991fe3220f1d961045f028a3b6a729f5a451b8c2ec90e1c1e2b1e4042e97267e1b" + "fa1782a10c3c29509bc8f2adffd3d695861e1594da91702830faf7", + }, + { + 0, + "22d1d8c8bde76a239d032804717face16d77b51170d0f53ccbcca4eaff4fb315", + "", + "5d3a7d40fdf95b98454bca03c6fcbf6abf3807de75171b55bab2db5a3f5f12f2", + "", + "1007e11f48e3c4813fddd67310db56d67a49fe93e45e61b37ba81485df6a62ee57ca41fa1d" + "987f467c2939790a20421c2b4f70b28fb0b90bbeab1ac0ae884f1a", + }, }; #if 0 @@ -179,29 +194,30 @@ uint32_t AJ_PlatformEntropy(uint8_t* __data, uint32_t size) } #endif -int AJ_RawToHex(const uint8_t* raw, size_t rawLen, char* hex, size_t hexLen, uint8_t lower) +int AJ_RawToHex( + const uint8_t *raw, size_t rawLen, char *hex, size_t hexLen, uint8_t lower) { - static const char nibble_upper[] = "0123456789ABCDEF"; - static const char nibble_lower[] = "0123456789abcdef"; - const char* nibble = lower ? nibble_lower : nibble_upper; - char* h = hex + 2 * rawLen; - const uint8_t* a = raw + rawLen; + static const char nibble_upper[] = "0123456789ABCDEF"; + static const char nibble_lower[] = "0123456789abcdef"; + const char *nibble = lower ? nibble_lower : nibble_upper; + char *h = hex + 2 * rawLen; + const uint8_t *a = raw + rawLen; - if ((2 * rawLen + 1) > hexLen) { - return 11; - } - h[0] = '\0'; - /* + if ((2 * rawLen + 1) > hexLen) { + return 11; + } + h[0] = '\0'; + /* * Running backwards encode each byte in inStr as a pair of ascii hex digits. * Going backwards allows the raw and hex buffers to be the same buffer. */ - while (rawLen--) { - uint8_t n = *(--a); - h -= 2; - h[0] = nibble[n >> 4]; - h[1] = nibble[n & 0xF]; - } - return 0; + while (rawLen--) { + uint8_t n = *(--a); + h -= 2; + h[0] = nibble[n >> 4]; + h[1] = nibble[n & 0xF]; + } + return 0; } #if 0 @@ -227,79 +243,79 @@ void AJ_RandBytes(uint8_t* rand, uint32_t size) } #endif -static uint8_t A2H(char hex, int* status) +static uint8_t A2H(char hex, int *status) { - if (hex >= '0' && hex <= '9') { - return hex - '0'; - } - hex |= 0x20; - if (hex >= 'a' && hex <= 'f') { - return 10 + hex - 'a'; - } else if (hex >= 'A' && hex <= 'F') { - return 10 + hex - 'A'; - } else { - *status = 3; - return 0; - } + if (hex >= '0' && hex <= '9') { + return hex - '0'; + } + hex |= 0x20; + if (hex >= 'a' && hex <= 'f') { + return 10 + hex - 'a'; + } else if (hex >= 'A' && hex <= 'F') { + return 10 + hex - 'A'; + } else { + *status = 3; + return 0; + } } -int AJ_HexToRaw(const char* hex, size_t hexLen, uint8_t* raw, size_t rawLen) +int AJ_HexToRaw(const char *hex, size_t hexLen, uint8_t *raw, size_t rawLen) { - int status = 0; - char* p = (char*)raw; - size_t sz = hexLen ? hexLen : strlen(hex); - size_t i; + int status = 0; + char *p = (char *)raw; + size_t sz = hexLen ? hexLen : strlen(hex); + size_t i; - /* + /* * Length of encoded hex must be an even number */ - if (sz & 1) { - return 2; - } - if (rawLen < (sz / 2)) { - return 11; - } - for (i = 0; (i < sz) && (status == 0); i += 2, hex += 2) { - *p++ = (A2H(hex[0], &status) << 4) | A2H(hex[1], &status); - } - return status; + if (sz & 1) { + return 2; + } + if (rawLen < (sz / 2)) { + return 11; + } + for (i = 0; (i < sz) && (status == 0); i += 2, hex += 2) { + *p++ = (A2H(hex[0], &status) << 4) | A2H(hex[1], &status); + } + return status; } /** * Macro for getting the size of an array variable */ -#define ArraySize(a) (sizeof(a) / sizeof(a[0])) +#define ArraySize(a) (sizeof(a) / sizeof(a[0])) void test_ctr_dbrg(void) { - CTR_DRBG_CTX ctx; - size_t i; - size_t size; - uint8_t* d; - uint8_t* __data; - uint8_t* rand; - uint8_t* personal; - uint8_t* p; - char message[256]; + CTR_DRBG_CTX ctx; + size_t i; + size_t size; + uint8_t *d; + uint8_t *__data; + uint8_t *rand; + uint8_t *personal; + uint8_t *p; + char message[256]; - for (i = 0; i < ArraySize(testVector); i++) { - size_t elen = strlen(testVector[i].entropy) / 2; - size_t nlen = strlen(testVector[i].nonce) / 2; - size_t plen = strlen(testVector[i].personal) / 2; - size_t rlen = strlen(testVector[i].reseed) / 2; + for (i = 0; i < ArraySize(testVector); i++) { + size_t elen = strlen(testVector[i].entropy) / 2; + size_t nlen = strlen(testVector[i].nonce) / 2; + size_t plen = strlen(testVector[i].personal) / 2; + size_t rlen = strlen(testVector[i].reseed) / 2; - size = elen + nlen; - __data = malloc(size); - personal = malloc(size); - TEST_ASSERT_NOT_NULL(__data); - TEST_ASSERT_NOT_NULL(personal); - d = __data; - p = personal; - AJ_HexToRaw(testVector[i].entropy, 2 * elen, d, size); - d += elen; - AJ_HexToRaw(testVector[i].nonce, 2 * nlen, d, size); + size = elen + nlen; + __data = malloc(size); + personal = malloc(size); + TEST_ASSERT_NOT_NULL(__data); + TEST_ASSERT_NOT_NULL(personal); + d = __data; + p = personal; + AJ_HexToRaw(testVector[i].entropy, 2 * elen, d, size); + d += elen; + AJ_HexToRaw(testVector[i].nonce, 2 * nlen, d, size); - AJ_HexToRaw(testVector[i].personal, 2 * plen, p, size); + AJ_HexToRaw(testVector[i].personal, 2 * plen, p, size); #if 0 for (i = 0; i < SEEDLEN; i++) { @@ -309,38 +325,38 @@ void test_ctr_dbrg(void) __data[i] ^= personal[i]; } #endif - //AJ_DumpBytes("SEED", __data, size); - AES_CTR_DRBG_Instantiate(&ctx, __data, personal); - free(__data); + //AJ_DumpBytes("SEED", __data, size); + AES_CTR_DRBG_Instantiate(&ctx, __data, personal); + free(__data); - if (rlen) { - size = rlen; - __data = malloc(size); - TEST_ASSERT_NOT_NULL(__data); - AJ_HexToRaw(testVector[i].reseed, 2 * rlen, __data, size); - AES_CTR_DRBG_Reseed(&ctx, __data); - free(__data); - } + if (rlen) { + size = rlen; + __data = malloc(size); + TEST_ASSERT_NOT_NULL(__data); + AJ_HexToRaw(testVector[i].reseed, 2 * rlen, __data, size); + AES_CTR_DRBG_Reseed(&ctx, __data); + free(__data); + } - size = strlen(testVector[i].rand) / 2; - __data = malloc(size); - rand = malloc(size); - TEST_ASSERT(__data); - TEST_ASSERT(rand); - AJ_HexToRaw(testVector[i].rand, 2 * size, rand, size); + size = strlen(testVector[i].rand) / 2; + __data = malloc(size); + rand = malloc(size); + TEST_ASSERT(__data); + TEST_ASSERT(rand); + AJ_HexToRaw(testVector[i].rand, 2 * size, rand, size); - AES_CTR_DRBG_Generate(&ctx, __data); - AES_CTR_DRBG_Generate(&ctx, __data); + AES_CTR_DRBG_Generate(&ctx, __data); + AES_CTR_DRBG_Generate(&ctx, __data); - sprintf(message, "Expected failed for test #%lu\n", (long unsigned)i); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(__data, rand, size, message); + sprintf(message, "Expected failed for test #%lu\n", (long unsigned)i); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(__data, rand, size, message); - free(__data); - free(rand); - free(personal); - } + free(__data); + free(rand); + free(personal); + } - /* + /* // Initialize the core context AJ_RandBytes(NULL, 0); diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_curve25519.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_curve25519.c index a2b21df9b..2505383fb 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_curve25519.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_curve25519.c @@ -1,212 +1,207 @@ /* © 2015 Silicon Laboratories Inc. - */ + */ /* * aes_cmac_unit_test.c * * Created on: 25/06/2015 * Author: COlsen - */ -#include -#include -#include -#include "unity.h" -#include - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -#define KEY_SIZE (32) // In bytes - -static const uint8_t alice_secret_key[KEY_SIZE] = { - 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d - ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45 - ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a - ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a -}; - + */ +#include +#include +#include +#include "unity.h" +#include + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define KEY_SIZE (32) // In bytes + +static const uint8_t alice_secret_key[KEY_SIZE] + = {0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, + 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, + 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a}; + /*static const uint8_t bob_secret_key[KEY_SIZE] = { 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb -};*/ - -static void bigint_mul(unsigned char *r, const unsigned char *a, const unsigned char *b, uint8_t len) -{ - //unsigned int i,j; - uint8_t i; - uint8_t j; - //uint16_t t; - uint16_t t; - for(i=0;i<2*len;i++) - r[i] = 0; - - for (i=0; i>8); - r[i+j]=(t & 0xFF); - } - r[i+len]=(t>>8); - } -} - -static void print16(uint8_t * pData) -{ - uint8_t i; - puts("\n"); - for (i = 0;i < 16;++i) - { - if (i > 0) - { - puts(","); - } - else - { - puts(" "); - } - printf("%x", pData[i]); - if (i % 8 == 7) - { - puts("\n"); - } - } -} - -static uint8_t alice_public_key[KEY_SIZE]; -#ifdef NOT_USED -static uint8_t bob_public_key[KEY_SIZE]; -#endif - -void test_alice_calculation_of_public_key(void) -{ - const uint8_t expected_alice_public_key[KEY_SIZE] = { - 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54 - ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a - ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4 - ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a - }; - - crypto_scalarmult_curve25519_base(alice_public_key, alice_secret_key); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_alice_public_key, alice_public_key, KEY_SIZE, __LINE__, ""); -} - -void test_bigint_calc(void) -{ - uint32_t i = 0x12345678; - - const uint8_t some_data1[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12 - }; - const uint8_t some_data2[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12 - }; - - uint8_t result[16]; - - memset(result, 0x00, sizeof(result)); - - bigint_mul(result, some_data1, some_data2, 8); - - print16(result); - - printf("------------------------------------"); - - if ( *(char *)&i == 0x12 ) - { - printf("Big endian\n"); - } - else if ( *(char *)&i == 0x78 ) - { - printf("Little endian\n"); - } -} - -#ifdef NOT_USED - -//void test_bob_calculation_of_public_key(void) -{ - const uint8_t expected_bob_public_key[KEY_SIZE] = { - 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4 - ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37 - ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d - ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f - }; - - crypto_scalarmult_curve25519_base(bob_public_key, bob_secret_key); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_bob_public_key, bob_public_key, KEY_SIZE, __LINE__, ""); -} - -//void test_alice_bob_shared_secret(void) -{ - const uint8_t expected_shared_secret[KEY_SIZE] = { - 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1 - ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25 - ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33 - ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42 - }; - uint8_t k[KEY_SIZE]; - - memset(k, 0x00, sizeof(k)); - - crypto_scalarmult_curve25519( - k, - alice_secret_key, - bob_public_key); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_shared_secret, k, KEY_SIZE, __LINE__, ""); - - memset(k, 0x00, sizeof(k)); - - crypto_scalarmult_curve25519( - k, - bob_secret_key, - alice_public_key); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_shared_secret, k, KEY_SIZE, __LINE__, ""); -} - -//void test_10_shared_secrets(void) -{ - uint8_t person1_secret_key[KEY_SIZE]; - uint8_t person1_public_key[KEY_SIZE]; - uint8_t person1_shared_key_calc[KEY_SIZE]; - - uint8_t person2_secret_key[KEY_SIZE]; - uint8_t person2_public_key[KEY_SIZE]; - uint8_t person2_shared_key_calc[KEY_SIZE]; - - uint16_t count; - uint8_t key_count; - - for (count = 0; count < 10; count++) - { - for (key_count = 0; key_count < KEY_SIZE; key_count++) - { - person1_secret_key[key_count] = (uint8_t)(rand() & 0xFF); - person2_secret_key[key_count] = (uint8_t)(rand() & 0xFF); - } - crypto_scalarmult_curve25519_base(person1_public_key, person1_secret_key); - crypto_scalarmult_curve25519_base(person2_public_key, person2_secret_key); - - crypto_scalarmult_curve25519( - person1_shared_key_calc, - person1_secret_key, - person2_public_key); - - crypto_scalarmult_curve25519( - person2_shared_key_calc, - person2_secret_key, - person1_public_key); - - UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(person1_shared_key_calc, person2_shared_key_calc, KEY_SIZE, __LINE__, ""); - - memset(person1_shared_key_calc, 0x00, KEY_SIZE); - memset(person2_shared_key_calc, 0x01, KEY_SIZE); - } -} - -#endif +};*/ + +static void bigint_mul(unsigned char *r, + const unsigned char *a, + const unsigned char *b, + uint8_t len) +{ + //unsigned int i,j; + uint8_t i; + uint8_t j; + //uint16_t t; + uint16_t t; + for (i = 0; i < 2 * len; i++) + r[i] = 0; + + for (i = 0; i < len; i++) { + t = 0; + for (j = 0; j < len; j++) { + t = r[i + j] + a[i] * b[j] + (t >> 8); + r[i + j] = (t & 0xFF); + } + r[i + len] = (t >> 8); + } +} + +static void print16(uint8_t *pData) +{ + uint8_t i; + puts("\n"); + for (i = 0; i < 16; ++i) { + if (i > 0) { + puts(","); + } else { + puts(" "); + } + printf("%x", pData[i]); + if (i % 8 == 7) { + puts("\n"); + } + } +} + +static uint8_t alice_public_key[KEY_SIZE]; +#ifdef NOT_USED +static uint8_t bob_public_key[KEY_SIZE]; +#endif + +void test_alice_calculation_of_public_key(void) +{ + const uint8_t expected_alice_public_key[KEY_SIZE] + = {0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a}; + + crypto_scalarmult_curve25519_base(alice_public_key, alice_secret_key); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_alice_public_key, + alice_public_key, + KEY_SIZE, + __LINE__, + ""); +} + +void test_bigint_calc(void) +{ + uint32_t i = 0x12345678; + + const uint8_t some_data1[8] + = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12}; + const uint8_t some_data2[8] + = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12}; + + uint8_t result[16]; + + memset(result, 0x00, sizeof(result)); + + bigint_mul(result, some_data1, some_data2, 8); + + print16(result); + + printf("------------------------------------"); + + if (*(char *)&i == 0x12) { + printf("Big endian\n"); + } else if (*(char *)&i == 0x78) { + printf("Little endian\n"); + } +} + +#ifdef NOT_USED + +//void test_bob_calculation_of_public_key(void) +{ + const uint8_t expected_bob_public_key[KEY_SIZE] + = {0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; + + crypto_scalarmult_curve25519_base(bob_public_key, bob_secret_key); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_bob_public_key, + bob_public_key, + KEY_SIZE, + __LINE__, + ""); +} + +//void test_alice_bob_shared_secret(void) +{ + const uint8_t expected_shared_secret[KEY_SIZE] + = {0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 0x72, 0x8e, 0x3b, + 0xf4, 0x80, 0x35, 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9, 0x47, 0xd1, + 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16, 0x17, 0x42}; + uint8_t k[KEY_SIZE]; + + memset(k, 0x00, sizeof(k)); + + crypto_scalarmult_curve25519(k, alice_secret_key, bob_public_key); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_shared_secret, + k, + KEY_SIZE, + __LINE__, + ""); + + memset(k, 0x00, sizeof(k)); + + crypto_scalarmult_curve25519(k, bob_secret_key, alice_public_key); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_shared_secret, + k, + KEY_SIZE, + __LINE__, + ""); +} + +//void test_10_shared_secrets(void) +{ + uint8_t person1_secret_key[KEY_SIZE]; + uint8_t person1_public_key[KEY_SIZE]; + uint8_t person1_shared_key_calc[KEY_SIZE]; + + uint8_t person2_secret_key[KEY_SIZE]; + uint8_t person2_public_key[KEY_SIZE]; + uint8_t person2_shared_key_calc[KEY_SIZE]; + + uint16_t count; + uint8_t key_count; + + for (count = 0; count < 10; count++) { + for (key_count = 0; key_count < KEY_SIZE; key_count++) { + person1_secret_key[key_count] = (uint8_t)(rand() & 0xFF); + person2_secret_key[key_count] = (uint8_t)(rand() & 0xFF); + } + crypto_scalarmult_curve25519_base(person1_public_key, person1_secret_key); + crypto_scalarmult_curve25519_base(person2_public_key, person2_secret_key); + + crypto_scalarmult_curve25519(person1_shared_key_calc, + person1_secret_key, + person2_public_key); + + crypto_scalarmult_curve25519(person2_shared_key_calc, + person2_secret_key, + person1_public_key); + + UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(person1_shared_key_calc, + person2_shared_key_calc, + KEY_SIZE, + __LINE__, + ""); + + memset(person1_shared_key_calc, 0x00, KEY_SIZE); + memset(person2_shared_key_calc, 0x01, KEY_SIZE); + } +} + +#endif diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_kderiv.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_kderiv.c index 489a3f49a..9ff595ace 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_kderiv.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/test/test_kderiv.c @@ -9,60 +9,206 @@ void print_array(const char *name, uint8_t *arr, int len) { - int i; + int i; - printf("%s", name); - for ( i = 0; i < len; i++) { - if (arr[i] <= 0xf) - printf("0x0%x ", arr[i]); - else - printf("0x%x ", arr[i]); - } - printf("\n"); + printf("%s", name); + for (i = 0; i < len; i++) { + if (arr[i] <= 0xf) + printf("0x0%x ", arr[i]); + else + printf("0x%x ", arr[i]); + } + printf("\n"); } void test_key_derivation(void) { - uint8_t network_key[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t pseudo_random_keymat_output[16]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t ccm_key[16]; - uint8_t mpan_key[16]; - uint8_t pers_string[32]; - /* These samples are generated from the Python cmac code */ - uint8_t auth_tag[64] = {0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; - uint8_t ecdh_share_secret[32] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; + uint8_t network_key[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t pseudo_random_keymat_output[16] = {0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f}; + uint8_t ccm_key[16]; + uint8_t mpan_key[16]; + uint8_t pers_string[32]; + /* These samples are generated from the Python cmac code */ + uint8_t auth_tag[64] + = {0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x48, 0x49, 0x4a, + 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}; + uint8_t ecdh_share_secret[32] + = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x40, 0x41, 0x42, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}; - /* following vectors are created by python code inside test/kderiv_python/generate*.py */ - /* test/kderiv_python/generate_networkkey_expand.py */ - uint8_t py_ccm_key[16] = { 0xaf,0x7f,0x0a,0x1e,0xfc,0xfe,0x8f,0x4b,0x1f,0xd2,0x84,0x5d,0xd2,0x85,0x6f,0x7d}; - uint8_t py_pers_string[32] = {0xcc,0xf8,0xb4,0x2a,0x4f,0x70,0x21,0x76,0xac,0x2b,0x91,0x94,0xdb,0xbd,0xb8,0x2c,0x47,0x43,0x02,0xff,0x12,0xe1,0xe8,0x26,0x64,0x22,0xf3,0xac,0x44,0x89,0x4b,0x87}; - // TODO: Update mpan key with real test vector - uint8_t py_mpan_key[16] = {0xb8, 0x9d, 0xb1, 0x54, 0x3f, 0xd2, 0x82, 0x0e, 0xa9, 0x79, 0xc9, 0x6a, 0x30, 0x5a, 0x23, 0x0b}; - //0xaf,0x7f,0x0a,0x1e,0xfc,0xfe,0x8f,0x4b,0x1f,0xd2,0x84,0x5d,0xd2,0x85,0x6f,0x7d}; - /* test/kderiv_python/generate_tempkey_expand.py */ - uint8_t py_temp_ccm_key[16] = {0x47, 0xda, 0x9d, 0x15, 0x39, 0xec, 0x73, 0xe5, 0xd2, 0xa0, 0xf7, 0x37, 0xdb, 0xf2, 0x9b, 0x33}; - uint8_t py_temp_pers_string[32] = {0x94, 0xa5, 0x3e, 0xb9, 0xa1, 0x2d, 0x7c, 0xd9, 0x49, 0xea, 0x70, 0xff, 0xb8, 0xa6, 0xe7, 0x1e, 0xa6, 0xf7, 0x9c, 0xa7, 0xa0, 0x14, 0x5a, 0x08, 0xba, 0xd5, 0x82, 0xae, 0xb0, 0x9b, 0xd2, 0x8b}; - // TODO: Update py_temp_mpan_key with real test vector - uint8_t py_temp_mpan_key[16] = {0xc2, 0x8e, 0x57, 0x5f, 0x24, 0x6f, 0x59, 0xa4, 0xa5, 0x85, 0x0f, 0x20, 0x66, 0xf1, 0x06, 0x2b}; - /* test/kderiv_python/generate_tempkey_extract.py */ - uint8_t py_pseudo_random_keymat_output[16] = {0x74,0x77,0x8f,0x89,0xd4,0xd8,0x8c,0x6e,0x46,0x59,0x63,0x4a,0x88,0xea,0x98,0x7a}; + /* following vectors are created by python code inside test/kderiv_python/generate*.py */ + /* test/kderiv_python/generate_networkkey_expand.py */ + uint8_t py_ccm_key[16] = {0xaf, + 0x7f, + 0x0a, + 0x1e, + 0xfc, + 0xfe, + 0x8f, + 0x4b, + 0x1f, + 0xd2, + 0x84, + 0x5d, + 0xd2, + 0x85, + 0x6f, + 0x7d}; + uint8_t py_pers_string[32] + = {0xcc, 0xf8, 0xb4, 0x2a, 0x4f, 0x70, 0x21, 0x76, 0xac, 0x2b, 0x91, + 0x94, 0xdb, 0xbd, 0xb8, 0x2c, 0x47, 0x43, 0x02, 0xff, 0x12, 0xe1, + 0xe8, 0x26, 0x64, 0x22, 0xf3, 0xac, 0x44, 0x89, 0x4b, 0x87}; + // TODO: Update mpan key with real test vector + uint8_t py_mpan_key[16] = {0xb8, + 0x9d, + 0xb1, + 0x54, + 0x3f, + 0xd2, + 0x82, + 0x0e, + 0xa9, + 0x79, + 0xc9, + 0x6a, + 0x30, + 0x5a, + 0x23, + 0x0b}; + //0xaf,0x7f,0x0a,0x1e,0xfc,0xfe,0x8f,0x4b,0x1f,0xd2,0x84,0x5d,0xd2,0x85,0x6f,0x7d}; + /* test/kderiv_python/generate_tempkey_expand.py */ + uint8_t py_temp_ccm_key[16] = {0x47, + 0xda, + 0x9d, + 0x15, + 0x39, + 0xec, + 0x73, + 0xe5, + 0xd2, + 0xa0, + 0xf7, + 0x37, + 0xdb, + 0xf2, + 0x9b, + 0x33}; + uint8_t py_temp_pers_string[32] + = {0x94, 0xa5, 0x3e, 0xb9, 0xa1, 0x2d, 0x7c, 0xd9, 0x49, 0xea, 0x70, + 0xff, 0xb8, 0xa6, 0xe7, 0x1e, 0xa6, 0xf7, 0x9c, 0xa7, 0xa0, 0x14, + 0x5a, 0x08, 0xba, 0xd5, 0x82, 0xae, 0xb0, 0x9b, 0xd2, 0x8b}; + // TODO: Update py_temp_mpan_key with real test vector + uint8_t py_temp_mpan_key[16] = {0xc2, + 0x8e, + 0x57, + 0x5f, + 0x24, + 0x6f, + 0x59, + 0xa4, + 0xa5, + 0x85, + 0x0f, + 0x20, + 0x66, + 0xf1, + 0x06, + 0x2b}; + /* test/kderiv_python/generate_tempkey_extract.py */ + uint8_t py_pseudo_random_keymat_output[16] = {0x74, + 0x77, + 0x8f, + 0x89, + 0xd4, + 0xd8, + 0x8c, + 0x6e, + 0x46, + 0x59, + 0x63, + 0x4a, + 0x88, + 0xea, + 0x98, + 0x7a}; - networkkey_expand(0, network_key, ccm_key, pers_string, mpan_key); + networkkey_expand(0, network_key, ccm_key, pers_string, mpan_key); - //print_array("ccm_key : ", ccm_key, 16); - //print_array("pers_string : ", pers_string, 32); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_ccm_key, ccm_key, 16, "ERROR: ccm_key is wrong"); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_pers_string, pers_string, 32, "ERROR: pers_string is wrong"); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_mpan_key, mpan_key, 16, "ERROR: mpan_key is wrong"); + //print_array("ccm_key : ", ccm_key, 16); + //print_array("pers_string : ", pers_string, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_ccm_key, + ccm_key, + 16, + "ERROR: ccm_key is wrong"); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_pers_string, + pers_string, + 32, + "ERROR: pers_string is wrong"); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_mpan_key, + mpan_key, + 16, + "ERROR: mpan_key is wrong"); - tempkey_extract(ecdh_share_secret, auth_tag, pseudo_random_keymat_output); - //print_array("pseudo_random_keymat_output: ", pseudo_random_keymat_output, 16); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_pseudo_random_keymat_output, pseudo_random_keymat_output, 16, "ERROR: pseudo_random_keymat_output is wrong"); + tempkey_extract(ecdh_share_secret, auth_tag, pseudo_random_keymat_output); + //print_array("pseudo_random_keymat_output: ", pseudo_random_keymat_output, 16); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE( + py_pseudo_random_keymat_output, + pseudo_random_keymat_output, + 16, + "ERROR: pseudo_random_keymat_output is wrong"); - tempkey_expand(0, pseudo_random_keymat_output, ccm_key, pers_string, mpan_key); - //print_array("ccm_key : ", ccm_key, 16); - //print_array("pers_string : ", pers_string, 32); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_temp_ccm_key, ccm_key, 16, "ERROR: temp ccm_key is wrong"); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_temp_pers_string, pers_string, 32, "ERROR: pers_string is wrong"); - TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_temp_mpan_key, mpan_key, 16, "ERROR: temp_mpan_key is wrong"); + tempkey_expand(0, + pseudo_random_keymat_output, + ccm_key, + pers_string, + mpan_key); + //print_array("ccm_key : ", ccm_key, 16); + //print_array("pers_string : ", pers_string, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_temp_ccm_key, + ccm_key, + 16, + "ERROR: temp ccm_key is wrong"); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_temp_pers_string, + pers_string, + 32, + "ERROR: pers_string is wrong"); + TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(py_temp_mpan_key, + mpan_key, + 16, + "ERROR: temp_mpan_key is wrong"); } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ZW_ctimer.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ZW_ctimer.h index 316cce6f0..181f02a35 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ZW_ctimer.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ZW_ctimer.h @@ -3,8 +3,8 @@ /** * \addtogroup sys * @{ - */ - + */ + /** * \defgroup ctimer Callback timer * @{ @@ -12,8 +12,8 @@ * The ctimer module provides a timer mechanism that calls a specified * C function when a ctimer expires. * - */ - + */ + /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -45,35 +45,34 @@ * This file is part of the Contiki operating system. * * $Id: ctimer.h,v 1.2 2010/06/14 07:35:53 adamdunkels Exp $ - */ - + */ + /** * \file * Header file for the callback timer * \author * Adam Dunkels - */ - -#ifndef __CTIMER_H__ -#define __CTIMER_H__ - -//#include "ZW_stdint.h" -//#include -#include - -#define CLOCK_SECOND 1000 // 1 ms ticks - -typedef uint32_t clock_time_t; - -struct ctimer { - struct ctimer *next; - clock_time_t tickCounts; - clock_time_t startValue; - VOID_CALLBACKFUNC(f)(void *); - void *ptr; -}; - - + */ + +#ifndef __CTIMER_H__ +#define __CTIMER_H__ + +//#include "ZW_stdint.h" +//#include +#include + +#define CLOCK_SECOND 1000 // 1 ms ticks + +typedef uint32_t clock_time_t; + +struct ctimer { + struct ctimer *next; + clock_time_t tickCounts; + clock_time_t startValue; + VOID_CALLBACKFUNC(f)(void *); + void *ptr; +}; + /** * \brief Reset a callback timer with the same interval as was * previously set. @@ -88,9 +87,9 @@ struct ctimer { * function. * * \sa ctimer_restart() - */ -//void ctimer_reset(struct ctimer *c); - + */ +//void ctimer_reset(struct ctimer *c); + /** * \brief Restart a callback timer from the current point in time * \param c A pointer to the callback timer. @@ -105,9 +104,9 @@ struct ctimer { * ctimer_reset() function instead. * * \sa ctimer_reset() - */ -void ctimer_restart(struct ctimer *c); - + */ +void ctimer_restart(struct ctimer *c); + /** * \brief Set a callback timer. * \param c A pointer to the callback timer. @@ -119,10 +118,12 @@ void ctimer_restart(struct ctimer *c); * sometime in the future. When the callback timer expires, * the callback function f will be called with ptr as argument. * - */ -void ctimer_set(struct ctimer *c, clock_time_t t, - VOID_CALLBACKFUNC(f)(void *), void *ptr); - + */ +void ctimer_set(struct ctimer *c, + clock_time_t t, + VOID_CALLBACKFUNC(f)(void *), + void *ptr); + /** * \brief Stop a pending callback timer. * \param c A pointer to the pending callback timer. @@ -132,9 +133,9 @@ void ctimer_set(struct ctimer *c, clock_time_t t, * After this function has been called, the callback timer will be * expired and will not call the callback function. * - */ -void ctimer_stop(struct ctimer *c); - + */ +void ctimer_stop(struct ctimer *c); + /** * \brief Check if a callback timer has expired. * \param c A pointer to the callback timer @@ -142,18 +143,18 @@ void ctimer_stop(struct ctimer *c); * * This function tests if a callback timer has expired and * returns true or false depending on its status. - */ -int ctimer_expired(struct ctimer *c); - + */ +int ctimer_expired(struct ctimer *c); + /** * \brief Initialize the callback timer library. * * This function initializes the callback timer library and * should be called from the system boot up code. - */ -void ctimer_init(void); - -void ctimer_poll(uint16_t bTicks); -#endif /* __CTIMER_H__ */ -/** @} */ -/** @} */ + */ +void ctimer_init(void); + +void ctimer_poll(uint16_t bTicks); +#endif /* __CTIMER_H__ */ +/** @} */ +/** @} */ diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.c index 566d1d2a1..ee39cefd0 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.c @@ -1,91 +1,93 @@ /* © 2014 Silicon Laboratories Inc. */ - /* Author: mdumbare */ +/* Author: mdumbare */ #include #include "transport2_fsm.h" #ifdef GRAPH /* This is set by Makefile.transport2_fsm while generating graphs */ -#define +#define #define uint16_t unsigned short -#define uint8_t unsigned char +#define uint8_t unsigned char -#define VOID_CALLBACKFUNC(completedFunc) void ( *completedFunc) +#define VOID_CALLBACKFUNC(completedFunc) void(*completedFunc) #else #include "transport_service2.h" //#include #endif -const char *T2_STATES_STRING[] = { - "ST_IDLE", +const char *T2_STATES_STRING[] = { + "ST_IDLE", - /* Receive state machine states */ - "ST_RECEIVING", - "ST_SEND_FRAG_COMPLETE", - "ST_SEND_FRAG_REQ", - "ST_SEND_FRAG_WAIT", - "ST_FIND_MISS_FRAG", + /* Receive state machine states */ + "ST_RECEIVING", + "ST_SEND_FRAG_COMPLETE", + "ST_SEND_FRAG_REQ", + "ST_SEND_FRAG_WAIT", + "ST_FIND_MISS_FRAG", - /* Send state machine states */ - "ST_SEND_FRAG", - "ST_SEND_LAST_FRAG", - "ST_WAIT_ACK", + /* Send state machine states */ + "ST_SEND_FRAG", + "ST_SEND_LAST_FRAG", + "ST_WAIT_ACK", }; const char *T2_EVENTS_STRING[] = { - /* Receive state machine events */ - "EV_START_RECV", - "EV_RECV_NEW_FRAG", - "EV_NO_SESSION_ID", - "EV_SEND_FRAG_COMPLETE", - "EV_NO_SEND_FRAG_COMPLETE", - "EV_SUCCESS", - "EV_SUCCESS2", - "EV_SUCCESS3", - "EV_FRAG_RX_TIMER", - "EV_MISSING_FRAG", - "EV_MISSING_FRAG_BCAST", - "EV_SCAST_DIFF_NODE", - "EV_BCAST_DIFF_NODE", - "EV_DIFF_SESSION", - "EV_SUBSEQ_DIFF_SESSION", - "EV_FRAG_REQ_COMPL_DIFF_SESSION", - "EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE", - "EV_RECV_FRAG_REQ", - "EV_RECV_LAST_FRAG", - "EV_RECV_FRAG_COMPLETE", - "EV_TIE_BREAK", - "EV_DUPL_FRAME", - "EV_FRAG_REQ_OR_COMPL", - - /* Send state machine events */ - "EV_START_SEND", - "EV_SEND_NEW_FRAG", - "EV_SEND_NXT_MISS_FRAG", - "EV_SENT_MISS_FRAG", - "EV_RECV_FRAG_WAIT", - "EV_SEND_LAST_FRAG", - "EV_SEND_LAST_MISS_FRAG", - "EV_FRAG_COMPL_TIMER", - "EV_FRAG_COMPL_TIMER2", - "EV_FRAG_COMPL_TIMER_REQ", - "EV_FAILURE_LAST_FRAG2", - "EV_RECV_FRAG_COMPL", - "EV_REPLY_FRAG_REQ_DONE", - "EV_FAIL", + /* Receive state machine events */ + "EV_START_RECV", + "EV_RECV_NEW_FRAG", + "EV_NO_SESSION_ID", + "EV_SEND_FRAG_COMPLETE", + "EV_NO_SEND_FRAG_COMPLETE", + "EV_SUCCESS", + "EV_SUCCESS2", + "EV_SUCCESS3", + "EV_FRAG_RX_TIMER", + "EV_MISSING_FRAG", + "EV_MISSING_FRAG_BCAST", + "EV_SCAST_DIFF_NODE", + "EV_BCAST_DIFF_NODE", + "EV_DIFF_SESSION", + "EV_SUBSEQ_DIFF_SESSION", + "EV_FRAG_REQ_COMPL_DIFF_SESSION", + "EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE", + "EV_RECV_FRAG_REQ", + "EV_RECV_LAST_FRAG", + "EV_RECV_FRAG_COMPLETE", + "EV_TIE_BREAK", + "EV_DUPL_FRAME", + "EV_FRAG_REQ_OR_COMPL", + + /* Send state machine events */ + "EV_START_SEND", + "EV_SEND_NEW_FRAG", + "EV_SEND_NXT_MISS_FRAG", + "EV_SENT_MISS_FRAG", + "EV_RECV_FRAG_WAIT", + "EV_SEND_LAST_FRAG", + "EV_SEND_LAST_MISS_FRAG", + "EV_FRAG_COMPL_TIMER", + "EV_FRAG_COMPL_TIMER2", + "EV_FRAG_COMPL_TIMER_REQ", + "EV_FAILURE_LAST_FRAG2", + "EV_RECV_FRAG_COMPL", + "EV_REPLY_FRAG_REQ_DONE", + "EV_FAIL", }; -#define ST_DEFINE(a, b, c, d) {a, b, c, d} - +#define ST_DEFINE(a, b, c, d) \ + { \ + a, b, c, d \ + } #define STATE enum TRANSPORT2_STATES #define EVENT enum TRANSPORT2_EVENTS typedef struct { - STATE st; /* Current state */ - EVENT ev; /* Incoming event */ - STATE next_st; - char *fun_name; /* Action function returning next state */ + STATE st; /* Current state */ + EVENT ev; /* Incoming event */ + STATE next_st; + char *fun_name; /* Action function returning next state */ } transition_t; /* State transition table @@ -97,189 +99,217 @@ typedef struct { * * Format: {Current state, incoming event, next state, action_function} */ static const transition_t trans[] = { - /* ========================*/ - /* Receiving State diagram */ - /* ========================*/ + /* ========================*/ + /* Receiving State diagram */ + /* ========================*/ - /* First event when on receiving end. */ - ST_DEFINE(ST_IDLE, EV_START_RECV, ST_RECEIVING, "start receive"), - ST_DEFINE(ST_IDLE, EV_START_SEND, ST_SEND_FRAG, "send_first_frag"), + /* First event when on receiving end. */ + ST_DEFINE(ST_IDLE, EV_START_RECV, ST_RECEIVING, "start receive"), + ST_DEFINE(ST_IDLE, EV_START_SEND, ST_SEND_FRAG, "send_first_frag"), - /* This happens when there is a fragment received from different session or node, which + /* This happens when there is a fragment received from different session or node, which will be ignored. Then the state machine lands up in ST_IDLE */ - ST_DEFINE(ST_IDLE, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "keep sending"), + ST_DEFINE(ST_IDLE, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "keep sending"), - /* Send new frame. Call the same funciton i.e. send(); */ - ST_DEFINE(ST_SEND_FRAG, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "send_subseq_frag"), + /* Send new frame. Call the same funciton i.e. send(); */ + ST_DEFINE(ST_SEND_FRAG, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "send_subseq_frag"), - ST_DEFINE(ST_RECEIVING, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "send"), - ST_DEFINE(ST_WAIT_ACK, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "send"), + ST_DEFINE(ST_RECEIVING, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "send"), + ST_DEFINE(ST_WAIT_ACK, EV_SEND_NEW_FRAG, ST_SEND_FRAG, "send"), - /* If the current state is ST_RECEIVING and new fragment arrives */ - /* If the fragment length is wrong */ - /* If the crc is bad */ - ST_DEFINE(ST_RECEIVING, EV_RECV_NEW_FRAG, ST_RECEIVING, "process new fram"), + /* If the current state is ST_RECEIVING and new fragment arrives */ + /* If the fragment length is wrong */ + /* If the crc is bad */ + ST_DEFINE(ST_RECEIVING, EV_RECV_NEW_FRAG, ST_RECEIVING, "process new fram"), - /* If duplicate frame arrives after frag completion move back to idle state */ - ST_DEFINE(ST_RECEIVING, EV_DUPL_FRAME, ST_IDLE, "discard the fragment"), + /* If duplicate frame arrives after frag completion move back to idle state */ + ST_DEFINE(ST_RECEIVING, EV_DUPL_FRAME, ST_IDLE, "discard the fragment"), - /* If the fragment received is corrupt and there is no session ID. Receiving node + /* If the fragment received is corrupt and there is no session ID. Receiving node * has to send Fragment wait command to sending node */ - ST_DEFINE(ST_RECEIVING, EV_NO_SESSION_ID, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), + ST_DEFINE( + ST_RECEIVING, EV_NO_SESSION_ID, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), - /* If the fragment received is singlecast fragment while receiving another fragmented + /* If the fragment received is singlecast fragment while receiving another fragmented * datagram. Receiving node has to send Fragment wait command to sending node */ - ST_DEFINE(ST_RECEIVING, EV_SCAST_DIFF_NODE, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), + ST_DEFINE( + ST_RECEIVING, EV_SCAST_DIFF_NODE, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), - /* If the fragment received is singlecast fragment while sending another fragmented + /* If the fragment received is singlecast fragment while sending another fragmented * datagram. */ - ST_DEFINE(ST_SEND_FRAG, EV_SCAST_DIFF_NODE, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), + ST_DEFINE( + ST_SEND_FRAG, EV_SCAST_DIFF_NODE, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), - /* If the fragment received is singlecast fragment while waiting for ack (frag req or frag compl) + /* If the fragment received is singlecast fragment while waiting for ack (frag req or frag compl) */ - ST_DEFINE(ST_WAIT_ACK, EV_SCAST_DIFF_NODE, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), - + ST_DEFINE( + ST_WAIT_ACK, EV_SCAST_DIFF_NODE, ST_SEND_FRAG_WAIT, "send_frag_wait_cmd"), - /* If the fragment received is singlecast fragment while receiving fragmented + /* If the fragment received is singlecast fragment while receiving fragmented * datagram from different session. Receiving node has to discard the fragment */ - ST_DEFINE(ST_RECEIVING, EV_DIFF_SESSION, ST_IDLE, "discard the fragment"), + ST_DEFINE(ST_RECEIVING, EV_DIFF_SESSION, ST_IDLE, "discard the fragment"), - ST_DEFINE(ST_RECEIVING, EV_SUBSEQ_DIFF_SESSION, ST_SEND_FRAG_WAIT, "send frag_wait"), + ST_DEFINE( + ST_RECEIVING, EV_SUBSEQ_DIFF_SESSION, ST_SEND_FRAG_WAIT, "send frag_wait"), - /* Fragment request/complete/wait from different node id*/ - ST_DEFINE(ST_RECEIVING, EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE, ST_IDLE, "discard the fragment"), + /* Fragment request/complete/wait from different node id*/ + ST_DEFINE(ST_RECEIVING, + EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE, + ST_IDLE, + "discard the fragment"), - /* Fragment request/complete/wait from different session */ - ST_DEFINE(ST_RECEIVING, EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION, ST_IDLE, "discard the fragment"), + /* Fragment request/complete/wait from different session */ + ST_DEFINE(ST_RECEIVING, + EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION, + ST_IDLE, + "discard the fragment"), - /* Go back to receiving state if Fragment wait command is sent successfully */ - ST_DEFINE(ST_SEND_FRAG_WAIT, EV_SUCCESS, ST_RECEIVING, NULL), - /* Go back to sending state as the fragment wait was sent in sending session */ - ST_DEFINE(ST_SEND_FRAG_WAIT, EV_SUCCESS2, ST_SEND_FRAG, NULL), - /* Go back to ST_WAIT_ACK as the fragment wait was sent in sending session */ - ST_DEFINE(ST_SEND_FRAG_WAIT, EV_SUCCESS3, ST_WAIT_ACK, NULL), + /* Go back to receiving state if Fragment wait command is sent successfully */ + ST_DEFINE(ST_SEND_FRAG_WAIT, EV_SUCCESS, ST_RECEIVING, NULL), + /* Go back to sending state as the fragment wait was sent in sending session */ + ST_DEFINE(ST_SEND_FRAG_WAIT, EV_SUCCESS2, ST_SEND_FRAG, NULL), + /* Go back to ST_WAIT_ACK as the fragment wait was sent in sending session */ + ST_DEFINE(ST_SEND_FRAG_WAIT, EV_SUCCESS3, ST_WAIT_ACK, NULL), - /* TODO. What if sending fragment wait command fails ?*/ + /* TODO. What if sending fragment wait command fails ?*/ - /* If Fragment complete has been sent to sending node successfully, Go back to receiving + /* If Fragment complete has been sent to sending node successfully, Go back to receiving * state */ - ST_DEFINE(ST_SEND_FRAG_COMPLETE, EV_SUCCESS, ST_IDLE, NULL), - /*After sending one fragment request go back to receiving state, either we will receive + ST_DEFINE(ST_SEND_FRAG_COMPLETE, EV_SUCCESS, ST_IDLE, NULL), + /*After sending one fragment request go back to receiving state, either we will receive another fragment request of fragment complete */ - ST_DEFINE(ST_SEND_FRAG_REQ, EV_SUCCESS, ST_RECEIVING, NULL), + ST_DEFINE(ST_SEND_FRAG_REQ, EV_SUCCESS, ST_RECEIVING, NULL), - /* If RX timer event happens while ST_RECEIVING */ - ST_DEFINE(ST_RECEIVING, EV_FRAG_RX_TIMER, ST_FIND_MISS_FRAG, "find_missing"), - /* If there is Fragment Rx timer event whiel sending Fragment Req command discard all the previous + /* If RX timer event happens while ST_RECEIVING */ + ST_DEFINE(ST_RECEIVING, EV_FRAG_RX_TIMER, ST_FIND_MISS_FRAG, "find_missing"), + /* If there is Fragment Rx timer event whiel sending Fragment Req command discard all the previous * Discard received fragmets in the datagram and go to Idle state */ - ST_DEFINE(ST_IDLE, EV_FRAG_RX_TIMER, ST_IDLE, "discard_all_received_fragments"), + ST_DEFINE( + ST_IDLE, EV_FRAG_RX_TIMER, ST_IDLE, "discard_all_received_fragments"), - /* If the fragment received is broadcast fragment while receiving another fragmented datagram, + /* If the fragment received is broadcast fragment while receiving another fragmented datagram, * Receiving node needs to drop that fragment */ - ST_DEFINE(ST_RECEIVING, EV_BCAST_DIFF_NODE, ST_RECEIVING, "drop_fragment"), + ST_DEFINE(ST_RECEIVING, EV_BCAST_DIFF_NODE, ST_RECEIVING, "drop_fragment"), - ST_DEFINE(ST_RECEIVING, EV_RECV_LAST_FRAG, ST_FIND_MISS_FRAG, "find_missing"), - ST_DEFINE(ST_WAIT_ACK, EV_SEND_FRAG_COMPLETE, ST_SEND_FRAG_COMPLETE, NULL), - ST_DEFINE(ST_RECEIVING, EV_RECV_FRAG_COMPL, ST_IDLE, NULL), + ST_DEFINE(ST_RECEIVING, EV_RECV_LAST_FRAG, ST_FIND_MISS_FRAG, "find_missing"), + ST_DEFINE(ST_WAIT_ACK, EV_SEND_FRAG_COMPLETE, ST_SEND_FRAG_COMPLETE, NULL), + ST_DEFINE(ST_RECEIVING, EV_RECV_FRAG_COMPL, ST_IDLE, NULL), - /* Stay in the same state ST_WAIT_ACK until we know if its REQUEST OR COMPLETE cmd */ - ST_DEFINE(ST_WAIT_ACK, EV_FRAG_REQ_OR_COMPL, ST_WAIT_ACK, NULL), + /* Stay in the same state ST_WAIT_ACK until we know if its REQUEST OR COMPLETE cmd */ + ST_DEFINE(ST_WAIT_ACK, EV_FRAG_REQ_OR_COMPL, ST_WAIT_ACK, NULL), - /* If the rx timer expires after sending Fragment Request, discard all fragments and go to IDLE state */ - ST_DEFINE(ST_WAIT_ACK, EV_FRAG_RX_TIMER, ST_IDLE, "discard all fragments"), + /* If the rx timer expires after sending Fragment Request, discard all fragments and go to IDLE state */ + ST_DEFINE(ST_WAIT_ACK, EV_FRAG_RX_TIMER, ST_IDLE, "discard all fragments"), - /* Need to move to ST_RECEIVING state to process the FRAGMENT_REQUEST or FRAGMENT_COMPLETE received while sending */ - ST_DEFINE(ST_RECEIVING, EV_FRAG_REQ_OR_COMPL, ST_RECEIVING, "process received"), - ST_DEFINE(ST_SEND_FRAG, EV_FRAG_REQ_OR_COMPL, ST_RECEIVING, "process received"), + /* Need to move to ST_RECEIVING state to process the FRAGMENT_REQUEST or FRAGMENT_COMPLETE received while sending */ + ST_DEFINE( + ST_RECEIVING, EV_FRAG_REQ_OR_COMPL, ST_RECEIVING, "process received"), + ST_DEFINE( + ST_SEND_FRAG, EV_FRAG_REQ_OR_COMPL, ST_RECEIVING, "process received"), - /* If there are missing frames, receiving node needs to send Fragment request command to + /* If there are missing frames, receiving node needs to send Fragment request command to * sending node */ - ST_DEFINE(ST_FIND_MISS_FRAG, EV_MISSING_FRAG, ST_SEND_FRAG_REQ, "send_frag_req_cmd"), - /* If the broacast fragment is being received and rx timer times out of there are some missing fragments*/ - ST_DEFINE(ST_FIND_MISS_FRAG, EV_MISSING_FRAG_BCAST, ST_IDLE, NULL), - /* If all the fragments of the datagram are receivied receiving node needs to send + ST_DEFINE( + ST_FIND_MISS_FRAG, EV_MISSING_FRAG, ST_SEND_FRAG_REQ, "send_frag_req_cmd"), + /* If the broacast fragment is being received and rx timer times out of there are some missing fragments*/ + ST_DEFINE(ST_FIND_MISS_FRAG, EV_MISSING_FRAG_BCAST, ST_IDLE, NULL), + /* If all the fragments of the datagram are receivied receiving node needs to send * Fragment complete command to sending node. */ - ST_DEFINE(ST_FIND_MISS_FRAG, EV_SEND_FRAG_COMPLETE, ST_SEND_FRAG_COMPLETE, "send_frag_complete_cmd"), - - /* NO need to send frag complete if it was bcast datagram which was being recived */ - ST_DEFINE(ST_FIND_MISS_FRAG, EV_NO_SEND_FRAG_COMPLETE, ST_IDLE, NULL), + ST_DEFINE(ST_FIND_MISS_FRAG, + EV_SEND_FRAG_COMPLETE, + ST_SEND_FRAG_COMPLETE, + "send_frag_complete_cmd"), - /* ======================*/ - /* Sending State diagram */ - /* ======================*/ + /* NO need to send frag complete if it was bcast datagram which was being recived */ + ST_DEFINE(ST_FIND_MISS_FRAG, EV_NO_SEND_FRAG_COMPLETE, ST_IDLE, NULL), + /* ======================*/ + /* Sending State diagram */ + /* ======================*/ - ST_DEFINE(ST_SEND_FRAG, EV_RECV_FRAG_WAIT, ST_SEND_FRAG, "wait_restart_from_first"), + ST_DEFINE( + ST_SEND_FRAG, EV_RECV_FRAG_WAIT, ST_SEND_FRAG, "wait_restart_from_first"), - /* ST_SEND_FRAG ->(EV_TIE_BREAK) -> ST_RECEIVING ->(EV_RECV_NEW_FRAG) ->( EV_RECV_FRAG_WAIT )*/ - ST_DEFINE(ST_RECEIVING, EV_RECV_FRAG_WAIT, ST_SEND_FRAG, "wait_restart_from_first"), + /* ST_SEND_FRAG ->(EV_TIE_BREAK) -> ST_RECEIVING ->(EV_RECV_NEW_FRAG) ->( EV_RECV_FRAG_WAIT )*/ + ST_DEFINE( + ST_RECEIVING, EV_RECV_FRAG_WAIT, ST_SEND_FRAG, "wait_restart_from_first"), - ST_DEFINE(ST_SEND_FRAG, EV_SEND_LAST_FRAG, ST_SEND_LAST_FRAG, "send_last_frag"), - ST_DEFINE(ST_SEND_FRAG, EV_SEND_LAST_MISS_FRAG, ST_SEND_LAST_FRAG, "send_last_frag"), + ST_DEFINE( + ST_SEND_FRAG, EV_SEND_LAST_FRAG, ST_SEND_LAST_FRAG, "send_last_frag"), + ST_DEFINE( + ST_SEND_FRAG, EV_SEND_LAST_MISS_FRAG, ST_SEND_LAST_FRAG, "send_last_frag"), - ST_DEFINE(ST_SEND_LAST_FRAG, EV_SUCCESS, ST_WAIT_ACK, NULL), - /* If the Fragment completion timer even happens send the last fragment again */ - ST_DEFINE(ST_WAIT_ACK, EV_FRAG_COMPL_TIMER, ST_SEND_LAST_FRAG, "send_last_frag"), + ST_DEFINE(ST_SEND_LAST_FRAG, EV_SUCCESS, ST_WAIT_ACK, NULL), + /* If the Fragment completion timer even happens send the last fragment again */ + ST_DEFINE( + ST_WAIT_ACK, EV_FRAG_COMPL_TIMER, ST_SEND_LAST_FRAG, "send_last_frag"), - /* fc_timer_expired in reply_frag_req*/ - ST_DEFINE(ST_WAIT_ACK, EV_FRAG_COMPL_TIMER_REQ, ST_IDLE, "send failure to application"), + /* fc_timer_expired in reply_frag_req*/ + ST_DEFINE(ST_WAIT_ACK, + EV_FRAG_COMPL_TIMER_REQ, + ST_IDLE, + "send failure to application"), - /* If the Fragment completion timer event happens again send error to application */ - ST_DEFINE(ST_WAIT_ACK, EV_FRAG_COMPL_TIMER2, ST_IDLE, NULL), + /* If the Fragment completion timer event happens again send error to application */ + ST_DEFINE(ST_WAIT_ACK, EV_FRAG_COMPL_TIMER2, ST_IDLE, NULL), - /* Failure in sending last fragment second time after one Fragment completion timer event */ - /*P.S. This is not failure in sending the last fragment at first time */ - ST_DEFINE(ST_WAIT_ACK, EV_FAILURE_LAST_FRAG2, ST_IDLE, NULL), + /* Failure in sending last fragment second time after one Fragment completion timer event */ + /*P.S. This is not failure in sending the last fragment at first time */ + ST_DEFINE(ST_WAIT_ACK, EV_FAILURE_LAST_FRAG2, ST_IDLE, NULL), - /* If received Fragment request command */ - ST_DEFINE(ST_WAIT_ACK, EV_RECV_FRAG_REQ, ST_SEND_FRAG, "reply_frag_req"), - ST_DEFINE(ST_RECEIVING, EV_RECV_FRAG_REQ, ST_SEND_FRAG, "reply_frag_req"), + /* If received Fragment request command */ + ST_DEFINE(ST_WAIT_ACK, EV_RECV_FRAG_REQ, ST_SEND_FRAG, "reply_frag_req"), + ST_DEFINE(ST_RECEIVING, EV_RECV_FRAG_REQ, ST_SEND_FRAG, "reply_frag_req"), - /* If received Fragment complete command, disable the fragment complete timer*/ - ST_DEFINE(ST_WAIT_ACK, EV_RECV_FRAG_COMPL, ST_IDLE, NULL), + /* If received Fragment complete command, disable the fragment complete timer*/ + ST_DEFINE(ST_WAIT_ACK, EV_RECV_FRAG_COMPL, ST_IDLE, NULL), - ST_DEFINE(ST_SEND_FRAG, EV_SEND_NXT_MISS_FRAG, ST_SEND_FRAG, "reply_frag_req"), - ST_DEFINE(ST_SEND_FRAG, EV_FRAG_COMPL_TIMER, ST_IDLE, "wait"), + ST_DEFINE( + ST_SEND_FRAG, EV_SEND_NXT_MISS_FRAG, ST_SEND_FRAG, "reply_frag_req"), + ST_DEFINE(ST_SEND_FRAG, EV_FRAG_COMPL_TIMER, ST_IDLE, "wait"), - /* This happens when the FC_complete timer happens before reply_frag_req() gets a callback + /* This happens when the FC_complete timer happens before reply_frag_req() gets a callback state machine is still in ST_SEND_FRAG as it goes in ST_WAIT_ACK in the callback*/ - ST_DEFINE(ST_SEND_FRAG, EV_FRAG_COMPL_TIMER_REQ, ST_IDLE, "wait"), + ST_DEFINE(ST_SEND_FRAG, EV_FRAG_COMPL_TIMER_REQ, ST_IDLE, "wait"), - ST_DEFINE(ST_SEND_FRAG, EV_SENT_MISS_FRAG, ST_WAIT_ACK, NULL), - ST_DEFINE(ST_SEND_FRAG, EV_TIE_BREAK, ST_RECEIVING, "receive"), - ST_DEFINE(ST_SEND_LAST_FRAG, EV_TIE_BREAK, ST_RECEIVING, "receive"), - ST_DEFINE(ST_WAIT_ACK, EV_RECV_FRAG_WAIT, ST_SEND_FRAG, NULL), + ST_DEFINE(ST_SEND_FRAG, EV_SENT_MISS_FRAG, ST_WAIT_ACK, NULL), + ST_DEFINE(ST_SEND_FRAG, EV_TIE_BREAK, ST_RECEIVING, "receive"), + ST_DEFINE(ST_SEND_LAST_FRAG, EV_TIE_BREAK, ST_RECEIVING, "receive"), + ST_DEFINE(ST_WAIT_ACK, EV_RECV_FRAG_WAIT, ST_SEND_FRAG, NULL), - /* If the ZW_SendData() function itself fails we go back to IDLE state + /* If the ZW_SendData() function itself fails we go back to IDLE state The other side will send fragment request command. But we need to be in IDLE state to atleast receive and process it */ - ST_DEFINE(ST_SEND_LAST_FRAG, EV_FAIL, ST_IDLE, NULL), - ST_DEFINE(ST_WAIT_ACK, EV_TIE_BREAK, ST_RECEIVING, "receive"), + ST_DEFINE(ST_SEND_LAST_FRAG, EV_FAIL, ST_IDLE, NULL), + ST_DEFINE(ST_WAIT_ACK, EV_TIE_BREAK, ST_RECEIVING, "receive"), }; TRANSPORT2_ST_T current_state = ST_IDLE; uint8_t find_transition(TRANSPORT2_ST_T cstate, TRANSPORT2_EV_T event) { - uint8_t num_trans; - - num_trans = sizeof(trans) / sizeof(trans[0]); /* FIXME better to move it inside some init function */ - while(num_trans--) { - if ((cstate == trans[num_trans].st) && (event == trans[num_trans].ev)) - return num_trans+1; - } - - return 0; + uint8_t num_trans; + + num_trans + = sizeof(trans) + / sizeof( + trans[0]); /* FIXME better to move it inside some init function */ + while (num_trans--) { + if ((cstate == trans[num_trans].st) && (event == trans[num_trans].ev)) + return num_trans + 1; + } + + return 0; } void t2_sm_post_event(TRANSPORT2_EV_T ev) { -/* + /* function fn; */ - uint8_t i; + uint8_t i; - i = find_transition(current_state, ev); - if (i) { - current_state = trans[i-1].next_st; - } + i = find_transition(current_state, ev); + if (i) { + current_state = trans[i - 1].next_st; + } } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.h index 86f98eef8..0426cbb8b 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport2_fsm.h @@ -11,63 +11,63 @@ /* States */ typedef enum TRANSPORT2_STATES { - ST_IDLE, + ST_IDLE, - /* Receive state machine states */ - ST_RECEIVING, - ST_SEND_FRAG_COMPLETE, - ST_SEND_FRAG_REQ, - ST_SEND_FRAG_WAIT, - ST_FIND_MISS_FRAG, + /* Receive state machine states */ + ST_RECEIVING, + ST_SEND_FRAG_COMPLETE, + ST_SEND_FRAG_REQ, + ST_SEND_FRAG_WAIT, + ST_FIND_MISS_FRAG, - /* Send state machine states */ - ST_SEND_FRAG, - ST_SEND_LAST_FRAG, - ST_WAIT_ACK, + /* Send state machine states */ + ST_SEND_FRAG, + ST_SEND_LAST_FRAG, + ST_WAIT_ACK, } TRANSPORT2_ST_T; typedef enum TRANSPORT2_EVENTS { - /* Receive state machine events */ - EV_START_RECV, - EV_RECV_NEW_FRAG, - EV_NO_SESSION_ID, - EV_SEND_FRAG_COMPLETE, - EV_NO_SEND_FRAG_COMPLETE, - EV_SUCCESS, - EV_SUCCESS2, - EV_SUCCESS3, - EV_FRAG_RX_TIMER, - EV_MISSING_FRAG, - EV_MISSING_FRAG_BCAST, - EV_SCAST_DIFF_NODE, - EV_BCAST_DIFF_NODE, - EV_DIFF_SESSION, - EV_SUBSEQ_DIFF_SESSION, - EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION, - EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE, - EV_RECV_FRAG_REQ, - EV_RECV_LAST_FRAG, - EV_RECV_FRAG_COMPLETE, - EV_TIE_BREAK, - EV_DUPL_FRAME, - EV_FRAG_REQ_OR_COMPL, + /* Receive state machine events */ + EV_START_RECV, + EV_RECV_NEW_FRAG, + EV_NO_SESSION_ID, + EV_SEND_FRAG_COMPLETE, + EV_NO_SEND_FRAG_COMPLETE, + EV_SUCCESS, + EV_SUCCESS2, + EV_SUCCESS3, + EV_FRAG_RX_TIMER, + EV_MISSING_FRAG, + EV_MISSING_FRAG_BCAST, + EV_SCAST_DIFF_NODE, + EV_BCAST_DIFF_NODE, + EV_DIFF_SESSION, + EV_SUBSEQ_DIFF_SESSION, + EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION, + EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE, + EV_RECV_FRAG_REQ, + EV_RECV_LAST_FRAG, + EV_RECV_FRAG_COMPLETE, + EV_TIE_BREAK, + EV_DUPL_FRAME, + EV_FRAG_REQ_OR_COMPL, - /* Send state machine events */ - EV_START_SEND, - EV_SEND_NEW_FRAG, - EV_SEND_NXT_MISS_FRAG, - EV_SENT_MISS_FRAG, - EV_RECV_FRAG_WAIT, - EV_SEND_LAST_FRAG, - EV_SEND_LAST_MISS_FRAG, - EV_FRAG_COMPL_TIMER, - EV_FRAG_COMPL_TIMER2, - EV_FRAG_COMPL_TIMER_REQ, - EV_FAILURE_LAST_FRAG2, - EV_RECV_FRAG_COMPL, - EV_REPLY_FRAG_REQ_DONE, - EV_FAIL, + /* Send state machine events */ + EV_START_SEND, + EV_SEND_NEW_FRAG, + EV_SEND_NXT_MISS_FRAG, + EV_SENT_MISS_FRAG, + EV_RECV_FRAG_WAIT, + EV_SEND_LAST_FRAG, + EV_SEND_LAST_MISS_FRAG, + EV_FRAG_COMPL_TIMER, + EV_FRAG_COMPL_TIMER2, + EV_FRAG_COMPL_TIMER_REQ, + EV_FAILURE_LAST_FRAG2, + EV_RECV_FRAG_COMPL, + EV_REPLY_FRAG_REQ_DONE, + EV_FAIL, } TRANSPORT2_EV_T; diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.c b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.c index 03748432c..0a140c82d 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.c @@ -8,7 +8,13 @@ #include "transport2_fsm.h" #ifdef ZIPGW -extern bool TS_SEND_RAW(nodeid_t snode, nodeid_t dnode, uint8_t *cmd, uint8_t len, uint8_t flags, VOID_CALLBACKFUNC(completedFunc)(uint8_t, TX_STATUS_TYPE*)); +extern bool TS_SEND_RAW(nodeid_t snode, + nodeid_t dnode, + uint8_t *cmd, + uint8_t len, + uint8_t flags, + VOID_CALLBACKFUNC(completedFunc)(uint8_t, + TX_STATUS_TYPE *)); #include #include "ctimer.h" @@ -18,23 +24,22 @@ extern bool TS_SEND_RAW(nodeid_t snode, nodeid_t dnode, uint8_t *cmd, uint8_t le /** ID of this node */ extern BYTE MyNodeID; /* Instead of including ZIP_Router.h */ -#else // ifdef ZIPGW +#else // ifdef ZIPGW #include "ZW_ctimer.h" #endif - #include -#if defined (EFR32ZG) || defined(ZWAVE_ON_LINUX) - #include - #include - #include - #define CRC_FUNC CRC_CheckCrc16 - #include "zpal_entropy.h" +#if defined(EFR32ZG) || defined(ZWAVE_ON_LINUX) +#include +#include +#include +#define CRC_FUNC CRC_CheckCrc16 +#include "zpal_entropy.h" #endif #ifdef NEW_TEST_T2 -#define CRC_POLY 0x1021 -#define CRC_INIT_VALUE 0x1D0F +#define CRC_POLY 0x1021 +#define CRC_INIT_VALUE 0x1D0F uint16_t zgw_crc16(uint16_t crc16, uint8_t *data, unsigned long data_len); #define CRC_FUNC zgw_crc16 #endif @@ -46,93 +51,107 @@ static void send_subseq_frag(void *); static void find_missing(); struct rx_timer_expired_data { - uint8_t state; /* Rx timer expired after sending SEG_REQ or after sending */ + uint8_t state; /* Rx timer expired after sending SEG_REQ or after sending */ }; static void rx_timer_expired(void *); - #if defined(NEW_TEST_T2) - #ifdef ZIPGW /* For NEW_TEST_T2 */ -typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t* p, ZW_APPLICATION_TX_BUFFER *pCmd, uint16_t cmdLength); +typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t *p, + ZW_APPLICATION_TX_BUFFER *pCmd, + uint16_t cmdLength); /* For NEW_TEST_T2 */ -#define ZIPCommandHandler(srcNode, count) \ - if(TSApplicationCommandHandler) {\ - ts_param_t p; \ - p.dendpoint = 0; \ - p.sendpoint = 0; \ - p.snode = srcNode; \ - p.dnode = rcb.cmn.p.dnode; \ - p.rx_flags =0; \ - p.tx_flags = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_EXPLORE;\ - p.scheme = NO_SCHEME; \ - TSApplicationCommandHandler(&p,(ZW_APPLICATION_TX_BUFFER*) rcb.datagramData, count); \ - } +#define ZIPCommandHandler(srcNode, count) \ + if (TSApplicationCommandHandler) { \ + ts_param_t p; \ + p.dendpoint = 0; \ + p.sendpoint = 0; \ + p.snode = srcNode; \ + p.dnode = rcb.cmn.p.dnode; \ + p.rx_flags = 0; \ + p.tx_flags = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE \ + | TRANSMIT_OPTION_EXPLORE; \ + p.scheme = NO_SCHEME; \ + TSApplicationCommandHandler(&p, \ + (ZW_APPLICATION_TX_BUFFER *)rcb.datagramData, \ + count); \ + } #endif -void test_rx_timer_expired(uint8_t state) { /* For NEW_TEST_T2 */ - struct rx_timer_expired_data rdata; - rdata.state = state; - rx_timer_expired(&rdata); +void test_rx_timer_expired(uint8_t state) +{ /* For NEW_TEST_T2 */ + struct rx_timer_expired_data rdata; + rdata.state = state; + rx_timer_expired(&rdata); } -#else // if defined(NEW_TEST_T2) +#else // if defined(NEW_TEST_T2) #ifdef ZIPGW -typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t* p, ZW_APPLICATION_TX_BUFFER *pCmd, uint16_t cmdLength); - -typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t* p, ZW_APPLICATION_TX_BUFFER *pCmd, uint16_t cmdLength); - -#define ZIPCommandHandler(srcNode, count) \ - if(TSApplicationCommandHandler) {\ - ts_param_t p; \ - p.dendpoint = 0; \ - p.sendpoint = 0; \ - p.snode = srcNode; \ - p.dnode = rcb.cmn.p.dnode; \ - p.rx_flags =0; \ - p.tx_flags = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_EXPLORE;\ - p.scheme = NO_SCHEME; \ - TSApplicationCommandHandler(&p,(ZW_APPLICATION_TX_BUFFER*) rcb.datagramData, count); \ - } +typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t *p, + ZW_APPLICATION_TX_BUFFER *pCmd, + uint16_t cmdLength); + +typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t *p, + ZW_APPLICATION_TX_BUFFER *pCmd, + uint16_t cmdLength); + +#define ZIPCommandHandler(srcNode, count) \ + if (TSApplicationCommandHandler) { \ + ts_param_t p; \ + p.dendpoint = 0; \ + p.sendpoint = 0; \ + p.snode = srcNode; \ + p.dnode = rcb.cmn.p.dnode; \ + p.rx_flags = 0; \ + p.tx_flags = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE \ + | TRANSMIT_OPTION_EXPLORE; \ + p.scheme = NO_SCHEME; \ + TSApplicationCommandHandler(&p, \ + (ZW_APPLICATION_TX_BUFFER *)rcb.datagramData, \ + count); \ + } -#define TS_SEND_RAW(src, dst, buf, buflen, txopt, cb) ZW_SendData_Bridge(src, dst, buf, buflen, txopt, cb) +#define TS_SEND_RAW(src, dst, buf, buflen, txopt, cb) \ + ZW_SendData_Bridge(src, dst, buf, buflen, txopt, cb) #endif -extern uint8_t ZW_SendData_Bridge(uint8_t, uint8_t, uint8_t *, uint8_t, uint8_t, VOID_CALLBACKFUNC(completedFunc)(uint8_t, TX_STATUS_TYPE*)); +extern uint8_t ZW_SendData_Bridge( + uint8_t, + uint8_t, + uint8_t *, + uint8_t, + uint8_t, + VOID_CALLBACKFUNC(completedFunc)(uint8_t, TX_STATUS_TYPE *)); #endif -static uint8_t flag_initialize_once = 1; // to initialize the receive session stuff once +static uint8_t flag_initialize_once + = 1; // to initialize the receive session stuff once extern const char *T2_EVENTS_STRING[]; extern const char *T2_STATES_STRING[]; - #if !defined(ZIPGW) -#define CRC_POLY 0x1021 -uint16_t -ZW_CheckCrc16(uint16_t crc, uint8_t *pDataAddr, uint16_t bDataLen) +#define CRC_POLY 0x1021 +uint16_t ZW_CheckCrc16(uint16_t crc, uint8_t *pDataAddr, uint16_t bDataLen) { uint8_t WorkData; uint8_t bitMask; uint8_t NewBit; - while (bDataLen--) - { + while (bDataLen--) { WorkData = *pDataAddr++; - for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) - { + for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) { /* Align test bit with next bit of the message byte, starting with msb. */ NewBit = ((WorkData & bitMask) != 0) ^ ((crc & 0x8000) != 0); crc <<= 1; - if (NewBit) - { + if (NewBit) { crc ^= CRC_POLY; } } /* for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) */ @@ -153,11 +172,13 @@ static uint8_t FragmentMaxPayload = 0; /* ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME has the max size in transport service header * subtracting 1 for payload field inside ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME */ -uint8_t t2_txBuf[FRAGMENTMAXPAYLOAD + sizeof(ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME) - 1]; - -ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME *first_frag = (ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME *)t2_txBuf; -ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME *subseq_frag = (ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME *)t2_txBuf; +uint8_t t2_txBuf[FRAGMENTMAXPAYLOAD + + sizeof(ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME) - 1]; +ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME *first_frag + = (ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME *)t2_txBuf; +ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME *subseq_frag + = (ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME *)t2_txBuf; static void send_last_frag(void); static void reply_frag_req(void *); @@ -167,66 +188,70 @@ static uint8_t discard_all_received_fragments(void); /* Structure desribing the inflight fragment. */ typedef struct cb { - ts_param_t p; + ts_param_t p; #ifdef ZIPGW - void (*completedFunc)(uint8_t txStatus, TX_STATUS_TYPE *t); + void (*completedFunc)(uint8_t txStatus, TX_STATUS_TYPE *t); #else - ZW_TransportService_SendData_Callback_t completedFunc; + ZW_TransportService_SendData_Callback_t completedFunc; #endif #if defined(ZIPGW) - TX_STATUS_TYPE tx_status; + TX_STATUS_TYPE tx_status; #endif - uint8_t session_id; - uint8_t pending_segments; -}control_block_t; + uint8_t session_id; + uint8_t pending_segments; +} control_block_t; struct sending_cntrl_blk { - uint16_t datalen_to_send; // this is set to FragmentMaxPayload or remaining data less than FragmentMaxPayload - uint16_t missing_offset; // this is set to missing offset received in FRAMENT_REQUEST command and used to resend that fragment - uint16_t offset; // this is used in sending side - uint16_t remaining_data_len; // this records the len of remaining data to be sent - control_block_t cmn; /* Common fields, necessary for both sending and receiving */ - const uint8_t *datagram; - uint16_t datagram_len; - uint8_t sending; - uint8_t flag_replied_frag_req; - uint8_t transmission_aborted; /*Initializing to out of range session id */ + uint16_t + datalen_to_send; // this is set to FragmentMaxPayload or remaining data less than FragmentMaxPayload + uint16_t + missing_offset; // this is set to missing offset received in FRAMENT_REQUEST command and used to resend that fragment + uint16_t offset; // this is used in sending side + uint16_t + remaining_data_len; // this records the len of remaining data to be sent + control_block_t + cmn; /* Common fields, necessary for both sending and receiving */ + const uint8_t *datagram; + uint16_t datagram_len; + uint8_t sending; + uint8_t flag_replied_frag_req; + uint8_t transmission_aborted; /*Initializing to out of range session id */ #define RESET_TIME 5000 /* ms */ - struct ctimer reset_timer; + struct ctimer reset_timer; - /* When fragment wait is received with pending segments this timer is used to halt the restart of datagram sending + /* When fragment wait is received with pending segments this timer is used to halt the restart of datagram sending by 100ms * no_of_pending_segments */ - struct ctimer wait_restart_timer; + struct ctimer wait_restart_timer; - /*Timer used to keep delay between two fragments sent typically 15ms */ - struct ctimer timer_btwn_2_frags; + /*Timer used to keep delay between two fragments sent typically 15ms */ + struct ctimer timer_btwn_2_frags; - /* Array to mark the receival of Fragment Completion command for each sending session */ - /* As there could be max 16 sessions (4 bits for the session id) */ - uint8_t frag_compl_list[15]; + /* Array to mark the receival of Fragment Completion command for each sending session */ + /* As there could be max 16 sessions (4 bits for the session id) */ + uint8_t frag_compl_list[15]; - /* If the session is sending one then this flag is set to true to mark that next send is going to be + /* If the session is sending one then this flag is set to true to mark that next send is going to be fragment wait. If the session is receiving send_frag_wait_cmd() is called directly */ - /*FIXME this and sending flags can be merged into one */ - uint8_t flag_send_frag_wait; - uint8_t flag_reply_frag_req; - ts_param_t frag_wait_p; + /*FIXME this and sending flags can be merged into one */ + uint8_t flag_send_frag_wait; + uint8_t flag_reply_frag_req; + ts_param_t frag_wait_p; - uint16_t round_trip_first_frag; + uint16_t round_trip_first_frag; - /* This flag is used to mark that there have been mutliple fc_timer expiration + /* This flag is used to mark that there have been mutliple fc_timer expiration * for this fragment complete * So that transport service can report error to the application layer */ - uint8_t flag_fc_timer_expired_once; + uint8_t flag_fc_timer_expired_once; - /* this stores the current destination node where the send session is going on. If a fragment + /* this stores the current destination node where the send session is going on. If a fragment request from different node is received this helps identifying it */ - node_t current_dnode; + node_t current_dnode; - /* Used to determine if the send_last_frag() function is called from send_first_frag() + /* Used to determine if the send_last_frag() function is called from send_first_frag() * or send_subseq_frag()/reply_frag_req */ - uint8_t does_not_fit_in_first_frag; + uint8_t does_not_fit_in_first_frag; } scb; @@ -235,41 +260,42 @@ struct sending_cntrl_blk { TRANSMIT_OPTIONS_TYPE ts_txo; #endif - struct receiving_cntrl_blk { - control_block_t cmn; /* Common fields, necessary for both sending and receiving */ - uint8_t *fragment; - uint8_t fragment_len; - uint8_t flag_retry_frag_req_once; - /* Fragment Completion timer */ - struct ctimer fc_timer; - /*RX timer */ - struct ctimer rx_timer; + control_block_t + cmn; /* Common fields, necessary for both sending and receiving */ + uint8_t *fragment; + uint8_t fragment_len; + uint8_t flag_retry_frag_req_once; + /* Fragment Completion timer */ + struct ctimer fc_timer; + /*RX timer */ + struct ctimer rx_timer; - struct rx_timer_expired_data rx_data; + struct rx_timer_expired_data rx_data; - /* Array to mark the receival of whole Fragment (sending of fragment complete) command for each receiving session */ - /* As there could be max 16 sessions (4 bits for the session id) */ - uint8_t recv_frag_compl_list[16]; + /* Array to mark the receival of whole Fragment (sending of fragment complete) command for each receiving session */ + /* As there could be max 16 sessions (4 bits for the session id) */ + uint8_t recv_frag_compl_list[16]; - /* Buffer for incoming re-assembled datagrams */ - uint8_t datagramData[DATAGRAM_SIZE_MAX]; + /* Buffer for incoming re-assembled datagrams */ + uint8_t datagramData[DATAGRAM_SIZE_MAX]; - /* To copy the data to destination buffer */ - uint8_t cur_recvd_data_size; + /* To copy the data to destination buffer */ + uint8_t cur_recvd_data_size; - /* this is set to the source node id on receiving FIRST_FRAG, and used in checking + /* this is set to the source node id on receiving FIRST_FRAG, and used in checking all subseq fragments and (first fragments if any before the transmissin of current datagram is done). This variable is set back to 0 on sending FRAG_COMPL or when the datagram is discarded */ - /*Used on receiving side */ - node_t current_snode; + /*Used on receiving side */ + node_t current_snode; - /* Mark each byte recived in a bit Then used to find missing + /* Mark each byte recived in a bit Then used to find missing * fragments/offsets if any */ - uint8_t bytes_recvd_bitmask[ (DATAGRAM_SIZE_MAX / 8) + 1 ]; //Bit for each byte received + uint8_t bytes_recvd_bitmask[(DATAGRAM_SIZE_MAX / 8) + + 1]; //Bit for each byte received - uint16_t datagram_size; + uint16_t datagram_size; } rcb; @@ -278,33 +304,32 @@ uint16_t offset_to_request = 0; #ifdef NEW_TEST_T2 /* Test helpers that look into local data. */ int call_with_large_value = 0; /* For NEW_TEST_T2 */ -int check_flag_tie_broken() /* For NEW_TEST_T2 */ +int check_flag_tie_broken() /* For NEW_TEST_T2 */ { - return flag_tie_broken; + return flag_tie_broken; } int get_current_scb_cmnd_session_id() /* For NEW_TEST_T2 */ { - return scb.cmn.session_id; + return scb.cmn.session_id; } int check_scb_current_dnode() /* For NEW_TEST_T2 */ { - return scb.current_dnode; + return scb.current_dnode; } int check_flag_fc_timer_expired_once() /* For NEW_TEST_T2 */ { - return scb.flag_fc_timer_expired_once; + return scb.flag_fc_timer_expired_once; } int compare_received_datagram(const uint8_t *cmp_data, uint16_t len) { - if (len == rcb.datagram_size) - { - return memcmp(rcb.datagramData, cmp_data, len); - } - return -1; + if (len == rcb.datagram_size) { + return memcmp(rcb.datagramData, cmp_data, len); + } + return -1; } #endif @@ -320,9 +345,9 @@ static void reset_transport_service(__attribute__((unused)) void *ss) #define FUNC(STR) STR static uint8_t recv_or_send(void) { - switch (current_state) { + switch (current_state) { case ST_IDLE: - return 2; /*Neither sending nor receiving */ + return 2; /*Neither sending nor receiving */ /* Receive state machine states */ case ST_RECEIVING: @@ -330,115 +355,120 @@ static uint8_t recv_or_send(void) case ST_SEND_FRAG_REQ: case ST_SEND_FRAG_WAIT: case ST_FIND_MISS_FRAG: - return 1; + return 1; /* Send state machine states */ case ST_SEND_FRAG: case ST_SEND_LAST_FRAG: case ST_WAIT_ACK: - return 0; + return 0; default: - break; - } - return -1; + break; + } + return -1; } bool ZW_TransportService_Is_Receving(void) { - return (recv_or_send() == 1)? true: false; + return (recv_or_send() == 1) ? true : false; } bool ZW_TransportService_Is_Sending(void) { - return (recv_or_send() == 0)? true: false; + return (recv_or_send() == 0) ? true : false; } - #ifdef ZIPGW -bool ZW_TransportService_SendData(ts_param_t* p, const uint8_t *pData, +bool ZW_TransportService_SendData(ts_param_t *p, + const uint8_t *pData, uint16_t dataLength, - void (*completedFunc)(uint8_t txStatus, TX_STATUS_TYPE *t)) + void (*completedFunc)(uint8_t txStatus, + TX_STATUS_TYPE *t)) #else -#if defined (EFR32ZG) || defined(ZWAVE_ON_LINUX) -bool ZW_TransportService_SendData(ts_param_t* p, const uint8_t *pData, +#if defined(EFR32ZG) || defined(ZWAVE_ON_LINUX) +bool ZW_TransportService_SendData(ts_param_t *p, + const uint8_t *pData, uint16_t dataLength, - void (*completedFunc)(uint8_t txStatus, void *t)) + void (*completedFunc)(uint8_t txStatus, + void *t)) #else -bool ZW_TransportService_SendData(ts_param_t* p, uint8_t *pData, - uint16_t dataLength, - ZW_TransportService_SendData_Callback_t completedFunc) +bool ZW_TransportService_SendData( + ts_param_t *p, + uint8_t *pData, + uint16_t dataLength, + ZW_TransportService_SendData_Callback_t completedFunc) #endif #endif { #if defined(ZIPGW) - TX_STATUS_TYPE t; - memset(&t, 0, sizeof(TX_STATUS_TYPE)); + TX_STATUS_TYPE t; + memset(&t, 0, sizeof(TX_STATUS_TYPE)); #endif - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - if (ZW_TransportService_Is_Sending()) { + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + if (ZW_TransportService_Is_Sending()) { #if defined(ZIPGW) - completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &t); + completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &t); #else - completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); + completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - return false; - } - if (ZW_TransportService_Is_Receving()) { + return false; + } + if (ZW_TransportService_Is_Receving()) { #if defined(ZIPGW) - completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &t); + completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &t); #else - completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); + completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - return false; - } + return false; + } - scb.datagram = pData; - memcpy((uint8_t*)&scb.cmn.p, (uint8_t*)p, sizeof(ts_param_t)); - scb.datagram_len = dataLength; - scb.cmn.completedFunc = completedFunc; + scb.datagram = pData; + memcpy((uint8_t *)&scb.cmn.p, (uint8_t *)p, sizeof(ts_param_t)); + scb.datagram_len = dataLength; + scb.cmn.completedFunc = completedFunc; #if defined(ZIPGW) - memset((uint8_t*)&scb.cmn.tx_status, 0, sizeof(TX_STATUS_TYPE)); + memset((uint8_t *)&scb.cmn.tx_status, 0, sizeof(TX_STATUS_TYPE)); #endif - scb.sending = false; - scb.flag_replied_frag_req = 0; - scb.transmission_aborted = 0x11; /*Initializing to out of range session id */ - scb.flag_send_frag_wait = false; - scb.flag_reply_frag_req = false; - scb.round_trip_first_frag = 0; - scb.flag_fc_timer_expired_once = 0; - scb.remaining_data_len = 0; - scb.current_dnode = 0; - - scb.current_dnode = p->dnode; - switch (current_state) { - case ST_IDLE: - t2_sm_post_event(EV_START_SEND); /* send() */ - break; + scb.sending = false; + scb.flag_replied_frag_req = 0; + scb.transmission_aborted = 0x11; /*Initializing to out of range session id */ + scb.flag_send_frag_wait = false; + scb.flag_reply_frag_req = false; + scb.round_trip_first_frag = 0; + scb.flag_fc_timer_expired_once = 0; + scb.remaining_data_len = 0; + scb.current_dnode = 0; + + scb.current_dnode = p->dnode; + switch (current_state) { + case ST_IDLE: + t2_sm_post_event(EV_START_SEND); /* send() */ + break; - case ST_SEND_FRAG: - t2_sm_post_event(EV_SEND_NEW_FRAG); /* send() */ - break; + case ST_SEND_FRAG: + t2_sm_post_event(EV_SEND_NEW_FRAG); /* send() */ + break; - default: - break; - } - send_first_frag(); - return true; + default: + break; + } + send_first_frag(); + return true; } static void add_crc(uint8_t *buf, uint8_t len) { - uint8_t *tmp_buf = buf; - uint16_t crc = CRC_FUNC(0x1D0F, tmp_buf, len); - tmp_buf+=len; + uint8_t *tmp_buf = buf; + uint16_t crc = CRC_FUNC(0x1D0F, tmp_buf, len); + tmp_buf += len; // TODO, may be reworked to avoid build errors #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif - *tmp_buf++ = (crc>>8)&0xff; - *tmp_buf=(crc)&0xff; + *tmp_buf++ = (crc >> 8) & 0xff; + *tmp_buf = (crc)&0xff; #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif @@ -449,148 +479,164 @@ static uint16_t get_next_missing_offset(); /*callback frunction when fc timer expires */ void fc_timer_expired(__attribute__((unused)) void *nthing) { - if (scb.flag_replied_frag_req) { - scb.transmission_aborted = scb.cmn.session_id; - scb.flag_replied_frag_req = 0; - scb.current_dnode = 0; - t2_sm_post_event(EV_FRAG_COMPL_TIMER_REQ); - if (scb.cmn.completedFunc) { + if (scb.flag_replied_frag_req) { + scb.transmission_aborted = scb.cmn.session_id; + scb.flag_replied_frag_req = 0; + scb.current_dnode = 0; + t2_sm_post_event(EV_FRAG_COMPL_TIMER_REQ); + if (scb.cmn.completedFunc) { #if defined(ZIPGW) - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); #else - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - } - return; } + return; + } - /* This happens when in Tie break we abort a transmission and then FC completion timer + /* This happens when in Tie break we abort a transmission and then FC completion timer event happens. Need to ignore it to make sure we dont send the last fragment again and make the state machine end up in weird state */ - /* Tested in test_fc_timer_after_frag_compl_of_aborted_transmission() */ - if (scb.transmission_aborted == scb.cmn.session_id) { - if (scb.cmn.completedFunc) { + /* Tested in test_fc_timer_after_frag_compl_of_aborted_transmission() */ + if (scb.transmission_aborted == scb.cmn.session_id) { + if (scb.cmn.completedFunc) { #if defined(ZIPGW) - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); #else - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - } - return; } + return; + } - /* Tested in test_fc_timer_after_last_frag_twice() */ - if (scb.flag_fc_timer_expired_once) { - scb.flag_fc_timer_expired_once = 0; - scb.current_dnode = 0; - if (scb.cmn.completedFunc) { + /* Tested in test_fc_timer_after_last_frag_twice() */ + if (scb.flag_fc_timer_expired_once) { + scb.flag_fc_timer_expired_once = 0; + scb.current_dnode = 0; + if (scb.cmn.completedFunc) { #if defined(ZIPGW) - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); #else - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - } - t2_sm_post_event(EV_FRAG_COMPL_TIMER2); - return; } - t2_sm_post_event(EV_FRAG_COMPL_TIMER); /*send_last_frag() */ - scb.flag_fc_timer_expired_once++; - send_last_frag(); + t2_sm_post_event(EV_FRAG_COMPL_TIMER2); + return; + } + t2_sm_post_event(EV_FRAG_COMPL_TIMER); /*send_last_frag() */ + scb.flag_fc_timer_expired_once++; + send_last_frag(); } #if defined(ZIPGW) -static void ZCB_temp_callback_last_frag(unsigned char status, TX_STATUS_TYPE* ts) +static void ZCB_temp_callback_last_frag(unsigned char status, + TX_STATUS_TYPE *ts) #else -static void ZCB_temp_callback_last_frag( __attribute__((unused)) unsigned char status, __attribute__((unused)) TX_STATUS_TYPE* ts) +static void + ZCB_temp_callback_last_frag(__attribute__((unused)) unsigned char status, + __attribute__((unused)) TX_STATUS_TYPE *ts) #endif { #if defined(ZIPGW) - memcpy((uint8_t*)&scb.cmn.tx_status, ts, sizeof(TX_STATUS_TYPE)); + memcpy((uint8_t *)&scb.cmn.tx_status, ts, sizeof(TX_STATUS_TYPE)); #endif } static void send_last_frag(void) { - - uint8_t ret = 0; + uint8_t ret = 0; retry: - ctimer_stop(&rcb.fc_timer); /* FIXME this is called twice. First in send_subseq_frag() ? */ - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - scb.sending = false; - /* this is last fragment being sent, so pending_segments are 0 now */ - scb.cmn.pending_segments = 0 ; - if (scb.does_not_fit_in_first_frag) { - ret = TS_SEND_RAW(scb.cmn.p.snode,scb.cmn.p.dnode, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, - scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_temp_callback_last_frag); - } else { - ret = TS_SEND_RAW(scb.cmn.p.snode,scb.cmn.p.dnode, t2_txBuf, sizeof(*first_frag) + scb.datalen_to_send - 1, - scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_temp_callback_last_frag); - } + ctimer_stop( + &rcb + .fc_timer); /* FIXME this is called twice. First in send_subseq_frag() ? */ + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + scb.sending = false; + /* this is last fragment being sent, so pending_segments are 0 now */ + scb.cmn.pending_segments = 0; + if (scb.does_not_fit_in_first_frag) { + ret = TS_SEND_RAW(scb.cmn.p.snode, + scb.cmn.p.dnode, + t2_txBuf, + sizeof(*subseq_frag) + scb.datalen_to_send - 1, + scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_temp_callback_last_frag); + } else { + ret = TS_SEND_RAW(scb.cmn.p.snode, + scb.cmn.p.dnode, + t2_txBuf, + sizeof(*first_frag) + scb.datalen_to_send - 1, + scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_temp_callback_last_frag); + } - if (ret == 0) { - goto retry; // wtf ??? isn't the rest of the code in this if() block unreachable now ? + if (ret == 0) { + goto retry; // wtf ??? isn't the rest of the code in this if() block unreachable now ? - if (scb.flag_fc_timer_expired_once) { - if (scb.cmn.completedFunc) { + if (scb.flag_fc_timer_expired_once) { + if (scb.cmn.completedFunc) { #if defined(ZIPGW) - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, &scb.cmn.tx_status); #else - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - } - t2_sm_post_event(EV_FAILURE_LAST_FRAG2); - return; - } else { - scb.flag_fc_timer_expired_once++; /* FIXME: Assuming transmit queue overflow as expired timer */ - goto retry; - } - } -#ifdef TIMER - if ((scb.cmn.p.tx_flags == RECEIVE_STATUS_TYPE_BROAD) || - (scb.cmn.p.dnode == 0xff)) { - t2_sm_post_event(EV_MISSING_FRAG_BCAST); + } + t2_sm_post_event(EV_FAILURE_LAST_FRAG2); + return; } else { - ctimer_set(&rcb.fc_timer, FRAGMENT_FC_TIMEOUT, FUNC(fc_timer_expired), 0); - t2_sm_post_event(EV_SUCCESS); /* Go to ST_WAIT_ACK state */ + scb + .flag_fc_timer_expired_once++; /* FIXME: Assuming transmit queue overflow as expired timer */ + goto retry; } + } +#ifdef TIMER + if ((scb.cmn.p.tx_flags == RECEIVE_STATUS_TYPE_BROAD) + || (scb.cmn.p.dnode == 0xff)) { + t2_sm_post_event(EV_MISSING_FRAG_BCAST); + } else { + ctimer_set(&rcb.fc_timer, FRAGMENT_FC_TIMEOUT, FUNC(fc_timer_expired), 0); + t2_sm_post_event(EV_SUCCESS); /* Go to ST_WAIT_ACK state */ + } #endif - return; + return; } #ifdef ZIPGW -void ZCB_ts_senddata_cb(unsigned char status_send, TX_STATUS_TYPE* txStatus) +void ZCB_ts_senddata_cb(unsigned char status_send, TX_STATUS_TYPE *txStatus) #else -void ZCB_ts_senddata_cb( __attribute__((unused)) unsigned char status_send, __attribute__((unused)) TX_STATUS_TYPE* txStatus) +void ZCB_ts_senddata_cb(__attribute__((unused)) unsigned char status_send, + __attribute__((unused)) TX_STATUS_TYPE *txStatus) #endif { - /* FIXME: May be, this should be part of the specs + /* FIXME: May be, this should be part of the specs Find out how long it took for the callback of FIRST_FRAG, wait that much before sending second FRAG. if the receiving node wants to send FRAG_WAIT, this will give the receiving node little time to breath - Anders Esbensen*/ #if defined(ZIPGW) - memcpy((uint8_t*)&scb.cmn.tx_status, (uint8_t*)txStatus, sizeof(TX_STATUS_TYPE)); + memcpy((uint8_t *)&scb.cmn.tx_status, + (uint8_t *)txStatus, + sizeof(TX_STATUS_TYPE)); #endif if (scb.round_trip_first_frag) { - scb.round_trip_first_frag = clock_time() - scb.round_trip_first_frag; + scb.round_trip_first_frag = clock_time() - scb.round_trip_first_frag; - /* FIXME 500 below is added to ease the receiving side to send fragment wait if it wants to */ - scb.round_trip_first_frag += 300; - } + /* FIXME 500 below is added to ease the receiving side to send fragment wait if it wants to */ + scb.round_trip_first_frag += 300; + } - if (scb.flag_reply_frag_req) { - scb.flag_reply_frag_req = false; - reply_frag_req(NULL); - return; - } + if (scb.flag_reply_frag_req) { + scb.flag_reply_frag_req = false; + reply_frag_req(NULL); + return; + } - if(scb.flag_send_frag_wait) { - scb.flag_send_frag_wait = false; - send_frag_wait_cmd(); - return; - } - /*In order not to congest the Z-Wave network, + if (scb.flag_send_frag_wait) { + scb.flag_send_frag_wait = false; + send_frag_wait_cmd(); + return; + } + /*In order not to congest the Z-Wave network, large data transfers MUST leave transmit opportunities for her nodes in the network. If sending a command longer than two frames, a node MUST implement a delay between every transmitted frame. The @@ -600,93 +646,100 @@ void ZCB_ts_senddata_cb( __attribute__((unused)) unsigned char status_send, __at 40 kbit/s: At least 35 ms if sending more than 2 frames back-to-back 100 kbit/s: At least 15 ms if sending more than 2 frames back-to-back */ - if (scb.transmission_aborted == scb.cmn.session_id) { - ctimer_stop(&scb.timer_btwn_2_frags); - } else { - ctimer_set(&scb.timer_btwn_2_frags, 15 + (scb.round_trip_first_frag), FUNC(send_subseq_frag), 0); + if (scb.transmission_aborted == scb.cmn.session_id) { + ctimer_stop(&scb.timer_btwn_2_frags); + } else { + ctimer_set(&scb.timer_btwn_2_frags, + 15 + (scb.round_trip_first_frag), + FUNC(send_subseq_frag), + 0); #ifdef NEW_TEST_T2 send_subseq_frag(NULL); #endif - - } - scb.round_trip_first_frag = 0; + } + scb.round_trip_first_frag = 0; } static void send_subseq_frag(__attribute__((unused)) void *nthing) { - uint8_t ret = 0; + uint8_t ret = 0; - ctimer_stop(&rcb.fc_timer); - if (scb.remaining_data_len == 0) - scb.remaining_data_len = scb.datagram_len; + ctimer_stop(&rcb.fc_timer); + if (scb.remaining_data_len == 0) + scb.remaining_data_len = scb.datagram_len; - if (scb.remaining_data_len >= FragmentMaxPayload) { - scb.datalen_to_send = FragmentMaxPayload; - } else { - scb.datalen_to_send = scb.remaining_data_len; - } + if (scb.remaining_data_len >= FragmentMaxPayload) { + scb.datalen_to_send = FragmentMaxPayload; + } else { + scb.datalen_to_send = scb.remaining_data_len; + } - if (scb.frag_compl_list[scb.cmn.session_id] == true) - { - return; /*FIXME just return?*/ - } - scb.offset = scb.datagram_len - scb.remaining_data_len; - subseq_frag->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; - subseq_frag->cmd_datagramSize1 = (COMMAND_SUBSEQUENT_FRAGMENT)|((scb.datagram_len>>8)&0x07); - subseq_frag->datagramSize2 = scb.datagram_len & 0xff; -#if 0//t + if (scb.frag_compl_list[scb.cmn.session_id] == true) { + return; /*FIXME just return?*/ + } + scb.offset = scb.datagram_len - scb.remaining_data_len; + subseq_frag->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; + subseq_frag->cmd_datagramSize1 + = (COMMAND_SUBSEQUENT_FRAGMENT) | ((scb.datagram_len >> 8) & 0x07); + subseq_frag->datagramSize2 = scb.datagram_len & 0xff; +#if 0 //t if (frag_wait_once) { subseq_frag->properties2 = ((scb.cmn.session_id+1) << 3) | ((scb.offset>>8)&0x07); frag_wait_once = 0; } else #endif - /* properties2 4 MSBs are session id 4th LSB is reserved and 3 LSBs are 3 MSBs of scb.offset */ - subseq_frag->properties2 = (scb.cmn.session_id << 4) | ((scb.offset>>8) & 0x07); - /* datagramOffset2 is 8 LSBs of scb.offset */ - subseq_frag->datagramOffset2 = scb.offset & 0xff; - - memcpy((uint8_t *)&subseq_frag->payload1, (scb.datagram + scb.offset), scb.datalen_to_send); - - /*5 is size of ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME till payload field */ - add_crc((uint8_t *)&subseq_frag->cmdClass, scb.datalen_to_send + 5); - - if (scb.remaining_data_len <= FragmentMaxPayload) { - scb.does_not_fit_in_first_frag = true; - t2_sm_post_event(EV_SEND_LAST_FRAG); /* send_last_frag() */ - send_last_frag(); - return; + /* properties2 4 MSBs are session id 4th LSB is reserved and 3 LSBs are 3 MSBs of scb.offset */ + subseq_frag->properties2 + = (scb.cmn.session_id << 4) | ((scb.offset >> 8) & 0x07); + /* datagramOffset2 is 8 LSBs of scb.offset */ + subseq_frag->datagramOffset2 = scb.offset & 0xff; + + memcpy((uint8_t *)&subseq_frag->payload1, + (scb.datagram + scb.offset), + scb.datalen_to_send); + + /*5 is size of ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME till payload field */ + add_crc((uint8_t *)&subseq_frag->cmdClass, scb.datalen_to_send + 5); + + if (scb.remaining_data_len <= FragmentMaxPayload) { + scb.does_not_fit_in_first_frag = true; + t2_sm_post_event(EV_SEND_LAST_FRAG); /* send_last_frag() */ + send_last_frag(); + return; + } + // ret = send_data(&scb.cmn.p, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, ZCB_ts_senddata_cb, NULL); + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + ret = TS_SEND_RAW(scb.cmn.p.snode, + scb.cmn.p.dnode, + t2_txBuf, + sizeof(*subseq_frag) + scb.datalen_to_send - 1, + scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_ts_senddata_cb); + if (0 != ret) { + if (scb.remaining_data_len >= FragmentMaxPayload) { + scb.remaining_data_len = scb.remaining_data_len - FragmentMaxPayload; } -// ret = send_data(&scb.cmn.p, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, ZCB_ts_senddata_cb, NULL); - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - ret = TS_SEND_RAW(scb.cmn.p.snode,scb.cmn.p.dnode, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, - scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_ts_senddata_cb); - if (0 != ret) - { - if (scb.remaining_data_len >= FragmentMaxPayload) { - scb.remaining_data_len = scb.remaining_data_len - FragmentMaxPayload; - } - scb.cmn.pending_segments = scb.remaining_data_len / scb.datalen_to_send; - if (scb.remaining_data_len % scb.datalen_to_send) { - scb.cmn.pending_segments++; - } + scb.cmn.pending_segments = scb.remaining_data_len / scb.datalen_to_send; + if (scb.remaining_data_len % scb.datalen_to_send) { + scb.cmn.pending_segments++; } + } - t2_sm_post_event(EV_SEND_NEW_FRAG); /*ZCB_send_subseq_frag*/ + t2_sm_post_event(EV_SEND_NEW_FRAG); /*ZCB_send_subseq_frag*/ } /* Incase fragment wait command is received */ static void wait_restart_from_first(__attribute__((unused)) void *nthing) { - send_first_frag(); - return; + send_first_frag(); + return; } static void send_first_frag(void) { - - uint8_t ret = 0; + uint8_t ret = 0; #if 0 unsigned int iseed = (unsigned int)time(NULL); @@ -695,165 +748,188 @@ static void send_first_frag(void) srand(iseed); #endif #ifdef NEW_TEST_T2 /* session id is fixed: 0 in tests */ - scb.cmn.session_id = 0; + scb.cmn.session_id = 0; #else - if (!scb.cmn.session_id) { - /* Session id begins with random number and then keeps incrementing */ - /* Only 4 bits for session id, so max session id can be 0xf */ - #if defined (EFR32ZG) || defined(ZWAVE_ON_LINUX) - scb.cmn.session_id = zpal_get_pseudo_random() % 0x10; - #else - scb.cmn.session_id = (rand() % 0x10); - #endif - } - else { - scb.cmn.session_id++; - } - if (scb.cmn.session_id > 0xf) /*scb.cmn.session_id has only 4 bits for it */ - scb.cmn.session_id = 0; /* Being back from 0 */ + if (!scb.cmn.session_id) { +/* Session id begins with random number and then keeps incrementing */ +/* Only 4 bits for session id, so max session id can be 0xf */ +#if defined(EFR32ZG) || defined(ZWAVE_ON_LINUX) + scb.cmn.session_id = zpal_get_pseudo_random() % 0x10; +#else + scb.cmn.session_id = (rand() % 0x10); +#endif + } else { + scb.cmn.session_id++; + } + if (scb.cmn.session_id > 0xf) /*scb.cmn.session_id has only 4 bits for it */ + scb.cmn.session_id = 0; /* Being back from 0 */ #endif - scb.frag_compl_list[scb.cmn.session_id] = false; - FragmentMaxPayload = FRAGMENTMAXPAYLOAD; + scb.frag_compl_list[scb.cmn.session_id] = false; + FragmentMaxPayload = FRAGMENTMAXPAYLOAD; #ifndef NEW_TEST_T2 - if(scb.cmn.p.tx_flags & TRANSMIT_OPTION_EXPLORE) { - FragmentMaxPayload-=8; - } else if(!(scb.cmn.p.tx_flags & TRANSMIT_OPTION_NO_ROUTE)) { - FragmentMaxPayload-=8; - } + if (scb.cmn.p.tx_flags & TRANSMIT_OPTION_EXPLORE) { + FragmentMaxPayload -= 8; + } else if (!(scb.cmn.p.tx_flags & TRANSMIT_OPTION_NO_ROUTE)) { + FragmentMaxPayload -= 8; + } #endif - if (scb.remaining_data_len == 0) - scb.remaining_data_len = scb.datagram_len; + if (scb.remaining_data_len == 0) + scb.remaining_data_len = scb.datagram_len; - if (scb.datagram_len > FragmentMaxPayload) { - scb.remaining_data_len = scb.datagram_len - FragmentMaxPayload; - scb.datalen_to_send = FragmentMaxPayload; - } else { - scb.remaining_data_len = scb.datagram_len; - scb.datalen_to_send = scb.datagram_len; - } + if (scb.datagram_len > FragmentMaxPayload) { + scb.remaining_data_len = scb.datagram_len - FragmentMaxPayload; + scb.datalen_to_send = FragmentMaxPayload; + } else { + scb.remaining_data_len = scb.datagram_len; + scb.datalen_to_send = scb.datagram_len; + } - first_frag->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; + first_frag->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; - /* Take 8th, 9th and 10th bit of scb.datagram_len */ - first_frag->cmd_datagramSize1 = (COMMAND_FIRST_FRAGMENT) | ((scb.datagram_len >> 8) & 0x07); + /* Take 8th, 9th and 10th bit of scb.datagram_len */ + first_frag->cmd_datagramSize1 + = (COMMAND_FIRST_FRAGMENT) | ((scb.datagram_len >> 8) & 0x07); - /* Take 0th-7th bit of scb.datagram_len */ - first_frag->datagramSize2 = scb.datagram_len & 0xff; - first_frag->properties2 = scb.cmn.session_id << 4; /*FIXME need to check EXT and Reserved section */ + /* Take 0th-7th bit of scb.datagram_len */ + first_frag->datagramSize2 = scb.datagram_len & 0xff; + first_frag->properties2 + = scb.cmn.session_id << 4; /*FIXME need to check EXT and Reserved section */ - memcpy((uint8_t*)&first_frag->payload1, scb.datagram, scb.datalen_to_send); + memcpy((uint8_t *)&first_frag->payload1, scb.datagram, scb.datalen_to_send); - /*4 is size of ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME till payload field */ - add_crc((uint8_t *)&subseq_frag->cmdClass, scb.datalen_to_send + 4); + /*4 is size of ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME till payload field */ + add_crc((uint8_t *)&subseq_frag->cmdClass, scb.datalen_to_send + 4); - scb.cmn.pending_segments = scb.remaining_data_len / scb.datalen_to_send; - if (scb.remaining_data_len % scb.datalen_to_send) - scb.cmn.pending_segments++; + scb.cmn.pending_segments = scb.remaining_data_len / scb.datalen_to_send; + if (scb.remaining_data_len % scb.datalen_to_send) + scb.cmn.pending_segments++; - if (scb.datagram_len <= FragmentMaxPayload) { /* If it was only one fragment */ - scb.does_not_fit_in_first_frag = false; - t2_sm_post_event(EV_SEND_LAST_FRAG); /* send_last_frag() */ - send_last_frag(); - return; - } + if (scb.datagram_len + <= FragmentMaxPayload) { /* If it was only one fragment */ + scb.does_not_fit_in_first_frag = false; + t2_sm_post_event(EV_SEND_LAST_FRAG); /* send_last_frag() */ + send_last_frag(); + return; + } -// ret = send_data(&scb.cmn.p, t2_txBuf, sizeof(*first_frag) + scb.datalen_to_send - 1, ZCB_ts_senddata_cb, NULL); - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - ret = TS_SEND_RAW(scb.cmn.p.snode, scb.cmn.p.dnode, t2_txBuf, sizeof(*first_frag) + scb.datalen_to_send - 1, - scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_ts_senddata_cb); - if (ret == 0) { - return; - } + // ret = send_data(&scb.cmn.p, t2_txBuf, sizeof(*first_frag) + scb.datalen_to_send - 1, ZCB_ts_senddata_cb, NULL); + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + ret = TS_SEND_RAW(scb.cmn.p.snode, + scb.cmn.p.dnode, + t2_txBuf, + sizeof(*first_frag) + scb.datalen_to_send - 1, + scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_ts_senddata_cb); + if (ret == 0) { + return; + } - scb.round_trip_first_frag = clock_time(); + scb.round_trip_first_frag = clock_time(); - scb.sending = true; - t2_sm_post_event(EV_SEND_NEW_FRAG); /*ZCB_send_subseq_frag*/ + scb.sending = true; + t2_sm_post_event(EV_SEND_NEW_FRAG); /*ZCB_send_subseq_frag*/ } #ifdef ZIPGW -static void ZCB_temp_callback_reply_frag_req(unsigned char status, TX_STATUS_TYPE* ts) +static void ZCB_temp_callback_reply_frag_req(unsigned char status, + TX_STATUS_TYPE *ts) #else -void ZCB_temp_callback_reply_frag_req(unsigned char status, __attribute__((unused)) TX_STATUS_TYPE* ts) +void ZCB_temp_callback_reply_frag_req(unsigned char status, + __attribute__((unused)) + TX_STATUS_TYPE *ts) #endif { #if defined(ZIPGW) - memcpy((uint8_t*)&scb.cmn.tx_status, ts, sizeof(TX_STATUS_TYPE)); + memcpy((uint8_t *)&scb.cmn.tx_status, ts, sizeof(TX_STATUS_TYPE)); #endif - if (status != S2_TRANSMIT_COMPLETE_OK) { - if (scb.cmn.completedFunc) { + if (status != S2_TRANSMIT_COMPLETE_OK) { + if (scb.cmn.completedFunc) { #if defined(ZIPGW) - scb.cmn.completedFunc(status, ts); + scb.cmn.completedFunc(status, ts); #else - scb.cmn.completedFunc(status, 0); + scb.cmn.completedFunc(status, 0); #endif - } } - t2_sm_post_event(EV_SENT_MISS_FRAG); - + } + t2_sm_post_event(EV_SENT_MISS_FRAG); } /*TODO this has to be aligned in sending session similarly to send_frag_wait_cmd() */ -static void reply_frag_req(__attribute__((unused)) void* nthing) +static void reply_frag_req(__attribute__((unused)) void *nthing) { - __attribute__((unused)) uint8_t ret; - if (scb.frag_compl_list[scb.cmn.session_id] == true) { - return; - } - scb.datalen_to_send = FragmentMaxPayload; - - subseq_frag->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; + __attribute__((unused)) uint8_t ret; + if (scb.frag_compl_list[scb.cmn.session_id] == true) { + return; + } + scb.datalen_to_send = FragmentMaxPayload; - if ((scb.missing_offset + scb.datalen_to_send) > scb.datagram_len) { /*last fragment */ - scb.datalen_to_send = scb.datagram_len - scb.missing_offset; - } + subseq_frag->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; - subseq_frag->cmd_datagramSize1 = (COMMAND_SUBSEQUENT_FRAGMENT) | - ((scb.datagram_len>>8)&0x07); - subseq_frag->datagramSize2 = scb.datagram_len & 0xff; - subseq_frag->properties2 = (scb.cmn.session_id << 4) | ((scb.missing_offset>>8)&0x07); - subseq_frag->datagramOffset2 = scb.missing_offset & 0xff; - memcpy((uint8_t *)&subseq_frag->payload1, (scb.datagram + scb.missing_offset), - scb.datalen_to_send); + if ((scb.missing_offset + scb.datalen_to_send) + > scb.datagram_len) { /*last fragment */ + scb.datalen_to_send = scb.datagram_len - scb.missing_offset; + } - /* 5 is size of ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME till payload + subseq_frag->cmd_datagramSize1 + = (COMMAND_SUBSEQUENT_FRAGMENT) | ((scb.datagram_len >> 8) & 0x07); + subseq_frag->datagramSize2 = scb.datagram_len & 0xff; + subseq_frag->properties2 + = (scb.cmn.session_id << 4) | ((scb.missing_offset >> 8) & 0x07); + subseq_frag->datagramOffset2 = scb.missing_offset & 0xff; + memcpy((uint8_t *)&subseq_frag->payload1, + (scb.datagram + scb.missing_offset), + scb.datalen_to_send); + + /* 5 is size of ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME till payload * field */ - add_crc((uint8_t *)&subseq_frag->cmdClass, scb.datalen_to_send + 5); - if ((scb.missing_offset + scb.datalen_to_send) == scb.datagram_len) { /*last fragment */ - scb.does_not_fit_in_first_frag = true; - t2_sm_post_event(EV_SEND_LAST_MISS_FRAG); /* send_last_frag() */ - scb.flag_replied_frag_req = 1; - send_last_frag(); - return; - } + add_crc((uint8_t *)&subseq_frag->cmdClass, scb.datalen_to_send + 5); + if ((scb.missing_offset + scb.datalen_to_send) + == scb.datagram_len) { /*last fragment */ + scb.does_not_fit_in_first_frag = true; + t2_sm_post_event(EV_SEND_LAST_MISS_FRAG); /* send_last_frag() */ + scb.flag_replied_frag_req = 1; + send_last_frag(); + return; + } -// ret = send_data(&scb.cmn.p, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, ZCB_temp_callback_reply_frag_req, NULL); - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - if (scb.sending) { - ret = TS_SEND_RAW(scb.cmn.p.snode, scb.cmn.p.dnode, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, - scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_ts_senddata_cb); - } else { - ret = TS_SEND_RAW(scb.cmn.p.snode, scb.cmn.p.dnode, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, - scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_temp_callback_reply_frag_req); - } + // ret = send_data(&scb.cmn.p, t2_txBuf, sizeof(*subseq_frag) + scb.datalen_to_send - 1, ZCB_temp_callback_reply_frag_req, NULL); + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + if (scb.sending) { + ret = TS_SEND_RAW(scb.cmn.p.snode, + scb.cmn.p.dnode, + t2_txBuf, + sizeof(*subseq_frag) + scb.datalen_to_send - 1, + scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_ts_senddata_cb); + } else { + ret = TS_SEND_RAW(scb.cmn.p.snode, + scb.cmn.p.dnode, + t2_txBuf, + sizeof(*subseq_frag) + scb.datalen_to_send - 1, + scb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_temp_callback_reply_frag_req); + } - scb.flag_replied_frag_req = 1; - /*FIXME: After replying to fragment request, the code wait for fragment complete or another fragment request. + scb.flag_replied_frag_req = 1; + /*FIXME: After replying to fragment request, the code wait for fragment complete or another fragment request. But on receive side decision of another fragment request or fragment complete is taken when rx timer expires after 800ms this makes the FC timer here on sending side expire so adding 500ms more here */ - ctimer_set(&rcb.fc_timer, (FRAGMENT_FC_TIMEOUT + 500), FUNC(fc_timer_expired), 0); - + ctimer_set(&rcb.fc_timer, + (FRAGMENT_FC_TIMEOUT + 500), + FUNC(fc_timer_expired), + 0); } /* ---------------------------------------------------------------------------------- * receive part *----------------------------------------------------------------------------------*/ - #ifdef ZIPGW -typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t*, ZW_APPLICATION_TX_BUFFER*, uint16_t); +typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t *, + ZW_APPLICATION_TX_BUFFER *, + uint16_t); #endif ZW_CommandHandler_Callback_t TSApplicationCommandHandler; @@ -864,167 +940,166 @@ static uint8_t send_frag_req_cmd(); void ZW_TransportService_Init(ZW_CommandHandler_Callback_t commandHandler) { - /* Set the callback function which will be called by this layer to notify + /* Set the callback function which will be called by this layer to notify upper (application) layer */ - TSApplicationCommandHandler = commandHandler; + TSApplicationCommandHandler = commandHandler; } -void TransportService_ApplicationCommandHandler(ts_param_t* p, +void TransportService_ApplicationCommandHandler(ts_param_t *p, uint8_t *pCmd, uint8_t cmdLength) { - uint8_t cmd_type; - uint16_t datagram_size_tmp; + uint8_t cmd_type; + uint16_t datagram_size_tmp; - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - /* Tie break check */ - /* 1. The receiving node is currently transmitting a datagram. + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + /* Tie break check */ + /* 1. The receiving node is currently transmitting a datagram. * 2. The recipient of the datagram being transmitted is also the originator of the received fragment * 3. The receiving node has a lower NodeID than the originator */ - if (ZW_TransportService_Is_Sending() && /* 1st condition */ - (scb.cmn.p.dnode == p->snode) && /* 2nd condition */ - (MyNodeID < p->snode)) { /* 3rd condition */ - t2_sm_post_event(EV_TIE_BREAK); - flag_tie_broken = 1; - /*FIXME: Can not FAIL the transmission because of following reason: + if (ZW_TransportService_Is_Sending() && /* 1st condition */ + (scb.cmn.p.dnode == p->snode) && /* 2nd condition */ + (MyNodeID < p->snode)) { /* 3rd condition */ + t2_sm_post_event(EV_TIE_BREAK); + flag_tie_broken = 1; + /*FIXME: Can not FAIL the transmission because of following reason: When GW is sending to some node. On receiving frag compl for a transmision from that node, if we have following line GW will fail the transmission just because of tie break logic scb.cmn.completedFunc(TRANSMIT_COMPLETE_FAIL, 0); */ - } - + } - /* There are some garbage retranmissions where the source and destination ids are messed up */ - if (p->snode == p->dnode) { - return; - } + /* There are some garbage retranmissions where the source and destination ids are messed up */ + if (p->snode == p->dnode) { + return; + } - if (cmdLength > DATAGRAM_SIZE_MAX) { + if (cmdLength > DATAGRAM_SIZE_MAX) { #ifdef NEW_TEST_T2 - call_with_large_value = 1; + call_with_large_value = 1; #endif + return; + } + + /* incase FRAG_WAIT has to be sent backup the ts_param_t received */ + memcpy((uint8_t *)&scb.frag_wait_p, (uint8_t *)p, sizeof(ts_param_t)); + + if ( + ((p->snode != rcb.current_snode) && (rcb.current_snode)) + || /* received frame from third node while receiving from second node */ + ((p->snode != scb.current_dnode) + && (scb + .current_dnode))) { /* received frame from third node while sending to second node */ + if (p->rx_flags == RECEIVE_STATUS_TYPE_SINGLE) { + /*FIXME workaround to ignore further singlecast frames from different node */ + if (current_state == ST_SEND_FRAG_WAIT) { return; + } + t2_sm_post_event(EV_SCAST_DIFF_NODE); /*send_frag_wait_cmd */ + if (scb.sending) { + scb.flag_send_frag_wait = true; + } else { + send_frag_wait_cmd(); + } + return; } - /* incase FRAG_WAIT has to be sent backup the ts_param_t received */ - memcpy((uint8_t*)&scb.frag_wait_p, (uint8_t*)p, sizeof(ts_param_t)); - - if (((p->snode != rcb.current_snode) && (rcb.current_snode)) || /* received frame from third node while receiving from second node */ - ((p->snode != scb.current_dnode) && (scb.current_dnode))) { /* received frame from third node while sending to second node */ - if (p->rx_flags == RECEIVE_STATUS_TYPE_SINGLE) { - - /*FIXME workaround to ignore further singlecast frames from different node */ - if (current_state == ST_SEND_FRAG_WAIT) { - return; - } - t2_sm_post_event(EV_SCAST_DIFF_NODE); /*send_frag_wait_cmd */ - if (scb.sending) { - scb.flag_send_frag_wait = true; - } else { - send_frag_wait_cmd(); - } - return; - } - - if (p->rx_flags == RECEIVE_STATUS_TYPE_BROAD) { - t2_sm_post_event(EV_BCAST_DIFF_NODE); /*drop_fragment */ - return; - } + if (p->rx_flags == RECEIVE_STATUS_TYPE_BROAD) { + t2_sm_post_event(EV_BCAST_DIFF_NODE); /*drop_fragment */ + return; } + } - cmd_type = *((uint8_t *)pCmd + 1); - cmd_type = cmd_type & 0xf8; + cmd_type = *((uint8_t *)pCmd + 1); + cmd_type = cmd_type & 0xf8; - if ((rcb.cmn.session_id == 0x10) && ( cmd_type == COMMAND_SUBSEQUENT_FRAGMENT)) { - datagram_size_tmp = (*((uint8_t *)pCmd + 1)) & 0x07; - datagram_size_tmp = (datagram_size_tmp << 8) + (*((uint8_t *)pCmd + 2)); + if ((rcb.cmn.session_id == 0x10) + && (cmd_type == COMMAND_SUBSEQUENT_FRAGMENT)) { + datagram_size_tmp = (*((uint8_t *)pCmd + 1)) & 0x07; + datagram_size_tmp = (datagram_size_tmp << 8) + (*((uint8_t *)pCmd + 2)); - if (datagram_size_tmp > DATAGRAM_SIZE_MAX) { - - datagram_size_tmp = 0; - t2_sm_post_event(EV_DIFF_SESSION); - return; - } - - t2_sm_post_event(EV_SUBSEQ_DIFF_SESSION); - if (scb.sending) { - scb.flag_send_frag_wait = true; - } else { - send_frag_wait_cmd(); - } - return; + if (datagram_size_tmp > DATAGRAM_SIZE_MAX) { + datagram_size_tmp = 0; + t2_sm_post_event(EV_DIFF_SESSION); + return; } - switch (current_state) - { - case ST_IDLE: - t2_sm_post_event(EV_START_RECV); - break; - case ST_RECEIVING: - t2_sm_post_event(EV_RECV_NEW_FRAG); - break; - case ST_WAIT_ACK: - /*Next state is decided in receive() */ - /*Only fragment complete, fragment request or fragment wait are expected */ - break; - default: - - /*no break no return*/ - break; + t2_sm_post_event(EV_SUBSEQ_DIFF_SESSION); + if (scb.sending) { + scb.flag_send_frag_wait = true; + } else { + send_frag_wait_cmd(); } + return; + } - if (flag_initialize_once) { - flag_initialize_once = 0; - memset((uint8_t*)&rcb.cmn, 0, sizeof(control_block_t)); - rcb.cmn.session_id = 0x10; - rcb.flag_retry_frag_req_once = 1; - rcb.cur_recvd_data_size = 0; - rcb.current_snode = 0; - memset(rcb.datagramData, 0, DATAGRAM_SIZE_MAX); - memset(rcb.bytes_recvd_bitmask, 0, sizeof(rcb.bytes_recvd_bitmask)); - } - rcb.fragment = pCmd; - /*need to memcpy because the (ts_param_t*)p pointer is not valid when + switch (current_state) { + case ST_IDLE: + t2_sm_post_event(EV_START_RECV); + break; + case ST_RECEIVING: + t2_sm_post_event(EV_RECV_NEW_FRAG); + break; + case ST_WAIT_ACK: + /*Next state is decided in receive() */ + /*Only fragment complete, fragment request or fragment wait are expected */ + break; + default: + + /*no break no return*/ + break; + } + + if (flag_initialize_once) { + flag_initialize_once = 0; + memset((uint8_t *)&rcb.cmn, 0, sizeof(control_block_t)); + rcb.cmn.session_id = 0x10; + rcb.flag_retry_frag_req_once = 1; + rcb.cur_recvd_data_size = 0; + rcb.current_snode = 0; + memset(rcb.datagramData, 0, DATAGRAM_SIZE_MAX); + memset(rcb.bytes_recvd_bitmask, 0, sizeof(rcb.bytes_recvd_bitmask)); + } + rcb.fragment = pCmd; + /*need to memcpy because the (ts_param_t*)p pointer is not valid when the rx_timer_expired is called by the timer*/ - memcpy((uint8_t*)&rcb.cmn.p, (uint8_t*)p, sizeof(ts_param_t)); - rcb.fragment_len = cmdLength; + memcpy((uint8_t *)&rcb.cmn.p, (uint8_t *)p, sizeof(ts_param_t)); + rcb.fragment_len = cmdLength; - receive(); - return; + receive(); + return; } static uint8_t mark_frag_received(uint16_t offset, uint8_t size) { - int i = 0; + int i = 0; - if ((offset != 0) && !(rcb.bytes_recvd_bitmask[0] & 1)) { - - t2_sm_post_event(EV_SUBSEQ_DIFF_SESSION); - if (scb.sending) { - scb.flag_send_frag_wait = true; - } else { - send_frag_wait_cmd(); - } - return 1; + if ((offset != 0) && !(rcb.bytes_recvd_bitmask[0] & 1)) { + t2_sm_post_event(EV_SUBSEQ_DIFF_SESSION); + if (scb.sending) { + scb.flag_send_frag_wait = true; + } else { + send_frag_wait_cmd(); } - for (i = offset; i < (offset+ size) ;i++) { - - // set the (i%8)th bit in (i/8)th byte in bitmask, where i is the byte received + return 1; + } + for (i = offset; i < (offset + size); i++) { + // set the (i%8)th bit in (i/8)th byte in bitmask, where i is the byte received - // if 9th byte is received following formula becomes - // rcb.bytes_recvd_bitmask[1] |= ( 1 << 1) - // if 11th byte is received following formula becomes rcb.bytes_recvd_bitmask[1] |= 4 - // rcb.bytes_recvd_bitmask[1] |= ( 1 << 3) + // if 9th byte is received following formula becomes + // rcb.bytes_recvd_bitmask[1] |= ( 1 << 1) + // if 11th byte is received following formula becomes rcb.bytes_recvd_bitmask[1] |= 4 + // rcb.bytes_recvd_bitmask[1] |= ( 1 << 3) - rcb.bytes_recvd_bitmask[ i / 8 ] |= (1 << (i%8)); - if ( i > DATAGRAM_SIZE_MAX) { // Prevent the array over run - break; - } + rcb.bytes_recvd_bitmask[i / 8] |= (1 << (i % 8)); + if (i > DATAGRAM_SIZE_MAX) { // Prevent the array over run + break; } + } - return 0; + return 0; } #if 0 @@ -1066,11 +1141,11 @@ static uint8_t get_num_missing_frag(void) static void rx_timer_expired(void *ss) { - struct rx_timer_expired_data *rdata = ss; - uint8_t state = rdata->state; + struct rx_timer_expired_data *rdata = ss; + uint8_t state = rdata->state; #ifdef TIMER - ctimer_stop(&rcb.rx_timer); + ctimer_stop(&rcb.rx_timer); #endif #if 0 /* Following code is just for information purpose */ @@ -1081,17 +1156,15 @@ static void rx_timer_expired(void *ss) t2_sm_post_event(EV_FRAG_RX_TIMER); /* send_frag_req_cmd */ } #endif - /* There could be two functions called after this depending on current + /* There could be two functions called after this depending on current * state. See code above */ - t2_sm_post_event(EV_FRAG_RX_TIMER); - if (state && (get_next_missing_offset(/*rcb.datagram_size*/))) { - - - discard_all_received_fragments(); - } else { - find_missing(); - } -/* + t2_sm_post_event(EV_FRAG_RX_TIMER); + if (state && (get_next_missing_offset(/*rcb.datagram_size*/))) { + discard_all_received_fragments(); + } else { + find_missing(); + } + /* ctimer_set(&rcb.rx_timer, FRAGMENT_RX_TIMEOUT, ZCB_rx_timer_expired, 0); */ } @@ -1099,298 +1172,311 @@ static void rx_timer_expired(void *ss) static void find_missing(void) { - uint8_t missing_frag; + uint8_t missing_frag; - missing_frag = get_next_missing_offset(); + missing_frag = get_next_missing_offset(); - if (missing_frag) { - if (rcb.cmn.p.rx_flags == RECEIVE_STATUS_TYPE_BROAD) { - discard_all_received_fragments(); - return; - } - t2_sm_post_event(EV_MISSING_FRAG); /* send_frag_req_cmd */ - send_frag_req_cmd(); - } else { - /* No need to send Fragment complete in case of Broadcast */ - if (rcb.cmn.p.rx_flags == RECEIVE_STATUS_TYPE_BROAD) { - return; - } - t2_sm_post_event(EV_SEND_FRAG_COMPLETE); - send_frag_complete_cmd(); + if (missing_frag) { + if (rcb.cmn.p.rx_flags == RECEIVE_STATUS_TYPE_BROAD) { + discard_all_received_fragments(); + return; + } + t2_sm_post_event(EV_MISSING_FRAG); /* send_frag_req_cmd */ + send_frag_req_cmd(); + } else { + /* No need to send Fragment complete in case of Broadcast */ + if (rcb.cmn.p.rx_flags == RECEIVE_STATUS_TYPE_BROAD) { + return; } + t2_sm_post_event(EV_SEND_FRAG_COMPLETE); + send_frag_complete_cmd(); + } } static void receive(void) { #if defined(ZIPGW) - TX_STATUS_TYPE t; + TX_STATUS_TYPE t; #endif - uint8_t byte1 = *((uint8_t *)rcb.fragment + 1); - uint8_t byte2 = *((uint8_t *)rcb.fragment + 2); - uint8_t byte3 = *((uint8_t *)rcb.fragment + 3); - uint8_t byte4 = *((uint8_t *)rcb.fragment + 4); + uint8_t byte1 = *((uint8_t *)rcb.fragment + 1); + uint8_t byte2 = *((uint8_t *)rcb.fragment + 2); + uint8_t byte3 = *((uint8_t *)rcb.fragment + 3); + uint8_t byte4 = *((uint8_t *)rcb.fragment + 4); - uint16_t datagram_offset = 0; /*It has to fit 11 bits so need to be two uint8_t */ - uint8_t *curr_datagramData; - uint8_t recvd_session_id = 0; - uint16_t datagram_size_tmp; + uint16_t datagram_offset + = 0; /*It has to fit 11 bits so need to be two uint8_t */ + uint8_t *curr_datagramData; + uint8_t recvd_session_id = 0; + uint16_t datagram_size_tmp; - if (*((uint8_t *)rcb.fragment) != COMMAND_CLASS_TRANSPORT_SERVICE) { - - return; - } + if (*((uint8_t *)rcb.fragment) != COMMAND_CLASS_TRANSPORT_SERVICE) { + return; + } - switch (byte1 & 0xf8) { + switch (byte1 & 0xf8) { case COMMAND_FIRST_FRAGMENT: - if (flag_tie_broken) { - scb.transmission_aborted = scb.cmn.session_id; - } -#define FIRST_FRAG_NONPAYLOAD_LENGTH (sizeof(ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME) - 1) -#define SUBSEQ_FRAG_NONPAYLOAD_LENGTH (sizeof(ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME) - 1) + if (flag_tie_broken) { + scb.transmission_aborted = scb.cmn.session_id; + } +#define FIRST_FRAG_NONPAYLOAD_LENGTH \ + (sizeof(ZW_COMMAND_FIRST_FRAGMENT_1BYTE_FRAME) - 1) +#define SUBSEQ_FRAG_NONPAYLOAD_LENGTH \ + (sizeof(ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME) - 1) - if (rcb.fragment_len <= FIRST_FRAG_NONPAYLOAD_LENGTH) { - - t2_sm_post_event(EV_RECV_NEW_FRAG); - return; - } + if (rcb.fragment_len <= FIRST_FRAG_NONPAYLOAD_LENGTH) { + t2_sm_post_event(EV_RECV_NEW_FRAG); + return; + } - /* If first fragment received is corrupt send fragment wait command */ - if (CRC_FUNC(0x1D0F, (uint8_t*) rcb.fragment, rcb.fragment_len) != 0) { - - /*FIXME: Do we need to send FRAG_WAIT here? */ - t2_sm_post_event(EV_RECV_NEW_FRAG); - return; - } + /* If first fragment received is corrupt send fragment wait command */ + if (CRC_FUNC(0x1D0F, (uint8_t *)rcb.fragment, rcb.fragment_len) != 0) { + /*FIXME: Do we need to send FRAG_WAIT here? */ + t2_sm_post_event(EV_RECV_NEW_FRAG); + return; + } - recvd_session_id = (byte3 & 0xf0) >> 4; - if ((recvd_session_id != rcb.cmn.session_id) && (rcb.cmn.session_id != 0x10)) { /*Refer 10.1.3.1.5 */ - t2_sm_post_event(EV_DIFF_SESSION); - return; - } - datagram_size_tmp = (byte1) & 0x07; - datagram_size_tmp = (datagram_size_tmp << 8) + byte2; + recvd_session_id = (byte3 & 0xf0) >> 4; + if ((recvd_session_id != rcb.cmn.session_id) + && (rcb.cmn.session_id != 0x10)) { /*Refer 10.1.3.1.5 */ + t2_sm_post_event(EV_DIFF_SESSION); + return; + } + datagram_size_tmp = (byte1)&0x07; + datagram_size_tmp = (datagram_size_tmp << 8) + byte2; - if (datagram_size_tmp > DATAGRAM_SIZE_MAX) { - - t2_sm_post_event(EV_DIFF_SESSION); - return; - } + if (datagram_size_tmp > DATAGRAM_SIZE_MAX) { + t2_sm_post_event(EV_DIFF_SESSION); + return; + } #ifdef TIMER - ctimer_set(&rcb.rx_timer, FRAGMENT_RX_TIMEOUT, FUNC(rx_timer_expired), &rcb.rx_data); + ctimer_set(&rcb.rx_timer, + FRAGMENT_RX_TIMEOUT, + FUNC(rx_timer_expired), + &rcb.rx_data); #endif - rcb.cmn.session_id = recvd_session_id; - rcb.recv_frag_compl_list[recvd_session_id] = false; /* Setting this session id as "havent received FRAG_COMPLETE for it"*/ + rcb.cmn.session_id = recvd_session_id; + rcb.recv_frag_compl_list[recvd_session_id] + = false; /* Setting this session id as "havent received FRAG_COMPLETE for it"*/ - rcb.cur_recvd_data_size = rcb.fragment_len - FIRST_FRAG_NONPAYLOAD_LENGTH; + rcb.cur_recvd_data_size = rcb.fragment_len - FIRST_FRAG_NONPAYLOAD_LENGTH; - rcb.datagram_size = datagram_size_tmp; - memset(rcb.bytes_recvd_bitmask, 0, sizeof(rcb.bytes_recvd_bitmask)); + rcb.datagram_size = datagram_size_tmp; + memset(rcb.bytes_recvd_bitmask, 0, sizeof(rcb.bytes_recvd_bitmask)); - rcb.current_snode = rcb.cmn.p.snode; + rcb.current_snode = rcb.cmn.p.snode; -#define FIRST_HDR_LEN 4 /* Cmd class, cmd, size, seqno */ +#define FIRST_HDR_LEN 4 /* Cmd class, cmd, size, seqno */ #define SUBSEQ_HDR_LEN 5 /* Cmd class, cmd, size, seqno + offset 1, offset 2*/ - memcpy(rcb.datagramData, rcb.fragment + FIRST_HDR_LEN, - rcb.cur_recvd_data_size); - if(mark_frag_received(0, rcb.cur_recvd_data_size)) - return; - - /* The current fragment had all the data needed for the datagram */ - if (rcb.cur_recvd_data_size == rcb.datagram_size) { - t2_sm_post_event(EV_SEND_FRAG_COMPLETE); /* send_frag_complete_cmd */ - send_frag_complete_cmd(); - return; - } + memcpy(rcb.datagramData, + rcb.fragment + FIRST_HDR_LEN, + rcb.cur_recvd_data_size); + if (mark_frag_received(0, rcb.cur_recvd_data_size)) + return; - /* The current fragment had more data than the size of + /* The current fragment had all the data needed for the datagram */ + if (rcb.cur_recvd_data_size == rcb.datagram_size) { + t2_sm_post_event(EV_SEND_FRAG_COMPLETE); /* send_frag_complete_cmd */ + send_frag_complete_cmd(); + return; + } + + /* The current fragment had more data than the size of whole datagram. TODO: Something wrong?*/ - if (rcb.cur_recvd_data_size > rcb.datagram_size) { - - //t2_sm_post_event(EV_ERROR); - } - rcb.rx_data.state = 0; /*not after sending req cmd */ - break; + if (rcb.cur_recvd_data_size > rcb.datagram_size) { + //t2_sm_post_event(EV_ERROR); + } + rcb.rx_data.state = 0; /*not after sending req cmd */ + break; case COMMAND_SUBSEQUENT_FRAGMENT: - /* Stay in the same function and handle fragment */ - if (flag_tie_broken) { - scb.transmission_aborted = scb.cmn.session_id; - } + /* Stay in the same function and handle fragment */ + if (flag_tie_broken) { + scb.transmission_aborted = scb.cmn.session_id; + } - if (rcb.fragment_len <= SUBSEQ_FRAG_NONPAYLOAD_LENGTH) { - - /*FIXME: Do we need to send FRAG_WAIT here? */ - t2_sm_post_event(EV_RECV_NEW_FRAG); - return; - } - /* If subseq fragment received is corrupt just ignore it */ - if (CRC_FUNC(0x1D0F, (uint8_t*) rcb.fragment, rcb.fragment_len) != 0) { - - /*FIXME: Do we need to send FRAG_WAIT here? */ - t2_sm_post_event(EV_RECV_NEW_FRAG); - return; - } + if (rcb.fragment_len <= SUBSEQ_FRAG_NONPAYLOAD_LENGTH) { + /*FIXME: Do we need to send FRAG_WAIT here? */ + t2_sm_post_event(EV_RECV_NEW_FRAG); + return; + } + /* If subseq fragment received is corrupt just ignore it */ + if (CRC_FUNC(0x1D0F, (uint8_t *)rcb.fragment, rcb.fragment_len) != 0) { + /*FIXME: Do we need to send FRAG_WAIT here? */ + t2_sm_post_event(EV_RECV_NEW_FRAG); + return; + } - recvd_session_id = (byte3 & 0xf0) >> 4; + recvd_session_id = (byte3 & 0xf0) >> 4; - if (rcb.recv_frag_compl_list[recvd_session_id] == true) { - - if (current_state == ST_RECEIVING) { - t2_sm_post_event(EV_DUPL_FRAME); - } else { - - } - return; - } - /* session ID of new received fragment is different from the one being assembled */ - if ((recvd_session_id != rcb.cmn.session_id) && (rcb.cmn.session_id != 0x10)) { - t2_sm_post_event(EV_DIFF_SESSION); - return; + if (rcb.recv_frag_compl_list[recvd_session_id] == true) { + if (current_state == ST_RECEIVING) { + t2_sm_post_event(EV_DUPL_FRAME); + } else { } + return; + } + /* session ID of new received fragment is different from the one being assembled */ + if ((recvd_session_id != rcb.cmn.session_id) + && (rcb.cmn.session_id != 0x10)) { + t2_sm_post_event(EV_DIFF_SESSION); + return; + } - datagram_offset = byte3 & 0x07; /* last three bits of 2nd byte */ - datagram_offset = (datagram_offset << 8) + byte4; + datagram_offset = byte3 & 0x07; /* last three bits of 2nd byte */ + datagram_offset = (datagram_offset << 8) + byte4; - // Also checks if first fragment for this datagram is missing and we received subsequent fragment. - // Sends FRAG_WAIT as well + // Also checks if first fragment for this datagram is missing and we received subsequent fragment. + // Sends FRAG_WAIT as well - rcb.cur_recvd_data_size = rcb.fragment_len - SUBSEQ_FRAG_NONPAYLOAD_LENGTH; + rcb.cur_recvd_data_size + = rcb.fragment_len - SUBSEQ_FRAG_NONPAYLOAD_LENGTH; - if ((datagram_offset + rcb.cur_recvd_data_size) > DATAGRAM_SIZE_MAX) { - - if (current_state == ST_RECEIVING) { - t2_sm_post_event(EV_DUPL_FRAME); - } - return; + if ((datagram_offset + rcb.cur_recvd_data_size) > DATAGRAM_SIZE_MAX) { + if (current_state == ST_RECEIVING) { + t2_sm_post_event(EV_DUPL_FRAME); } - datagram_size_tmp = (byte1) & 0x07; - datagram_size_tmp = (datagram_size_tmp << 8) + byte2; + return; + } + datagram_size_tmp = (byte1)&0x07; + datagram_size_tmp = (datagram_size_tmp << 8) + byte2; - if (datagram_size_tmp > DATAGRAM_SIZE_MAX) { - - t2_sm_post_event(EV_DIFF_SESSION); - return; - } + if (datagram_size_tmp > DATAGRAM_SIZE_MAX) { + t2_sm_post_event(EV_DIFF_SESSION); + return; + } #ifdef TIMER - ctimer_set(&rcb.rx_timer, FRAGMENT_RX_TIMEOUT, FUNC(rx_timer_expired), &rcb.rx_data); + ctimer_set(&rcb.rx_timer, + FRAGMENT_RX_TIMEOUT, + FUNC(rx_timer_expired), + &rcb.rx_data); #endif - if (mark_frag_received(datagram_offset, rcb.cur_recvd_data_size)) - break; + if (mark_frag_received(datagram_offset, rcb.cur_recvd_data_size)) + break; - rcb.datagram_size = datagram_size_tmp; - curr_datagramData = rcb.datagramData; /* Should not change the global buffer address */ - curr_datagramData = curr_datagramData + datagram_offset; + rcb.datagram_size = datagram_size_tmp; + curr_datagramData + = rcb.datagramData; /* Should not change the global buffer address */ + curr_datagramData = curr_datagramData + datagram_offset; - memcpy(curr_datagramData, rcb.fragment + SUBSEQ_HDR_LEN, rcb.cur_recvd_data_size); + memcpy(curr_datagramData, + rcb.fragment + SUBSEQ_HDR_LEN, + rcb.cur_recvd_data_size); - if (((datagram_offset + rcb.cur_recvd_data_size) >= rcb.datagram_size)) { /*last fragment? */ - t2_sm_post_event(EV_RECV_LAST_FRAG); /*find_missing()*/ - find_missing(); - return; - } - rcb.rx_data.state = 0; /*not after sending req cmd */ - break; + if (((datagram_offset + rcb.cur_recvd_data_size) + >= rcb.datagram_size)) { /*last fragment? */ + t2_sm_post_event(EV_RECV_LAST_FRAG); /*find_missing()*/ + find_missing(); + return; + } + rcb.rx_data.state = 0; /*not after sending req cmd */ + break; - case COMMAND_SEGMENT_REQUEST_V2: - t2_sm_post_event(EV_FRAG_REQ_OR_COMPL); - recvd_session_id = (byte2 & 0xf0) >> 4; - /*Fragment request is not from the same session in which we were sending */ + case COMMAND_SEGMENT_REQUEST_V2: + t2_sm_post_event(EV_FRAG_REQ_OR_COMPL); + recvd_session_id = (byte2 & 0xf0) >> 4; + /*Fragment request is not from the same session in which we were sending */ - if (recvd_session_id == scb.transmission_aborted) { - t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); - return; - } - if (recvd_session_id != scb.cmn.session_id) { - t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); - return; - } - if ((rcb.cmn.p.snode != scb.current_dnode) && (rcb.current_snode != 0)) { /* Check if the FRAG REQ is from the destination node where we were sending data to */ - - t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE); - return; - } + if (recvd_session_id == scb.transmission_aborted) { + t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); + return; + } + if (recvd_session_id != scb.cmn.session_id) { + t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); + return; + } + if ( + (rcb.cmn.p.snode != scb.current_dnode) + && (rcb.current_snode + != 0)) { /* Check if the FRAG REQ is from the destination node where we were sending data to */ + + t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE); + return; + } #ifdef TIMER - ctimer_stop(&rcb.fc_timer); + ctimer_stop(&rcb.fc_timer); #endif - scb.missing_offset = ((byte2 & 0x7) << 8); - scb.missing_offset |= byte3; + scb.missing_offset = ((byte2 & 0x7) << 8); + scb.missing_offset |= byte3; - t2_sm_post_event(EV_RECV_FRAG_REQ); /* reply_frag_req(); */ - if (scb.sending) { - scb.flag_reply_frag_req = true; - } else { - reply_frag_req(NULL); - } - break; + t2_sm_post_event(EV_RECV_FRAG_REQ); /* reply_frag_req(); */ + if (scb.sending) { + scb.flag_reply_frag_req = true; + } else { + reply_frag_req(NULL); + } + break; - case COMMAND_SEGMENT_COMPLETE_V2: - t2_sm_post_event(EV_FRAG_REQ_OR_COMPL); - recvd_session_id = (byte2 & 0xf0) >> 4; - if (recvd_session_id == scb.transmission_aborted) { - t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); - return; - } - /*Fragment complete is not from the same session in which we were sending */ - if (recvd_session_id != scb.cmn.session_id) { - - t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); - return; - } - if ((rcb.cmn.p.snode != scb.current_dnode) && (rcb.current_snode != 0)) { /* Check if the FRAG complete is from the destination node where we were sending data to */ - - t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE); - return; - } + case COMMAND_SEGMENT_COMPLETE_V2: + t2_sm_post_event(EV_FRAG_REQ_OR_COMPL); + recvd_session_id = (byte2 & 0xf0) >> 4; + if (recvd_session_id == scb.transmission_aborted) { + t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); + return; + } + /*Fragment complete is not from the same session in which we were sending */ + if (recvd_session_id != scb.cmn.session_id) { + t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_SESSION); + return; + } + if ( + (rcb.cmn.p.snode != scb.current_dnode) + && (rcb.current_snode + != 0)) { /* Check if the FRAG complete is from the destination node where we were sending data to */ + + t2_sm_post_event(EV_FRAG_REQ_COMPL_WAIT_DIFF_NODE); + return; + } #ifdef TIMER - ctimer_stop(&rcb.fc_timer); + ctimer_stop(&rcb.fc_timer); #endif - if (scb.cmn.session_id == recvd_session_id) { - scb.frag_compl_list[recvd_session_id] = true; - scb.current_dnode = 0; - if (scb.cmn.completedFunc) { + if (scb.cmn.session_id == recvd_session_id) { + scb.frag_compl_list[recvd_session_id] = true; + scb.current_dnode = 0; + if (scb.cmn.completedFunc) { #if defined(ZIPGW) - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_OK, &scb.cmn.tx_status); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_OK, &scb.cmn.tx_status); #else - scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_OK, 0); + scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_OK, 0); #endif - } - } else { - } + } else { + } - t2_sm_post_event(EV_RECV_FRAG_COMPL); /* Go back to ST_IDLE state */ - break; + t2_sm_post_event(EV_RECV_FRAG_COMPL); /* Go back to ST_IDLE state */ + break; - case COMMAND_SEGMENT_WAIT_V2: - /* Though the code flow is in receive() function. Current state is still be ST_SEND_FRAG */ - if (scb.frag_compl_list[scb.cmn.session_id] == true) { - - t2_sm_post_event(EV_DUPL_FRAME); - return; - } - t2_sm_post_event(EV_RECV_FRAG_WAIT); - scb.transmission_aborted = scb.cmn.session_id; - /* call ZCB_ts_senddata_cb() here that will halt the next fragment send function called from ZCB_ts_senddata_cb() */ + case COMMAND_SEGMENT_WAIT_V2: + /* Though the code flow is in receive() function. Current state is still be ST_SEND_FRAG */ + if (scb.frag_compl_list[scb.cmn.session_id] == true) { + t2_sm_post_event(EV_DUPL_FRAME); + return; + } + t2_sm_post_event(EV_RECV_FRAG_WAIT); + scb.transmission_aborted = scb.cmn.session_id; + /* call ZCB_ts_senddata_cb() here that will halt the next fragment send function called from ZCB_ts_senddata_cb() */ #if defined(ZIPGW) - memset(&t, 0, sizeof(TX_STATUS_TYPE)); - ZCB_ts_senddata_cb(S2_TRANSMIT_COMPLETE_FAIL, &t); + memset(&t, 0, sizeof(TX_STATUS_TYPE)); + ZCB_ts_senddata_cb(S2_TRANSMIT_COMPLETE_FAIL, &t); #else - ZCB_ts_senddata_cb(S2_TRANSMIT_COMPLETE_FAIL, 0); + ZCB_ts_senddata_cb(S2_TRANSMIT_COMPLETE_FAIL, 0); #endif - /* Refer 10.1.3.5.3 */ - rcb.cmn.pending_segments = byte2; - /*FIXME: Shall we increment the scb.sending session id here or should we send it in same session id */ - /* If the pending segments are 0 then the sending side is going to bombard the receiving side with new fragments + /* Refer 10.1.3.5.3 */ + rcb.cmn.pending_segments = byte2; + /*FIXME: Shall we increment the scb.sending session id here or should we send it in same session id */ + /* If the pending segments are 0 then the sending side is going to bombard the receiving side with new fragments so added a delay of 100ms regardless of number of pending segments */ - ctimer_set(&scb.wait_restart_timer, (100 + 100 * rcb.cmn.pending_segments), FUNC(wait_restart_from_first), NULL); - break; + ctimer_set(&scb.wait_restart_timer, + (100 + 100 * rcb.cmn.pending_segments), + FUNC(wait_restart_from_first), + NULL); + break; default: - - break; - } - return; + + break; + } + return; } /* FIXME: FRAGMENT_WAIT should have session id field inside it. Delayed FRAGMENT_WAIT frames end up stopping the wrong session. @@ -1400,173 +1486,192 @@ receiving side has been sending subseq fragments without first fragment then (as Then receiving side sends frag wait which finally makes the transfer happen as sending side restarts the third session */ static uint8_t send_frag_wait_cmd(void) { - uint8_t ret = 0; - ZW_COMMAND_SEGMENT_WAIT_V2_FRAME frag_wait; - - frag_wait.cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; - frag_wait.cmd_reserved = (COMMAND_SEGMENT_WAIT_V2 & 0xf8); - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - if (scb.sending) { /* If there is a sending session going on FRAG_WAIT will be queed for next callback*/ - frag_wait.pendingFragments = scb.cmn.pending_segments; - ret = TS_SEND_RAW(scb.frag_wait_p.dnode, scb.frag_wait_p.snode, (uint8_t *)&frag_wait, sizeof(frag_wait), - scb.frag_wait_p.tx_flags | TRANSMIT_OPTION_ACK, ZCB_ts_senddata_cb); - t2_sm_post_event(EV_SUCCESS2); /* Go back to ST_SEND_FRAG state in */ + uint8_t ret = 0; + ZW_COMMAND_SEGMENT_WAIT_V2_FRAME frag_wait; + + frag_wait.cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; + frag_wait.cmd_reserved = (COMMAND_SEGMENT_WAIT_V2 & 0xf8); + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + if ( + scb + .sending) { /* If there is a sending session going on FRAG_WAIT will be queed for next callback*/ + frag_wait.pendingFragments = scb.cmn.pending_segments; + ret = TS_SEND_RAW(scb.frag_wait_p.dnode, + scb.frag_wait_p.snode, + (uint8_t *)&frag_wait, + sizeof(frag_wait), + scb.frag_wait_p.tx_flags | TRANSMIT_OPTION_ACK, + ZCB_ts_senddata_cb); + t2_sm_post_event(EV_SUCCESS2); /* Go back to ST_SEND_FRAG state in */ + } else { + if (rcb.cmn.session_id == 0x10) { + rcb.cmn.pending_segments = 0; } else { - if (rcb.cmn.session_id == 0x10) { - rcb.cmn.pending_segments = 0; - } else { - // TODO? this is approximate. If we have variable frame size - rcb.cmn.pending_segments = rcb.datagram_size / rcb.cur_recvd_data_size; - (rcb.datagram_size % rcb.cur_recvd_data_size) ? rcb.cmn.pending_segments++:0; - } - - - frag_wait.pendingFragments = rcb.cmn.pending_segments; - ret = TS_SEND_RAW(scb.frag_wait_p.dnode, scb.frag_wait_p.snode, (uint8_t *)&frag_wait, sizeof(frag_wait), - scb.frag_wait_p.tx_flags | TRANSMIT_OPTION_ACK, NULL); - t2_sm_post_event(EV_SUCCESS); /* Go back to ST_RECEIVING state in receive() funciton */ + // TODO? this is approximate. If we have variable frame size + rcb.cmn.pending_segments = rcb.datagram_size / rcb.cur_recvd_data_size; + (rcb.datagram_size % rcb.cur_recvd_data_size) ? rcb.cmn.pending_segments++ + : 0; } - /*TODO SPEC: What to do if sending frag wait fails*/ - if (ret == 0) { - - } - return 0; + frag_wait.pendingFragments = rcb.cmn.pending_segments; + ret = TS_SEND_RAW(scb.frag_wait_p.dnode, + scb.frag_wait_p.snode, + (uint8_t *)&frag_wait, + sizeof(frag_wait), + scb.frag_wait_p.tx_flags | TRANSMIT_OPTION_ACK, + NULL); + t2_sm_post_event( + EV_SUCCESS); /* Go back to ST_RECEIVING state in receive() funciton */ + } + + /*TODO SPEC: What to do if sending frag wait fails*/ + if (ret == 0) { + } + return 0; } static uint8_t send_frag_complete_cmd(void) { - uint8_t ret = 0; - //uint8_t i; + uint8_t ret = 0; + //uint8_t i; - ZW_COMMAND_SEGMENT_COMPLETE_V2_FRAME frag_compl; + ZW_COMMAND_SEGMENT_COMPLETE_V2_FRAME frag_compl; - if (rcb.cmn.session_id > 0x0f) { /* Session ID has only 4 bits for it.*/ - - return 0; - } + if (rcb.cmn.session_id > 0x0f) { /* Session ID has only 4 bits for it.*/ - frag_compl.cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; - frag_compl.cmd_reserved = (COMMAND_SEGMENT_COMPLETE_V2 & 0xf8); + return 0; + } - frag_compl.properties2 = (rcb.cmn.session_id << 4); - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - ret = TS_SEND_RAW(rcb.cmn.p.dnode, rcb.cmn.p.snode, (uint8_t *)&frag_compl, sizeof(frag_compl), - rcb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, NULL); - if (ret == 0) { - - } + frag_compl.cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; + frag_compl.cmd_reserved = (COMMAND_SEGMENT_COMPLETE_V2 & 0xf8); + + frag_compl.properties2 = (rcb.cmn.session_id << 4); + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + ret = TS_SEND_RAW(rcb.cmn.p.dnode, + rcb.cmn.p.snode, + (uint8_t *)&frag_compl, + sizeof(frag_compl), + rcb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + NULL); + if (ret == 0) { + } #ifdef ZIPGW - ZIPCommandHandler(rcb.cmn.p.snode, rcb.datagram_size); /**/ -#endif /* ifdef ZIPGW */ + ZIPCommandHandler(rcb.cmn.p.snode, rcb.datagram_size); /**/ +#endif /* ifdef ZIPGW */ - /* Resetting for next session */ - rcb.recv_frag_compl_list[rcb.cmn.session_id] = true; - rcb.cmn.session_id = 0x10; - rcb.current_snode = 0; + /* Resetting for next session */ + rcb.recv_frag_compl_list[rcb.cmn.session_id] = true; + rcb.cmn.session_id = 0x10; + rcb.current_snode = 0; #ifdef TIMER - ctimer_stop(&rcb.rx_timer); + ctimer_stop(&rcb.rx_timer); #endif - /* FIXME: should this be in the call back? */ - t2_sm_post_event(EV_SUCCESS); /* just change the state to ST_RECEIVING */ + /* FIXME: should this be in the call back? */ + t2_sm_post_event(EV_SUCCESS); /* just change the state to ST_RECEIVING */ #if (defined(EFR32ZG) || defined(ZWAVE_ON_LINUX)) && !defined(NEW_TEST_T2) #if DATAGRAM_SIZE_MAX > 250 #error Datagram size does not fit in uin8_t. #endif - TransportService_msg_received_event((uint8_t*) rcb.datagramData, (uint8_t)rcb.datagram_size, rcb.cmn.p.snode); + TransportService_msg_received_event((uint8_t *)rcb.datagramData, + (uint8_t)rcb.datagram_size, + rcb.cmn.p.snode); #endif - return 0; + return 0; } static uint16_t get_next_missing_offset(void) { - int i = 0; - int j = 0; - int missing_offset = 0; - - for ( i = 0; i < (sizeof(rcb.bytes_recvd_bitmask)); i++) { - for ( j = 0; j < 8; j++) { - if ((rcb.bytes_recvd_bitmask[i] & ( 1 << j)) == 0) { - missing_offset = ((i * 8)+j); - if (missing_offset == 0) { - continue; - } - if(missing_offset >= rcb.datagram_size) { - return 0; - } - return missing_offset; - } + int i = 0; + int j = 0; + int missing_offset = 0; + + for (i = 0; i < (sizeof(rcb.bytes_recvd_bitmask)); i++) { + for (j = 0; j < 8; j++) { + if ((rcb.bytes_recvd_bitmask[i] & (1 << j)) == 0) { + missing_offset = ((i * 8) + j); + if (missing_offset == 0) { + continue; } + if (missing_offset >= rcb.datagram_size) { + return 0; + } + return missing_offset; + } } - return 0; + } + return 0; } static uint8_t send_frag_req_cmd(void) { - ZW_COMMAND_SEGMENT_REQUEST_V2_FRAME *frag_req = - (ZW_COMMAND_SEGMENT_REQUEST_V2_FRAME *) t2_txBuf; - uint8_t ret1 = 0; + ZW_COMMAND_SEGMENT_REQUEST_V2_FRAME *frag_req + = (ZW_COMMAND_SEGMENT_REQUEST_V2_FRAME *)t2_txBuf; + uint8_t ret1 = 0; + offset_to_request = get_next_missing_offset(); + if (!offset_to_request) { + t2_sm_post_event(EV_SUCCESS); /* Just change the state to ST_RECEIVING */ + return 0; + } - offset_to_request = get_next_missing_offset(); - if (!offset_to_request) { - - t2_sm_post_event(EV_SUCCESS); /* Just change the state to ST_RECEIVING */ - return 0; - } + if (rcb.cmn.session_id > 0x0f) { /* Session ID has only 4 bits for it.*/ - if (rcb.cmn.session_id > 0x0f) {/* Session ID has only 4 bits for it.*/ - - return 0; - } + return 0; + } - frag_req->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; - frag_req->cmd_reserved = (COMMAND_SEGMENT_REQUEST_V2) & 0xf8; - frag_req->properties2 = rcb.cmn.session_id << 4; - frag_req->properties2 |= ((offset_to_request & 0x700) >> 8); /* Get 9th, 10th and 11th MSB */ - frag_req->datagramOffset2 = (offset_to_request & 0xff); + frag_req->cmdClass = COMMAND_CLASS_TRANSPORT_SERVICE; + frag_req->cmd_reserved = (COMMAND_SEGMENT_REQUEST_V2)&0xf8; + frag_req->properties2 = rcb.cmn.session_id << 4; + frag_req->properties2 + |= ((offset_to_request & 0x700) >> 8); /* Get 9th, 10th and 11th MSB */ + frag_req->datagramOffset2 = (offset_to_request & 0xff); retry: - /* At receiver t2_txBuf is only needed in sending frag request. + /* At receiver t2_txBuf is only needed in sending frag request. * max size = 21 _to_reqoffsets * 2bytes + size of frag req cmd header * uint8_t t2_txBuf[(21 * 2) + sizeof(ZW_COMMAND_FRAGMENT_REQUEST_1BYTE_FRAME)]; */ - //ret1 = send_data(&rcb.cmn.p, t2_txBuf, sizeof(*frag_req), NULL, NULL); - ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); - ret1 = TS_SEND_RAW(rcb.cmn.p.dnode, rcb.cmn.p.snode, t2_txBuf, sizeof(*frag_req), - rcb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, NULL); - if (ret1 == false) { - /* TODO SPEC: what to do if frag req cmd fails */ - - if (rcb.flag_retry_frag_req_once) { - rcb.flag_retry_frag_req_once--; - goto retry; - } + //ret1 = send_data(&rcb.cmn.p, t2_txBuf, sizeof(*frag_req), NULL, NULL); + ctimer_set(&scb.reset_timer, RESET_TIME, FUNC(reset_transport_service), 0); + ret1 = TS_SEND_RAW(rcb.cmn.p.dnode, + rcb.cmn.p.snode, + t2_txBuf, + sizeof(*frag_req), + rcb.cmn.p.tx_flags | TRANSMIT_OPTION_ACK, + NULL); + if (ret1 == false) { + /* TODO SPEC: what to do if frag req cmd fails */ + + if (rcb.flag_retry_frag_req_once) { + rcb.flag_retry_frag_req_once--; + goto retry; } + } - /*TODO Got to wait here some time or wait for ACK */ - rcb.rx_data.state = 1; /*after sending frag req, as we need to discard fragments in rx_timer_expired */ + /*TODO Got to wait here some time or wait for ACK */ + rcb.rx_data.state + = 1; /*after sending frag req, as we need to discard fragments in rx_timer_expired */ #ifdef TIMER - t2_sm_post_event(EV_SUCCESS); /* FIXME: should this be in the call back? Just change the state to ST_RECEIVING */ - ctimer_set(&rcb.rx_timer, FRAGMENT_RX_TIMEOUT, FUNC(rx_timer_expired), &rcb.rx_data); + t2_sm_post_event( + EV_SUCCESS); /* FIXME: should this be in the call back? Just change the state to ST_RECEIVING */ + ctimer_set(&rcb.rx_timer, + FRAGMENT_RX_TIMEOUT, + FUNC(rx_timer_expired), + &rcb.rx_data); #endif - return 0; + return 0; } static uint8_t discard_all_received_fragments(void) { - memset(rcb.datagramData, 0, sizeof(rcb.datagramData)); + memset(rcb.datagramData, 0, sizeof(rcb.datagramData)); - memset((uint8_t*)&rcb.cmn, 0, sizeof(control_block_t)); - rcb.cmn.session_id = 0x10; - rcb.current_snode = 0; - memset(rcb.bytes_recvd_bitmask, 0, sizeof(rcb.bytes_recvd_bitmask)); - return 0; + memset((uint8_t *)&rcb.cmn, 0, sizeof(control_block_t)); + rcb.cmn.session_id = 0x10; + rcb.current_snode = 0; + memset(rcb.bytes_recvd_bitmask, 0, sizeof(rcb.bytes_recvd_bitmask)); + return 0; } - - - - diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.h index e5debc0be..2f5554ff3 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/transport_service2.h @@ -24,15 +24,13 @@ #include "transport2_fsm.h" //#include - extern TRANSPORT2_ST_T current_state; - -#define FRAGMENT_FC_TIMEOUT 1000 /*ms*/ -#define FRAGMENT_RX_TIMEOUT 800 /*ms*/ +#define FRAGMENT_FC_TIMEOUT 1000 /*ms*/ +#define FRAGMENT_RX_TIMEOUT 800 /*ms*/ //#define DATAGRAM_SIZE_MAX (UIP_BUFSIZE - UIP_LLH_LEN) /*1280*/ -#define DATAGRAM_SIZE_MAX (200) /*1280*/ +#define DATAGRAM_SIZE_MAX (200) /*1280*/ #define TIMER //#define DEBUG_TIMER @@ -48,17 +46,17 @@ extern TRANSPORT2_ST_T current_state; * \param pCmd pointer to the received frame. * \param cmdLength Length of the received frame. */ -void TransportService_ApplicationCommandHandler(ts_param_t* p, uint8_t *pCmd, uint8_t cmdLength); +void TransportService_ApplicationCommandHandler(ts_param_t *p, + uint8_t *pCmd, + uint8_t cmdLength); /** * Initialize the Transport service state machine. * \param commandHandler Application command handler to be called when a full datagram has been received. * */ -void -ZW_TransportService_Init(void -(*commandHandler)(ts_param_t* p, ZW_APPLICATION_TX_BUFFER *pCmd, -uint16_t cmdLength)); +void ZW_TransportService_Init(void (*commandHandler)( + ts_param_t *p, ZW_APPLICATION_TX_BUFFER *pCmd, uint16_t cmdLength)); /** * \defgroup TransportService Transport service module @@ -69,7 +67,6 @@ uint16_t cmdLength)); * a number of RX session for some nodes. */ - /** * Send a large frame from srcNodeID to dstNodeID using TRANSPORT_SERVICE V2. Only one * transmit session is allowed at any time. @@ -85,11 +82,12 @@ uint16_t cmdLength)); * - false Transmission is not started, because another transmission is already on progress. * The callback function will not be called. */ -bool ZW_TransportService_SendData(ts_param_t* p, const uint8_t *pData, uint16_t dataLength, - void (*completedFunc)(uint8_t txStatus, TX_STATUS_TYPE *)); - +bool ZW_TransportService_SendData(ts_param_t *p, + const uint8_t *pData, + uint16_t dataLength, + void (*completedFunc)(uint8_t txStatus, + TX_STATUS_TYPE *)); #endif #endif /* TRANSPORT_SERVICE2_H_ */ - diff --git a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ts_types.h b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ts_types.h index e6c390422..3ebd2133b 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ts_types.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/libs/zw-libs2/transport_service/ts_types.h @@ -28,60 +28,58 @@ typedef unsigned long u32; typedef unsigned short u16; - /* Transmit frame option flags */ -#define TRANSMIT_OPTION_ACK 0x01 /* request acknowledge from destination node */ -#define TRANSMIT_OPTION_LOW_POWER 0x02 /* transmit at low output power level (1/3 of normal RF range)*/ -#define TRANSMIT_OPTION_AUTO_ROUTE 0x04 /* request retransmission via repeater nodes */ +#define TRANSMIT_OPTION_ACK 0x01 /* request acknowledge from destination node */ +#define TRANSMIT_OPTION_LOW_POWER \ + 0x02 /* transmit at low output power level (1/3 of normal RF range)*/ +#define TRANSMIT_OPTION_AUTO_ROUTE \ + 0x04 /* request retransmission via repeater nodes */ /* do not use response route - Even if available */ -#define TRANSMIT_OPTION_NO_ROUTE 0x10 +#define TRANSMIT_OPTION_NO_ROUTE 0x10 /* Use explore frame if needed */ -#define TRANSMIT_OPTION_EXPLORE 0x20 +#define TRANSMIT_OPTION_EXPLORE 0x20 /** * A response route is locked by the application */ -#define RECEIVE_STATUS_ROUTED_BUSY 0x01 +#define RECEIVE_STATUS_ROUTED_BUSY 0x01 /** * Received at low output power level, this must * have the same value as TRANSMIT_OPTION_LOW_POWER */ -#define RECEIVE_STATUS_LOW_POWER 0x02 +#define RECEIVE_STATUS_LOW_POWER 0x02 /** * Mask for masking out the received frametype bits */ -#define RECEIVE_STATUS_TYPE_MASK 0x0C +#define RECEIVE_STATUS_TYPE_MASK 0x0C /** * Received frame is singlecast frame (rxOptions == xxxx00xx) */ -#define RECEIVE_STATUS_TYPE_SINGLE 0x00 +#define RECEIVE_STATUS_TYPE_SINGLE 0x00 /** * Received frame is broadcast frame (rxOptions == xxxx01xx) */ -#define RECEIVE_STATUS_TYPE_BROAD 0x04 +#define RECEIVE_STATUS_TYPE_BROAD 0x04 /** * Received frame is multicast frame (rxOptions == xxxx10xx) */ -#define RECEIVE_STATUS_TYPE_MULTI 0x08 +#define RECEIVE_STATUS_TYPE_MULTI 0x08 /** * Received frame is an explore frame (rxOptions == xxx1xxxx) * Only TYPE_BROAD can be active at the same time as TYPE_EXPLORE */ -#define RECEIVE_STATUS_TYPE_EXPLORE 0x10 +#define RECEIVE_STATUS_TYPE_EXPLORE 0x10 /** * Received frame is not send to me (rxOptions == x1xxxxxx) * - useful only in promiscuous mode */ -#define RECEIVE_STATUS_FOREIGN_FRAME 0x40 - - +#define RECEIVE_STATUS_FOREIGN_FRAME 0x40 #if !defined(ZIPGW) /** * Structure describing how a package was received / should be transmitted */ -typedef struct ts_param -{ +typedef struct ts_param { /** * Source node */ @@ -116,15 +114,18 @@ typedef struct ts_param /** * Security scheme used for this package */ - uint8_t scheme; // Security scheme + uint8_t scheme; // Security scheme } ts_param_t; #include #endif /* Typedefs shared between ZIPGW and EFR32ZG*/ -typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t* p, ZW_APPLICATION_TX_BUFFER *pCmd, uint16_t cmdLength); -typedef void (*ZW_TransportService_SendData_Callback_t)(uint8_t txStatus, void *t); +typedef void (*ZW_CommandHandler_Callback_t)(ts_param_t *p, + ZW_APPLICATION_TX_BUFFER *pCmd, + uint16_t cmdLength); +typedef void (*ZW_TransportService_SendData_Callback_t)(uint8_t txStatus, + void *t); #if defined(EFR32ZG) || defined(ZWAVE_ON_LINUX) @@ -132,39 +133,50 @@ extern uint16_t g_nodeID; #define MyNodeID g_nodeID -bool TS_SendRaw(node_t dst, uint8_t *buf, uint8_t buflen, uint8_t txopt, VOID_CALLBACKFUNC(cb)(uint8_t status, TX_STATUS_TYPE* user)); -#define TS_SEND_RAW(src, dst, buf, buflen, txopt, cb) TS_SendRaw(dst, buf, buflen, txopt, cb) - +bool TS_SendRaw(node_t dst, + uint8_t *buf, + uint8_t buflen, + uint8_t txopt, + VOID_CALLBACKFUNC(cb)(uint8_t status, TX_STATUS_TYPE *user)); +#define TS_SEND_RAW(src, dst, buf, buflen, txopt, cb) \ + TS_SendRaw(dst, buf, buflen, txopt, cb) #else #define CALLBACKFUNC(func) func -#define ZIPCommandHandler(srcNode, count) \ - if(TSApplicationCommandHandler) {\ - ts_param_t p; \ - p.dendpoint = 0; \ - p.sendpoint = 0; \ - p.snode = srcNode; \ - p.dnode = rcb.cmn.p.dnode; \ - p.rx_flags =0; \ - p.tx_flags = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_EXPLORE;\ - p.scheme = 0xff; \ - TSApplicationCommandHandler(&p,(ZW_APPLICATION_TX_BUFFER*) rcb.datagramData, count); \ - } - +#define ZIPCommandHandler(srcNode, count) \ + if (TSApplicationCommandHandler) { \ + ts_param_t p; \ + p.dendpoint = 0; \ + p.sendpoint = 0; \ + p.snode = srcNode; \ + p.dnode = rcb.cmn.p.dnode; \ + p.rx_flags = 0; \ + p.tx_flags = TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE \ + | TRANSMIT_OPTION_EXPLORE; \ + p.scheme = 0xff; \ + TSApplicationCommandHandler(&p, \ + (ZW_APPLICATION_TX_BUFFER *)rcb.datagramData, \ + count); \ + } extern uint8_t MyNodeID; #if !defined(NEW_TEST_T2) -#define TS_SEND_RAW(src, dst, buf, buflen, txopt, cb) ZW_SendData_Bridge(src, dst, buf, buflen, txopt, cb) +#define TS_SEND_RAW(src, dst, buf, buflen, txopt, cb) \ + ZW_SendData_Bridge(src, dst, buf, buflen, txopt, cb) #endif #endif -#if (defined(__i386__) || defined(__amd64__) || defined(__arm__) || defined(__aarch64__)) && !defined(EFR32ZG) && !defined(ZWAVE_ON_LINUX) -typedef void* TX_STATUS_TYPE; -bool TS_SEND_RAW(node_t snode, node_t dnode, uint8_t *cmd, uint8_t len, uint8_t flags, void(*completedFunc)(uint8_t, TX_STATUS_TYPE*)); +#if (defined(__i386__) || defined(__amd64__) || defined(__arm__) \ + || defined(__aarch64__)) \ + && !defined(EFR32ZG) && !defined(ZWAVE_ON_LINUX) +typedef void *TX_STATUS_TYPE; +bool TS_SEND_RAW(node_t snode, + node_t dnode, + uint8_t *cmd, + uint8_t len, + uint8_t flags, + void (*completedFunc)(uint8_t, TX_STATUS_TYPE *)); #endif - #endif /* _TRANSPORT_SERVICE_TYPES_H_ */ - - diff --git a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_inclusion_controller.c b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_inclusion_controller.c index 43702452d..969dc043c 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_inclusion_controller.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_inclusion_controller.c @@ -49,108 +49,210 @@ typedef enum { } s2_action_controller_t; const s2_transition_t s2_transition_table_controller[] = { - {S2_INC_IDLE, S2_INCLUDING_START, S2_SEND_KEX_GET_ACTION, S2_AWAITING_KEX_REPORT}, - {S2_AWAITING_KEX_REPORT, S2_KEX_REPORT_RECV, S2_KEX_REP_RECV_ACTION, S2_AWAITING_KEY_USER_ACCEPT}, - {S2_AWAITING_KEX_REPORT, S2_INCLUSION_RETRY, S2_RESEND_FRAME_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_KEY_USER_ACCEPT, S2_INCLUDING_ACCEPT, S2_SEND_KEX_SET_ACTION, S2_AWAITING_PUB_KEY_B}, - {S2_AWAITING_KEY_USER_ACCEPT, S2_INCLUDING_REJECT, S2_SEND_ERROR_CANCEL_ACTION, S2_ERROR_SENT}, - {S2_AWAITING_KEY_USER_ACCEPT, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_PUB_KEY_B, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_PUB_KEY_B, S2_INCLUSION_RETRY, S2_RESEND_FRAME_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_PUB_KEY_B, S2_PUB_KEY_RECV_B, S2_SEND_PUB_KEY_A_ACTION, S2_AWAITING_USER_ACCEPT}, - - {S2_AWAITING_USER_ACCEPT, S2_INCLUDING_ACCEPT, S2_DO_ECDH_CALC_A_ACTION, S2_AWAITING_ECHO_KEX_SET}, - {S2_AWAITING_USER_ACCEPT, S2_INCLUDING_REJECT, S2_SEND_ERROR_CANCEL_ACTION, S2_ERROR_SENT}, - {S2_AWAITING_USER_ACCEPT, S2_INCLUSION_RETRY, S2_RESEND_FRAME_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_USER_ACCEPT, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_USER_ACCEPT, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_ECHO_KEX_SET, S2_ECHO_KEX_SET_RECV, S2_SEND_ECHO_KEX_REPORT_ACTION, S2_AWAITING_NET_KEY_GET}, - {S2_AWAITING_ECHO_KEX_SET, S2_INCLUSION_RETRY, S2_RESEND_FRAME_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_ECHO_KEX_SET, S2_INCLUDING_DECRYPT_FAILED, S2_SEND_ERROR_DECRYPT_ACTION, S2_ERROR_SENT}, - {S2_AWAITING_ECHO_KEX_SET, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_ECHO_KEX_SET, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_GET, S2_NET_KEY_GET_RECV, S2_SEND_NET_KEY_REPORT_ACTION, S2_AWAITING_NET_KEY_VERIFY}, - {S2_AWAITING_NET_KEY_GET, S2_SEND_FINAL_TRANSFER_END, S2_CHECK_NO_KEYS, S2_INC_IDLE}, - {S2_AWAITING_NET_KEY_GET, S2_INCLUSION_RETRY, S2_RESEND_DATA_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_GET, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_GET, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_GET, S2_ECHO_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_GET, S2_NET_KEY_VERIFY_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_VERIFY, S2_NET_KEY_VERIFY_FINAL_RECV, S2_SEND_TRANSFER_END_ACTION, S2_AWAITING_TRANSFER_END}, - {S2_AWAITING_NET_KEY_VERIFY, S2_NET_KEY_VERIFY_RECV, S2_SEND_TRANSFER_END_ACTION, S2_AWAITING_NET_KEY_GET}, - {S2_AWAITING_NET_KEY_VERIFY, S2_INCLUSION_RETRY, S2_RESEND_DATA_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_VERIFY, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_VERIFY, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_VERIFY, S2_ECHO_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_NET_KEY_VERIFY, S2_NET_KEY_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_TRANSFER_END_RECV, S2_INCLUSION_COMPLETE_ACTION, S2_INC_IDLE}, - {S2_AWAITING_TRANSFER_END, S2_INCLUSION_RETRY, S2_RESEND_DATA_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_ECHO_KEX_SET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_NET_KEY_GET_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_NET_KEY_VERIFY_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, - {S2_AWAITING_TRANSFER_END, S2_NET_KEY_VERIFY_FINAL_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_INC_IDLE, + S2_INCLUDING_START, + S2_SEND_KEX_GET_ACTION, + S2_AWAITING_KEX_REPORT}, + {S2_AWAITING_KEX_REPORT, + S2_KEX_REPORT_RECV, + S2_KEX_REP_RECV_ACTION, + S2_AWAITING_KEY_USER_ACCEPT}, + {S2_AWAITING_KEX_REPORT, + S2_INCLUSION_RETRY, + S2_RESEND_FRAME_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_KEY_USER_ACCEPT, + S2_INCLUDING_ACCEPT, + S2_SEND_KEX_SET_ACTION, + S2_AWAITING_PUB_KEY_B}, + {S2_AWAITING_KEY_USER_ACCEPT, + S2_INCLUDING_REJECT, + S2_SEND_ERROR_CANCEL_ACTION, + S2_ERROR_SENT}, + {S2_AWAITING_KEY_USER_ACCEPT, + S2_KEX_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_PUB_KEY_B, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_PUB_KEY_B, + S2_INCLUSION_RETRY, + S2_RESEND_FRAME_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_PUB_KEY_B, + S2_PUB_KEY_RECV_B, + S2_SEND_PUB_KEY_A_ACTION, + S2_AWAITING_USER_ACCEPT}, + + {S2_AWAITING_USER_ACCEPT, + S2_INCLUDING_ACCEPT, + S2_DO_ECDH_CALC_A_ACTION, + S2_AWAITING_ECHO_KEX_SET}, + {S2_AWAITING_USER_ACCEPT, + S2_INCLUDING_REJECT, + S2_SEND_ERROR_CANCEL_ACTION, + S2_ERROR_SENT}, + {S2_AWAITING_USER_ACCEPT, + S2_INCLUSION_RETRY, + S2_RESEND_FRAME_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_USER_ACCEPT, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_USER_ACCEPT, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_ECHO_KEX_SET, + S2_ECHO_KEX_SET_RECV, + S2_SEND_ECHO_KEX_REPORT_ACTION, + S2_AWAITING_NET_KEY_GET}, + {S2_AWAITING_ECHO_KEX_SET, + S2_INCLUSION_RETRY, + S2_RESEND_FRAME_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_ECHO_KEX_SET, + S2_INCLUDING_DECRYPT_FAILED, + S2_SEND_ERROR_DECRYPT_ACTION, + S2_ERROR_SENT}, + {S2_AWAITING_ECHO_KEX_SET, + S2_KEX_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_ECHO_KEX_SET, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_GET, + S2_NET_KEY_GET_RECV, + S2_SEND_NET_KEY_REPORT_ACTION, + S2_AWAITING_NET_KEY_VERIFY}, + {S2_AWAITING_NET_KEY_GET, + S2_SEND_FINAL_TRANSFER_END, + S2_CHECK_NO_KEYS, + S2_INC_IDLE}, + {S2_AWAITING_NET_KEY_GET, + S2_INCLUSION_RETRY, + S2_RESEND_DATA_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_GET, S2_KEX_REPORT_RECV, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_GET, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_GET, + S2_ECHO_KEX_SET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_GET, + S2_NET_KEY_VERIFY_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_NET_KEY_VERIFY_FINAL_RECV, + S2_SEND_TRANSFER_END_ACTION, + S2_AWAITING_TRANSFER_END}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_NET_KEY_VERIFY_RECV, + S2_SEND_TRANSFER_END_ACTION, + S2_AWAITING_NET_KEY_GET}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_INCLUSION_RETRY, + S2_RESEND_DATA_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_KEX_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_PUB_KEY_RECV_B, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_ECHO_KEX_SET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_NET_KEY_VERIFY, + S2_NET_KEY_GET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, + S2_TRANSFER_END_RECV, + S2_INCLUSION_COMPLETE_ACTION, + S2_INC_IDLE}, + {S2_AWAITING_TRANSFER_END, + S2_INCLUSION_RETRY, + S2_RESEND_DATA_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, + S2_KEX_REPORT_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, S2_PUB_KEY_RECV_B, S2_NO_ACTION, S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, + S2_ECHO_KEX_SET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, + S2_NET_KEY_GET_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, + S2_NET_KEY_VERIFY_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, + {S2_AWAITING_TRANSFER_END, + S2_NET_KEY_VERIFY_FINAL_RECV, + S2_NO_ACTION, + S2_INC_STATE_ANY}, }; -const size_t s2_transition_table_controller_length = ELEM_COUNT(s2_transition_table_controller); +const size_t s2_transition_table_controller_length + = ELEM_COUNT(s2_transition_table_controller); void execute_action_controller(uint8_t action) { const s2_action_controller_t ctrl_action = (s2_action_controller_t)action; - switch (ctrl_action) - { + switch (ctrl_action) { case S2_CHECK_NO_KEYS: s2_check_no_keys(); - break; + break; case S2_SEND_KEX_GET_ACTION: s2_send_kex_get(); - break; + break; case S2_KEX_REP_RECV_ACTION: s2_kex_rep_recv(); - break; + break; case S2_SEND_KEX_SET_ACTION: s2_send_kex_set(); - break; + break; case S2_SEND_PUB_KEY_A_ACTION: s2_send_pub_key_a(); - break; + break; case S2_DO_ECDH_CALC_A_ACTION: s2_do_ecdh_calc_a(); - break; + break; case S2_SEND_ECHO_KEX_REPORT_ACTION: s2_send_echo_kex_report(); - break; + break; case S2_SEND_ERROR_DECRYPT_ACTION: inclusion_failed_frame_send(KEX_FAIL_DECRYPT, NON_SECURE); - break; + break; case S2_SEND_ERROR_CANCEL_ACTION: inclusion_failed_frame_send(KEX_FAIL_CANCEL, NON_SECURE); - break; + break; case S2_SEND_NET_KEY_REPORT_ACTION: s2_send_net_key_report(); - break; + break; case S2_SEND_TRANSFER_END_ACTION: s2_send_transfer_end(); - break; + break; case S2_INCLUSION_COMPLETE_ACTION: s2_inclusion_complete(); - break; + break; default: - break; + break; } } @@ -159,20 +261,29 @@ void execute_action_controller(uint8_t action) static void s2_do_ecdh_calc_a(void) { #ifdef ZWAVE_PSA_SECURE_VAULT - zw_status_t status = zw_compute_inclusion_ecdh_shared_secret(mp_context->public_key, zwave_shared_secret); + zw_status_t status + = zw_compute_inclusion_ecdh_shared_secret(mp_context->public_key, + zwave_shared_secret); if (status != ZW_PSA_SUCCESS) { zw_security_error(status); } memcpy(shared_secret, zwave_shared_secret, ZWAVE_ECDH_SECRET_LENGTH); #else keystore_private_key_read(&shared_key_mem[LOCAL_PRIVATE_KEY_INDEX]); - crypto_scalarmult_curve25519(shared_secret, &shared_key_mem[LOCAL_PRIVATE_KEY_INDEX], mp_context->public_key); + crypto_scalarmult_curve25519(shared_secret, + &shared_key_mem[LOCAL_PRIVATE_KEY_INDEX], + mp_context->public_key); #endif memcpy(&shared_key_mem[PUBLIC_KEY_B_INDEX], mp_context->public_key, 32); keystore_public_key_read(&shared_key_mem[PUBLIC_KEY_A_INDEX]); tempkey_extract(shared_secret, shared_key_mem, mp_context->public_key); - S2_network_key_update(mp_context, ZWAVE_KEY_ID_NONE, TEMP_KEY_SECURE, mp_context->public_key, 1, false); + S2_network_key_update(mp_context, + ZWAVE_KEY_ID_NONE, + TEMP_KEY_SECURE, + mp_context->public_key, + 1, + false); } /**@brief Function for validating the schemes supported in a KEX Report frame. @@ -185,10 +296,10 @@ static void s2_do_ecdh_calc_a(void) */ static uint8_t validate_reported_schemes(void) { - mp_context->scheme_support = (mp_context->buf[SECURITY_2_KEX_REP_SCHEME_POS] & SECURITY_2_SCHEME_SUPPORT_MASK); + mp_context->scheme_support = (mp_context->buf[SECURITY_2_KEX_REP_SCHEME_POS] + & SECURITY_2_SCHEME_SUPPORT_MASK); - if (mp_context->scheme_support & SECURITY_2_SCHEME_1_SUPPORT) - { + if (mp_context->scheme_support & SECURITY_2_SCHEME_1_SUPPORT) { return 0; } @@ -207,10 +318,10 @@ static uint8_t validate_reported_schemes(void) */ static uint8_t validate_reported_curves(void) { - mp_context->curve_support = (mp_context->buf[SECURITY_2_KEX_REP_CURVE_POS] & KEX_REPORT_CURVE_MASK); + mp_context->curve_support + = (mp_context->buf[SECURITY_2_KEX_REP_CURVE_POS] & KEX_REPORT_CURVE_MASK); - if (mp_context->curve_support & KEX_REPORT_CURVE_25519) - { + if (mp_context->curve_support & KEX_REPORT_CURVE_25519) { return 0; } @@ -231,15 +342,16 @@ static uint8_t validate_reported_keys(void) { // Store reported keys for echoing back unmodified in Kex Report Echo mp_context->kex_report_keys = mp_context->buf[SECURITY_2_KEX_REP_KEYS_POS]; - mp_context->key_exchange = mp_context->buf[SECURITY_2_KEX_REP_KEYS_POS]; - /* If LR inclusion, filter out invalid keys */ + mp_context->key_exchange = mp_context->buf[SECURITY_2_KEX_REP_KEYS_POS]; + /* If LR inclusion, filter out invalid keys */ if (IS_LR_NODE(mp_context->inclusion_peer.r_node)) { mp_context->key_exchange &= ~(KEY_CLASS_S2_UNAUTHENTICATED | KEY_CLASS_S0); } - mp_context->key_granted = mp_context->key_exchange & SECURITY_2_KEY_MASK; /* Why not mask ->key_exchange? */ + mp_context->key_granted + = mp_context->key_exchange + & SECURITY_2_KEY_MASK; /* Why not mask ->key_exchange? */ - if (mp_context->key_granted != 0) - { + if (mp_context->key_granted != 0) { return 0; } @@ -259,10 +371,13 @@ static uint8_t validate_reported_keys(void) static uint8_t validate_requested_key(void) { uint8_t req_key = mp_context->buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS]; - + // Test that only one bit is set and that the bit corresponds to a granted key. - if ((0 == (req_key & (req_key - 1))) && - (req_key & mp_context->key_granted)) // key_granted is already in LR format because it was converted in s2_inclusion_key_grant() + if ( + (0 == (req_key & (req_key - 1))) + && (req_key + & mp_context + ->key_granted)) // key_granted is already in LR format because it was converted in s2_inclusion_key_grant() { mp_context->key_requested = req_key; return 0; @@ -272,7 +387,6 @@ static uint8_t validate_requested_key(void) inclusion_failed_frame_send(KEX_FAIL_KEY_GET, NON_SECURE); return KEX_FAIL; - } /**@brief Function for validating that the echo kex set frame is identical to the transmitted @@ -286,12 +400,18 @@ static uint8_t validate_requested_key(void) static uint8_t validate_echo_kex_set(void) { // Test that only one bit is set and that the bit corresponds to a granted key. - if ((mp_context->scheme_support == mp_context->buf[SECURITY_2_KEX_SET_SCHEME_POS]) && - (mp_context->curve_support == mp_context->buf[SECURITY_2_KEX_SET_CURVE_POS]) && - (mp_context->key_granted == mp_context->buf[SECURITY_2_KEX_SET_KEYS_POS]) && - (mp_context->inclusion_mode == ((mp_context->buf[SECURITY_2_KEX_SET_ECHO_POS] & SECURITY_2_CSA_ON) == SECURITY_2_CSA_ON) ? INCLUSION_MODE_CSA : INCLUSION_MODE_SSA) - ) - { + if ((mp_context->scheme_support + == mp_context->buf[SECURITY_2_KEX_SET_SCHEME_POS]) + && (mp_context->curve_support + == mp_context->buf[SECURITY_2_KEX_SET_CURVE_POS]) + && (mp_context->key_granted + == mp_context->buf[SECURITY_2_KEX_SET_KEYS_POS]) + && (mp_context->inclusion_mode + == ((mp_context->buf[SECURITY_2_KEX_SET_ECHO_POS] + & SECURITY_2_CSA_ON) + == SECURITY_2_CSA_ON) + ? INCLUSION_MODE_CSA + : INCLUSION_MODE_SSA)) { return 0; } @@ -307,9 +427,10 @@ static uint8_t validate_echo_kex_set(void) */ static void s2_send_kex_get(void) { - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_GET; - mp_context->inclusion_buf_length = SECURITY_2_KEX_GET_LENGTH; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_GET; + mp_context->inclusion_buf_length = SECURITY_2_KEX_GET_LENGTH; m_retry_counter = MAX_RETRY_COUNT; s2_inclusion_send_frame(); @@ -318,40 +439,49 @@ static void s2_send_kex_get(void) static void s2_kex_rep_recv(void) { - uint8_t ret_val; - zwave_event_t * s2_event; + uint8_t ret_val; + zwave_event_t *s2_event; s2_inclusion_stop_timeout(); - ret_val = validate_reported_schemes(); - if (ret_val != 0) - { + ret_val = validate_reported_schemes(); + if (ret_val != 0) { process_event(S2_INCLUSION_ERROR_SENT); return; } ret_val = validate_reported_curves(); - if (ret_val != 0) - { + if (ret_val != 0) { process_event(S2_INCLUSION_ERROR_SENT); return; } ret_val = validate_reported_keys(); - if (ret_val != 0) - { + if (ret_val != 0) { process_event(S2_INCLUSION_ERROR_SENT); return; } - mp_context->csa_support = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] & SECURITY_2_KEX_REP_CSA_MASK) ? 1 : 0; - mp_context->nls_state = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] & SECURITY_2_KEX_REP_NLS_MASK) ? 1 : 0; - - s2_event = (zwave_event_t *)m_event_buffer; - s2_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - s2_event->evt.s2_event.peer = mp_context->inclusion_peer; - s2_event->evt.s2_event.s2_data.kex_report.security_keys = mp_context->key_granted; - s2_event->evt.s2_event.s2_data.kex_report.csa = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] & SECURITY_2_KEX_REP_CSA_MASK) !=0; - s2_event->evt.s2_event.s2_data.kex_report.nls_available = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] & SECURITY_2_KEX_REP_NLS_MASK); + mp_context->csa_support = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] + & SECURITY_2_KEX_REP_CSA_MASK) + ? 1 + : 0; + mp_context->nls_state = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] + & SECURITY_2_KEX_REP_NLS_MASK) + ? 1 + : 0; + + s2_event = (zwave_event_t *)m_event_buffer; + s2_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + s2_event->evt.s2_event.peer = mp_context->inclusion_peer; + s2_event->evt.s2_event.s2_data.kex_report.security_keys + = mp_context->key_granted; + s2_event->evt.s2_event.s2_data.kex_report.csa + = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] + & SECURITY_2_KEX_REP_CSA_MASK) + != 0; + s2_event->evt.s2_event.s2_data.kex_report.nls_available + = (mp_context->buf[SECURITY_2_KEX_REP_ECHO_POS] + & SECURITY_2_KEX_REP_NLS_MASK); m_evt_handler(s2_event); s2_inclusion_set_timeout(mp_context, TAI1_TIMEOUT); @@ -361,16 +491,22 @@ static void s2_send_kex_set(void) { s2_inclusion_stop_timeout(); - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_SET; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_ECHO_POS] = SECURITY_2_ECHO_OFF; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_SCHEME_POS] = SECURITY_2_SCHEME_1_SUPPORT; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_CURVE_POS] = KEX_REPORT_CURVE_25519; - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_KEYS_POS] = mp_context->key_granted; - mp_context->inclusion_buf_length = SECURITY_2_KEX_SET_LENGTH; - - if(mp_context->inclusion_mode == INCLUSION_MODE_CSA) { - mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_ECHO_POS] |= SECURITY_2_CSA_ON; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_SET; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_ECHO_POS] + = SECURITY_2_ECHO_OFF; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_SCHEME_POS] + = SECURITY_2_SCHEME_1_SUPPORT; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_CURVE_POS] + = KEX_REPORT_CURVE_25519; + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_KEYS_POS] + = mp_context->key_granted; + mp_context->inclusion_buf_length = SECURITY_2_KEX_SET_LENGTH; + + if (mp_context->inclusion_mode == INCLUSION_MODE_CSA) { + mp_context->u.inclusion_buf[SECURITY_2_KEX_SET_ECHO_POS] + |= SECURITY_2_CSA_ON; } m_retry_counter = MAX_RETRY_COUNT; s2_inclusion_send_frame(); @@ -383,14 +519,21 @@ static void s2_send_transfer_end(void) // A network key verify frame has been received. // This packet has been successfully decrypted, thus we must update the context to use temp key for sending transfer end. - S2_network_key_update(mp_context, ZWAVE_KEY_ID_NONE, TEMP_KEY_SECURE, mp_context->public_key, 1, false); - - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_TRANSFER_END; - mp_context->u.inclusion_buf[SECURITY_2_TRANSFER_END_FLAGS_POS] = SECURITY_2_KEY_VERIFIED; - mp_context->inclusion_buf_length = SECURITY_2_TRANSFER_END_LENGTH; - - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + S2_network_key_update(mp_context, + ZWAVE_KEY_ID_NONE, + TEMP_KEY_SECURE, + mp_context->public_key, + 1, + false); + + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_TRANSFER_END; + mp_context->u.inclusion_buf[SECURITY_2_TRANSFER_END_FLAGS_POS] + = SECURITY_2_KEY_VERIFIED; + mp_context->inclusion_buf_length = SECURITY_2_TRANSFER_END_LENGTH; + + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; mp_context->inclusion_peer.tx_options = 0; m_retry_counter = MAX_RETRY_COUNT; @@ -402,27 +545,28 @@ static void s2_send_pub_key_a(void) { // Post event upwards to inform that a public key is received and the user should confirm the // inclusion of the node. - zwave_event_t * s2_event; + zwave_event_t *s2_event; s2_inclusion_stop_timeout(); - s2_event = (zwave_event_t *)m_event_buffer; - s2_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + s2_event = (zwave_event_t *)m_event_buffer; + s2_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; s2_event->evt.s2_event.peer = mp_context->inclusion_peer; // For now, do a raw copy. Design should be cleaned up to ensure proper use of buffers. // Remember to strip away the frame header. memcpy(s2_event->evt.s2_event.s2_data.challenge_req.public_key, - &mp_context->buf[SECURITY_2_PUB_KEY_KEY_POS], sizeof(public_key_t)); + &mp_context->buf[SECURITY_2_PUB_KEY_KEY_POS], + sizeof(public_key_t)); s2_event->evt.s2_event.s2_data.challenge_req.length = sizeof(public_key_t); - s2_event->evt.s2_event.s2_data.challenge_req.granted_keys = mp_context->key_granted; - if ((mp_context->key_granted & (SECURITY_2_SECURITY_2_CLASS_1 | SECURITY_2_SECURITY_2_CLASS_2)) && - (mp_context->inclusion_mode == INCLUSION_MODE_SSA)) - { - s2_event->evt.s2_event.s2_data.challenge_req.dsk_length = DSK_SSA_CHALLENGE_LENGTH; - } - else - { + s2_event->evt.s2_event.s2_data.challenge_req.granted_keys + = mp_context->key_granted; + if ((mp_context->key_granted + & (SECURITY_2_SECURITY_2_CLASS_1 | SECURITY_2_SECURITY_2_CLASS_2)) + && (mp_context->inclusion_mode == INCLUSION_MODE_SSA)) { + s2_event->evt.s2_event.s2_data.challenge_req.dsk_length + = DSK_SSA_CHALLENGE_LENGTH; + } else { s2_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; } memcpy(mp_context->public_key, @@ -431,15 +575,18 @@ static void s2_send_pub_key_a(void) m_evt_handler(s2_event); - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = PUBLIC_KEY_REPORT; - mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_INC_FLAG_POS] = SECURITY_2_INCLUDING_NODE; - mp_context->inclusion_buf_length = SECURITY_2_PUB_KEY_LENGTH; - keystore_public_key_read(&mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS]); - - if ((mp_context->inclusion_mode == INCLUSION_MODE_CSA) && - (mp_context->key_granted & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) - { + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = PUBLIC_KEY_REPORT; + mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_INC_FLAG_POS] + = SECURITY_2_INCLUDING_NODE; + mp_context->inclusion_buf_length = SECURITY_2_PUB_KEY_LENGTH; + keystore_public_key_read( + &mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS]); + + if ((mp_context->inclusion_mode == INCLUSION_MODE_CSA) + && (mp_context->key_granted + & ~(KEY_CLASS_S0 | KEY_CLASS_S2_UNAUTHENTICATED))) { mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS] = 0x00; mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS + 1] = 0x00; mp_context->u.inclusion_buf[SECURITY_2_PUB_KEY_KEY_POS + 2] = 0x00; @@ -458,22 +605,27 @@ static void s2_send_echo_kex_report(void) s2_inclusion_stop_timeout(); ret_val = validate_echo_kex_set(); - if (ret_val != 0) - { + if (ret_val != 0) { process_event(S2_INCLUSION_ERROR_SENT); return; } - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_REPORT; - mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_ECHO_POS] = (uint8_t) ((mp_context->nls_state << 2) | (mp_context->csa_support << 1) | SECURITY_2_ECHO_ON); - mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_SCHEME_POS] = mp_context->scheme_support; - mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_CURVE_POS] = mp_context->curve_support; - mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_KEYS_POS] = mp_context->kex_report_keys; - mp_context->inclusion_buf_length = SECURITY_2_KEX_REPORT_LENGTH; - mp_context->key_exchange = 0x00; - - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = KEX_REPORT; + mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_ECHO_POS] + = (uint8_t)((mp_context->nls_state << 2) | (mp_context->csa_support << 1) + | SECURITY_2_ECHO_ON); + mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_SCHEME_POS] + = mp_context->scheme_support; + mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_CURVE_POS] + = mp_context->curve_support; + mp_context->u.inclusion_buf[SECURITY_2_KEX_REP_KEYS_POS] + = mp_context->kex_report_keys; + mp_context->inclusion_buf_length = SECURITY_2_KEX_REPORT_LENGTH; + mp_context->key_exchange = 0x00; + + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; mp_context->inclusion_peer.tx_options = S2_TXOPTION_VERIFY_DELIVERY; m_retry_counter = MAX_RETRY_COUNT; @@ -487,18 +639,20 @@ static void s2_send_echo_kex_report(void) * In other words, the Access key requested by an LR node is different from the Access key * requested by a normal node. Same for the Authenticated key. */ -static uint8_t translate_keyslot_to_read_for_LR(uint8_t requested_keyslot, node_t peer_nodeid) +static uint8_t translate_keyslot_to_read_for_LR(uint8_t requested_keyslot, + node_t peer_nodeid) { (void)requested_keyslot; (void)peer_nodeid; - uint8_t actual_keyslot = mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS]; + uint8_t actual_keyslot + = mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS]; // Read other keys here in case of LR // Note: This logic cannot handle bootstrapping controllers requesing BOTH LR and normal keys // It will have to be expanded to include a check for that. Luckily, we are not required // to support that yet. if (IS_LR_NODE(mp_context->inclusion_peer.r_node)) { - switch(actual_keyslot) { + switch (actual_keyslot) { case KEY_CLASS_S2_AUTHENTICATED: actual_keyslot = KEY_CLASS_S2_AUTHENTICATED_LR; break; @@ -521,26 +675,30 @@ static void s2_send_net_key_report(void) s2_inclusion_stop_timeout(); ret_val = validate_requested_key(); - if (ret_val != 0) - { + if (ret_val != 0) { process_event(S2_INCLUSION_ERROR_SENT); return; } - mp_context->key_exchange |= mp_context->buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS]; + mp_context->key_exchange + |= mp_context->buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS]; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] = COMMAND_CLASS_SECURITY_2; - mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] = SECURITY_2_NETWORK_KEY_REPORT; - mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS] = mp_context->buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS]; - mp_context->inclusion_buf_length = SECURITY_2_NET_KEY_REPORT_LENGTH; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_CLASS_POS] + = COMMAND_CLASS_SECURITY_2; + mp_context->u.inclusion_buf[SECURITY_2_COMMAND_POS] + = SECURITY_2_NETWORK_KEY_REPORT; + mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS] + = mp_context->buf[SECURITY_2_NET_KEY_GET_REQ_KEY_POS]; + mp_context->inclusion_buf_length = SECURITY_2_NET_KEY_REPORT_LENGTH; uint8_t keyslot_to_read = translate_keyslot_to_read_for_LR( - mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS], - mp_context->inclusion_peer.r_node); + mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS], + mp_context->inclusion_peer.r_node); - keystore_network_key_read(keyslot_to_read, - &mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_KEY_POS]); + keystore_network_key_read( + keyslot_to_read, + &mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_KEY_POS]); - mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; + mp_context->inclusion_peer.class_id = TEMP_KEY_SECURE; mp_context->inclusion_peer.tx_options = 0; m_retry_counter = MAX_RETRY_COUNT; @@ -550,72 +708,79 @@ static void s2_send_net_key_report(void) // After tranmitting the Network key, we expect the Netkey verify to be transmitted using that key. // Thus we must update the context. - if(mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS] == SECURITY_2_SECURITY_0_NETWORK_KEY) { - // After tranmitting the Network key, we expect the Netkey verify to be transmitted using that key. - // Thus we must update the context. - S2_network_key_update(mp_context, ZWAVE_KEY_ID_NONE, NETWORK_KEY_SECURE, &mp_context->u.inclusion_buf[3], 0, false); + if (mp_context->u.inclusion_buf[SECURITY_2_NET_KEY_REP_GRANT_KEY_POS] + == SECURITY_2_SECURITY_0_NETWORK_KEY) { + // After tranmitting the Network key, we expect the Netkey verify to be transmitted using that key. + // Thus we must update the context. + S2_network_key_update(mp_context, + ZWAVE_KEY_ID_NONE, + NETWORK_KEY_SECURE, + &mp_context->u.inclusion_buf[3], + 0, + false); } } static void s2_inclusion_complete(void) { // Post event upwards to inform that inclusion of noda A has successfully completed. - zwave_event_t * s2_event; + zwave_event_t *s2_event; //Check that the final transfer end is ok - if ((SECURITY_2_TRANSFER_END == mp_context->buf[SECURITY_2_COMMAND_POS]) && - (SECURITY_2_KEY_REQ_COMPLETE == (mp_context->buf[SECURITY_2_TRANSFER_END_FLAGS_POS] & - (SECURITY_2_KEY_REQ_COMPLETE | SECURITY_2_KEY_VERIFIED)))) - { + if ((SECURITY_2_TRANSFER_END == mp_context->buf[SECURITY_2_COMMAND_POS]) + && (SECURITY_2_KEY_REQ_COMPLETE + == (mp_context->buf[SECURITY_2_TRANSFER_END_FLAGS_POS] + & (SECURITY_2_KEY_REQ_COMPLETE | SECURITY_2_KEY_VERIFIED)))) { s2_inclusion_stop_timeout(); s2_restore_keys(mp_context, true); - s2_event = (zwave_event_t *)m_event_buffer; - s2_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - s2_event->evt.s2_event.peer = mp_context->inclusion_peer; - s2_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = mp_context->key_exchange; + s2_event = (zwave_event_t *)m_event_buffer; + s2_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + s2_event->evt.s2_event.peer = mp_context->inclusion_peer; + s2_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys + = mp_context->key_exchange; m_evt_handler(s2_event); } else { - inclusion_failed_frame_send(KEX_FAIL_KEY_VERIFY,NON_SECURE); + inclusion_failed_frame_send(KEX_FAIL_KEY_VERIFY, NON_SECURE); inclusion_failed_evt_push(KEX_FAIL_KEY_VERIFY); } } -static void s2_check_no_keys(void) { - if(mp_context->key_granted) { +static void s2_check_no_keys(void) +{ + if (mp_context->key_granted) { inclusion_failed_evt_push(mp_context->kex_fail_code); } else { s2_inclusion_complete(); } } -void s2_inclusion_key_grant(struct S2 *p_context, uint8_t include, uint8_t keys, uint8_t csa) +void s2_inclusion_key_grant(struct S2 *p_context, + uint8_t include, + uint8_t keys, + uint8_t csa) { MP_CTX_DEF - if (ACCEPT_INCLUSION == include) - { + if (ACCEPT_INCLUSION == include) { mp_context->inclusion_mode = csa ? INCLUSION_MODE_CSA : INCLUSION_MODE_SSA; - mp_context->key_granted = keys; + mp_context->key_granted = keys; process_event(S2_INCLUDING_ACCEPT); - } - else - { + } else { process_event(S2_INCLUDING_REJECT); } } - -void s2_inclusion_including_start(struct S2 *p_context, const s2_connection_t* conn) +void s2_inclusion_including_start(struct S2 *p_context, + const s2_connection_t *conn) { MP_CTX_DEF - if(mp_context->inclusion_state == S2_INC_IDLE) - { - mp_context->inclusion_peer = *conn; + if (mp_context->inclusion_state == S2_INC_IDLE) { + mp_context->inclusion_peer = *conn; mp_context->inclusion_peer.tx_options = 0; - mp_context->inclusion_mode = INCLUSION_MODE_SSA; - mp_context->kex_fail_code = 0; + mp_context->inclusion_mode = INCLUSION_MODE_SSA; + mp_context->kex_fail_code = 0; process_event(S2_INCLUDING_START); mp_context->is_keys_restored = false; } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_keystore_int.h b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_keystore_int.h index cc76387ef..cf9011215 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_keystore_int.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_keystore_int.h @@ -46,11 +46,11 @@ typedef struct nvm_config { #define nvm_config_get(par_name, dst) \ zwapi_memory_get_buffer(offsetof(struct nvm_config, par_name), \ - (uint8_t*)dst, \ + (uint8_t *)dst, \ sizeof(((struct nvm_config *)0)->par_name)) #define nvm_config_set(par_name, src) \ zwapi_memory_put_buffer(offsetof(struct nvm_config, par_name), \ - (uint8_t*)src, \ + (uint8_t *)src, \ sizeof(((struct nvm_config *)0)->par_name), \ NULL) @@ -76,7 +76,6 @@ void zwave_s2_create_new_dynamic_ecdh_key(); void zwave_s2_keystore_set_ecdh_key_mode( zwave_s2_keystore_ecdh_key_mode_t mode); - #ifdef __cplusplus } #endif diff --git a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_network.c b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_network.c index 6d66492d6..93214daa2 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_network.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_network.c @@ -139,21 +139,31 @@ void zwave_s2_network_init() zwave_s2_log_security_keys(SL_LOG_INFO); #endif - uint8_t nls_support = 0; - uint8_t nls_state = 0; + uint8_t nls_support = 0; + uint8_t nls_state = 0; zwave_node_id_t node_id = zwave_network_management_get_node_id(); sl_status_t status = zwapi_get_node_nls(node_id, &nls_state, &nls_support); if (status != SL_STATUS_OK) { - sl_log_error(LOG_TAG, "Unable to read NLS state for Node ID: %d\n", node_id); + sl_log_error(LOG_TAG, + "Unable to read NLS state for Node ID: %d\n", + node_id); return; } - sl_log_info(LOG_TAG, "NLS %s, NLS %s for Node ID: %d\n", nls_support == 0 ? "not supported" : "supported", nls_state == 0 ? "not active" : "active", node_id); + sl_log_info(LOG_TAG, + "NLS %s, NLS %s for Node ID: %d\n", + nls_support == 0 ? "not supported" : "supported", + nls_state == 0 ? "not active" : "active", + node_id); S2_load_nls_state(s2_ctx, nls_state); - status = zwave_store_nls_state(node_id, nls_state, REPORTED_ATTRIBUTE) || zwave_store_nls_support(node_id, nls_support, REPORTED_ATTRIBUTE); + status = zwave_store_nls_state(node_id, nls_state, REPORTED_ATTRIBUTE) + || zwave_store_nls_support(node_id, nls_support, REPORTED_ATTRIBUTE); if (status != SL_STATUS_OK) { - sl_log_error(LOG_TAG, "Unable to store NLS state/support in attribute store for Node ID: %d\n", node_id); + sl_log_error( + LOG_TAG, + "Unable to store NLS state/support in attribute store for Node ID: %d\n", + node_id); } } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_nonce_management.c b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_nonce_management.c index 9b65cfb0c..e9dd019cc 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_nonce_management.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_nonce_management.c @@ -113,7 +113,7 @@ void zwave_s2_reset_span(zwave_node_id_t node_id) } void zwave_s2_reset_mpan(zwave_node_id_t owner_node_id, - zwave_multicast_group_id_t group_id) + zwave_multicast_group_id_t group_id) { for (size_t i = 0; i < MPAN_TABLE_SIZE; i++) { if (s2_ctx->mpan_table[i].owner_id == owner_node_id diff --git a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_printf.c b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_printf.c index 242970a3a..bbd94f4ee 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_printf.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_printf.c @@ -11,7 +11,7 @@ * *****************************************************************************/ #include "S2.h" -#include +#include #include #include "sl_log.h" @@ -21,18 +21,18 @@ void S2_dbg_printf(const char *format, ...) { char buffer[256]; va_list args; - va_start (args, format); - vsnprintf (buffer,sizeof(buffer),format, args); - sl_log_debug(LOG_TAG, "%s",buffer); - va_end (args); + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + sl_log_debug(LOG_TAG, "%s", buffer); + va_end(args); } void S2_err_printf(const char *format, ...) { char buffer[256]; va_list args; - va_start (args, format); - vsnprintf (buffer,sizeof(buffer),format, args); - sl_log_error(LOG_TAG, "%s",buffer); - va_end (args); + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + sl_log_error(LOG_TAG, "%s", buffer); + va_end(args); } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_transport.c b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_transport.c index a156af2d5..9c43bb68a 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_transport.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/src/zwave_s2_transport.c @@ -89,11 +89,16 @@ static uint8_t secure_nif_length; // NLS context typedef struct s2_node_nls_context { - zwave_nodemask_t node_list; // bitmask containing NLS enabled nodes in the network - uint16_t node_list_length; // length of the list in bytes (is not equal to the number of nodes in the network) - zwave_node_id_t next_sent_node_id; // node ID of the NLS enabled node to be sent next - uint16_t nls_enabled_node_cnt; // total number of NLS enabled nodes in the network - uint16_t nls_enabled_node_sent_cnt; // number of NLS enabled nodes already sent to the joining node + zwave_nodemask_t + node_list; // bitmask containing NLS enabled nodes in the network + uint16_t + node_list_length; // length of the list in bytes (is not equal to the number of nodes in the network) + zwave_node_id_t + next_sent_node_id; // node ID of the NLS enabled node to be sent next + uint16_t + nls_enabled_node_cnt; // total number of NLS enabled nodes in the network + uint16_t + nls_enabled_node_sent_cnt; // number of NLS enabled nodes already sent to the joining node } s2_node_nls_context_t; static s2_node_nls_context_t node_nls_context = {0}; @@ -324,7 +329,7 @@ uint8_t S2_send_frame(struct S2 *ctxt, { (void)ctxt; zwave_controller_connection_info_t info = {}; - zwave_tx_options_t options = {}; + zwave_tx_options_t options = {}; if (state.tx_options.transport.is_protocol_frame) { // TX options provided to zwave_s2_send_data can be used now at libS2 exit @@ -428,11 +433,19 @@ uint8_t S2_send_frame_multi(struct S2 *ctxt, 0); } -void S2_notify_nls_state_report(node_t srcNode, uint8_t class_id, bool nls_capability, bool nls_state) +void S2_notify_nls_state_report(node_t srcNode, + uint8_t class_id, + bool nls_capability, + bool nls_state) { (void)class_id; - sl_log_debug(LOG_TAG, "NLS state report received for node %d, capability : %d, state: %d", srcNode, nls_capability, nls_state); + sl_log_debug( + LOG_TAG, + "NLS state report received for node %d, capability : %d, state: %d", + srcNode, + nls_capability, + nls_state); if (zwave_store_nls_support((zwave_node_id_t)srcNode, nls_capability, @@ -444,9 +457,10 @@ void S2_notify_nls_state_report(node_t srcNode, uint8_t class_id, bool nls_capab return; } - if(nls_capability && nls_state) { + if (nls_capability && nls_state) { if (SL_STATUS_OK != zwapi_enable_node_nls(srcNode)) { - sl_log_error(LOG_TAG, "Error saving NLS support and state in the controller NVM"); + sl_log_error(LOG_TAG, + "Error saving NLS support and state in the controller NVM"); } } } @@ -455,21 +469,30 @@ void S2_save_nls_state(void) { zwave_node_id_t node_id = zwave_network_management_get_node_id(); - sl_status_t status = zwave_store_nls_state(node_id, s2_ctx->nls_state, REPORTED_ATTRIBUTE); + sl_status_t status + = zwave_store_nls_state(node_id, s2_ctx->nls_state, REPORTED_ATTRIBUTE); if (status != SL_STATUS_OK) { - sl_log_error(LOG_TAG, "Unable to save NLS state in attribute store for Node ID: %d\n", node_id); + sl_log_error( + LOG_TAG, + "Unable to save NLS state in attribute store for Node ID: %d\n", + node_id); return; } if (s2_ctx->nls_state) { status = zwapi_enable_node_nls(node_id); if (SL_STATUS_OK != status) { - sl_log_error(LOG_TAG, "Error saving NLS state in the controller NVM for Node ID: %d", node_id); + sl_log_error( + LOG_TAG, + "Error saving NLS state in the controller NVM for Node ID: %d", + node_id); return; } } - sl_log_debug(LOG_TAG, "NLS state saved in the controller NVM for Node ID: %d\n", node_id); + sl_log_debug(LOG_TAG, + "NLS state saved in the controller NVM for Node ID: %d\n", + node_id); } sl_status_t compute_next_nls_enabled_node(void) @@ -686,8 +709,8 @@ sl_status_t // Protocol metadata can be used now libS2 exit if (tx_options->transport.is_protocol_frame == true) { protocol_metadata_t *protocol_metadata = (protocol_metadata_t *)user; - state.protocol_metadata.session_id = protocol_metadata->session_id; - state.protocol_metadata.data_length = protocol_metadata->data_length; + state.protocol_metadata.session_id = protocol_metadata->session_id; + state.protocol_metadata.data_length = protocol_metadata->data_length; memcpy(state.protocol_metadata.data, protocol_metadata->data, state.protocol_metadata.data_length); diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion.c b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion.c index b8ad1150a..1b772ddeb 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion.c @@ -5,349 +5,411 @@ * Author: trasmussen */ - #include "s2_inclusion.h" - #include - #include - #include - #include "s2_protocol.h" - #include "unity.h" - #include "curve25519.h" - #include "s2_keystore.h" - - void setUpSuite(void) { - - } - - void tearDownSuite(void) { - - } - - #define ELEM_COUNT(ARRAY) (sizeof(ARRAY)/(sizeof(ARRAY[0]))) - #define UNIT_TEST_TEMP_KEY_SECURE 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. - #define UNIT_TEST_NETWORK_KEY 6 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. - - // Public key A as used in ECDH curve test cases. - static uint8_t m_test_public_key_a[] = {0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, - 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, - 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, - 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a}; - - // Public key B as used in ECDH curve test cases. - static uint8_t m_test_public_key_b[] = {0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, - 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, - 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, - 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; - - // Private key A as used in ECDH curve test cases. - static uint8_t m_test_private_key_a[] = {0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, - 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, - 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, - 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a}; - - // Private key B as used in ECDH curve test cases. - static uint8_t m_test_private_key_b[] = {0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, - 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6, - 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, - 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb}; - - //static uint8_t m_test_public_key_a[32]; - //static uint8_t m_test_public_key_b[32]; - - static uint8_t m_test_network_key_s2_class_0[] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - - static uint8_t m_test_network_key_s0[] = {0xCA, 0xFE, 0xBA, 0xBE, 0x44, 0x33, 0x22, 0x11, - 0xCA, 0xFE, 0xBA, 0xBE, 0xCC, 0xBB, 0xAA, 0x99}; - - void compare_any_all_args(mock_t *p_mock) - { - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For this call we just expect any, as we will feed the actual output into next event. - p_mock->compare_rule_arg[1] = COMPARE_ANY; - p_mock->compare_rule_arg[2] = COMPARE_ANY; - p_mock->compare_rule_arg[3] = COMPARE_ANY; - } - - /** This is not a real test case but a test to ensure that the including node +#include "s2_inclusion.h" +#include +#include +#include +#include "s2_protocol.h" +#include "unity.h" +#include "curve25519.h" +#include "s2_keystore.h" + +void setUpSuite(void) {} + +void tearDownSuite(void) {} + +#define ELEM_COUNT(ARRAY) (sizeof(ARRAY) / (sizeof(ARRAY[0]))) +#define UNIT_TEST_TEMP_KEY_SECURE \ + 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define UNIT_TEST_NETWORK_KEY \ + 6 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. + +// Public key A as used in ECDH curve test cases. +static uint8_t m_test_public_key_a[] + = {0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a}; + +// Public key B as used in ECDH curve test cases. +static uint8_t m_test_public_key_b[] + = {0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; + +// Private key A as used in ECDH curve test cases. +static uint8_t m_test_private_key_a[] + = {0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, + 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, + 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a}; + +// Private key B as used in ECDH curve test cases. +static uint8_t m_test_private_key_b[] + = {0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, + 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, + 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb}; + +//static uint8_t m_test_public_key_a[32]; +//static uint8_t m_test_public_key_b[32]; + +static uint8_t m_test_network_key_s2_class_0[] = {0x88, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s0[] = {0xCA, + 0xFE, + 0xBA, + 0xBE, + 0x44, + 0x33, + 0x22, + 0x11, + 0xCA, + 0xFE, + 0xBA, + 0xBE, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +void compare_any_all_args(mock_t *p_mock) +{ + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For this call we just expect any, as we will feed the actual output into next event. + p_mock->compare_rule_arg[1] = COMPARE_ANY; + p_mock->compare_rule_arg[2] = COMPARE_ANY; + p_mock->compare_rule_arg[3] = COMPARE_ANY; +} + +/** This is not a real test case but a test to ensure that the including node * code in inclusion is correctly working when building for a controller. */ - void test_controller_build(void) - { - #ifndef ZW_CONTROLLER - TEST_FAIL_MESSAGE("ZW_CONTROLLER is not defined but including node (ZW Controller) test cases are being executed."); - #endif - } - - /** Verification that the normal flow succeeds in inclusion of a new node. +void test_controller_build(void) +{ +#ifndef ZW_CONTROLLER + TEST_FAIL_MESSAGE("ZW_CONTROLLER is not defined but including node (ZW " + "Controller) test cases are being executed."); +#endif +} + +/** Verification that the normal flow succeeds in inclusion of a new node. * * It verifies the behavior as seen from an including node (Controller node) as described in SDS11274. * * When a node is to be included securely it is expected that a ZW_SendData is send. * For this the common S2_send_frame(...) defined in s2.h is used, which will be implemented elsewhere. */ - void test_kex_joining_node_state_machine(void) { - mock_t * p_kex_get_mock; - mock_t * p_kex_report_mock; - mock_t * p_kex_set_mock; - mock_t * p_pub_key_b_report_mock; - mock_t * p_pub_key_a_report_mock; - mock_t * p_network_key_joining_update_temp_key_mock; - mock_t * p_network_key_including_update_temp_key_mock; - - mock_t * p_echo_kex_set_mock; - mock_t * p_echo_kex_report_mock; - mock_t * p_network_key_get_round1_mock; - mock_t * p_network_key_report_round1_mock; - mock_t * p_network_key_verify_round1_mock; - mock_t * p_network_key_update_round1_mock; - mock_t * p_transfer_end_round1_mock; - mock_t * p_network_key_get_round2_mock; - mock_t * p_network_key_report_round2_mock; - mock_t * p_network_key_verify_round2_mock; - mock_t * p_network_key_update_round2_mock; - mock_t * p_transfer_end_round2_mock; - mock_t * p_transfer_end_complete_mock; - - mock_t * p_keystore_clear; - mock_t * p_keystore_read_pub_a; - mock_t * p_keystore_read_pub_b; - mock_t * p_keystore_read_priv_a; - mock_t * p_keystore_read_priv_b; - mock_t * p_keystore_read_network_key_s2_class_0; - mock_t * p_keystore_read_network_key_s0; - - struct S2 s2_including_context; - struct S2 s2_joining_context; - s2_connection_t s2_joining_conn; - s2_connection_t s2_including_conn; - - s2_joining_conn.l_node = 2; - s2_joining_conn.r_node = 1; - s2_joining_conn.class_id = 0xFF; - s2_joining_conn.rx_options = 0x00; - - s2_including_conn.l_node = 1; - s2_including_conn.r_node = 2; - s2_including_conn.class_id = 0xFF; - s2_including_conn.rx_options = 0x00; - - /**************************** +void test_kex_joining_node_state_machine(void) +{ + mock_t *p_kex_get_mock; + mock_t *p_kex_report_mock; + mock_t *p_kex_set_mock; + mock_t *p_pub_key_b_report_mock; + mock_t *p_pub_key_a_report_mock; + mock_t *p_network_key_joining_update_temp_key_mock; + mock_t *p_network_key_including_update_temp_key_mock; + + mock_t *p_echo_kex_set_mock; + mock_t *p_echo_kex_report_mock; + mock_t *p_network_key_get_round1_mock; + mock_t *p_network_key_report_round1_mock; + mock_t *p_network_key_verify_round1_mock; + mock_t *p_network_key_update_round1_mock; + mock_t *p_transfer_end_round1_mock; + mock_t *p_network_key_get_round2_mock; + mock_t *p_network_key_report_round2_mock; + mock_t *p_network_key_verify_round2_mock; + mock_t *p_network_key_update_round2_mock; + mock_t *p_transfer_end_round2_mock; + mock_t *p_transfer_end_complete_mock; + + mock_t *p_keystore_clear; + mock_t *p_keystore_read_pub_a; + mock_t *p_keystore_read_pub_b; + mock_t *p_keystore_read_priv_a; + mock_t *p_keystore_read_priv_b; + mock_t *p_keystore_read_network_key_s2_class_0; + mock_t *p_keystore_read_network_key_s0; + + struct S2 s2_including_context; + struct S2 s2_joining_context; + s2_connection_t s2_joining_conn; + s2_connection_t s2_including_conn; + + s2_joining_conn.l_node = 2; + s2_joining_conn.r_node = 1; + s2_joining_conn.class_id = 0xFF; + s2_joining_conn.rx_options = 0x00; + + s2_including_conn.l_node = 1; + s2_including_conn.r_node = 2; + s2_including_conn.class_id = 0xFF; + s2_including_conn.rx_options = 0x00; + + /**************************** * Mock expectation section * ****************************/ - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(s2_inclusion_event_handler)); - mock_call_use_as_stub(TO_STR(keystore_network_key_write)); - - // Keystore calls. - mock_call_expect(TO_STR(keystore_network_key_clear), &p_keystore_clear); - p_keystore_clear->expect_arg[0].value = 0xFF; - - mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_keystore_read_pub_b); - p_keystore_read_pub_b->output_arg[0].pointer = m_test_public_key_b; - - mock_call_expect(TO_STR(keystore_public_key_read), &p_keystore_read_pub_a); - p_keystore_read_pub_a->output_arg[0].pointer = m_test_public_key_a; - - // When calculating the shared secret - Joining node. - mock_call_expect(TO_STR(keystore_dynamic_private_key_read), &p_keystore_read_priv_b); - p_keystore_read_priv_b->output_arg[0].pointer = m_test_private_key_b; - mock_call_expect(TO_STR(keystore_dynamic_public_key_read), &p_keystore_read_pub_b); - p_keystore_read_pub_b->output_arg[0].pointer = m_test_public_key_b; - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_joining_update_temp_key_mock); - compare_any_all_args(p_network_key_joining_update_temp_key_mock); - - // When calculating the shared secret - Joining node. - mock_call_expect(TO_STR(keystore_private_key_read), &p_keystore_read_priv_a); - p_keystore_read_priv_a->output_arg[0].pointer = m_test_private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_keystore_read_pub_a); - p_keystore_read_pub_a->output_arg[0].pointer = m_test_public_key_a; - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_including_update_temp_key_mock); - compare_any_all_args(p_network_key_including_update_temp_key_mock); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_keystore_read_network_key_s2_class_0); - p_keystore_read_network_key_s2_class_0->expect_arg[0].value = KEY_CLASS_S2_UNAUTHENTICATED; - p_keystore_read_network_key_s2_class_0->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_keystore_read_network_key_s0); - p_keystore_read_network_key_s0->expect_arg[0].value = KEY_CLASS_S0; - p_keystore_read_network_key_s0->output_arg[1].pointer = m_test_network_key_s0; - - // Expectations of call for transmitting network frames. - mock_call_expect(TO_STR(S2_send_frame), &p_kex_get_mock); - compare_any_all_args(p_kex_get_mock); - - mock_call_expect(TO_STR(S2_send_frame), &p_kex_report_mock); - compare_any_all_args(p_kex_report_mock); - - mock_call_expect(TO_STR(S2_send_frame), &p_kex_set_mock); - compare_any_all_args(p_kex_set_mock); - - mock_call_expect(TO_STR(S2_send_frame), &p_pub_key_b_report_mock); - compare_any_all_args(p_pub_key_b_report_mock); - - mock_call_expect(TO_STR(S2_send_frame), &p_pub_key_a_report_mock); - compare_any_all_args(p_pub_key_a_report_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_echo_kex_set_mock); - compare_any_all_args(p_echo_kex_set_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_echo_kex_report_mock); - compare_any_all_args(p_echo_kex_report_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_network_key_get_round1_mock); - compare_any_all_args(p_network_key_get_round1_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_network_key_report_round1_mock); - compare_any_all_args(p_network_key_report_round1_mock); - - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_update_round1_mock); - compare_any_all_args(p_network_key_update_round1_mock); - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_update_round1_mock); - compare_any_all_args(p_network_key_update_round1_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_network_key_verify_round1_mock); - compare_any_all_args(p_network_key_verify_round1_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_transfer_end_round1_mock); - compare_any_all_args(p_transfer_end_round1_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_network_key_get_round2_mock); - compare_any_all_args(p_network_key_get_round2_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_network_key_report_round2_mock); - compare_any_all_args(p_network_key_report_round2_mock); - - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_update_round2_mock); - compare_any_all_args(p_network_key_update_round2_mock); - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_update_round2_mock); - compare_any_all_args(p_network_key_update_round2_mock); - - mock_call_expect(TO_STR(S2_send_data), &p_network_key_verify_round2_mock); - compare_any_all_args(p_network_key_verify_round2_mock); - - mock_call_expect(TO_STR(S2_network_key_update), &p_network_key_update_round2_mock); - compare_any_all_args(p_network_key_update_round2_mock); - - mock_call_expect( TO_STR(S2_send_data), &p_transfer_end_round2_mock); - compare_any_all_args(p_transfer_end_round2_mock); - - - mock_call_expect( TO_STR(S2_send_data), &p_transfer_end_complete_mock); - compare_any_all_args(p_transfer_end_complete_mock); - - /******************* + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(s2_inclusion_event_handler)); + mock_call_use_as_stub(TO_STR(keystore_network_key_write)); + + // Keystore calls. + mock_call_expect(TO_STR(keystore_network_key_clear), &p_keystore_clear); + p_keystore_clear->expect_arg[0].value = 0xFF; + + mock_call_expect(TO_STR(keystore_dynamic_public_key_read), + &p_keystore_read_pub_b); + p_keystore_read_pub_b->output_arg[0].pointer = m_test_public_key_b; + + mock_call_expect(TO_STR(keystore_public_key_read), &p_keystore_read_pub_a); + p_keystore_read_pub_a->output_arg[0].pointer = m_test_public_key_a; + + // When calculating the shared secret - Joining node. + mock_call_expect(TO_STR(keystore_dynamic_private_key_read), + &p_keystore_read_priv_b); + p_keystore_read_priv_b->output_arg[0].pointer = m_test_private_key_b; + mock_call_expect(TO_STR(keystore_dynamic_public_key_read), + &p_keystore_read_pub_b); + p_keystore_read_pub_b->output_arg[0].pointer = m_test_public_key_b; + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_joining_update_temp_key_mock); + compare_any_all_args(p_network_key_joining_update_temp_key_mock); + + // When calculating the shared secret - Joining node. + mock_call_expect(TO_STR(keystore_private_key_read), &p_keystore_read_priv_a); + p_keystore_read_priv_a->output_arg[0].pointer = m_test_private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_keystore_read_pub_a); + p_keystore_read_pub_a->output_arg[0].pointer = m_test_public_key_a; + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_including_update_temp_key_mock); + compare_any_all_args(p_network_key_including_update_temp_key_mock); + + mock_call_expect(TO_STR(keystore_network_key_read), + &p_keystore_read_network_key_s2_class_0); + p_keystore_read_network_key_s2_class_0->expect_arg[0].value + = KEY_CLASS_S2_UNAUTHENTICATED; + p_keystore_read_network_key_s2_class_0->output_arg[1].pointer + = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), + &p_keystore_read_network_key_s0); + p_keystore_read_network_key_s0->expect_arg[0].value = KEY_CLASS_S0; + p_keystore_read_network_key_s0->output_arg[1].pointer = m_test_network_key_s0; + + // Expectations of call for transmitting network frames. + mock_call_expect(TO_STR(S2_send_frame), &p_kex_get_mock); + compare_any_all_args(p_kex_get_mock); + + mock_call_expect(TO_STR(S2_send_frame), &p_kex_report_mock); + compare_any_all_args(p_kex_report_mock); + + mock_call_expect(TO_STR(S2_send_frame), &p_kex_set_mock); + compare_any_all_args(p_kex_set_mock); + + mock_call_expect(TO_STR(S2_send_frame), &p_pub_key_b_report_mock); + compare_any_all_args(p_pub_key_b_report_mock); + + mock_call_expect(TO_STR(S2_send_frame), &p_pub_key_a_report_mock); + compare_any_all_args(p_pub_key_a_report_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_echo_kex_set_mock); + compare_any_all_args(p_echo_kex_set_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_echo_kex_report_mock); + compare_any_all_args(p_echo_kex_report_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_network_key_get_round1_mock); + compare_any_all_args(p_network_key_get_round1_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_network_key_report_round1_mock); + compare_any_all_args(p_network_key_report_round1_mock); + + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_update_round1_mock); + compare_any_all_args(p_network_key_update_round1_mock); + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_update_round1_mock); + compare_any_all_args(p_network_key_update_round1_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_network_key_verify_round1_mock); + compare_any_all_args(p_network_key_verify_round1_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_transfer_end_round1_mock); + compare_any_all_args(p_transfer_end_round1_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_network_key_get_round2_mock); + compare_any_all_args(p_network_key_get_round2_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_network_key_report_round2_mock); + compare_any_all_args(p_network_key_report_round2_mock); + + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_update_round2_mock); + compare_any_all_args(p_network_key_update_round2_mock); + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_update_round2_mock); + compare_any_all_args(p_network_key_update_round2_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_network_key_verify_round2_mock); + compare_any_all_args(p_network_key_verify_round2_mock); + + mock_call_expect(TO_STR(S2_network_key_update), + &p_network_key_update_round2_mock); + compare_any_all_args(p_network_key_update_round2_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_transfer_end_round2_mock); + compare_any_all_args(p_transfer_end_round2_mock); + + mock_call_expect(TO_STR(S2_send_data), &p_transfer_end_complete_mock); + compare_any_all_args(p_transfer_end_complete_mock); + + /******************* * Testing section * *******************/ - // All output from previous call (which is recordered by the mock) will be fed into the state - // machine for the opposit site context. - s2_joining_context.inclusion_state = 0; - s2_including_context.inclusion_state = 0; - - s2_inclusion_init(SECURITY_2_SCHEME_1_SUPPORT, - KEX_REPORT_CURVE_25519, - 0x81 /* SECURITY_2_KEY_0 | SECURITY_2_KEY_2_CLASS_0 */); - - s2_inclusion_joining_start(&s2_joining_context,&s2_joining_conn,0); - s2_inclusion_including_start(&s2_including_context,&s2_including_conn); - - s2_joining_context.buf = p_kex_get_mock->actual_arg[2].pointer; - s2_joining_context.length = p_kex_get_mock->actual_arg[3].value; - s2_joining_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - s2_including_context.buf = p_kex_report_mock->actual_arg[2].pointer; - s2_including_context.length = p_kex_report_mock->actual_arg[3].value; - s2_including_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_inclusion_key_grant(&s2_including_context, 1, 0x81,0); - - s2_joining_context.buf = p_kex_set_mock->actual_arg[2].pointer; - s2_joining_context.length = p_kex_set_mock->actual_arg[3].value; - s2_joining_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - s2_including_context.buf = p_pub_key_b_report_mock->actual_arg[2].pointer; - s2_including_context.length = p_pub_key_b_report_mock->actual_arg[3].value; - s2_including_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_joining_context.buf = p_pub_key_a_report_mock->actual_arg[2].pointer; - s2_joining_context.length = p_pub_key_a_report_mock->actual_arg[3].value; - s2_joining_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - - s2_inclusion_challenge_response(&s2_including_context, 1, m_test_public_key_b, 2); - s2_inclusion_challenge_response(&s2_joining_context, 1,m_test_public_key_a, 0); - - - s2_including_context.buf = p_echo_kex_set_mock->actual_arg[2].pointer; - s2_including_context.length = p_echo_kex_set_mock->actual_arg[3].value; - s2_including_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_joining_context.buf = p_echo_kex_report_mock->actual_arg[2].pointer; - s2_joining_context.length = p_echo_kex_report_mock->actual_arg[3].value; - s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - s2_including_context.buf = p_network_key_get_round1_mock->actual_arg[2].pointer; - s2_including_context.length = p_network_key_get_round1_mock->actual_arg[3].value; - s2_including_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_joining_context.buf = p_network_key_report_round1_mock->actual_arg[2].pointer; - s2_joining_context.length = p_network_key_report_round1_mock->actual_arg[3].value; - s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - s2_including_context.buf = p_network_key_verify_round1_mock->actual_arg[2].pointer; - s2_including_context.length = p_network_key_verify_round1_mock->actual_arg[3].value; - s2_including_conn.class_id = 0x00; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_joining_context.buf = p_transfer_end_round1_mock->actual_arg[2].pointer; - s2_joining_context.length = p_transfer_end_round1_mock->actual_arg[3].value; - s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - s2_including_context.buf = p_network_key_get_round2_mock->actual_arg[2].pointer; - s2_including_context.length = p_network_key_get_round2_mock->actual_arg[3].value; - s2_including_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_joining_context.buf = p_network_key_report_round2_mock->actual_arg[2].pointer; - s2_joining_context.length = p_network_key_report_round2_mock->actual_arg[3].value; - s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - s2_including_context.buf = p_network_key_verify_round2_mock->actual_arg[2].pointer; - s2_including_context.length = p_network_key_verify_round2_mock->actual_arg[3].value; - s2_including_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_including_context, &s2_including_conn); - - s2_joining_context.buf = p_transfer_end_round2_mock->actual_arg[2].pointer; - s2_joining_context.length = p_transfer_end_round2_mock->actual_arg[3].value; - s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); - - // Verify that both sides agree on the calculated temporary key. - // Original test compared ->actual_arg[1] instead of ->actual_arg[2]. - // ->actual_arg[1] contained a 0 (NULL) and thus always returned without comparing. - // Index 2 is containing the actual indexes, however, those do not match. - // However, that was also the case when NULL pointer was wrongly compared. - // ToDo: EInvestigate if and how the calculated temp key should be compared. Test is disabled for now. - // TEST_ASSERT_EQUAL_UINT8_ARRAY(p_network_key_joining_update_temp_key_mock->actual_arg[2].pointer, - // p_network_key_including_update_temp_key_mock->actual_arg[2].pointer, - // 16); - - // Verify the mock has been called and stop test if not, to avoid p_transfer_end_complete_mock->actual_arg[2].pointer dereference 0x00. - TEST_ASSERT_TRUE(p_transfer_end_complete_mock->executed); - // 0x0C in second byte is the command value, here a TRANSFER_END is expected. - TEST_ASSERT_EQUAL_UINT8(0x0C, ((uint8_t *)p_transfer_end_complete_mock->actual_arg[2].pointer)[1]); - // 0x01 in third byte denotes the if key exchange is complete. - TEST_ASSERT_EQUAL_UINT8(0x01, ((uint8_t *)p_transfer_end_complete_mock->actual_arg[2].pointer)[2]); - - mock_calls_verify(); - } \ No newline at end of file + // All output from previous call (which is recordered by the mock) will be fed into the state + // machine for the opposit site context. + s2_joining_context.inclusion_state = 0; + s2_including_context.inclusion_state = 0; + + s2_inclusion_init(SECURITY_2_SCHEME_1_SUPPORT, + KEX_REPORT_CURVE_25519, + 0x81 /* SECURITY_2_KEY_0 | SECURITY_2_KEY_2_CLASS_0 */); + + s2_inclusion_joining_start(&s2_joining_context, &s2_joining_conn, 0); + s2_inclusion_including_start(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf = p_kex_get_mock->actual_arg[2].pointer; + s2_joining_context.length = p_kex_get_mock->actual_arg[3].value; + s2_joining_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_including_context.buf = p_kex_report_mock->actual_arg[2].pointer; + s2_including_context.length = p_kex_report_mock->actual_arg[3].value; + s2_including_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_inclusion_key_grant(&s2_including_context, 1, 0x81, 0); + + s2_joining_context.buf = p_kex_set_mock->actual_arg[2].pointer; + s2_joining_context.length = p_kex_set_mock->actual_arg[3].value; + s2_joining_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_including_context.buf = p_pub_key_b_report_mock->actual_arg[2].pointer; + s2_including_context.length = p_pub_key_b_report_mock->actual_arg[3].value; + s2_including_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf = p_pub_key_a_report_mock->actual_arg[2].pointer; + s2_joining_context.length = p_pub_key_a_report_mock->actual_arg[3].value; + s2_joining_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_inclusion_challenge_response(&s2_including_context, + 1, + m_test_public_key_b, + 2); + s2_inclusion_challenge_response(&s2_joining_context, + 1, + m_test_public_key_a, + 0); + + s2_including_context.buf = p_echo_kex_set_mock->actual_arg[2].pointer; + s2_including_context.length = p_echo_kex_set_mock->actual_arg[3].value; + s2_including_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf = p_echo_kex_report_mock->actual_arg[2].pointer; + s2_joining_context.length = p_echo_kex_report_mock->actual_arg[3].value; + s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_including_context.buf + = p_network_key_get_round1_mock->actual_arg[2].pointer; + s2_including_context.length + = p_network_key_get_round1_mock->actual_arg[3].value; + s2_including_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf + = p_network_key_report_round1_mock->actual_arg[2].pointer; + s2_joining_context.length + = p_network_key_report_round1_mock->actual_arg[3].value; + s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_including_context.buf + = p_network_key_verify_round1_mock->actual_arg[2].pointer; + s2_including_context.length + = p_network_key_verify_round1_mock->actual_arg[3].value; + s2_including_conn.class_id = 0x00; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf = p_transfer_end_round1_mock->actual_arg[2].pointer; + s2_joining_context.length = p_transfer_end_round1_mock->actual_arg[3].value; + s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_including_context.buf + = p_network_key_get_round2_mock->actual_arg[2].pointer; + s2_including_context.length + = p_network_key_get_round2_mock->actual_arg[3].value; + s2_including_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf + = p_network_key_report_round2_mock->actual_arg[2].pointer; + s2_joining_context.length + = p_network_key_report_round2_mock->actual_arg[3].value; + s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + s2_including_context.buf + = p_network_key_verify_round2_mock->actual_arg[2].pointer; + s2_including_context.length + = p_network_key_verify_round2_mock->actual_arg[3].value; + s2_including_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_including_context, &s2_including_conn); + + s2_joining_context.buf = p_transfer_end_round2_mock->actual_arg[2].pointer; + s2_joining_context.length = p_transfer_end_round2_mock->actual_arg[3].value; + s2_joining_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_joining_context, &s2_joining_conn); + + // Verify that both sides agree on the calculated temporary key. + // Original test compared ->actual_arg[1] instead of ->actual_arg[2]. + // ->actual_arg[1] contained a 0 (NULL) and thus always returned without comparing. + // Index 2 is containing the actual indexes, however, those do not match. + // However, that was also the case when NULL pointer was wrongly compared. + // ToDo: EInvestigate if and how the calculated temp key should be compared. Test is disabled for now. + // TEST_ASSERT_EQUAL_UINT8_ARRAY(p_network_key_joining_update_temp_key_mock->actual_arg[2].pointer, + // p_network_key_including_update_temp_key_mock->actual_arg[2].pointer, + // 16); + + // Verify the mock has been called and stop test if not, to avoid p_transfer_end_complete_mock->actual_arg[2].pointer dereference 0x00. + TEST_ASSERT_TRUE(p_transfer_end_complete_mock->executed); + // 0x0C in second byte is the command value, here a TRANSFER_END is expected. + TEST_ASSERT_EQUAL_UINT8( + 0x0C, + ((uint8_t *)p_transfer_end_complete_mock->actual_arg[2].pointer)[1]); + // 0x01 in third byte denotes the if key exchange is complete. + TEST_ASSERT_EQUAL_UINT8( + 0x01, + ((uint8_t *)p_transfer_end_complete_mock->actual_arg[2].pointer)[2]); + + mock_calls_verify(); +} \ No newline at end of file diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion_including_node.c b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion_including_node.c index f837623da..15b524125 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion_including_node.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_inclusion_including_node.c @@ -7,30 +7,28 @@ * Author: trasmussen */ - #include "s2_inclusion.h" - #include - #include - #include - #include "platform.h" - #include "unity.h" - #include "s2_protocol.h" - - #include "ZW_classcmd.h" - #include "s2_classcmd.h" - - void setUpSuite(void) { - - } - - void tearDownSuite(void) { - - } - - #define ELEM_COUNT(ARRAY) (sizeof(ARRAY)/(sizeof(ARRAY[0]))) - #define UNIT_TEST_TEMP_KEY_SECURE 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. - #define UNIT_TEST_NETWORK_KEY 6 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. - - /** Overview of behavior which should be implemented: +#include "s2_inclusion.h" +#include +#include +#include +#include "platform.h" +#include "unity.h" +#include "s2_protocol.h" + +#include "ZW_classcmd.h" +#include "s2_classcmd.h" + +void setUpSuite(void) {} + +void tearDownSuite(void) {} + +#define ELEM_COUNT(ARRAY) (sizeof(ARRAY) / (sizeof(ARRAY[0]))) +#define UNIT_TEST_TEMP_KEY_SECURE \ + 5 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. +#define UNIT_TEST_NETWORK_KEY \ + 6 //< Value identifying index for the temporary key in S2 network key when transmitting secure frames. + +/** Overview of behavior which should be implemented: * General inclusion: * - Implement SM according to designed flow. * - Identify all events and actions which must be handled and executed during node inclusion. @@ -50,61 +48,117 @@ * The SM will not be responsible for further actions due to timeouts. * */ - - /** Current working assumptions: + +/** Current working assumptions: * Lib S2 - message encapsulation/inclusion mode and context handling * - Currently context is updated with peer, buffer, and length in libs2 protocol (message * encapsulation handling), this should be moved to common place. s2 dispatch layer ? * - Libs2 S2.c contains the entry point for frames receined, S2_application_command_handler(.), * this should ideally be refactored to upper dispatcher layer which should be common for encapsulation handling and inclusion. */ - - /** Currently identyfied test cases not yet implemented. + +/** Currently identyfied test cases not yet implemented. * * - Key Verify failure. * */ - #define UNIT_TEST_BUF_SIZE 256 - - static uint8_t m_test_mem_pool[4][256]; // Statically allocated chunks of memory that can be freely used during the test. - - // Public key A as used in ECDH curve test cases. - static uint8_t m_test_public_key_a[] = {0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, - 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, - 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, - 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a}; - - // Public key B as used in ECDH curve test cases. - static uint8_t m_test_public_key_b[] = {0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, - 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, - 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, - 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; - - - // Obfuscated Public key B where first bytes are masked out as used for DSK input. - static uint8_t m_test_obfuscated_public_key_b[] = {0x00, 0x00, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, - 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, - 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, - 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; - - - //static uint8_t m_temp_key[] = {0x7E, 0xFE, 0x12, 0x32, 0x45, 0x65, 0x78, 0x98, - // 0x7E, 0xFE, 0x12, 0x32, 0x45, 0x65, 0x78, 0x98}; - - static uint8_t m_test_network_key_s2_class_0[] = {0x11, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - - static uint8_t m_test_network_key_s2_class_1[] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - - static uint8_t m_test_network_key_s2_class_2[] = {0x22, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, - 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99}; - - static uint8_t m_test_network_key_s0[] = {0xCA, 0xFE, 0xBA, 0xBE, 0x44, 0x33, 0x22, 0x11, - 0xCA, 0xFE, 0xBA, 0xBE, 0xCC, 0xBB, 0xAA, 0x99}; - - s2_connection_t s2_conn; - /** Event listener for S2 inclusion. +#define UNIT_TEST_BUF_SIZE 256 + +static uint8_t m_test_mem_pool + [4] + [256]; // Statically allocated chunks of memory that can be freely used during the test. + +// Public key A as used in ECDH curve test cases. +static uint8_t m_test_public_key_a[] + = {0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a}; + +// Public key B as used in ECDH curve test cases. +static uint8_t m_test_public_key_b[] + = {0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; + +// Obfuscated Public key B where first bytes are masked out as used for DSK input. +static uint8_t m_test_obfuscated_public_key_b[] + = {0x00, 0x00, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f}; + +//static uint8_t m_temp_key[] = {0x7E, 0xFE, 0x12, 0x32, 0x45, 0x65, 0x78, 0x98, +// 0x7E, 0xFE, 0x12, 0x32, 0x45, 0x65, 0x78, 0x98}; + +static uint8_t m_test_network_key_s2_class_0[] = {0x11, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s2_class_1[] = {0x88, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s2_class_2[] = {0x22, + 0x77, + 0x66, + 0x55, + 0x44, + 0x33, + 0x22, + 0x11, + 0x00, + 0xFF, + 0xEE, + 0xDD, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +static uint8_t m_test_network_key_s0[] = {0xCA, + 0xFE, + 0xBA, + 0xBE, + 0x44, + 0x33, + 0x22, + 0x11, + 0xCA, + 0xFE, + 0xBA, + 0xBE, + 0xCC, + 0xBB, + 0xAA, + 0x99}; + +s2_connection_t s2_conn; +/** Event listener for S2 inclusion. * * S2 will use an event listening scheme for posting notifications upwards. * How the notification is stored/handled is outside scope of the state machine, but it is @@ -113,67 +167,77 @@ * * This forward declares the mock funtion used, because the callback is a function pointer with no named declaration. */ - void s2_event_handler(zwave_event_t * p_zwave_evt); - - /** Forward declaration of helper classes. +void s2_event_handler(zwave_event_t *p_zwave_evt); + +/** Forward declaration of helper classes. * All helper classes are implemented in buttom of file to easily keep them seperated from the test cases. */ - void helper_func_kex_report_frame(struct S2 *p_context); - void helper_func_echo_kex_report_frame_expect(uint8_t expected_scheme, uint8_t expected_curves, uint8_t expected_keys); - void helper_func_kex_set_frame_expect(uint8_t expected_scheme, uint8_t expected_curves, uint8_t expected_keys); - void helper_func_pub_key_frame(struct S2 *p_context); - void helper_func_echo_kex_set_frame(struct S2 *p_context); - void helper_func_net_key_get_frame(struct S2 *p_context, uint8_t key); - void helper_func_net_key_verify_frame(struct S2 *p_context, uint8_t key); - void helper_func_transfer_end_final_frame(struct S2 *p_context); - void helper_func_verify_idle_state(struct S2 *p_context); - void helper_func_kex_get_frame_expect(void); - void helper_func_restore_keys_expect(void); - static void helper_func_init_s2_conn(void); - - /** This is not a real test case but a test to ensure that the including node +void helper_func_kex_report_frame(struct S2 *p_context); +void helper_func_echo_kex_report_frame_expect(uint8_t expected_scheme, + uint8_t expected_curves, + uint8_t expected_keys); +void helper_func_kex_set_frame_expect(uint8_t expected_scheme, + uint8_t expected_curves, + uint8_t expected_keys); +void helper_func_pub_key_frame(struct S2 *p_context); +void helper_func_echo_kex_set_frame(struct S2 *p_context); +void helper_func_net_key_get_frame(struct S2 *p_context, uint8_t key); +void helper_func_net_key_verify_frame(struct S2 *p_context, uint8_t key); +void helper_func_transfer_end_final_frame(struct S2 *p_context); +void helper_func_verify_idle_state(struct S2 *p_context); +void helper_func_kex_get_frame_expect(void); +void helper_func_restore_keys_expect(void); +static void helper_func_init_s2_conn(void); + +/** This is not a real test case but a test to ensure that the including node * code in inclusion is correctly working when building for a controller. */ - void test_controller_build(void) - { - #ifndef ZW_CONTROLLER - TEST_FAIL_MESSAGE("ZW_CONTROLLER is not defined but including node (ZW Controller) test cases are being executed."); - #endif - } - - /** Verification that the normal flow succeeds in inclusion of a new node when using SSA. +void test_controller_build(void) +{ +#ifndef ZW_CONTROLLER + TEST_FAIL_MESSAGE("ZW_CONTROLLER is not defined but including node (ZW " + "Controller) test cases are being executed."); +#endif +} + +/** Verification that the normal flow succeeds in inclusion of a new node when using SSA. * * It verifies the behavior as seen from an including node (Controller node) as described in SDS11274. * * When a node is to be included securely it is expected that a ZW_SendData is send. * For this the common S2_send_frame(...) defined in s2.h is used, which will be implemented elsewhere. */ - void test_kex_including_node_state_machine_csa(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x06, // bit 0 is echo field, bit 1 is CSA, bit 2 is NLS support. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_state_machine_csa(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x06, // bit 0 is echo field, bit 1 is CSA, bit 2 is NLS support. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -205,271 +269,369 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x01; - p_expected_report_event->evt.s2_event.s2_data.kex_report.nls_available = 0x01; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x02, // bit0: echo field, bit1: CSA, bit2-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. - }; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent minus the first 4 bytes. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0x00, 0x00, 0x00, 0x00, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x82}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - // Expect Net Key Set to be sent. - uint8_t S2_net_key_report_0_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; - memcpy(&S2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); - - // Expect S2 Transfer End to be sent. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_mem_pool[0]; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_mem_pool[1]; - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x01; + p_expected_report_event->evt.s2_event.s2_data.kex_report.nls_available = 0x01; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x02, // bit0: echo field, bit1: CSA, bit2-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. + }; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent minus the first 4 bytes. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0x00, + 0x00, + 0x00, + 0x00, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x07, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + // Expect Net Key Set to be sent. + uint8_t S2_net_key_report_0_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; + memcpy(&S2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); + + // Expect S2 Transfer End to be sent. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_mem_pool[0]; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_mem_pool[1]; + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82, 0x01); - - uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x03, 0x02, 0x01, 0x82}; - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x01; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Verification that the normal flow succeeds in inclusion of a new node when using SSA. + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0x01); + + uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_b, + sizeof(m_test_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x03, 0x02, 0x01, 0x82}; + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x01; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Verification that the normal flow succeeds in inclusion of a new node when using SSA. * * It verifies the behavior as seen from an including node (Controller node) as described in SDS11274. * * When a node is to be included securely it is expected that a ZW_SendData is send. * For this the common S2_send_frame(...) defined in s2.h is used, which will be implemented elsewhere. */ - static void kex_including_node_state_machine_bad_tansfer_end(uint8_t transfer_end_code) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // // bit 0 is echo field, bit 1 is CSA. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +static void + kex_including_node_state_machine_bad_tansfer_end(uint8_t transfer_end_code) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // // bit 0 is echo field, bit 1 is CSA. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -501,288 +663,390 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x00, // bit0: echo field, bit1-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. - }; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_obfuscated_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - // Expect Net Key Set to be sent. - uint8_t S2_net_key_report_0_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; - memcpy(&S2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); - - // Expect S2 Transfer End to be sent. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - // Expect that we send a KEX fail - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - uint8_t S2_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x09}; - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_fail_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x9; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x00, // bit0: echo field, bit1-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. + }; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_obfuscated_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x01, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + // Expect Net Key Set to be sent. + uint8_t S2_net_key_report_0_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; + memcpy(&S2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); + + // Expect S2 Transfer End to be sent. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + // Expect that we send a KEX fail + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + uint8_t S2_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x09}; + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_fail_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x9; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - s2_conn.l_node = 1; - s2_conn.l_node = 2; - s2_conn.class_id = 0xFF; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82, 0x00); - - uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // This should ensure the full public key is available. - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; - - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x01; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, transfer_end_code}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - void test_kex_including_node_state_machine_bad_tansfer_end2(uint8_t transfer_end_code) { - // S2 Transfer end frame received. - // bit0: Key request complete not set, - // bit1: Key verified set, - // bit2-7: Reserved. - kex_including_node_state_machine_bad_tansfer_end(2); - } - - void test_kex_including_node_state_machine_bad_tansfer_end3(uint8_t transfer_end_code) { - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified set, - // bit2-7: Reserved. - kex_including_node_state_machine_bad_tansfer_end(3); - } - - - void test_kex_including_node_state_machine_ssa(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // // bit 0 is echo field, bit 1 is CSA. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** + struct S2 s2_context; + s2_conn.l_node = 1; + s2_conn.l_node = 2; + s2_conn.class_id = 0xFF; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0x00); + + uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // This should ensure the full public key is available. + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x01; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, transfer_end_code}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +void test_kex_including_node_state_machine_bad_tansfer_end2( + uint8_t transfer_end_code) +{ + // S2 Transfer end frame received. + // bit0: Key request complete not set, + // bit1: Key verified set, + // bit2-7: Reserved. + kex_including_node_state_machine_bad_tansfer_end(2); +} + +void test_kex_including_node_state_machine_bad_tansfer_end3( + uint8_t transfer_end_code) +{ + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified set, + // bit2-7: Reserved. + kex_including_node_state_machine_bad_tansfer_end(3); +} + +void test_kex_including_node_state_machine_ssa(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // // bit 0 is echo field, bit 1 is CSA. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -814,371 +1078,485 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x00, // bit0: echo field, bit1-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. - }; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_obfuscated_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - // Expect Net Key Set to be sent. - uint8_t S2_net_key_report_0_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; - memcpy(&S2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); - - // Expect S2 Transfer End to be sent. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x00, // bit0: echo field, bit1-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. + }; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_obfuscated_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x01, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + // Expect Net Key Set to be sent. + uint8_t S2_net_key_report_0_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; + memcpy(&S2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); + + // Expect S2 Transfer End to be sent. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - s2_conn.l_node = 1; - s2_conn.l_node = 2; - s2_conn.class_id = 0xFF; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82, 0x00); - - uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // This should ensure the full public key is available. - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; - - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x01; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Verification that the normal flow succeeds when send done is succesful. + struct S2 s2_context; + s2_conn.l_node = 1; + s2_conn.l_node = 2; + s2_conn.class_id = 0xFF; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0x00); + + uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // This should ensure the full public key is available. + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x01; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Verification that the normal flow succeeds when send done is succesful. * */ - void test_kex_including_node_sond_complete(void) { - // uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - // 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - // 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - // 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - // - // uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - // 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - // 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - // 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - // - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // bit 0 is echo field, rest are reserved - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - mock_call_use_as_stub(TO_STR(s2_event_handler)); - mock_call_use_as_stub(TO_STR(S2_send_data)); - mock_call_use_as_stub(TO_STR(S2_send_frame)); - mock_call_use_as_stub(TO_STR(s2_keystore_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_sond_complete(void) +{ + // uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. + // 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, + // 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, + // 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + // + // uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + // 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + // 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + // 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + // + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // bit 0 is echo field, rest are reserved + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + mock_call_use_as_stub(TO_STR(s2_event_handler)); + mock_call_use_as_stub(TO_STR(S2_send_data)); + mock_call_use_as_stub(TO_STR(S2_send_frame)); + mock_call_use_as_stub(TO_STR(s2_keystore_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test execution. */ - struct S2 s2_context; - s2_conn.l_node = 1; - s2_conn.r_node = 2; - s2_conn.class_id = 0xFF; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_KEX_REPORT, s2_context.inclusion_state); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_KEY_USER_ACCEPT, s2_context.inclusion_state); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_PUB_KEY_B, s2_context.inclusion_state); - - uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_USER_ACCEPT, s2_context.inclusion_state); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_ECHO_KEX_SET, s2_context.inclusion_state); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_GET, s2_context.inclusion_state); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_VERIFY, s2_context.inclusion_state); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x01; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_GET, s2_context.inclusion_state); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_VERIFY, s2_context.inclusion_state); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_TRANSFER_END, s2_context.inclusion_state); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - TEST_ASSERT_EQUAL_UINT8(S2_INC_IDLE, s2_context.inclusion_state); - - mock_calls_verify(); - } - - /** Test case for ensuring correct timer handling during inclusion. + struct S2 s2_context; + s2_conn.l_node = 1; + s2_conn.r_node = 2; + s2_conn.class_id = 0xFF; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_KEX_REPORT, s2_context.inclusion_state); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_KEY_USER_ACCEPT, + s2_context.inclusion_state); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_PUB_KEY_B, s2_context.inclusion_state); + + uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_b, + sizeof(m_test_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_USER_ACCEPT, s2_context.inclusion_state); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_ECHO_KEX_SET, s2_context.inclusion_state); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_GET, s2_context.inclusion_state); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_VERIFY, + s2_context.inclusion_state); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x01; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_GET, s2_context.inclusion_state); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_NET_KEY_VERIFY, + s2_context.inclusion_state); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_AWAITING_TRANSFER_END, s2_context.inclusion_state); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + TEST_ASSERT_EQUAL_UINT8(S2_INC_IDLE, s2_context.inclusion_state); + + mock_calls_verify(); +} + +/** Test case for ensuring correct timer handling during inclusion. * * Purpose: In order to ensure correct inclusion flow and avoid deadlock during inclusion it is * important that in case messages are never received during inclusion, then the state @@ -1189,156 +1567,156 @@ * relevant for this test as they are verified in: test_kex_including_node_state_machine() * NOTE: messages related to Timeout will be verified in this test. */ - void test_kex_inclusion_timer_handling(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(S2_send_frame)); - mock_call_use_as_stub(TO_STR(S2_send_data)); - mock_call_use_as_stub(TO_STR(s2_event_handler)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(s2_keystore_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - s2_conn.l_node = 1; - s2_conn.r_node = 2; - s2_conn.class_id = 0xFF; - - /** Timer start expected on every transmitted frame. +void test_kex_inclusion_timer_handling(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(S2_send_frame)); + mock_call_use_as_stub(TO_STR(S2_send_data)); + mock_call_use_as_stub(TO_STR(s2_event_handler)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(s2_keystore_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + s2_conn.l_node = 1; + s2_conn.r_node = 2; + s2_conn.class_id = 0xFF; + + /** Timer start expected on every transmitted frame. * For flow chart, see SDS11274. * Timer values: * - TA1, TA2, TA4, TA5, TA6, TA7, TA : 10s * - TA3 : 20s * - TAI1, TAI2 : 240s */ - - // When initiating the secure inclusion of node B, then we expect a Timer Start call. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving next frame we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After pushing up the event with requested keys, then we expect a reset of the timer with 240s for user input. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 24000; - p_mock->return_code.value = 1; - - // After user acceptance we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting KEX Set we expect a reset of the timer. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving next frame we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting Public Key and pushing event upwards with received public key we expect a reset of the timer. - // Timeout is 240s for the user to provide the missing part of the DSK. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 24000; - p_mock->return_code.value = 1; - - // After receiving the echo Kex set we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting echo(KEX Report) we expect a reset of the timer. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving next frame (Net Key Get) we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting Network Key Set we expect a reset of the timer. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving next frame (Net Key Verify, key 0x02) we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting Transfer End we expect a reset of the timer. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving next frame (Net Key Get) we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting Network Key Set we expect a reset of the timer. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving next frame (Net Key Verify, key 0x80) we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After transmitting Transfer End we expect a reset of the timer. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // When receiving the final transfer end frame we expect the timer to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context, &s2_conn); - - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_transfer_end_final_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - - /** Test case for ensuring correct timer handling on timeout during inclusion in case a timeout + + // When initiating the secure inclusion of node B, then we expect a Timer Start call. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving next frame we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After pushing up the event with requested keys, then we expect a reset of the timer with 240s for user input. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 24000; + p_mock->return_code.value = 1; + + // After user acceptance we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting KEX Set we expect a reset of the timer. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving next frame we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting Public Key and pushing event upwards with received public key we expect a reset of the timer. + // Timeout is 240s for the user to provide the missing part of the DSK. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 24000; + p_mock->return_code.value = 1; + + // After receiving the echo Kex set we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting echo(KEX Report) we expect a reset of the timer. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving next frame (Net Key Get) we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting Network Key Set we expect a reset of the timer. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving next frame (Net Key Verify, key 0x02) we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting Transfer End we expect a reset of the timer. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving next frame (Net Key Get) we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting Network Key Set we expect a reset of the timer. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving next frame (Net Key Verify, key 0x80) we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After transmitting Transfer End we expect a reset of the timer. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // When receiving the final transfer end frame we expect the timer to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_transfer_end_final_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Test case for ensuring correct timer handling on timeout during inclusion in case a timeout * occurs after sending KEX Get. * * Purpose: In order to ensure correct inclusion flow and avoid deadlock during inclusion it is @@ -1351,80 +1729,84 @@ * After timeout, we expect the system to retry node inclusion. * */ - void test_kex_inclusion_timeout_kex_get_with_retry(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - - mock_calls_clear(); - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - /** Timer start expected on every transmitted frame. +void test_kex_inclusion_timeout_kex_get_with_retry(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + + mock_calls_clear(); + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + /** Timer start expected on every transmitted frame. * For flow chart, see SDS11274. * Timer values: * - TA1, TA2, TA4, TA5, TA6, TA7, TA : 10s * - TA3 : 20s * - TI1 : 240s */ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When initiating the secure inclusion of node B, then we expect a Timer Start call. - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // When the secure inclusion fails we expect any inclusion timers to be stopped. - mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); - - // After receiving a timeout it is expected that the inclusion state machine is back in idle and - // that we can initiate a new inclusion which will also trigger a new set timeout call. - uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); - - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - s2_inclusion_notify_timeout(&s2_context); - - // Retry node inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - mock_calls_verify(); - } - - - /** Test case for ensuring correct timer handling on timeout during inclusion in case a timeout + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When initiating the secure inclusion of node B, then we expect a Timer Start call. + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // When the secure inclusion fails we expect any inclusion timers to be stopped. + mock_call_expect(TO_STR(s2_inclusion_stop_timeout), &p_mock); + + // After receiving a timeout it is expected that the inclusion state machine is back in idle and + // that we can initiate a new inclusion which will also trigger a new set timeout call. + uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); + + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + s2_inclusion_notify_timeout(&s2_context); + + // Retry node inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Test case for ensuring correct timer handling on timeout during inclusion in case a timeout * occurs after sending KEX Set. * * Purpose: In order to ensure correct inclusion flow and avoid deadlock during inclusion it is @@ -1437,86 +1819,100 @@ * After timeout, we expect the system to retry node inclusion. * */ - void test_kex_inclusion_timeout_kex_set_with_retry(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // After receiving a timeout it is expected that the inclusion state machine is back in idle and - // that we can initiate a new inclusion. - uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x82}; // Scheme 1, curve25519, S2, key 1, and S0 network key. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - - // Retry node inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - mock_calls_verify(); - } - - /** Test case for ensuring correct timer handling on timeout during inclusion in case a timeout +void test_kex_inclusion_timeout_kex_set_with_retry(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // After receiving a timeout it is expected that the inclusion state machine is back in idle and + // that we can initiate a new inclusion. + uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + uint8_t s2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, + 0x02, + 0x01, + 0x82}; // Scheme 1, curve25519, S2, key 1, and S0 network key. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + + // Retry node inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Test case for ensuring correct timer handling on timeout during inclusion in case a timeout * occurs after any state. * * Purpose: In order to ensure correct inclusion flow and avoid deadlock during inclusion it is @@ -1531,855 +1927,1112 @@ * decrement a counter to go one step further on each loop. * */ - #define NO_OF_STATES 6 - void test_kex_inclusion_timeout_all_states(void) { - mock_t * p_mock; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - helper_func_init_s2_conn(); - - /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < NO_OF_STATES; i++) - { - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - if (i == 0){ - helper_func_restore_keys_expect(); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - continue; // if first iteration, continue here to test timeout for timeout. - } - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - if (i == 1) - { - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - helper_func_restore_keys_expect(); - - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - continue; // if second iteration, break here to test timeout for timeout. - } - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - - if (i == 2){ - helper_func_restore_keys_expect(); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - continue; // if third iteration, break here to test timeout for timeout. - } - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 3){ - helper_func_restore_keys_expect(); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - continue; // if fourth iteration, break here to test timeout for timeout. - } - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - // Expect Net Key Set to be sent. - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 4){ - helper_func_restore_keys_expect(); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - continue; // if fifth iteration, break here to test timeout for timeout. - } - - // Expect S2 Transfer End to be sent. - static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 5){ - helper_func_restore_keys_expect(); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - continue; // if sixth iteration, break here to test timeout for timeout. - } - } - - // After receiving a timeout it is expected that the inclusion state machine is back in idle and - // that we can initiate a new inclusion which will also trigger a new set timeout call. - static uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); - - // At final stage retry node inclusion to ensure we are in idle stage. - s2_inclusion_including_start(&s2_context,&s2_conn); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling when frames are received in wrong order during inclusion. - * This could either be implementation error or more critical, someone trying to find weakness in - * the system. Therefore the system must silently return to idle. - * - * An error should still be returned upwards to the application. - */ - void test_kex_inclusion_invalid_frame_order_all_states(void) { - mock_t * p_mock; - uint32_t i; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < NO_OF_STATES; i++) - { - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - if (i == 0){ - // The invalid frame. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; - - helper_func_restore_keys_expect(); - - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Let's try to directly fetch a network key. - memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); - s2_context.length = sizeof(s2_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - //s2_context.buf = frame_buffer; // Reset buffer back. - continue; // if first iteration, continue here to test timeout for timeout. - } - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - if (i == 1) - { - // The invalid frame - Let's send a KEX Get the opposite direction. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Let's try to directly fetch a network key. - memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); - s2_context.length = sizeof(s2_frame); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - // s2_context.buf = frame_buffer; // Reset buffer back. - continue; // if first iteration, continue here to test timeout for timeout. - } - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0x02; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - - if (i == 2){ - uint8_t S2_pub_key_A_return[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Let's try to reply by sending back public key frame to examine behavior. - memcpy((uint8_t *)s2_context.buf, S2_pub_key_A_return, sizeof(S2_pub_key_A_return)); - s2_context.length = sizeof(S2_pub_key_A_return); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_context.buf = frame_buffer; // Reset buffer back. - continue; // if first iteration, continue here to test timeout for timeout. - } - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 3){ - // The invalid frame. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x07; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // When inclusion fails, we expect a KEX Fail to be sent to inclusion_peer. - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_AUTH = 0x05 - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - // Let's try to check what happens if we intercept and try to restart secure inclusion by - // sending a KEX Report. Will we be accepted ? - memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); - s2_context.length = sizeof(s2_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - //s2_context.buf = frame_buffer; // Reset buffer back. - - s2_inclusion_send_done(&s2_context, 1); - - continue; // if first iteration, continue here to test timeout for timeout. - } - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 4){ - // Go to transfer end without verifying the key. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); - s2_context.length = sizeof(s2_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - continue; // if fifth iteration, break here to test timeout for timeout. - } - - // Expect S2 Transfer End to be sent. - static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 5){ - // Retry the echo to see if we can get further back in the loop than officially allowed. - // This should just be ignored as it should be considered a duplicate frame and hence ignored. - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; - - memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); - s2_context.length = sizeof(s2_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // In order to get back to idle for processing next loop of test we simply issue a transfer - // end out of the correct inclusion sequence which we force the system back to idle. - // Go to transfer end without verifying the key. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x03}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - memcpy((uint8_t *)s2_context.buf, s2_transfer_end_frame, sizeof(s2_transfer_end_frame)); - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_context.buf = frame_buffer; // Reset buffer back. - continue; - } - } - - // After receiving a timeout it is expected that the inclusion state machine is back in idle and - // that we can initiate a new inclusion which will also trigger a new set timeout call. - static uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); - - // At final stage retry node inclusion to ensure we are in idle stage. - s2_inclusion_including_start(&s2_context,&s2_conn); - - mock_calls_verify(); - } - - void test_kex_inclusion_duplicate_frame_order_all_states(void) { - mock_t * p_mock; - uint32_t i; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - // Expect S2 Transfer End to be sent. - static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - static uint8_t S2_net_key_set_frame_s0[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80}; - memcpy(&S2_net_key_set_frame_s0[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame_s0; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame_s0); - - // Expect S2 Transfer End to be sent. - //static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - helper_func_restore_keys_expect(); - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < 7; i++) - { - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - if (i == 0) - continue; - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - if (i == 1) - { - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - continue; // if first iteration, continue here to test timeout for timeout. - } - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - if (i == 2){ - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - continue; - } - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 3) - continue; - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 4) - continue; - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - - if (i == 5) - continue; - - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - } - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the node is not supporting - * mandatory schemes, or the schemes supported are not supported by the controller. - * - * Purpose: In order to ensure a node can be correctly included there must be a match between the - * schemes supported by both inclusion and joining node. If this cannot be established - * between the node, then it must be ensured that appropriate failure is returned. - * - * Test: This test case will in case the following schemes are received from joining node as - * supported then a KEX_FAIL_SCHEME is returned. +#define NO_OF_STATES 6 +void test_kex_inclusion_timeout_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + helper_func_init_s2_conn(); + + /** The loop which will set up the expectation based on the round. */ + for (i = 0; i < NO_OF_STATES; i++) { + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + if (i == 0) { + helper_func_restore_keys_expect(); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + continue; // if first iteration, continue here to test timeout for timeout. + } + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + if (i == 1) { + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + helper_func_restore_keys_expect(); + + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + continue; // if second iteration, break here to test timeout for timeout. + } + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + + if (i == 2) { + helper_func_restore_keys_expect(); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + continue; // if third iteration, break here to test timeout for timeout. + } + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 3) { + helper_func_restore_keys_expect(); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + continue; // if fourth iteration, break here to test timeout for timeout. + } + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + // Expect Net Key Set to be sent. + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 4) { + helper_func_restore_keys_expect(); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + continue; // if fifth iteration, break here to test timeout for timeout. + } + + // Expect S2 Transfer End to be sent. + static uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 5) { + helper_func_restore_keys_expect(); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + continue; // if sixth iteration, break here to test timeout for timeout. + } + } + + // After receiving a timeout it is expected that the inclusion state machine is back in idle and + // that we can initiate a new inclusion which will also trigger a new set timeout call. + static uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); + + // At final stage retry node inclusion to ensure we are in idle stage. + s2_inclusion_including_start(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling when frames are received in wrong order during inclusion. + * This could either be implementation error or more critical, someone trying to find weakness in + * the system. Therefore the system must silently return to idle. + * + * An error should still be returned upwards to the application. */ - void test_kex_inclusion_error_schemes(void) { - mock_t * p_mock; - uint32_t i; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6]; - struct S2 s2_context; - - uint8_t scheme_scheme_fail_test_vector[][2] = { - {0x00, 0x00}, // Scheme 2 = false, scheme 0 = false, key request don't care. This should return FAIL_KEY_REPORT. - {0x01, 0x80}, // Scheme 2 = false, scheme 0 = true, key request don't care. This should return FAIL_KEY_REPORT. - }; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - for (i = 0; i < ELEM_COUNT(scheme_scheme_fail_test_vector); i++) - { - - /**************************** +void test_kex_inclusion_invalid_frame_order_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + /** The loop which will set up the expectation based on the round. */ + for (i = 0; i < NO_OF_STATES; i++) { + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + if (i == 0) { + // The invalid frame. + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; + + helper_func_restore_keys_expect(); + + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Let's try to directly fetch a network key. + memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); + s2_context.length = sizeof(s2_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + //s2_context.buf = frame_buffer; // Reset buffer back. + continue; // if first iteration, continue here to test timeout for timeout. + } + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + if (i == 1) { + // The invalid frame - Let's send a KEX Get the opposite direction. + uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Let's try to directly fetch a network key. + memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); + s2_context.length = sizeof(s2_frame); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + // s2_context.buf = frame_buffer; // Reset buffer back. + continue; // if first iteration, continue here to test timeout for timeout. + } + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length + = 0x02; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + + if (i == 2) { + uint8_t S2_pub_key_A_return[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Let's try to reply by sending back public key frame to examine behavior. + memcpy((uint8_t *)s2_context.buf, + S2_pub_key_A_return, + sizeof(S2_pub_key_A_return)); + s2_context.length = sizeof(S2_pub_key_A_return); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_context.buf = frame_buffer; // Reset buffer back. + continue; // if first iteration, continue here to test timeout for timeout. + } + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 3) { + // The invalid frame. + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x07; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // When inclusion fails, we expect a KEX Fail to be sent to inclusion_peer. + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_AUTH = 0x05 + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + // Let's try to check what happens if we intercept and try to restart secure inclusion by + // sending a KEX Report. Will we be accepted ? + memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); + s2_context.length = sizeof(s2_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + //s2_context.buf = frame_buffer; // Reset buffer back. + + s2_inclusion_send_done(&s2_context, 1); + + continue; // if first iteration, continue here to test timeout for timeout. + } + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 4) { + // Go to transfer end without verifying the key. + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); + s2_context.length = sizeof(s2_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + continue; // if fifth iteration, break here to test timeout for timeout. + } + + // Expect S2 Transfer End to be sent. + static uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 5) { + // Retry the echo to see if we can get further back in the loop than officially allowed. + // This should just be ignored as it should be considered a duplicate frame and hence ignored. + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + + memcpy((uint8_t *)s2_context.buf, s2_frame, sizeof(s2_frame)); + s2_context.length = sizeof(s2_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // In order to get back to idle for processing next loop of test we simply issue a transfer + // end out of the correct inclusion sequence which we force the system back to idle. + // Go to transfer end without verifying the key. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x03}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + memcpy((uint8_t *)s2_context.buf, + s2_transfer_end_frame, + sizeof(s2_transfer_end_frame)); + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_context.buf = frame_buffer; // Reset buffer back. + continue; + } + } + + // After receiving a timeout it is expected that the inclusion state machine is back in idle and + // that we can initiate a new inclusion which will also trigger a new set timeout call. + static uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); + + // At final stage retry node inclusion to ensure we are in idle stage. + s2_inclusion_including_start(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +void test_kex_inclusion_duplicate_frame_order_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + // Expect S2 Transfer End to be sent. + static uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + static uint8_t S2_net_key_set_frame_s0[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80}; + memcpy(&S2_net_key_set_frame_s0[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame_s0; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame_s0); + + // Expect S2 Transfer End to be sent. + //static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + helper_func_restore_keys_expect(); + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** The loop which will set up the expectation based on the round. */ + for (i = 0; i < 7; i++) { + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + if (i == 0) + continue; + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + if (i == 1) { + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + continue; // if first iteration, continue here to test timeout for timeout. + } + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + if (i == 2) { + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + continue; + } + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 3) + continue; + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 4) + continue; + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + + if (i == 5) + continue; + + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + } + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the node is not supporting + * mandatory schemes, or the schemes supported are not supported by the controller. + * + * Purpose: In order to ensure a node can be correctly included there must be a match between the + * schemes supported by both inclusion and joining node. If this cannot be established + * between the node, then it must be ensured that appropriate failure is returned. + * + * Test: This test case will in case the following schemes are received from joining node as + * supported then a KEX_FAIL_SCHEME is returned. + */ +void test_kex_inclusion_error_schemes(void) +{ + mock_t *p_mock; + uint32_t i; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6]; + struct S2 s2_context; + + uint8_t scheme_scheme_fail_test_vector[][2] = { + {0x00, + 0x00}, // Scheme 2 = false, scheme 0 = false, key request don't care. This should return FAIL_KEY_REPORT. + {0x01, + 0x80}, // Scheme 2 = false, scheme 0 = true, key request don't care. This should return FAIL_KEY_REPORT. + }; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + for (i = 0; i < ELEM_COUNT(scheme_scheme_fail_test_vector); i++) { + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. - uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x02}; // KEX_FAIL_KEX_SCHEME = 0x02 - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); - - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x02; // KEX_FAIL_KEX_SCHEME Scheme failure indicating that no scheme is supported by controller or joining node specified an invalid scheme. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. + uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_FAIL, + 0x02}; // KEX_FAIL_KEX_SCHEME = 0x02 + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); + + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x02; // KEX_FAIL_KEX_SCHEME Scheme failure indicating that no scheme is supported by controller or joining node specified an invalid scheme. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - With an unsupported scheme set. - s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; - s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x00, // bit 0 is echo field, rest are reserved - s2_kex_report_frame[3] = scheme_scheme_fail_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = scheme_scheme_fail_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - } - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the node is not supporting + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - With an unsupported scheme set. + s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; + s2_kex_report_frame[1] = KEX_REPORT; + s2_kex_report_frame[2] = 0x00, // bit 0 is echo field, rest are reserved + s2_kex_report_frame[3] + = scheme_scheme_fail_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] + = scheme_scheme_fail_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + } + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the node is not supporting * curve 25519, or other curves requested are not (yet) supported by the controller. * * Purpose: In order to ensure a node can be correctly included there must be a match between the @@ -2388,72 +3041,78 @@ * * Test: This test case will a KEX_FAIL_CURVE is returned when invalid set of schemes is requested. */ - void test_kex_inclusion_error_curves(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - - uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x03}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - /**************************** +void test_kex_inclusion_error_curves(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + + uint8_t S2_kex_set_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x03}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // Expect a S2 KEX Fail as the including node is not supporting curve 25519, or other curves requested are not (yet) supported by the controller - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x03; // KEX_FAIL_KEX_CURVES Curve failure indicating that no curve is supported by controller or joining node specified an invalid curve. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // Expect a S2 KEX Fail as the including node is not supporting curve 25519, or other curves requested are not (yet) supported by the controller + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x03; // KEX_FAIL_KEX_CURVES Curve failure indicating that no curve is supported by controller or joining node specified an invalid curve. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Unknown curve set. - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // bit 0 is echo field, rest are reserved - 0x02, // Supported schemes. Scheme 1. - 0x02, // Supported ECDH Profiles, bit1=1 is unknown cureve value. - 0x01}; // Requested keys bit0=Security2 Class 0 key. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case there is an invalid combination + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Unknown curve set. + uint8_t s2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // bit 0 is echo field, rest are reserved + 0x02, // Supported schemes. Scheme 1. + 0x02, // Supported ECDH Profiles, bit1=1 is unknown cureve value. + 0x01}; // Requested keys bit0=Security2 Class 0 key. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case there is an invalid combination * of scheme support and key request. * * Purpose: In order to ensure a node can be correctly included there must be a match between the @@ -2461,81 +3120,87 @@ * * Test: This test case will a KEX_FAIL_KEY is returned when invalid set of schemes/keys is requested. */ - void test_kex_inclusion_error_keys(void) { - uint32_t i; - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6]; - struct S2 s2_context; - - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x01}; // KEX_FAIL_KEX_KEY = 0x01 - uint8_t scheme_key_request_fail_test_vector[] = { - 0x00, // key request S2 = no, key request S0 = no. This should return FAIL_KEY_REPORT. - }; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - for (i = 0; i < ELEM_COUNT(scheme_key_request_fail_test_vector); i++) - { - /**************************** +void test_kex_inclusion_error_keys(void) +{ + uint32_t i; + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6]; + struct S2 s2_context; + + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x01}; // KEX_FAIL_KEX_KEY = 0x01 + uint8_t scheme_key_request_fail_test_vector[] = { + 0x00, // key request S2 = no, key request S0 = no. This should return FAIL_KEY_REPORT. + }; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + for (i = 0; i < ELEM_COUNT(scheme_key_request_fail_test_vector); i++) { + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // Expect a S2 KEX Fail as the case there is an invalid combination of scheme support and key request. - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x01; // KEX_FAIL_KEX_KEY Key failure indicating that no match exists between requested/granted keys in the network. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // Expect a S2 KEX Fail as the case there is an invalid combination of scheme support and key request. + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x01; // KEX_FAIL_KEX_KEY Key failure indicating that no match exists between requested/granted keys in the network. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Invalid mix of schemes and keys. - s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; - s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x00, // bit 0 is echo field, rest are reserved - s2_kex_report_frame[3] = 0x02; // Supported schemes. - s2_kex_report_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = scheme_key_request_fail_test_vector[i]; // Requested keys bit. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - } - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in all cases when there is a valid combination + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Invalid mix of schemes and keys. + s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; + s2_kex_report_frame[1] = KEX_REPORT; + s2_kex_report_frame[2] = 0x00, // bit 0 is echo field, rest are reserved + s2_kex_report_frame[3] = 0x02; // Supported schemes. + s2_kex_report_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] + = scheme_key_request_fail_test_vector[i]; // Requested keys bit. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + } + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in all cases when there is a valid combination * of scheme support and key request. * * Purpose: In order to ensure a node can be correctly included there must be a match between the @@ -2543,95 +3208,154 @@ * * Test: This test case will ensure a KEX Set is transmitted when a valid set of schemes/keys is requested. */ - void test_kex_inclusion_valid_keys(void) { - uint32_t i; - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6]; - struct S2 s2_context; - - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; // Scheme 0 and 2, curve25519, S2, key 2, and S0 network key. - - // Double array, each row is a test, first two bytes in column is received frame, second two bytes are the expected output. - uint8_t scheme_key_request_pass_test_vector[][4] = { - {0x02, 0x01, 0x02, 0x01}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x02, 0x02, 0x02}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x03, 0x02, 0x03}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x04, 0x02, 0x04}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x05, 0x02, 0x05}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x06, 0x02, 0x06}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x07, 0x02, 0x07}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. - {0x02, 0x80, 0x02, 0x80}, // Scheme 1 = true, key request S2 = no, key request S0 = yes. Valid request. - {0x02, 0x81, 0x02, 0x81}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x82, 0x02, 0x82}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x83, 0x02, 0x83}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x84, 0x02, 0x84}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x85, 0x02, 0x85}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x86, 0x02, 0x86}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - {0x02, 0x87, 0x02, 0x87}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. - }; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(s2_event_handler)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_public_key_read)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - for (i = 0; i < ELEM_COUNT(scheme_key_request_pass_test_vector); i++) - { - /**************************** +void test_kex_inclusion_valid_keys(void) +{ + uint32_t i; + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6]; + struct S2 s2_context; + + uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x00, + 0x02, + 0x01, + 0x82}; // Scheme 0 and 2, curve25519, S2, key 2, and S0 network key. + + // Double array, each row is a test, first two bytes in column is received frame, second two bytes are the expected output. + uint8_t scheme_key_request_pass_test_vector[][4] = { + {0x02, + 0x01, + 0x02, + 0x01}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x02, + 0x02, + 0x02}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x03, + 0x02, + 0x03}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x04, + 0x02, + 0x04}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x05, + 0x02, + 0x05}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x06, + 0x02, + 0x06}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x07, + 0x02, + 0x07}, // Scheme 1 = true, key request S2 = yes, key request S0 = no. Valid request. + {0x02, + 0x80, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = no, key request S0 = yes. Valid request. + {0x02, + 0x81, + 0x02, + 0x81}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x82, + 0x02, + 0x82}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x83, + 0x02, + 0x83}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x84, + 0x02, + 0x84}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x85, + 0x02, + 0x85}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x86, + 0x02, + 0x86}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + {0x02, + 0x87, + 0x02, + 0x87}, // Scheme 1 = true, key request S2 = yes, key request S0 = yes. Valid request. + }; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(s2_event_handler)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_public_key_read)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + for (i = 0; i < ELEM_COUNT(scheme_key_request_pass_test_vector); i++) { + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - S2_kex_set_frame[3] = scheme_key_request_pass_test_vector[i][2]; - S2_kex_set_frame[5] = scheme_key_request_pass_test_vector[i][3]; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + S2_kex_set_frame[3] = scheme_key_request_pass_test_vector[i][2]; + S2_kex_set_frame[5] = scheme_key_request_pass_test_vector[i][3]; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; - s2_kex_report_frame[1] = KEX_REPORT; - s2_kex_report_frame[2] = 0x00, // bit 0 is echo field, rest are reserved - s2_kex_report_frame[3] = scheme_key_request_pass_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[4] = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - s2_kex_report_frame[5] = scheme_key_request_pass_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, scheme_key_request_pass_test_vector[i][3],0); // Granted keys. - - // Inject a timeout to ensure state goes back to idle so we can test next combination. - s2_inclusion_notify_timeout(&s2_context); - } - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the joining node is + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + s2_kex_report_frame[0] = COMMAND_CLASS_SECURITY_2; + s2_kex_report_frame[1] = KEX_REPORT; + s2_kex_report_frame[2] = 0x00, // bit 0 is echo field, rest are reserved + s2_kex_report_frame[3] + = scheme_key_request_pass_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[4] + = 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + s2_kex_report_frame[5] + = scheme_key_request_pass_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, + 1, + scheme_key_request_pass_test_vector[i][3], + 0); // Granted keys. + + // Inject a timeout to ensure state goes back to idle so we can test next combination. + s2_inclusion_notify_timeout(&s2_context); + } + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the joining node is * requesting more keys than what was granted in KEX Set * * Purpose: In order to ensure a node can be correctly included there must be a match between the @@ -2639,684 +3363,1011 @@ * * Test: This test case will ensure a KEX_FAIL_KEY_GET is returned when non granted key is requested. */ - void test_kex_inclusion_error_key_get_request(void) { - uint32_t i; - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x00, 0x01, 0x00}; - uint8_t s2_echo_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x00, 0x01, 0x00}; - uint8_t s2_net_key_get_frame[6] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x00}; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - struct S2 s2_context; - - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x08}; // KEX_FAIL_KEY_GET = 0x08 - - // Double array, each row is a test, first two bytes in column is reported/granted keys, third byte is the requested key. - uint8_t key_get_request_fail_test_vector[][3] = { - {0x02, 0x01, 0x02}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. - {0x02, 0x01, 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. - {0x02, 0x01, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x02, 0x01}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 0. - {0x02, 0x02, 0x04}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 2. - {0x02, 0x02, 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. - {0x02, 0x02, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x03, 0x04}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 2. - {0x02, 0x03, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class x. - {0x02, 0x03, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x04, 0x01}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 0. - {0x02, 0x04, 0x02}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. - {0x02, 0x04, 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. - {0x02, 0x04, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x05, 0x02}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. - {0x02, 0x05, 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. - {0x02, 0x05, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x06, 0x01}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. - {0x02, 0x06, 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. - {0x02, 0x06, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x07, 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. - {0x02, 0x07, 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. - {0x02, 0x81, 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. - {0x02, 0x81, 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. - {0x02, 0x81, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x82, 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. - {0x02, 0x82, 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. - {0x02, 0x82, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x84, 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. - {0x02, 0x84, 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. - {0x02, 0x84, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x85, 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. - {0x02, 0x85, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x86, 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. - {0x02, 0x86, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x81, 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. - {0x02, 0x81, 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. - {0x02, 0x82, 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. - {0x02, 0x82, 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. - {0x02, 0x83, 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. - {0x02, 0x83, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x87, 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - - - - {0x02, 0x83, 0x10}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x83, 0x20}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - {0x02, 0x83, 0x40}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. - }; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - for (i = 0; i < ELEM_COUNT(key_get_request_fail_test_vector); i++) - { - /**************************** +void test_kex_inclusion_error_key_get_request(void) +{ + uint32_t i; + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x00, 0x01, 0x00}; + uint8_t s2_echo_kex_set_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x00, 0x01, 0x00}; + uint8_t s2_net_key_get_frame[6] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x00}; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + struct S2 s2_context; + + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x08}; // KEX_FAIL_KEY_GET = 0x08 + + // Double array, each row is a test, first two bytes in column is reported/granted keys, third byte is the requested key. + uint8_t key_get_request_fail_test_vector[][3] = { + {0x02, + 0x01, + 0x02}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. + {0x02, + 0x01, + 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. + {0x02, + 0x01, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x02, + 0x01}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 0. + {0x02, + 0x02, + 0x04}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 2. + {0x02, + 0x02, + 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. + {0x02, + 0x02, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x03, + 0x04}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 2. + {0x02, + 0x03, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class x. + {0x02, + 0x03, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x04, + 0x01}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 0. + {0x02, + 0x04, + 0x02}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. + {0x02, + 0x04, + 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. + {0x02, + 0x04, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x05, + 0x02}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. + {0x02, + 0x05, + 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. + {0x02, + 0x05, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x06, + 0x01}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class 1. + {0x02, + 0x06, + 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. + {0x02, + 0x06, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x07, + 0x08}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S2 class x. + {0x02, + 0x07, + 0x80}, // Scheme 2 = true, scheme 0 = false, key request S2 = yes - Request S0 Network key. + {0x02, + 0x81, + 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. + {0x02, + 0x81, + 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. + {0x02, + 0x81, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x82, + 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. + {0x02, + 0x82, + 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. + {0x02, + 0x82, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x84, + 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. + {0x02, + 0x84, + 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. + {0x02, + 0x84, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x85, + 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. + {0x02, + 0x85, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x86, + 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. + {0x02, + 0x86, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x81, + 0x02}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 1. + {0x02, + 0x81, + 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. + {0x02, + 0x82, + 0x01}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 0. + {0x02, + 0x82, + 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. + {0x02, + 0x83, + 0x04}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request S2 class 2. + {0x02, + 0x83, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x87, + 0x08}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + + {0x02, + 0x83, + 0x10}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x83, + 0x20}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + {0x02, + 0x83, + 0x40}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request unknown/unsupported key. + }; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + for (i = 0; i < ELEM_COUNT(key_get_request_fail_test_vector); i++) { + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = key_get_request_fail_test_vector[i][1]; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - helper_func_kex_set_frame_expect(key_get_request_fail_test_vector[i][0], 0x01, - key_get_request_fail_test_vector[i][1]); - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = key_get_request_fail_test_vector[i][1]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = key_get_request_fail_test_vector[i][1]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = ((key_get_request_fail_test_vector[i][1] & 0x06)?2:0); - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - helper_func_echo_kex_report_frame_expect(key_get_request_fail_test_vector[i][0], 0x01, - key_get_request_fail_test_vector[i][1]); - - // Expect a S2 KEX Fail as the the joining node is requesting more keys than what was granted in KEX Set - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x08; //KEX_FAIL_KEY_GET The joining node has requested a key, which was not granted by the including node at an earlier stage - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = key_get_request_fail_test_vector[i][1]; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + helper_func_kex_set_frame_expect(key_get_request_fail_test_vector[i][0], + 0x01, + key_get_request_fail_test_vector[i][1]); + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = key_get_request_fail_test_vector[i][1]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = key_get_request_fail_test_vector[i][1]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length + = ((key_get_request_fail_test_vector[i][1] & 0x06) ? 2 : 0); + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + helper_func_echo_kex_report_frame_expect( + key_get_request_fail_test_vector[i][0], + 0x01, + key_get_request_fail_test_vector[i][1]); + + // Expect a S2 KEX Fail as the the joining node is requesting more keys than what was granted in KEX Set + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x08; //KEX_FAIL_KEY_GET The joining node has requested a key, which was not granted by the including node at an earlier stage + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - s2_kex_report_frame[3] = key_get_request_fail_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[5] = key_get_request_fail_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, key_get_request_fail_test_vector[i][1],0); // Granted keys. - - s2_context.buf = frame_buffer; - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - - // KEX Echo Set frame received - Valid mix of schemes and keys. - s2_echo_kex_set_frame[3] = key_get_request_fail_test_vector[i][0]; // Supported schemes. - s2_echo_kex_set_frame[5] = key_get_request_fail_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network key get frame received - Invalid key requested. - s2_net_key_get_frame[2] = key_get_request_fail_test_vector[i][2]; // Requested key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - } - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the user rejects the node + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + s2_kex_report_frame[3] + = key_get_request_fail_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[5] + = key_get_request_fail_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, + 1, + key_get_request_fail_test_vector[i][1], + 0); // Granted keys. + + s2_context.buf = frame_buffer; + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + + // KEX Echo Set frame received - Valid mix of schemes and keys. + s2_echo_kex_set_frame[3] + = key_get_request_fail_test_vector[i][0]; // Supported schemes. + s2_echo_kex_set_frame[5] + = key_get_request_fail_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network key get frame received - Invalid key requested. + s2_net_key_get_frame[2] + = key_get_request_fail_test_vector[i][2]; // Requested key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + } + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the user rejects the node * from inclusion after receiving KEX Report containing requested keys. * * Test: This test case will ensure a KEX_FAIL_USER_CANCEL is returned when user rejects inclusion. */ - void test_kex_inclusion_key_grant_user_reject(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x83}; - - struct S2 s2_context; - s2_connection_t s2_conn; - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x06}; // KEX_FAIL_CANCEL = 0x06 - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - memset(&s2_conn, 0, sizeof(s2_conn)); - /**************************** +void test_kex_inclusion_key_grant_user_reject(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x83}; + + struct S2 s2_context; + s2_connection_t s2_conn; + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x06}; // KEX_FAIL_CANCEL = 0x06 + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + memset(&s2_conn, 0, sizeof(s2_conn)); + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x83; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Fail as the user cancelled inclusion. - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x06; //KEX_FAIL_CANCEL User has cancelled the S2 bootstrapping. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x83; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Fail as the user cancelled inclusion. + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x06; //KEX_FAIL_CANCEL User has cancelled the S2 bootstrapping. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - memcpy((uint8_t *)s2_context.buf, s2_kex_report_frame, sizeof(s2_kex_report_frame)); - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 0, 0x00,0); // Granted keys. - - // helper_func_pub_key_frame(&s2_context); - // s2_inclusion_post_event_peer(&s2_context, &s2_conn); - - // s2_inclusion_challenge_response(&s2_context, 0, 0xAABB); - - s2_inclusion_send_done(&s2_context, 1); - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the user rejects the node + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + memcpy((uint8_t *)s2_context.buf, + s2_kex_report_frame, + sizeof(s2_kex_report_frame)); + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 0, 0x00, 0); // Granted keys. + + // helper_func_pub_key_frame(&s2_context); + // s2_inclusion_post_event_peer(&s2_context, &s2_conn); + + // s2_inclusion_challenge_response(&s2_context, 0, 0xAABB); + + s2_inclusion_send_done(&s2_context, 1); + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the user rejects the node * from inclusion during DSK input. * * Test: This test case will ensure a KEX_FAIL_USER_CANCEL is returned when user rejects inclusion. */ - void test_kex_inclusion_user_reject(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x81}; - //uint8_t s2_echo_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; - //uint8_t s2_net_key_get_frame[6] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - struct S2 s2_context; - s2_connection_t s2_conn; - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x06}; // KEX_FAIL_CANCEL = 0x06 - - memset(&s2_conn, 0, sizeof(s2_conn)); - s2_conn.rx_options = 0x00; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - /**************************** +void test_kex_inclusion_user_reject(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x81}; + //uint8_t s2_echo_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; + //uint8_t s2_net_key_get_frame[6] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + struct S2 s2_context; + s2_connection_t s2_conn; + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x06}; // KEX_FAIL_CANCEL = 0x06 + + memset(&s2_conn, 0, sizeof(s2_conn)); + s2_conn.rx_options = 0x00; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x81; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - helper_func_kex_set_frame_expect(0x02, 0x01, 0x81); - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x81; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x06; //KEX_FAIL_CANCEL User has cancelled the S2 bootstrapping. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x81; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + helper_func_kex_set_frame_expect(0x02, 0x01, 0x81); + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x81; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x06; //KEX_FAIL_CANCEL User has cancelled the S2 bootstrapping. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - memcpy((uint8_t *)s2_context.buf, s2_kex_report_frame, sizeof(s2_kex_report_frame)); - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x81,0); // Granted keys. - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 0, m_test_public_key_b, 2); - - s2_inclusion_send_done(&s2_context, 1); - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case an echo kex set is received. + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + memcpy((uint8_t *)s2_context.buf, + s2_kex_report_frame, + sizeof(s2_kex_report_frame)); + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x81, 0); // Granted keys. + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 0, m_test_public_key_b, 2); + + s2_inclusion_send_done(&s2_context, 1); + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case an echo kex set is received. * As user has not accepted the inclusion, then the Temporary Shared Secret has not been * established, thus receiving such a frame is an error. */ - void test_kex_inclusion_pending_user_accept_echo_kex_set_received(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x81}; - uint8_t s2_echo_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - struct S2 s2_context; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - /**************************** +void test_kex_inclusion_pending_user_accept_echo_kex_set_received(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x81}; + uint8_t s2_echo_kex_set_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + struct S2 s2_context; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x81; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - helper_func_kex_set_frame_expect(0x02, 0x01, 0x81); - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x81; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // Expect an inclusion error to be pushed upwards. - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x81; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + helper_func_kex_set_frame_expect(0x02, 0x01, 0x81); + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x81; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // Expect an inclusion error to be pushed upwards. + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - memcpy((uint8_t *)s2_context.buf, s2_kex_report_frame, sizeof(s2_kex_report_frame)); - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x81,0); // Granted keys. - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - // No challenge response received, anyway we receive Key get frame, which is invalid. - // s2_inclusion_challenge_response(&s2_context, 0, 0xAABB); - - // KEX Echo Set frame received - Valid mix of schemes and keys. - memcpy((uint8_t *)s2_context.buf, s2_echo_kex_set_frame, sizeof(s2_echo_kex_set_frame)); - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the joining node is + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + memcpy((uint8_t *)s2_context.buf, + s2_kex_report_frame, + sizeof(s2_kex_report_frame)); + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x81, 0); // Granted keys. + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + // No challenge response received, anyway we receive Key get frame, which is invalid. + // s2_inclusion_challenge_response(&s2_context, 0, 0xAABB); + + // KEX Echo Set frame received - Valid mix of schemes and keys. + memcpy((uint8_t *)s2_context.buf, + s2_echo_kex_set_frame, + sizeof(s2_echo_kex_set_frame)); + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the joining node is * requesting more than a single key in Network Key Get request. * * Test: This test case will ensure a KEX_FAIL_KEY_GET is returned when more than one key is requested. */ - void test_kex_inclusion_error_multi_key_get_request(void) { - uint32_t i; - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x00, 0x01, 0x00}; - uint8_t s2_echo_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x00, 0x01, 0x00}; - uint8_t s2_net_key_get_frame[6] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x00}; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - struct S2 s2_context; - - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x08}; // KEX_FAIL_KEY_GET = 0x08 - - // Double array, each row is a test, first two bytes in column is reported/granted keys, third byte is the requested key. - uint8_t key_get_request_fail_test_vector[][3] = { - {0x02, 0x83, 0x83}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request all keys. - {0x02, 0x83, 0x03}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request all S2 keys. - {0x02, 0x83, 0x81}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - two keys. - {0x02, 0x83, 0x82}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - two keys. - }; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - //mock_call_use_as_stub(TO_STR(s2_event_handler)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - for (i = 0; i < ELEM_COUNT(key_get_request_fail_test_vector); i++) - { - /**************************** +void test_kex_inclusion_error_multi_key_get_request(void) +{ + uint32_t i; + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x00, 0x01, 0x00}; + uint8_t s2_echo_kex_set_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x00, 0x01, 0x00}; + uint8_t s2_net_key_get_frame[6] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x00}; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + struct S2 s2_context; + + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x08}; // KEX_FAIL_KEY_GET = 0x08 + + // Double array, each row is a test, first two bytes in column is reported/granted keys, third byte is the requested key. + uint8_t key_get_request_fail_test_vector[][3] = { + {0x02, + 0x83, + 0x83}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request all keys. + {0x02, + 0x83, + 0x03}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - Request all S2 keys. + {0x02, + 0x83, + 0x81}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - two keys. + {0x02, + 0x83, + 0x82}, // Scheme 2 = true, scheme 0 = true, key request S2 = yes - two keys. + }; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + //mock_call_use_as_stub(TO_STR(s2_event_handler)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + for (i = 0; i < ELEM_COUNT(key_get_request_fail_test_vector); i++) { + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = key_get_request_fail_test_vector[i][1]; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - helper_func_kex_set_frame_expect(key_get_request_fail_test_vector[i][0], 0x01, - key_get_request_fail_test_vector[i][1]); - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = key_get_request_fail_test_vector[i][1]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = key_get_request_fail_test_vector[i][1]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = (key_get_request_fail_test_vector[i][1] & 0x06) ? 2 : 0; - - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - helper_func_echo_kex_report_frame_expect(key_get_request_fail_test_vector[i][0], 0x01, - key_get_request_fail_test_vector[i][1]); - - // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x08; //KEX_FAIL_KEY_GET The joining node has requested a key, which was not granted by the including node at an earlier stage. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = key_get_request_fail_test_vector[i][1]; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + helper_func_kex_set_frame_expect(key_get_request_fail_test_vector[i][0], + 0x01, + key_get_request_fail_test_vector[i][1]); + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = key_get_request_fail_test_vector[i][1]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = key_get_request_fail_test_vector[i][1]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length + = (key_get_request_fail_test_vector[i][1] & 0x06) ? 2 : 0; + + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + helper_func_echo_kex_report_frame_expect( + key_get_request_fail_test_vector[i][0], + 0x01, + key_get_request_fail_test_vector[i][1]); + + // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x08; //KEX_FAIL_KEY_GET The joining node has requested a key, which was not granted by the including node at an earlier stage. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - s2_kex_report_frame[3] = key_get_request_fail_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[5] = key_get_request_fail_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, key_get_request_fail_test_vector[i][1],0); // Granted keys. - - s2_context.buf = frame_buffer; - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b,2 ); - - // KEX Echo Set frame received - Valid mix of schemes and keys. - s2_echo_kex_set_frame[3] = key_get_request_fail_test_vector[i][0]; // Supported schemes. - s2_echo_kex_set_frame[5] = key_get_request_fail_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network key get frame received - Invalid key requested. - s2_net_key_get_frame[2] = key_get_request_fail_test_vector[i][2]; // Requested key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - } - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the joining node is + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + s2_kex_report_frame[3] + = key_get_request_fail_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[5] + = key_get_request_fail_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, + 1, + key_get_request_fail_test_vector[i][1], + 0); // Granted keys. + + s2_context.buf = frame_buffer; + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + + // KEX Echo Set frame received - Valid mix of schemes and keys. + s2_echo_kex_set_frame[3] + = key_get_request_fail_test_vector[i][0]; // Supported schemes. + s2_echo_kex_set_frame[5] + = key_get_request_fail_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network key get frame received - Invalid key requested. + s2_net_key_get_frame[2] + = key_get_request_fail_test_vector[i][2]; // Requested key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + } + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the joining node is * transmitting its public key with including node flag set, TO#7554. * * Purpose: In order to ensure correct key exchange it is important that the nodes agrees on who @@ -3325,289 +4376,363 @@ * Test: This test case will ensure that the state machine returns to idle as the wrong including * bit is identical to a unexpected frame at this stages in the state machine. */ - void test_kex_inclusion_error_public_key_including_bit(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x02}; - struct S2 s2_context; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - /**************************** +void test_kex_inclusion_error_public_key_including_bit(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x02, 0x01, 0x02}; + struct S2 s2_context; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x02; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - helper_func_kex_set_frame_expect(0x02, 0x01, 0x02); - - // When including fails we expect at call to keystore in order to restore keys. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x02; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + helper_func_kex_set_frame_expect(0x02, 0x01, 0x02); + + // When including fails we expect at call to keystore in order to restore keys. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - memcpy((uint8_t *)s2_context.buf, s2_kex_report_frame, sizeof(s2_kex_report_frame)); - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x02, 0); // Granted keys. - - frame_buffer[0] = COMMAND_CLASS_SECURITY_2; - frame_buffer[1] = PUBLIC_KEY_REPORT; - frame_buffer[2] = 0x01; // Including bit set (error) - memcpy(&frame_buffer[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = frame_buffer; - s2_conn.class_id = 0xFF; - s2_context.length = 3 + sizeof(m_test_public_key_b); - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Retry node inclusion to ensure we are in idle state. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the joining node is + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + memcpy((uint8_t *)s2_context.buf, + s2_kex_report_frame, + sizeof(s2_kex_report_frame)); + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x02, 0); // Granted keys. + + frame_buffer[0] = COMMAND_CLASS_SECURITY_2; + frame_buffer[1] = PUBLIC_KEY_REPORT; + frame_buffer[2] = 0x01; // Including bit set (error) + memcpy(&frame_buffer[3], m_test_public_key_b, sizeof(m_test_public_key_b)); + s2_context.buf = frame_buffer; + s2_conn.class_id = 0xFF; + s2_context.length = 3 + sizeof(m_test_public_key_b); + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Retry node inclusion to ensure we are in idle state. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the joining node is * transmitting frames with reserved bits set (which should be ignored). */ - void test_kex_inclusion_public_key_reserved_bits(void) { - mock_t * p_mock; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - // Expect S2 Transfer End to be sent. - static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - static uint8_t S2_net_key_set_frame_s0[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80}; - memcpy(&S2_net_key_set_frame_s0[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame_s0; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame_s0); - - // Expect S2 Transfer End to be sent. - //static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - helper_func_restore_keys_expect(); - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - frame_buffer[0] = COMMAND_CLASS_SECURITY_2; - frame_buffer[1] = PUBLIC_KEY_REPORT; - frame_buffer[2] = 0xA2; // Setting a couple of reserved bits which should be ignored on remote side. - memcpy(&frame_buffer[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = frame_buffer; - s2_context.length = 3 + sizeof(m_test_public_key_b); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling of node inclusion in case the joining node is +void test_kex_inclusion_public_key_reserved_bits(void) +{ + mock_t *p_mock; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + // Expect S2 Transfer End to be sent. + static uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + static uint8_t S2_net_key_set_frame_s0[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80}; + memcpy(&S2_net_key_set_frame_s0[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame_s0; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame_s0); + + // Expect S2 Transfer End to be sent. + //static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + helper_func_restore_keys_expect(); + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + frame_buffer[0] = COMMAND_CLASS_SECURITY_2; + frame_buffer[1] = PUBLIC_KEY_REPORT; + frame_buffer[2] + = 0xA2; // Setting a couple of reserved bits which should be ignored on remote side. + memcpy(&frame_buffer[3], m_test_public_key_b, sizeof(m_test_public_key_b)); + s2_context.buf = frame_buffer; + s2_context.length = 3 + sizeof(m_test_public_key_b); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling of node inclusion in case the joining node is * not echo'ing KEX Set with identical fields. * * Purpose: In order to ensure a node can be correctly included the KEX Set and the echo KEX Set @@ -3616,206 +4741,363 @@ * Test: This test case will ensure a KEX_FAIL_AUTH is returned when the echo KEX Set does not * match the KEX Set frame. */ - void test_kex_inclusion_error_echo_kex_set(void) { - uint32_t i; - mock_t * p_mock; - zwave_event_t * p_expected_event; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - uint8_t s2_kex_report_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x00, 0x01, 0x00}; - uint8_t s2_echo_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x00, 0x01, 0x00}; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - struct S2 s2_context; - - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_AUTH = 0x07 - - // Double array, each row is a test, first two bytes in column is reported/granted keys, third and fourth bytes are hte bytes in echo KEX Set. - uint8_t key_echo_fail_test_vector[][4] = { - {0x02, 0x01, 0x02, 0x02}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x01, 0x02, 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x01, 0x02, 0x04}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x01, 0x02, 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x02, 0x02, 0x01}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x02, 0x02, 0x04}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x02, 0x02, 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x02, 0x02, 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - - {0x02, 0x01, 0x03, 0x01}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x02, 0x03, 0x02}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x03, 0x03, 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x03, 0x72, 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x03, 0xF2, 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x03, 0xFA, 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - - {0x02, 0x81, 0x02, 0x82}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x81, 0x02, 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x81, 0x02, 0x84}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x81, 0x02, 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x82, 0x02, 0x81}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x82, 0x02, 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x82, 0x02, 0x84}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x82, 0x02, 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x81}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x82}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x84}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x07}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x78}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0xFF}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0x02, 0x00}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - - {0x02, 0x83, 0x7C, 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0xF3, 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - {0x02, 0x83, 0xFC, 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. - }; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - for (i = 0; i < ELEM_COUNT(key_echo_fail_test_vector); i++) - { - /**************************** +void test_kex_inclusion_error_echo_kex_set(void) +{ + uint32_t i; + mock_t *p_mock; + zwave_event_t *p_expected_event; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + uint8_t s2_kex_report_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x00, 0x00, 0x01, 0x00}; + uint8_t s2_echo_kex_set_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x00, 0x01, 0x00}; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + struct S2 s2_context; + + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_AUTH = 0x07 + + // Double array, each row is a test, first two bytes in column is reported/granted keys, third and fourth bytes are hte bytes in echo KEX Set. + uint8_t key_echo_fail_test_vector[][4] = { + {0x02, + 0x01, + 0x02, + 0x02}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x01, + 0x02, + 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x01, + 0x02, + 0x04}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x01, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x02, + 0x02, + 0x01}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x02, + 0x02, + 0x04}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x02, + 0x02, + 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x02, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + + {0x02, + 0x01, + 0x03, + 0x01}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x02, + 0x03, + 0x02}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x03, + 0x03, + 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x03, + 0x72, + 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x03, + 0xF2, + 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x03, + 0xFA, + 0x03}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + + {0x02, + 0x81, + 0x02, + 0x82}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x81, + 0x02, + 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x81, + 0x02, + 0x84}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x81, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x82, + 0x02, + 0x81}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x82, + 0x02, + 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x82, + 0x02, + 0x84}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x82, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x81}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x82}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x84}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x80}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x07}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x78}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0xFF}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0x02, + 0x00}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + + {0x02, + 0x83, + 0x7C, + 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0xF3, + 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + {0x02, + 0x83, + 0xFC, + 0x83}, // Scheme 1 = true, key request S2 = yes - Wrong echo frame. + }; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + for (i = 0; i < ELEM_COUNT(key_echo_fail_test_vector); i++) { + /**************************** * Mock expectation section * ****************************/ - - // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = key_echo_fail_test_vector[i][1]; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - helper_func_kex_set_frame_expect(key_echo_fail_test_vector[i][0], 0x01, - key_echo_fail_test_vector[i][1]); - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = key_echo_fail_test_vector[i][1]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = key_echo_fail_test_vector[i][1]; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = (key_echo_fail_test_vector[i][1] & 0x06) ? 2 : 0; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x07; //KEX_FAIL_AUTH The Echo KEX Set/Report frame did not match the earlier exchanged frame. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /******************* + + // When initiating the secure inclusion of node B, then we expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = key_echo_fail_test_vector[i][1]; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + helper_func_kex_set_frame_expect(key_echo_fail_test_vector[i][0], + 0x01, + key_echo_fail_test_vector[i][1]); + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + // p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.security_keys = key_echo_fail_test_vector[i][1]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = key_echo_fail_test_vector[i][1]; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length + = (key_echo_fail_test_vector[i][1] & 0x06) ? 2 : 0; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect a S2 KEX Fail as the including node received an unsupported combination of security schemes. + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x07; //KEX_FAIL_AUTH The Echo KEX Set/Report frame did not match the earlier exchanged frame. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /******************* * Testing section * *******************/ - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received - Valid mix of schemes and keys. - s2_kex_report_frame[3] = key_echo_fail_test_vector[i][0]; // Supported schemes. - s2_kex_report_frame[5] = key_echo_fail_test_vector[i][1]; // Requested keys bit. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, key_echo_fail_test_vector[i][1],0); // Granted keys. - - s2_context.buf = frame_buffer; - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - - // KEX Echo Set frame received - Valid mix of schemes and keys. - s2_echo_kex_set_frame[3] = key_echo_fail_test_vector[i][2]; // Wrong match supported schemes. - s2_echo_kex_set_frame[5] = key_echo_fail_test_vector[i][3]; // Wrong match requested keys bit. - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - } - - // Retry node inclusion. - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Test case for ensuring correct timer handling on timeout while in idle. + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received - Valid mix of schemes and keys. + s2_kex_report_frame[3] + = key_echo_fail_test_vector[i][0]; // Supported schemes. + s2_kex_report_frame[5] + = key_echo_fail_test_vector[i][1]; // Requested keys bit. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, + 1, + key_echo_fail_test_vector[i][1], + 0); // Granted keys. + + s2_context.buf = frame_buffer; + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + + // KEX Echo Set frame received - Valid mix of schemes and keys. + s2_echo_kex_set_frame[3] + = key_echo_fail_test_vector[i][2]; // Wrong match supported schemes. + s2_echo_kex_set_frame[5] + = key_echo_fail_test_vector[i][3]; // Wrong match requested keys bit. + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + } + + // Retry node inclusion. + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Test case for ensuring correct timer handling on timeout while in idle. * * Purpose: In order to ensure correct inclusion flow and avoid deadlock during inclusion it is * important that in case messages are never received during inclusion, then the state @@ -3827,743 +5109,987 @@ * After timeout, we expect nothing to happen as we are already in idle. * */ - void test_kex_inclusion_timeout_when_idle(void) { - mock_t * p_mock; - uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(keystore_network_key_read)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - - // No timeout event/node inclusion failure is expected as we are already in idle. - - // After timeout we will issue a node inclusion just to insure we were in idle and that a node - // may be included after timeout. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // Trigger a timeout. - s2_inclusion_notify_timeout(&s2_context); - - // Node id (first step in inclusion) has been assigned. - // Let's initiate a secure inclusion after the timeout to verify the state of the system. - s2_inclusion_including_start(&s2_context,&s2_conn); - - mock_calls_verify(); - } - - /** Verification that the ECHO Kex report match the received frame even if only a subset of keys are granted. +void test_kex_inclusion_timeout_when_idle(void) +{ + mock_t *p_mock; + uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(keystore_network_key_read)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + // No timeout event/node inclusion failure is expected as we are already in idle. + + // After timeout we will issue a node inclusion just to insure we were in idle and that a node + // may be included after timeout. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // Trigger a timeout. + s2_inclusion_notify_timeout(&s2_context); + + // Node id (first step in inclusion) has been assigned. + // Let's initiate a secure inclusion after the timeout to verify the state of the system. + s2_inclusion_including_start(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Verification that the ECHO Kex report match the received frame even if only a subset of keys are granted. */ - void test_kex_including_node_key_grant_subset(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // bit 0 is echo field, rest are reserved - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x87};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_key_grant_subset(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // bit 0 is echo field, rest are reserved + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x87}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x87; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - helper_func_kex_set_frame_expect(0x02, 0x01, 0x82); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x87}; // Note: Echo flag set. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - // Expect Net Key Set to be sent. - uint8_t S2_net_key_report_0_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; - memcpy(&S2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); - - // Expect S2 Transfer End to be sent. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - helper_func_restore_keys_expect(); - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x87; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + helper_func_kex_set_frame_expect(0x02, 0x01, 0x82); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x01, + 0x02, + 0x01, + 0x87}; // Note: Echo flag set. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + // Expect Net Key Set to be sent. + uint8_t S2_net_key_report_0_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; + memcpy(&S2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); + + // Expect S2 Transfer End to be sent. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + helper_func_restore_keys_expect(); + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); - - uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x02}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x01; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Verification that the in case an decryption failure is reported from the S2 protocol layer, + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_b, + sizeof(m_test_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x02}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x01; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Verification that the in case an decryption failure is reported from the S2 protocol layer, * that the S2 inclusion state machine transmits the corresponding error to the inclusion_peer. */ - void test_kex_including_node_decrypt_failed(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // bit 0 is echo field, rest are reserved - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. - zwave_event_t * p_expected_event; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_decrypt_failed(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // bit 0 is echo field, rest are reserved + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. + zwave_event_t *p_expected_event; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - helper_func_kex_get_frame_expect(); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - helper_func_kex_set_frame_expect(0x02, 0x01, 0x82); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key[0] = 0x00; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key[1] = 0x00; - memcpy(&p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key[2], &m_test_public_key_b[2], sizeof(m_test_public_key_b) - 2); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // When inclusion fails, we expect a KEX Fail to be sent to inclusion_peer. - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x05}; // KEX_FAIL_DECRYPT = 0x05 - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - // When inclusion fails, we expect keys to be restored and a corresponding failed inclusion event from libs2. - helper_func_restore_keys_expect(); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x05; //KEX_FAIL_DECRYPT Node failed to decrypt received frame. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + helper_func_kex_get_frame_expect(); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + helper_func_kex_set_frame_expect(0x02, 0x01, 0x82); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key[0] + = 0x00; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key[1] + = 0x00; + memcpy(&p_expected_challenge_event->evt.s2_event.s2_data.challenge_req + .public_key[2], + &m_test_public_key_b[2], + sizeof(m_test_public_key_b) - 2); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // When inclusion fails, we expect a KEX Fail to be sent to inclusion_peer. + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x05}; // KEX_FAIL_DECRYPT = 0x05 + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + // When inclusion fails, we expect keys to be restored and a corresponding failed inclusion event from libs2. + helper_func_restore_keys_expect(); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x05; //KEX_FAIL_DECRYPT Node failed to decrypt received frame. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00, 0x00, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[5], &m_test_public_key_b[2], sizeof(m_test_public_key_b) - 2); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // A ECHO KEX Set was received, unfortunately the missing part of the DSK has not yet been - // provided by the end user, resulting in s2_inclusion_decryption_failure(...) from S2 - // protocol layer. - // This is supposed to be ignored by the state machine. - s2_inclusion_decryption_failure(&s2_context,&s2_context.inclusion_peer); - - s2_inclusion_decryption_failure(&s2_context,&s2_context.inclusion_peer); - - // User provides wrong key. - - const uint8_t wrong_key[] = {0xBB,0xCC}; - s2_inclusion_challenge_response(&s2_context, 1, wrong_key, 2); - - //The joing node's retry of A ECHO KEX Set was received, public key is set but with wrong value. - // This result in s2_inclusion_decryption_failure(...) from S2 protocol layer which should - // trigger transmission of a KEX Fail. - s2_inclusion_decryption_failure(&s2_context,&s2_context.inclusion_peer); - - s2_inclusion_send_done(&s2_context, 1); - - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - /** Verification that in case the inclusion state machine is in idle, then AUTH Failed should not + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00, + 0x00, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[5], + &m_test_public_key_b[2], + sizeof(m_test_public_key_b) - 2); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // A ECHO KEX Set was received, unfortunately the missing part of the DSK has not yet been + // provided by the end user, resulting in s2_inclusion_decryption_failure(...) from S2 + // protocol layer. + // This is supposed to be ignored by the state machine. + s2_inclusion_decryption_failure(&s2_context, &s2_context.inclusion_peer); + + s2_inclusion_decryption_failure(&s2_context, &s2_context.inclusion_peer); + + // User provides wrong key. + + const uint8_t wrong_key[] = {0xBB, 0xCC}; + s2_inclusion_challenge_response(&s2_context, 1, wrong_key, 2); + + //The joing node's retry of A ECHO KEX Set was received, public key is set but with wrong value. + // This result in s2_inclusion_decryption_failure(...) from S2 protocol layer which should + // trigger transmission of a KEX Fail. + s2_inclusion_decryption_failure(&s2_context, &s2_context.inclusion_peer); + + s2_inclusion_send_done(&s2_context, 1); + + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +/** Verification that in case the inclusion state machine is in idle, then AUTH Failed should not * be returned for an invalid encrypted frame. TO#06510 */ - void test_kex_invalid_crypt_frame_idle(void) { - - mock_calls_clear(); - - /** +void test_kex_invalid_crypt_frame_idle(void) +{ + mock_calls_clear(); + + /** * Test expectation setup. */ - - /** + + /** * Test execution. */ - struct S2 s2_context; - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_verify_idle_state(&s2_context); - - mock_calls_verify(); - } - - void test_kex_inclusion_tx_queue_full(void) { - mock_t * p_mock; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - p_mock->return_code.value = 1; - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - p_mock->return_code.value = 1; - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - p_mock->return_code.value = 1; - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - p_mock->return_code.value = 1; - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - p_mock->return_code.value = 1; - - // Expect S2 Transfer End to be sent. - static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - p_mock->return_code.value = 1; - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - static uint8_t S2_net_key_set_frame_s0[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80}; - memcpy(&S2_net_key_set_frame_s0[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame_s0; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame_s0); - p_mock->return_code.value = 1; - - // Expect S2 Transfer End to be sent. - //static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - p_mock->return_code.value = 0; - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - p_mock->return_code.value = 1; - - helper_func_restore_keys_expect(); - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x82; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event; - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_send_done(&s2_context, 0); - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_net_key_get_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_send_done(&s2_context, 1); - - helper_func_net_key_verify_frame(&s2_context, 0x80); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_inclusion_send_done(&s2_context, 1); - - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Verification that in case the including only offers unauthenticated keys (with CSA still set) then the full public key is transmitted. + struct S2 s2_context; + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_verify_idle_state(&s2_context); + + mock_calls_verify(); +} + +void test_kex_inclusion_tx_queue_full(void) +{ + mock_t *p_mock; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + p_mock->return_code.value = 1; + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + p_mock->return_code.value = 1; + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + p_mock->return_code.value = 1; + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + p_mock->return_code.value = 1; + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + p_mock->return_code.value = 1; + + // Expect S2 Transfer End to be sent. + static uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->return_code.value = 1; + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + static uint8_t S2_net_key_set_frame_s0[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80}; + memcpy(&S2_net_key_set_frame_s0[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame_s0; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame_s0); + p_mock->return_code.value = 1; + + // Expect S2 Transfer End to be sent. + //static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->return_code.value = 0; + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + p_mock->return_code.value = 1; + + helper_func_restore_keys_expect(); + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x82; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 0); + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_net_key_get_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 1); + + helper_func_net_key_verify_frame(&s2_context, 0x80); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_inclusion_send_done(&s2_context, 1); + + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Verification that in case the including only offers unauthenticated keys (with CSA still set) then the full public key is transmitted. * * Expectation: CSA is requested and accepted * Including node sends its full public key * Joining node sends its full public key * Only S2 unauthenticated and S0 keys are transfered */ - void test_kex_including_node_csa_unauthenticated_only(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x06, // bit 0 is echo field, bit 1 is CSA, bit 2 is NLS support. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x87};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_csa_unauthenticated_only(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x06, // bit 0 is echo field, bit 1 is CSA, bit 2 is NLS support. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x87}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -4595,270 +6121,366 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x87; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x01; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x02, // bit0: echo field, bit1: CSA, bit2-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - 0x81 // Keys to exchange, Security2, class 1 - Security0, network key. - }; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x81; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x87}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x01, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_0, sizeof(m_test_network_key_s2_class_0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - // Expect Net Key Set to be sent. - uint8_t S2_net_key_report_0_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; - memcpy(&S2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); - - // Expect S2 Transfer End to be sent. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x81; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x87; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x01; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x02, // bit0: echo field, bit1: CSA, bit2-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + 0x81 // Keys to exchange, Security2, class 1 - Security0, network key. + }; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x81; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x07, + 0x02, + 0x01, + 0x87}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x01, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_0, + sizeof(m_test_network_key_s2_class_0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + // Expect Net Key Set to be sent. + uint8_t S2_net_key_report_0_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; + memcpy(&S2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); + + // Expect S2 Transfer End to be sent. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x81; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x81, 0x01); - - uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x03, 0x02, 0x01, 0x81}; - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x00; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Verification that in case the including disables/rejects a CSA request then the full public key is transmitted. + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x81, 0x01); + + uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_b, + sizeof(m_test_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x03, 0x02, 0x01, 0x81}; + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x01}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x00; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Verification that in case the including disables/rejects a CSA request then the full public key is transmitted. * * Expectation: Including node sends its full public key * Joining node sends its full public key * Only S2 unauthenticated and S0 keys are transfered */ - void test_kex_including_node_csa_disable(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x06, // bit 0 is echo field, bit 1 is CSA, bit 2 is NLS support. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x87};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_csa_disable(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x06, // bit 0 is echo field, bit 1 is CSA, bit 2 is NLS support. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x87}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -4890,1010 +6512,1310 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x87; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x01; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x00, // bit0: echo field, bit1: CSA, bit2-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - 0x81 // Keys to exchange, Security2, class 1 - Security0, network key. - }; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x81; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x07, 0x02, 0x01, 0x87}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x01, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_0, sizeof(m_test_network_key_s2_class_0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x80; - p_mock->output_arg[1].pointer = m_test_network_key_s0; - - // Expect Net Key Set to be sent. - uint8_t S2_net_key_report_0_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x80, }; - memcpy(&S2_net_key_report_0_frame[3], m_test_network_key_s0, sizeof(m_test_network_key_s0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); - - // Expect S2 Transfer End to be sent. - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x81; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x87; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x01; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x00, // bit0: echo field, bit1: CSA, bit2-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + 0x81 // Keys to exchange, Security2, class 1 - Security0, network key. + }; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x81; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x07, + 0x02, + 0x01, + 0x87}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x01, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_0, + sizeof(m_test_network_key_s2_class_0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x80; + p_mock->output_arg[1].pointer = m_test_network_key_s0; + + // Expect Net Key Set to be sent. + uint8_t S2_net_key_report_0_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x80, + }; + memcpy(&S2_net_key_report_0_frame[3], + m_test_network_key_s0, + sizeof(m_test_network_key_s0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_0_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_0_frame); + + // Expect S2 Transfer End to be sent. + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x81; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x81, 0x00); - - uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x01}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_frame; - s2_context.length = sizeof(s2_net_key_get_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_frame; - s2_context.length = sizeof(s2_net_key_verify_frame); - s2_conn.class_id = 0x00; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Get frame received. - uint8_t s2_net_key_get_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, 0x80}; // Keys requested, Security2, class 2 - Security0, network key. - s2_context.buf = s2_net_key_get_0_frame; - s2_context.length = sizeof(s2_net_key_get_0_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Network Key Verify frame received. - uint8_t s2_net_key_verify_0_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - s2_context.buf = s2_net_key_verify_0_frame; - s2_context.length = sizeof(s2_net_key_verify_0_frame); - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - /** Test case for ensuring correct handling when KEX fail frames are received from opposite side during inclusion. + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x81, 0x00); + + uint8_t public_key_frame[3 + sizeof(m_test_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_public_key_b, + sizeof(m_test_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, NULL, 0); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x81}; + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x01}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_frame; + s2_context.length = sizeof(s2_net_key_get_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_frame; + s2_context.length = sizeof(s2_net_key_verify_frame); + s2_conn.class_id = 0x00; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Get frame received. + uint8_t s2_net_key_get_0_frame[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_GET, + 0x80}; // Keys requested, Security2, class 2 - Security0, network key. + s2_context.buf = s2_net_key_get_0_frame; + s2_context.length = sizeof(s2_net_key_get_0_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Network Key Verify frame received. + uint8_t s2_net_key_verify_0_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + s2_context.buf = s2_net_key_verify_0_frame; + s2_context.length = sizeof(s2_net_key_verify_0_frame); + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** Test case for ensuring correct handling when KEX fail frames are received from opposite side during inclusion. * This could either be implementation error or more critical, someone trying to find weakness in * the system. As an error is received from opposite side over the air, the system must silently return to idle. * * An error should still be returned upwards to the application including the KEX fail type of remote side. */ - void test_kex_inclusion_kex_fail_frame_all_states(void) { - mock_t * p_mock; - uint32_t i; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - /** The loop which will set up the expectation based on the round. */ - for (i = 0; i < 4; i++) - { - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - - if (i == 0) - { - // The KEX Fail frame. - uint8_t s2_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEX_KEY}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x01; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Let's try to directly fetch a network key. - memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); - s2_context.length = sizeof(s2_error_frame); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - // s2_context.buf = frame_buffer; // Reset buffer back. - continue; // if first iteration, continue here to test timeout for timeout. - } - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - - if (i == 1){ - // The KEX Fail frame. - uint8_t s2_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_CANCEL}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x06; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Let's try to reply by sending back public key frame to examine behavior. - memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); - s2_context.length = sizeof(s2_error_frame); - s2_inclusion_post_event(&s2_context, &s2_conn); - s2_context.buf = frame_buffer; // Reset buffer back. - continue; // if first iteration, continue here to test timeout for timeout. - } - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 2){ - // The KEX Fail frame. - uint8_t s2_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_AUTH}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x07; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - // Let's try to check what happens if we intercept and try to restart secure inclusion by - // sending a KEX Report. Will we be accepted ? - memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); - s2_context.length = sizeof(s2_error_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - //s2_context.buf = frame_buffer; // Reset buffer back. - continue; // if first iteration, continue here to test timeout for timeout. - } - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - if (i == 3){ - // The KEX Fail frame. - uint8_t s2_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_REPORT}; - - helper_func_restore_keys_expect(); - // This test will trigger a timeout to the inclusion module after which we expect to receive a - // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x0A; +void test_kex_inclusion_kex_fail_frame_all_states(void) +{ + mock_t *p_mock; + uint32_t i; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + /** The loop which will set up the expectation based on the round. */ + for (i = 0; i < 4; i++) { + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event + = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = 0x82; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + + if (i == 0) { + // The KEX Fail frame. + uint8_t s2_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEX_KEY}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x01; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Let's try to directly fetch a network key. + memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); + s2_context.length = sizeof(s2_error_frame); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + // s2_context.buf = frame_buffer; // Reset buffer back. + continue; // if first iteration, continue here to test timeout for timeout. + } + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + + if (i == 1) { + // The KEX Fail frame. + uint8_t s2_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_CANCEL}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x06; mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); - s2_context.length = sizeof(s2_error_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - continue; // if fifth iteration, break here to test timeout for timeout. - } - - // Expect S2 Transfer End to be sent. - static uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - } - - // After receiving a timeout it is expected that the inclusion state machine is back in idle and - // that we can initiate a new inclusion which will also trigger a new set timeout call. - static uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); - - // At final stage retry node inclusion to ensure we are in idle stage. - s2_inclusion_including_start(&s2_context,&s2_conn); - - mock_calls_verify(); - } - - /** + p_mock->expect_arg[0].pointer = p_expected_event; + + // Let's try to reply by sending back public key frame to examine behavior. + memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); + s2_context.length = sizeof(s2_error_frame); + s2_inclusion_post_event(&s2_context, &s2_conn); + s2_context.buf = frame_buffer; // Reset buffer back. + continue; // if first iteration, continue here to test timeout for timeout. + } + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 2) { + // The KEX Fail frame. + uint8_t s2_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_AUTH}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x07; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Let's try to check what happens if we intercept and try to restart secure inclusion by + // sending a KEX Report. Will we be accepted ? + memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); + s2_context.length = sizeof(s2_error_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + //s2_context.buf = frame_buffer; // Reset buffer back. + continue; // if first iteration, continue here to test timeout for timeout. + } + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + if (i == 3) { + // The KEX Fail frame. + uint8_t s2_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, KEX_FAIL_KEY_REPORT}; + + helper_func_restore_keys_expect(); + // This test will trigger a timeout to the inclusion module after which we expect to receive a + // callback event with a S2_NODE_INCLUSION_FAILED_EVENT. + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x0A; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + memcpy((uint8_t *)s2_context.buf, s2_error_frame, sizeof(s2_error_frame)); + s2_context.length = sizeof(s2_error_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + continue; // if fifth iteration, break here to test timeout for timeout. + } + + // Expect S2 Transfer End to be sent. + static uint8_t S2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + } + + // After receiving a timeout it is expected that the inclusion state machine is back in idle and + // that we can initiate a new inclusion which will also trigger a new set timeout call. + static uint8_t S2_kex_get_frame_retry[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame_retry; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame_retry); + + // At final stage retry node inclusion to ensure we are in idle stage. + s2_inclusion_including_start(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/** * This test verifies that a KEX_FAIL is returned in case the NET KEY VERIFY frame was wrongly encrypted with the Temp key when transmitted by the joining node. */ - void test_kex_inclusion_net_key_verify_temp_key_encrypted_error(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_KEY_GET = 0x08 - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x07; //KEX_FAIL_AUTH The Echo KEX Set/Report frame did not match the earlier exchanged frame. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - helper_func_restore_keys_expect(); - - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x03); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - - mock_calls_verify(); - } - - /** +void test_kex_inclusion_net_key_verify_temp_key_encrypted_error(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_KEY_GET = 0x08 + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x07; //KEX_FAIL_AUTH The Echo KEX Set/Report frame did not match the earlier exchanged frame. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + helper_func_restore_keys_expect(); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x03); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + + mock_calls_verify(); +} + +/** * This test verifies that a KEX_FAIL is returned in case the NET KEY VERIFY frame was wrongly encrypted with the Temp key when transmitted by the joining node. */ - void test_kex_inclusion_net_key_verify_unencrypted_error(void) { - mock_t * p_mock; - zwave_event_t * p_expected_event; - static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; - struct S2 s2_context; - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - memset(&s2_context, 0, sizeof(s2_context)); - s2_context.inclusion_state = S2_INC_IDLE; - s2_context.buf = frame_buffer; - s2_inclusion_set_event_handler(s2_event_handler); - helper_func_init_s2_conn(); - - // Expect a S2 KEX Get to be sent. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - static uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_inc_req_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_public_key_b); - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x82; - p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; - memcpy(p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_inc_req_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t S2_kex_error_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_KEY_GET = 0x08 - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - // Expect Net Key Set to be sent. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - static uint8_t S2_net_key_set_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; - memcpy(&S2_net_key_set_frame[3], m_test_network_key_s2_class_1, sizeof(m_test_network_key_s2_class_1)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_error_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); - - p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x07; //KEX_FAIL_AUTH The Echo KEX Set/Report frame did not match the earlier exchanged frame. - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event; - - helper_func_restore_keys_expect(); - - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - helper_func_kex_report_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x82,0); - helper_func_pub_key_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); - helper_func_echo_kex_set_frame(&s2_context); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - helper_func_net_key_verify_frame(&s2_context, 0x00); - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_send_done(&s2_context, 1); - - mock_calls_verify(); - } - - /** Helper function sections - Start */ - - /** This helper function set up an expected KEX get frame to be send (through the mock). */ - void helper_func_kex_get_frame_expect(void) - { - mock_t * p_mock; - // Static to keep in scope for complete test. - static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - } - - /** This helper function set up the expectation of restoring all keys, either upon completion or error. */ - void helper_func_restore_keys_expect(void) - { - mock_t * p_mock; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - } - - /** This helper function set up an expected KEX set frame to be send (through the mock). +void test_kex_inclusion_net_key_verify_unencrypted_error(void) +{ + mock_t *p_mock; + zwave_event_t *p_expected_event; + static uint8_t frame_buffer[UNIT_TEST_BUF_SIZE]; + struct S2 s2_context; + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + memset(&s2_context, 0, sizeof(s2_context)); + s2_context.inclusion_state = S2_INC_IDLE; + s2_context.buf = frame_buffer; + s2_inclusion_set_event_handler(s2_event_handler); + helper_func_init_s2_conn(); + + // Expect a S2 KEX Get to be sent. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + static uint8_t S2_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_inc_req_event = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_inc_req_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_public_key_b); + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x82; + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.dsk_length = 2; + memcpy( + p_expected_inc_req_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_inc_req_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + + uint8_t S2_kex_error_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, 0x07}; // KEX_FAIL_KEY_GET = 0x08 + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + // Expect Net Key Set to be sent. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + static uint8_t S2_net_key_set_frame[19] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02}; + memcpy(&S2_net_key_set_frame[3], + m_test_network_key_s2_class_1, + sizeof(m_test_network_key_s2_class_1)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_set_frame); + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_error_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_error_frame); + + p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type + = 0x07; //KEX_FAIL_AUTH The Echo KEX Set/Report frame did not match the earlier exchanged frame. + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + helper_func_restore_keys_expect(); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + helper_func_kex_report_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x82, 0); + helper_func_pub_key_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_a, 2); + helper_func_echo_kex_set_frame(&s2_context); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + helper_func_net_key_verify_frame(&s2_context, 0x00); + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_send_done(&s2_context, 1); + + mock_calls_verify(); +} + +/** Helper function sections - Start */ + +/** This helper function set up an expected KEX get frame to be send (through the mock). */ +void helper_func_kex_get_frame_expect(void) +{ + mock_t *p_mock; + // Static to keep in scope for complete test. + static uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); +} + +/** This helper function set up the expectation of restoring all keys, either upon completion or error. */ +void helper_func_restore_keys_expect(void) +{ + mock_t *p_mock; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; +} + +/** This helper function set up an expected KEX set frame to be send (through the mock). * param[in] expected_scheme Expected value for scheme field. * param[in] expected_curves Expected value for curves field. * param[in] expected_keys Expected value for keys field. */ - void helper_func_kex_set_frame_expect(uint8_t expected_scheme, uint8_t expected_curves, uint8_t expected_keys) - { - mock_t * p_mock; - static uint8_t s2_kex_set_frame[6] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x00, 0x00, 0x00}; - // Expect a S2 KEX Set when the scheme/key request combination was accepted. - s2_kex_set_frame[3] = expected_scheme; - s2_kex_set_frame[4] = expected_curves; - s2_kex_set_frame[5] = expected_keys; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = s2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(s2_kex_set_frame); - } - - /** This helper function set up an expected Echo KEX report frame to be send (through the mock). +void helper_func_kex_set_frame_expect(uint8_t expected_scheme, + uint8_t expected_curves, + uint8_t expected_keys) +{ + mock_t *p_mock; + static uint8_t s2_kex_set_frame[6] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x00, 0x00, 0x00, 0x00}; + // Expect a S2 KEX Set when the scheme/key request combination was accepted. + s2_kex_set_frame[3] = expected_scheme; + s2_kex_set_frame[4] = expected_curves; + s2_kex_set_frame[5] = expected_keys; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = s2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(s2_kex_set_frame); +} + +/** This helper function set up an expected Echo KEX report frame to be send (through the mock). * param[in] expected_scheme Expected value for scheme field. * param[in] expected_curves Expected value for curves field. * param[in] expected_keys Expected value for keys field. */ - void helper_func_echo_kex_report_frame_expect(uint8_t expected_scheme, uint8_t expected_curves, uint8_t expected_keys) - { - mock_t * p_mock; - // Expect Echo(KEX Report) to be sent. - static uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x00, 0x00, 0x00}; - S2_echo_kex_report_frame[3] = expected_scheme; - S2_echo_kex_report_frame[4] = expected_curves; - S2_echo_kex_report_frame[5] = expected_keys; - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - } - - /** This helper function constructs a KEX Report frame and update p_context */ - void helper_func_kex_report_frame(struct S2 *p_context) - { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // Reserved, csa off, echo off => 0x00 - 0x02, // Supported schemes, Scheme 1 = 1 => 0x02 - 0x01, // Curve25519 support => 0x01 - 0x82}; // Security2, Class 1 key = 1, Security0, Network key = 1 => 0x82 - memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); - p_context->length = sizeof(s2_frame); - s2_conn.class_id = 0xFF; - } - - void helper_func_pub_key_frame(struct S2 *p_context) - { - uint8_t * p_tmp = (uint8_t *)p_context->buf; - p_tmp[0] = COMMAND_CLASS_SECURITY_2; - p_tmp[1] = PUBLIC_KEY_REPORT; - p_tmp[2] = 0x00; - memcpy(&p_tmp[3], m_test_public_key_b, sizeof(m_test_public_key_b)); - p_context->length = 3 + sizeof(m_test_public_key_b); - s2_conn.class_id = 0xFF; - } - - void helper_func_echo_kex_set_frame(struct S2 *p_context) - { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x82}; // This data must be compared to earlier sent data. As long as frames are not defined, this data is unknown. - memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); - p_context->length = sizeof(s2_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - } - - void helper_func_net_key_get_frame(struct S2 *p_context, uint8_t key) - { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, key}; - memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); - p_context->length = sizeof(s2_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - } - - // The context must be updated to net key must be updated when S2 Network Key Set has been tranmitted. - - void helper_func_net_key_verify_frame(struct S2 *p_context, uint8_t key) - { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; - memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); - p_context->length = sizeof(s2_frame); - switch (key) - { - case 0x00: - s2_conn.class_id = 0xFF; - break; - case 0x01: - s2_conn.class_id = 0x00; - break; - case 0x02: - s2_conn.class_id = 0x01; - break; - case 0x04: - s2_conn.class_id = 0x02; - break; - case 0x80: - s2_conn.class_id = UNIT_TEST_NETWORK_KEY; - break; - } - } - - void helper_func_transfer_end_final_frame(struct S2 *p_context) - { - uint8_t s2_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); - p_context->length = sizeof(s2_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - } - - - void helper_func_verify_idle_state(struct S2 *p_context) - { - mock_t * p_mock; - - // No timeout event/node inclusion failure is expected as we are verifying that the system is in idle. - - // After timeout we will issue a node inclusion just to insure we were in idle and that a node - // may be included after timeout. - - if (!mock_call_used_as_stub(TO_STR(S2_send_frame), "s2_extern_mock.c")) - { - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - } - - if (!mock_call_used_as_stub(TO_STR(s2_inclusion_set_timeout), "s2_inclusion_extern_mock.c")) - { - mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; - p_mock->expect_arg[1].value = 1000; - p_mock->return_code.value = 1; - } - - // Node id (first step in inclusion) has been assigned. - // Let's initiate a secure inclusion after the timeout to verify the state of the system. - s2_inclusion_including_start(p_context,&s2_conn); - } - - - - - - - void kex_including_node_state_machine_no_keys(int positive_test) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // // bit 0 is echo field, bit 1 is CSA. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x82};// Requested keys bits. Security 2 class 1, Security 0 network key. - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void helper_func_echo_kex_report_frame_expect(uint8_t expected_scheme, + uint8_t expected_curves, + uint8_t expected_keys) +{ + mock_t *p_mock; + // Expect Echo(KEX Report) to be sent. + static uint8_t S2_echo_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x00, 0x00, 0x00}; + S2_echo_kex_report_frame[3] = expected_scheme; + S2_echo_kex_report_frame[4] = expected_curves; + S2_echo_kex_report_frame[5] = expected_keys; + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); +} + +/** This helper function constructs a KEX Report frame and update p_context */ +void helper_func_kex_report_frame(struct S2 *p_context) +{ + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // Reserved, csa off, echo off => 0x00 + 0x02, // Supported schemes, Scheme 1 = 1 => 0x02 + 0x01, // Curve25519 support => 0x01 + 0x82}; // Security2, Class 1 key = 1, Security0, Network key = 1 => 0x82 + memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); + p_context->length = sizeof(s2_frame); + s2_conn.class_id = 0xFF; +} + +void helper_func_pub_key_frame(struct S2 *p_context) +{ + uint8_t *p_tmp = (uint8_t *)p_context->buf; + p_tmp[0] = COMMAND_CLASS_SECURITY_2; + p_tmp[1] = PUBLIC_KEY_REPORT; + p_tmp[2] = 0x00; + memcpy(&p_tmp[3], m_test_public_key_b, sizeof(m_test_public_key_b)); + p_context->length = 3 + sizeof(m_test_public_key_b); + s2_conn.class_id = 0xFF; +} + +void helper_func_echo_kex_set_frame(struct S2 *p_context) +{ + uint8_t s2_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + 0x82}; // This data must be compared to earlier sent data. As long as frames are not defined, this data is unknown. + memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); + p_context->length = sizeof(s2_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; +} + +void helper_func_net_key_get_frame(struct S2 *p_context, uint8_t key) +{ + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_GET, key}; + memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); + p_context->length = sizeof(s2_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; +} + +// The context must be updated to net key must be updated when S2 Network Key Set has been tranmitted. + +void helper_func_net_key_verify_frame(struct S2 *p_context, uint8_t key) +{ + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_VERIFY}; + memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); + p_context->length = sizeof(s2_frame); + switch (key) { + case 0x00: + s2_conn.class_id = 0xFF; + break; + case 0x01: + s2_conn.class_id = 0x00; + break; + case 0x02: + s2_conn.class_id = 0x01; + break; + case 0x04: + s2_conn.class_id = 0x02; + break; + case 0x80: + s2_conn.class_id = UNIT_TEST_NETWORK_KEY; + break; + } +} + +void helper_func_transfer_end_final_frame(struct S2 *p_context) +{ + uint8_t s2_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + memcpy((uint8_t *)p_context->buf, s2_frame, sizeof(s2_frame)); + p_context->length = sizeof(s2_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; +} + +void helper_func_verify_idle_state(struct S2 *p_context) +{ + mock_t *p_mock; + + // No timeout event/node inclusion failure is expected as we are verifying that the system is in idle. + + // After timeout we will issue a node inclusion just to insure we were in idle and that a node + // may be included after timeout. + + if (!mock_call_used_as_stub(TO_STR(S2_send_frame), "s2_extern_mock.c")) { + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + } + + if (!mock_call_used_as_stub(TO_STR(s2_inclusion_set_timeout), + "s2_inclusion_extern_mock.c")) { + mock_call_expect(TO_STR(s2_inclusion_set_timeout), &p_mock); + p_mock->compare_rule_arg[0] = COMPARE_ANY; + p_mock->expect_arg[1].value = 1000; + p_mock->return_code.value = 1; + } + + // Node id (first step in inclusion) has been assigned. + // Let's initiate a secure inclusion after the timeout to verify the state of the system. + s2_inclusion_including_start(p_context, &s2_conn); +} + +void kex_including_node_state_machine_no_keys(int positive_test) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // // bit 0 is echo field, bit 1 is CSA. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x82}; // Requested keys bits. Security 2 class 1, Security 0 network key. + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -5925,223 +7847,299 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x00, // bit0: echo field, bit1-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - positive_test ? 0x00 : 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. - }; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_obfuscated_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = positive_test ? 0x00 : 0x82; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = positive_test ? 0 : 2; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x82}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - if(positive_test) { - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x00; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - } else { - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event ; - } - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x82; + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x00, // bit0: echo field, bit1-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + positive_test + ? 0x00 + : 0x82 // Keys to exchange, Security2, class 1 - Security0, network key. + }; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_obfuscated_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = positive_test ? 0x00 : 0x82; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length + = positive_test ? 0 : 2; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x01, + 0x02, + 0x01, + 0x82}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + if (positive_test) { + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x00; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + } else { + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x00; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + } + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, positive_test ? 0x00: 0x82, 0x00); - - uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // This should ensure the full public key is available. - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2 - Security0, network key. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, positive_test? 0x00: 0x82}; - - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - - void test_kex_including_node_state_machine_no_keys_pos(void) { - kex_including_node_state_machine_no_keys(1); - } - void test_kex_including_node_state_machine_no_keys_neg(void) { - kex_including_node_state_machine_no_keys(0); - } - - static void helper_func_init_s2_conn(void) - { - s2_conn.l_node = 1; - s2_conn.r_node = 2; - s2_conn.class_id = 0xFF; - s2_conn.rx_options = 0x00; - } - - /* Test what happens when LR end nodes request the Unauthenticated key a.k.a. SWPROT-4909 + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, positive_test ? 0x00 : 0x82, 0x00); + + uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // This should ensure the full public key is available. + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2 - Security0, network key. + uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x01, + 0x02, + 0x01, + positive_test ? 0x00 : 0x82}; + + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +void test_kex_including_node_state_machine_no_keys_pos(void) +{ + kex_including_node_state_machine_no_keys(1); +} +void test_kex_including_node_state_machine_no_keys_neg(void) +{ + kex_including_node_state_machine_no_keys(0); +} + +static void helper_func_init_s2_conn(void) +{ + s2_conn.l_node = 1; + s2_conn.r_node = 2; + s2_conn.class_id = 0xFF; + s2_conn.rx_options = 0x00; +} + +/* Test what happens when LR end nodes request the Unauthenticated key a.k.a. SWPROT-4909 * */ - void test_kex_including_node_LR_unauth_keys(void) { - uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - - uint8_t private_key_a[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; - - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // // bit 0 is echo field, bit 1 is CSA. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x03};// Requested keys bits. Request unauth and auth - - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** +void test_kex_including_node_LR_unauth_keys(void) +{ + uint8_t public_key_a[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, // Public key as being set by upper layer. + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x11, 0x22, 0xAA, 0xBB, + 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; + + uint8_t private_key_a[] + = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // Private key. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, + 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + uint8_t s2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // // bit 0 is echo field, bit 1 is CSA. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x03}; // Requested keys bits. Request unauth and auth + + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -6173,222 +8171,297 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - // Expect a S2 KEX Get to be sent. - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. - // The operator (or including app automatically) can then respond with granted keys. - // Expect that the LR invalid key 0x01 has been filtered out by libs2. - zwave_event_t * p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; - p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; - p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys = 0x02; // 0x01 bit must be filtered out by libs2 - p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_report_event; - - // Expect a S2 KEX Set to be sent. - uint8_t S2_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, - 0x00, // bit0: echo field, bit1-7: Reserved. - 0x02, // Selected schemes: scheme 1. - 0x01, // Selected curve25519 - 0x02 // Keys to exchange, Security2, auth. Unauth has been filtered out since it is not valid for LR - }; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_set_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); - - // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. - // Therefore we copy the key minus header frame into expected data. - zwave_event_t * p_expected_challenge_event = (zwave_event_t *)m_test_mem_pool[1]; - p_expected_challenge_event->event_type = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length = sizeof(m_test_obfuscated_public_key_b); - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys = 0x02; - p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length = 0x02; - memcpy(p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_challenge_event; - - // When the public key is received, we expect a call to the keystore in order to obtain our public key. - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - // Expect Public KeyA to be sent. - uint8_t S2_pub_key_A_frame[] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x01, // Including node bit set - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, // Public key as being set by upper layer. - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; - p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); - - // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. - mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); - p_mock->output_arg[0].pointer = private_key_a; - mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); - p_mock->output_arg[0].pointer = public_key_a; - - - // Expect Echo(KEX Report) to be sent. - uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, 0x01, 0x02, 0x01, 0x03}; // Note: Echo flag set. - - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. - p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); - - //Expect LR Auth key to be read - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; // Just using a random key here, arg0 with the index is what matters - - // Expect Net Key Report to be sent. - uint8_t S2_net_key_report_2_frame[19] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NETWORK_KEY_REPORT, 0x02, }; - memcpy(&S2_net_key_report_2_frame[3], m_test_network_key_s2_class_0, sizeof(m_test_network_key_s2_class_0)); - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; - p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); - - // Expect S2 Transfer End to be sent. - uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x02}; // 0x02 = Key Verified - mock_call_expect(TO_STR(S2_send_data), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_transfer_end_frame; - p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); - - - // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - - zwave_event_t * p_expected_complete_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; - p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete.exchanged_keys = 0x02; - - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_complete_event ; - - /** + mock_t *p_mock; + + // Expect a S2 KEX Get to be sent. + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // When the KEX Report is received, we expect that the event from libs2 contains the key requested in order to present it for the operator. + // The operator (or including app automatically) can then respond with granted keys. + // Expect that the LR invalid key 0x01 has been filtered out by libs2. + zwave_event_t *p_expected_report_event = (zwave_event_t *)m_test_mem_pool[0]; + p_expected_report_event->event_type = S2_NODE_INCLUSION_KEX_REPORT_EVENT; + p_expected_report_event->evt.s2_event.s2_data.kex_report.security_keys + = 0x02; // 0x01 bit must be filtered out by libs2 + p_expected_report_event->evt.s2_event.s2_data.kex_report.csa = 0x00; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_report_event; + + // Expect a S2 KEX Set to be sent. + uint8_t S2_kex_set_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_SET, + 0x00, // bit0: echo field, bit1-7: Reserved. + 0x02, // Selected schemes: scheme 1. + 0x01, // Selected curve25519 + 0x02 // Keys to exchange, Security2, auth. Unauth has been filtered out since it is not valid for LR + }; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_set_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_set_frame); + + // When the public key is received, we expect that the event from libs2 contains the key in order to present it for the operator. + // Therefore we copy the key minus header frame into expected data. + zwave_event_t *p_expected_challenge_event + = (zwave_event_t *)m_test_mem_pool[1]; + p_expected_challenge_event->event_type + = S2_NODE_INCLUSION_PUBLIC_KEY_CHALLENGE_EVENT; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.length + = sizeof(m_test_obfuscated_public_key_b); + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.granted_keys + = 0x02; + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.dsk_length + = 0x02; + memcpy( + p_expected_challenge_event->evt.s2_event.s2_data.challenge_req.public_key, + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_challenge_event; + + // When the public key is received, we expect a call to the keystore in order to obtain our public key. + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Public KeyA to be sent. + uint8_t S2_pub_key_A_frame[] + = {COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x01, // Including node bit set + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, // Public key as being set by upper layer. + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22, + 0xAA, + 0xBB, + 0xCC, + 0xDD, + 0xEE, + 0xFF, + 0x11, + 0x22}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_pub_key_A_frame; + p_mock->expect_arg[3].value = sizeof(S2_pub_key_A_frame); + + // After our public key has been sent, we expect user acceptance of the inclusion, which will result in key updates and key derivation. + mock_call_expect(TO_STR(keystore_private_key_read), &p_mock); + p_mock->output_arg[0].pointer = private_key_a; + mock_call_expect(TO_STR(keystore_public_key_read), &p_mock); + p_mock->output_arg[0].pointer = public_key_a; + + // Expect Echo(KEX Report) to be sent. + uint8_t S2_echo_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x01, + 0x02, + 0x01, + 0x03}; // Note: Echo flag set. + + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer + = S2_echo_kex_report_frame; // Ideally, this should be updated to be identically to replayed received KEX Set. + p_mock->expect_arg[3].value = sizeof(S2_echo_kex_report_frame); + + //Expect LR Auth key to be read + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer + = m_test_network_key_s2_class_0; // Just using a random key here, arg0 with the index is what matters + + // Expect Net Key Report to be sent. + uint8_t S2_net_key_report_2_frame[19] = { + COMMAND_CLASS_SECURITY_2, + SECURITY_2_NETWORK_KEY_REPORT, + 0x02, + }; + memcpy(&S2_net_key_report_2_frame[3], + m_test_network_key_s2_class_0, + sizeof(m_test_network_key_s2_class_0)); + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_net_key_report_2_frame; + p_mock->expect_arg[3].value = sizeof(S2_net_key_report_2_frame); + + // Expect S2 Transfer End to be sent. + uint8_t S2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_TRANSFER_END, + 0x02}; // 0x02 = Key Verified + mock_call_expect(TO_STR(S2_send_data), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_transfer_end_frame; + p_mock->expect_arg[3].value = sizeof(S2_transfer_end_frame); + + // When S2 Transfer End is received, we expect keys to be restored and a corresponding Node inclusion complete event from libs2. + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + zwave_event_t *p_expected_complete_event + = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_complete_event->event_type = S2_NODE_INCLUSION_COMPLETE_EVENT; + p_expected_complete_event->evt.s2_event.s2_data.inclusion_complete + .exchanged_keys + = 0x02; + + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_complete_event; + + /** * Test execution. */ - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_conn.l_node = 1; - s2_conn.r_node = 1000; /* LR inclusion*/ - s2_conn.class_id = 0xFF; - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // KEX Report frame received. - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x02, 0x00); - - uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = {COMMAND_CLASS_SECURITY_2, PUBLIC_KEY_REPORT, 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. - memcpy(&public_key_frame[3], m_test_obfuscated_public_key_b, sizeof(m_test_obfuscated_public_key_b)); - s2_context.buf = public_key_frame; - s2_context.length = sizeof(public_key_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - // This should ensure the full public key is available. - s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); - TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, m_test_public_key_b, sizeof(m_test_public_key_b)); - - // Echo(KEX Set) frame received. - // bit0: echo field set, bit1-7: Reserved. - // Selected schemes: scheme 0 and scheme 2. - // Selected curve25519 - // Keys to exchange, Security2, class 2. Unauth Key was not granted because it is invalid in LR. - uint8_t s2_echo_kex_set_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x02}; - - s2_context.buf = s2_echo_kex_set_frame; - s2_context.length = sizeof(s2_echo_kex_set_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - //Inject the Net Key Get but only for LR Auth - helper_func_net_key_get_frame(&s2_context, 0x02); - s2_inclusion_post_event(&s2_context, &s2_conn); - - // Inject Net Key Verify - helper_func_net_key_verify_frame(&s2_context, 0x02); - s2_conn.class_id = 0x03; /* Slot for LR unauth key class */ - s2_inclusion_post_event(&s2_context, &s2_conn); - - // S2 Transfer end frame received. - // bit0: Key request complete set, - // bit1: Key verified not set, - // bit2-7: Reserved. - uint8_t s2_transfer_end_frame[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; - s2_context.buf = s2_transfer_end_frame; - s2_context.length = sizeof(s2_transfer_end_frame); - s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; - s2_inclusion_post_event(&s2_context, &s2_conn); - - mock_calls_verify(); - } - - - - - /* Test what happens when LR end nodes request the Unauthenticated and S0 key* */ - void test_kex_including_node_LR_unauth_s0_keys(void) - { - mock_calls_clear(); - mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); - mock_call_use_as_stub(TO_STR(curve25519_mock.c)); - mock_call_use_as_stub(TO_STR(kderiv_mock.c)); - - // Stubbed as it is about to be removed. - mock_call_use_as_stub(TO_STR(S2_network_key_update)); - - /** + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_conn.l_node = 1; + s2_conn.r_node = 1000; /* LR inclusion*/ + s2_conn.class_id = 0xFF; + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // KEX Report frame received. + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x02, 0x00); + + uint8_t public_key_frame[3 + sizeof(m_test_obfuscated_public_key_b)] = { + COMMAND_CLASS_SECURITY_2, + PUBLIC_KEY_REPORT, + 0x00}; // Key exchange received from slave - public key for secure exchange of LTK. + memcpy(&public_key_frame[3], + m_test_obfuscated_public_key_b, + sizeof(m_test_obfuscated_public_key_b)); + s2_context.buf = public_key_frame; + s2_context.length = sizeof(public_key_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + // This should ensure the full public key is available. + s2_inclusion_challenge_response(&s2_context, 1, m_test_public_key_b, 2); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2_context.public_key, + m_test_public_key_b, + sizeof(m_test_public_key_b)); + + // Echo(KEX Set) frame received. + // bit0: echo field set, bit1-7: Reserved. + // Selected schemes: scheme 0 and scheme 2. + // Selected curve25519 + // Keys to exchange, Security2, class 2. Unauth Key was not granted because it is invalid in LR. + uint8_t s2_echo_kex_set_frame[] + = {COMMAND_CLASS_SECURITY_2, KEX_SET, 0x01, 0x02, 0x01, 0x02}; + + s2_context.buf = s2_echo_kex_set_frame; + s2_context.length = sizeof(s2_echo_kex_set_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + //Inject the Net Key Get but only for LR Auth + helper_func_net_key_get_frame(&s2_context, 0x02); + s2_inclusion_post_event(&s2_context, &s2_conn); + + // Inject Net Key Verify + helper_func_net_key_verify_frame(&s2_context, 0x02); + s2_conn.class_id = 0x03; /* Slot for LR unauth key class */ + s2_inclusion_post_event(&s2_context, &s2_conn); + + // S2 Transfer end frame received. + // bit0: Key request complete set, + // bit1: Key verified not set, + // bit2-7: Reserved. + uint8_t s2_transfer_end_frame[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_TRANSFER_END, 0x01}; + s2_context.buf = s2_transfer_end_frame; + s2_context.length = sizeof(s2_transfer_end_frame); + s2_conn.class_id = UNIT_TEST_TEMP_KEY_SECURE; + s2_inclusion_post_event(&s2_context, &s2_conn); + + mock_calls_verify(); +} + +/* Test what happens when LR end nodes request the Unauthenticated and S0 key* */ +void test_kex_including_node_LR_unauth_s0_keys(void) +{ + mock_calls_clear(); + mock_call_use_as_stub(TO_STR(s2_inclusion_extern_mock.c)); + mock_call_use_as_stub(TO_STR(curve25519_mock.c)); + mock_call_use_as_stub(TO_STR(kderiv_mock.c)); + + // Stubbed as it is about to be removed. + mock_call_use_as_stub(TO_STR(S2_network_key_update)); + + /** * Test expectation setup. * This section set up the expectations in the system when the inclusion state machine progresses: * 1) Starting in idle it is expected that an S2 frame KEX1 will be transmitted based on external event when a node id has been assigned. @@ -6420,83 +8493,90 @@ * e) Joining node shall reply with a 'Transfer End' if no more keys shall be exchanged. * */ - mock_t * p_mock; - - struct S2 s2_context; - - /*FIXME S2_init_ctx() bomb placed */ - - s2_conn.l_node = 1; - s2_conn.r_node = 1000; /* LR inclusion*/ - s2_conn.class_id = 0xFF; - - s2_context.inclusion_state = S2_INC_IDLE; - s2_inclusion_set_event_handler(s2_event_handler); - - // Expect a S2 KEX Get to be sent from libs2(DUT nodeid 1) to unit test (nodeid 1000). - uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_get_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); - - // Node id (first step in inclusion) has been assigned. - // Continue with secure inclusion. - s2_inclusion_including_start(&s2_context,&s2_conn); - - // Expect inclusion fail event - zwave_event_t * p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; - p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; - p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x01; - mock_call_expect(TO_STR(s2_event_handler), &p_mock); - p_mock->expect_arg[0].pointer = p_expected_event ; - - - // Expect a S2 KEX FAIL to be sent.from libs2(DUT nodeid 1) to unit test (nodeid 1000). - // And it should match following frame - uint8_t S2_kex_fail_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_FAIL, - 0x01, //KEX_FAIL_KEX_KEYS - }; - mock_call_expect(TO_STR(S2_send_frame), &p_mock); - p_mock->compare_rule_arg[0] = COMPARE_ANY; // For the outline, we just expect any/null pointers now. - p_mock->compare_rule_arg[1] = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. - p_mock->expect_arg[2].pointer = S2_kex_fail_frame; - p_mock->expect_arg[3].value = sizeof(S2_kex_fail_frame); - - // When S2 inclusion has failed, we expect keys to be restored - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x01; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x02; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x04; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x08; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); - p_mock->expect_arg[0].value = 0x10; - p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; - - // Inject KEX REPORT from unit test - uint8_t s2_kex_report_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_REPORT, - 0x00, // // bit 0 is echo field, bit 1 is CSA. - 0x02, // Supported schemes. Scheme 1. - 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. - 0x81};// Requested keys bits. Request unauth and auth - s2_context.buf = s2_kex_report_frame; - s2_context.length = sizeof(s2_kex_report_frame); - s2_conn.class_id = 0xFF; - s2_inclusion_post_event(&s2_context, &s2_conn); - - s2_inclusion_key_grant(&s2_context, 1, 0x00, 0x00); - - mock_calls_verify(); - } \ No newline at end of file + mock_t *p_mock; + + struct S2 s2_context; + + /*FIXME S2_init_ctx() bomb placed */ + + s2_conn.l_node = 1; + s2_conn.r_node = 1000; /* LR inclusion*/ + s2_conn.class_id = 0xFF; + + s2_context.inclusion_state = S2_INC_IDLE; + s2_inclusion_set_event_handler(s2_event_handler); + + // Expect a S2 KEX Get to be sent from libs2(DUT nodeid 1) to unit test (nodeid 1000). + uint8_t S2_kex_get_frame[] = {COMMAND_CLASS_SECURITY_2, KEX_GET}; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_get_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_get_frame); + + // Node id (first step in inclusion) has been assigned. + // Continue with secure inclusion. + s2_inclusion_including_start(&s2_context, &s2_conn); + + // Expect inclusion fail event + zwave_event_t *p_expected_event = (zwave_event_t *)m_test_mem_pool[2]; + p_expected_event->event_type = S2_NODE_INCLUSION_FAILED_EVENT; + p_expected_event->evt.s2_event.s2_data.inclusion_fail.kex_fail_type = 0x01; + mock_call_expect(TO_STR(s2_event_handler), &p_mock); + p_mock->expect_arg[0].pointer = p_expected_event; + + // Expect a S2 KEX FAIL to be sent.from libs2(DUT nodeid 1) to unit test (nodeid 1000). + // And it should match following frame + uint8_t S2_kex_fail_frame[] = { + COMMAND_CLASS_SECURITY_2, + KEX_FAIL, + 0x01, //KEX_FAIL_KEX_KEYS + }; + mock_call_expect(TO_STR(S2_send_frame), &p_mock); + p_mock->compare_rule_arg[0] + = COMPARE_ANY; // For the outline, we just expect any/null pointers now. + p_mock->compare_rule_arg[1] + = COMPARE_NOT_NULL; // This shall be updated once excact frame is defined for S2 frames. + p_mock->expect_arg[2].pointer = S2_kex_fail_frame; + p_mock->expect_arg[3].value = sizeof(S2_kex_fail_frame); + + // When S2 inclusion has failed, we expect keys to be restored + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x01; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_0; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x02; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_1; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x04; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x08; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + mock_call_expect(TO_STR(keystore_network_key_read), &p_mock); + p_mock->expect_arg[0].value = 0x10; + p_mock->output_arg[1].pointer = m_test_network_key_s2_class_2; + + // Inject KEX REPORT from unit test + uint8_t s2_kex_report_frame[] + = {COMMAND_CLASS_SECURITY_2, + KEX_REPORT, + 0x00, // // bit 0 is echo field, bit 1 is CSA. + 0x02, // Supported schemes. Scheme 1. + 0x01, // Supported ECDH Profiles, bit0=1 is curve 25519 value. + 0x81}; // Requested keys bits. Request unauth and auth + s2_context.buf = s2_kex_report_frame; + s2_context.length = sizeof(s2_kex_report_frame); + s2_conn.class_id = 0xFF; + s2_inclusion_post_event(&s2_context, &s2_conn); + + s2_inclusion_key_grant(&s2_context, 1, 0x00, 0x00); + + mock_calls_verify(); +} \ No newline at end of file diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_callbacks.h b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_callbacks.h index 1aa0e7e25..b3b8e5e28 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_callbacks.h +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_callbacks.h @@ -27,12 +27,12 @@ extern "C" { void on_inclusion_started(); void on_inclusion_complete(zwave_keyset_t granted_keys, - zwave_kex_fail_type_t kex_fail_code); + zwave_kex_fail_type_t kex_fail_code); void on_keys_request(zwave_keyset_t requested_keys, bool csa); void on_dsk_challenge(zwave_keyset_t granted_keys, - int num_blank_bytes, - zwave_dsk_t dsk); + int num_blank_bytes, + zwave_dsk_t dsk); #ifdef __cplusplus } diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_test.c b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_test.c index 860d9f8c8..6d8e875cf 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_network_test.c @@ -77,7 +77,7 @@ static void void test_s2_network_init() { - uint8_t nls_state = false; + uint8_t nls_state = false; uint8_t nls_support = false; S2_destroy_Expect(s2_ctx); @@ -140,20 +140,20 @@ void test_s2_network_callbacks() uint8_t buff[100] = {0}; zwave_event_t *ev = (zwave_event_t *)buff; zwave_dsk_t dsk = { - 0, - 0, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, - 0x1, + 0, + 0, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, }; zwave_s2_network_callbacks_t cb = {.on_inclusion_started = on_inclusion_started, diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_nonce_management_test.c b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_nonce_management_test.c index 739d38d58..e545f7358 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_nonce_management_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_nonce_management_test.c @@ -93,7 +93,6 @@ void test_zwave_s2_nonce_management_get_span_data() sizeof(span_data.key)); zwave_s2_reset_span(node_id); TEST_ASSERT_EQUAL(test_ctx.span_table[1].state, SPAN_NOT_USED); - } void test_zwave_s2_nonce_management_zwave_s2_set_span_table() diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_protocol.c b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_protocol.c index d56f9f73c..40502515a 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_protocol.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_protocol.c @@ -7,13 +7,13 @@ * Author: aes */ #include "unity.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#define ZW_CONTROLLER // defined type definitions match the S2 library we are unit testing +#define ZW_CONTROLLER // defined type definitions match the S2 library we are unit testing #include "../include/S2.h" #include "../include/s2_protocol.h" #include "../include/s2_keystore.h" @@ -24,14 +24,14 @@ extern int verbose; -#define TIMER_STOPPED -1; /**< Special value used by struct test_state field timeout_value */ +#define TIMER_STOPPED \ + -1; /**< Special value used by struct test_state field timeout_value */ -struct test_state -{ - uint8_t frame[1280+8+4]; +struct test_state { + uint8_t frame[1280 + 8 + 4]; uint16_t frame_len; - int fcount; //number of frames sent + int fcount; //number of frames sent int timeout_value; @@ -56,103 +56,124 @@ struct test_state bool S2_nls_node_list_report_nls_state; bool S2_nls_node_list_report_called; - int send_data_return_fail; //Make send_data return fail + int send_data_return_fail; //Make send_data return fail uint8_t rx_frame[1280]; uint16_t rx_frame_len; - s2_connection_t last_trans; //The last transaction reversed + s2_connection_t last_trans; //The last transaction reversed struct { - uint16_t count; // Count of S2 Synchronization Events received - uint8_t reason; // The latest reason value received - node_t remote_node; // Remote node ID of the latest S2 Synchronization event + uint16_t count; // Count of S2 Synchronization Events received + uint8_t reason; // The latest reason value received + node_t + remote_node; // Remote node ID of the latest S2 Synchronization event uint8_t seqno; node_t local_node; } sync_ev; } ts; -uint8_t S2_send_frame_multi(struct S2* ctxt,s2_connection_t *peer, uint8_t* buf, uint16_t len) { - - - if(verbose) { - printf("********** MULTICAST ***************\n"); +uint8_t S2_send_frame_multi(struct S2 *ctxt, + s2_connection_t *peer, + uint8_t *buf, + uint16_t len) +{ + if (verbose) { + printf("********** MULTICAST ***************\n"); } - return S2_send_frame(ctxt,peer,buf,len); + return S2_send_frame(ctxt, peer, buf, len); } - -uint8_t -S2_send_frame_no_cb(struct S2* ctxt, const s2_connection_t* dst, uint8_t* buf, uint16_t len) +uint8_t S2_send_frame_no_cb(struct S2 *ctxt, + const s2_connection_t *dst, + uint8_t *buf, + uint16_t len) { - return S2_send_frame(ctxt,dst,buf,len); + return S2_send_frame(ctxt, dst, buf, len); } - -uint8_t -S2_send_frame(struct S2* ctxt, const s2_connection_t* dst, uint8_t* buf, uint16_t len) +uint8_t S2_send_frame(struct S2 *ctxt, + const s2_connection_t *dst, + uint8_t *buf, + uint16_t len) { - int i; s2_connection_t swap; - if(verbose) { -#if defined (SINGLE_CONTEXT) - printf("Sending %02u -> %02u (len %04u) : ", dst->l_node, dst->r_node,len); + if (verbose) { +#if defined(SINGLE_CONTEXT) + printf("Sending %02u -> %02u (len %04u) : ", + dst->l_node, + dst->r_node, + len); #else - printf("Sending %p %02u -> %02u (len %04u) : ", ctxt, dst->l_node, dst->r_node,len); + printf("Sending %p %02u -> %02u (len %04u) : ", + ctxt, + dst->l_node, + dst->r_node, + len); #endif - for (i = 0; i < len; i++) - { - printf("%02X", buf[i]); - } - printf("\n"); + for (i = 0; i < len; i++) { + printf("%02X", buf[i]); + } + printf("\n"); } - TEST_ASSERT(len < 1280+8+4); + TEST_ASSERT(len < 1280 + 8 + 4); - if (ts.send_data_return_fail) - { - if(verbose) printf("making send_data return fail\n"); - return 0; - } + if (ts.send_data_return_fail) { + if (verbose) + printf("making send_data return fail\n"); + return 0; + } memcpy(ts.frame, buf, len); ts.frame_len = len; ts.fcount++; - swap = *dst; + swap = *dst; ts.last_trans.l_node = swap.r_node; ts.last_trans.r_node = swap.l_node; return 1; } -void S2_notify_nls_state_report(node_t srcNode, uint8_t class_id, bool nls_capability, bool nls_state) +void S2_notify_nls_state_report(node_t srcNode, + uint8_t class_id, + bool nls_capability, + bool nls_state) { ts.S2_notify_nls_state_report_nls_capability = nls_capability; - ts.S2_notify_nls_state_report_nls_state = nls_state; - ts.S2_notify_nls_state_report_called = true; + ts.S2_notify_nls_state_report_nls_state = nls_state; + ts.S2_notify_nls_state_report_called = true; } -int8_t S2_get_nls_node_list(node_t srcNode, bool request, bool *is_last_node, uint16_t *node_id, uint8_t *granted_keys, bool *nls_state) +int8_t S2_get_nls_node_list(node_t srcNode, + bool request, + bool *is_last_node, + uint16_t *node_id, + uint8_t *granted_keys, + bool *nls_state) { ts.S2_nls_node_list_get_request = request; - ts.S2_nls_node_list_get_called = true; + ts.S2_nls_node_list_get_called = true; *is_last_node = ts.S2_nls_node_list_get_is_last_node; - *node_id = ts.S2_nls_node_list_get_node_id; + *node_id = ts.S2_nls_node_list_get_node_id; *granted_keys = ts.S2_nls_node_list_get_granted_keys; - *nls_state = ts.S2_nls_node_list_nls_state; + *nls_state = ts.S2_nls_node_list_nls_state; return 0; } -int8_t S2_notify_nls_node_list_report(node_t srcNode, uint16_t id_of_node, uint8_t keys_node_bitmask, bool nls_state) +int8_t S2_notify_nls_node_list_report(node_t srcNode, + uint16_t id_of_node, + uint8_t keys_node_bitmask, + bool nls_state) { - ts.S2_nls_node_list_report_id_of_node = id_of_node; + ts.S2_nls_node_list_report_id_of_node = id_of_node; ts.S2_nls_node_list_report_keys_node_bitmask = keys_node_bitmask; - ts.S2_nls_node_list_report_nls_state = nls_state; - ts.S2_nls_node_list_report_called = true; + ts.S2_nls_node_list_report_nls_state = nls_state; + ts.S2_nls_node_list_report_called = true; return 0; } @@ -162,119 +183,166 @@ void S2_save_nls_state(void) ts.S2_save_nls_state_called = true; } -void -S2_set_timeout(struct S2* ctxt, uint32_t interval) +void S2_set_timeout(struct S2 *ctxt, uint32_t interval) { //ctxt = ctxt; - if(verbose) printf("Timer set on interval %lu\n", (long unsigned)interval); + if (verbose) + printf("Timer set on interval %lu\n", (long unsigned)interval); ts.timeout_value = interval; } -void -S2_stop_timeout(struct S2* ctxt) +void S2_stop_timeout(struct S2 *ctxt) { //ctxt = ctxt; - if(verbose) printf("Timer stopped\n"); + if (verbose) + printf("Timer stopped\n"); ts.timeout_value = TIMER_STOPPED; } -void -S2_send_done_event(struct S2* ctxt, s2_tx_status_t status) +void S2_send_done_event(struct S2 *ctxt, s2_tx_status_t status) { //ctxt=ctxt; - if(verbose) printf("S2 send done status %d\n", (int)status); + if (verbose) + printf("S2 send done status %d\n", (int)status); ts.s2_send_done++; ts.s2_send_status = status; } -void -S2_msg_received_event(struct S2* ctxt, s2_connection_t* src, uint8_t* buf, uint16_t len) +void S2_msg_received_event(struct S2 *ctxt, + s2_connection_t *src, + uint8_t *buf, + uint16_t len) { //int i; //ctxt = ctxt; - if(verbose) { - printf("Message received. from %d -> %d\n ", src->r_node, src->l_node); - puts((char*)buf); - /*for (i = 0; i < len; i++) + if (verbose) { + printf("Message received. from %d -> %d\n ", src->r_node, src->l_node); + puts((char *)buf); + /*for (i = 0; i < len; i++) { printf("%02X", buf[i]); } printf("\n");*/ - } memcpy(ts.rx_frame, buf, len); ts.rx_frame_len = len; } -void -S2_get_hw_random(uint8_t* rnd,uint8_t len) +void S2_get_hw_random(uint8_t *rnd, uint8_t len) { int i; - for (i = 0; i < len; i++) - { - rnd[i] = rand() % 0xFF; - } + for (i = 0; i < len; i++) { + rnd[i] = rand() % 0xFF; + } } -void S2_get_commands_supported(node_t lnode,uint8_t class_id, const uint8_t ** cmdClasses, uint8_t* length) { +void S2_get_commands_supported(node_t lnode, + uint8_t class_id, + const uint8_t **cmdClasses, + uint8_t *length) +{ static uint8_t cmd_classes[] = {COMMAND_CLASS_SECURITY_2}; - *length = sizeof(cmd_classes); - *cmdClasses = cmd_classes; + *length = sizeof(cmd_classes); + *cmdClasses = cmd_classes; } -void S2_resynchronization_event( - node_t remote_node, - sos_event_reason_t reason, - uint8_t seqno, - node_t local_node) +void S2_resynchronization_event(node_t remote_node, + sos_event_reason_t reason, + uint8_t seqno, + node_t local_node) { ts.sync_ev.count++; - ts.sync_ev.reason = reason; - ts.sync_ev.seqno = seqno; + ts.sync_ev.reason = reason; + ts.sync_ev.seqno = seqno; ts.sync_ev.remote_node = remote_node; - ts.sync_ev.local_node = local_node; + ts.sync_ev.local_node = local_node; } //---------------- global test state --------------------- -s2_connection_t conn12 = - { 1, 2 }; //Sending form node 1 to 2 -s2_connection_t conn21 = - { 2, 1 }; //Sending form node 2 to 1 - -s2_connection_t conn13 = - { 1, 3 }; //Sending form node 1 to 3 -s2_connection_t conn31 = - { 3, 1 }; //Sending form node 3 to 1 +s2_connection_t conn12 = {1, 2}; //Sending form node 1 to 2 +s2_connection_t conn21 = {2, 1}; //Sending form node 2 to 1 +s2_connection_t conn13 = {1, 3}; //Sending form node 1 to 3 +s2_connection_t conn31 = {3, 1}; //Sending form node 3 to 1 /* * Test that we a able to send a message from once instance to another */ -const uint8_t key[] = - { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, }; - -const uint8_t key2[] = {0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,}; - -const uint8_t key3[] = {0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,}; - -const char hello[] = "HelloWorld"; -const uint8_t nonce_get[] = - { COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_GET, 0 }; -const uint8_t nonce_report[] = - { COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_REPORT }; - -const uint8_t commands_supported_report[] = {COMMAND_CLASS_SECURITY_2,SECURITY_2_COMMANDS_SUPPORTED_REPORT,COMMAND_CLASS_SECURITY_2}; - -struct S2* ctx1; -struct S2* ctx2; -struct S2* ctx3; - -static void -my_setup(void) +const uint8_t key[] = { + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, +}; + +const uint8_t key2[] = { + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, + 0xab, +}; + +const uint8_t key3[] = { + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, + 0xac, +}; + +const char hello[] = "HelloWorld"; +const uint8_t nonce_get[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_GET, 0}; +const uint8_t nonce_report[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_REPORT}; + +const uint8_t commands_supported_report[] + = {COMMAND_CLASS_SECURITY_2, + SECURITY_2_COMMANDS_SUPPORTED_REPORT, + COMMAND_CLASS_SECURITY_2}; + +struct S2 *ctx1; +struct S2 *ctx2; +struct S2 *ctx3; + +static void my_setup(void) { srand(0x44); //reset test state @@ -282,35 +350,34 @@ my_setup(void) conn12.tx_options = 0; conn21.tx_options = 0; - if(ctx1) { - S2_destroy(ctx1); + if (ctx1) { + S2_destroy(ctx1); } - ctx1 = S2_init_ctx( 0xAABBCCDD); + ctx1 = S2_init_ctx(0xAABBCCDD); - if(ctx2) { - S2_destroy(ctx2); + if (ctx2) { + S2_destroy(ctx2); } - ctx2 = S2_init_ctx( 0xAABBCCDD); + ctx2 = S2_init_ctx(0xAABBCCDD); - if(ctx3) { - S2_destroy(ctx3); + if (ctx3) { + S2_destroy(ctx3); } - ctx3 = S2_init_ctx( 0xAABBCCDD); + ctx3 = S2_init_ctx(0xAABBCCDD); S2_init_prng(); - S2_network_key_update(ctx1,ZWAVE_KEY_ID_NONE,0,key,0, false); - S2_network_key_update(ctx2,ZWAVE_KEY_ID_NONE,0,key,0, false); - S2_network_key_update(ctx3,ZWAVE_KEY_ID_NONE,0,key,0, false); - - S2_network_key_update(ctx1,ZWAVE_KEY_ID_NONE,1,key2,0, false); - S2_network_key_update(ctx2,ZWAVE_KEY_ID_NONE,1,key2,0, false); - S2_network_key_update(ctx3,ZWAVE_KEY_ID_NONE,1,key2,0, false); + S2_network_key_update(ctx1, ZWAVE_KEY_ID_NONE, 0, key, 0, false); + S2_network_key_update(ctx2, ZWAVE_KEY_ID_NONE, 0, key, 0, false); + S2_network_key_update(ctx3, ZWAVE_KEY_ID_NONE, 0, key, 0, false); - S2_network_key_update(ctx1,ZWAVE_KEY_ID_NONE,2,key3,0, false); - S2_network_key_update(ctx2,ZWAVE_KEY_ID_NONE,2,key3,0, false); - S2_network_key_update(ctx3,ZWAVE_KEY_ID_NONE,2,key3,0, false); + S2_network_key_update(ctx1, ZWAVE_KEY_ID_NONE, 1, key2, 0, false); + S2_network_key_update(ctx2, ZWAVE_KEY_ID_NONE, 1, key2, 0, false); + S2_network_key_update(ctx3, ZWAVE_KEY_ID_NONE, 1, key2, 0, false); + S2_network_key_update(ctx1, ZWAVE_KEY_ID_NONE, 2, key3, 0, false); + S2_network_key_update(ctx2, ZWAVE_KEY_ID_NONE, 2, key3, 0, false); + S2_network_key_update(ctx3, ZWAVE_KEY_ID_NONE, 2, key3, 0, false); } void setUp(void) @@ -320,42 +387,45 @@ void setUp(void) void tearDownSuite(void) { - if(ctx1) { + if (ctx1) { S2_destroy(ctx1); ctx1 = NULL; } - if(ctx2) { + if (ctx2) { S2_destroy(ctx2); ctx2 = NULL; } - if(ctx3) { + if (ctx3) { S2_destroy(ctx3); ctx3 = NULL; } } /*In general we should valgrind to make sure there is no buffer overruns*/ - -void wrap_test_s2_send_data(struct S2* ctx_dest, s2_connection_t* dst) +void wrap_test_s2_send_data(struct S2 *ctx_dest, s2_connection_t *dst) { - ts.fcount = 0; - ts.s2_send_done =0; - S2_send_data(ctx1, dst, (uint8_t*) hello, sizeof(hello)); + ts.fcount = 0; + ts.s2_send_done = 0; + S2_send_data(ctx1, dst, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ - S2_application_command_handler(ctx_dest, &ts.last_trans, ts.frame, ts.frame_len); + S2_application_command_handler(ctx_dest, + &ts.last_trans, + ts.frame, + ts.frame_len); /*Expect that we get a nonce report*/ TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - S2_send_frame_done_notify(ctx_dest, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx_dest, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx1*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -364,21 +434,29 @@ void wrap_test_s2_send_data(struct S2* ctx_dest, s2_connection_t* dst) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); //Check we got a send done event + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, + ts.s2_send_status); //Check we got a send done event /*Send the frame to ctx2*/ - S2_application_command_handler(ctx_dest, &ts.last_trans, ts.frame, ts.frame_len); + S2_application_command_handler(ctx_dest, + &ts.last_trans, + ts.frame, + ts.frame_len); TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -399,11 +477,11 @@ void test_s2_send_data(void) my_setup(); wrap_test_s2_send_data(ctx2, &conn12); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - - /** * Test that we can use single frame transmissions once SPAN * has been established. @@ -417,22 +495,24 @@ void test_single_frame_transmission(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -448,14 +528,15 @@ void test_secondary_controller_joining_to_network_happy_case(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; /* --- step 1 (NLS_STATE_SET_V2 from primary to secondary controller) --- */ // Primary controller sends an encapsulated NLS_STATE_SET_V2 frame - uint8_t nls_state = 1; // enable NLS - uint8_t nls_state_set[] = {COMMAND_CLASS_SECURITY_2, NLS_STATE_SET_V2, nls_state}; + uint8_t nls_state = 1; // enable NLS + uint8_t nls_state_set[] + = {COMMAND_CLASS_SECURITY_2, NLS_STATE_SET_V2, nls_state}; S2_send_data(ctx1, &conn12, (uint8_t *)nls_state_set, sizeof(nls_state_set)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -465,11 +546,15 @@ void test_secondary_controller_joining_to_network_happy_case(void) // Secondary controller receives the encapsulated NLS_STATE_SET_V2 frame S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(1, ctx2->nls_state); // Test the flag in the context of secondary controller + TEST_ASSERT_EQUAL( + 1, + ctx2->nls_state); // Test the flag in the context of secondary controller TEST_ASSERT_EQUAL(true, ts.S2_save_nls_state_called); // Test callback TEST_ASSERT_EQUAL(1, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test /* --- step 2 (NLS_STATE_GET_V2 from primary to secondary controller) --- */ @@ -485,7 +570,8 @@ void test_secondary_controller_joining_to_network_happy_case(void) // Secondary controller receives the encapsulated NLS_STATE_GET_V2 frame S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(true, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(true, + ctx2->delayed_transmission_flags.send_nls_node_list_get); /* --- step 3 (NLS_STATE_REPORT_V2 from secondary to primary controller) --- */ @@ -507,7 +593,9 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(true, ts.S2_notify_nls_state_report_nls_state); TEST_ASSERT_EQUAL(3, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test // Secondary controller receives an ack following to the transmitted encapsulated NLS_STATE_REPORT_V2 frame S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); @@ -515,7 +603,8 @@ void test_secondary_controller_joining_to_network_happy_case(void) /* --- step 4 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -529,9 +618,9 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); ts.S2_nls_node_list_get_is_last_node = false; - ts.S2_nls_node_list_get_node_id = 4; + ts.S2_nls_node_list_get_node_id = 4; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(true, ts.S2_nls_node_list_get_called); @@ -546,7 +635,9 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(5, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); @@ -557,14 +648,18 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 6 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -577,9 +672,9 @@ void test_secondary_controller_joining_to_network_happy_case(void) // Primary controller receives the encapsulated NLS_NODE_LIST_GET_V2 frame ts.S2_nls_node_list_get_is_last_node = false; - ts.S2_nls_node_list_get_node_id = 5; + ts.S2_nls_node_list_get_node_id = 5; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -596,13 +691,15 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(7, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); - ts.S2_nls_node_list_report_called = 0; - ts.S2_nls_node_list_report_id_of_node = 0; + ts.S2_nls_node_list_report_called = 0; + ts.S2_nls_node_list_report_id_of_node = 0; ts.S2_nls_node_list_report_keys_node_bitmask = 0; - ts.S2_nls_node_list_report_nls_state = false; + ts.S2_nls_node_list_report_nls_state = false; // Secondary controller receives the encapsulated NLS_NODE_LIST_REPORT_V2 frame TEST_ASSERT_EQUAL(0, ts.S2_nls_node_list_report_called); @@ -611,14 +708,18 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 8 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -631,9 +732,9 @@ void test_secondary_controller_joining_to_network_happy_case(void) // Primary controller receives the encapsulated NLS_NODE_LIST_GET_V2 frame ts.S2_nls_node_list_get_is_last_node = true; - ts.S2_nls_node_list_get_node_id = 6; + ts.S2_nls_node_list_get_node_id = 6; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(true, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -650,13 +751,15 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(9, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); - ts.S2_nls_node_list_report_called = 0; - ts.S2_nls_node_list_report_id_of_node = 0; + ts.S2_nls_node_list_report_called = 0; + ts.S2_nls_node_list_report_id_of_node = 0; ts.S2_nls_node_list_report_keys_node_bitmask = 0; - ts.S2_nls_node_list_report_nls_state = false; + ts.S2_nls_node_list_report_nls_state = false; // Secondary controller receives the encapsulated NLS_NODE_LIST_REPORT_V2 frame TEST_ASSERT_EQUAL(0, ts.S2_nls_node_list_report_called); @@ -665,9 +768,12 @@ void test_secondary_controller_joining_to_network_happy_case(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 10 (Secondary controller gets last_node flag finally and does not re-initiate another NLS_NODE_LIST_GET_v2) --- */ @@ -689,14 +795,15 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; /* --- step 1 (NLS_STATE_SET_V2 from primary to secondary controller) --- */ // Primary controller sends an encapsulated NLS_STATE_SET_V2 frame - uint8_t nls_state = 1; // enable NLS - uint8_t nls_state_set[] = {COMMAND_CLASS_SECURITY_2, NLS_STATE_SET_V2, nls_state}; + uint8_t nls_state = 1; // enable NLS + uint8_t nls_state_set[] + = {COMMAND_CLASS_SECURITY_2, NLS_STATE_SET_V2, nls_state}; S2_send_data(ctx1, &conn12, (uint8_t *)nls_state_set, sizeof(nls_state_set)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -706,11 +813,15 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) // Secondary controller receives the encapsulated NLS_STATE_SET_V2 frame S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(1, ctx2->nls_state); // Test the flag in the context of secondary controller + TEST_ASSERT_EQUAL( + 1, + ctx2->nls_state); // Test the flag in the context of secondary controller TEST_ASSERT_EQUAL(true, ts.S2_save_nls_state_called); // Test callback TEST_ASSERT_EQUAL(1, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test /* --- step 2 (NLS_STATE_GET_V2 from primary to secondary controller) --- */ @@ -726,7 +837,8 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) // Secondary controller receives the encapsulated NLS_STATE_GET_V2 frame S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(true, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(true, + ctx2->delayed_transmission_flags.send_nls_node_list_get); /* --- step 3 (NLS_STATE_REPORT_V2 from secondary to primary controller) --- */ @@ -748,7 +860,9 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(true, ts.S2_notify_nls_state_report_nls_state); TEST_ASSERT_EQUAL(3, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test // Secondary controller receives an ack following to the transmitted encapsulated NLS_STATE_REPORT_V2 frame S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); @@ -756,7 +870,8 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) /* --- step 4 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -770,17 +885,23 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); ts.S2_nls_node_list_get_is_last_node = false; - ts.S2_nls_node_list_get_node_id = 4; + ts.S2_nls_node_list_get_node_id = 4; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(SENDING_MSG, ctx1->fsm); - TEST_ASSERT_EQUAL(0, ctx1->delayed_transmission_flags.send_nls_node_list_report); + TEST_ASSERT_EQUAL(0, + ctx1->delayed_transmission_flags.send_nls_node_list_report); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(1, ctx1->delayed_transmission_flags.send_nls_node_list_report); + TEST_ASSERT_EQUAL(1, + ctx1->delayed_transmission_flags.send_nls_node_list_report); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(true, ts.S2_nls_node_list_get_called); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); // Receive the ack of the encapsulated NLS_STATE_GET_V2 frame - TEST_ASSERT_EQUAL(0, ctx1->delayed_transmission_flags.send_nls_node_list_report); + S2_send_frame_done_notify( + ctx1, + S2_TRANSMIT_COMPLETE_OK, + 0x42); // Receive the ack of the encapsulated NLS_STATE_GET_V2 frame + TEST_ASSERT_EQUAL(0, + ctx1->delayed_transmission_flags.send_nls_node_list_report); TEST_ASSERT_EQUAL(SENDING_MSG, ctx1->fsm); S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); @@ -794,7 +915,9 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(5, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); @@ -809,10 +932,16 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); // Receive the ack of the encapsulated NLS_NODE_LIST_GET_V2 frame + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); + S2_send_frame_done_notify( + ctx2, + S2_TRANSMIT_COMPLETE_OK, + 0x42); // Receive the ack of the encapsulated NLS_NODE_LIST_GET_V2 frame TEST_ASSERT_EQUAL(0, ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); @@ -832,9 +961,9 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) // Primary controller receives the encapsulated NLS_NODE_LIST_GET_V2 frame ts.S2_nls_node_list_get_is_last_node = false; - ts.S2_nls_node_list_get_node_id = 5; + ts.S2_nls_node_list_get_node_id = 5; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -851,13 +980,15 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(7, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); - ts.S2_nls_node_list_report_called = 0; - ts.S2_nls_node_list_report_id_of_node = 0; + ts.S2_nls_node_list_report_called = 0; + ts.S2_nls_node_list_report_id_of_node = 0; ts.S2_nls_node_list_report_keys_node_bitmask = 0; - ts.S2_nls_node_list_report_nls_state = false; + ts.S2_nls_node_list_report_nls_state = false; // Secondary controller receives the encapsulated NLS_NODE_LIST_REPORT_V2 frame TEST_ASSERT_EQUAL(0, ts.S2_nls_node_list_report_called); @@ -866,14 +997,18 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 8 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -886,9 +1021,9 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) // Primary controller receives the encapsulated NLS_NODE_LIST_GET_V2 frame ts.S2_nls_node_list_get_is_last_node = true; - ts.S2_nls_node_list_get_node_id = 6; + ts.S2_nls_node_list_get_node_id = 6; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(true, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -905,13 +1040,15 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(9, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); - ts.S2_nls_node_list_report_called = 0; - ts.S2_nls_node_list_report_id_of_node = 0; + ts.S2_nls_node_list_report_called = 0; + ts.S2_nls_node_list_report_id_of_node = 0; ts.S2_nls_node_list_report_keys_node_bitmask = 0; - ts.S2_nls_node_list_report_nls_state = false; + ts.S2_nls_node_list_report_nls_state = false; // Secondary controller receives the encapsulated NLS_NODE_LIST_REPORT_V2 frame TEST_ASSERT_EQUAL(0, ts.S2_nls_node_list_report_called); @@ -920,9 +1057,12 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 10 (Secondary controller gets last_node flag finally and does not re-initiate another NLS_NODE_LIST_GET_v2) --- */ @@ -935,20 +1075,22 @@ void test_secondary_controller_joining_to_network_delayed_transmissions(void) * an irrelevant packet instead of the ack. Luckily, the secondary controller is still able to receive the ack * after the irrelevant packet reception and the flow continues as expected. */ -void test_secondary_controller_joining_to_network_nls_state_report_ack_received_after_irrelevent_packet_reception(void) +void test_secondary_controller_joining_to_network_nls_state_report_ack_received_after_irrelevent_packet_reception( + void) { test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; /* --- step 1 (NLS_STATE_SET_V2 from primary to secondary controller) --- */ // Primary controller sends an encapsulated NLS_STATE_SET_V2 frame - uint8_t nls_state = 1; // enable NLS - uint8_t nls_state_set[] = {COMMAND_CLASS_SECURITY_2, NLS_STATE_SET_V2, nls_state}; + uint8_t nls_state = 1; // enable NLS + uint8_t nls_state_set[] + = {COMMAND_CLASS_SECURITY_2, NLS_STATE_SET_V2, nls_state}; S2_send_data(ctx1, &conn12, (uint8_t *)nls_state_set, sizeof(nls_state_set)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -958,11 +1100,15 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ // Secondary controller receives the encapsulated NLS_STATE_SET_V2 frame S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(1, ctx2->nls_state); // Test the flag in the context of secondary controller + TEST_ASSERT_EQUAL( + 1, + ctx2->nls_state); // Test the flag in the context of secondary controller TEST_ASSERT_EQUAL(true, ts.S2_save_nls_state_called); // Test callback TEST_ASSERT_EQUAL(1, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test /* --- step 2 (NLS_STATE_GET_V2 from primary to secondary controller) --- */ @@ -978,7 +1124,8 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ // Secondary controller receives the encapsulated NLS_STATE_GET_V2 frame S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(true, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(true, + ctx2->delayed_transmission_flags.send_nls_node_list_get); /* --- step 3 (NLS_STATE_REPORT_V2 from secondary to primary controller) --- */ @@ -1000,17 +1147,25 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(true, ts.S2_notify_nls_state_report_nls_state); TEST_ASSERT_EQUAL(3, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test /* --- step 3.1 (Secondary controller gets an irrelevant packet instead of the ack) --- */ // Irrelevant packet triggers a transmission of SECURITY_2_NONCE_REPORT frame without a need for an ack TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); - uint8_t inject_frame[]="irrelevant packet"; - inject_frame[0] = COMMAND_CLASS_SECURITY_2; - inject_frame[1] = SECURITY_2_NONCE_GET; - S2_application_command_handler(ctx2, &conn31, inject_frame, sizeof(inject_frame)); - TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); // We're still lucky that state machine is still in the same state + uint8_t inject_frame[] = "irrelevant packet"; + inject_frame[0] = COMMAND_CLASS_SECURITY_2; + inject_frame[1] = SECURITY_2_NONCE_GET; + S2_application_command_handler(ctx2, + &conn31, + inject_frame, + sizeof(inject_frame)); + TEST_ASSERT_EQUAL( + SENDING_MSG, + ctx2 + ->fsm); // We're still lucky that state machine is still in the same state /* --- step 3.2 (Secondary controller finally receives the ack it is waiting) --- */ @@ -1021,7 +1176,8 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ /* --- step 4 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -1035,9 +1191,9 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); ts.S2_nls_node_list_get_is_last_node = false; - ts.S2_nls_node_list_get_node_id = 4; + ts.S2_nls_node_list_get_node_id = 4; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(true, ts.S2_nls_node_list_get_called); @@ -1052,7 +1208,9 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(6, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); @@ -1063,14 +1221,18 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 6 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -1083,9 +1245,9 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ // Primary controller receives the encapsulated NLS_NODE_LIST_GET_V2 frame ts.S2_nls_node_list_get_is_last_node = false; - ts.S2_nls_node_list_get_node_id = 5; + ts.S2_nls_node_list_get_node_id = 5; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -1102,13 +1264,15 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(8, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); - ts.S2_nls_node_list_report_called = 0; - ts.S2_nls_node_list_report_id_of_node = 0; + ts.S2_nls_node_list_report_called = 0; + ts.S2_nls_node_list_report_id_of_node = 0; ts.S2_nls_node_list_report_keys_node_bitmask = 0; - ts.S2_nls_node_list_report_nls_state = false; + ts.S2_nls_node_list_report_nls_state = false; // Secondary controller receives the encapsulated NLS_NODE_LIST_REPORT_V2 frame TEST_ASSERT_EQUAL(0, ts.S2_nls_node_list_report_called); @@ -1117,14 +1281,18 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 8 (NLS_NODE_LIST_GET_V2 from secondary to primary controller) --- */ // Secondary controller immediately responds to the primary controller with an encapsulated NLS_NODE_LIST_GET_v2 frame - TEST_ASSERT_EQUAL(false, ctx2->delayed_transmission_flags.send_nls_node_list_get); + TEST_ASSERT_EQUAL(false, + ctx2->delayed_transmission_flags.send_nls_node_list_get); TEST_ASSERT_EQUAL(SENDING_MSG, ctx2->fsm); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); @@ -1137,9 +1305,9 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ // Primary controller receives the encapsulated NLS_NODE_LIST_GET_V2 frame ts.S2_nls_node_list_get_is_last_node = true; - ts.S2_nls_node_list_get_node_id = 6; + ts.S2_nls_node_list_get_node_id = 6; ts.S2_nls_node_list_get_granted_keys = 0xFF; - ts.S2_nls_node_list_nls_state = true; + ts.S2_nls_node_list_nls_state = true; TEST_ASSERT_EQUAL(true, ts.S2_nls_node_list_get_request); TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_get_called); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -1156,13 +1324,15 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(19, ts.frame_len); // Lenght of encrypted frame TEST_ASSERT_EQUAL(10, ts.fcount); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(IDLE, ctx1->fsm); - ts.S2_nls_node_list_report_called = 0; - ts.S2_nls_node_list_report_id_of_node = 0; + ts.S2_nls_node_list_report_called = 0; + ts.S2_nls_node_list_report_id_of_node = 0; ts.S2_nls_node_list_report_keys_node_bitmask = 0; - ts.S2_nls_node_list_report_nls_state = false; + ts.S2_nls_node_list_report_nls_state = false; // Secondary controller receives the encapsulated NLS_NODE_LIST_REPORT_V2 frame TEST_ASSERT_EQUAL(0, ts.S2_nls_node_list_report_called); @@ -1171,9 +1341,12 @@ void test_secondary_controller_joining_to_network_nls_state_report_ack_received_ TEST_ASSERT_EQUAL(false, ts.S2_nls_node_list_report_nls_state); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.S2_nls_node_list_report_called); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, ts.S2_nls_node_list_report_id_of_node); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, ts.S2_nls_node_list_report_keys_node_bitmask); - TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, ts.S2_nls_node_list_report_nls_state); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_node_id, + ts.S2_nls_node_list_report_id_of_node); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_get_granted_keys, + ts.S2_nls_node_list_report_keys_node_bitmask); + TEST_ASSERT_EQUAL(ts.S2_nls_node_list_nls_state, + ts.S2_nls_node_list_report_nls_state); /* --- step 10 (Secondary controller gets last_node flag finally and does not re-initiate another NLS_NODE_LIST_GET_v2) --- */ @@ -1187,10 +1360,12 @@ void test_send_data_fail_in_nonce_get(void) { my_setup(); ts.send_data_return_fail = 1; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_FAIL, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -1199,15 +1374,17 @@ void test_send_data_fail_in_nonce_get(void) void test_transmit_complete_no_ack_in_nonce_get(void) { my_setup(); - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_NO_ACK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_NO_ACK, 0x42); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -1216,16 +1393,18 @@ void test_transmit_complete_no_ack_in_nonce_get(void) void test_transmit_timeout_after_sending_nonce_get(void) { my_setup(); - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_timeout_notify(ctx1); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -1234,20 +1413,20 @@ void test_transmit_timeout_after_sending_nonce_get(void) void test_transmit_timeout_before_sending_nonce_get(void) { my_setup(); - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); S2_timeout_notify(ctx1); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - - /* Test that duplicate nonce get frames are ignored * Test that duplicate nonce raport frames are ignored * Test that duplicate msg enap frames are ignored */ @@ -1257,14 +1436,14 @@ void test_dup_nonce_get(void) uint8_t backup_len; my_setup(); - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); - memcpy(backup_frame,ts.frame,ts.frame_len); + memcpy(backup_frame, ts.frame, ts.frame_len); backup_len = ts.frame_len; /*Send the frame to ctx2 twice */ S2_application_command_handler(ctx2, &conn21, backup_frame, backup_len); @@ -1274,11 +1453,12 @@ void test_dup_nonce_get(void) TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); - memcpy(backup_frame,ts.frame,ts.frame_len); + memcpy(backup_frame, ts.frame, ts.frame_len); backup_len = ts.frame_len; /*Send the frame to ctx1 twice */ S2_application_command_handler(ctx1, &conn12, backup_frame, backup_len); @@ -1289,29 +1469,32 @@ void test_dup_nonce_get(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); //Check we got a send done event + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, + ts.s2_send_status); //Check we got a send done event - memcpy(backup_frame,ts.frame,ts.frame_len); + memcpy(backup_frame, ts.frame, ts.frame_len); backup_len = ts.frame_len; /*Send the frame to ctx2 twice */ S2_application_command_handler(ctx2, &conn21, backup_frame, backup_len); S2_application_command_handler(ctx2, &conn21, backup_frame, backup_len); - TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - /** * Test that we get transmissions complete fail when send_data * fails in encap_message @@ -1325,15 +1508,17 @@ void test_send_data_fail_in_encap_message(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; - ts.send_data_return_fail=1; - ts.s2_send_done =0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; + ts.send_data_return_fail = 1; + ts.s2_send_done = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_FAIL, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -1349,15 +1534,17 @@ void test_send_data_no_ack_in_encap_message(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - ts.s2_send_done =0; + ts.s2_send_done = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_NO_ACK,0x42); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_NO_ACK, 0x42); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_NO_ACK, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } void test_stop_timeout_transmit_no_ack(void) @@ -1368,21 +1555,22 @@ void test_stop_timeout_transmit_no_ack(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - ts.s2_send_done =0; + ts.s2_send_done = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_NO_ACK,0x42); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_NO_ACK, 0x42); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_NO_ACK, ts.s2_send_status); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - /* Test that sequence counter increases and test all message lengths */ - /* loop len 0..1280 +/* loop len 0..1280 * send encap message with len * verify message decryption * verify seq increases @@ -1393,20 +1581,19 @@ void test_encap_seq_increase(void) uint8_t seq; int i; - for(i=0; i < sizeof(test_buf); i++) { - test_buf[i] = rand() & 0xFF; + for (i = 0; i < sizeof(test_buf); i++) { + test_buf[i] = rand() & 0xFF; } - test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); seq = ts.frame[2]; @@ -1415,76 +1602,83 @@ void test_encap_seq_increase(void) TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - ts.fcount=0; - for(i=1; i < 1280; i++) { - S2_send_data(ctx1, &conn12, (uint8_t*) test_buf, i); + ts.fcount = 0; + for (i = 1; i < 1280; i++) { + S2_send_data(ctx1, &conn12, (uint8_t *)test_buf, i); TEST_ASSERT_EQUAL(i, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ - S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); + S2_application_command_handler(ctx2, + &ts.last_trans, + ts.frame, + ts.frame_len); TEST_ASSERT_EQUAL(++seq, ts.frame[2]); TEST_ASSERT_EQUAL(i, ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(test_buf, ts.rx_frame, i); - } - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test } + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test +} /*Validate nonce report */ void test_nonce_report(void) { - uint8_t nonce_get[] = {COMMAND_CLASS_SECURITY_2,SECURITY_2_NONCE_GET,42}; + uint8_t nonce_get[] = {COMMAND_CLASS_SECURITY_2, SECURITY_2_NONCE_GET, 42}; int seq2; uint8_t nonce[8]; my_setup(); /*send nonce get */ - S2_application_command_handler(ctx2,&conn12,nonce_get,3); - S2_send_frame_done_notify(ctx2,S2_TRANSMIT_COMPLETE_OK,0x42); + S2_application_command_handler(ctx2, &conn12, nonce_get, 3); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /* verify nonce report save nonce for later */ - TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2,ts.frame[0]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT,ts.frame[1]); + TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); seq2 = ts.frame[2]; - memcpy(nonce,&ts.frame[4],8); + memcpy(nonce, &ts.frame[4], 8); /*verify sequence number */ nonce_get[2]++; - S2_application_command_handler(ctx2,&conn12,nonce_get,3); - S2_send_frame_done_notify(ctx2,S2_TRANSMIT_COMPLETE_OK,0x42); - TEST_ASSERT_EQUAL(2,ts.fcount); - TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2,ts.frame[0]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT,ts.frame[1]); - TEST_ASSERT_EQUAL(seq2+1,ts.frame[2]); - + S2_application_command_handler(ctx2, &conn12, nonce_get, 3); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); + TEST_ASSERT_EQUAL(2, ts.fcount); + TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); + TEST_ASSERT_EQUAL(seq2 + 1, ts.frame[2]); /* verify reserved is 0 */ /* verify SOS = 1 and MOS 0* */ - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK,ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /* Verify nonce bytes */ /* Verify nonce bytes different than in case 1 */ - TEST_ASSERT( memcmp(nonce,&ts.frame[4],8) != 0 ); + TEST_ASSERT(memcmp(nonce, &ts.frame[4], 8) != 0); /* Verify frame length */ - TEST_ASSERT_EQUAL(4+16,ts.frame_len); + TEST_ASSERT_EQUAL(4 + 16, ts.frame_len); /* send nonce get which is too short ie 2 bytes */ /* Verify that no report is sent */ - ts.fcount =0; + ts.fcount = 0; nonce_get[2]++; - S2_application_command_handler(ctx2,&conn12,nonce_get,2); - S2_send_done_event(ctx2,S2_TRANSMIT_COMPLETE_OK); - TEST_ASSERT_EQUAL(0,ts.fcount); + S2_application_command_handler(ctx2, &conn12, nonce_get, 2); + S2_send_done_event(ctx2, S2_TRANSMIT_COMPLETE_OK); + TEST_ASSERT_EQUAL(0, ts.fcount); /* send nonce get which has some extra data appened */ /* Verify we get a valid report*/ nonce_get[2]++; - S2_application_command_handler(ctx2,&conn12,nonce_get,6); - S2_send_done_event(ctx2,S2_TRANSMIT_COMPLETE_OK); - TEST_ASSERT_EQUAL(1,ts.fcount); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + S2_application_command_handler(ctx2, &conn12, nonce_get, 6); + S2_send_done_event(ctx2, S2_TRANSMIT_COMPLETE_OK); + TEST_ASSERT_EQUAL(1, ts.fcount); + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -1498,65 +1692,72 @@ void test_nonce_report(void) * B receives MSG 2 * */ -void test_sos_recover_scenario1(void) { - +void test_sos_recover_scenario1(void) +{ const char hello[] = "HelloWorld Second Frame"; test_s2_send_data(); - ts.rx_frame_len=0; + ts.rx_frame_len = 0; ts.s2_send_done = 0; - ts.fcount = 0; + ts.fcount = 0; /* ----------- now send second frame with SPAN established --------- * */ - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check the callback + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check the callback /*Make the message invalid*/ - ts.frame[ts.frame_len-1] =0; - ts.frame[ts.frame_len-2] =0; - ts.frame[ts.frame_len-3] =0; - ts.frame[ts.frame_len-4] =0; + ts.frame[ts.frame_len - 1] = 0; + ts.frame[ts.frame_len - 2] = 0; + ts.frame[ts.frame_len - 3] = 0; + ts.frame[ts.frame_len - 4] = 0; /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); /*Verify that the ctx2 sends a nonce report SOS, because it could not receive the frame.*/ - TEST_ASSERT_EQUAL(2, ts.fcount); //Check the callback + TEST_ASSERT_EQUAL(2, ts.fcount); //Check the callback TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(1, ts.sync_ev.count); // Test that a sync events was emitted after receiving Nonce Report SOS + TEST_ASSERT_EQUAL( + 1, + ts.sync_ev + .count); // Test that a sync events was emitted after receiving Nonce Report SOS /* send a new frame */ - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); /*Check that SN is included */ + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); /*Check that SN is included */ TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); - - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + ts.frame[5]); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); //Verify that the frame has been received + TEST_ASSERT_EQUAL(sizeof(hello), + ts.rx_frame_len); //Verify that the frame has been received TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(1, ts.sync_ev.count); // Test that no further sync events was emitted during test + TEST_ASSERT_EQUAL( + 1, + ts.sync_ev + .count); // Test that no further sync events was emitted during test } - /** * Check recover after a node has sent SOS * @@ -1571,56 +1772,61 @@ void test_sos_recover_scenario1(void) { * A Gets MSG 2 * */ -void test_sos_recover_scenario2(void) { - +void test_sos_recover_scenario2(void) +{ const char hello[] = "HelloWorld Second Frame"; test_s2_send_data(); - ts.rx_frame_len=0; + ts.rx_frame_len = 0; ts.s2_send_done = 0; - ts.fcount = 0; + ts.fcount = 0; /* ----------- now send second frame with SPAN established --------- * */ - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check the callback + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check the callback /*Make the message invalid*/ - ts.frame[ts.frame_len-1] =0; - ts.frame[ts.frame_len-2] =0; - ts.frame[ts.frame_len-3] =0; - ts.frame[ts.frame_len-4] =0; + ts.frame[ts.frame_len - 1] = 0; + ts.frame[ts.frame_len - 2] = 0; + ts.frame[ts.frame_len - 3] = 0; + ts.frame[ts.frame_len - 4] = 0; /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); /*Verify that the ctx2 sends a nonce report SOS, because it could not receive the frame.*/ - TEST_ASSERT_EQUAL(2, ts.fcount); //Check the callback + TEST_ASSERT_EQUAL(2, ts.fcount); //Check the callback TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); - TEST_ASSERT_EQUAL(1, ts.sync_ev.count); // Test that a sync events was emitted when receiving the Nonce Report SOS while idle + TEST_ASSERT_EQUAL( + 1, + ts.sync_ev + .count); // Test that a sync events was emitted when receiving the Nonce Report SOS while idle /* send a new frame from ctx 2*/ - S2_send_data(ctx2, &conn21, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx2, &conn21, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_GET, ts.frame[1]); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx1*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the NONCE REPORT frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -1628,24 +1834,28 @@ void test_sos_recover_scenario2(void) { /*Verify a ENCAP msg comes out */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); /*Check that SN is included */ + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); /*Check that SN is included */ TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); - - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + ts.frame[5]); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); /* verify that ctx1 gets the message */ - TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); //Verify that the frame has been received + TEST_ASSERT_EQUAL(sizeof(hello), + ts.rx_frame_len); //Verify that the frame has been received TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(1, ts.sync_ev.count); // Test that no further sync events was emitted during test + TEST_ASSERT_EQUAL( + 1, + ts.sync_ev + .count); // Test that no further sync events was emitted during test } - /**Verify that message is ignored if MAC is invalid */ @@ -1655,20 +1865,22 @@ void test_encap_message_authcheck(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Break the mac */ - ts.frame[ts.frame_len-3] = 0x1; - ts.frame[ts.frame_len-2] = 0x2; - ts.frame[ts.frame_len-1] = 0x3; + ts.frame[ts.frame_len - 3] = 0x1; + ts.frame[ts.frame_len - 2] = 0x2; + ts.frame[ts.frame_len - 1] = 0x3; /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /* Verify we dont go into an infinite loop when parsing a zero-length header extension @@ -1679,16 +1891,22 @@ void test_hdr_ext_zero_length_and_more_to_follow(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; //uint8_t strange_frame[] = {0x9F, 0x03 , 0x17 , 0x01 , 0x02 , 0xBF , 0x00 , 0x89, 0xE , 0xDD , 0x69 , 0xFC , 0x92 , 0xA0 , 0xA5 , 0x09 , 0xF0 , 0xF4}; - uint8_t strange_frame[] = {0x9F, 0x03 , 0x17 , 0x01 , 0x02 , 0xBF , 0x00 , 0x89, 0 , 0 , 0 , 0, 0, 0, 0}; + uint8_t strange_frame[] + = {0x9F, 0x03, 0x17, 0x01, 0x02, 0xBF, 0x00, 0x89, 0, 0, 0, 0, 0, 0, 0}; /*Send the frame to ctx2*/ - S2_application_command_handler(ctx2, &ts.last_trans, strange_frame, sizeof(strange_frame)); + S2_application_command_handler(ctx2, + &ts.last_trans, + strange_frame, + sizeof(strange_frame)); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /* Verify we dont go into an infinite loop when parsing a zero-length header extension @@ -1699,15 +1917,37 @@ void test_hdr_ext_zero_length_and_more_to_follow2(void) /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - uint8_t strange_frame[] = {0x9F, 0x03 , 0x17 , 0x01 , 0x02 , 0xBF , 0x00 , 0x89, 0xE , 0xDD , 0x69 , 0xFC , 0x92 , 0xA0 , 0xA5 , 0x09 , 0xF0 , 0xF4}; + uint8_t strange_frame[] = {0x9F, + 0x03, + 0x17, + 0x01, + 0x02, + 0xBF, + 0x00, + 0x89, + 0xE, + 0xDD, + 0x69, + 0xFC, + 0x92, + 0xA0, + 0xA5, + 0x09, + 0xF0, + 0xF4}; /*Send the frame to ctx2*/ - S2_application_command_handler(ctx2, &ts.last_trans, strange_frame, sizeof(strange_frame)); + S2_application_command_handler(ctx2, + &ts.last_trans, + strange_frame, + sizeof(strange_frame)); TEST_ASSERT_EQUAL(0, ts.rx_frame_len); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } void test_encap_message_oversize(void) @@ -1718,7 +1958,7 @@ void test_encap_message_oversize(void) /*construct message which is 1281 bytes long */ /* verify that the message is ignored by receiver*/ TEST_IGNORE_MESSAGE("Implement me"); - ; + ; } void test_encap_message_lencheck(void) @@ -1759,7 +1999,6 @@ void test_encap_message_extlen(void) ; } - void test_m_enacap_send(void) { /* generate MPAN for nodes 2,3,4 */ @@ -1784,63 +2023,72 @@ void test_m_enacap_send(void) */ void test_commands_supported_report(void) { - const uint8_t commands_supported_get[] = {COMMAND_CLASS_SECURITY_2,SECURITY_2_COMMANDS_SUPPORTED_GET}; + const uint8_t commands_supported_get[] + = {COMMAND_CLASS_SECURITY_2, SECURITY_2_COMMANDS_SUPPORTED_GET}; test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) commands_supported_get, sizeof(commands_supported_get)); + S2_send_data(ctx1, + &conn12, + (uint8_t *)commands_supported_get, + sizeof(commands_supported_get)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); - TEST_ASSERT_EQUAL(2, ts.fcount); //encap commands supported get + encap commands supported report + TEST_ASSERT_EQUAL( + 2, + ts.fcount); //encap commands supported get + encap commands supported report S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); - /*Expect ctx2 to reply with command supported report*/ TEST_ASSERT_EQUAL(sizeof(commands_supported_report), ts.rx_frame_len); - TEST_ASSERT_EQUAL_MEMORY( commands_supported_report, ts.rx_frame, sizeof(commands_supported_report)); + TEST_ASSERT_EQUAL_MEMORY(commands_supported_report, + ts.rx_frame, + sizeof(commands_supported_report)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** * Check that we receive S2_TRANSMIT_COMPLETE_OK if we are sending with verify, * if the receiving controller is able to decrypt the message */ -void test_sd_verify_tx_ok(void) { - +void test_sd_verify_tx_ok(void) +{ const char hello[] = "HelloWorld Second Frame"; test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -1848,72 +2096,71 @@ void test_sd_verify_tx_ok(void) { TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); S2_timeout_notify(ctx1); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - - - /** * Check that we receive S2_TRANSMIT_COMPLETE_NO_ACK if senddata returns false in fist transmission * Related to ZGW-XXXX */ -void test_sd_verify_tx_sd_false(void) { - +void test_sd_verify_tx_sd_false(void) +{ const char hello[] = "HelloWorld Second Frame"; test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - ts.s2_send_status = 42; /* Init to invalid status code, so we can verify that S2_send_data changes it */ + ts.s2_send_status + = 42; /* Init to invalid status code, so we can verify that S2_send_data changes it */ conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; ts.send_data_return_fail = 1; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_FAIL, ts.s2_send_status); TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - - - /** * Check that we receive S2_TRANSMIT_COMPLETE_FAIL if send data returns false * when trying to do nonce sync in verify delivery. */ -void test_sd_verify_tx_sd_false_second_attempt(void) { +void test_sd_verify_tx_sd_false_second_attempt(void) +{ const char hello[] = "HelloWorld Second Frame"; uint8_t bad_frame[1500]; test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*make a bad frame */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC /*Send the BAD frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); @@ -1921,9 +2168,10 @@ void test_sd_verify_tx_sd_false_second_attempt(void) { /*We expect ctx2 to send a nonce report */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - ts.send_data_return_fail=1; + ts.send_data_return_fail = 1; /*Make ctx1 hear the nocne report*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -1932,38 +2180,40 @@ void test_sd_verify_tx_sd_false_second_attempt(void) { //Make sure we are not stuck TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - /** * Check that we receive S2_TRANSMIT_COMPLETE_OK if we are sending with verify, * if the receiving controller is able to decrypt the message after the * second attempt */ -void test_sd_verify_tx_ok_second_attempt(void) { +void test_sd_verify_tx_ok_second_attempt(void) +{ const char hello[] = "HelloWorld Second Frame"; uint8_t bad_frame[1500]; test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*make a bad frame */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC /*Send the BAD frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); @@ -1971,7 +2221,8 @@ void test_sd_verify_tx_ok_second_attempt(void) { /*We expect ctx2 to send a nonce report */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /*Make ctx1 hear the nocne report*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -1979,10 +2230,12 @@ void test_sd_verify_tx_ok_second_attempt(void) { /* ctx1 should now send a MSG,SN */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); /*Make ctx1 hear the MSG,SN*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -1996,38 +2249,40 @@ void test_sd_verify_tx_ok_second_attempt(void) { S2_timeout_notify(ctx1); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - /** * Check that we receive S2_TRANSMIT_COMPLETE_FIAL if we are sending with verify, * if the receiving controller is not able to decrypt, and sends a NONCE_REPORT - * after both first and second attempt. */ -void test_sd_verify_tx_fail(void) { +void test_sd_verify_tx_fail(void) +{ const char hello[] = "HelloWorld Second Frame"; uint8_t bad_frame[1500]; test_s2_send_data(); /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*make a bad frame */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC /*Send the BAD frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); @@ -2035,7 +2290,8 @@ void test_sd_verify_tx_fail(void) { /*We expect ctx2 to send a nonce report */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /*Make ctx1 hear the nocne report*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -2043,14 +2299,16 @@ void test_sd_verify_tx_fail(void) { /* ctx1 should now send a MSG,SN */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); /*make a bad frame */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC /*Make ctx1 hear the bad frame*/ S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); @@ -2058,8 +2316,8 @@ void test_sd_verify_tx_fail(void) { /*We expect ctx2 to send a nonce report */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); - + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /*Verify that the callback only comes after the second frame */ TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_FAIL, ts.s2_send_status); @@ -2069,16 +2327,17 @@ void test_sd_verify_tx_fail(void) { TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_FAIL, ts.s2_send_status); TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - - /** * Check that we receive S2_TRANSMIT_COMPLETE_VERIFIED if we are sending with verify, * if the receiving controller is able to decrypt the message,and sends a reply */ -void test_sd_verify_tx_verifify(void) { +void test_sd_verify_tx_verifify(void) +{ const char ping[] = "PING"; const char pong[] = "PONG"; @@ -2086,8 +2345,8 @@ void test_sd_verify_tx_verifify(void) { /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; @@ -2097,12 +2356,12 @@ void test_sd_verify_tx_verifify(void) { */ conn21.tx_options = S2_TXOPTION_VERIFY_DELIVERY; - S2_send_data(ctx1, &conn12, (uint8_t*) ping, sizeof(ping)); + S2_send_data(ctx1, &conn12, (uint8_t *)ping, sizeof(ping)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2110,12 +2369,12 @@ void test_sd_verify_tx_verifify(void) { TEST_ASSERT_EQUAL(sizeof(ping), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(ping, ts.rx_frame, sizeof(ping)); - S2_send_data(ctx2, &conn21, (uint8_t*) pong, sizeof(pong)); + S2_send_data(ctx2, &conn21, (uint8_t *)pong, sizeof(pong)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_VERIFIED, ts.s2_send_status); @@ -2128,16 +2387,18 @@ void test_sd_verify_tx_verifify(void) { TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_VERIFIED, ts.s2_send_status); TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - /** * Check that we receive S2_TRANSMIT_COMPLETE_VERIFIED if we are sending with verify, * if the receiving controller is able to decrypt the message after the * second attempt, and sends a reply message */ -void test_sd_verify_tx_verify_second_attempt(void) { +void test_sd_verify_tx_verify_second_attempt(void) +{ const char ping[] = "PING"; const char pong[] = "PONG"; @@ -2146,8 +2407,8 @@ void test_sd_verify_tx_verify_second_attempt(void) { /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count - ts.rx_frame_len = 0; + ts.fcount = 0; //Reset frame count + ts.rx_frame_len = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY; @@ -2156,17 +2417,16 @@ void test_sd_verify_tx_verify_second_attempt(void) { */ conn21.tx_options = S2_TXOPTION_VERIFY_DELIVERY; - - S2_send_data(ctx1, &conn12, (uint8_t*) ping, sizeof(ping)); + S2_send_data(ctx1, &conn12, (uint8_t *)ping, sizeof(ping)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*make a bad frame */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC /*Send the BAD frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); @@ -2174,7 +2434,8 @@ void test_sd_verify_tx_verify_second_attempt(void) { /*We expect ctx2 to send a nonce report */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /*Make ctx1 hear the nocne report*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -2182,10 +2443,12 @@ void test_sd_verify_tx_verify_second_attempt(void) { /* ctx1 should now send a MSG,SN */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); /*Make ctx1 hear the MSG,SN*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2199,12 +2462,12 @@ void test_sd_verify_tx_verify_second_attempt(void) { /*Now make ctx2 send reply*/ - S2_send_data(ctx2, &conn21, (uint8_t*) pong, sizeof(pong)); + S2_send_data(ctx2, &conn21, (uint8_t *)pong, sizeof(pong)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_NOT_EQUAL(S2_TRANSMIT_COMPLETE_VERIFIED, ts.s2_send_status); @@ -2217,20 +2480,25 @@ void test_sd_verify_tx_verify_second_attempt(void) { TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_VERIFIED, ts.s2_send_status); TEST_ASSERT_FALSE(S2_is_busy(ctx1)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** * Do a singlecast followup, where SPAN is ok, but node b is MOS */ -void singlecast_followup_mos(struct S2* ctx_a, struct S2* ctx_b, s2_connection_t* conn) { +void singlecast_followup_mos(struct S2 *ctx_a, + struct S2 *ctx_b, + s2_connection_t *conn) +{ char hello_mc[] = "Hello multicast"; - ts.fcount = 0; - ts.s2_send_done=0; + ts.fcount = 0; + ts.s2_send_done = 0; /* Send the single cast frame */ - S2_send_data(ctx_a, conn, (uint8_t*) hello_mc, sizeof(hello_mc)); - S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data(ctx_a, conn, (uint8_t *)hello_mc, sizeof(hello_mc)); + S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_application_command_handler(ctx_b, &ts.last_trans, ts.frame, ts.frame_len); S2_timeout_notify(ctx_b); @@ -2241,7 +2509,7 @@ void singlecast_followup_mos(struct S2* ctx_a, struct S2* ctx_b, s2_connection_t TEST_ASSERT_EQUAL(2, ts.frame[3]); TEST_ASSERT_EQUAL(4, ts.frame_len); - S2_send_frame_done_notify(ctx_b, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx_b, S2_TRANSMIT_COMPLETE_OK, 0x42); /* Deliver NR,MOS to ctx 1*/ S2_application_command_handler(ctx_a, &ts.last_trans, ts.frame, ts.frame_len); @@ -2250,10 +2518,10 @@ void singlecast_followup_mos(struct S2* ctx_a, struct S2* ctx_b, s2_connection_t TEST_ASSERT_EQUAL(3, ts.fcount); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(2, ts.frame[3]); //Verify that there is a ENC, EXT included + TEST_ASSERT_EQUAL(2, ts.frame[3]); //Verify that there is a ENC, EXT included TEST_ASSERT_EQUAL(4 + 19 + 8, ts.frame_len); - S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_timeout_notify(ctx_a); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); @@ -2266,42 +2534,53 @@ void singlecast_followup_mos(struct S2* ctx_a, struct S2* ctx_b, s2_connection_t * Do a singlecast followup, where SPAN is ok, but node b is MOS, but * here its a supervision get, and receiver will send a report */ -void supervision_singlecast_followup_mos(struct S2* ctx_a, struct S2* ctx_b, s2_connection_t* conn) { - char supervision_get[] = "Supervision Get"; +void supervision_singlecast_followup_mos(struct S2 *ctx_a, + struct S2 *ctx_b, + s2_connection_t *conn) +{ + char supervision_get[] = "Supervision Get"; char supervision_report[] = "Supervision Report"; - ts.fcount = 0; - ts.s2_send_done=0; + ts.fcount = 0; + ts.s2_send_done = 0; /* Send the single cast frame */ - S2_send_data(ctx_a, conn, (uint8_t*) supervision_get, sizeof(supervision_get)); - S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data(ctx_a, + conn, + (uint8_t *)supervision_get, + sizeof(supervision_get)); + S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_application_command_handler(ctx_b, &ts.last_trans, ts.frame, ts.frame_len); /*Reply with supervison report */ - S2_send_data(ctx_b, &ts.last_trans, (uint8_t*) supervision_report, sizeof(supervision_report)); - S2_send_frame_done_notify(ctx_b, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data(ctx_b, + &ts.last_trans, + (uint8_t *)supervision_report, + sizeof(supervision_report)); + S2_send_frame_done_notify(ctx_b, S2_TRANSMIT_COMPLETE_OK, 0x42); /* Verify that ctx2 sends a message with the,MOS extension */ TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a ENC, EXT included - TEST_ASSERT_EQUAL(2, ts.frame[4]); //length 2 - TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_TYPE_MOS, ts.frame[5]); //length 2 + TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a ENC, EXT included + TEST_ASSERT_EQUAL(2, ts.frame[4]); //length 2 + TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_TYPE_MOS, ts.frame[5]); //length 2 - S2_send_frame_done_notify(ctx_b, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx_b, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_application_command_handler(ctx_a, &ts.last_trans, ts.frame, ts.frame_len); /* The CTX1 sends a MSG,MPAN */ TEST_ASSERT_EQUAL(3, ts.fcount); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(2, ts.frame[3]); //Verify that there is a ENC, EXT included + TEST_ASSERT_EQUAL(2, ts.frame[3]); //Verify that there is a ENC, EXT included TEST_ASSERT_EQUAL(4 + 19 + 8, ts.frame_len); - S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx_a, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_timeout_notify(ctx_a); - TEST_ASSERT_EQUAL(2, ts.s2_send_done); //both ctx_a and ctx_b have been sending a message + TEST_ASSERT_EQUAL( + 2, + ts.s2_send_done); //both ctx_a and ctx_b have been sending a message TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); /* Deliver MSG,MPAN to ctx 2*/ @@ -2316,53 +2595,54 @@ void supervision_singlecast_followup_mos(struct S2* ctx_a, struct S2* ctx_b, s2_ * 4) Verify that sender sends EMSG,MPAN * */ -void -establish_mpan(uint8_t group) +void establish_mpan(uint8_t group) { uint8_t buf[1024]; - char hello_mc[] = "Hello multicast"; - s2_connection_t mc_group = - { 1, 0x42 }; - s2_connection_t mc_group_rx = - { 0x42, 1, 0, S2_RXOPTION_MULTICAST }; + char hello_mc[] = "Hello multicast"; + s2_connection_t mc_group = {1, 0x42}; + s2_connection_t mc_group_rx = {0x42, 1, 0, S2_RXOPTION_MULTICAST}; - mc_group.class_id = 2; - mc_group.r_node = group; + mc_group.class_id = 2; + mc_group.r_node = group; mc_group_rx.l_node = group; /* Send the first multicast message */ - S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) hello_mc, - sizeof(hello_mc)); + S2_send_data_multicast(ctx1, + &mc_group, + (uint8_t *)hello_mc, + sizeof(hello_mc)); TEST_ASSERT_EQUAL(ts.fcount, 1); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included + TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included TEST_ASSERT_EQUAL(3, ts.frame[4]); - TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG|S2_MSG_EXTHDR_TYPE_MGRP, - ts.frame[5]); + TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_MGRP, + ts.frame[5]); TEST_ASSERT_EQUAL(mc_group.r_node, ts.frame[6]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); - memcpy(buf,ts.frame,ts.frame_len); + memcpy(buf, ts.frame, ts.frame_len); S2_application_command_handler(ctx2, &mc_group_rx, ts.frame, ts.frame_len); S2_application_command_handler(ctx3, &mc_group_rx, buf, ts.frame_len); - /* Of ctx 2 */ conn12.rx_options = 0; - conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP; + conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY + | S2_TXOPTION_SINGLECAST_FOLLOWUP + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP; - supervision_singlecast_followup_mos(ctx1,ctx2,&conn12); + supervision_singlecast_followup_mos(ctx1, ctx2, &conn12); conn13.rx_options = 0; - conn13.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP; + conn13.tx_options + = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP; - singlecast_followup_mos(ctx1,ctx3,&conn13); + singlecast_followup_mos(ctx1, ctx3, &conn13); } /** @@ -2378,99 +2658,114 @@ establish_mpan(uint8_t group) void test_mulicast_send(void) { uint8_t buf[1024]; - char hello_mc2[] = "Jello multicast 2"; + char hello_mc2[] = "Jello multicast 2"; char hello_single[] = "hello singlecast"; int i; - int group_id = 2; - s2_connection_t mc_group = - { 1, group_id }; - s2_connection_t mc_group_rx = - { group_id, 1, 0, S2_RXOPTION_MULTICAST }; - - conn12.class_id=2; - conn13.class_id=2; - mc_group.class_id=2; + int group_id = 2; + s2_connection_t mc_group = {1, group_id}; + s2_connection_t mc_group_rx = {group_id, 1, 0, S2_RXOPTION_MULTICAST}; + + conn12.class_id = 2; + conn13.class_id = 2; + mc_group.class_id = 2; /*Establish span*/ //test_s2_send_data(); my_setup(); - wrap_test_s2_send_data(ctx2,&conn12); - wrap_test_s2_send_data(ctx3,&conn13); + wrap_test_s2_send_data(ctx2, &conn12); + wrap_test_s2_send_data(ctx3, &conn13); - ts.fcount = 0; - ts.s2_send_done = 0; + ts.fcount = 0; + ts.s2_send_done = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; establish_mpan(group_id); - - for(i=0; i < 10; i++) { + for (i = 0; i < 10; i++) { int j; - uint8_t retval=0; + uint8_t retval = 0; - printf("Round %i.....\n",i); + printf("Round %i.....\n", i); /*Send 3 multicast frames */ - for(j=0; j<3; j++) { + for (j = 0; j < 3; j++) { /*Send a new multicast and verify that ctx2 is able to decrypt the frame*/ - retval = S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) hello_mc2, - sizeof(hello_mc2)); - TEST_ASSERT_EQUAL(retval,1); + retval = S2_send_data_multicast(ctx1, + &mc_group, + (uint8_t *)hello_mc2, + sizeof(hello_mc2)); + TEST_ASSERT_EQUAL(retval, 1); /* Negative test: we cannot send twice */ - retval = S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) hello_mc2, - sizeof(hello_mc2)); - TEST_ASSERT_EQUAL(retval,0); + retval = S2_send_data_multicast(ctx1, + &mc_group, + (uint8_t *)hello_mc2, + sizeof(hello_mc2)); + TEST_ASSERT_EQUAL(retval, 0); /* Negative test: we cannot send nothing */ - retval = S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) NULL, - sizeof(hello_mc2)); + retval = S2_send_data_multicast(ctx1, + &mc_group, + (uint8_t *)NULL, + sizeof(hello_mc2)); /* Negative test: we cannot send no data */ - TEST_ASSERT_EQUAL(retval,0); - retval = S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) hello_mc2, - 0); - TEST_ASSERT_EQUAL(retval,0); + TEST_ASSERT_EQUAL(retval, 0); + retval = S2_send_data_multicast(ctx1, &mc_group, (uint8_t *)hello_mc2, 0); + TEST_ASSERT_EQUAL(retval, 0); /* Back to the legal path */ - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); - memcpy(buf,ts.frame,ts.frame_len); + memcpy(buf, ts.frame, ts.frame_len); - memset(ts.rx_frame,0,sizeof(ts.rx_frame)); - ts.rx_frame_len=0; - S2_application_command_handler(ctx2, &mc_group_rx, ts.frame, ts.frame_len); + memset(ts.rx_frame, 0, sizeof(ts.rx_frame)); + ts.rx_frame_len = 0; + S2_application_command_handler(ctx2, + &mc_group_rx, + ts.frame, + ts.frame_len); TEST_ASSERT_EQUAL_STRING(hello_mc2, ts.rx_frame); - TEST_ASSERT_EQUAL( ts.rx_frame_len, sizeof(hello_mc2)); + TEST_ASSERT_EQUAL(ts.rx_frame_len, sizeof(hello_mc2)); - memset(ts.rx_frame,0,sizeof(ts.rx_frame)); + memset(ts.rx_frame, 0, sizeof(ts.rx_frame)); ts.rx_frame_len = 0; S2_application_command_handler(ctx3, &mc_group_rx, buf, ts.frame_len); TEST_ASSERT_EQUAL_STRING(hello_mc2, ts.rx_frame); - TEST_ASSERT_EQUAL( ts.rx_frame_len, sizeof(hello_mc2)); + TEST_ASSERT_EQUAL(ts.rx_frame_len, sizeof(hello_mc2)); } - /*Verify no NR send on next single cast */ ts.fcount = 0; - conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY |S2_TXOPTION_SINGLECAST_FOLLOWUP | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP; - - memset(ts.rx_frame,0,sizeof(ts.rx_frame)); - S2_send_data(ctx1,&conn12, (uint8_t*)hello_single, sizeof(hello_single)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); - S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); + conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY + | S2_TXOPTION_SINGLECAST_FOLLOWUP + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP; + + memset(ts.rx_frame, 0, sizeof(ts.rx_frame)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello_single, sizeof(hello_single)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); + S2_application_command_handler(ctx2, + &ts.last_trans, + ts.frame, + ts.frame_len); TEST_ASSERT_EQUAL_STRING(hello_single, ts.rx_frame); - TEST_ASSERT_EQUAL(1,ts.fcount); + TEST_ASSERT_EQUAL(1, ts.fcount); S2_timeout_notify(ctx1); - conn13.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP; + conn13.tx_options + = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP; /*Verify no NR send on next single cast */ - memset(ts.rx_frame,0,sizeof(ts.rx_frame)); - S2_send_data(ctx1,&conn13, (uint8_t*)hello_single, sizeof(hello_single)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); - S2_application_command_handler(ctx3, &ts.last_trans, ts.frame, ts.frame_len); + memset(ts.rx_frame, 0, sizeof(ts.rx_frame)); + S2_send_data(ctx1, &conn13, (uint8_t *)hello_single, sizeof(hello_single)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); + S2_application_command_handler(ctx3, + &ts.last_trans, + ts.frame, + ts.frame_len); TEST_ASSERT_EQUAL_STRING(hello_single, ts.rx_frame); - TEST_ASSERT_EQUAL(2,ts.fcount); + TEST_ASSERT_EQUAL(2, ts.fcount); S2_timeout_notify(ctx1); } - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /* @@ -2479,48 +2774,50 @@ void test_mulicast_send(void) */ void test_mulicast_send_mos_sos_sync(void) { - char hello_mc2[] = "Jello multicast 2"; + char hello_mc2[] = "Jello multicast 2"; char hello_single[] = "hello singlecast"; - char hello_mc[] = "Hello multicast"; + char hello_mc[] = "Hello multicast"; int i; - s2_connection_t mc_group = - { 1, 0x42 }; - s2_connection_t mc_group_rx = - { 0x42, 1, 0, S2_RXOPTION_MULTICAST }; + s2_connection_t mc_group = {1, 0x42}; + s2_connection_t mc_group_rx = {0x42, 1, 0, S2_RXOPTION_MULTICAST}; my_setup(); - ts.fcount = 0; - ts.s2_send_done = 0; + ts.fcount = 0; + ts.s2_send_done = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; - mc_group.class_id=2; + mc_group.class_id = 2; /* Send the first multicast message */ - S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) hello_mc, - sizeof(hello_mc)); + S2_send_data_multicast(ctx1, + &mc_group, + (uint8_t *)hello_mc, + sizeof(hello_mc)); TEST_ASSERT_EQUAL(ts.fcount, 1); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included + TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included TEST_ASSERT_EQUAL(3, ts.frame[4]); - TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG|S2_MSG_EXTHDR_TYPE_MGRP, - ts.frame[5]); + TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_MGRP, + ts.frame[5]); TEST_ASSERT_EQUAL(mc_group.r_node, ts.frame[6]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(1, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); S2_application_command_handler(ctx2, &mc_group_rx, ts.frame, ts.frame_len); conn12.rx_options = 0; - conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP | S2_TXOPTION_SINGLECAST_FOLLOWUP; + conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP + | S2_TXOPTION_SINGLECAST_FOLLOWUP; /* Send the single cast frame */ - S2_send_data(ctx1, &conn12, (uint8_t*) hello_mc, sizeof(hello_mc)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data(ctx1, &conn12, (uint8_t *)hello_mc, sizeof(hello_mc)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2528,9 +2825,9 @@ void test_mulicast_send_mos_sos_sync(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT, ts.frame[1]); TEST_ASSERT_EQUAL(S2_NONCE_REPORT_SOS_FLAG, ts.frame[3]); /*SOS*/ - TEST_ASSERT_EQUAL(4+16, ts.frame_len); + TEST_ASSERT_EQUAL(4 + 16, ts.frame_len); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /* Deliver NR,SOS to ctx 1*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -2539,12 +2836,19 @@ void test_mulicast_send_mos_sos_sync(void) TEST_ASSERT_EQUAL(ts.fcount, 4); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(S2_MSG_FLAG_EXT, ts.frame[3]); //Verify that there is a non ENC EXT is included - TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_MORE_FLAG, ts.frame[5] & S2_MSG_EXTHDR_MORE_FLAG); //Verify that there is a non ENC EXT is included + TEST_ASSERT_EQUAL( + S2_MSG_FLAG_EXT, + ts.frame[3]); //Verify that there is a non ENC EXT is included + TEST_ASSERT_EQUAL( + S2_MSG_EXTHDR_MORE_FLAG, + ts.frame[5] + & S2_MSG_EXTHDR_MORE_FLAG); //Verify that there is a non ENC EXT is included + + TEST_ASSERT_EQUAL( + 4 + 3 + 18 + sizeof(hello_mc) + 8, + ts.frame_len); //SH=4, MC GRP=3, SPAN=18, PAYLOAD , AUTH=8 - TEST_ASSERT_EQUAL(4 +3+ 18+ sizeof(hello_mc) + 8, ts.frame_len); //SH=4, MC GRP=3, SPAN=18, PAYLOAD , AUTH=8 - - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /* Deliver MSG, to ctx 2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2560,8 +2864,9 @@ void test_mulicast_send_mos_sos_sync(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(S2_MSG_FLAG_SEXT, ts.frame[3]); //Verify that there is a ENC, SEXT included - TEST_ASSERT_EQUAL(4 + 19 + 8 , ts.frame_len); //SH, MPAN, AUTH + TEST_ASSERT_EQUAL(S2_MSG_FLAG_SEXT, + ts.frame[3]); //Verify that there is a ENC, SEXT included + TEST_ASSERT_EQUAL(4 + 19 + 8, ts.frame_len); //SH, MPAN, AUTH /* Deliver ENC, MPAN to ctx 2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2571,54 +2876,60 @@ void test_mulicast_send_mos_sos_sync(void) TEST_ASSERT_EQUAL(2, ts.s2_send_done); TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); - ts.fcount = 0; + ts.fcount = 0; ts.s2_send_done = 0; - for(i =0; i < 10; i++) { - + for (i = 0; i < 10; i++) { /*Send a new multicast and verify that ctx2 is able to decrypt the frame*/ - S2_send_data_multicast(ctx1, &mc_group, (uint8_t*) hello_mc2, - sizeof(hello_mc2)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_data_multicast(ctx1, + &mc_group, + (uint8_t *)hello_mc2, + sizeof(hello_mc2)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); S2_application_command_handler(ctx2, &mc_group_rx, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL_STRING(hello_mc2, ts.rx_frame); - conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP | S2_TXOPTION_SINGLECAST_FOLLOWUP; + conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP + | S2_TXOPTION_SINGLECAST_FOLLOWUP; /*Verify no NR send on next single cast */ - S2_send_data(ctx1,&conn12, (uint8_t*)hello_single, sizeof(hello_single)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); - S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); - - TEST_ASSERT_EQUAL(2*i+1,ts.s2_send_done); + S2_send_data(ctx1, &conn12, (uint8_t *)hello_single, sizeof(hello_single)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); + S2_application_command_handler(ctx2, + &ts.last_trans, + ts.frame, + ts.frame_len); + + TEST_ASSERT_EQUAL(2 * i + 1, ts.s2_send_done); S2_timeout_notify(ctx1); - TEST_ASSERT_EQUAL(2*i+2,ts.s2_send_done); - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK,ts.s2_send_status); + TEST_ASSERT_EQUAL(2 * i + 2, ts.s2_send_done); + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); TEST_ASSERT_EQUAL_STRING(hello_single, ts.rx_frame); - TEST_ASSERT_EQUAL((i+1)*2,ts.fcount); + TEST_ASSERT_EQUAL((i + 1) * 2, ts.fcount); } - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } - /** * Send a frame with sec group 1, verify that it goes just like group 0 */ void test_s2_send_data_second_group(void) { - const char hello2[] = "HelloWorld Second Frame"; my_setup(); conn12.class_id = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2626,9 +2937,10 @@ void test_s2_send_data_second_group(void) TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx1*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -2637,35 +2949,37 @@ void test_s2_send_data_second_group(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); //Check we got a send done event + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, + ts.s2_send_status); //Check we got a send done event /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - /*Now verify that we can send single frames*/ /* ----------- now send second frame with SPAN established --------- * */ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello2, sizeof(hello2)); + S2_send_data(ctx1, &conn12, (uint8_t *)hello2, sizeof(hello2)); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + TEST_ASSERT_EQUAL(0, ts.frame[3]); //Verify that there is no SN included + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2673,19 +2987,18 @@ void test_s2_send_data_second_group(void) TEST_ASSERT_EQUAL(sizeof(hello2), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello2, ts.rx_frame, sizeof(hello2)); - /*Now change group again this should look exactly like the first transmission*/ - ts.fcount = 0; //Reset frame count + ts.fcount = 0; //Reset frame count ts.rx_frame_len = 0; - ts.s2_send_done =0; + ts.s2_send_done = 0; conn21.class_id = 2; - S2_send_data(ctx2, &conn21, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx2, &conn21, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -2693,9 +3006,10 @@ void test_s2_send_data_second_group(void) TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx1*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2704,21 +3018,26 @@ void test_s2_send_data_second_group(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); //Check we got a send done event + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, + ts.s2_send_status); //Check we got a send done event /*Send the frame to ctx2*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -2727,35 +3046,34 @@ void test_s2_send_data_second_group(void) */ void test_s2_send_data_multicast_and_follow_up_with_keyset(void) { - char hello_mc2[] = "Hello multicast 2"; - char hello_mc[] = "Hello multicast"; - s2_connection_t mc_group1 = - { 1, 0x42 }; - s2_connection_t mc_group_rx1 = - { 0x42, 1, 0, S2_RXOPTION_MULTICAST }; - s2_connection_t mc_group2 = - { 1, 0x47 }; - s2_connection_t mc_group_rx2 = - { 0x47, 1, 0, S2_RXOPTION_MULTICAST }; + char hello_mc2[] = "Hello multicast 2"; + char hello_mc[] = "Hello multicast"; + s2_connection_t mc_group1 = {1, 0x42}; + s2_connection_t mc_group_rx1 = {0x42, 1, 0, S2_RXOPTION_MULTICAST}; + s2_connection_t mc_group2 = {1, 0x47}; + s2_connection_t mc_group_rx2 = {0x47, 1, 0, S2_RXOPTION_MULTICAST}; my_setup(); - ts.fcount = 0; - ts.s2_send_done = 0; + ts.fcount = 0; + ts.s2_send_done = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; - mc_group1.class_id=1; + mc_group1.class_id = 1; /* Send the first multicast message, group 0x42 */ - S2_send_data_multicast_with_keyset(ctx1, &mc_group1, ZWAVE_LONG_RANGE_KEYSET, (uint8_t*) hello_mc, - sizeof(hello_mc)); + S2_send_data_multicast_with_keyset(ctx1, + &mc_group1, + ZWAVE_LONG_RANGE_KEYSET, + (uint8_t *)hello_mc, + sizeof(hello_mc)); TEST_ASSERT_EQUAL(ts.fcount, 1); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included + TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included TEST_ASSERT_EQUAL(3, ts.frame[4]); - TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG|S2_MSG_EXTHDR_TYPE_MGRP, - ts.frame[5]); + TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_MGRP, + ts.frame[5]); TEST_ASSERT_EQUAL(mc_group1.r_node, ts.frame[6]); TEST_ASSERT_EQUAL(mc_group1.class_id, 3); @@ -2766,22 +3084,28 @@ void test_s2_send_data_multicast_and_follow_up_with_keyset(void) S2_application_command_handler(ctx1, &mc_group_rx1, ts.frame, ts.frame_len); // Try with an unknown keyset. That should get rejected. - S2_send_data_multicast_with_keyset(ctx1, &mc_group2, UNKNOWN_KEYSET, (uint8_t*) hello_mc2, - sizeof(hello_mc2)); + S2_send_data_multicast_with_keyset(ctx1, + &mc_group2, + UNKNOWN_KEYSET, + (uint8_t *)hello_mc2, + sizeof(hello_mc2)); TEST_ASSERT_EQUAL(ts.fcount, 1); /* Send the second multicast message, group 0x47 */ - mc_group2.class_id=1; - S2_send_data_multicast_with_keyset(ctx1, &mc_group2, ZWAVE_KEYSET, (uint8_t*) hello_mc2, - sizeof(hello_mc2)); + mc_group2.class_id = 1; + S2_send_data_multicast_with_keyset(ctx1, + &mc_group2, + ZWAVE_KEYSET, + (uint8_t *)hello_mc2, + sizeof(hello_mc2)); TEST_ASSERT_EQUAL(ts.fcount, 2); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); - TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included + TEST_ASSERT_EQUAL(1, ts.frame[3]); //Verify that there is a MC group included TEST_ASSERT_EQUAL(3, ts.frame[4]); - TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG|S2_MSG_EXTHDR_TYPE_MGRP, - ts.frame[5]); + TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_MGRP, + ts.frame[5]); TEST_ASSERT_EQUAL(mc_group2.r_node, ts.frame[6]); TEST_ASSERT_EQUAL(mc_group2.class_id, 1); @@ -2793,88 +3117,119 @@ void test_s2_send_data_multicast_and_follow_up_with_keyset(void) /* Send the single cast frame, to the first group, i.e. ID 42. */ conn12.mgrp_group_id = 0x42; - conn12.rx_options = 0; - conn12.class_id = 2; - conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP | S2_TXOPTION_SINGLECAST_FOLLOWUP; - S2_send_data_singlecast_follow_up_with_keyset(ctx1, &conn12, ZWAVE_LONG_RANGE_KEYSET,(uint8_t*) hello_mc, sizeof(hello_mc)); + conn12.rx_options = 0; + conn12.class_id = 2; + conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY + | S2_TXOPTION_FIRST_SINGLECAST_FOLLOWUP + | S2_TXOPTION_SINGLECAST_FOLLOWUP; + S2_send_data_singlecast_follow_up_with_keyset(ctx1, + &conn12, + ZWAVE_LONG_RANGE_KEYSET, + (uint8_t *)hello_mc, + sizeof(hello_mc)); TEST_ASSERT_EQUAL(ts.fcount, 3); TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_NONCE_GET, ts.frame[1]); - TEST_ASSERT_EQUAL(ctx1->mpan->group_id, 0x42); // Did the context change to the right MGRP ID ? - TEST_ASSERT_EQUAL(ctx1->peer.class_id, 4); // Did the Keyset select the right adjusted class id 2->4? + TEST_ASSERT_EQUAL(ctx1->mpan->group_id, + 0x42); // Did the context change to the right MGRP ID ? + TEST_ASSERT_EQUAL( + ctx1->peer.class_id, + 4); // Did the Keyset select the right adjusted class id 2->4? S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x47); S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); // Try with an unknown keyset TEST_ASSERT_EQUAL(ts.fcount, 4); - S2_send_data_singlecast_follow_up_with_keyset(ctx1, &conn12, UNKNOWN_KEYSET, (uint8_t*) hello_mc, sizeof(hello_mc)); + S2_send_data_singlecast_follow_up_with_keyset(ctx1, + &conn12, + UNKNOWN_KEYSET, + (uint8_t *)hello_mc, + sizeof(hello_mc)); TEST_ASSERT_EQUAL(ts.fcount, 4); // Abort the previous transmission and test the follow-up with Z-Wave keyset ctx1->fsm = IDLE; - conn12.tx_options = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP; + conn12.tx_options + = S2_TXOPTION_VERIFY_DELIVERY | S2_TXOPTION_SINGLECAST_FOLLOWUP; conn12.class_id = 20; - S2_send_data_singlecast_follow_up_with_keyset(ctx1, &conn12, ZWAVE_KEYSET,(uint8_t*) hello_mc, sizeof(hello_mc)); - TEST_ASSERT_EQUAL(ctx1->peer.class_id, 20); // Did the Keyset select the right adjusted class id 2->4? + S2_send_data_singlecast_follow_up_with_keyset(ctx1, + &conn12, + ZWAVE_KEYSET, + (uint8_t *)hello_mc, + sizeof(hello_mc)); + TEST_ASSERT_EQUAL( + ctx1->peer.class_id, + 20); // Did the Keyset select the right adjusted class id 2->4? TEST_ASSERT_EQUAL(ts.fcount, 5); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } void test_s2_send_data_with_keyset(void) { my_setup(); - ts.fcount = 0; - ts.s2_send_done =0; + ts.fcount = 0; + ts.s2_send_done = 0; // Should not accept any unknown keysets - S2_send_data_singlecast_with_keyset(ctx1, &conn12, UNKNOWN_KEYSET, (uint8_t*) hello, sizeof(hello)); + S2_send_data_singlecast_with_keyset(ctx1, + &conn12, + UNKNOWN_KEYSET, + (uint8_t *)hello, + sizeof(hello)); TEST_ASSERT_EQUAL(0, ts.fcount); // Accept and do not modify the class id for the Z-Wave keyset conn12.class_id = 1; - S2_send_data_singlecast_with_keyset(ctx1, &conn12, ZWAVE_KEYSET, (uint8_t*) hello, sizeof(hello)); + S2_send_data_singlecast_with_keyset(ctx1, + &conn12, + ZWAVE_KEYSET, + (uint8_t *)hello, + sizeof(hello)); TEST_ASSERT_EQUAL(1, ts.fcount); TEST_ASSERT_EQUAL(1, conn12.class_id); - // Abort this previous transmission, go back to idle ctx1->fsm = IDLE; // Accept and modify the class id for the Z-Wave Long Range keyset conn12.class_id = 1; - S2_send_data_singlecast_with_keyset(ctx1, &conn12, ZWAVE_LONG_RANGE_KEYSET, (uint8_t*) hello, sizeof(hello)); + S2_send_data_singlecast_with_keyset(ctx1, + &conn12, + ZWAVE_LONG_RANGE_KEYSET, + (uint8_t *)hello, + sizeof(hello)); TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(3, conn12.class_id); } - void test_s2_free_mpan(void) { - char hello_mc[] = "Test free MPAN"; - s2_connection_t mc_group1 = - { 1, 0x42 }; + char hello_mc[] = "Test free MPAN"; + s2_connection_t mc_group1 = {1, 0x42}; my_setup(); - ts.fcount = 0; - ts.s2_send_done = 0; + ts.fcount = 0; + ts.s2_send_done = 0; ts.s2_send_status = S2_TRANSMIT_COMPLETE_NO_ACK; - mc_group1.class_id=2; + mc_group1.class_id = 2; /* Send the first multicast message, group 0x42 */ - S2_send_data_multicast(ctx1, &mc_group1, (uint8_t*) hello_mc, - sizeof(hello_mc)); + S2_send_data_multicast(ctx1, + &mc_group1, + (uint8_t *)hello_mc, + sizeof(hello_mc)); // MPAN should have been set up - TEST_ASSERT_EQUAL(0x42,ctx1->mpan->group_id); - TEST_ASSERT_EQUAL(MPAN_SET,ctx1->mpan->state); + TEST_ASSERT_EQUAL(0x42, ctx1->mpan->group_id); + TEST_ASSERT_EQUAL(MPAN_SET, ctx1->mpan->state); - S2_free_mpan(ctx1,0,0x42); - TEST_ASSERT_EQUAL(MPAN_NOT_USED,ctx1->mpan->state); + S2_free_mpan(ctx1, 0, 0x42); + TEST_ASSERT_EQUAL(MPAN_NOT_USED, ctx1->mpan->state); } - - /** * Check that the sequence number check in verify delivery works */ @@ -2882,33 +3237,37 @@ void test_s2_verify_delivery_seq_no_check(void) { my_setup(); uint8_t dup_nr[64]; - struct S2* ctx_dest = ctx2; - s2_connection_t* dst = &conn12; + struct S2 *ctx_dest = ctx2; + s2_connection_t *dst = &conn12; s2_connection_t nr_conn; - ts.fcount = 0; - ts.s2_send_done =0; + ts.fcount = 0; + ts.s2_send_done = 0; dst->tx_options = S2_TXOPTION_VERIFY_DELIVERY; - S2_send_data(ctx1, dst, (uint8_t*) hello, sizeof(hello)); + S2_send_data(ctx1, dst, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ - S2_application_command_handler(ctx_dest, &ts.last_trans, ts.frame, ts.frame_len); + S2_application_command_handler(ctx_dest, + &ts.last_trans, + ts.frame, + ts.frame_len); /*Expect that we get a nonce report*/ TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /*Remember the nonce report */ - memcpy(dup_nr,ts.frame,ts.frame_len); - nr_conn= ts.last_trans; - S2_send_frame_done_notify(ctx_dest, S2_TRANSMIT_COMPLETE_OK,0x42); + memcpy(dup_nr, ts.frame, ts.frame_len); + nr_conn = ts.last_trans; + S2_send_frame_done_notify(ctx_dest, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx1*/ S2_application_command_handler(ctx1, &ts.last_trans, ts.frame, ts.frame_len); @@ -2917,16 +3276,20 @@ void test_s2_verify_delivery_seq_no_check(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); - - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + ts.frame[5]); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ - S2_application_command_handler(ctx_dest, &ts.last_trans, ts.frame, ts.frame_len); + S2_application_command_handler(ctx_dest, + &ts.last_trans, + ts.frame, + ts.frame_len); TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); @@ -2935,24 +3298,26 @@ void test_s2_verify_delivery_seq_no_check(void) S2_timeout_notify(ctx1); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); //Check we got a send done event - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, + ts.s2_send_status); //Check we got a send done event + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } void test_s2_exploit(void) { my_setup(); - - ts.fcount = 0; - ts.s2_send_done =0; - S2_send_data(ctx1, &conn12, (uint8_t*) hello, sizeof(hello)); + ts.fcount = 0; + ts.s2_send_done = 0; + S2_send_data(ctx1, &conn12, (uint8_t *)hello, sizeof(hello)); TEST_ASSERT_EQUAL_STRING_LEN(nonce_get, ts.frame, 2); TEST_ASSERT_EQUAL(3, ts.frame_len); TEST_ASSERT_EQUAL(1, ts.fcount); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); @@ -2960,17 +3325,18 @@ void test_s2_exploit(void) TEST_ASSERT_EQUAL(2, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); - - S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK,0x42); - + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); + S2_send_frame_done_notify(ctx2, S2_TRANSMIT_COMPLETE_OK, 0x42); - uint8_t inject_frame[]=" You have been haCKed"; - inject_frame[0] = COMMAND_CLASS_SECURITY_2; - inject_frame[1] = SECURITY_2_COMMANDS_SUPPORTED_REPORT; - S2_application_command_handler(ctx1, &conn12, inject_frame, sizeof(inject_frame)); - + uint8_t inject_frame[] = " You have been haCKed"; + inject_frame[0] = COMMAND_CLASS_SECURITY_2; + inject_frame[1] = SECURITY_2_COMMANDS_SUPPORTED_REPORT; + S2_application_command_handler(ctx1, + &conn12, + inject_frame, + sizeof(inject_frame)); /*Send the frame to ctx1*/ S2_application_command_handler(ctx1, &conn12, ts.frame, ts.frame_len); @@ -2979,21 +3345,26 @@ void test_s2_exploit(void) TEST_ASSERT_EQUAL(COMMAND_CLASS_SECURITY_2, ts.frame[0]); TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION, ts.frame[1]); //TEST_ASSERT_EQUAL(ts.frame[2],COMMAND_CLASS_SECURITY_2); //seq - TEST_ASSERT_EQUAL(SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL( + SECURITY_2_MESSAGE_ENCAPSULATION_PROPERTIES1_EXTENSION_BIT_MASK, + ts.frame[3]); TEST_ASSERT_EQUAL(18, ts.frame[4]); TEST_ASSERT_EQUAL(S2_MSG_EXTHDR_CRITICAL_FLAG | S2_MSG_EXTHDR_TYPE_SN, - ts.frame[5]); + ts.frame[5]); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); - TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event - TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, ts.s2_send_status); //Check we got a send done event + TEST_ASSERT_EQUAL(1, ts.s2_send_done); //Check we got a send done event + TEST_ASSERT_EQUAL(S2_TRANSMIT_COMPLETE_OK, + ts.s2_send_status); //Check we got a send done event /*Send the frame to ctx2*/ S2_application_command_handler(ctx2, &ts.last_trans, ts.frame, ts.frame_len); TEST_ASSERT_EQUAL(sizeof(hello), ts.rx_frame_len); TEST_ASSERT_EQUAL_STRING_LEN(hello, ts.rx_frame, sizeof(hello)); - TEST_ASSERT_EQUAL(0, ts.sync_ev.count); // Test that no sync events were emitted during test + TEST_ASSERT_EQUAL( + 0, + ts.sync_ev.count); // Test that no sync events were emitted during test } /** @@ -3007,8 +3378,8 @@ void test_s2_exploit(void) * In this test, the S2 context is idle when the SOS comes in. * */ -void test_sos_recsync_event_1(void) { - +void test_sos_recsync_event_1(void) +{ uint8_t bad_frame[1500]; test_sd_verify_tx_ok_second_attempt(); @@ -3018,9 +3389,10 @@ void test_sos_recsync_event_1(void) { /* Generate a Nonce Report SOS by injecting a bad frame into ctx2 */ /*make a bad frame (there is a good frame in */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC - bad_frame[2]++; /* This will increment seqno, so it doesnt get duplicate detected */ + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC + bad_frame + [2]++; /* This will increment seqno, so it doesnt get duplicate detected */ /* Now we have a nonce report SOS in ts.frame*/ /*Send the BAD frame to ctx2*/ @@ -3031,13 +3403,14 @@ void test_sos_recsync_event_1(void) { TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); uint8_t sos_seqno = ts.frame[2]; - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); /* Expect no Sync Events so far*/ TEST_ASSERT_EQUAL(0, ts.sync_ev.count); /* Invalidate ts.sync_ev so they aren't accidentally correct for the following asserts */ - memset(&ts.sync_ev, 0 ,sizeof ts.sync_ev); + memset(&ts.sync_ev, 0, sizeof ts.sync_ev); ts.sync_ev.reason = 42; /*Send the Nonce Rep SOS to ctx1*/ @@ -3057,8 +3430,8 @@ void test_sos_recsync_event_1(void) { * Test that a resync event is emitted if SOS comes in from Node A, while sending to Node B * */ -void test_sos_recsync_event_2(void) { - +void test_sos_recsync_event_2(void) +{ uint8_t bad_frame[1500]; uint8_t nonce_rep_frame[30]; uint16_t nonce_rep_frame_len; @@ -3067,8 +3440,7 @@ void test_sos_recsync_event_2(void) { /* Test has two flavours: With and without verify delivery for the "busy" transmission to A * while Nonce Rep SOS comes in from node B */ - for (uint8_t test_flavour = 0; test_flavour < 2; test_flavour++) - { + for (uint8_t test_flavour = 0; test_flavour < 2; test_flavour++) { char flavour_msg[] = "test flavour 01"; snprintf(flavour_msg, sizeof flavour_msg, "test flavour %u", test_flavour); @@ -3079,21 +3451,28 @@ void test_sos_recsync_event_2(void) { /* Generate a Nonce Report SOS by injecting a bad frame into ctx2 */ /*make a bad frame (there is a good frame in */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC - bad_frame[2]++; /* This will increment seqno, so it doesnt get duplicate detected */ + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC + bad_frame + [2]++; /* This will increment seqno, so it doesnt get duplicate detected */ /* Now we have a nonce report SOS in ts.frame*/ /*Send the BAD frame to ctx2*/ - S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); + S2_application_command_handler(ctx2, + &ts.last_trans, + bad_frame, + ts.frame_len); /*Expect that we get a nonce report*/ TEST_ASSERT_EQUAL(4, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - memcpy(nonce_rep_frame, ts.frame, (ts.frame_len <= sizeof nonce_rep_frame) ? ts.frame_len : 0); + memcpy(nonce_rep_frame, + ts.frame, + (ts.frame_len <= sizeof nonce_rep_frame) ? ts.frame_len : 0); nonce_rep_frame_len = ts.frame_len; /* Expect no Sync Events so far*/ @@ -3101,30 +3480,35 @@ void test_sos_recsync_event_2(void) { /* Invalidate ts.sync_ev */ ts.sync_ev.remote_node = 0; - ts.sync_ev.reason = 0xFF; + ts.sync_ev.reason = 0xFF; /* Make ctx1 busy sending to node 2 */ if (test_flavour == 0) { TEST_ASSERT_EQUAL(S2_TXOPTION_VERIFY_DELIVERY, conn12.tx_options); - S2_send_data(ctx1, &conn12, (uint8_t*) test_msg, sizeof(test_msg)); + S2_send_data(ctx1, &conn12, (uint8_t *)test_msg, sizeof(test_msg)); TEST_ASSERT_EQUAL(VERIFYING_DELIVERY, ctx1->fsm); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(VERIFYING_DELIVERY, ctx1->fsm); } else { conn12.tx_options = 0; /* disable verify delivery */ - S2_send_data(ctx1, &conn12, (uint8_t*) test_msg, sizeof(test_msg)); + S2_send_data(ctx1, &conn12, (uint8_t *)test_msg, sizeof(test_msg)); TEST_ASSERT_EQUAL(SENDING_MSG, ctx1->fsm); } ts.fcount = 0; /* Send the Nonce Rep SOS to from node 3 ctx1 */ - S2_application_command_handler(ctx1, &conn13, nonce_rep_frame, nonce_rep_frame_len); + S2_application_command_handler(ctx1, + &conn13, + nonce_rep_frame, + nonce_rep_frame_len); /* Expect that we get a s2 resync event*/ TEST_ASSERT_EQUAL_MESSAGE(1, ts.sync_ev.count, flavour_msg); TEST_ASSERT_EQUAL_MESSAGE(3, ts.sync_ev.remote_node, flavour_msg); - TEST_ASSERT_EQUAL_MESSAGE(SOS_EVENT_REASON_UNANSWERED, ts.sync_ev.reason, flavour_msg); + TEST_ASSERT_EQUAL_MESSAGE(SOS_EVENT_REASON_UNANSWERED, + ts.sync_ev.reason, + flavour_msg); /*Expect that nothing is sent from ctx 1*/ TEST_ASSERT_EQUAL_MESSAGE(0, ts.fcount, flavour_msg); @@ -3135,8 +3519,8 @@ void test_sos_recsync_event_2(void) { * Test that a resync event is emitted if SOS comes in from Node A, while WAIT_NONCE_RAPORT to Node B * */ -void test_sos_recsync_event_3(void) { - +void test_sos_recsync_event_3(void) +{ uint8_t bad_frame[1500]; uint8_t nonce_rep_frame[30]; uint16_t nonce_rep_frame_len; @@ -3144,8 +3528,7 @@ void test_sos_recsync_event_3(void) { const char test_msg[] = "Testing 1 2 3"; /* Test has only one flavour - remove this for loop */ - for (uint8_t test_flavour = 0; test_flavour < 1; test_flavour++) - { + for (uint8_t test_flavour = 0; test_flavour < 1; test_flavour++) { char flavour_msg[] = "test flavour 01"; snprintf(flavour_msg, sizeof flavour_msg, "test flavour %u", test_flavour); @@ -3156,21 +3539,28 @@ void test_sos_recsync_event_3(void) { /* Generate a Nonce Report SOS by injecting a bad frame into ctx2 */ /*make a bad frame (there is a good frame in */ - memcpy(bad_frame,ts.frame,ts.frame_len); - bad_frame[ts.frame_len-1]++; // *this* will invalidate the MAC - bad_frame[2]++; /* This will increment seqno, so it doesnt get duplicate detected */ + memcpy(bad_frame, ts.frame, ts.frame_len); + bad_frame[ts.frame_len - 1]++; // *this* will invalidate the MAC + bad_frame + [2]++; /* This will increment seqno, so it doesnt get duplicate detected */ /* Now we have a nonce report SOS in ts.frame*/ /*Send the BAD frame to ctx2*/ - S2_application_command_handler(ctx2, &ts.last_trans, bad_frame, ts.frame_len); + S2_application_command_handler(ctx2, + &ts.last_trans, + bad_frame, + ts.frame_len); /*Expect that we get a nonce report*/ TEST_ASSERT_EQUAL(4, ts.fcount); TEST_ASSERT_EQUAL(20, ts.frame_len); TEST_ASSERT_EQUAL_STRING_LEN(nonce_report, ts.frame, 2); - TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, ts.frame[3]); + TEST_ASSERT_EQUAL(SECURITY_2_NONCE_REPORT_PROPERTIES1_SOS_BIT_MASK, + ts.frame[3]); - memcpy(nonce_rep_frame, ts.frame, (ts.frame_len <= sizeof nonce_rep_frame) ? ts.frame_len : 0); + memcpy(nonce_rep_frame, + ts.frame, + (ts.frame_len <= sizeof nonce_rep_frame) ? ts.frame_len : 0); nonce_rep_frame_len = ts.frame_len; /* Expect no Sync Events so far*/ @@ -3178,23 +3568,28 @@ void test_sos_recsync_event_3(void) { /* Invalidate ts.sync_ev */ ts.sync_ev.remote_node = 0; - ts.sync_ev.reason = 0xFF; + ts.sync_ev.reason = 0xFF; /* Get ctx1 in WAIT_NONCE_RAPPORT state by asking it to send to node 4 */ - s2_connection_t conn14 = { 1, 4 }; - S2_send_data(ctx1, &conn14, (uint8_t*) test_msg, sizeof(test_msg)); - S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK,0x42); + s2_connection_t conn14 = {1, 4}; + S2_send_data(ctx1, &conn14, (uint8_t *)test_msg, sizeof(test_msg)); + S2_send_frame_done_notify(ctx1, S2_TRANSMIT_COMPLETE_OK, 0x42); TEST_ASSERT_EQUAL(WAIT_NONCE_RAPORT, ctx1->fsm); ts.fcount = 0; /* Send the Nonce Rep SOS to from node 3 ctx1 */ - S2_application_command_handler(ctx1, &conn13, nonce_rep_frame, nonce_rep_frame_len); + S2_application_command_handler(ctx1, + &conn13, + nonce_rep_frame, + nonce_rep_frame_len); /* Expect that we get a s2 resync event*/ TEST_ASSERT_EQUAL_MESSAGE(1, ts.sync_ev.count, flavour_msg); TEST_ASSERT_EQUAL_MESSAGE(3, ts.sync_ev.remote_node, flavour_msg); - TEST_ASSERT_EQUAL_MESSAGE(SOS_EVENT_REASON_UNANSWERED, ts.sync_ev.reason, flavour_msg); + TEST_ASSERT_EQUAL_MESSAGE(SOS_EVENT_REASON_UNANSWERED, + ts.sync_ev.reason, + flavour_msg); /*Expect that nothing is sent from ctx 1*/ TEST_ASSERT_EQUAL_MESSAGE(0, ts.fcount, flavour_msg); @@ -3202,37 +3597,30 @@ void test_sos_recsync_event_3(void) { } /* Stub function */ -uint8_t s2_inclusion_set_timeout(__attribute__((unused)) struct S2* ctxt, __attribute__((unused)) uint32_t interval) +uint8_t s2_inclusion_set_timeout(__attribute__((unused)) struct S2 *ctxt, + __attribute__((unused)) uint32_t interval) { return 0; } -void s2_inclusion_stop_timeout(void) -{ -} +void s2_inclusion_stop_timeout(void) {} -void keystore_public_key_read(__attribute__((unused)) uint8_t *buf) -{ -} +void keystore_public_key_read(__attribute__((unused)) uint8_t *buf) {} -void keystore_dynamic_public_key_read(__attribute__((unused)) uint8_t *buf) -{ -} +void keystore_dynamic_public_key_read(__attribute__((unused)) uint8_t *buf) {} -void keystore_private_key_read(__attribute__((unused)) uint8_t *buf) -{ -} +void keystore_private_key_read(__attribute__((unused)) uint8_t *buf) {} -void keystore_dynamic_private_key_read(__attribute__((unused)) uint8_t *buf) -{ -} +void keystore_dynamic_private_key_read(__attribute__((unused)) uint8_t *buf) {} -bool keystore_network_key_read(__attribute__((unused)) uint8_t keyclass, __attribute__((unused)) uint8_t *buf) +bool keystore_network_key_read(__attribute__((unused)) uint8_t keyclass, + __attribute__((unused)) uint8_t *buf) { return true; } -bool keystore_network_key_write(__attribute__((unused)) uint8_t keyclass, __attribute__((unused)) const uint8_t *keybuf) +bool keystore_network_key_write(__attribute__((unused)) uint8_t keyclass, + __attribute__((unused)) const uint8_t *keybuf) { return true; } @@ -3244,10 +3632,9 @@ bool keystore_network_key_clear(__attribute__((unused)) uint8_t keyclass) void S2_dbg_printf(const char *format, ...) { - va_list argptr; - - va_start(argptr, format); - vfprintf(stdout, format, argptr); - va_end(argptr); + va_list argptr; + va_start(argptr, format); + vfprintf(stdout, format, argptr); + va_end(argptr); } \ No newline at end of file diff --git a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_transport_test.c b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_transport_test.c index 5f9db3000..cae7b37e6 100644 --- a/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_transport_test.c +++ b/applications/zpc/components/zwave/zwave_transports/s2/test/zwave_s2_transport_test.c @@ -64,7 +64,7 @@ extern const unify_dotdot_attribute_store_configuration_t zpc_configuration; static void create_basic_network(void) { const zwave_home_id_t home_id = 0xcafecafe; - zwave_keyset_t granted_keys = 0xFF; + zwave_keyset_t granted_keys = 0xFF; unify_dotdot_attribute_store_set_configuration(&zpc_configuration); @@ -88,13 +88,15 @@ static void create_basic_network(void) node_id = 3; // Z-Wave node node_id_node = attribute_store_add_node(ATTRIBUTE_NODE_ID, home_id_node); attribute_store_set_reported(node_id_node, &node_id, sizeof(node_id)); - node_id_node = attribute_store_add_node(ATTRIBUTE_GRANTED_SECURITY_KEYS, node_id_node); + node_id_node + = attribute_store_add_node(ATTRIBUTE_GRANTED_SECURITY_KEYS, node_id_node); zwave_set_node_granted_keys(node_id, &granted_keys); node_id = 4; // Z-Wave node node_id_node = attribute_store_add_node(ATTRIBUTE_NODE_ID, home_id_node); attribute_store_set_reported(node_id_node, &node_id, sizeof(node_id)); - node_id_node = attribute_store_add_node(ATTRIBUTE_GRANTED_SECURITY_KEYS, node_id_node); + node_id_node + = attribute_store_add_node(ATTRIBUTE_GRANTED_SECURITY_KEYS, node_id_node); zwave_set_node_granted_keys(node_id, &granted_keys); } @@ -607,14 +609,17 @@ void test_zwave_s2_nls_node_list_report_test_happy_case() uint8_t granted_keys; bool nls_state; - src_node = 1; - node_id = 3; + src_node = 1; + node_id = 3; granted_keys = 0xFF; - nls_state = true; + nls_state = true; zwapi_enable_node_nls_ExpectAndReturn(node_id, SL_STATUS_OK); - status = S2_notify_nls_node_list_report(src_node, node_id, granted_keys, nls_state); + status = S2_notify_nls_node_list_report(src_node, + node_id, + granted_keys, + nls_state); TEST_ASSERT_EQUAL(0, status); } @@ -629,14 +634,17 @@ void test_zwave_s2_nls_node_list_report_test_node_does_not_exist() uint8_t granted_keys; bool nls_state; - src_node = 1; - node_id = 6; // Non existant node + src_node = 1; + node_id = 6; // Non existant node granted_keys = 0xFF; - nls_state = true; + nls_state = true; zwapi_enable_node_nls_ExpectAndReturn(node_id, SL_STATUS_OK); - status = S2_notify_nls_node_list_report(src_node, node_id, granted_keys, nls_state); + status = S2_notify_nls_node_list_report(src_node, + node_id, + granted_keys, + nls_state); TEST_ASSERT_EQUAL(-1, status); } @@ -651,12 +659,15 @@ void test_zwave_s2_nls_node_list_report_test_nls_state_not_set() uint8_t granted_keys; bool nls_state; - src_node = 1; - node_id = 3; // Non existant node + src_node = 1; + node_id = 3; // Non existant node granted_keys = 0xFF; - nls_state = false; + nls_state = false; - status = S2_notify_nls_node_list_report(src_node, node_id, granted_keys, nls_state); + status = S2_notify_nls_node_list_report(src_node, + node_id, + granted_keys, + nls_state); TEST_ASSERT_EQUAL(-1, status); } diff --git a/applications/zpc/components/zwave/zwave_transports/transport_service_wrapper/transport_service/src/transport_service_command_class_def.h b/applications/zpc/components/zwave/zwave_transports/transport_service_wrapper/transport_service/src/transport_service_command_class_def.h index 5b35f1cd1..adca59e01 100644 --- a/applications/zpc/components/zwave/zwave_transports/transport_service_wrapper/transport_service/src/transport_service_command_class_def.h +++ b/applications/zpc/components/zwave/zwave_transports/transport_service_wrapper/transport_service/src/transport_service_command_class_def.h @@ -4,7 +4,7 @@ #define COMMAND_SEGMENT_REQUEST_V2 0xC8 #define COMMAND_SEGMENT_COMPLETE_V2 0xE8 #define COMMAND_SEGMENT_WAIT_V2 0xF0 -#define COMMAND_CLASS_INDEX 0 +#define COMMAND_CLASS_INDEX 0 /************************************************************/ /* Command Segment Request V2 command class structs */ /************************************************************/ @@ -59,4 +59,3 @@ typedef struct _ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME_ { uint8_t checksum1; /* MSB */ uint8_t checksum2; /* LSB */ } ZW_COMMAND_SUBSEQUENT_FRAGMENT_1BYTE_FRAME; - diff --git a/applications/zpc/components/zwave/zwave_tx/src/zwave_tx.cpp b/applications/zpc/components/zwave/zwave_tx/src/zwave_tx.cpp index 9f1d227a6..540918c98 100644 --- a/applications/zpc/components/zwave/zwave_tx/src/zwave_tx.cpp +++ b/applications/zpc/components/zwave/zwave_tx/src/zwave_tx.cpp @@ -128,7 +128,8 @@ sl_status_t // Protocol CCs must not be encrypted, but Z-Wave API transport is called last // and S2 will just encrypt stuff.. // We automatically downgrade security if Command Class is 0x00 or 0x01. - if (data_length > 0 && (data[0] == 0x00 || data[0] == 0x01) && (new_element.options.transport.is_protocol_frame == false)) { + if (data_length > 0 && (data[0] == 0x00 || data[0] == 0x01) + && (new_element.options.transport.is_protocol_frame == false)) { new_element.connection_info.encapsulation = ZWAVE_CONTROLLER_ENCAPSULATION_NONE; new_element.connection_info.remote.endpoint_id = 0; diff --git a/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_callbacks.cpp b/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_callbacks.cpp index 2d9d5b9ef..d5350a15c 100644 --- a/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_callbacks.cpp +++ b/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_callbacks.cpp @@ -34,7 +34,7 @@ // Shared variables from the Z-Wave TX Process extern zwave_tx_queue tx_queue; extern zwave_tx_session_id_t current_tx_session_id; -extern bool is_protocol_frame; // NOSONAR +extern bool is_protocol_frame; // NOSONAR // Static variables zwave_controller_connection_info_t last_received_connection_info; @@ -58,7 +58,7 @@ void on_zwave_transport_send_data_complete(uint8_t status, void *session_id = user; if (is_protocol_frame) { protocol_metadata_t *protocol_metadata = (protocol_metadata_t *)user; - session_id = protocol_metadata->tx_session_id; + session_id = protocol_metadata->tx_session_id; } // Copy the transmission results to the session_id (user pointer) diff --git a/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_process.cpp b/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_process.cpp index deab136e0..54932ab9f 100644 --- a/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_process.cpp +++ b/applications/zpc/components/zwave/zwave_tx/src/zwave_tx_process.cpp @@ -55,7 +55,7 @@ zwave_tx_backoff_reason_t backoff_reason; zwave_tx_queue tx_queue; // zwave_tx.cpp uses the tx_queue. // Shared ariable indicating if the ongoing session is for a procotol frame -bool is_protocol_frame = false; // NOSONAR +bool is_protocol_frame = false; // NOSONAR // Forward declarations static void zwave_tx_message_transmission_completed_step( @@ -335,16 +335,17 @@ static void zwave_tx_process_send_next_message_step() return; } - void *user = current_tx_session_id; + void *user = current_tx_session_id; is_protocol_frame = false; if (current_element.options.transport.is_protocol_frame == true) { // `user` argument in `zwave_controller_transport_send_data` is used to transport the current TX session ID // which is not ideal so we need to transport the real user data in the protocol metadata structure to match // the queue element when `on_zwave_transport_send_data_complete` is called. - protocol_metadata_t *protocol_metadata = (protocol_metadata_t *)current_element.user; + protocol_metadata_t *protocol_metadata + = (protocol_metadata_t *)current_element.user; protocol_metadata->tx_session_id = current_tx_session_id; - user = current_element.user; - is_protocol_frame = true; + user = current_element.user; + is_protocol_frame = true; } // Ask the transports to take the frame. diff --git a/applications/zpc/components/zwave/zwave_tx/test/zwave_tx_test.c b/applications/zpc/components/zwave/zwave_tx/test/zwave_tx_test.c index c891827ee..99dc08727 100644 --- a/applications/zpc/components/zwave/zwave_tx/test/zwave_tx_test.c +++ b/applications/zpc/components/zwave/zwave_tx/test/zwave_tx_test.c @@ -2157,7 +2157,6 @@ void test_full_zwave_tx_queue() TEST_ASSERT_EQUAL(1, send_done_count); TEST_ASSERT_EQUAL(TRANSMIT_COMPLETE_FAIL, send_done_status); - // The first frame should be discarded no matter it's timestamp since the queue is full TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_tx_send_data(&test_connection_1, @@ -2168,9 +2167,8 @@ void test_full_zwave_tx_queue() (void *)&my_user_pointer, &test_tx_session_id)); - zwave_controller_transport_abort_send_data_ExpectAndReturn( - second_message_id, - SL_STATUS_FAIL); + zwave_controller_transport_abort_send_data_ExpectAndReturn(second_message_id, + SL_STATUS_FAIL); // Check that we only discarded one frame and that the other frames are still here TEST_ASSERT_EQUAL(SL_STATUS_FAIL, @@ -2233,7 +2231,6 @@ void test_full_zwave_tx_queue_with_timeouts() TEST_ASSERT_EQUAL(ZWAVE_TX_QUEUE_BUFFER_SIZE, send_done_count); TEST_ASSERT_EQUAL(TRANSMIT_COMPLETE_FAIL, send_done_status); - // We filling the queue again and check if everything works as expected // By now the queue should be empty since all the frames should have timed out for (int i = 1; i < ZWAVE_TX_QUEUE_BUFFER_SIZE; ++i) { @@ -2248,7 +2245,6 @@ void test_full_zwave_tx_queue_with_timeouts() } } - void test_additional_back_off() { zwave_node_id_t chatty_node_id = 23; diff --git a/applications/zpc/components/zwave/zwave_tx_scheme_selector/src/zwave_tx_scheme_selector.c b/applications/zpc/components/zwave/zwave_tx_scheme_selector/src/zwave_tx_scheme_selector.c index 695dc9568..3e6eb987b 100644 --- a/applications/zpc/components/zwave/zwave_tx_scheme_selector/src/zwave_tx_scheme_selector.c +++ b/applications/zpc/components/zwave/zwave_tx_scheme_selector/src/zwave_tx_scheme_selector.c @@ -135,9 +135,9 @@ uint16_t zwave_tx_scheme_get_max_payload(zwave_node_id_t node_id) maximum_fragment_size -= MAX_ROUTING_HEADER_SIZE_R1_R2; } } else { - // Else we have to assume R1/R2: - maximum_fragment_size = MAX_MSDU_SIZE_R1_R2; - maximum_fragment_size -= MAX_ROUTING_HEADER_SIZE_R1_R2; + // Else we have to assume R1/R2: + maximum_fragment_size = MAX_MSDU_SIZE_R1_R2; + maximum_fragment_size -= MAX_ROUTING_HEADER_SIZE_R1_R2; sl_log_warning(LOG_TAG, "Unknown protocol for NodeID %d. Selecting the " diff --git a/applications/zpc/components/zwave_api/external/ext_defines.h b/applications/zpc/components/zwave_api/external/ext_defines.h index 655089a30..fd52fe92f 100644 --- a/applications/zpc/components/zwave_api/external/ext_defines.h +++ b/applications/zpc/components/zwave_api/external/ext_defines.h @@ -25,7 +25,6 @@ */ #define TRANSMIT_COMPLETE_REQUEUE_QUEUED 0xFD - // CLEANUP: chip_descriptor chip_desc belongs in serial_api_process component /** diff --git a/applications/zpc/components/zwave_api/external/ext_nvm_tools.c b/applications/zpc/components/zwave_api/external/ext_nvm_tools.c index d6a2dd4aa..3690086e6 100644 --- a/applications/zpc/components/zwave_api/external/ext_nvm_tools.c +++ b/applications/zpc/components/zwave_api/external/ext_nvm_tools.c @@ -7,24 +7,24 @@ #include "nvm_tools.h" static int set_default_cb_called = 0; -static void Set_Default_Callback() { +static void Set_Default_Callback() +{ set_default_cb_called = 1; } -bool ZW_NVM_Backup(const char* filename,uint8_t chiptype) +bool ZW_NVM_Backup(const char *filename, uint8_t chiptype) { - uint32_t backup_length = 0; - uint8_t length_read = 0; - uint16_t offset = 0; - uint8_t read_status = 0; + uint32_t backup_length = 0; + uint8_t length_read = 0; + uint16_t offset = 0; + uint8_t read_status = 0; uint8_t nvm_close_status = 0; - uint8_t read_buffer[ REQUEST_BUFFER_SIZE ]; + uint8_t read_buffer[REQUEST_BUFFER_SIZE]; FILE *my_nvm_backup_file; /* Open up a file */ my_nvm_backup_file = fopen(filename, "wb"); - if (NULL == my_nvm_backup_file) - { + if (NULL == my_nvm_backup_file) { printf("Cannot create NVM file \"%s\": %s.\n", filename, strerror(errno)); return false; } @@ -41,38 +41,35 @@ bool ZW_NVM_Backup(const char* filename,uint8_t chiptype) printf("backup_length: %d\n", backup_length); // Read the NVM chunck by chunk and put it into the file - while (offset length_write && 0 != write_status) - { - printf("ERROR : More data to write from file, but could not write on NVM (write status = %d, length write = %d\n", write_status,length_write); + length_write = fread(buffer, + sizeof(uint8_t), + NVM_WRITE_CHUNK_SIZE, + my_nvm_backup_file); + + if (0 > length_write && 0 != write_status) { + printf("ERROR : More data to write from file, but could not write on NVM " + "(write status = %d, length write = %d\n", + write_status, + length_write); break; } /* Print the progress */ fflush(stdout); - printf("\rWritten %d / %d bytes...",offset,expected_length); + printf("\rWritten %d / %d bytes...", offset, expected_length); } printf("\n"); @@ -158,8 +160,7 @@ bool ZW_NVM_Restore(const char* filename, uint8_t chiptype) fclose(my_nvm_backup_file); nvm_close_status = zwapi_nvm_close(); - if (0 != nvm_close_status) - { + if (0 != nvm_close_status) { printf("ERROR: NVM close command failed.\n"); return false; } @@ -167,16 +168,13 @@ bool ZW_NVM_Restore(const char* filename, uint8_t chiptype) // Perform a soft reset on the module printf("Soft reset of the module\n"); - /*The WatchDog is used to reset the chip after restoring EEPROM image to Z-Wave module from backup on 500 series, + /*The WatchDog is used to reset the chip after restoring EEPROM image to Z-Wave module from backup on 500 series, *in 700 series: the FUNC_ID_ZW_WATCHDOG_ENABLE will be removed, therefore, zwapi_soft_reset() should be used*/ if (ZW_GECKO_CHIP_TYPE(chiptype)) { zwapi_soft_reset(); - } - else { + } else { zwapi_enable_watchdog(); } return true; } - - diff --git a/applications/zpc/components/zwave_api/external/ext_nvm_tools.h b/applications/zpc/components/zwave_api/external/ext_nvm_tools.h index 02c1547ad..e2fe56049 100644 --- a/applications/zpc/components/zwave_api/external/ext_nvm_tools.h +++ b/applications/zpc/components/zwave_api/external/ext_nvm_tools.h @@ -1,33 +1,33 @@ // CLEANUP: Move out of zwave_api (e.g. to zpc_utils) -#ifndef NVM_TOOLS_H -#define NVM_TOOLS_H +#ifndef NVM_TOOLS_H +#define NVM_TOOLS_H #include #include enum nvm_backup_restore_operation { - nvm_backup_restore_open = 0x00, - nvm_backup_restore_read = 0x01, - nvm_backup_restore_write = 0x02, - nvm_backup_restore_close = 0x03, + nvm_backup_restore_open = 0x00, + nvm_backup_restore_read = 0x01, + nvm_backup_restore_write = 0x02, + nvm_backup_restore_close = 0x03, }; /* How many bytes we pass at a time when writing in the NVM via the SerialAPI */ -#define NVM_WRITE_CHUNK_SIZE 64 +#define NVM_WRITE_CHUNK_SIZE 64 /** * Read the NVM from a device and write it into an output file * * \param filename where the NVM backup should be stored * \param chiptype Type of chip to write to ZW_GECKO_CHIP_TYPE (700 serries) or ZW_CHIP_TYPE (500 serries) */ -bool ZW_NVM_Backup(const char* filename,uint8_t chiptype); +bool ZW_NVM_Backup(const char *filename, uint8_t chiptype); /** * Write the NVM from an input file to a 500 or 700 series device * * \param filename from where the NVM backup should be restored * \param chiptype Type of chip to write to ZW_GECKO_CHIP_TYPE (700 serries) or ZW_CHIP_TYPE (500 serries) */ -bool ZW_NVM_Restore(const char* filename,uint8_t chiptype); +bool ZW_NVM_Restore(const char *filename, uint8_t chiptype); #endif diff --git a/applications/zpc/components/zwave_api/external/ext_util.c b/applications/zpc/components/zwave_api/external/ext_util.c index bb40eba4c..802066f20 100644 --- a/applications/zpc/components/zwave_api/external/ext_util.c +++ b/applications/zpc/components/zwave_api/external/ext_util.c @@ -9,8 +9,7 @@ */ unsigned int min(unsigned int x, unsigned int y) { - if (y < x) - { + if (y < x) { return y; } return x; diff --git a/applications/zpc/components/zwave_api/external/ext_util.h b/applications/zpc/components/zwave_api/external/ext_util.h index cdbb135f5..fca1c2057 100644 --- a/applications/zpc/components/zwave_api/external/ext_util.h +++ b/applications/zpc/components/zwave_api/external/ext_util.h @@ -1,6 +1,5 @@ // CLEANUP: Moved from Serialapi.c - /** * Return the minimum of two unsigned numbers. * Preferring function to macro to avoid double evaluation. No need to performance optimize diff --git a/applications/zpc/components/zwave_api/include/zwapi_init.h b/applications/zpc/components/zwave_api/include/zwapi_init.h index fca0d2abe..4e77c364c 100644 --- a/applications/zpc/components/zwave_api/include/zwapi_init.h +++ b/applications/zpc/components/zwave_api/include/zwapi_init.h @@ -271,7 +271,8 @@ typedef struct zwapi_callbacks { application_command_handler_function application_command_handler; application_controller_update_function application_controller_update; application_command_handler_function application_command_handler_bridge; - protocol_cc_encryption_command_handler_function protocol_cc_encryption_request; + protocol_cc_encryption_command_handler_function + protocol_cc_encryption_request; void (*zwapi_started)(const uint8_t *pData, uint8_t pLen); void (*poll_request)(); } zwapi_callbacks_t; diff --git a/applications/zpc/components/zwave_api/include/zwapi_protocol_basis.h b/applications/zpc/components/zwave_api/include/zwapi_protocol_basis.h index 5f191f682..d537328f0 100644 --- a/applications/zpc/components/zwave_api/include/zwapi_protocol_basis.h +++ b/applications/zpc/components/zwave_api/include/zwapi_protocol_basis.h @@ -82,8 +82,8 @@ typedef enum { NODEID_8BITS = 1, NODEID_16BITS = 2 } zwave_node_id_basetype_t; /// @name Chip type definitions for 700-series ///@{ -#define ZW_GECKO_CHIP_TYPE(x) ((x == 7) || (x == 8)) -#define ZW_GECKO_CHIP_700 7 +#define ZW_GECKO_CHIP_TYPE(x) ((x == 7) || (x == 8)) +#define ZW_GECKO_CHIP_700 7 #define ZW_GECKO_CHIP_REVISION 0 ///@} diff --git a/applications/zpc/components/zwave_api/include/zwapi_protocol_controller.h b/applications/zpc/components/zwave_api/include/zwapi_protocol_controller.h index e0af3ec07..a353a281e 100644 --- a/applications/zpc/components/zwave_api/include/zwapi_protocol_controller.h +++ b/applications/zpc/components/zwave_api/include/zwapi_protocol_controller.h @@ -1030,11 +1030,10 @@ sl_status_t zwapi_set_virtual_node_application_node_information( * @param payloadLength decrypted payload length * @param payload decrypted payload */ -sl_status_t zwapi_transfer_protocol_cc( - const zwave_node_id_t srcNode, - const uint8_t decryptionKey, - uint8_t payloadLength, - const uint8_t * const payload); +sl_status_t zwapi_transfer_protocol_cc(const zwave_node_id_t srcNode, + const uint8_t decryptionKey, + uint8_t payloadLength, + const uint8_t *const payload); /** * @brief Set the NLS State of the node in the controller NVM @@ -1053,7 +1052,9 @@ sl_status_t zwapi_enable_node_nls(const zwave_node_id_t nodeId); * @param nls_support NLS support pointer to be filled * */ -sl_status_t zwapi_get_node_nls(const zwave_node_id_t nodeId, uint8_t* nls_state, uint8_t* nls_support); +sl_status_t zwapi_get_node_nls(const zwave_node_id_t nodeId, + uint8_t *nls_state, + uint8_t *nls_support); /** * @brief Get the NLS State of the nodes of a network in the controller NVM diff --git a/applications/zpc/components/zwave_api/platform/posix/zwapi_serial.c b/applications/zpc/components/zwave_api/platform/posix/zwapi_serial.c index 29b50861c..d83db1f3d 100644 --- a/applications/zpc/components/zwave_api/platform/posix/zwapi_serial.c +++ b/applications/zpc/components/zwave_api/platform/posix/zwapi_serial.c @@ -52,11 +52,12 @@ static char last_used_serial_port[PATH_MAX] = {0}; * @return true if a is lesser than b + ms * @return false if a is greater or equal to b + ms */ -static bool zwapi_serial_timeval_a_lt_b_milis( - const struct timeval *a, const struct timeval *b, unsigned int ms) +static bool zwapi_serial_timeval_a_lt_b_milis(const struct timeval *a, + const struct timeval *b, + unsigned int ms) { const struct timeval adder = {ms / 1000, (ms % 1000) * 1000}; - struct timeval result = {0}; + struct timeval result = {0}; timeradd(b, &adder, &result); return timercmp(a, &result, <); } @@ -148,13 +149,14 @@ int zwapi_serial_init(const char *port) return serial_fd; } -static void zwapi_serial_log_timestamp(const struct timeval *cur_time) { +static void zwapi_serial_log_timestamp(const struct timeval *cur_time) +{ if (log_fd) { char timebuf[28]; struct tm timeinfo; localtime_r(&cur_time->tv_sec, &timeinfo); strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", &timeinfo); - fprintf(log_fd, "%s:%06d", timebuf, (int) cur_time->tv_usec); + fprintf(log_fd, "%s:%06d", timebuf, (int)cur_time->tv_usec); } } @@ -165,12 +167,16 @@ sl_status_t zwapi_serial_log_to_file_enable(const char *filename) return SL_STATUS_OK; } if (log_fd) { - sl_log_error(LOG_TAG, "Tried to enable log to file, while it is already enabled"); + sl_log_error(LOG_TAG, + "Tried to enable log to file, while it is already enabled"); return SL_STATUS_ALREADY_INITIALIZED; } log_fd = fopen(filename, "a"); if (NULL == log_fd) { - sl_log_error(LOG_TAG, "Failed to open file '%s' Error: %s", filename, strerror(errno)); + sl_log_error(LOG_TAG, + "Failed to open file '%s' Error: %s", + filename, + strerror(errno)); return SL_STATUS_FAIL; } fprintf(log_fd, "\n"); @@ -234,7 +240,8 @@ int zwapi_serial_get_buffer(uint8_t *c, int len) if (log_fd) { struct timeval cur_time; gettimeofday(&cur_time, NULL); - if (log_dir == 1 || !zwapi_serial_timeval_a_lt_b_milis(&cur_time, &last_time, 3)) { + if (log_dir == 1 + || !zwapi_serial_timeval_a_lt_b_milis(&cur_time, &last_time, 3)) { fprintf(log_fd, "\n"); zwapi_serial_log_timestamp(&cur_time); fprintf(log_fd, " R "); @@ -256,8 +263,7 @@ void zwapi_serial_put_buffer(uint8_t *c, int len) int res = write(serial_fd, c, len); if (res < 0) { sl_log_error(LOG_TAG, "Serial Write Error: %s", strerror(errno)); - } - else { + } else { n += res; if (n == len) { break; @@ -269,7 +275,8 @@ void zwapi_serial_put_buffer(uint8_t *c, int len) if (log_fd) { struct timeval cur_time; gettimeofday(&cur_time, NULL); - if (log_dir == 0 || !zwapi_serial_timeval_a_lt_b_milis(&cur_time, &last_time, 200)) { + if (log_dir == 0 + || !zwapi_serial_timeval_a_lt_b_milis(&cur_time, &last_time, 200)) { fprintf(log_fd, "\n"); zwapi_serial_log_timestamp(&cur_time); fprintf(log_fd, " W "); diff --git a/applications/zpc/components/zwave_api/platform/posix/zwapi_timestamp.c b/applications/zpc/components/zwave_api/platform/posix/zwapi_timestamp.c index 4a105ec7c..1bf730df6 100644 --- a/applications/zpc/components/zwave_api/platform/posix/zwapi_timestamp.c +++ b/applications/zpc/components/zwave_api/platform/posix/zwapi_timestamp.c @@ -18,7 +18,6 @@ #include #include "sl_log.h" - void zwapi_timestamp_get(zwapi_timestamp_t *timestamp, int period_ms) { struct timespec now; diff --git a/applications/zpc/components/zwave_api/src/zwapi_connection.c b/applications/zpc/components/zwave_api/src/zwapi_connection.c index 1f503eaba..ceefb85da 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_connection.c +++ b/applications/zpc/components/zwave_api/src/zwapi_connection.c @@ -143,7 +143,8 @@ void zwapi_connection_tx( = sizeof(tx_buffer) - 4 - 1; // 255 - 5 = 250 if (len > MAX_PAYLOAD_LEN_ALLOWED) { sl_log_error(LOG_TAG, - "zwapi_connection_tx: Buffer overflow prevented: Payload length (%u) exceeds " + "zwapi_connection_tx: Buffer overflow prevented: Payload " + "length (%u) exceeds " "maximum allowed (%zu).\n", len, MAX_PAYLOAD_LEN_ALLOWED); diff --git a/applications/zpc/components/zwave_api/src/zwapi_func_ids.h b/applications/zpc/components/zwave_api/src/zwapi_func_ids.h index 3e8f248ad..ac4e49807 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_func_ids.h +++ b/applications/zpc/components/zwave_api/src/zwapi_func_ids.h @@ -5,7 +5,6 @@ #ifndef _ZW_SERIALAPI_H_ #define _ZW_SERIALAPI_H_ - /** * @addtogroup ZWaveAPI * @{ @@ -15,38 +14,38 @@ #define SOF 0x01 ///< Start Of Frame #define ACK 0x06 ///< Acknowledge successful frame reception -#define NAK 0x15 ///< Not Acknowledge successful frame reception - please retransmit... +#define NAK \ + 0x15 ///< Not Acknowledge successful frame reception - please retransmit... #define CAN 0x18 ///< Frame received (from host) was dropped - waiting for ACK ///@addtogroup FT Frame Types /// @{ -#define REQUEST 0x00 -#define RESPONSE 0x01 +#define REQUEST 0x00 +#define RESPONSE 0x01 ///@} ///@addtogroup GET_INIT_DATA_FLAG /// Flags used in FUNC_ID_SERIAL_API_GET_INIT_DATA functionality /// @{ -#define GET_INIT_DATA_FLAG_SLAVE_API 0x01 -#define GET_INIT_DATA_FLAG_TIMER_SUPPORT 0x02 -#define GET_INIT_DATA_FLAG_CONTROLLER_STATUS 0x04 /* Obsolete. USE next */ -#define GET_INIT_DATA_FLAG_SECONDARY_CTRL 0x04 -#define GET_INIT_DATA_FLAG_IS_SUC 0x08 +#define GET_INIT_DATA_FLAG_SLAVE_API 0x01 +#define GET_INIT_DATA_FLAG_TIMER_SUPPORT 0x02 +#define GET_INIT_DATA_FLAG_CONTROLLER_STATUS 0x04 /* Obsolete. USE next */ +#define GET_INIT_DATA_FLAG_SECONDARY_CTRL 0x04 +#define GET_INIT_DATA_FLAG_IS_SUC 0x08 ///@} /** * Firmware update functionality specifics * Enum definitions for Firmware Update functionality selector; firmwareUpdateFunction */ -typedef enum -{ - FIRMWARE_UPDATE_NVM_INIT = 0, - FIRMWARE_UPDATE_NVM_SET_NEW_IMAGE = 1, - FIRMWARE_UPDATE_NVM_GET_NEW_IMAGE = 2, - FIRMWARE_UPDATE_NVM_UPDATE_CRC16 = 3, +typedef enum { + FIRMWARE_UPDATE_NVM_INIT = 0, + FIRMWARE_UPDATE_NVM_SET_NEW_IMAGE = 1, + FIRMWARE_UPDATE_NVM_GET_NEW_IMAGE = 2, + FIRMWARE_UPDATE_NVM_UPDATE_CRC16 = 3, FIRMWARE_UPDATE_NVM_IS_VALID_CRC16 = 4, - FIRMWARE_UPDATE_NVM_WRITE = 5, - FIRMWARE_UPDATE_NVM_UNKNOWN = 0xFF + FIRMWARE_UPDATE_NVM_WRITE = 5, + FIRMWARE_UPDATE_NVM_UNKNOWN = 0xFF } FIRMWARE_UPDATE_NVM_T; /** @@ -54,342 +53,339 @@ typedef enum * Function IDs * @{ */ -#define FUNC_ID_SERIAL_API_GET_INIT_DATA 0x02 -#define FUNC_ID_SERIAL_API_APPL_NODE_INFORMATION 0x03 -#define FUNC_ID_APPLICATION_COMMAND_HANDLER 0x04 -#define FUNC_ID_ZW_GET_CONTROLLER_CAPABILITIES 0x05 +#define FUNC_ID_SERIAL_API_GET_INIT_DATA 0x02 +#define FUNC_ID_SERIAL_API_APPL_NODE_INFORMATION 0x03 +#define FUNC_ID_APPLICATION_COMMAND_HANDLER 0x04 +#define FUNC_ID_ZW_GET_CONTROLLER_CAPABILITIES 0x05 /* SERIAL API ver 4 added - START */ -#define FUNC_ID_SERIAL_API_SET_TIMEOUTS 0x06 -#define FUNC_ID_SERIAL_API_GET_CAPABILITIES 0x07 -#define FUNC_ID_SERIAL_API_SOFT_RESET 0x08 +#define FUNC_ID_SERIAL_API_SET_TIMEOUTS 0x06 +#define FUNC_ID_SERIAL_API_GET_CAPABILITIES 0x07 +#define FUNC_ID_SERIAL_API_SOFT_RESET 0x08 /* SERIAL API ver 4 added - END */ -#define FUNC_ID_ZW_GET_PROTOCOL_VERSION 0x09 +#define FUNC_ID_ZW_GET_PROTOCOL_VERSION 0x09 /* Function ID for startup message */ -#define FUNC_ID_SERIAL_API_STARTED 0x0A -#define FUNC_ID_SERIAL_API_SETUP 0x0B +#define FUNC_ID_SERIAL_API_STARTED 0x0A +#define FUNC_ID_SERIAL_API_SETUP 0x0B -#define FUNC_ID_SERIAL_API_APPL_NODE_INFORMATION_CMD_CLASSES 0x0C +#define FUNC_ID_SERIAL_API_APPL_NODE_INFORMATION_CMD_CLASSES 0x0C -#define FUNC_ID_ZW_SEND_DATA_EX 0x0E -#define FUNC_ID_ZW_SEND_DATA_MULTI_EX 0x0F +#define FUNC_ID_ZW_SEND_DATA_EX 0x0E +#define FUNC_ID_ZW_SEND_DATA_MULTI_EX 0x0F -#define FUNC_ID_ZW_SET_RF_RECEIVE_MODE 0x10 -#define FUNC_ID_ZW_SET_SLEEP_MODE 0x11 -#define FUNC_ID_ZW_SEND_NODE_INFORMATION 0x12 -#define FUNC_ID_ZW_SEND_DATA 0x13 -#define FUNC_ID_ZW_SEND_DATA_MULTI 0x14 -#define FUNC_ID_ZW_GET_VERSION 0x15 +#define FUNC_ID_ZW_SET_RF_RECEIVE_MODE 0x10 +#define FUNC_ID_ZW_SET_SLEEP_MODE 0x11 +#define FUNC_ID_ZW_SEND_NODE_INFORMATION 0x12 +#define FUNC_ID_ZW_SEND_DATA 0x13 +#define FUNC_ID_ZW_SEND_DATA_MULTI 0x14 +#define FUNC_ID_ZW_GET_VERSION 0x15 /* SERIAL API ver 4 added - START */ -#define FUNC_ID_ZW_SEND_DATA_ABORT 0x16 +#define FUNC_ID_ZW_SEND_DATA_ABORT 0x16 // FUNC_ID_ZW_RF_POWER_LEVEL_SET is no longer supported -#define FUNC_ID_ZW_RF_POWER_LEVEL_SET 0x17 -#define FUNC_ID_ZW_SEND_DATA_META 0x18 +#define FUNC_ID_ZW_RF_POWER_LEVEL_SET 0x17 +#define FUNC_ID_ZW_SEND_DATA_META 0x18 /* SERIAL API ver 4 added - END */ -#define FUNC_ID_ZW_RESERVED_SD 0x19 -#define FUNC_ID_ZW_RESERVED_SDM 0x1A -#define FUNC_ID_ZW_RESERVED_SRI 0x1B +#define FUNC_ID_ZW_RESERVED_SD 0x19 +#define FUNC_ID_ZW_RESERVED_SDM 0x1A +#define FUNC_ID_ZW_RESERVED_SRI 0x1B -#define FUNC_ID_ZW_SET_ROUTING_INFO 0x1B +#define FUNC_ID_ZW_SET_ROUTING_INFO 0x1B -#define FUNC_ID_ZW_GET_RANDOM 0x1C -#define FUNC_ID_ZW_RANDOM 0x1D -#define FUNC_ID_ZW_RF_POWER_LEVEL_REDISCOVERY_SET 0x1E +#define FUNC_ID_ZW_GET_RANDOM 0x1C +#define FUNC_ID_ZW_RANDOM 0x1D +#define FUNC_ID_ZW_RF_POWER_LEVEL_REDISCOVERY_SET 0x1E -#define FUNC_ID_MEMORY_GET_ID 0x20 -#define FUNC_ID_MEMORY_GET_BYTE 0x21 -#define FUNC_ID_MEMORY_PUT_BYTE 0x22 -#define FUNC_ID_MEMORY_GET_BUFFER 0x23 -#define FUNC_ID_MEMORY_PUT_BUFFER 0x24 +#define FUNC_ID_MEMORY_GET_ID 0x20 +#define FUNC_ID_MEMORY_GET_BYTE 0x21 +#define FUNC_ID_MEMORY_PUT_BYTE 0x22 +#define FUNC_ID_MEMORY_GET_BUFFER 0x23 +#define FUNC_ID_MEMORY_PUT_BUFFER 0x24 /* Unimplemented - START */ -#define FUNC_ID_SERIAL_API_GET_APPL_HOST_MEMORY_OFFSET 0x25 -#define FUNC_ID_DEBUG_OUTPUT 0x26 +#define FUNC_ID_SERIAL_API_GET_APPL_HOST_MEMORY_OFFSET 0x25 +#define FUNC_ID_DEBUG_OUTPUT 0x26 /* Unimplemented - END */ -#define FUNC_ID_AUTO_PROGRAMMING 0x27 - -#define FUNC_ID_NVR_GET_VALUE 0x28 - -#define FUNC_ID_NVM_GET_ID 0x29 -#define FUNC_ID_NVM_EXT_READ_LONG_BUFFER 0x2A -#define FUNC_ID_NVM_EXT_WRITE_LONG_BUFFER 0x2B -#define FUNC_ID_NVM_EXT_READ_LONG_BYTE 0x2C -#define FUNC_ID_NVM_EXT_WRITE_LONG_BYTE 0x2D -#define FUNC_ID_NVM_BACKUP_RESTORE 0x2E - -#define FUNC_ID_ZW_NVR_GET_APP_VALUE 0x2F - -#define FUNC_ID_CLOCK_SET 0x30 -#define FUNC_ID_CLOCK_GET 0x31 -#define FUNC_ID_CLOCK_CMP 0x32 -#define FUNC_ID_RTC_TIMER_CREATE 0x33 -#define FUNC_ID_RTC_TIMER_READ 0x34 -#define FUNC_ID_RTC_TIMER_DELETE 0x35 -#define FUNC_ID_RTC_TIMER_CALL 0x36 - -#define FUNC_ID_CLEAR_TX_TIMERS 0x37 -#define FUNC_ID_GET_TX_TIMERS 0x38 - -#define FUNC_ID_ZW_CLEAR_NETWORK_STATS 0x39 -#define FUNC_ID_ZW_GET_NETWORK_STATS 0x3A -#define FUNC_ID_ZW_GET_BACKGROUND_RSSI 0x3B -#define FUNC_ID_ZW_SET_LISTEN_BEFORE_TALK_THRESHOLD 0x3C -#define FUNC_ID_NVM_EXT_BACKUP_RESTORE 0x3D -#define FUNC_ID_ZW_REMOVE_NODE_ID_FROM_NETWORK 0x3F - -#define FUNC_ID_ZW_SET_LEARN_NODE_STATE 0x40 -#define FUNC_ID_ZW_GET_NODE_PROTOCOL_INFO 0x41 -#define FUNC_ID_ZW_SET_DEFAULT 0x42 -#define FUNC_ID_ZW_NEW_CONTROLLER 0x43 +#define FUNC_ID_AUTO_PROGRAMMING 0x27 + +#define FUNC_ID_NVR_GET_VALUE 0x28 + +#define FUNC_ID_NVM_GET_ID 0x29 +#define FUNC_ID_NVM_EXT_READ_LONG_BUFFER 0x2A +#define FUNC_ID_NVM_EXT_WRITE_LONG_BUFFER 0x2B +#define FUNC_ID_NVM_EXT_READ_LONG_BYTE 0x2C +#define FUNC_ID_NVM_EXT_WRITE_LONG_BYTE 0x2D +#define FUNC_ID_NVM_BACKUP_RESTORE 0x2E + +#define FUNC_ID_ZW_NVR_GET_APP_VALUE 0x2F + +#define FUNC_ID_CLOCK_SET 0x30 +#define FUNC_ID_CLOCK_GET 0x31 +#define FUNC_ID_CLOCK_CMP 0x32 +#define FUNC_ID_RTC_TIMER_CREATE 0x33 +#define FUNC_ID_RTC_TIMER_READ 0x34 +#define FUNC_ID_RTC_TIMER_DELETE 0x35 +#define FUNC_ID_RTC_TIMER_CALL 0x36 + +#define FUNC_ID_CLEAR_TX_TIMERS 0x37 +#define FUNC_ID_GET_TX_TIMERS 0x38 + +#define FUNC_ID_ZW_CLEAR_NETWORK_STATS 0x39 +#define FUNC_ID_ZW_GET_NETWORK_STATS 0x3A +#define FUNC_ID_ZW_GET_BACKGROUND_RSSI 0x3B +#define FUNC_ID_ZW_SET_LISTEN_BEFORE_TALK_THRESHOLD 0x3C +#define FUNC_ID_NVM_EXT_BACKUP_RESTORE 0x3D +#define FUNC_ID_ZW_REMOVE_NODE_ID_FROM_NETWORK 0x3F + +#define FUNC_ID_ZW_SET_LEARN_NODE_STATE 0x40 +#define FUNC_ID_ZW_GET_NODE_PROTOCOL_INFO 0x41 +#define FUNC_ID_ZW_SET_DEFAULT 0x42 +#define FUNC_ID_ZW_NEW_CONTROLLER 0x43 // -#define FUNC_ID_ZW_REPLICATION_COMMAND_COMPLETE 0x44 -#define FUNC_ID_ZW_REPLICATION_SEND_DATA 0x45 +#define FUNC_ID_ZW_REPLICATION_COMMAND_COMPLETE 0x44 +#define FUNC_ID_ZW_REPLICATION_SEND_DATA 0x45 // -#define FUNC_ID_ZW_ASSIGN_RETURN_ROUTE 0x46 -#define FUNC_ID_ZW_DELETE_RETURN_ROUTE 0x47 -#define FUNC_ID_ZW_REQUEST_NODE_NEIGHBOR_UPDATE 0x48 -#define FUNC_ID_ZW_REQUEST_NODETYPE_NEIGHBOR_UPDATE 0x68 -#define FUNC_ID_ZW_APPLICATION_UPDATE 0x49 +#define FUNC_ID_ZW_ASSIGN_RETURN_ROUTE 0x46 +#define FUNC_ID_ZW_DELETE_RETURN_ROUTE 0x47 +#define FUNC_ID_ZW_REQUEST_NODE_NEIGHBOR_UPDATE 0x48 +#define FUNC_ID_ZW_REQUEST_NODETYPE_NEIGHBOR_UPDATE 0x68 +#define FUNC_ID_ZW_APPLICATION_UPDATE 0x49 /** @deprecated Use ZW_APPLICATION_UPDATE */ -#define FUNC_ID_ZW_APPLICATION_CONTROLLER_UPDATE 0x49 +#define FUNC_ID_ZW_APPLICATION_CONTROLLER_UPDATE 0x49 -#define FUNC_ID_ZW_ADD_NODE_TO_NETWORK 0x4A -#define FUNC_ID_ZW_REMOVE_NODE_FROM_NETWORK 0x4B -#define FUNC_ID_ZW_CREATE_NEW_PRIMARY 0x4C -#define FUNC_ID_ZW_CONTROLLER_CHANGE 0x4D +#define FUNC_ID_ZW_ADD_NODE_TO_NETWORK 0x4A +#define FUNC_ID_ZW_REMOVE_NODE_FROM_NETWORK 0x4B +#define FUNC_ID_ZW_CREATE_NEW_PRIMARY 0x4C +#define FUNC_ID_ZW_CONTROLLER_CHANGE 0x4D -#define FUNC_ID_ZW_RESERVED_FN 0x4E +#define FUNC_ID_ZW_RESERVED_FN 0x4E /* Devkit 6.6x */ -#define FUNC_ID_ZW_ASSIGN_PRIORITY_RETURN_ROUTE 0x4F +#define FUNC_ID_ZW_ASSIGN_PRIORITY_RETURN_ROUTE 0x4F /* Slave only */ -#define FUNC_ID_ZW_SET_LEARN_MODE 0x50 +#define FUNC_ID_ZW_SET_LEARN_MODE 0x50 /* Slave only end */ -#define FUNC_ID_ZW_ASSIGN_SUC_RETURN_ROUTE 0x51 -#define FUNC_ID_ZW_ENABLE_SUC 0x52 -#define FUNC_ID_ZW_REQUEST_NETWORK_UPDATE 0x53 -#define FUNC_ID_ZW_SET_SUC_NODE_ID 0x54 -#define FUNC_ID_ZW_DELETE_SUC_RETURN_ROUTE 0x55 -#define FUNC_ID_ZW_GET_SUC_NODE_ID 0x56 -#define FUNC_ID_ZW_SEND_SUC_ID 0x57 +#define FUNC_ID_ZW_ASSIGN_SUC_RETURN_ROUTE 0x51 +#define FUNC_ID_ZW_ENABLE_SUC 0x52 +#define FUNC_ID_ZW_REQUEST_NETWORK_UPDATE 0x53 +#define FUNC_ID_ZW_SET_SUC_NODE_ID 0x54 +#define FUNC_ID_ZW_DELETE_SUC_RETURN_ROUTE 0x55 +#define FUNC_ID_ZW_GET_SUC_NODE_ID 0x56 +#define FUNC_ID_ZW_SEND_SUC_ID 0x57 /* Devkit 6.6x */ -#define FUNC_ID_ZW_ASSIGN_PRIORITY_SUC_RETURN_ROUTE 0x58 +#define FUNC_ID_ZW_ASSIGN_PRIORITY_SUC_RETURN_ROUTE 0x58 /* Obsolete - Not available in devkit 6.6x+ */ -#define FUNC_ID_ZW_REDISCOVERY_NEEDED 0x59 +#define FUNC_ID_ZW_REDISCOVERY_NEEDED 0x59 -#define FUNC_ID_ZW_REQUEST_NODE_NEIGHBOR_UPDATE_OPTION 0x5A +#define FUNC_ID_ZW_REQUEST_NODE_NEIGHBOR_UPDATE_OPTION 0x5A /* Slave only */ -#define FUNC_ID_ZW_SUPPORT9600_ONLY 0x5B +#define FUNC_ID_ZW_SUPPORT9600_ONLY 0x5B /* Slave only end */ /* Enhanced/Routing Slave only */ -#define FUNC_ID_ZW_REQUEST_NEW_ROUTE_DESTINATIONS 0x5C -#define FUNC_ID_ZW_IS_NODE_WITHIN_DIRECT_RANGE 0x5D +#define FUNC_ID_ZW_REQUEST_NEW_ROUTE_DESTINATIONS 0x5C +#define FUNC_ID_ZW_IS_NODE_WITHIN_DIRECT_RANGE 0x5D /* Enhanced/Routing Slave only end */ -#define FUNC_ID_ZW_EXPLORE_REQUEST_INCLUSION 0x5E -#define FUNC_ID_ZW_EXPLORE_REQUEST_EXCLUSION 0x5F +#define FUNC_ID_ZW_EXPLORE_REQUEST_INCLUSION 0x5E +#define FUNC_ID_ZW_EXPLORE_REQUEST_EXCLUSION 0x5F -#define FUNC_ID_ZW_REQUEST_NODE_INFO 0x60 -#define FUNC_ID_ZW_REMOVE_FAILED_NODE_ID 0x61 -#define FUNC_ID_ZW_IS_FAILED_NODE_ID 0x62 -#define FUNC_ID_ZW_REPLACE_FAILED_NODE 0x63 +#define FUNC_ID_ZW_REQUEST_NODE_INFO 0x60 +#define FUNC_ID_ZW_REMOVE_FAILED_NODE_ID 0x61 +#define FUNC_ID_ZW_IS_FAILED_NODE_ID 0x62 +#define FUNC_ID_ZW_REPLACE_FAILED_NODE 0x63 /* In 6.0x the function id was wrong so we need to support this wrong function id as well in the future */ -#define FUNC_ID_ZW_SET_ROUTING_MAX_6_00 0x65 +#define FUNC_ID_ZW_SET_ROUTING_MAX_6_00 0x65 /* */ -#define FUNC_ID_ZW_IS_PRIMARY_CTRL 0x66 +#define FUNC_ID_ZW_IS_PRIMARY_CTRL 0x66 -#define FUNC_ID_ZW_AES_ECB 0x67 +#define FUNC_ID_ZW_AES_ECB 0x67 -#define FUNC_ID_ZW_TRANSFER_PROTOCOL_CC 0x69 +#define FUNC_ID_ZW_TRANSFER_PROTOCOL_CC 0x69 -#define FUNC_ID_ZW_ENABLE_NODE_NLS 0x6A -#define FUNC_ID_ZW_GET_NODE_NLS_STATE 0x6B -#define FUNC_ID_ZW_REQUEST_PROTOCOL_CC_ENCRYPTION 0x6C -#define FUNC_ID_ZW_SEND_PROTOCOL_DATA 0xAC -#define FUNC_ID_ZW_GET_NLS_NODES 0xC0 +#define FUNC_ID_ZW_ENABLE_NODE_NLS 0x6A +#define FUNC_ID_ZW_GET_NODE_NLS_STATE 0x6B +#define FUNC_ID_ZW_REQUEST_PROTOCOL_CC_ENCRYPTION 0x6C +#define FUNC_ID_ZW_SEND_PROTOCOL_DATA 0xAC +#define FUNC_ID_ZW_GET_NLS_NODES 0xC0 -#define FUNC_ID_TIMER_START 0x70 -#define FUNC_ID_TIMER_RESTART 0x71 -#define FUNC_ID_TIMER_CANCEL 0x72 -#define FUNC_ID_TIMER_CALL 0x73 +#define FUNC_ID_TIMER_START 0x70 +#define FUNC_ID_TIMER_RESTART 0x71 +#define FUNC_ID_TIMER_CANCEL 0x72 +#define FUNC_ID_TIMER_CALL 0x73 /* Firmware Update API */ -#define FUNC_ID_ZW_FIRMWARE_UPDATE_NVM 0x78 +#define FUNC_ID_ZW_FIRMWARE_UPDATE_NVM 0x78 /* Installer API */ -#define FUNC_ID_GET_ROUTING_TABLE_LINE 0x80 -#define FUNC_ID_GET_TX_COUNTER 0x81 -#define FUNC_ID_RESET_TX_COUNTER 0x82 -#define FUNC_ID_STORE_NODEINFO 0x83 -#define FUNC_ID_STORE_HOMEID 0x84 +#define FUNC_ID_GET_ROUTING_TABLE_LINE 0x80 +#define FUNC_ID_GET_TX_COUNTER 0x81 +#define FUNC_ID_RESET_TX_COUNTER 0x82 +#define FUNC_ID_STORE_NODEINFO 0x83 +#define FUNC_ID_STORE_HOMEID 0x84 /* Installer API only end */ -#define FUNC_ID_LOCK_ROUTE_RESPONSE 0x90 +#define FUNC_ID_LOCK_ROUTE_RESPONSE 0x90 #ifdef ZW_ROUTING_DEMO /* Max hops in route */ -#define TRANSMIT_ROUTED_ATTEMPT 0x08 -#define FUNC_ID_ZW_SEND_DATA_ROUTE_DEMO 0x91 +#define TRANSMIT_ROUTED_ATTEMPT 0x08 +#define FUNC_ID_ZW_SEND_DATA_ROUTE_DEMO 0x91 #endif /* ZW_SetPriorityRoute/ZW_GetPriorityRoute replaces ZW_SetLastWorkingRoute/ZW_GetLastWorkingRoute */ -#define FUNC_ID_ZW_GET_PRIORITY_ROUTE 0x92 -#define FUNC_ID_ZW_SET_PRIORITY_ROUTE 0x93 +#define FUNC_ID_ZW_GET_PRIORITY_ROUTE 0x92 +#define FUNC_ID_ZW_SET_PRIORITY_ROUTE 0x93 /* NOTE: Obsoleted - BEGIN */ -#define FUNC_ID_ZW_GET_LAST_WORKING_ROUTE 0x92 -#define FUNC_ID_ZW_SET_LAST_WORKING_ROUTE 0x93 +#define FUNC_ID_ZW_GET_LAST_WORKING_ROUTE 0x92 +#define FUNC_ID_ZW_SET_LAST_WORKING_ROUTE 0x93 /* NOTE: Obsoleted - END */ -#define FUNC_ID_SERIAL_API_TEST 0x95 +#define FUNC_ID_SERIAL_API_TEST 0x95 -#define FUNC_ID_SERIAL_API_EXT 0x98 +#define FUNC_ID_SERIAL_API_EXT 0x98 /* DevKit 6.7x introduced - slave_enhanced_232 and slave_routing only */ -#define FUNC_ID_ZW_SECURITY_SETUP 0x9C -#define FUNC_ID_APPLICATION_SECURITY_EVENT 0x9D +#define FUNC_ID_ZW_SECURITY_SETUP 0x9C +#define FUNC_ID_APPLICATION_SECURITY_EVENT 0x9D /* ZW_CONTROLLER_BRIDGE only START */ -#define FUNC_ID_SERIAL_API_APPL_SLAVE_NODE_INFORMATION 0xA0 +#define FUNC_ID_SERIAL_API_APPL_SLAVE_NODE_INFORMATION 0xA0 /** @deprecated OBSOLETE: In DevKit 4.5x/6.0x Controller Bridge applications, this is obsoleted * by the FUNC_ID_APPLICATION_COMMAND_HANDLER_BRIDGE */ -#define FUNC_ID_APPLICATION_SLAVE_COMMAND_HANDLER 0xA1 -#define FUNC_ID_ZW_SEND_SLAVE_NODE_INFORMATION 0xA2 -#define FUNC_ID_ZW_SEND_SLAVE_DATA 0xA3 -#define FUNC_ID_ZW_SET_SLAVE_LEARN_MODE 0xA4 -#define FUNC_ID_ZW_GET_VIRTUAL_NODES 0xA5 -#define FUNC_ID_ZW_IS_VIRTUAL_NODE 0xA6 -#define FUNC_ID_ZW_RESERVED_SSD 0xA7 +#define FUNC_ID_APPLICATION_SLAVE_COMMAND_HANDLER 0xA1 +#define FUNC_ID_ZW_SEND_SLAVE_NODE_INFORMATION 0xA2 +#define FUNC_ID_ZW_SEND_SLAVE_DATA 0xA3 +#define FUNC_ID_ZW_SET_SLAVE_LEARN_MODE 0xA4 +#define FUNC_ID_ZW_GET_VIRTUAL_NODES 0xA5 +#define FUNC_ID_ZW_IS_VIRTUAL_NODE 0xA6 +#define FUNC_ID_ZW_RESERVED_SSD 0xA7 /* DevKit 4.5x/6.0x added - obsoletes FUNC_ID_APPLICATION_SLAVE_COMMAND_HANDLER and */ /* FUNC_ID_APPLICATION_COMMAND_HANDLER for the Controller Bridge applications as */ /* this handles both cases - only for 4.5x/6.0x based Controller Bridge applications */ -#define FUNC_ID_APPLICATION_COMMAND_HANDLER_BRIDGE 0xA8 +#define FUNC_ID_APPLICATION_COMMAND_HANDLER_BRIDGE 0xA8 /* DevKit 4.5x/6.0x added - Adds sourceNodeID to the parameter list */ -#define FUNC_ID_ZW_SEND_DATA_BRIDGE 0xA9 +#define FUNC_ID_ZW_SEND_DATA_BRIDGE 0xA9 /* Obsolete */ -#define FUNC_ID_ZW_SEND_DATA_META_BRIDGE 0xAA -#define FUNC_ID_ZW_SEND_DATA_MULTI_BRIDGE 0xAB +#define FUNC_ID_ZW_SEND_DATA_META_BRIDGE 0xAA +#define FUNC_ID_ZW_SEND_DATA_MULTI_BRIDGE 0xAB /* ZW_CONTROLLER_BRIDGE only END */ -#define FUNC_ID_PWR_SETSTOPMODE 0xB0 // ZW102 only -#define FUNC_ID_PWR_CLK_PD 0xB1 // ZW102 only -#define FUNC_ID_PWR_CLK_PUP 0xB2 // ZW102 only -#define FUNC_ID_PWR_SELECT_CLK 0xB3 // ZW102 only -#define FUNC_ID_ZW_SET_WUT_TIMEOUT 0xB4 -#define FUNC_ID_ZW_IS_WUT_KICKED 0xB5 // ZW201 only +#define FUNC_ID_PWR_SETSTOPMODE 0xB0 // ZW102 only +#define FUNC_ID_PWR_CLK_PD 0xB1 // ZW102 only +#define FUNC_ID_PWR_CLK_PUP 0xB2 // ZW102 only +#define FUNC_ID_PWR_SELECT_CLK 0xB3 // ZW102 only +#define FUNC_ID_ZW_SET_WUT_TIMEOUT 0xB4 +#define FUNC_ID_ZW_IS_WUT_KICKED 0xB5 // ZW201 only -#define FUNC_ID_ZW_WATCHDOG_ENABLE 0xB6 -#define FUNC_ID_ZW_WATCHDOG_DISABLE 0xB7 -#define FUNC_ID_ZW_WATCHDOG_KICK 0xB8 +#define FUNC_ID_ZW_WATCHDOG_ENABLE 0xB6 +#define FUNC_ID_ZW_WATCHDOG_DISABLE 0xB7 +#define FUNC_ID_ZW_WATCHDOG_KICK 0xB8 /** @deprecated Use FUNC_ID_ZW_INT_EXT_LEVEL_SET */ -#define FUNC_ID_ZW_SET_EXT_INT_LEVEL 0xB9 // ZW201 only -#define FUNC_ID_ZW_INT_EXT_LEVEL_SET 0xB9 +#define FUNC_ID_ZW_SET_EXT_INT_LEVEL 0xB9 // ZW201 only +#define FUNC_ID_ZW_INT_EXT_LEVEL_SET 0xB9 // FUNC_ID_ZW_RF_POWER_LEVEL_GET is no longer supported -#define FUNC_ID_ZW_RF_POWER_LEVEL_GET 0xBA -#define FUNC_ID_ZW_GET_NEIGHBOR_COUNT 0xBB -#define FUNC_ID_ZW_ARE_NODES_NEIGHBOURS 0xBC +#define FUNC_ID_ZW_RF_POWER_LEVEL_GET 0xBA +#define FUNC_ID_ZW_GET_NEIGHBOR_COUNT 0xBB +#define FUNC_ID_ZW_ARE_NODES_NEIGHBOURS 0xBC -#define FUNC_ID_ZW_TYPE_LIBRARY 0xBD -#define FUNC_ID_ZW_SEND_TEST_FRAME 0xBE -#define FUNC_ID_ZW_GET_PROTOCOL_STATUS 0xBF +#define FUNC_ID_ZW_TYPE_LIBRARY 0xBD +#define FUNC_ID_ZW_SEND_TEST_FRAME 0xBE +#define FUNC_ID_ZW_GET_PROTOCOL_STATUS 0xBF -#define FUNC_ID_ZW_SET_PROMISCUOUS_MODE 0xD0 +#define FUNC_ID_ZW_SET_PROMISCUOUS_MODE 0xD0 /* SERIAL API ver 5 added - START */ #define FUNC_ID_PROMISCUOUS_APPLICATION_COMMAND_HANDLER 0xD1 /* SERIAL API ver 5 added - END */ -#define FUNC_ID_ZW_WATCHDOG_START 0xD2 -#define FUNC_ID_ZW_WATCHDOG_STOP 0xD3 +#define FUNC_ID_ZW_WATCHDOG_START 0xD2 +#define FUNC_ID_ZW_WATCHDOG_STOP 0xD3 -#define FUNC_ID_ZW_SET_ROUTING_MAX 0xD4 +#define FUNC_ID_ZW_SET_ROUTING_MAX 0xD4 /* Unimplemented - START */ /* Obsoleted */ -#define FUNC_ID_ZW_GET_ROUTING_MAX 0xD5 +#define FUNC_ID_ZW_GET_ROUTING_MAX 0xD5 -#define FUNC_ID_PM_STAY_AWAKE 0xD7 -#define FUNC_ID_PM_CANCEL 0xD8 +#define FUNC_ID_PM_STAY_AWAKE 0xD7 +#define FUNC_ID_PM_CANCEL 0xD8 /* Unimplemented - END */ /* Allocated for setting the maximum number of 128sec ticks inbetween SmartStart inclusion requests. */ #define FUNC_ID_ZW_NETWORK_MANAGEMENT_SET_MAX_INCLUSION_REQUEST_INTERVALS 0xD6 -#define FUNC_ID_ZW_INITIATE_SHUTDOWN 0xD9 +#define FUNC_ID_ZW_INITIATE_SHUTDOWN 0xD9 -#define FUNC_ID_SERIAL_API_GET_LR_NODES 0xDA +#define FUNC_ID_SERIAL_API_GET_LR_NODES 0xDA -#define FUNC_ID_GET_LR_CHANNEL 0xDB -#define FUNC_ID_SET_LR_CHANNEL 0xDC +#define FUNC_ID_GET_LR_CHANNEL 0xDB +#define FUNC_ID_SET_LR_CHANNEL 0xDC -#define FUNC_ID_ZW_SET_LR_VIRTUAL_IDS 0xDD +#define FUNC_ID_ZW_SET_LR_VIRTUAL_IDS 0xDD -#define FUNC_ID_GET_DCDC_CONFIG 0xDE -#define FUNC_ID_SET_DCDC_CONFIG 0xDF +#define FUNC_ID_GET_DCDC_CONFIG 0xDE +#define FUNC_ID_SET_DCDC_CONFIG 0xDF /* Allocated for NUNIT test */ -#define FUNC_ID_ZW_NUNIT_CMD 0xE0 // DEPRECATED -#define FUNC_ID_ZW_NUNIT_INIT 0xE1 // DEPRECATED -#define FUNC_ID_ZW_NUNIT_LIST 0xE2 // DEPRECATED -#define FUNC_ID_ZW_NUNIT_RUN 0xE3 // DEPRECATED -#define FUNC_ID_ZW_NUNIT_END 0xE4 // DEPRECATED +#define FUNC_ID_ZW_NUNIT_CMD 0xE0 // DEPRECATED +#define FUNC_ID_ZW_NUNIT_INIT 0xE1 // DEPRECATED +#define FUNC_ID_ZW_NUNIT_LIST 0xE2 // DEPRECATED +#define FUNC_ID_ZW_NUNIT_RUN 0xE3 // DEPRECATED +#define FUNC_ID_ZW_NUNIT_END 0xE4 // DEPRECATED -#define FUNC_ID_ENABLE_RADIO_PTI 0xE7 -#define FUNC_ID_GET_RADIO_PTI 0xE8 +#define FUNC_ID_ENABLE_RADIO_PTI 0xE7 +#define FUNC_ID_GET_RADIO_PTI 0xE8 -#define FUNC_ID_SEND_NOP 0xE9 //Reserved. Command to be implemented in future. +#define FUNC_ID_SEND_NOP 0xE9 //Reserved. Command to be implemented in future. /* Allocated for Power Management */ -#define FUNC_ID_SERIAL_API_POWER_MANAGEMENT 0xEE -#define FUNC_ID_SERIAL_API_READY 0xEF +#define FUNC_ID_SERIAL_API_POWER_MANAGEMENT 0xEE +#define FUNC_ID_SERIAL_API_READY 0xEF /* Allocated for proprietary serial API commands */ -#define FUNC_ID_PROPRIETARY_0 0xF0 -#define FUNC_ID_PROPRIETARY_1 0xF1 -#define FUNC_ID_PROPRIETARY_2 0xF2 -#define FUNC_ID_PROPRIETARY_3 0xF3 -#define FUNC_ID_PROPRIETARY_4 0xF4 -#define FUNC_ID_PROPRIETARY_5 0xF5 -#define FUNC_ID_PROPRIETARY_6 0xF6 -#define FUNC_ID_PROPRIETARY_7 0xF7 -#define FUNC_ID_PROPRIETARY_8 0xF8 -#define FUNC_ID_PROPRIETARY_9 0xF9 -#define FUNC_ID_PROPRIETARY_A 0xFA -#define FUNC_ID_PROPRIETARY_B 0xFB -#define FUNC_ID_PROPRIETARY_C 0xFC -#define FUNC_ID_PROPRIETARY_D 0xFD -#define FUNC_ID_PROPRIETARY_E 0xFE - +#define FUNC_ID_PROPRIETARY_0 0xF0 +#define FUNC_ID_PROPRIETARY_1 0xF1 +#define FUNC_ID_PROPRIETARY_2 0xF2 +#define FUNC_ID_PROPRIETARY_3 0xF3 +#define FUNC_ID_PROPRIETARY_4 0xF4 +#define FUNC_ID_PROPRIETARY_5 0xF5 +#define FUNC_ID_PROPRIETARY_6 0xF6 +#define FUNC_ID_PROPRIETARY_7 0xF7 +#define FUNC_ID_PROPRIETARY_8 0xF8 +#define FUNC_ID_PROPRIETARY_9 0xF9 +#define FUNC_ID_PROPRIETARY_A 0xFA +#define FUNC_ID_PROPRIETARY_B 0xFB +#define FUNC_ID_PROPRIETARY_C 0xFC +#define FUNC_ID_PROPRIETARY_D 0xFD +#define FUNC_ID_PROPRIETARY_E 0xFE /* Illegal function ID */ -#define FUNC_ID_UNKNOWN 0xFF +#define FUNC_ID_UNKNOWN 0xFF ///@} /**size of the address field of NVM_BACKUP_RESTORE or NVM_EXT_BACKUP_RESTORE frames. Item value is the size in byte of the address field. */ -typedef enum -{ - NVM_BACKUP_RESTORE_ADDR_SIZE = 2, ///< 2 bytes for the legacy NVM backup & restore command - NVM_EXT_BACKUP_RESTORE_ADDR_SIZE = 4, ///< 4 bytes for the extended NVM backup & restore command +typedef enum { + NVM_BACKUP_RESTORE_ADDR_SIZE + = 2, ///< 2 bytes for the legacy NVM backup & restore command + NVM_EXT_BACKUP_RESTORE_ADDR_SIZE + = 4, ///< 4 bytes for the extended NVM backup & restore command } nvm_backup_restore_addr_size_t; - ///@} ///@} - - #endif /*_ZW_SERIALAPI_H_*/ diff --git a/applications/zpc/components/zwave_api/src/zwapi_init.c b/applications/zpc/components/zwave_api/src/zwapi_init.c index 0d38c0a94..eb1990c16 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_init.c +++ b/applications/zpc/components/zwave_api/src/zwapi_init.c @@ -136,7 +136,7 @@ bool zwapi_poll() zwapi_session_enqueue_rx_frames(); bool more_frames = zwapi_session_dequeue_frame(&frame, &len); - if (frame && len >=1) { + if (frame && len >= 1) { zwave_api_protocol_rx_dispatch(frame, len); free(frame); } @@ -190,8 +190,8 @@ sl_status_t zwapi_refresh_capabilities(void) * One or more Serial API Request(s) could have been stored during the execution of: * zwapi_session_send_frame_with_response(FUNC_ID_SERIAL_API_GET_CAPABILITIES, ...) * (in the case of a FUNC_ID_SERIAL_API_STARTED request, this can break ZPC network management state machine later) - */ - + */ + zwapi_session_flush_queue(); if (zwapi_support_command_func(FUNC_ID_SERIAL_API_SETUP)) { diff --git a/applications/zpc/components/zwave_api/src/zwapi_protocol_controller.c b/applications/zpc/components/zwave_api/src/zwapi_protocol_controller.c index 86afbd364..a80f8f454 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_protocol_controller.c +++ b/applications/zpc/components/zwave_api/src/zwapi_protocol_controller.c @@ -25,13 +25,13 @@ #define LOG_TAG "zwave_protocol_controller" sl_status_t zwapi_request_neighbor_update(zwave_node_id_t bNodeID, - void (*completedFunc)(uint8_t)) + void (*completedFunc)(uint8_t)) { uint8_t func_id, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, bNodeID); - request_buffer[index++] = func_id; + request_buffer[index++] = func_id; zwapi_request_neighbor_update_callback = completedFunc; return zwapi_send_command(FUNC_ID_ZW_REQUEST_NODE_NEIGHBOR_UPDATE, @@ -158,12 +158,13 @@ sl_status_t zwapi_remove_node_from_network(uint8_t bMode, index); } -uint8_t zwapi_remove_failed_node(zwave_node_id_t NodeID, void (*completedFunc)(uint8_t)) +uint8_t zwapi_remove_failed_node(zwave_node_id_t NodeID, + void (*completedFunc)(uint8_t)) { uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, NodeID); request_buffer[index++] = func_id; zwapi_remove_failed_node_callback = completedFunc; @@ -188,7 +189,7 @@ uint8_t zwapi_replace_failed_node(zwave_node_id_t NodeID, uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, NodeID); request_buffer[index++] = func_id; zwapi_replace_failed_node_callback = completedFunc; @@ -214,7 +215,7 @@ sl_status_t zwapi_assign_return_route(zwave_node_id_t bSrcNodeID, uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, bSrcNodeID); zwapi_write_node_id(request_buffer, &index, bDstNodeID); request_buffer[index++] = func_id; @@ -241,7 +242,7 @@ sl_status_t zwapi_delete_return_route(zwave_node_id_t nodeID, uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, nodeID); request_buffer[index++] = func_id; zwapi_delete_return_route_callback = completedFunc; @@ -267,7 +268,7 @@ sl_status_t zwapi_assign_suc_return_route(zwave_node_id_t bSrcNodeID, uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, bSrcNodeID); request_buffer[index++] = func_id; zwapi_assign_suc_return_route_callback = completedFunc; @@ -293,7 +294,7 @@ sl_status_t zwapi_delete_suc_return_route(zwave_node_id_t nodeID, uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, nodeID); request_buffer[index++] = func_id; zwapi_delete_suc_return_route_callback = completedFunc; @@ -317,7 +318,7 @@ zwave_node_id_t zwapi_get_suc_node_id(void) { uint8_t response_length = 0; uint8_t response_buffer[FRAME_LENGTH_MAX] = {0}; - zwave_node_id_t suc_node_id = 0; + zwave_node_id_t suc_node_id = 0; sl_status_t send_command_status = zwapi_send_command_with_response(FUNC_ID_ZW_GET_SUC_NODE_ID, NULL, @@ -325,9 +326,11 @@ zwave_node_id_t zwapi_get_suc_node_id(void) response_buffer, &response_length); - if (send_command_status == SL_STATUS_OK && - (((NODEID_8BITS == zwapi_get_node_id_basetype()) &&(response_length > IDX_DATA)) || - ((NODEID_16BITS == zwapi_get_node_id_basetype()) &&(response_length > IDX_DATA + 1)))) { + if (send_command_status == SL_STATUS_OK + && (((NODEID_8BITS == zwapi_get_node_id_basetype()) + && (response_length > IDX_DATA)) + || ((NODEID_16BITS == zwapi_get_node_id_basetype()) + && (response_length > IDX_DATA + 1)))) { int current_index = IDX_DATA; if (NODEID_16BITS == zwapi_get_node_id_basetype()) { suc_node_id = response_buffer[current_index++] << 8; @@ -347,7 +350,7 @@ sl_status_t zwapi_set_suc_node_id(zwave_node_id_t nodeID, uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, nodeID); request_buffer[index++] = SUCState; /* Do we want to enable or disable?? */ request_buffer[index++] = bTxOption; @@ -396,15 +399,17 @@ sl_status_t zwapi_set_learn_mode(uint8_t mode, } sl_status_t zwapi_set_virtual_node_to_learn_mode( - zwave_node_id_t node, uint8_t mode, void (*completedFunc)(uint8_t, zwave_node_id_t, zwave_node_id_t)) + zwave_node_id_t node, + uint8_t mode, + void (*completedFunc)(uint8_t, zwave_node_id_t, zwave_node_id_t)) { uint8_t func_id, response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - func_id = (completedFunc == NULL ? 0 : 0x03); + func_id = (completedFunc == NULL ? 0 : 0x03); zwapi_write_node_id(request_buffer, &index, node); - request_buffer[index++] = mode; - request_buffer[index++] = func_id; + request_buffer[index++] = mode; + request_buffer[index++] = func_id; zwapi_set_virtual_node_to_learn_mode_callback = completedFunc; sl_status_t send_command_status @@ -444,9 +449,10 @@ sl_status_t zwapi_request_node_info(zwave_node_id_t node_id) return SL_STATUS_FAIL; } -sl_status_t zwapi_request_protocol_cc_encryption_callback(uint8_t tx_status, const zwapi_tx_report_t *tx_report, uint8_t session_id) +sl_status_t zwapi_request_protocol_cc_encryption_callback( + uint8_t tx_status, const zwapi_tx_report_t *tx_report, uint8_t session_id) { - uint8_t index = 0; + uint8_t index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; request_buffer[index++] = session_id; @@ -467,7 +473,7 @@ sl_status_t zwapi_request_protocol_cc_encryption_callback(uint8_t tx_status, con request_buffer[index++] = tx_report->last_route_repeaters[1]; request_buffer[index++] = tx_report->last_route_repeaters[2]; request_buffer[index++] = tx_report->last_route_repeaters[3]; - request_buffer[index] = (tx_report->beam_1000ms & 0x01) << 6; + request_buffer[index] = (tx_report->beam_1000ms & 0x01) << 6; request_buffer[index] |= (tx_report->beam_250ms & 0x01) << 5; request_buffer[index] |= (tx_report->last_route_speed & 0x07); index++; @@ -478,7 +484,8 @@ sl_status_t zwapi_request_protocol_cc_encryption_callback(uint8_t tx_status, con request_buffer[index++] = tx_report->measured_noise_floor; request_buffer[index++] = tx_report->destination_ack_mpdu_tx_power; request_buffer[index++] = tx_report->destination_ack_mpdu_measured_rssi; - request_buffer[index++] = tx_report->destination_ack_mpdu_measured_noise_floor; + request_buffer[index++] + = tx_report->destination_ack_mpdu_measured_noise_floor; sl_status_t send_command_status = zwapi_send_command(FUNC_ID_ZW_REQUEST_PROTOCOL_CC_ENCRYPTION, @@ -630,7 +637,8 @@ sl_status_t zwapi_set_max_source_route(uint8_t maxRouteTries) return SL_STATUS_FAIL; } -uint8_t zwapi_get_priority_route(zwave_node_id_t bNodeID, uint8_t *pLastWorkingRoute) +uint8_t zwapi_get_priority_route(zwave_node_id_t bNodeID, + uint8_t *pLastWorkingRoute) { uint8_t response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, @@ -646,7 +654,8 @@ uint8_t zwapi_get_priority_route(zwave_node_id_t bNodeID, uint8_t *pLastWorkingR if (send_command_status == SL_STATUS_OK && response_length > (IDX_DATA + 6)) { index = IDX_DATA; - zwave_node_id_t response_node_id = zwapi_read_node_id(response_buffer, &index); + zwave_node_id_t response_node_id + = zwapi_read_node_id(response_buffer, &index); if (bNodeID == response_node_id) { memcpy(pLastWorkingRoute, &response_buffer[IDX_DATA + 2], 5); return response_buffer[IDX_DATA + 1]; @@ -664,11 +673,11 @@ sl_status_t zwapi_set_priority_route(zwave_node_id_t bNodeID, uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; zwapi_write_node_id(request_buffer, &index, bNodeID); - request_buffer[index++] = pLastWorkingRoute[0]; - request_buffer[index++] = pLastWorkingRoute[1]; - request_buffer[index++] = pLastWorkingRoute[2]; - request_buffer[index++] = pLastWorkingRoute[3]; - request_buffer[index++] = pLastWorkingRoute[4]; + request_buffer[index++] = pLastWorkingRoute[0]; + request_buffer[index++] = pLastWorkingRoute[1]; + request_buffer[index++] = pLastWorkingRoute[2]; + request_buffer[index++] = pLastWorkingRoute[3]; + request_buffer[index++] = pLastWorkingRoute[4]; sl_status_t send_command_status = zwapi_send_command_with_response(FUNC_ID_ZW_SET_LAST_WORKING_ROUTE, @@ -694,9 +703,9 @@ sl_status_t zwapi_get_old_routing_info(zwave_node_id_t bNodeID, uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; zwapi_write_node_id(request_buffer, &index, bNodeID); - request_buffer[index++] = bRemoveBad; - request_buffer[index++] = bRemoveNonReps; - request_buffer[index++] = 0; // func_id must be set to 0 + request_buffer[index++] = bRemoveBad; + request_buffer[index++] = bRemoveNonReps; + request_buffer[index++] = 0; // func_id must be set to 0 sl_status_t send_command_status = zwapi_send_command_with_response(FUNC_ID_GET_ROUTING_TABLE_LINE, @@ -770,10 +779,10 @@ sl_status_t zwapi_set_virtual_node_application_node_information( uint8_t index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; zwapi_write_node_id(request_buffer, &index, dstNode); - request_buffer[index++] = listening; - request_buffer[index++] = node_type->generic; - request_buffer[index++] = node_type->specific; - request_buffer[index++] = parmLength; + request_buffer[index++] = listening; + request_buffer[index++] = node_type->generic; + request_buffer[index++] = node_type->specific; + request_buffer[index++] = parmLength; for (uint8_t i = 0; i < parmLength; i++) { request_buffer[index++] = nodeParm[i]; @@ -786,10 +795,10 @@ sl_status_t zwapi_set_virtual_node_application_node_information( sl_status_t zwapi_enable_node_nls(const zwave_node_id_t nodeId) { - uint8_t response_length = 0; - uint8_t index = 0; - uint8_t request_buffer[REQUEST_BUFFER_SIZE] = { 0 }; - uint8_t response_buffer[FRAME_LENGTH_MAX] = { 0 }; + uint8_t response_length = 0; + uint8_t index = 0; + uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; + uint8_t response_buffer[FRAME_LENGTH_MAX] = {0}; zwapi_write_node_id(request_buffer, &index, nodeId); sl_status_t send_command_status = zwapi_send_command_with_response(FUNC_ID_ZW_ENABLE_NODE_NLS, @@ -799,24 +808,22 @@ sl_status_t zwapi_enable_node_nls(const zwave_node_id_t nodeId) &response_length); if (send_command_status == SL_STATUS_OK && response_length > IDX_DATA - && response_buffer[IDX_DATA] == ZW_COMMAND_RETURN_VALUE_TRUE) - { + && response_buffer[IDX_DATA] == ZW_COMMAND_RETURN_VALUE_TRUE) { sl_log_debug(LOG_TAG, "NLS enabled for node %d", nodeId); return SL_STATUS_OK; } - return SL_STATUS_FAIL; + return SL_STATUS_FAIL; } -sl_status_t zwapi_get_node_nls( - const zwave_node_id_t nodeId, - uint8_t* nls_state, - uint8_t* nls_support) +sl_status_t zwapi_get_node_nls(const zwave_node_id_t nodeId, + uint8_t *nls_state, + uint8_t *nls_support) { - uint8_t response_length = 0; - uint8_t index = 0; - uint8_t request_buffer[REQUEST_BUFFER_SIZE] = { 0 }; - uint8_t response_buffer[FRAME_LENGTH_MAX] = { 0 }; + uint8_t response_length = 0; + uint8_t index = 0; + uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; + uint8_t response_buffer[FRAME_LENGTH_MAX] = {0}; zwapi_write_node_id(request_buffer, &index, nodeId); sl_status_t send_command_status = zwapi_send_command_with_response(FUNC_ID_ZW_GET_NODE_NLS_STATE, @@ -825,11 +832,11 @@ sl_status_t zwapi_get_node_nls( response_buffer, &response_length); - if (send_command_status == SL_STATUS_OK && response_length > IDX_DATA) - { + if (send_command_status == SL_STATUS_OK && response_length > IDX_DATA) { *nls_support = response_buffer[IDX_DATA]; - *nls_state = response_buffer[IDX_DATA + 1]; - if (((*nls_support != 0) && (*nls_support != 1)) || ((*nls_state != 0) && (*nls_state != 1))) { + *nls_state = response_buffer[IDX_DATA + 1]; + if (((*nls_support != 0) && (*nls_support != 1)) + || ((*nls_state != 0) && (*nls_state != 1))) { return SL_STATUS_FAIL; } return SL_STATUS_OK; @@ -847,8 +854,8 @@ sl_status_t zwapi_get_nls_nodes(uint16_t *list_length, *list_length = 0; while (more_nodes > 0) { - uint8_t response_length = 0; - uint8_t index = 0; + uint8_t response_length = 0; + uint8_t index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; uint8_t response_buffer[FRAME_LENGTH_MAX] = {0}; uint8_t received_nodelist_length = 0; @@ -867,7 +874,9 @@ sl_status_t zwapi_get_nls_nodes(uint16_t *list_length, *list_length += received_nodelist_length; const uint8_t *p = &response_buffer[IDX_DATA + 3]; for (uint8_t i = 0; i < received_nodelist_length; i++) { - if ((i + (start_offset * GET_NLS_NODES_OFFSET_GRANULARITY_IN_BYTES)) // NOSONAR + if ((i + + (start_offset + * GET_NLS_NODES_OFFSET_GRANULARITY_IN_BYTES)) // NOSONAR > sizeof(zwave_nodemask_t)) { sl_log_debug(LOG_TAG, "Z-Wave API get NLS node list index of bound\n"); @@ -895,22 +904,20 @@ sl_status_t zwapi_get_nls_nodes(uint16_t *list_length, return SL_STATUS_OK; } -sl_status_t zwapi_transfer_protocol_cc( - const zwave_node_id_t srcNode, - const uint8_t decryptionKey, - const uint8_t payloadLength, - const uint8_t * const payload) +sl_status_t zwapi_transfer_protocol_cc(const zwave_node_id_t srcNode, + const uint8_t decryptionKey, + const uint8_t payloadLength, + const uint8_t *const payload) { - uint8_t index = 0; - uint8_t response_length = 0; - uint8_t request_buffer[REQUEST_BUFFER_SIZE] = { 0 }; - uint8_t response_buffer[FRAME_LENGTH_MAX] = { 0 }; + uint8_t index = 0; + uint8_t response_length = 0; + uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}; + uint8_t response_buffer[FRAME_LENGTH_MAX] = {0}; zwapi_write_node_id(request_buffer, &index, srcNode); request_buffer[index++] = decryptionKey; - if (payloadLength > ZWAVE_MAX_FRAME_SIZE) - { + if (payloadLength > ZWAVE_MAX_FRAME_SIZE) { return SL_STATUS_WOULD_OVERFLOW; } diff --git a/applications/zpc/components/zwave_api/src/zwapi_protocol_mem.c b/applications/zpc/components/zwave_api/src/zwapi_protocol_mem.c index b71dd1bb4..f3c97f94d 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_protocol_mem.c +++ b/applications/zpc/components/zwave_api/src/zwapi_protocol_mem.c @@ -79,11 +79,12 @@ sl_status_t zwapi_memory_get_ids(zwave_home_id_t *home_id, &response_buffer[IDX_DATA], sizeof(received_home_id)); - received_home_id = zwave_controller_ntohl(received_home_id); // swap to our endian - *home_id = received_home_id; + received_home_id + = zwave_controller_ntohl(received_home_id); // swap to our endian + *home_id = received_home_id; uint8_t index = IDX_DATA + 4; - *node_id = zwapi_read_node_id(response_buffer, &index); + *node_id = zwapi_read_node_id(response_buffer, &index); return SL_STATUS_OK; } diff --git a/applications/zpc/components/zwave_api/src/zwapi_protocol_nvm.c b/applications/zpc/components/zwave_api/src/zwapi_protocol_nvm.c index 65e2dfea4..6075b167a 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_protocol_nvm.c +++ b/applications/zpc/components/zwave_api/src/zwapi_protocol_nvm.c @@ -57,9 +57,9 @@ uint32_t zwapi_nvm_open(void) if (response_buffer[IDX_DATA] == ZWAVE_API_NVM_RETURN_CODE_OK) { nvm_length = response_buffer[IDX_DATA + 2] << 8; nvm_length = nvm_length | response_buffer[IDX_DATA + 3]; - if (nvm_length == 0){ - /*Fix for 800s nvm that is 0x10000 bytes long and therefore overflows the 2 bytes in the frame */ - nvm_length = 0x10000; + if (nvm_length == 0) { + /*Fix for 800s nvm that is 0x10000 bytes long and therefore overflows the 2 bytes in the frame */ + nvm_length = 0x10000; } else { /* FIXME: 700 series return 1 more byte than the size of the NVM, it seems */ nvm_length += 1; diff --git a/applications/zpc/components/zwave_api/src/zwapi_protocol_transport.c b/applications/zpc/components/zwave_api/src/zwapi_protocol_transport.c index 8037877c3..c7ab7795f 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_protocol_transport.c +++ b/applications/zpc/components/zwave_api/src/zwapi_protocol_transport.c @@ -262,7 +262,7 @@ sl_status_t zwapi_send_protocol_data( uint8_t response_length = 0, index = 0; uint8_t request_buffer[REQUEST_BUFFER_SIZE] = {0}, response_buffer[FRAME_LENGTH_MAX] = {0}; - protocol_metadata_t *protocol_metadata = (protocol_metadata_t *)metadata; + protocol_metadata_t *protocol_metadata = (protocol_metadata_t *)metadata; // Check for too long payloads if ((data_length + protocol_metadata->data_length + 2) > sizeof(request_buffer)) { @@ -277,7 +277,9 @@ sl_status_t zwapi_send_protocol_data( memcpy(&request_buffer[index], data, data_length); index += data_length; request_buffer[index++] = protocol_metadata->data_length; - memcpy(&request_buffer[index], protocol_metadata->data, protocol_metadata->data_length); + memcpy(&request_buffer[index], + protocol_metadata->data, + protocol_metadata->data_length); index += protocol_metadata->data_length; request_buffer[index++] = protocol_metadata->session_id; diff --git a/applications/zpc/components/zwave_api/src/zwapi_utils.c b/applications/zpc/components/zwave_api/src/zwapi_utils.c index 073d77efc..8cb08820c 100644 --- a/applications/zpc/components/zwave_api/src/zwapi_utils.c +++ b/applications/zpc/components/zwave_api/src/zwapi_utils.c @@ -24,7 +24,9 @@ zwave_node_id_t zwapi_read_node_id(uint8_t *pData, uint8_t *index) return node_id; } -void zwapi_write_node_id(uint8_t *pData, uint8_t *index, zwave_node_id_t node_id) +void zwapi_write_node_id(uint8_t *pData, + uint8_t *index, + zwave_node_id_t node_id) { if (NODEID_16BITS == zwapi_get_node_id_basetype()) { pData[(*index)++] = node_id >> 8; diff --git a/applications/zpc/components/zwave_api/test/zwapi_connection_test.c b/applications/zpc/components/zwave_api/test/zwapi_connection_test.c index 8a8d05ef7..e1fa3b647 100644 --- a/applications/zpc/components/zwave_api/test/zwapi_connection_test.c +++ b/applications/zpc/components/zwave_api/test/zwapi_connection_test.c @@ -38,12 +38,12 @@ void setUp() {} void test_zwapi_connection_tx_invalid_payload_full() { - uint8_t cmd = 0x01; - uint8_t type = 0x02; - uint8_t buffer [0xFF] = {0}; ///< Maximum of len type - uint8_t len = sizeof(buffer); - bool ack_needed = true; - + uint8_t cmd = 0x01; + uint8_t type = 0x02; + uint8_t buffer[0xFF] = {0}; ///< Maximum of len type + uint8_t len = sizeof(buffer); + bool ack_needed = true; + // Expect the function to detect overflow zwapi_connection_tx(cmd, type, buffer, len, ack_needed); } diff --git a/applications/zpc/components/zwave_api/test/zwapi_init_test.c b/applications/zpc/components/zwave_api/test/zwapi_init_test.c index 1463f8e44..ea8c3126c 100644 --- a/applications/zpc/components/zwave_api/test/zwapi_init_test.c +++ b/applications/zpc/components/zwave_api/test/zwapi_init_test.c @@ -396,11 +396,11 @@ void test_zwapi_get_init_data() uint8_t ver, capabilities, len, chip_type, chip_version; uint8_t node_list[501] = {0}; - ver = 1; - capabilities = 1; - len = 1; - chip_type = 1; - chip_version = 1; + ver = 1; + capabilities = 1; + len = 1; + chip_type = 1; + chip_version = 1; zwapi_session_send_frame_with_response_ExpectAndReturn( FUNC_ID_SERIAL_API_GET_INIT_DATA, NULL, diff --git a/applications/zpc/components/zwave_api/test/zwapi_protocol_basis_test.c b/applications/zpc/components/zwave_api/test/zwapi_protocol_basis_test.c index 594549fed..5f32ebe72 100644 --- a/applications/zpc/components/zwave_api/test/zwapi_protocol_basis_test.c +++ b/applications/zpc/components/zwave_api/test/zwapi_protocol_basis_test.c @@ -39,17 +39,24 @@ void test_zwapi_soft_reset() void test_zwapi_supports_nls() { //Happy case - zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_TRANSFER_PROTOCOL_CC, true); + zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_TRANSFER_PROTOCOL_CC, + true); zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_ENABLE_NODE_NLS, true); - zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_GET_NODE_NLS_STATE, true); - zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_REQUEST_PROTOCOL_CC_ENCRYPTION, true); - zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_SEND_PROTOCOL_DATA, true); + zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_GET_NODE_NLS_STATE, + true); + zwapi_support_command_func_ExpectAndReturn( + FUNC_ID_ZW_REQUEST_PROTOCOL_CC_ENCRYPTION, + true); + zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_SEND_PROTOCOL_DATA, + true); TEST_ASSERT_EQUAL(true, zwapi_supports_nls()); //Bad case - zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_TRANSFER_PROTOCOL_CC, true); + zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_TRANSFER_PROTOCOL_CC, + true); zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_ENABLE_NODE_NLS, true); - zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_GET_NODE_NLS_STATE, false); + zwapi_support_command_func_ExpectAndReturn(FUNC_ID_ZW_GET_NODE_NLS_STATE, + false); TEST_ASSERT_EQUAL(false, zwapi_supports_nls()); } diff --git a/applications/zpc/components/zwave_api/test/zwapi_protocol_controller_test.c b/applications/zpc/components/zwave_api/test/zwapi_protocol_controller_test.c index 9d47dc252..86b36d238 100644 --- a/applications/zpc/components/zwave_api/test/zwapi_protocol_controller_test.c +++ b/applications/zpc/components/zwave_api/test/zwapi_protocol_controller_test.c @@ -35,13 +35,13 @@ void setUp() {} void test_zwapi_enable_node_nls(void) { - zwave_node_id_t node_id = 2; + zwave_node_id_t node_id = 2; uint8_t response_buffer[] = {0x04 /* length = len(payload) + 3 */, 0x01 /* type: response */, FUNC_ID_ZW_ENABLE_NODE_NLS /* cmd */, 0x01 /* payload */}; uint8_t response_length = 4; - uint8_t payload_buffer[] = {0x02}; + uint8_t payload_buffer[] = {0x02}; uint8_t payload_buffer_length = 1; zwapi_session_send_frame_with_response_ExpectAndReturn( @@ -64,16 +64,16 @@ void test_zwapi_enable_node_nls(void) void test_zwapi_get_node_nls(void) { - zwave_node_id_t node_id = 2; - uint8_t nls_supported = 1; - uint8_t nls_enabled = 1; + zwave_node_id_t node_id = 2; + uint8_t nls_supported = 1; + uint8_t nls_enabled = 1; uint8_t response_buffer[] = {0x04 /* length = len(payload) + 3 */, 0x01 /* type: response */, FUNC_ID_ZW_GET_NODE_NLS_STATE /* cmd */, nls_supported, nls_enabled /* payload */}; uint8_t response_length = 5; - uint8_t payload_buffer[] = {0x02}; + uint8_t payload_buffer[] = {0x02}; uint8_t payload_buffer_length = 1; uint8_t node_nls_state = 99; uint8_t node_nls_support = 99; @@ -93,7 +93,9 @@ void test_zwapi_get_node_nls(void) zwapi_session_send_frame_with_response_ReturnThruPtr_response_len( &response_length); - TEST_ASSERT_EQUAL(SL_STATUS_OK, zwapi_get_node_nls(node_id, &node_nls_state, &node_nls_support)); + TEST_ASSERT_EQUAL( + SL_STATUS_OK, + zwapi_get_node_nls(node_id, &node_nls_state, &node_nls_support)); TEST_ASSERT_EQUAL(nls_enabled, node_nls_state); } @@ -349,16 +351,16 @@ void test_zwapi_get_nls_nodes_frame_0_full_frame_1_full(void) void test_zwapi_transfer_protocol_cc(void) { - zwave_node_id_t node_id = 2; - uint8_t decryption_key = 3; - uint8_t tpcc_payload[] = {0xAA, 0xBB}; + zwave_node_id_t node_id = 2; + uint8_t decryption_key = 3; + uint8_t tpcc_payload[] = {0xAA, 0xBB}; uint8_t tpcc_payload_length = 2; uint8_t response_buffer[] = {0x04 /* length = len(payload) + 3 */, 0x01 /* type: response */, FUNC_ID_ZW_TRANSFER_PROTOCOL_CC /* cmd */, 0x01 /* payload */}; uint8_t response_length = 4; - uint8_t payload_buffer[] = {0x02, 0x03, 0x02, 0xAA, 0xBB}; + uint8_t payload_buffer[] = {0x02, 0x03, 0x02, 0xAA, 0xBB}; uint8_t payload_buffer_length = 5; zwapi_session_send_frame_with_response_ExpectAndReturn( @@ -376,14 +378,21 @@ void test_zwapi_transfer_protocol_cc(void) zwapi_session_send_frame_with_response_ReturnThruPtr_response_len( &response_length); - TEST_ASSERT_EQUAL(SL_STATUS_OK, zwapi_transfer_protocol_cc(node_id, decryption_key, tpcc_payload_length, tpcc_payload)); + TEST_ASSERT_EQUAL(SL_STATUS_OK, + zwapi_transfer_protocol_cc(node_id, + decryption_key, + tpcc_payload_length, + tpcc_payload)); } void test_zwapi_request_protocol_cc_encryption_callback(void) { - zwave_node_id_t node_id = 2; + zwave_node_id_t node_id = 2; zwapi_tx_report_t tx_report = {0}; - uint8_t session_id = 1; + uint8_t session_id = 1; - TEST_ASSERT_EQUAL(SL_STATUS_OK, zwapi_request_protocol_cc_encryption_callback(node_id, &tx_report, session_id)); + TEST_ASSERT_EQUAL(SL_STATUS_OK, + zwapi_request_protocol_cc_encryption_callback(node_id, + &tx_report, + session_id)); } diff --git a/applications/zpc/components/zwave_api/test/zwapi_protocol_mem_mock_test.c b/applications/zpc/components/zwave_api/test/zwapi_protocol_mem_mock_test.c index 9f78bc071..20c3b4944 100644 --- a/applications/zpc/components/zwave_api/test/zwapi_protocol_mem_mock_test.c +++ b/applications/zpc/components/zwave_api/test/zwapi_protocol_mem_mock_test.c @@ -5,7 +5,7 @@ void test_read_write() { const char *test1_data = "my_first_data"; - char test1_result[14] = {1}; + char test1_result[14] = {1}; zwapi_memory_put_buffer(0, (uint8_t *)test1_data, strlen(test1_data), NULL); zwapi_memory_get_buffer(0, (uint8_t *)test1_result, strlen(test1_data)); TEST_ASSERT_EQUAL_STRING(test1_data, test1_result); diff --git a/applications/zpc/components/zwave_api/test/zwapi_protocol_rx_dispatch_test.c b/applications/zpc/components/zwave_api/test/zwapi_protocol_rx_dispatch_test.c index 0331bbf4e..697b855e8 100644 --- a/applications/zpc/components/zwave_api/test/zwapi_protocol_rx_dispatch_test.c +++ b/applications/zpc/components/zwave_api/test/zwapi_protocol_rx_dispatch_test.c @@ -519,6 +519,7 @@ void test_zwapi_protocol_rx_dispatch_protocol_cc_encryption_request() = {0x0C, 0x00, 0x6C, 0x00, 0x01, 0x02, 0x03, 0x02, 0xAA, 0xCC, 0x01, 0x01}; zwave_api_protocol_rx_dispatch(frame, sizeof(frame)); - TEST_ASSERT_EQUAL(1, - zwapi_protocol_cc_encryption_request_test_function_call_count); + TEST_ASSERT_EQUAL( + 1, + zwapi_protocol_cc_encryption_request_test_function_call_count); } diff --git a/applications/zpc/components/zwave_command_classes/include/zwave_command_class_crc16.h b/applications/zpc/components/zwave_command_classes/include/zwave_command_class_crc16.h index 1d341cefb..f94eb32e7 100644 --- a/applications/zpc/components/zwave_command_classes/include/zwave_command_class_crc16.h +++ b/applications/zpc/components/zwave_command_classes/include/zwave_command_class_crc16.h @@ -22,7 +22,7 @@ * you use the same encapsulation as the sender. * @{ */ - + #ifndef ZWAVE_COMMAND_CLASS_CRC16_H #define ZWAVE_COMMAND_CLASS_CRC16_H @@ -30,7 +30,6 @@ #include "zwave_node_id_definitions.h" #include "attribute_store.h" - #ifdef __cplusplus extern "C" { #endif @@ -84,7 +83,7 @@ bool zwave_command_class_crc16_is_expecting_crc16_response( sl_status_t zwave_command_class_crc16_init(); #ifdef __cplusplus -} // extern "C" +} // extern "C" #endif #endif //ZWAVE_COMMAND_CLASS_CRC16_H diff --git a/applications/zpc/components/zwave_command_classes/include/zwave_command_classes_utils.h b/applications/zpc/components/zwave_command_classes/include/zwave_command_classes_utils.h index 3ccc5706e..3ea37ebf4 100644 --- a/applications/zpc/components/zwave_command_classes/include/zwave_command_classes_utils.h +++ b/applications/zpc/components/zwave_command_classes/include/zwave_command_classes_utils.h @@ -240,7 +240,7 @@ int16_t zwave_temperature_to_ucl_temperature(int32_t zwave_value, int32_t ucl_temperature_to_zwave_temperature(int16_t ucl_value, uint8_t zwave_precision, uint8_t zwave_scale); - /** +/** * @brief Converts a clock_time_t duration to a Z-Wave Command Class duration * byte * @@ -250,7 +250,7 @@ int32_t ucl_temperature_to_zwave_temperature(int16_t ucl_value, * @param time The system time duration * @returns uint8_t The corresponding Z-Wave duration encoding. */ - uint8_t time_to_zwave_duration(clock_time_t time); +uint8_t time_to_zwave_duration(clock_time_t time); /** * @brief Converts a duration byte encoded for a Z-Wave command class and returns diff --git a/applications/zpc/components/zwave_command_classes/platform/platform_exec.h b/applications/zpc/components/zwave_command_classes/platform/platform_exec.h index f461c4cc5..addf76c35 100644 --- a/applications/zpc/components/zwave_command_classes/platform/platform_exec.h +++ b/applications/zpc/components/zwave_command_classes/platform/platform_exec.h @@ -15,7 +15,7 @@ #define PLATFORM_EXEC_H void platform_exec(const char *file, - char *const *args, - char *const *environment); + char *const *args, + char *const *environment); #endif diff --git a/applications/zpc/components/zwave_command_classes/platform/posix/platform_date_time.c b/applications/zpc/components/zwave_command_classes/platform/posix/platform_date_time.c index 2aa73f149..2456530c3 100644 --- a/applications/zpc/components/zwave_command_classes/platform/posix/platform_date_time.c +++ b/applications/zpc/components/zwave_command_classes/platform/posix/platform_date_time.c @@ -7,51 +7,51 @@ static time_t time_offset = 0; date_time_t platform_get_date_time() { - date_time_t return_time = {0}; - time_t current_time; - current_time = time(NULL); + date_time_t return_time = {0}; + time_t current_time; + current_time = time(NULL); - current_time += time_offset; - struct tm *local_time = localtime(¤t_time); + current_time += time_offset; + struct tm *local_time = localtime(¤t_time); - if (local_time == NULL) { - return return_time; - } + if (local_time == NULL) { + return return_time; + } - // Populate return_time with the adjusted values - return_time.sec = local_time->tm_sec; - return_time.min = local_time->tm_min; - return_time.hour = local_time->tm_hour; - return_time.day = local_time->tm_mday; - return_time.mon = local_time->tm_mon; - return_time.year = local_time->tm_year; + // Populate return_time with the adjusted values + return_time.sec = local_time->tm_sec; + return_time.min = local_time->tm_min; + return_time.hour = local_time->tm_hour; + return_time.day = local_time->tm_mday; + return_time.mon = local_time->tm_mon; + return_time.year = local_time->tm_year; - return return_time; + return return_time; } sl_status_t platform_set_date_time(const date_time_t *new_time) { - struct tm tm = {0}; + struct tm tm = {0}; - // Populate the tm structure with the values from new_time - tm.tm_year = new_time->year; // tm_year is years since 1900 - tm.tm_mon = new_time->mon; // tm_mon is 0-11 - tm.tm_mday = new_time->day; - tm.tm_hour = new_time->hour; - tm.tm_min = new_time->min; - tm.tm_sec = new_time->sec; + // Populate the tm structure with the values from new_time + tm.tm_year = new_time->year; // tm_year is years since 1900 + tm.tm_mon = new_time->mon; // tm_mon is 0-11 + tm.tm_mday = new_time->day; + tm.tm_hour = new_time->hour; + tm.tm_min = new_time->min; + tm.tm_sec = new_time->sec; - // Convert tm structure to time_t - time_t time_in_secs = mktime(&tm); - if (time_in_secs == (time_t)(-1)) { - return SL_STATUS_FAIL; - } + // Convert tm structure to time_t + time_t time_in_secs = mktime(&tm); + if (time_in_secs == (time_t)(-1)) { + return SL_STATUS_FAIL; + } - // Get the current system time - time_t real_time_in_secs = time(NULL); + // Get the current system time + time_t real_time_in_secs = time(NULL); - // Calculate the time offset - time_offset = time_in_secs - real_time_in_secs; + // Calculate the time offset + time_offset = time_in_secs - real_time_in_secs; - return SL_STATUS_OK; // Return success status + return SL_STATUS_OK; // Return success status } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_agi.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_agi.h index 451225b8d..06942ec68 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_agi.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_agi.h @@ -39,9 +39,9 @@ #define AGI_NA_PROFILE 0x0000 ///< Lifeline Group ID -#define LIFELINE_GROUP_ID 1 -#define AGI_LIFELINE_PROFILE 0x0001 -#define LIFELINE_NAME "Lifeline" +#define LIFELINE_GROUP_ID 1 +#define AGI_LIFELINE_PROFILE 0x0001 +#define LIFELINE_NAME "Lifeline" /// Profile that is reserved, used to indicate that no profile data is available /// or valid diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association.cpp index 918336ed9..a8458b064 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association.cpp @@ -163,9 +163,9 @@ static sl_status_t zwave_command_class_association_handle_report_command( reports_to_follow_t previous_reports_to_follow = get_reports_to_follow(group_content_node); - reports_to_follow_t reports = - frame_data[ASSOCIATION_REPORTS_REPORTS_TO_FOLLOW]; - + reports_to_follow_t reports + = frame_data[ASSOCIATION_REPORTS_REPORTS_TO_FOLLOW]; + set_reports_to_follow(group_content_node, reports); if (reports < previous_reports_to_follow) { @@ -183,8 +183,8 @@ static sl_status_t zwave_command_class_association_handle_report_command( attribute group(group_content_node); if (concatenate_with_previous_value == true) { association_set existing_list; - association_bytes existing_bytes = - group.get(REPORTED_ATTRIBUTE); + association_bytes existing_bytes + = group.get(REPORTED_ATTRIBUTE); get_node_id_association_list(existing_bytes, existing_list); association_set merged_list; diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association_internals.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association_internals.h index 5a2add87e..783a2d378 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association_internals.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_association_internals.h @@ -30,10 +30,9 @@ #include "attribute_store.h" // First index of the frame containing association data for (Multi Channel) Association Reports -#define REPORT_ASSOCIATION_BYTES_INDEX 5 +#define REPORT_ASSOCIATION_BYTES_INDEX 5 #define ASSOCIATION_REPORTS_REPORTS_TO_FOLLOW 4 - ///< Maximum content (number of bytes) for a Association group. This is aligned ///< with the storage capacity of the attribute store. #define MAX_GROUP_CONTENT_SIZE ATTRIBUTE_STORE_MAXIMUM_VALUE_LENGTH diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_barrier_operator.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_barrier_operator.c index 7973bb064..7a7f03817 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_barrier_operator.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_barrier_operator.c @@ -169,7 +169,7 @@ static sl_status_t zwave_command_class_barrier_operator_signal_set( set_frame->cmd = BARRIER_OPERATOR_EVENT_SIGNAL_SET; set_frame->subsystemType = subsystem_type; set_frame->subsystemState = subsystem_state; - *frame_length = sizeof(ZW_BARRIER_OPERATOR_EVENT_SIGNAL_SET_FRAME); + *frame_length = sizeof(ZW_BARRIER_OPERATOR_EVENT_SIGNAL_SET_FRAME); return SL_STATUS_OK; } @@ -205,7 +205,7 @@ static sl_status_t zwave_command_class_barrier_operator_signal_get( get_frame->cmdClass = COMMAND_CLASS_BARRIER_OPERATOR; get_frame->cmd = BARRIER_OPERATOR_EVENT_SIGNALING_GET; get_frame->subsystemType = type; - *frame_length = sizeof(ZW_BARRIER_OPERATOR_EVENT_SIGNALING_GET_FRAME); + *frame_length = sizeof(ZW_BARRIER_OPERATOR_EVENT_SIGNALING_GET_FRAME); return SL_STATUS_OK; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_battery.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_battery.cpp index 52288be11..c4bb83ecb 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_battery.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_battery.cpp @@ -48,7 +48,8 @@ constexpr char LOG_TAG[] = "zwave_command_class_battery"; // Cpp helpers namespace { -zwave_frame_generator frame_generator(COMMAND_CLASS_BATTERY); //NOSONAR - false positive since it is warped in a namespace +zwave_frame_generator frame_generator( + COMMAND_CLASS_BATTERY); //NOSONAR - false positive since it is warped in a namespace } /////////////////////////////////////////////////////////////////////////////// @@ -191,7 +192,8 @@ static sl_status_t zwave_command_class_battery_handle_battery_health_report( zwave_frame_parser parser(frame_data, frame_length); if (!parser.is_frame_size_valid(report_min_size, report_min_size + 3)) { - sl_log_error(LOG_TAG, "Invalid frame size for Battery Health Report frame"); + sl_log_error(LOG_TAG, + "Invalid frame size for Battery Health Report frame"); return SL_STATUS_FAIL; } @@ -209,10 +211,12 @@ static sl_status_t zwave_command_class_battery_handle_battery_health_report( {.bitmask = BATTERY_HEALTH_REPORT_PROPERTIES1_SIZE_MASK_V2}}); // Parse temperature size - auto temperature_size = read_data[BATTERY_HEALTH_REPORT_PROPERTIES1_SIZE_MASK_V2]; + auto temperature_size + = read_data[BATTERY_HEALTH_REPORT_PROPERTIES1_SIZE_MASK_V2]; sl_log_debug(LOG_TAG, "Temperature size: %d", temperature_size); - parser.read_sequential(temperature_size, + parser.read_sequential( + temperature_size, endpoint_node.child_by_type(ATTRIBUTE(HEALTH_BATTERY_TEMPERATURE))); } catch (const std::exception &e) { sl_log_error(LOG_TAG, diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_binary_switch.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_binary_switch.cpp index 53c85c6de..f35b727ac 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_binary_switch.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_binary_switch.cpp @@ -53,16 +53,19 @@ constexpr uint8_t VALUE_OFF = 0x00; // Cpp helpers namespace { -zwave_frame_generator frame_generator(COMMAND_CLASS_SWITCH_BINARY); //NOSONAR - false positive since it is warped in a namespace +zwave_frame_generator frame_generator( + COMMAND_CLASS_SWITCH_BINARY); //NOSONAR - false positive since it is warped in a namespace } /////////////////////////////////////////////////////////////////////////////// // Helper functions /////////////////////////////////////////////////////////////////////////////// -zwave_cc_version_t get_current_binary_switch_version(attribute_store_node_t node) +zwave_cc_version_t + get_current_binary_switch_version(attribute_store_node_t node) { zwave_cc_version_t version - = zwave_command_class_get_version_from_node(node, COMMAND_CLASS_SWITCH_BINARY); + = zwave_command_class_get_version_from_node(node, + COMMAND_CLASS_SWITCH_BINARY); if (version == 0) { sl_log_error(LOG_TAG, "Binary Switch Command Class Version not found"); @@ -130,7 +133,8 @@ static sl_status_t zwave_command_class_binary_switch_set( auto duration_node = value_node.parent().child_by_type(ATTRIBUTE(DURATION)); - auto duration = duration_node.desired_or_reported(); + auto duration + = duration_node.desired_or_reported(); frame_generator.add_raw_byte(static_cast(duration)); } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_central_scene.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_central_scene.c index c9fcfa79d..be19fc5a2 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_central_scene.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_central_scene.c @@ -554,7 +554,7 @@ static sl_status_t zwave_command_class_central_scene_control_handler( const uint8_t *frame, uint16_t frame_length) { - if (frame_length <= COMMAND_INDEX) { // Should contain at least class and cmd + if (frame_length <= COMMAND_INDEX) { // Should contain at least class and cmd return SL_STATUS_NOT_SUPPORTED; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_crc16.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_crc16.cpp index f76cbe062..0ef8eef53 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_crc16.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_crc16.cpp @@ -18,7 +18,7 @@ #include #include #include -#include // make_pair +#include // make_pair // Includes from other ZPC Components #include "zwave_command_class_indices.h" @@ -41,23 +41,22 @@ #include "zwave_frame_generator.hpp" #include "zwave_frame_parser.hpp" - // Attribute macro, shortening those long defines for attribute types: #define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_CRC16_##type // Log tag constexpr char LOG_TAG[] = "zwave_command_class_crc16"; -using crc16_disabled_flag_t = uint8_t; +using crc16_disabled_flag_t = uint8_t; constexpr uint8_t CRC16_DISABLED_FLAG_OFF = 0x00; constexpr uint8_t CRC16_DISABLED_FLAG_ON = 0x01; namespace { using connection_info_pair_t = std::pair; -std::vector // NOSONAR : false positive - expecting_crc16_response; // NOSONAR : false positive -} +std::vector // NOSONAR : false positive + expecting_crc16_response; // NOSONAR : false positive +} // namespace /////////////////////////////////////////////////////////////////////////////// // Helper @@ -207,8 +206,8 @@ sl_status_t zwave_command_class_crc16_init() // The support side of things: Register our handler to the Z-Wave CC framework: zwave_command_handler_t handler = {}; // Need to register the support handler to be included in the NIF - handler.support_handler = &zwave_command_class_crc16_support_handler; - handler.control_handler = NULL; + handler.support_handler = &zwave_command_class_crc16_support_handler; + handler.control_handler = NULL; // Not supported, so this does not really matter handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE; handler.manual_security_validation = false; @@ -221,4 +220,3 @@ sl_status_t zwave_command_class_crc16_init() return SL_STATUS_OK; } - diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_device_reset_locally.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_device_reset_locally.h index 389304df7..333148739 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_device_reset_locally.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_device_reset_locally.h @@ -20,7 +20,6 @@ * @{ */ - #ifndef ZWAVE_COMMAND_CLASS_DEVICE_RESET_LOCALLY_H #define ZWAVE_COMMAND_CLASS_DEVICE_RESET_LOCALLY_H diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_door_lock_control.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_door_lock_control.cpp index ace8977cb..71eed0101 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_door_lock_control.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_door_lock_control.cpp @@ -341,7 +341,7 @@ sl_status_t zwave_command_class_door_lock_handle_configuration_report( = zwave_command_class_get_endpoint_node(connection_info); //Set Current Door Lock Mode - int32_t oper_type = frame_data[2]; + int32_t oper_type = frame_data[2]; attribute_store_node_t state_node = attribute_store_get_first_child_by_type( endpoint_node, ATTRIBUTE_DOOR_LOCK_CONFIGURATION_OPERATION_TYPE); @@ -352,24 +352,28 @@ sl_status_t zwave_command_class_door_lock_handle_configuration_report( state_node = attribute_store_get_first_child_by_type( endpoint_node, ATTRIBUTE_DOOR_LOCK_CONFIGURATION_OUTSIDE_DOOR_HANDLES_STATE); - attribute_store_set_reported(state_node, &outside_handles, sizeof(outside_handles)); + attribute_store_set_reported(state_node, + &outside_handles, + sizeof(outside_handles)); int32_t inside_handles = frame_data[3] & 0b1111; state_node = attribute_store_get_first_child_by_type( endpoint_node, ATTRIBUTE_DOOR_LOCK_CONFIGURATION_INSIDE_DOOR_HANDLES_STATE); - attribute_store_set_reported(state_node, &inside_handles, sizeof(inside_handles)); + attribute_store_set_reported(state_node, + &inside_handles, + sizeof(inside_handles)); //Lock Time Minutes int32_t minutes = frame_data[4]; - state_node = attribute_store_get_first_child_by_type( + state_node = attribute_store_get_first_child_by_type( endpoint_node, ATTRIBUTE_DOOR_LOCK_CONFIGURATION_LOCK_TIMEOUT_MINUTES); attribute_store_set_reported(state_node, &minutes, sizeof(minutes)); //Lock Time Seconds int32_t seconds = frame_data[5]; - state_node = attribute_store_get_first_child_by_type( + state_node = attribute_store_get_first_child_by_type( endpoint_node, ATTRIBUTE_DOOR_LOCK_CONFIGURATION_LOCK_TIMEOUT_SECONDS); attribute_store_set_reported(state_node, &seconds, sizeof(seconds)); diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_firmware_update_internals.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_firmware_update_internals.h index 88d332403..685146a28 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_firmware_update_internals.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_firmware_update_internals.h @@ -102,8 +102,8 @@ sl_status_t set_transfer_offset(attribute_store_node_t firmware_transfer_node, * * @returns sl_status_t code. */ -uint16_t - firmware_transfer_get_theoretical_max_fragment_size(attribute_store_node_t endpoint_node); +uint16_t firmware_transfer_get_theoretical_max_fragment_size( + attribute_store_node_t endpoint_node); /** * @brief Sets the Firmware transfer fragment size for a Firmware Update. diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c index 0814c1677..d676f9b2f 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_humidity_control_mode.c @@ -34,9 +34,9 @@ #define LOG_TAG "zwave_command_class_humidity_control_mode" -#define HUMIDITY_CONTROL_MODE_SET_MODE_HUMIDIFY_BITMASK 0x01 +#define HUMIDITY_CONTROL_MODE_SET_MODE_HUMIDIFY_BITMASK 0x01 #define HUMIDITY_CONTROL_MODE_SET_MODE_DEHUMIDIFY_BITMASK 0x02 -#define HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_BITMASK 0x04 +#define HUMIDITY_CONTROL_MODE_SET_MODE_AUTO_BITMASK 0x04 ///////////////////////////////////////////////////////////////////////////// // Utils @@ -265,8 +265,8 @@ sl_status_t zwave_command_class_humidity_control_mode_handle_report( attribute_store_node_t endpoint_node = zwave_command_class_get_endpoint_node(connection_info); - - if (!is_humidity_control_mode_supported(humidity_control_mode, endpoint_node)) { + if (!is_humidity_control_mode_supported(humidity_control_mode, + endpoint_node)) { sl_log_warning(LOG_TAG, "Reported humidity control mode mismatch."); return SL_STATUS_NOT_SUPPORTED; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_inclusion_controller.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_inclusion_controller.cpp index 1e65e5480..3cf86fc35 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_inclusion_controller.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_inclusion_controller.cpp @@ -516,7 +516,8 @@ static sl_status_t zwave_command_class_inclusion_controller_support_handler( = attribute_store_network_helper_create_endpoint_node(unid, 0); attribute_store_node_t node_id_node = attribute_store_get_node_parent(endpoint_node); - attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, node_id_node); + attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS, + node_id_node); // During replace fail, on_node_assigned zwave_controller callback (i.e, trigger via protocol command) // will not be received. Therefore, we trigger the nif interview when we only receive INITIATE command it->second.get()->on_node_add_received = true; diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_meter_control.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_meter_control.c index 33ca10c1a..f4213dad4 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_meter_control.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_meter_control.c @@ -253,10 +253,10 @@ static sl_status_t zwave_command_class_meter_supported_get( = zwave_command_class_get_version_from_node(node, COMMAND_CLASS_METER); if (supporting_node_version == 1) { - ZW_METER_GET_FRAME *get_frame = (ZW_METER_GET_FRAME *)frame; - get_frame->cmdClass = COMMAND_CLASS_METER; - get_frame->cmd = METER_GET; - *frame_length = sizeof(ZW_METER_GET_FRAME); + ZW_METER_GET_FRAME *get_frame = (ZW_METER_GET_FRAME *)frame; + get_frame->cmdClass = COMMAND_CLASS_METER; + get_frame->cmd = METER_GET; + *frame_length = sizeof(ZW_METER_GET_FRAME); return SL_STATUS_OK; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c index 87c35cf95..dfc12d49f 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c @@ -558,7 +558,7 @@ sl_status_t zwave_command_class_multi_channel_capability_get( static sl_status_t zwave_command_class_multi_channel_endpoint_find( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_len) { - uint8_t generic_device_class = 0xFF; + uint8_t generic_device_class = 0xFF; uint8_t specific_device_class = 0xFF; attribute_store_node_t endpoint_node diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel_association.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel_association.cpp index 475d4cdf5..72d0bc512 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel_association.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel_association.cpp @@ -521,8 +521,8 @@ static sl_status_t reports_to_follow_t previous_reports_to_follow = get_reports_to_follow(group_content_node); - reports_to_follow_t reports = - frame_data[ASSOCIATION_REPORTS_REPORTS_TO_FOLLOW]; + reports_to_follow_t reports + = frame_data[ASSOCIATION_REPORTS_REPORTS_TO_FOLLOW]; set_reports_to_follow(group_content_node, reports); if (reports < previous_reports_to_follow) { diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_node_info_resolver.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_node_info_resolver.c index 92caf86c5..03e68ccd6 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_node_info_resolver.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_node_info_resolver.c @@ -281,14 +281,14 @@ static void on_node_information_update(zwave_node_id_t node_id, node_id, nif, nif_length)) { - if (nif_length < sizeof(nif)) { - // Keep S2 in the NIF ! - nif[nif_length] = COMMAND_CLASS_SECURITY_2; - nif_length += 1; - } else { - // Overflow, just return and toss the faulty NIF. - return; - } + if (nif_length < sizeof(nif)) { + // Keep S2 in the NIF ! + nif[nif_length] = COMMAND_CLASS_SECURITY_2; + nif_length += 1; + } else { + // Overflow, just return and toss the faulty NIF. + return; + } } attribute_store_set_reported(non_secure_nif_node, nif, nif_length); diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.cpp index 57aebad4e..55e2afd17 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.cpp @@ -60,14 +60,15 @@ static constexpr uint8_t PUSH_REPORT_STATUS_ENABLED = 0xFF; static constexpr uint8_t PULL_REPORT_STATUS_NOT_EMPTY = 0x00; static constexpr uint8_t PULL_REPORT_STATUS_EMPTY = 0xFE; -static constexpr uint32_t PULL_NODE_PROBE_INTERVAL = 10800000; //in msec (3h * 60m * 60s * 1000ms) +static constexpr uint32_t PULL_NODE_PROBE_INTERVAL + = 10800000; //in msec (3h * 60m * 60s * 1000ms) enum class mode_discovery_state_t : uint8_t { - PUSH_MODE_DETECTED = 0x00, - PULL_MODE_DETECTED = 0x01, - AGI_TEST_PENDING = 0x02, + PUSH_MODE_DETECTED = 0x00, + PULL_MODE_DETECTED = 0x01, + AGI_TEST_PENDING = 0x02, NOTIFICATION_TEST_PENDING = 0x03, - UNKNOWN = 0xFF + UNKNOWN = 0xFF }; struct event_queue { @@ -76,23 +77,28 @@ struct event_queue { uint8_t seq; }; -namespace { +namespace +{ // Private variables -static mode_discovery_state_t discovery_state; //NOSONAR : false positive since it is warped in a namespace +static mode_discovery_state_t + discovery_state; //NOSONAR : false positive since it is warped in a namespace // probe timer, that will ensure that we probe all pull nodes // at least this interval. -static struct etimer notification_probe_timer; //NOSONAR : false positive since it is warped in a namespace -static std::map> pull_mode_queue; -} - +static struct etimer + notification_probe_timer; //NOSONAR : false positive since it is warped in a namespace +static std::map> + pull_mode_queue; +} // namespace // Cpp helpers namespace { -zwave_frame_generator frame_generator(COMMAND_CLASS_NOTIFICATION_V8); //NOSONAR - false positive since it is warped in a namespace +zwave_frame_generator frame_generator( + COMMAND_CLASS_NOTIFICATION_V8); //NOSONAR - false positive since it is warped in a namespace } -PROCESS(zwave_command_class_notification_process, "zwave_command_class_notification_process"); +PROCESS(zwave_command_class_notification_process, + "zwave_command_class_notification_process"); using namespace attribute_store; @@ -133,8 +139,7 @@ void zwave_command_class_agi_test_perform_discovery(attribute_store_node_t node) sl_log_warning(LOG_TAG, "Group with ID %u missing in attribute store", i); return; } - if (!group_node.reported_exists()) - { + if (!group_node.reported_exists()) { attribute_resolver_clear_resolution_listener( node, zwave_command_class_agi_test_perform_discovery); @@ -149,7 +154,7 @@ void zwave_command_class_agi_test_perform_discovery(attribute_store_node_t node) sl_log_warning(LOG_TAG, "Group Cmd List info missing for group %u", i); return; } - auto command_list = group_cmdlist_node.reported>(); + auto command_list = group_cmdlist_node.reported>(); if (is_command_in_array(COMMAND_CLASS_NOTIFICATION_V8, NOTIFICATION_REPORT_V3, @@ -218,9 +223,7 @@ void zwave_command_class_notification_pull_push_discovery( attribute_resolver_set_resolution_listener( groupings_node, zwave_command_class_agi_test_perform_discovery); - } - else - { + } else { sl_log_warning(LOG_TAG, "supported grouping not yet available"); } @@ -232,50 +235,49 @@ void zwave_command_class_notification_pull_push_discovery( /////////////////////////////////////////////////////////////////////////////// // Helpers for Pull mode and probe handling /////////////////////////////////////////////////////////////////////////////// -static void pull_mode_check_and_clear_persistence(attribute ep_node, const uint8_t *frame_data) +static void pull_mode_check_and_clear_persistence(attribute ep_node, + const uint8_t *frame_data) { - const auto *frame = reinterpret_cast( + const auto *frame + = reinterpret_cast( frame_data); auto prev_events = pull_mode_queue.find(ep_node); - if (prev_events == pull_mode_queue.cend()) - { + if (prev_events == pull_mode_queue.cend()) { std::vector queue_entry; struct event_queue entry = {frame->notificationType, frame->mevent, 0xFF}; if ((frame->properties1 - & NOTIFICATION_REPORT_PROPERTIES1_SEQUENCE_BIT_MASK_V3) != 0) - entry.seq = frame->sequenceNumber; + & NOTIFICATION_REPORT_PROPERTIES1_SEQUENCE_BIT_MASK_V3) + != 0) + entry.seq = frame->sequenceNumber; queue_entry.emplace(queue_entry.end(), entry); pull_mode_queue.emplace(std::make_pair(ep_node, queue_entry)); return; } - + // check if current and last event notification have same seq - if (prev_events->second[0].type == frame->notificationType && prev_events->second[0].event == frame->mevent) - { + if (prev_events->second[0].type == frame->notificationType + && prev_events->second[0].event == frame->mevent) { if (((frame->properties1 - & NOTIFICATION_REPORT_PROPERTIES1_SEQUENCE_BIT_MASK_V3) != 0 - && frame->sequenceNumber == prev_events->second[0].seq) - || (prev_events->second.size() == 4)) - { + & NOTIFICATION_REPORT_PROPERTIES1_SEQUENCE_BIT_MASK_V3) + != 0 + && frame->sequenceNumber == prev_events->second[0].seq) + || (prev_events->second.size() == 4)) { auto notification_type_node = ep_node.child_by_type(ATTRIBUTE(TYPE)); notification_type_node.set_desired( - notification_type_node.reported()); + notification_type_node.reported()); pull_mode_queue.erase(ep_node); - } - else { + } else { struct event_queue entry = {frame->notificationType, frame->mevent, 0xFF}; if ((frame->properties1 - & NOTIFICATION_REPORT_PROPERTIES1_SEQUENCE_BIT_MASK_V3) != 0) - entry.seq = frame->sequenceNumber; + & NOTIFICATION_REPORT_PROPERTIES1_SEQUENCE_BIT_MASK_V3) + != 0) + entry.seq = frame->sequenceNumber; prev_events->second.insert(prev_events->second.cbegin(), entry); } - } - else - { + } else { pull_mode_queue.erase(ep_node); } - } static void pull_mode_trigger_next_probe(attribute ep_node) @@ -291,9 +293,8 @@ static void zwave_command_class_notification_trigger_probe() attribute_store::attribute home_node = get_zpc_network_node(); try { sl_log_debug(LOG_TAG, "periodic probe started for pull nodes"); - for (auto end_node : home_node.children(ATTRIBUTE_NODE_ID)) { - for (auto ep_node : end_node.children(ATTRIBUTE_ENDPOINT_ID)) - { + for (auto end_node: home_node.children(ATTRIBUTE_NODE_ID)) { + for (auto ep_node: end_node.children(ATTRIBUTE_ENDPOINT_ID)) { // devices which doesn't support Notification CC to be skipped if (!ep_node.child_by_type(ATTRIBUTE(VERSION)).is_valid()) continue; @@ -301,17 +302,14 @@ static void zwave_command_class_notification_trigger_probe() if (ep_node.child_by_type_and_value(ATTRIBUTE(MODE), PUSH_MODE) .is_valid()) continue; - + // clear probe active node to start probe process pull_mode_trigger_next_probe(ep_node); } } } catch (const std::exception &ex) { // continue with next state in case of erorrs - sl_log_warning( - LOG_TAG, - "Failed during probe process: %s", - ex.what()); + sl_log_warning(LOG_TAG, "Failed during probe process: %s", ex.what()); } } @@ -326,38 +324,35 @@ static sl_status_t zwave_command_class_notification_update_state_event( if (notification_event == 0xFE) { notification_event = 0; } - auto version_node = notification_type_node.parent().child_by_type(ATTRIBUTE(VERSION)); + auto version_node + = notification_type_node.parent().child_by_type(ATTRIBUTE(VERSION)); zwave_cc_version_t version = version_node.reported(); attribute notification_event_node; - if (version > 2) - { + if (version > 2) { notification_event_node - = attribute_store_get_node_child_by_value(notification_type_node, - ATTRIBUTE(STATE), - REPORTED_ATTRIBUTE, - &state, - sizeof(state), - 0); + = attribute_store_get_node_child_by_value(notification_type_node, + ATTRIBUTE(STATE), + REPORTED_ATTRIBUTE, + &state, + sizeof(state), + 0); notification_event_node - = notification_event_node.child_by_type(ATTRIBUTE(EVENT), 0); + = notification_event_node.child_by_type(ATTRIBUTE(EVENT), 0); sl_log_info(NOTIFICATION_TAG, - " State: %u Event: %u", - notification_type_node.reported(), - state, - notification_event); - } - else - { + " State: %u Event: %u", + notification_type_node.reported(), + state, + notification_event); + } else { // version 1 and 2 do not have a concept of state hence it will be a dummy parent node auto state_node = notification_type_node.child_by_type(ATTRIBUTE(STATE)); notification_event_node = state_node.emplace_node(ATTRIBUTE(EVENT)); sl_log_info(NOTIFICATION_TAG, - " Event: %u", - notification_type_node.reported(), - notification_event); + " Event: %u", + notification_type_node.reported(), + notification_event); } - if (!notification_event_node.is_valid()) { sl_log_debug(LOG_TAG, @@ -369,7 +364,6 @@ static sl_status_t zwave_command_class_notification_update_state_event( } notification_event_node.set_reported(notification_event); - uint8_t state_event_param_len = frame->properties1 & NOTIFICATION_REPORT_PROPERTIES1_EVENT_PARAMETERS_LENGTH_MASK_V4; @@ -390,9 +384,9 @@ static sl_status_t zwave_command_class_notification_update_state_event( int32_t state_event = frame->eventParameter1; notification_event_param.set_reported(state_event); sl_log_info(NOTIFICATION_TAG, - "Event: %u Param: %u", - notification_event, - state_event); + "Event: %u Param: %u", + notification_event, + state_event); } else { // No Event/state parameter byte added to the payload, we just undefine the // value again. @@ -424,10 +418,9 @@ static sl_status_t zwave_command_class_notification_report_cmd_handler( sending_node_unid, connection_info->remote.endpoint_id); auto mode_node = ep_node.child_by_type(ATTRIBUTE(MODE)); - uint8_t mode = PUSH_MODE; + uint8_t mode = PUSH_MODE; if (discovery_state == mode_discovery_state_t::NOTIFICATION_TEST_PENDING) { - if (frame->notificationStatus == PUSH_REPORT_STATUS_ENABLED) { mode = PUSH_MODE; discovery_state = mode_discovery_state_t::PUSH_MODE_DETECTED; @@ -437,8 +430,7 @@ static sl_status_t zwave_command_class_notification_report_cmd_handler( ep_node.emplace_node(ATTRIBUTE(PROBE_ACTIVE)); } mode_node.set_reported(mode); - } - else { + } else { mode = mode_node.reported(); } @@ -475,9 +467,9 @@ static sl_status_t zwave_command_class_notification_report_cmd_handler( } if (mode == PULL_MODE) { - if (frame->notificationStatus == PULL_REPORT_STATUS_EMPTY) - { - sl_log_debug(LOG_TAG, "Pull sensor queue empty, stopped further probing"); + if (frame->notificationStatus == PULL_REPORT_STATUS_EMPTY) { + sl_log_debug(LOG_TAG, + "Pull sensor queue empty, stopped further probing"); auto probe_active = ep_node.child_by_type(ATTRIBUTE(PROBE_ACTIVE)); probe_active.set_reported(false); return SL_STATUS_OK; @@ -752,8 +744,9 @@ static sl_status_t &supported_notification_types[i], sizeof(supported_notification_types[i])); if (version > 2) { - auto node = attribute_store_add_node(ATTRIBUTE(SUPPORTED_STATES_OR_EVENTS), - notification_type); + auto node + = attribute_store_add_node(ATTRIBUTE(SUPPORTED_STATES_OR_EVENTS), + notification_type); /* Wait till last type is completely resolved, to discover pull/push mode*/ if ((i == (number_of_supported_notification_types - 1)) && (discovery_state @@ -762,11 +755,9 @@ static sl_status_t node, zwave_command_class_continue_mode_discovery); } - } - else if (version > 1) - { + } else if (version > 1) { attribute_store_add_node(ATTRIBUTE(STATE), notification_type); - } + } } return SL_STATUS_OK; @@ -1032,7 +1023,6 @@ void zwave_command_class_notification_on_version_attribute_update( = attribute_store_get_node_parent(updated_node); // For version 1 Notification Supported Get is not available if (version > 1) { - // Verify if there is already supported notification types attribute. // Note that updated_node is the ENDPOINT node in the Attribute Store. attribute_store_node_t supported_notification_type_node @@ -1046,34 +1036,31 @@ void zwave_command_class_notification_on_version_attribute_update( } } attribute_store_node_t notification_mode_node - = attribute_store_get_first_child_by_type( - parent_node, ATTRIBUTE(MODE)); - if (notification_mode_node == ATTRIBUTE_STORE_INVALID_NODE) - { + = attribute_store_get_first_child_by_type(parent_node, ATTRIBUTE(MODE)); + if (notification_mode_node == ATTRIBUTE_STORE_INVALID_NODE) { attribute_store_add_node(ATTRIBUTE(MODE), parent_node); zwave_command_class_notification_pull_push_discovery(node_id, endpoint_id); } } -static sl_status_t zwave_command_class_alarm_get( - attribute_store_node_t node, uint8_t *frame, uint16_t *frame_len) +static sl_status_t zwave_command_class_alarm_get(attribute_store_node_t node, + uint8_t *frame, + uint16_t *frame_len) { - auto alarm_get_frame - = reinterpret_cast(frame); + auto alarm_get_frame = reinterpret_cast(frame); attribute_store::attribute ep_node = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_ENDPOINT_ID); auto version_node = ep_node.child_by_type(ATTRIBUTE(VERSION)); zwave_cc_version_t version = version_node.reported(); - if (version > 2) - { + if (version > 2) { sl_log_error(LOG_TAG, "Should not be called for versions > v2"); return SL_STATUS_FAIL; } - alarm_get_frame->cmdClass = COMMAND_CLASS_NOTIFICATION_V8; - alarm_get_frame->cmd = NOTIFICATION_GET_V8; - alarm_get_frame->alarmType = 0x00; //v1 AlarmType + alarm_get_frame->cmdClass = COMMAND_CLASS_NOTIFICATION_V8; + alarm_get_frame->cmd = NOTIFICATION_GET_V8; + alarm_get_frame->alarmType = 0x00; //v1 AlarmType // read the Notification type attribute_store_node_t type_node = attribute_store_get_first_parent_with_type(node, ATTRIBUTE(TYPE)); @@ -1085,7 +1072,7 @@ static sl_status_t zwave_command_class_alarm_get( *frame_len = sizeof(ZW_ALARM_GET_V2_FRAME); - return SL_STATUS_OK; + return SL_STATUS_OK; } static sl_status_t zwave_command_class_notification_set( @@ -1093,7 +1080,7 @@ static sl_status_t zwave_command_class_notification_set( { attribute_store::attribute type_node(node); try { - auto type = type_node.desired(); + auto type = type_node.desired(); auto mode_node = type_node.parent().child_by_type(ATTRIBUTE(MODE)); frame_generator.initialize_frame(NOTIFICATION_SET_V8, frame, @@ -1104,8 +1091,7 @@ static sl_status_t zwave_command_class_notification_set( frame_generator.add_raw_byte(0xFF); } // if pull mode, then send 0x00 to clear persistent notification - else if (mode_node.reported() == PULL_MODE) - { + else if (mode_node.reported() == PULL_MODE) { frame_generator.add_raw_byte(0x00); } frame_generator.validate_frame(frame_len); @@ -1135,17 +1121,16 @@ static sl_status_t zwave_command_class_probe_notification( auto ep_node = attribute(node).first_parent(ATTRIBUTE_ENDPOINT_ID); uint8_t mode = ep_node.child_by_type(ATTRIBUTE(MODE)).reported(); - if (mode != PULL_MODE) - { + if (mode != PULL_MODE) { sl_log_warning(LOG_TAG, "Ignoring probe attempted for push sensor"); return SL_STATUS_FAIL; } - notification_get_frame->cmdClass = COMMAND_CLASS_NOTIFICATION_V8; - notification_get_frame->cmd = NOTIFICATION_GET_V8; - notification_get_frame->v1AlarmType = 0x00; + notification_get_frame->cmdClass = COMMAND_CLASS_NOTIFICATION_V8; + notification_get_frame->cmd = NOTIFICATION_GET_V8; + notification_get_frame->v1AlarmType = 0x00; notification_get_frame->notificationType = 0xFF; - notification_get_frame->mevent = 0x00; + notification_get_frame->mevent = 0x00; *frame_len = sizeof(ZW_NOTIFICATION_GET_V4_FRAME); return SL_STATUS_OK; @@ -1287,7 +1272,7 @@ sl_status_t zwave_command_class_notification_init() zwave_command_handler_register_handler(handler); - process_start(&zwave_command_class_notification_process,NULL); + process_start(&zwave_command_class_notification_process, NULL); return SL_STATUS_OK; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.h index 10859f50e..bfedf40c9 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification.h @@ -41,7 +41,6 @@ extern "C" { #include "zwave_rx.h" #include "attribute_store.h" - // Following defines are created using the notification.py #define NOTIFICATION_SMOKE_ALARM (0x1) #define NOTIFICATION_CO_ALARM (0x2) diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification_types.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification_types.h index 6b34aa541..ff565c551 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification_types.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_notification_types.h @@ -24,137 +24,144 @@ #define ZWAVE_COMMAND_CLASS_NOTIFICATION_TYPES_H // Notification Types -#define NOTIFICATION_SMOKE_ALARM (0x1) -#define NOTIFICATION_CO_ALARM (0x2) -#define NOTIFICATION_CO2_ALARM (0x3) -#define NOTIFICATION_HEAT_ALARM (0x4) -#define NOTIFICATION_WATER_ALARM (0x5) -#define NOTIFICATION_ACCESS_CONTROL (0x6) -#define NOTIFICATION_HOME_SECURITY (0x7) -#define NOTIFICATION_POWER_MANAGEMENT (0x8) -#define NOTIFICATION_SYSTEM (0x9) -#define NOTIFICATION_APPLIANCE (0xc) -#define NOTIFICATION_HOME_HEALTH (0xd) -#define NOTIFICATION_SIREN (0xe) -#define NOTIFICATION_WATER_VALVE (0xf) -#define NOTIFICATION_WEATHER_ALARM (0x10) -#define NOTIFICATION_IRRIGATION (0x11) -#define NOTIFICATION_GAS_ALARM (0x12) -#define NOTIFICATION_PEST_CONTROL (0x13) -#define NOTIFICATION_LIGHT_SENSOR (0x14) +#define NOTIFICATION_SMOKE_ALARM (0x1) +#define NOTIFICATION_CO_ALARM (0x2) +#define NOTIFICATION_CO2_ALARM (0x3) +#define NOTIFICATION_HEAT_ALARM (0x4) +#define NOTIFICATION_WATER_ALARM (0x5) +#define NOTIFICATION_ACCESS_CONTROL (0x6) +#define NOTIFICATION_HOME_SECURITY (0x7) +#define NOTIFICATION_POWER_MANAGEMENT (0x8) +#define NOTIFICATION_SYSTEM (0x9) +#define NOTIFICATION_APPLIANCE (0xc) +#define NOTIFICATION_HOME_HEALTH (0xd) +#define NOTIFICATION_SIREN (0xe) +#define NOTIFICATION_WATER_VALVE (0xf) +#define NOTIFICATION_WEATHER_ALARM (0x10) +#define NOTIFICATION_IRRIGATION (0x11) +#define NOTIFICATION_GAS_ALARM (0x12) +#define NOTIFICATION_PEST_CONTROL (0x13) +#define NOTIFICATION_LIGHT_SENSOR (0x14) #define NOTIFICATION_WATER_QUALITY_MONITORING (0x15) -#define NOTIFICATION_HOME_MONITORING (0x16) +#define NOTIFICATION_HOME_MONITORING (0x16) // Notification States -#define NOTIFICATION_STATE_LAST_EVENT (0xff) -#define NOTIFICATION_STATE_SMOKE_ALARM_SENSOR_STATUS (0x0) -#define NOTIFICATION_STATE_SMOKE_ALARM_ALARM_STATUS (0x1) -#define NOTIFICATION_STATE_SMOKE_ALARM_MAINTENANCE_STATUS (0x2) -#define NOTIFICATION_STATE_SMOKE_ALARM_PERIODIC_INSPECTION_STATUS (0x3) -#define NOTIFICATION_STATE_SMOKE_ALARM_DUST_IN_DEVICE_STATUS (0x4) -#define NOTIFICATION_STATE_CO_ALARM_SENSOR_STATUS (0x0) -#define NOTIFICATION_STATE_CO_ALARM_TEST_STATUS (0x1) -#define NOTIFICATION_STATE_CO_ALARM_MAINTENANCE_STATUS (0x2) -#define NOTIFICATION_STATE_CO_ALARM_ALARM_STATUS (0x3) -#define NOTIFICATION_STATE_CO_ALARM_PERIODIC_INSPECTION_STATUS (0x4) -#define NOTIFICATION_STATE_CO2_ALARM_SENSOR_STATUS (0x0) -#define NOTIFICATION_STATE_CO2_ALARM_TEST_STATUS (0x1) -#define NOTIFICATION_STATE_CO2_ALARM_MAINTENANCE_STATUS (0x2) -#define NOTIFICATION_STATE_CO2_ALARM_ALARM_STATUS (0x3) -#define NOTIFICATION_STATE_CO2_ALARM_PERIODIC_INSPECTION_STATUS (0x4) -#define NOTIFICATION_STATE_HEAT_ALARM_HEAT_SENSOR_STATUS (0x0) -#define NOTIFICATION_STATE_HEAT_ALARM_ALARM_STATUS (0x1) -#define NOTIFICATION_STATE_HEAT_ALARM_MAINTENANCE_STATUS (0x2) -#define NOTIFICATION_STATE_HEAT_ALARM_DUST_IN_DEVICE_STATUS (0x3) -#define NOTIFICATION_STATE_HEAT_ALARM_PERIODIC_INSPECTION_STATUS (0x4) -#define NOTIFICATION_STATE_WATER_ALARM_SENSOR_STATUS (0x0) -#define NOTIFICATION_STATE_WATER_ALARM_MAINTENANCE_STATUS (0x1) -#define NOTIFICATION_STATE_WATER_ALARM_WATER_FLOW_ALARM_STATUS (0x2) -#define NOTIFICATION_STATE_WATER_ALARM_WATER_PRESSURE_ALARM_STATUS (0x3) -#define NOTIFICATION_STATE_WATER_ALARM_WATER_TEMPERATURE_ALARM_STATUS (0x4) -#define NOTIFICATION_STATE_WATER_ALARM_WATER_LEVEL_ALARM_STATUS (0x5) -#define NOTIFICATION_STATE_WATER_ALARM_PUMP_STATUS (0x6) -#define NOTIFICATION_STATE_ACCESS_CONTROL_LOCK_STATE (0x0) -#define NOTIFICATION_STATE_ACCESS_CONTROL_KEYPAD_STATE (0x1) -#define NOTIFICATION_STATE_ACCESS_CONTROL_DOOR_STATE (0x2) -#define NOTIFICATION_STATE_ACCESS_CONTROL_DOOR_HANDLE_STATE (0x3) -#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_UL_DISABLING_STATUS (0x4) +#define NOTIFICATION_STATE_LAST_EVENT (0xff) +#define NOTIFICATION_STATE_SMOKE_ALARM_SENSOR_STATUS (0x0) +#define NOTIFICATION_STATE_SMOKE_ALARM_ALARM_STATUS (0x1) +#define NOTIFICATION_STATE_SMOKE_ALARM_MAINTENANCE_STATUS (0x2) +#define NOTIFICATION_STATE_SMOKE_ALARM_PERIODIC_INSPECTION_STATUS (0x3) +#define NOTIFICATION_STATE_SMOKE_ALARM_DUST_IN_DEVICE_STATUS (0x4) +#define NOTIFICATION_STATE_CO_ALARM_SENSOR_STATUS (0x0) +#define NOTIFICATION_STATE_CO_ALARM_TEST_STATUS (0x1) +#define NOTIFICATION_STATE_CO_ALARM_MAINTENANCE_STATUS (0x2) +#define NOTIFICATION_STATE_CO_ALARM_ALARM_STATUS (0x3) +#define NOTIFICATION_STATE_CO_ALARM_PERIODIC_INSPECTION_STATUS (0x4) +#define NOTIFICATION_STATE_CO2_ALARM_SENSOR_STATUS (0x0) +#define NOTIFICATION_STATE_CO2_ALARM_TEST_STATUS (0x1) +#define NOTIFICATION_STATE_CO2_ALARM_MAINTENANCE_STATUS (0x2) +#define NOTIFICATION_STATE_CO2_ALARM_ALARM_STATUS (0x3) +#define NOTIFICATION_STATE_CO2_ALARM_PERIODIC_INSPECTION_STATUS (0x4) +#define NOTIFICATION_STATE_HEAT_ALARM_HEAT_SENSOR_STATUS (0x0) +#define NOTIFICATION_STATE_HEAT_ALARM_ALARM_STATUS (0x1) +#define NOTIFICATION_STATE_HEAT_ALARM_MAINTENANCE_STATUS (0x2) +#define NOTIFICATION_STATE_HEAT_ALARM_DUST_IN_DEVICE_STATUS (0x3) +#define NOTIFICATION_STATE_HEAT_ALARM_PERIODIC_INSPECTION_STATUS (0x4) +#define NOTIFICATION_STATE_WATER_ALARM_SENSOR_STATUS (0x0) +#define NOTIFICATION_STATE_WATER_ALARM_MAINTENANCE_STATUS (0x1) +#define NOTIFICATION_STATE_WATER_ALARM_WATER_FLOW_ALARM_STATUS (0x2) +#define NOTIFICATION_STATE_WATER_ALARM_WATER_PRESSURE_ALARM_STATUS (0x3) +#define NOTIFICATION_STATE_WATER_ALARM_WATER_TEMPERATURE_ALARM_STATUS (0x4) +#define NOTIFICATION_STATE_WATER_ALARM_WATER_LEVEL_ALARM_STATUS (0x5) +#define NOTIFICATION_STATE_WATER_ALARM_PUMP_STATUS (0x6) +#define NOTIFICATION_STATE_ACCESS_CONTROL_LOCK_STATE (0x0) +#define NOTIFICATION_STATE_ACCESS_CONTROL_KEYPAD_STATE (0x1) +#define NOTIFICATION_STATE_ACCESS_CONTROL_DOOR_STATE (0x2) +#define NOTIFICATION_STATE_ACCESS_CONTROL_DOOR_HANDLE_STATE (0x3) +#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_UL_DISABLING_STATUS (0x4) #define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_VACATION_MODE_STATUS (0x5) -#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_SAFETY_BEARM_OBSTACLE_STATUS (0x6) -#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_SENSOR_STATUS (0x7) -#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_BATTERY_STATUS (0x8) -#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_SHORTCIRCUIT_STATUS (0x9) -#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_CONTROL_STATUS (0xa) -#define NOTIFICATION_STATE_HOME_SECURITY_SENSOR_STATUS (0x0) -#define NOTIFICATION_STATE_HOME_SECURITY_COVER_STATUS (0x1) -#define NOTIFICATION_STATE_HOME_SECURITY_MOTION_SENSOR_STATUS (0x2) -#define NOTIFICATION_STATE_HOME_SECURITY_MAGNETIC_INTERFERENCE_STATUS (0x3) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_POWER_STATUS (0x0) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_MAINS_STATUS (0x1) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_OVERCURRENT_STATUS (0x2) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_OVERVOLTAGE_STATUS (0x3) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_OVERLOAD_STATUS (0x4) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_LOAD_ERROR_STATUS (0x5) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_BATTERY_MAINTENANCE_STATUS (0x6) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_BATTERY_LOAD_STATUS (0x7) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_BATTERY_LEVEL_STATUS (0x8) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_BACKUP_BATTERY_LEVEL_STATUS (0x9) -#define NOTIFICATION_STATE_POWER_MANAGEMENT_DC_JACK_STATUS (0xa) -#define NOTIFICATION_STATE_SYSTEM_HW_STATUS (0x0) -#define NOTIFICATION_STATE_SYSTEM_SW_STATUS (0x1) -#define NOTIFICATION_STATE_SYSTEM_COVER_STATUS (0x2) -#define NOTIFICATION_STATE_SYSTEM_EMERGENCY_SHUTOFF_STATUS (0x3) -#define NOTIFICATION_STATE_SYSTEM_DIGITAL_INPUT_STATE (0x4) -#define NOTIFICATION_STATE_APPLIANCE_PROGRAM_STATUS (0x0) -#define NOTIFICATION_STATE_APPLIANCE_MAINTENANCE_STATUS (0x1) -#define NOTIFICATION_STATE_APPLIANCE_APPLIANCE_STATUS (0x2) -#define NOTIFICATION_STATE_APPLIANCE_TARGET_TEMPERATURE_FAILURE_STATUS (0x3) -#define NOTIFICATION_STATE_APPLIANCE_WATER_SUPPLY_FAILURE_STATUS (0x4) -#define NOTIFICATION_STATE_APPLIANCE_BOILING_FAILURE_STATUS (0x5) -#define NOTIFICATION_STATE_APPLIANCE_WASHING_FAILURE_STATUS (0x6) -#define NOTIFICATION_STATE_APPLIANCE_RINSING_FAILURE_STATUS (0x7) -#define NOTIFICATION_STATE_APPLIANCE_DRAINING_FAILURE_STATUS (0x8) -#define NOTIFICATION_STATE_APPLIANCE_SPINNING_FAILURE_STATUS (0x9) -#define NOTIFICATION_STATE_APPLIANCE_DRYING_FAILURE_STATUS (0xa) -#define NOTIFICATION_STATE_APPLIANCE_FAN_FAILURE_STATUS (0xb) -#define NOTIFICATION_STATE_APPLIANCE_COMPRESSOR_FAILURE_STATUS (0xc) -#define NOTIFICATION_STATE_HOME_HEALTH_POSITION_STATUS (0x0) -#define NOTIFICATION_STATE_HOME_HEALTH_SLEEP_APNEA_STATUS (0x1) -#define NOTIFICATION_STATE_HOME_HEALTH_SLEEP_STAGE_STATUS (0x2) -#define NOTIFICATION_STATE_SIREN_SIREN_STATUS (0x0) -#define NOTIFICATION_STATE_WATER_VALVE_VALVE_OPERATION_STATUS (0x0) -#define NOTIFICATION_STATE_WATER_VALVE_MAIN_VALVE_OPERATION_STATUS (0x1) -#define NOTIFICATION_STATE_WATER_VALVE_VALVE_SHORT_CIRCUIT_STATUS (0x2) -#define NOTIFICATION_STATE_WATER_VALVE_MAIN_VALVE_SHORT_CIRCUIT_STATUS (0x3) -#define NOTIFICATION_STATE_WATER_VALVE_VALVE_CURRENT_ALARM_STATUS (0x4) -#define NOTIFICATION_STATE_WATER_VALVE_MAIN_VALVE_CURRENT_ALARM_STATUS (0x5) -#define NOTIFICATION_STATE_WATER_VALVE_WATER_JAMMED_STATUS (0x6) -#define NOTIFICATION_STATE_WEATHER_ALARM_RAIN_ALARM_STATUS (0x0) -#define NOTIFICATION_STATE_WEATHER_ALARM_MOISTURE_ALARM_STATUS (0x1) -#define NOTIFICATION_STATE_WEATHER_ALARM_FREEZE_ALARM_STATUS (0x2) -#define NOTIFICATION_STATE_IRRIGATION_SCHEDULE_ID_STATUS (0x0) -#define NOTIFICATION_STATE_IRRIGATION_VALVE_RUN_STATUS (0x1) -#define NOTIFICATION_STATE_IRRIGATION_DEVICE_CONFIGURATION_STATUS (0x2) -#define NOTIFICATION_STATE_GAS_ALARM_COMBUSTIBLE_GAS_STATUS (0x0) -#define NOTIFICATION_STATE_GAS_ALARM_TOXIC_GAS_STATUS (0x1) -#define NOTIFICATION_STATE_GAS_ALARM_ALARM_STATUS (0x2) -#define NOTIFICATION_STATE_GAS_ALARM_MAINTENANCE_STATUS (0x3) -#define NOTIFICATION_STATE_PEST_CONTROL_TRAP_STATUS (0x0) -#define NOTIFICATION_STATE_LIGHT_SENSOR_LIGHT_DETECTION_STATUS (0x0) +#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_SAFETY_BEARM_OBSTACLE_STATUS \ + (0x6) +#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_SENSOR_STATUS (0x7) +#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_BATTERY_STATUS (0x8) +#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_SHORTCIRCUIT_STATUS (0x9) +#define NOTIFICATION_STATE_ACCESS_CONTROL_BARRIER_CONTROL_STATUS (0xa) +#define NOTIFICATION_STATE_HOME_SECURITY_SENSOR_STATUS (0x0) +#define NOTIFICATION_STATE_HOME_SECURITY_COVER_STATUS (0x1) +#define NOTIFICATION_STATE_HOME_SECURITY_MOTION_SENSOR_STATUS (0x2) +#define NOTIFICATION_STATE_HOME_SECURITY_MAGNETIC_INTERFERENCE_STATUS (0x3) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_POWER_STATUS (0x0) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_MAINS_STATUS (0x1) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_OVERCURRENT_STATUS (0x2) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_OVERVOLTAGE_STATUS (0x3) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_OVERLOAD_STATUS (0x4) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_LOAD_ERROR_STATUS (0x5) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_BATTERY_MAINTENANCE_STATUS (0x6) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_BATTERY_LOAD_STATUS (0x7) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_BATTERY_LEVEL_STATUS (0x8) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_BACKUP_BATTERY_LEVEL_STATUS (0x9) +#define NOTIFICATION_STATE_POWER_MANAGEMENT_DC_JACK_STATUS (0xa) +#define NOTIFICATION_STATE_SYSTEM_HW_STATUS (0x0) +#define NOTIFICATION_STATE_SYSTEM_SW_STATUS (0x1) +#define NOTIFICATION_STATE_SYSTEM_COVER_STATUS (0x2) +#define NOTIFICATION_STATE_SYSTEM_EMERGENCY_SHUTOFF_STATUS (0x3) +#define NOTIFICATION_STATE_SYSTEM_DIGITAL_INPUT_STATE (0x4) +#define NOTIFICATION_STATE_APPLIANCE_PROGRAM_STATUS (0x0) +#define NOTIFICATION_STATE_APPLIANCE_MAINTENANCE_STATUS (0x1) +#define NOTIFICATION_STATE_APPLIANCE_APPLIANCE_STATUS (0x2) +#define NOTIFICATION_STATE_APPLIANCE_TARGET_TEMPERATURE_FAILURE_STATUS (0x3) +#define NOTIFICATION_STATE_APPLIANCE_WATER_SUPPLY_FAILURE_STATUS (0x4) +#define NOTIFICATION_STATE_APPLIANCE_BOILING_FAILURE_STATUS (0x5) +#define NOTIFICATION_STATE_APPLIANCE_WASHING_FAILURE_STATUS (0x6) +#define NOTIFICATION_STATE_APPLIANCE_RINSING_FAILURE_STATUS (0x7) +#define NOTIFICATION_STATE_APPLIANCE_DRAINING_FAILURE_STATUS (0x8) +#define NOTIFICATION_STATE_APPLIANCE_SPINNING_FAILURE_STATUS (0x9) +#define NOTIFICATION_STATE_APPLIANCE_DRYING_FAILURE_STATUS (0xa) +#define NOTIFICATION_STATE_APPLIANCE_FAN_FAILURE_STATUS (0xb) +#define NOTIFICATION_STATE_APPLIANCE_COMPRESSOR_FAILURE_STATUS (0xc) +#define NOTIFICATION_STATE_HOME_HEALTH_POSITION_STATUS (0x0) +#define NOTIFICATION_STATE_HOME_HEALTH_SLEEP_APNEA_STATUS (0x1) +#define NOTIFICATION_STATE_HOME_HEALTH_SLEEP_STAGE_STATUS (0x2) +#define NOTIFICATION_STATE_SIREN_SIREN_STATUS (0x0) +#define NOTIFICATION_STATE_WATER_VALVE_VALVE_OPERATION_STATUS (0x0) +#define NOTIFICATION_STATE_WATER_VALVE_MAIN_VALVE_OPERATION_STATUS (0x1) +#define NOTIFICATION_STATE_WATER_VALVE_VALVE_SHORT_CIRCUIT_STATUS (0x2) +#define NOTIFICATION_STATE_WATER_VALVE_MAIN_VALVE_SHORT_CIRCUIT_STATUS (0x3) +#define NOTIFICATION_STATE_WATER_VALVE_VALVE_CURRENT_ALARM_STATUS (0x4) +#define NOTIFICATION_STATE_WATER_VALVE_MAIN_VALVE_CURRENT_ALARM_STATUS (0x5) +#define NOTIFICATION_STATE_WATER_VALVE_WATER_JAMMED_STATUS (0x6) +#define NOTIFICATION_STATE_WEATHER_ALARM_RAIN_ALARM_STATUS (0x0) +#define NOTIFICATION_STATE_WEATHER_ALARM_MOISTURE_ALARM_STATUS (0x1) +#define NOTIFICATION_STATE_WEATHER_ALARM_FREEZE_ALARM_STATUS (0x2) +#define NOTIFICATION_STATE_IRRIGATION_SCHEDULE_ID_STATUS (0x0) +#define NOTIFICATION_STATE_IRRIGATION_VALVE_RUN_STATUS (0x1) +#define NOTIFICATION_STATE_IRRIGATION_DEVICE_CONFIGURATION_STATUS (0x2) +#define NOTIFICATION_STATE_GAS_ALARM_COMBUSTIBLE_GAS_STATUS (0x0) +#define NOTIFICATION_STATE_GAS_ALARM_TOXIC_GAS_STATUS (0x1) +#define NOTIFICATION_STATE_GAS_ALARM_ALARM_STATUS (0x2) +#define NOTIFICATION_STATE_GAS_ALARM_MAINTENANCE_STATUS (0x3) +#define NOTIFICATION_STATE_PEST_CONTROL_TRAP_STATUS (0x0) +#define NOTIFICATION_STATE_LIGHT_SENSOR_LIGHT_DETECTION_STATUS (0x0) #define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_CHLORINE_ALARM_STATUS (0x0) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_ACIDITY_PH_STATUS (0x1) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_WATER_OXIDATION_ALARM_STATUS (0x2) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_ACIDITY_PH_STATUS (0x1) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_WATER_OXIDATION_ALARM_STATUS \ + (0x2) #define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_CHLORINE_SENSOR_STATUS (0x3) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_ACIDITY_PH_SENSOR_STATUS (0x4) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_WATERFLOW_MEASURING_STATION_SENSOR (0x5) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_WATERFLOW_CLEAR_WATER_SENSOR (0x6) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_DISINFECTION_SYSTEM_STATUS (0x7) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_ACIDITY_PH_SENSOR_STATUS \ + (0x4) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_WATERFLOW_MEASURING_STATION_SENSOR \ + (0x5) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_WATERFLOW_CLEAR_WATER_SENSOR \ + (0x6) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_DISINFECTION_SYSTEM_STATUS \ + (0x7) #define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_FILTER_CLEANING_STATUS (0x8) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_HEATING_STATUS (0x9) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_FILTER_PUMP_STATUS (0xa) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_HEATING_STATUS (0x9) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_FILTER_PUMP_STATUS (0xa) #define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_FRESHWATER_FLOW_STATUS (0xb) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_DRY_PROTECTION_STATUS (0xc) -#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_COLLECTIVE_DISORDER_STATUS (0xd) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_DRY_PROTECTION_STATUS (0xc) +#define NOTIFICATION_STATE_WATER_QUALITY_MONITORING_COLLECTIVE_DISORDER_STATUS \ + (0xd) #define NOTIFICATION_STATE_HOME_MONITORING_HOME_OCCUPANCY_STATUS (0x0) #endif //ZWAVE_COMMAND_CLASS_NOTIFICATION_TYPES_H diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_protocol.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_protocol.c index 4f8a64ef7..e519dd8d3 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_protocol.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_protocol.c @@ -42,15 +42,19 @@ protocol_metadata_t metadata = {0}; static zwave_controller_callbacks_t zwave_command_class_protocol_callbacks = { - .on_protocol_cc_encryption_request = zwave_on_protocol_cc_encryption_request -}; + .on_protocol_cc_encryption_request = zwave_on_protocol_cc_encryption_request}; -static void on_send_protocol_data_callback_received(uint8_t status, const zwapi_tx_report_t *tx_info, void *user) +static void on_send_protocol_data_callback_received( + uint8_t status, const zwapi_tx_report_t *tx_info, void *user) { protocol_metadata_t *metadata = (protocol_metadata_t *)user; - if (status == TRANSMIT_COMPLETE_FAIL || status == TRANSMIT_COMPLETE_VERIFIED) { - zwave_controller_request_protocol_cc_encryption_callback(status, tx_info, metadata->session_id); + if (status == TRANSMIT_COMPLETE_FAIL + || status == TRANSMIT_COMPLETE_VERIFIED) { + zwave_controller_request_protocol_cc_encryption_callback( + status, + tx_info, + metadata->session_id); } else { sl_log_debug(LOG_TAG, "Send Protocol Data callback, status: %d", status); } @@ -65,19 +69,20 @@ void zwave_on_protocol_cc_encryption_request( const uint8_t use_supervision, const uint8_t session_id) { - zwave_controller_connection_info_t connection_info = {0}; - zwave_tx_options_t tx_options = {0}; - uint8_t number_of_expected_responses = 1; - uint32_t discard_timeout_ms = 5000; + zwave_controller_connection_info_t connection_info = {0}; + zwave_tx_options_t tx_options = {0}; + uint8_t number_of_expected_responses = 1; + uint32_t discard_timeout_ms = 5000; // sl_status_t ret = SL_STATUS_OK; - zwave_tx_session_id_t tx_session_id = NULL; + zwave_tx_session_id_t tx_session_id = NULL; - zwave_tx_scheme_get_node_connection_info(destination_node_id, 0, &connection_info); - zwave_tx_scheme_get_node_tx_options( - ZWAVE_TX_QOS_MAX_PRIORITY, - number_of_expected_responses, - discard_timeout_ms, - &tx_options); + zwave_tx_scheme_get_node_connection_info(destination_node_id, + 0, + &connection_info); + zwave_tx_scheme_get_node_tx_options(ZWAVE_TX_QOS_MAX_PRIORITY, + number_of_expected_responses, + discard_timeout_ms, + &tx_options); // Other TX options are set in the transport layer in `S2_send_frame` tx_options.transport.is_protocol_frame = true; @@ -86,8 +91,7 @@ void zwave_on_protocol_cc_encryption_request( metadata.data_length = protocol_metadata_length; memcpy(metadata.data, protocol_metadata, protocol_metadata_length); - if (use_supervision) - { + if (use_supervision) { zwave_command_class_supervision_send_data( &connection_info, payload_length, @@ -97,14 +101,13 @@ void zwave_on_protocol_cc_encryption_request( (void *)&metadata, &tx_session_id); } else { - zwave_tx_send_data( - &connection_info, - payload_length, - payload, - &tx_options, - &on_send_protocol_data_callback_received, - (void *)&metadata, - &tx_session_id); + zwave_tx_send_data(&connection_info, + payload_length, + payload, + &tx_options, + &on_send_protocol_data_callback_received, + (void *)&metadata, + &tx_session_id); } } @@ -118,11 +121,12 @@ sl_status_t zwave_command_class_protocol_support_handler( return SL_STATUS_NOT_SUPPORTED; } - sl_log_info(LOG_TAG, "Protocol command received from NodeID %d:%d", - connection->remote.node_id, connection->remote.endpoint_id); + sl_log_info(LOG_TAG, + "Protocol command received from NodeID %d:%d", + connection->remote.node_id, + connection->remote.endpoint_id); - sl_status_t status = - zwapi_transfer_protocol_cc( + sl_status_t status = zwapi_transfer_protocol_cc( connection->remote.node_id, zwave_controller_get_key_from_encapsulation(connection->encapsulation), frame_length, @@ -131,17 +135,17 @@ sl_status_t zwave_command_class_protocol_support_handler( switch (status) { case SL_STATUS_OK: sl_log_info(LOG_TAG, - "Command from NodeID %d:%d was handled successfully.", - connection->remote.node_id, - connection->remote.endpoint_id); + "Command from NodeID %d:%d was handled successfully.", + connection->remote.node_id, + connection->remote.endpoint_id); break; case SL_STATUS_FAIL: sl_log_warning(LOG_TAG, - "Command from NodeID %d:%d had an error during handling. " - "Not all parameters were accepted", - connection->remote.node_id, - connection->remote.endpoint_id); + "Command from NodeID %d:%d had an error during handling. " + "Not all parameters were accepted", + connection->remote.node_id, + connection->remote.endpoint_id); break; case SL_STATUS_BUSY: @@ -177,38 +181,42 @@ sl_status_t zwave_command_class_protocol_support_handler( sl_status_t zwave_command_class_protocol_init() { - zwave_command_handler_t handler_protocol = { 0 }; - handler_protocol.support_handler = &zwave_command_class_protocol_support_handler; - handler_protocol.control_handler = NULL; - handler_protocol.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE; - handler_protocol.command_class = ZWAVE_CMD_CLASS_PROTOCOL; - handler_protocol.version = 1; + zwave_command_handler_t handler_protocol = {0}; + handler_protocol.support_handler + = &zwave_command_class_protocol_support_handler; + handler_protocol.control_handler = NULL; + handler_protocol.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE; + handler_protocol.command_class = ZWAVE_CMD_CLASS_PROTOCOL; + handler_protocol.version = 1; handler_protocol.command_class_name = "Protocol"; handler_protocol.manual_security_validation = false; - if(SL_STATUS_OK != zwave_controller_register_callbacks(&zwave_command_class_protocol_callbacks)) - { - sl_log_error(LOG_TAG, "Failed to register callbacks for Protocol Command Class"); + if (SL_STATUS_OK + != zwave_controller_register_callbacks( + &zwave_command_class_protocol_callbacks)) { + sl_log_error(LOG_TAG, + "Failed to register callbacks for Protocol Command Class"); return SL_STATUS_FAIL; } - if(SL_STATUS_OK != zwave_command_handler_register_handler(handler_protocol)) - { + if (SL_STATUS_OK + != zwave_command_handler_register_handler(handler_protocol)) { sl_log_error(LOG_TAG, "Failed to register Protocol Command Class"); return SL_STATUS_FAIL; } - zwave_command_handler_t handler_protocol_lr = { 0 }; - handler_protocol_lr.support_handler = &zwave_command_class_protocol_support_handler; - handler_protocol_lr.control_handler = NULL; - handler_protocol_lr.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE; - handler_protocol_lr.command_class = ZWAVE_CMD_CLASS_PROTOCOL_LR; - handler_protocol_lr.version = 1; + zwave_command_handler_t handler_protocol_lr = {0}; + handler_protocol_lr.support_handler + = &zwave_command_class_protocol_support_handler; + handler_protocol_lr.control_handler = NULL; + handler_protocol_lr.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NONE; + handler_protocol_lr.command_class = ZWAVE_CMD_CLASS_PROTOCOL_LR; + handler_protocol_lr.version = 1; handler_protocol_lr.command_class_name = "Protocol LR"; handler_protocol_lr.manual_security_validation = false; - if (SL_STATUS_OK != zwave_command_handler_register_handler(handler_protocol_lr)) - { + if (SL_STATUS_OK + != zwave_command_handler_register_handler(handler_protocol_lr)) { sl_log_error(LOG_TAG, "Failed to register Protocol Command Class"); return SL_STATUS_FAIL; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_security_2.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_security_2.c index 3306a14f8..a80f39462 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_security_2.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_security_2.c @@ -152,7 +152,11 @@ static void on_nls_state_get_v2_send_complete(uint8_t status, zwave_node_id_t node_id = *((zwave_node_id_t *)user); (void)tx_info; - sl_log_debug(LOG_TAG, "%s, status: %d, node_id: %d", __func__, status, node_id); + sl_log_debug(LOG_TAG, + "%s, status: %d, node_id: %d", + __func__, + status, + node_id); } static void on_nls_state_set_v2_send_complete(uint8_t status, @@ -165,47 +169,54 @@ static void on_nls_state_set_v2_send_complete(uint8_t status, zwave_node_id_t node_id = *((zwave_node_id_t *)user); sl_status_t send_status = SL_STATUS_OK; - sl_log_debug(LOG_TAG, "%s, status: %d, node_id: %d", __func__, status, node_id); + sl_log_debug(LOG_TAG, + "%s, status: %d, node_id: %d", + __func__, + status, + node_id); switch (status) { - case TRANSMIT_COMPLETE_VERIFIED: - case TRANSMIT_COMPLETE_OK: - { - ZW_NLS_STATE_GET_V2_FRAME frame = {0}; - frame.cmdClass = COMMAND_CLASS_SECURITY_2; - frame.cmd = NLS_STATE_GET_V2; - - zwave_controller_connection_info_t connection_info = {}; - zwave_tx_options_t tx_options = {}; - uint8_t number_of_expected_responses = 1; - uint32_t discard_timeout_ms = 5 * CLOCK_CONF_SECOND; - - zwave_tx_scheme_get_node_connection_info(node_id, 0, &connection_info); - zwave_tx_scheme_get_node_tx_options( - ZWAVE_TX_QOS_MAX_PRIORITY, - number_of_expected_responses, - discard_timeout_ms, - &tx_options); - - last_node_id = node_id; - send_status = zwave_tx_send_data(&connection_info, - sizeof(ZW_NLS_STATE_GET_V2_FRAME), - (const uint8_t *)&frame, - &tx_options, - on_nls_state_get_v2_send_complete, - (void *)&last_node_id, - NULL); - } - break; + case TRANSMIT_COMPLETE_VERIFIED: + case TRANSMIT_COMPLETE_OK: { + ZW_NLS_STATE_GET_V2_FRAME frame = {0}; + frame.cmdClass = COMMAND_CLASS_SECURITY_2; + frame.cmd = NLS_STATE_GET_V2; + + zwave_controller_connection_info_t connection_info = {}; + zwave_tx_options_t tx_options = {}; + uint8_t number_of_expected_responses = 1; + uint32_t discard_timeout_ms = 5 * CLOCK_CONF_SECOND; + + zwave_tx_scheme_get_node_connection_info(node_id, 0, &connection_info); + zwave_tx_scheme_get_node_tx_options(ZWAVE_TX_QOS_MAX_PRIORITY, + number_of_expected_responses, + discard_timeout_ms, + &tx_options); + + last_node_id = node_id; + send_status = zwave_tx_send_data(&connection_info, + sizeof(ZW_NLS_STATE_GET_V2_FRAME), + (const uint8_t *)&frame, + &tx_options, + on_nls_state_get_v2_send_complete, + (void *)&last_node_id, + NULL); + } break; default: send_status = SL_STATUS_TRANSMIT_INCOMPLETE; break; } if (send_status == SL_STATUS_OK) { - sl_log_debug(LOG_TAG, "Sending NLS State Get Command to node ID: %d", node_id); + sl_log_debug(LOG_TAG, + "Sending NLS State Get Command to node ID: %d", + node_id); } else { - sl_log_error(LOG_TAG, "Failed to send NLS State Get Command to node ID: %d, status: %d", node_id, send_status); + sl_log_error( + LOG_TAG, + "Failed to send NLS State Get Command to node ID: %d, status: %d", + node_id, + send_status); } } @@ -213,15 +224,15 @@ static sl_status_t zwave_command_class_security_2_nls_state_set(zwave_node_id_t node_id) { ZW_NLS_STATE_SET_V2_FRAME frame = {0}; - frame.cmdClass = COMMAND_CLASS_SECURITY_2; - frame.cmd = NLS_STATE_SET_V2; - frame.nlsState = true; + frame.cmdClass = COMMAND_CLASS_SECURITY_2; + frame.cmd = NLS_STATE_SET_V2; + frame.nlsState = true; - zwave_controller_connection_info_t connection_info = {0}; - zwave_tx_options_t tx_options = {0}; - uint8_t number_of_expected_responses = 0; - uint32_t discard_timeout_ms = 5 * CLOCK_CONF_SECOND; - sl_status_t send_status = SL_STATUS_OK; + zwave_controller_connection_info_t connection_info = {0}; + zwave_tx_options_t tx_options = {0}; + uint8_t number_of_expected_responses = 0; + uint32_t discard_timeout_ms = 5 * CLOCK_CONF_SECOND; + sl_status_t send_status = SL_STATUS_OK; zwave_tx_scheme_get_node_connection_info(node_id, 0, &connection_info); zwave_tx_scheme_get_node_tx_options( @@ -229,28 +240,34 @@ static sl_status_t number_of_expected_responses, discard_timeout_ms, &tx_options); - + last_node_id = node_id; - send_status = zwave_tx_send_data( - &connection_info, - sizeof(ZW_NLS_STATE_SET_V2_FRAME), - (const uint8_t *)&frame, - &tx_options, - on_nls_state_set_v2_send_complete, - (void *)&last_node_id, - NULL); + send_status = zwave_tx_send_data(&connection_info, + sizeof(ZW_NLS_STATE_SET_V2_FRAME), + (const uint8_t *)&frame, + &tx_options, + on_nls_state_set_v2_send_complete, + (void *)&last_node_id, + NULL); if (send_status == SL_STATUS_OK) { - sl_log_debug(LOG_TAG, "Sending NLS State Set Command to node ID: %d", node_id); + sl_log_debug(LOG_TAG, + "Sending NLS State Set Command to node ID: %d", + node_id); } else { - sl_log_error(LOG_TAG, "Failed to send NLS State Set Command to node ID: %d, status: %d", node_id, send_status); + sl_log_error( + LOG_TAG, + "Failed to send NLS State Set Command to node ID: %d, status: %d", + node_id, + send_status); } return send_status; } -static void on_attribute_zwave_nls_state_desired_change( - attribute_store_node_t node, attribute_store_change_t change) +static void + on_attribute_zwave_nls_state_desired_change(attribute_store_node_t node, + attribute_store_change_t change) { if (change != ATTRIBUTE_UPDATED) { sl_log_debug(LOG_TAG, "NLS State Desired attribute change ignored"); diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_sound_switch.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_sound_switch.c index 73507bc28..c0899edaf 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_sound_switch.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_sound_switch.c @@ -47,7 +47,6 @@ typedef struct sound_switch_configuration { sound_switch_tone_id_t tone; } sound_switch_configuration_t; - static sl_status_t zwave_command_class_sound_switch_tones_number_get( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { @@ -66,7 +65,7 @@ sl_status_t zwave_command_class_sound_switch_handle_tones_number_report( uint16_t frame_length) { if (frame_length < 2 + 1) { - return SL_STATUS_FAIL ; + return SL_STATUS_FAIL; } attribute_store_node_t endpoint_node @@ -77,13 +76,20 @@ sl_status_t zwave_command_class_sound_switch_handle_tones_number_report( sl_log_warning(LOG_TAG, "Zero Tones reported"); } - attribute_store_node_t tone_number_node = attribute_store_get_node_child_by_type(endpoint_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, 0); - - attribute_store_set_reported(tone_number_node, &tone_number, sizeof(tone_number)); + attribute_store_node_t tone_number_node + = attribute_store_get_node_child_by_type( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, + 0); + + attribute_store_set_reported(tone_number_node, + &tone_number, + sizeof(tone_number)); - for(uint8_t i=1; i <= tone_number; i++) { - attribute_store_node_t node_id = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER, tone_number_node); + for (uint8_t i = 1; i <= tone_number; i++) { + attribute_store_node_t node_id = attribute_store_add_node( + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER, + tone_number_node); attribute_store_set_desired(node_id, &i, sizeof(i)); sl_log_debug(LOG_TAG, "Set desired value %d of node %d", i, node_id); } @@ -94,23 +100,27 @@ sl_status_t zwave_command_class_sound_switch_handle_tones_number_report( static sl_status_t zwave_command_class_sound_switch_tone_info_get( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { - sl_log_debug(LOG_TAG, "zwave_command_class_sound_switch_tone_info_get : %d", node); - + sl_log_debug(LOG_TAG, + "zwave_command_class_sound_switch_tone_info_get : %d", + node); sound_switch_tone_id_t tone_id = 0; - sl_status_t status = attribute_store_get_desired(node, &tone_id, sizeof(tone_id)); + sl_status_t status + = attribute_store_get_desired(node, &tone_id, sizeof(tone_id)); sl_log_debug(LOG_TAG, "tone_id : %d", tone_id); // If we don't have a desired value look for the default tone ID if present // NOTE : if we don't have a node ID to look for we just abort here and don't send anything. // This will prevent a request to go off for no reason. if (status != SL_STATUS_OK) { - attribute_store_node_t parent_node = attribute_store_get_node_parent(node); - attribute_store_node_t tone_id_node = attribute_store_get_first_child_by_type(parent_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER); + attribute_store_node_t tone_id_node + = attribute_store_get_first_child_by_type( + parent_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER); - status = attribute_store_get_reported(tone_id_node, &tone_id, sizeof(tone_id)); + status + = attribute_store_get_reported(tone_id_node, &tone_id, sizeof(tone_id)); if (status != SL_STATUS_OK) { // We return SL_STATUS_NOT_SUPPORTED instead of SL_STATUS_FAIL to prevent an error @@ -121,26 +131,24 @@ static sl_status_t zwave_command_class_sound_switch_tone_info_get( ZW_SOUND_SWITCH_TONE_INFO_GET_FRAME *get_frame = (ZW_SOUND_SWITCH_TONE_INFO_GET_FRAME *)frame; - get_frame->cmdClass = COMMAND_CLASS_SOUND_SWITCH; - get_frame->cmd = SOUND_SWITCH_TONE_INFO_GET; + get_frame->cmdClass = COMMAND_CLASS_SOUND_SWITCH; + get_frame->cmd = SOUND_SWITCH_TONE_INFO_GET; get_frame->toneIdentifier = tone_id; - *frame_length = sizeof(ZW_SOUND_SWITCH_TONE_INFO_GET_FRAME); + *frame_length = sizeof(ZW_SOUND_SWITCH_TONE_INFO_GET_FRAME); return SL_STATUS_OK; } - sl_status_t zwave_command_class_sound_switch_handle_tone_info_report( const zwave_controller_connection_info_t *connection_info, const uint8_t *frame_data, uint16_t frame_length) { - - // Frame format : + // Frame format : // 0 Command Class = COMMAND_CLASS_SOUND_SWITCH // 1 Command = SOUND_SWITCH_TONE_INFO_REPORT SIZE_FRAME_INFO // 2 Tone Identifier SIZE_TONE_ID - // 3 Tone Duration 1 SIZE_TONE_DURATION + // 3 Tone Duration 1 SIZE_TONE_DURATION // 4 Tone Duration 2 // 5 Name Length SIZE_TONE_NAME_SIZE // 6 Name 1 @@ -148,18 +156,20 @@ sl_status_t zwave_command_class_sound_switch_handle_tone_info_report( // N Name N // Size frame info - const uint8_t SIZE_FRAME_INFO = 2; - const uint8_t SIZE_TONE_ID = 1; - const uint8_t SIZE_TONE_DURATION = 2; + const uint8_t SIZE_FRAME_INFO = 2; + const uint8_t SIZE_TONE_ID = 1; + const uint8_t SIZE_TONE_DURATION = 2; const uint8_t SIZE_TONE_NAME_SIZE = 1; - const uint8_t SIZE_MESSAGE_WITHOUT_NAME = SIZE_FRAME_INFO + SIZE_TONE_ID + SIZE_TONE_DURATION + SIZE_TONE_NAME_SIZE; + const uint8_t SIZE_MESSAGE_WITHOUT_NAME + = SIZE_FRAME_INFO + SIZE_TONE_ID + SIZE_TONE_DURATION + SIZE_TONE_NAME_SIZE; // Addresses - const uint8_t ADDRESS_TONE_IDENTIFIER = SIZE_FRAME_INFO; // 2 - const uint8_t ADDRESS_DURATION_1 = SIZE_FRAME_INFO + 1; // 3 - const uint8_t ADDRESS_DURATION_2 = SIZE_FRAME_INFO + 2; // 4 - const uint8_t ADDRESS_NAME_SIZE = SIZE_FRAME_INFO + SIZE_TONE_ID + SIZE_TONE_DURATION; // 5 - const uint8_t ADDRESS_NAME_STR_BASE = ADDRESS_NAME_SIZE + 1; // 6 + const uint8_t ADDRESS_TONE_IDENTIFIER = SIZE_FRAME_INFO; // 2 + const uint8_t ADDRESS_DURATION_1 = SIZE_FRAME_INFO + 1; // 3 + const uint8_t ADDRESS_DURATION_2 = SIZE_FRAME_INFO + 2; // 4 + const uint8_t ADDRESS_NAME_SIZE + = SIZE_FRAME_INFO + SIZE_TONE_ID + SIZE_TONE_DURATION; // 5 + const uint8_t ADDRESS_NAME_STR_BASE = ADDRESS_NAME_SIZE + 1; // 6 // Check frame size if (frame_length < SIZE_MESSAGE_WITHOUT_NAME) { @@ -173,7 +183,8 @@ sl_status_t zwave_command_class_sound_switch_handle_tone_info_report( // frame_data[ADDRESS_DURATION_1] frame_data[ADDRESS_DURATION_2] // 01 05 // Result 0105 - sound_switch_tone_duration_t tone_duration = (frame_data[ADDRESS_DURATION_1] << 8) | frame_data[ADDRESS_DURATION_2]; + sound_switch_tone_duration_t tone_duration + = (frame_data[ADDRESS_DURATION_1] << 8) | frame_data[ADDRESS_DURATION_2]; // Size of name array uint8_t tone_name_size = frame_data[ADDRESS_NAME_SIZE]; @@ -195,10 +206,12 @@ sl_status_t zwave_command_class_sound_switch_handle_tone_info_report( // Update attribute store attribute_store_node_t endpoint_node = zwave_command_class_get_endpoint_node(connection_info); - - attribute_store_node_t tone_number_node = - attribute_store_get_node_child_by_type(endpoint_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, 0); + + attribute_store_node_t tone_number_node + = attribute_store_get_node_child_by_type( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, + 0); // Find tone identifier attribute_store_node_t id_node = attribute_store_get_node_child_by_value( @@ -206,9 +219,12 @@ sl_status_t zwave_command_class_sound_switch_handle_tone_info_report( ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER, DESIRED_ATTRIBUTE, &tone_identifier, - sizeof(tone_identifier), 0); + sizeof(tone_identifier), + 0); - attribute_store_set_reported(id_node, &tone_identifier, sizeof(tone_identifier)); + attribute_store_set_reported(id_node, + &tone_identifier, + sizeof(tone_identifier)); // Store attributes attribute_store_set_child_reported( @@ -223,12 +239,11 @@ sl_status_t zwave_command_class_sound_switch_handle_tone_info_report( id_node, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_NAME, &tone_name, - tone_name_size+1); + tone_name_size + 1); return SL_STATUS_OK; } - static sl_status_t zwave_command_class_sound_switch_configuration_get( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { @@ -246,7 +261,6 @@ sl_status_t zwave_command_class_sound_switch_handle_configuration_report( const uint8_t *frame_data, uint16_t frame_length) { - if (frame_length < 4) { return SL_STATUS_FAIL; } @@ -277,33 +291,38 @@ sl_status_t zwave_command_class_sound_switch_handle_configuration_report( return SL_STATUS_OK; } - static void get_configuration(attribute_store_node_t state_node, sound_switch_configuration_t *configuration) { - attribute_store_node_t volume_node - = attribute_store_get_first_child_by_type(state_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME); - - sl_status_t status = attribute_store_get_desired_else_reported(volume_node, - &configuration->volume, - sizeof(configuration->volume)); + attribute_store_node_t volume_node = attribute_store_get_first_child_by_type( + state_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME); + + sl_status_t status + = attribute_store_get_desired_else_reported(volume_node, + &configuration->volume, + sizeof(configuration->volume)); if (status != SL_STATUS_OK) { configuration->volume = 0; - sl_log_warning(LOG_TAG, "Can't get CONFIGURED_DEFAULT_VOLUME from attribute store. Value set to 0."); + sl_log_warning(LOG_TAG, + "Can't get CONFIGURED_DEFAULT_VOLUME from attribute store. " + "Value set to 0."); } - attribute_store_node_t tone_node - = attribute_store_get_first_child_by_type(state_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER); + attribute_store_node_t tone_node = attribute_store_get_first_child_by_type( + state_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER); - status = attribute_store_get_desired_else_reported(tone_node, - &configuration->tone, - sizeof(configuration->tone)); + status + = attribute_store_get_desired_else_reported(tone_node, + &configuration->tone, + sizeof(configuration->tone)); if (status != SL_STATUS_OK) { configuration->tone = 0; - sl_log_warning(LOG_TAG, "Can't get CONFIGURED_DEFAULT_TONE_IDENTIFIER from attribute store. Value set to 0."); + sl_log_warning(LOG_TAG, + "Can't get CONFIGURED_DEFAULT_TONE_IDENTIFIER from " + "attribute store. Value set to 0."); } } @@ -325,15 +344,16 @@ static sl_status_t zwave_command_class_sound_switch_configuration_set( set_frame->defaultToneIdentifier = configuration.tone; *frame_length = sizeof(ZW_SOUND_SWITCH_CONFIGURATION_SET_FRAME); return SL_STATUS_OK; -} +} static void zwave_monitor_dotdot_on_off_on_time_update( - attribute_store_node_t updated_node, attribute_store_change_t change) { - + attribute_store_node_t updated_node, attribute_store_change_t change) +{ attribute_store_node_t endpoint_node = attribute_store_get_first_parent_with_type(updated_node, ATTRIBUTE_ENDPOINT_ID); - attribute_store_node_t play_node = attribute_store_get_first_child_by_type(endpoint_node, + attribute_store_node_t play_node = attribute_store_get_first_child_by_type( + endpoint_node, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY); // We are not in a sound switch environemnt, we can don't care about this update @@ -347,7 +367,8 @@ static void zwave_monitor_dotdot_on_off_on_time_update( } uint16_t on_time = 0; - sl_status_t status = attribute_store_get_desired(updated_node, &on_time, sizeof(on_time)); + sl_status_t status + = attribute_store_get_desired(updated_node, &on_time, sizeof(on_time)); // We can be in this state for many reasons (e.g. desired attribute undefined) // In that case we do nothing and move on. @@ -362,7 +383,9 @@ static void zwave_monitor_dotdot_on_off_on_time_update( sound_switch_tone_id_t tone_id = (sound_switch_tone_id_t)on_time; // Copy attribute to the play node - attribute_store_set_desired(play_node, &tone_id, sizeof(sound_switch_tone_id_t)); + attribute_store_set_desired(play_node, + &tone_id, + sizeof(sound_switch_tone_id_t)); // Undefine temp buffer attribute_store_undefine_desired(updated_node); } @@ -375,7 +398,9 @@ static void zwave_command_class_sound_switch_on_version_attribute_update( } if (is_zwave_command_class_filtered_for_root_device( - COMMAND_CLASS_SOUND_SWITCH, updated_node) == true) { + COMMAND_CLASS_SOUND_SWITCH, + updated_node) + == true) { return; } @@ -390,11 +415,10 @@ static void zwave_command_class_sound_switch_on_version_attribute_update( = attribute_store_get_first_parent_with_type(updated_node, ATTRIBUTE_ENDPOINT_ID); - // Attribute initialisation order is important here since it determines in + // Attribute initialisation order is important here since it determines in // which order the GET commands will be sent const attribute_store_type_t attributes[] - = { - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, + = {ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY}; @@ -408,11 +432,17 @@ static sl_status_t zwave_command_class_sound_switch_tone_play_set( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_length) { // Check version - attribute_store_node_t endpoint_node = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_ENDPOINT_ID); - attribute_store_node_t version_node = attribute_store_get_node_child_by_type(endpoint_node, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_VERSION, 0); + attribute_store_node_t endpoint_node + = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_ENDPOINT_ID); + attribute_store_node_t version_node = attribute_store_get_node_child_by_type( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_VERSION, + 0); zwave_cc_version_t current_supported_version = 0; - attribute_store_get_desired_else_reported(version_node, ¤t_supported_version, sizeof(current_supported_version)); + attribute_store_get_desired_else_reported(version_node, + ¤t_supported_version, + sizeof(current_supported_version)); // Attributes for the set command // 0 : Stop tone | 255 : Default tone @@ -422,22 +452,27 @@ static sl_status_t zwave_command_class_sound_switch_tone_play_set( attribute_store_get_desired_else_reported(node, &play, sizeof(play)); if (current_supported_version == 2) { - // Default volume + // Default volume sound_switch_volume_t volume = 255; - // Check volume if we doesn't try to stop the + // Check volume if we doesn't try to stop the if (play != 0) { - attribute_store_node_t volume_node = attribute_store_get_first_child_by_type(endpoint_node, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME); - - attribute_store_get_desired_else_reported(volume_node, &volume, sizeof(volume)); + attribute_store_node_t volume_node + = attribute_store_get_first_child_by_type( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME); + + attribute_store_get_desired_else_reported(volume_node, + &volume, + sizeof(volume)); } ZW_SOUND_SWITCH_TONE_PLAY_SET_V2_FRAME *set_frame = (ZW_SOUND_SWITCH_TONE_PLAY_SET_V2_FRAME *)frame; - set_frame->cmdClass = COMMAND_CLASS_SOUND_SWITCH; - set_frame->cmd = SOUND_SWITCH_TONE_PLAY_SET; - set_frame->toneIdentifier = play; + set_frame->cmdClass = COMMAND_CLASS_SOUND_SWITCH; + set_frame->cmd = SOUND_SWITCH_TONE_PLAY_SET; + set_frame->toneIdentifier = play; set_frame->playCommandToneVolume = volume; - *frame_length = sizeof(ZW_SOUND_SWITCH_TONE_PLAY_SET_V2_FRAME); + *frame_length = sizeof(ZW_SOUND_SWITCH_TONE_PLAY_SET_V2_FRAME); } else { ZW_SOUND_SWITCH_TONE_PLAY_SET_FRAME *set_frame = (ZW_SOUND_SWITCH_TONE_PLAY_SET_FRAME *)frame; @@ -474,9 +509,8 @@ sl_status_t zwave_command_class_sound_switch_handle_tone_play_report( attribute_store_node_t endpoint_node = zwave_command_class_get_endpoint_node(connection_info); - sound_switch_tone_id_t tone_identifier = frame_data[2]; - sound_switch_volume_t volume = 0; + sound_switch_volume_t volume = 0; // Volume is optional and only done in the version 2 of the class if (frame_length == 2 + 1 + 1) { @@ -576,13 +610,13 @@ sl_status_t zwave_command_class_sound_switch_init() // Workaround to allow to send a specific tone ID though this attribute. // - // The OnOff UCL cluster only support boolean states and we need a uint8_t to be able to + // The OnOff UCL cluster only support boolean states and we need a uint8_t to be able to // send specific toneID though the Play Set command. - // + // // There is 3 way to do this : // - Add an attribute to an existing UCL cluster // - Add a whole new cluster for sound switch - // - Map this functionality to an unused property. + // - Map this functionality to an unused property. // // The latest has been choosen to avoid changes on clusters. This approach might change // in future release, don't take this as a reference for now. @@ -593,7 +627,7 @@ sl_status_t zwave_command_class_sound_switch_init() // - Play specific tone (1-254) with the ZCL OnTime attribute (1-254) that will be "copied" into our ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY // - It can be controlled by the command WriteAttribute of the OnOff cluster though MQTT : ucl/by-unid/+/ep0/OnOff/Commands/WriteAttributes {"OnTime":2} // - // zwave_monitor_dotdot_on_off_on_time_update will copy the contents of DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME into + // zwave_monitor_dotdot_on_off_on_time_update will copy the contents of DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME into // ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY and then undefine itself. // // We do that here and not in UAM because we need to undefined the DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME value @@ -611,7 +645,9 @@ sl_status_t zwave_command_class_sound_switch_init() handler.command_class = COMMAND_CLASS_SOUND_SWITCH; handler.version = SOUND_SWITCH_VERSION_V2; handler.command_class_name = "Sound Switch"; - handler.comments = "You can control the specific tone play with the ON_OFF_ON_TIME ZCL attribute. See code or python CTT script for details."; - + handler.comments + = "You can control the specific tone play with the ON_OFF_ON_TIME ZCL " + "attribute. See code or python CTT script for details."; + return zwave_command_handler_register_handler(handler); } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_supervision.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_supervision.c index f9ee011bb..8ebd053c1 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_supervision.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_supervision.c @@ -504,14 +504,13 @@ sl_status_t zwave_command_class_supervision_send_data( supervision_tx_options.number_of_responses += 1; intptr_t user_parameter; - if (!tx_options->transport.is_protocol_frame) - { + if (!tx_options->transport.is_protocol_frame) { user_parameter = (intptr_t)INVALID_SUPERVISION_ID; if (connection->remote.is_multicast == false) { user_parameter = (intptr_t)supervision_id; } } else { - user_parameter = (intptr_t) user; + user_parameter = (intptr_t)user; } sl_status_t zwave_tx_status = zwave_tx_send_data( diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_color.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_color.cpp index 649307245..a674b5d77 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_color.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_color.cpp @@ -52,8 +52,7 @@ static void set_duration(attribute_store_node_t state_node, sizeof(duration)); } -[[maybe_unused]] -static void +[[maybe_unused]] static void set_all_color_switch_durations(attribute_store_node_t state_node, attribute_store_node_value_state_t value_state, color_component_id_duration_t duration) @@ -83,14 +82,12 @@ static void switch_color_undefine_reported(attribute_store_node_t state_node) attribute_stop_transition); attribute_store_node_t duration_node - = attribute_store_get_first_child_by_type( - state_node, - ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_DURATION); + = attribute_store_get_first_child_by_type( + state_node, + ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_DURATION); color_component_id_duration_t duration = 0; attribute_store_undefine_desired(duration_node); - attribute_store_set_reported(duration_node, - &duration, - sizeof(duration)); + attribute_store_set_reported(duration_node, &duration, sizeof(duration)); sl_log_debug(LOG_TAG, "Transition time expired, probe color"); zwave_command_class_switch_color_invoke_on_all_attributes( @@ -118,14 +115,12 @@ static void } attribute_store_node_t duration_node - = attribute_store_get_first_child_by_type( - state_node, - ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_DURATION); + = attribute_store_get_first_child_by_type( + state_node, + ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_DURATION); color_component_id_duration_t duration = 0; - attribute_store_get_desired(duration_node, - &duration, - sizeof(duration)); + attribute_store_get_desired(duration_node, &duration, sizeof(duration)); clock_time_t zwave_desired_duration = zwave_duration_to_time((uint8_t)duration); @@ -153,7 +148,7 @@ static void state_node, ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_VALUE, attribute_stop_transition); - if(zwave_desired_duration > 0) { + if (zwave_desired_duration > 0) { // Should we estimate reported color values during transition // and publish them as reported, like we did for level cluster? diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_multilevel.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_multilevel.c index a95d1413d..8f5073af6 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_multilevel.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_switch_multilevel.c @@ -222,8 +222,8 @@ static sl_status_t zwave_command_class_switch_multilevel_set( set_frame->cmd = SWITCH_MULTILEVEL_SET_V4; *frame_length = sizeof(ZW_SWITCH_MULTILEVEL_SET_V4_FRAME); - set_frame->value = (uint8_t)state.desired_value; - set_frame->duration = (uint8_t)state.desired_duration; + set_frame->value = (uint8_t)state.desired_value; + set_frame->duration = (uint8_t)state.desired_duration; return SL_STATUS_OK; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.c index c62ce554e..8910ddfd4 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.c @@ -97,7 +97,7 @@ static bool // Check version compatibility if (!is_fan_mode_compatible_with_version(fan_control_mode_type, - current_version)) { + current_version)) { return false; } @@ -242,7 +242,9 @@ static sl_status_t zwave_command_class_thermostat_fan_mode_set( // Check version compatibility if (!is_fan_control_mode_supported(fan_mode, endpoint_node)) { - sl_log_warning(LOG_TAG, "Unsupported fan mode %#04x. Clearing desired value.", fan_mode); + sl_log_warning(LOG_TAG, + "Unsupported fan mode %#04x. Clearing desired value.", + fan_mode); attribute_store_undefine_desired(node); return SL_STATUS_NOT_SUPPORTED; } @@ -354,7 +356,7 @@ sl_status_t zwave_command_class_thermostat_fan_mode_supported_handle_report( } thermostat_fan_supported_modes_t supported_modes_bitmask = 0x0000; - uint8_t bitmask_length = frame_length - 2; + uint8_t bitmask_length = frame_length - 2; // Since we are using uint32_t we can't have more that 4 bit mask if (bitmask_length > 4) { @@ -372,13 +374,15 @@ sl_status_t zwave_command_class_thermostat_fan_mode_supported_handle_report( = zwave_command_class_get_endpoint_node(connection_info); sl_status_t set_value_status = attribute_store_set_child_reported( - endpoint_node, - ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_SUPPORTED_MODES, - &supported_modes_bitmask, - sizeof(supported_modes_bitmask)); + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_SUPPORTED_MODES, + &supported_modes_bitmask, + sizeof(supported_modes_bitmask)); if (set_value_status != SL_STATUS_OK) { - sl_log_error(LOG_TAG, "Can't set ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_SUPPORTED_MODES"); + sl_log_error( + LOG_TAG, + "Can't set ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_SUPPORTED_MODES"); return SL_STATUS_NOT_SUPPORTED; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.h index 5dd42edd5..c18861b7d 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_mode.h @@ -28,7 +28,6 @@ // Definition missing for now #define THERMOSTAT_FAN_MODE_REPORT_FAN_MODE_EXTERNAL_CIRCULATION_V5 0x0B - #include "sl_status.h" #ifdef __cplusplus diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_state.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_state.c index f03ed1f1c..3d4d060ee 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_state.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_fan_state.c @@ -38,8 +38,9 @@ ///////////////////////////////////////////////////////////////////////////// // Version & Attribute Creation ///////////////////////////////////////////////////////////////////////////// -static void zwave_command_class_thermostat_fan_state_on_version_attribute_update( - attribute_store_node_t updated_node, attribute_store_change_t change) +static void + zwave_command_class_thermostat_fan_state_on_version_attribute_update( + attribute_store_node_t updated_node, attribute_store_change_t change) { if (change == ATTRIBUTE_DELETED) { return; @@ -71,7 +72,6 @@ static void zwave_command_class_thermostat_fan_state_on_version_attribute_update attribute_store_add_if_missing(endpoint_node, attributes, COUNT_OF(attributes)); - } ///////////////////////////////////////////////////////////////////////////// @@ -99,11 +99,13 @@ sl_status_t zwave_command_class_thermostat_fan_state_handle_report( return SL_STATUS_FAIL; } - thermostat_fan_state_t fan_state = frame_data[2] & THERMOSTAT_FAN_STATE_REPORT_LEVEL_FAN_OPERATING_STATE_MASK; + thermostat_fan_state_t fan_state + = frame_data[2] + & THERMOSTAT_FAN_STATE_REPORT_LEVEL_FAN_OPERATING_STATE_MASK; attribute_store_node_t endpoint_node = zwave_command_class_get_endpoint_node(connection_info); - + attribute_store_set_child_reported( endpoint_node, ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_STATE_FAN_OPERATING_STATE, @@ -133,7 +135,6 @@ sl_status_t zwave_command_class_thermostat_fan_state_control_handler( } } - sl_status_t zwave_command_class_thermostat_fan_state_init() { attribute_store_register_callback_by_type( @@ -145,7 +146,6 @@ sl_status_t zwave_command_class_thermostat_fan_state_init() NULL, &zwave_command_class_thermostat_fan_state_get); - zwave_command_handler_t handler = {}; handler.support_handler = NULL; handler.control_handler diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.c index 8de55e3fa..11114ea33 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.c @@ -186,15 +186,16 @@ static sl_status_t zwave_command_class_thermostat_mode_handle_supported_report( = attribute_store_get_first_child_by_type( endpoint_node, ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES); - + uint8_t bitmask_length = frame_length - THERMOSTAT_MODE_SUPPORTED_REPORT_BITMASK_INDEX; uint32_t supported_thermostat_bitmask = 0x0000; // Since we are using uint32_t we can't have more that 4 bit mask if (bitmask_length > 4) { - sl_log_error(LOG_TAG, - "Supported Thermostat Mode type Bit Mask length is not supported\n"); + sl_log_error( + LOG_TAG, + "Supported Thermostat Mode type Bit Mask length is not supported\n"); return SL_STATUS_NOT_SUPPORTED; } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.h index 38cad626d..eb55b3a99 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_mode.h @@ -17,7 +17,7 @@ #include "sl_status.h" -#define THERMOSTAT_MODE_REPORT_MODE_INDEX 2 +#define THERMOSTAT_MODE_REPORT_MODE_INDEX 2 #define THERMOSTAT_MODE_SUPPORTED_REPORT_BITMASK_INDEX 2 #ifdef __cplusplus diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.c index be71eac1a..1cdd17d4a 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.c @@ -446,7 +446,8 @@ sl_status_t zwave_command_class_thermostat_operating_state_init() handler.command_class = COMMAND_CLASS_THERMOSTAT_OPERATING_STATE; handler.version = THERMOSTAT_OPERATING_STATE_VERSION_V2; handler.command_class_name = "Thermostat Operating State"; - handler.comments = "Experimental. Log related functions are not yet exposed to MQTT."; + handler.comments + = "Experimental. Log related functions are not yet exposed to MQTT."; return zwave_command_handler_register_handler(handler); } \ No newline at end of file diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.h index 5cf1568a0..b899c521d 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_operating_state.h @@ -37,4 +37,4 @@ sl_status_t zwave_command_class_thermostat_operating_state_init(); #endif #endif //ZWAVE_COMMAND_CLASS_THERMOSTAT_OPERATING_STATE_H -/** @} end zwave_command_class_thermostat_operating_state */ \ No newline at end of file + /** @} end zwave_command_class_thermostat_operating_state */ \ No newline at end of file diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_setpoint.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_setpoint.cpp index df97a34d5..b3513b6bb 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_setpoint.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_thermostat_setpoint.cpp @@ -1433,12 +1433,12 @@ sl_status_t zwave_command_class_thermostat_setpoint_init() // Resolver functions. attribute_resolver_register_rule( ATTRIBUTE(SUPPORTED_SETPOINT_TYPES), - NULL, // NOSONAR + NULL, // NOSONAR &zwave_command_class_thermostat_setpoint_supported_get); attribute_resolver_register_rule( ATTRIBUTE(MIN_VALUE), - NULL, // NOSONAR + NULL, // NOSONAR &zwave_command_class_thermostat_setpoint_capabilities_get); attribute_resolver_register_rule( diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.cpp b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.cpp index 4dbf92acc..47decdb47 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.cpp +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.cpp @@ -65,9 +65,8 @@ static sl_status_t zwave_command_class_time_parameters_get( (uint8_t *)&report); } -sl_status_t - zwave_command_class_time_parameters_set(const uint8_t *frame_data, - uint16_t frame_length) +sl_status_t zwave_command_class_time_parameters_set(const uint8_t *frame_data, + uint16_t frame_length) { if (frame_length < sizeof(ZW_TIME_PARAMETERS_SET_FRAME)) { return SL_STATUS_FAIL; diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.h b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.h index efe9fdc85..7dc733038 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.h +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_time_parameters.h @@ -46,7 +46,6 @@ sl_status_t zwave_command_class_time_parameters_support_handler( const uint8_t *frame_data, uint16_t frame_length); - /** * @brief Handles time parameters set commands * @@ -55,9 +54,8 @@ sl_status_t zwave_command_class_time_parameters_support_handler( * @returns SL_STATUS_OK on success, any other error code for an error. */ -sl_status_t - zwave_command_class_time_parameters_set(const uint8_t *frame_data, - uint16_t frame_length); +sl_status_t zwave_command_class_time_parameters_set(const uint8_t *frame_data, + uint16_t frame_length); #ifdef __cplusplus } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_user_code.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_user_code.c index dc29d7171..9e3472fd7 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_user_code.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_user_code.c @@ -951,7 +951,9 @@ static void on_delete_all_send_data_complete(attribute_store_node_t node, sl_log_debug(LOG_TAG, "Erasing all user code failed. " "User Code database will be read again."); - undefine_all_user_codes(attribute_store_get_first_parent_with_type(node,ATTRIBUTE_ENDPOINT_ID)); + undefine_all_user_codes( + attribute_store_get_first_parent_with_type(node, + ATTRIBUTE_ENDPOINT_ID)); break; //FRAME_SENT_EVENT_OK_NO_SUPERVISION @@ -1044,9 +1046,9 @@ static sl_status_t return SL_STATUS_OK; } - uint16_t user_id = frame[2]; - uint8_t user_id_status = frame[3]; - attribute_store_node_t data_node = get_user_code_data_node(info); + uint16_t user_id = frame[2]; + uint8_t user_id_status = frame[3]; + attribute_store_node_t data_node = get_user_code_data_node(info); attribute_store_node_t user_id_node = get_user_id_node(data_node, user_id); // Save the user ID Status diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_version.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_version.c index 35c0790ef..715e72a06 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_version.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_version.c @@ -155,8 +155,10 @@ static void zwave_command_class_version_command_class_version_get); attribute_resolver_set_attribute_depth(version_attribute[0], 0); - sl_log_debug(LOG_TAG, "Create CC 0x%02x version attribute for Endpoint ID %d\n", - command_class, endpoint_node); + sl_log_debug(LOG_TAG, + "Create CC 0x%02x version attribute for Endpoint ID %d\n", + command_class, + endpoint_node); // Add it into the attribute store. attribute_store_add_if_missing(endpoint_node, @@ -223,15 +225,15 @@ static void zwave_command_class_version_create_cc_version_attributes( // Prioritize COMMAND_CLASS_MANUFACTURER_SPECIFIC before others // UAM rules can match unique device model, so we could override // supported command class version attributes for matching device model. - if (SL_STATUS_OK == attribute_store_read_value(endpoint_node, - REPORTED_ATTRIBUTE, - &endpoint_id, - sizeof(endpoint_id)) + if (SL_STATUS_OK + == attribute_store_read_value(endpoint_node, + REPORTED_ATTRIBUTE, + &endpoint_id, + sizeof(endpoint_id)) && endpoint_id == 0) { - - if(zwave_node_supports_command_class(COMMAND_CLASS_MANUFACTURER_SPECIFIC, - node_id, - endpoint_id)) { + if (zwave_node_supports_command_class(COMMAND_CLASS_MANUFACTURER_SPECIFIC, + node_id, + endpoint_id)) { add_command_class_version_attributes(COMMAND_CLASS_MANUFACTURER_SPECIFIC, endpoint_node); } diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_utils.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_utils.c index 18db01916..7aab5608f 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_utils.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_classes_utils.c @@ -297,8 +297,7 @@ int32_t command_class_get_int32_value(uint8_t size, return extracted_value; } -int32_t - get_signed_value_from_frame_and_size(const uint8_t *frame, uint8_t size) +int32_t get_signed_value_from_frame_and_size(const uint8_t *frame, uint8_t size) { int32_t extracted_value = get_unsigned_value_from_frame_and_size(frame, size); @@ -327,19 +326,19 @@ int16_t zwave_temperature_to_ucl_temperature(int32_t value, uint8_t scale) { // First convert value with precision of 2 - double coeff = pow(10, (2-precision)); + double coeff = pow(10, (2 - precision)); int32_t ucl_value = value * coeff; - while (ucl_value > INT16_MAX || ucl_value < INT16_MIN ) { - ucl_value /= 10; - sl_log_warning(LOG_TAG, "Reducing precision of temperature value"); + while (ucl_value > INT16_MAX || ucl_value < INT16_MIN) { + ucl_value /= 10; + sl_log_warning(LOG_TAG, "Reducing precision of temperature value"); } // Need to convert to C° if (scale == 1) { double real_value = ucl_value / 100.0; - double f_value = FAHRENHEIT_TO_DEGREES(real_value); - ucl_value = f_value * 100; + double f_value = FAHRENHEIT_TO_DEGREES(real_value); + ucl_value = f_value * 100; } return ucl_value; @@ -354,12 +353,12 @@ int32_t ucl_temperature_to_zwave_temperature(int16_t value, // First Need to convert to C° if (scale == 1) { double real_value = value / 100.0; - double f_value = DEGREES_TO_FAHRENHEIT(real_value); - zwave_value = f_value * 100; + double f_value = DEGREES_TO_FAHRENHEIT(real_value); + zwave_value = f_value * 100; } // Then convert back to our precision - double coeff = pow(10, (precision-2)); + double coeff = pow(10, (precision - 2)); zwave_value *= coeff; return zwave_value; diff --git a/applications/zpc/components/zwave_command_classes/test/helpers/zwave_command_class_test_helper.hpp b/applications/zpc/components/zwave_command_classes/test/helpers/zwave_command_class_test_helper.hpp index 65fb181f1..0501015dc 100644 --- a/applications/zpc/components/zwave_command_classes/test/helpers/zwave_command_class_test_helper.hpp +++ b/applications/zpc/components/zwave_command_classes/test/helpers/zwave_command_class_test_helper.hpp @@ -34,7 +34,7 @@ extern "C" { // Unify #include "zwave_command_handler.h" -// Dirty hack to allow existing cases to use function in zpc_attribute_store_test_helper +// Dirty hack to allow existing cases to use function in zpc_attribute_store_test_helper // namespace without changing the code using namespace zpc_attribute_store_test_helper; @@ -154,8 +154,9 @@ sl_status_t * * @note This class inherits from vector directly. **/ -class zwave_frame : public std::vector { - public: +class zwave_frame : public std::vector +{ + public: zwave_frame() = default; /** * @brief Add a byte to the frame @@ -313,6 +314,4 @@ void helper_test_report_frame(uint8_t command_id, } // extern "C" - - #endif // ZWAVE_COMMAND_CLASS_TEST_HELPER_HPP \ No newline at end of file diff --git a/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.cpp b/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.cpp index 6c7fea9f9..05e957637 100644 --- a/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.cpp +++ b/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.cpp @@ -42,14 +42,12 @@ sl_status_t zwave_resolver_function_helper::register_resolver_functions( std::string message; std::string node_name = attribute_store_get_type_name(node_type); - if (attributes_binding.count(node_type) == 0) - { + if (attributes_binding.count(node_type) == 0) { return SL_STATUS_OK; } auto funcs = attributes_binding.equal_range(node_type); - for (auto &func = funcs.first; func != funcs.second; ++func) - { + for (auto &func = funcs.first; func != funcs.second; ++func) { if (func->second.get_func_id == 0) { message = "GET function should not be defined for " + node_name + ". Did you forget to add it to the binding attribute ?"; @@ -69,7 +67,7 @@ sl_status_t zwave_resolver_function_helper::register_resolver_functions( message = "SET function should be defined for " + node_name + ". Did you forget to remove it to the binding attribute ?"; TEST_ASSERT_NOT_NULL_MESSAGE(set_func, message.c_str()); - resolver_functions[func->second.set_func_id] = set_func; + resolver_functions[func->second.set_func_id] = set_func; } } diff --git a/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.hpp b/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.hpp index f36602391..cfa25c1e9 100644 --- a/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.hpp +++ b/applications/zpc/components/zwave_command_classes/test/helpers/zwave_resolver_function_helper.hpp @@ -64,7 +64,8 @@ struct zwave_functions { * @endcode * */ -using resolver_function_map = std::multimap; +using resolver_function_map + = std::multimap; /** * @brief Helper class to manage resolver functions diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_agi_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_agi_test.cpp index 566ce8cda..0573857c9 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_agi_test.cpp +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_agi_test.cpp @@ -533,9 +533,9 @@ void test_zwave_command_class_agi_handle_group_info_get() { // Test a scenario when List Mode is set to 0 const uint8_t get_frame[] = {COMMAND_CLASS_ASSOCIATION_GRP_INFO, - ASSOCIATION_GROUP_INFO_GET_V3, - 0x00, - LIFELINE_GROUP_ID}; + ASSOCIATION_GROUP_INFO_GET_V3, + 0x00, + LIFELINE_GROUP_ID}; uint8_t expected_report_frame[] = {COMMAND_CLASS_ASSOCIATION_GRP_INFO, ASSOCIATION_GROUP_INFO_REPORT, 0x01, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_alarm_sensor_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_alarm_sensor_test.c index 331c34ff6..b69b7a7a1 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_alarm_sensor_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_alarm_sensor_test.c @@ -411,10 +411,10 @@ void test_zwave_command_class_alarm_sensor_report_smaller_frame() alarm_sensor_type_t type = 25; alarm_sensor_state_t state = 40; uint8_t incoming_frame[] = {COMMAND_CLASS_SENSOR_ALARM, - SENSOR_ALARM_REPORT, - id & 0xFF, - type & 0xFF, - state & 0xFF}; + SENSOR_ALARM_REPORT, + id & 0xFF, + type & 0xFF, + state & 0xFF}; TEST_ASSERT_NOT_NULL(alarm_sensor_handler.control_handler); TEST_ASSERT_EQUAL( diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_barrier_operator_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_barrier_operator_test.c index 5e4768d2b..e4429fa85 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_barrier_operator_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_barrier_operator_test.c @@ -295,8 +295,9 @@ void test_zwave_command_class_barrier_operator_signal_get_happy_case() barrier_operator_signal_get(subsystem_state_node, received_frame, &received_frame_size)); - const uint8_t expected_frame[] - = {COMMAND_CLASS_BARRIER_OPERATOR, BARRIER_OPERATOR_EVENT_SIGNALING_GET, type}; + const uint8_t expected_frame[] = {COMMAND_CLASS_BARRIER_OPERATOR, + BARRIER_OPERATOR_EVENT_SIGNALING_GET, + type}; TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame, received_frame, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_battery_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_battery_test.cpp index bfdfa0c8d..fb727493f 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_battery_test.cpp +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_battery_test.cpp @@ -60,10 +60,9 @@ const zwave_struct_handler_args command_class_handler = {.command_class_id = COMMAND_CLASS_BATTERY, .supported_version = BATTERY_VERSION_V3}; // Get Set function map -const resolver_function_map attribute_bindings = { - {ATTRIBUTE(BATTERY_LEVEL), {BATTERY_GET, 0}}, - {ATTRIBUTE(HEALTH_MAXIMUM_CAPACITY), {BATTERY_HEALTH_GET_V2, 0}} -}; +const resolver_function_map attribute_bindings + = {{ATTRIBUTE(BATTERY_LEVEL), {BATTERY_GET, 0}}, + {ATTRIBUTE(HEALTH_MAXIMUM_CAPACITY), {BATTERY_HEALTH_GET_V2, 0}}}; /// Called before each and every test void setUp() @@ -94,7 +93,6 @@ void helper_test_health_report_attributes(uint8_t expected_max_capacity, // Test cases /////////////////////////////////////////////////////////////////////////////// - void test_battery_interview_v1_happy_case() { helper_set_version(1); @@ -121,7 +119,7 @@ void test_battery_interview_v2_happy_case() ATTRIBUTE(HEALTH_PRECISION), ATTRIBUTE(HEALTH_BATTERY_TEMPERATURE)}; - for (const auto& attribute : tested_attributes) { + for (const auto &attribute: tested_attributes) { helper_test_node_exists(attribute); } } @@ -147,7 +145,7 @@ void test_battery_interview_v3_happy_case() // Added in v3 ATTRIBUTE(LOW_TEMPERATURE)}; - for (const auto& attribute : tested_attributes) { + for (const auto &attribute: tested_attributes) { helper_test_node_exists(attribute); } } @@ -196,8 +194,6 @@ void test_battery_health_report_temperature_size_4_happy_case() -120000); } - - void helper_battery_report(uint8_t expected_battery_level, uint8_t expected_charging_status = 0, uint8_t rechargeable = 0, @@ -233,14 +229,14 @@ void helper_battery_report(uint8_t expected_battery_level, } } -void test_battery_report_version_1_happy_case() { +void test_battery_report_version_1_happy_case() +{ helper_set_version(1); uint8_t expected_battery_level = 0x12; helper_test_report_frame(BATTERY_REPORT, {expected_battery_level}); helper_battery_report(expected_battery_level); - } void test_battery_report_version_2_happy_case() @@ -270,7 +266,6 @@ void test_battery_report_version_3_happy_case() helper_battery_report(expected_battery_level, 1, 1, 0, 1, 0, 1, 0, 1); } - void test_battery_get_happy_case() { helper_test_get_set_frame_happy_case(BATTERY_GET); diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_binary_switch_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_binary_switch_test.cpp index cda2337ba..897e4d0a5 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_binary_switch_test.cpp +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_binary_switch_test.cpp @@ -215,7 +215,8 @@ void test_binary_switch_report_no_node_state() helper_test_report_frame(SWITCH_BINARY_REPORT, {0x12}, SL_STATUS_FAIL); } -void test_binary_switch_report_invalid_value_v1() { +void test_binary_switch_report_invalid_value_v1() +{ helper_set_version(1); auto value_node = helper_get_value_node(); @@ -223,13 +224,16 @@ void test_binary_switch_report_invalid_value_v1() { helper_test_report_frame(SWITCH_BINARY_REPORT, {0xFC}, SL_STATUS_FAIL); // Verify that the value is not updated - TEST_ASSERT_FALSE_MESSAGE(value_node.reported_exists(), - "Value should not be updated (reported) after invalid report"); - TEST_ASSERT_FALSE_MESSAGE(value_node.desired_exists(), - "Value should not be updated (desired) after invalid report"); + TEST_ASSERT_FALSE_MESSAGE( + value_node.reported_exists(), + "Value should not be updated (reported) after invalid report"); + TEST_ASSERT_FALSE_MESSAGE( + value_node.desired_exists(), + "Value should not be updated (desired) after invalid report"); } -void test_binary_switch_report_invalid_value_v2() { +void test_binary_switch_report_invalid_value_v2() +{ helper_set_version(2); auto value_node = helper_get_value_node(); @@ -240,23 +244,25 @@ void test_binary_switch_report_invalid_value_v2() { SL_STATUS_FAIL); // Verify that the value is not updated - TEST_ASSERT_FALSE_MESSAGE(value_node.reported_exists(), - "Value should not be updated (reported) after invalid report"); - TEST_ASSERT_FALSE_MESSAGE(value_node.desired_exists(), - "Value should not be updated (desired) after invalid report"); + TEST_ASSERT_FALSE_MESSAGE( + value_node.reported_exists(), + "Value should not be updated (reported) after invalid report"); + TEST_ASSERT_FALSE_MESSAGE( + value_node.desired_exists(), + "Value should not be updated (desired) after invalid report"); } -void test_binary_switch_report_adjusted_value_v1() { +void test_binary_switch_report_adjusted_value_v1() +{ helper_set_version(1); auto value_node = helper_get_value_node(); // Invalid destination value - helper_test_report_frame(SWITCH_BINARY_REPORT, - {0x12}); + helper_test_report_frame(SWITCH_BINARY_REPORT, {0x12}); // Verify that the value is not updated - // Verify that the duration is updated + // Verify that the duration is updated TEST_ASSERT_EQUAL_MESSAGE(0xFF, value_node.reported(), "Value should be adjusted to 0xFF after report"); @@ -269,8 +275,7 @@ void test_binary_switch_report_adjusted_value_v2() auto value_node = helper_get_value_node(); auto duration_node = helper_get_duration_node(); - helper_test_report_frame(SWITCH_BINARY_REPORT, - {0xFF, 0x12, 0xFF}); + helper_test_report_frame(SWITCH_BINARY_REPORT, {0xFF, 0x12, 0xFF}); // Verify that the value is updated TEST_ASSERT_EQUAL_MESSAGE(0xFF, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_central_scene_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_central_scene_test.c index a0e65a8d7..cb8335329 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_central_scene_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_central_scene_test.c @@ -354,7 +354,7 @@ void test_zwave_command_class_central_scene_frame_too_short() TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, central_scene_handler.control_handler( &connection_info, - incoming_frame, + incoming_frame, sizeof(incoming_frame) - 1 // remove padding )); } @@ -414,12 +414,12 @@ void test_zwave_command_class_central_scene_supported_report_happy_case() const uint8_t properties_1 = (0 << 7) | (1 << 1) | 0; const uint8_t highest_key_attribute = 5; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1, - 1, - 1 << highest_key_attribute}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1, + 1, + 1 << highest_key_attribute}; TEST_ASSERT_EQUAL( SL_STATUS_OK, @@ -446,13 +446,13 @@ void test_zwave_command_class_central_scene_supported_report_not_identical() const uint8_t properties_1 = (1 << 7) | (2 << 1) | 0; const uint8_t highest_key_attribute = 3; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1 << highest_key_attribute, - 1 << highest_key_attribute, - 1 << highest_key_attribute, - 0}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1 << highest_key_attribute, + 1 << highest_key_attribute, + 1 << highest_key_attribute, + 0}; TEST_ASSERT_EQUAL( SL_STATUS_OK, @@ -483,12 +483,12 @@ void test_zwave_command_class_central_scene_supported_report_happy_bitmask_too_s const uint8_t properties_1 = (1 << 7) | (1 << 1) | 0; const uint8_t highest_key_attribute = 3; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1 << highest_key_attribute, - 1 << highest_key_attribute, - 1 << highest_key_attribute}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1 << highest_key_attribute, + 1 << highest_key_attribute, + 1 << highest_key_attribute}; TEST_ASSERT_EQUAL( SL_STATUS_OK, @@ -524,12 +524,12 @@ void test_zwave_command_class_central_scene_supported_report_happy_bitmask_too_s const uint8_t properties_1 = (1 << 7) | (2 << 1) | 0; const uint8_t highest_key_attribute = 3; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1 << highest_key_attribute, - 1 << highest_key_attribute, - 1 << highest_key_attribute}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1 << highest_key_attribute, + 1 << highest_key_attribute, + 1 << highest_key_attribute}; TEST_ASSERT_EQUAL( SL_STATUS_OK, @@ -565,12 +565,12 @@ void test_zwave_command_class_central_scene_supported_report_happy_bitmask_too_s const uint8_t properties_1 = (1 << 7) | (3 << 1) | 0; const uint8_t highest_key_attribute = 3; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1 << highest_key_attribute, - 1 << highest_key_attribute, - 1 << highest_key_attribute}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1 << highest_key_attribute, + 1 << highest_key_attribute, + 1 << highest_key_attribute}; TEST_ASSERT_EQUAL( SL_STATUS_OK, @@ -600,18 +600,18 @@ void test_zwave_command_class_central_scene_supported_report_happy_bitmask_very_ const uint8_t properties_1 = (1 << 7) | (3 << 1) | 0; const uint8_t highest_key_attribute = 5; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1 << 7, - 1 << 7, - 1 << 2, - 1 << 7, - 1 << 7, - 1 << 3, - 1 << 7, - 1 << 7, - 1 << highest_key_attribute}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1 << 7, + 1 << 7, + 1 << 2, + 1 << 7, + 1 << 7, + 1 << 3, + 1 << 7, + 1 << 7, + 1 << highest_key_attribute}; TEST_ASSERT_EQUAL( SL_STATUS_OK, @@ -643,10 +643,10 @@ void test_zwave_command_class_central_scene_supported_report_identical_scenes() const uint8_t properties_1 = (1 << 7) | (1 << 1) | 1; const uint8_t highest_key_attribute = 5; const uint8_t incoming_frame[] = {COMMAND_CLASS_CENTRAL_SCENE_V3, - CENTRAL_SCENE_SUPPORTED_REPORT_V3, - supported_scenes, - properties_1, - 1 << highest_key_attribute}; + CENTRAL_SCENE_SUPPORTED_REPORT_V3, + supported_scenes, + properties_1, + 1 << highest_key_attribute}; TEST_ASSERT_EQUAL( SL_STATUS_OK, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_crc16_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_crc16_test.cpp index 55c349abd..8cab26755 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_crc16_test.cpp +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_crc16_test.cpp @@ -33,11 +33,9 @@ // Test helpers #include "zwave_command_class_test_helper.hpp" - // Attribute macro, shortening those long defines for attribute types: #define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_CRC16_##type - using namespace zwave_command_class_test_helper; extern "C" { @@ -69,8 +67,7 @@ const zwave_struct_handler_args command_class_handler /// Called before each and every test void setUp() { - zwave_setUp(command_class_handler, - &zwave_command_class_crc16_init); + zwave_setUp(command_class_handler, &zwave_command_class_crc16_init); } void helper_set_network_status(NodeStateNetworkStatus status) @@ -99,7 +96,7 @@ void test_attribute_initialized_happy_case() "CRC16 should be marked as supported"); // Set disabled to true - disable_crc16_node.set_reported(0x01); + disable_crc16_node.set_reported(0x01); TEST_ASSERT_EQUAL_MESSAGE( false, @@ -211,4 +208,4 @@ void test_zwave_command_class_crc16_expect_crc16_response_stacked_happy_case() "should be cleared"); } -} // extern "C" +} // extern "C" diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c index 497a08c83..390e24481 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_mode_test.c @@ -165,8 +165,7 @@ void set_current_mode(humidity_control_mode_t humidity_control_mode) "Should be able to set humidity control mode value"); } -void set_supported_modes( - humidity_control_supported_modes_t supported_modes) +void set_supported_modes(humidity_control_supported_modes_t supported_modes) { sl_status_t status = attribute_store_set_child_reported( endpoint_id_node, @@ -215,7 +214,7 @@ void helper_humidity_control_mode_report(zwave_cc_version_t version, default: TEST_ABORT(); } - + set_supported_modes(supported_modes); uint8_t frame[] = {COMMAND_CLASS_HUMIDITY_CONTROL_MODE, @@ -313,7 +312,7 @@ void helper_humidity_control_mode_set(zwave_cc_version_t version, set_supported_modes(supported_modes); set_current_mode(expected_humidity_control_mode); - // Call set + // Call set sl_status_t reported_set_status = current_expected_humidity_control_mode_set(current_mode_node, received_frame, @@ -348,8 +347,8 @@ void helper_humidity_control_mode_set(zwave_cc_version_t version, } set_supported_modes(supported_modes); set_current_mode(expected_humidity_control_mode); - - // Call set + + // Call set reported_set_status = current_expected_humidity_control_mode_set(current_mode_node, received_frame, @@ -358,7 +357,7 @@ void helper_humidity_control_mode_set(zwave_cc_version_t version, } } //////////////////////////////////////////////////////////////////////////// -// Humidity Control Mode Supported +// Humidity Control Mode Supported //////////////////////////////////////////////////////////////////////////// void test_humidity_control_mode_supported_get_happy_case() { @@ -377,7 +376,7 @@ void test_humidity_control_mode_supported_get_happy_case() void test_humidity_control_mode_supported_report_happy_case() { - zwave_controller_connection_info_t info = {}; + zwave_controller_connection_info_t info = {}; info.remote.node_id = node_id; info.remote.endpoint_id = endpoint_id; info.local.is_multicast = false; @@ -402,12 +401,10 @@ void test_humidity_control_mode_supported_report_happy_case() ATTRIBUTE_COMMAND_CLASS_HUMIDITY_CONTROL_MODE_SUPPORTED_MODES, &reported_supported_modes, sizeof(reported_supported_modes)); - TEST_ASSERT_EQUAL(SL_STATUS_OK,reported_status); - TEST_ASSERT_EQUAL(expected_supported_modes,reported_supported_modes); + TEST_ASSERT_EQUAL(SL_STATUS_OK, reported_status); + TEST_ASSERT_EQUAL(expected_supported_modes, reported_supported_modes); } - - //////////////////////////////////////////////////////////////////////////// // Humidity Control Mode Get/Set/Report //////////////////////////////////////////////////////////////////////////// diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp index a3b5f52f0..ba158b4b6 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_humidity_control_setpoint_test.cpp @@ -166,17 +166,17 @@ attribute_store_node_t attribute_store_node_t type_node = create_type_node(type); auto min_value_node = attribute_store_emplace(type_node, - ATTRIBUTE(MIN_VALUE), - &min_value, - sizeof(min_value)); + ATTRIBUTE(MIN_VALUE), + &min_value, + sizeof(min_value)); attribute_store_emplace(min_value_node, ATTRIBUTE(MIN_VALUE_PRECISION), &precision, sizeof(precision)); auto max_value_node = attribute_store_emplace(type_node, - ATTRIBUTE(MAX_VALUE), - &max_value, - sizeof(max_value)); + ATTRIBUTE(MAX_VALUE), + &max_value, + sizeof(max_value)); attribute_store_emplace(max_value_node, ATTRIBUTE(MAX_VALUE_PRECISION), &precision, @@ -311,8 +311,8 @@ void helper_report_setpoint(enum set_bytes bytes_count, bool happy_case) attribute_store_node_t value_node = 0; humidity_control_setpoint_precision_t precision = 0; - humidity_control_setpoint_scale_t scale = 0; - humidity_control_setpoint_value_t value = 0; + humidity_control_setpoint_scale_t scale = 0; + humidity_control_setpoint_value_t value = 0; humidity_control_setpoint_size_t size = bytes_count; diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_inclusion_controller_test.cpp b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_inclusion_controller_test.cpp index d0ac4d4ae..fd338b996 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_inclusion_controller_test.cpp +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_inclusion_controller_test.cpp @@ -352,7 +352,8 @@ void test_zwave_command_class_inclusion_controller_proxy_inclusion_replace() TEST_ASSERT_TRUE( found_node_id.child_by_type(ATTRIBUTE_ENDPOINT_ID).is_valid()); TEST_ASSERT_TRUE( - found_node_id.child_by_type(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS).is_valid()); + found_node_id.child_by_type(DOTDOT_ATTRIBUTE_ID_STATE_NETWORK_STATUS) + .is_valid()); TEST_ASSERT_TRUE(found_node_id.child_by_type(ATTRIBUTE_ENDPOINT_ID) .child_by_type(ATTRIBUTE_ZWAVE_NIF) .is_valid()); diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_indicator_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_indicator_test.c index 779aa687e..7903dbc72 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_indicator_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_indicator_test.c @@ -386,21 +386,21 @@ void test_zwave_command_class_indicator_supported_get_v3(void) void test_zwave_command_class_indicator_default_set(void) { uint8_t cmd_frame_get[] = {COMMAND_CLASS_INDICATOR_V3, - INDICATOR_GET_V3, - INDICATOR_SET_NODE_IDENTIFY_V3}; + INDICATOR_GET_V3, + INDICATOR_SET_NODE_IDENTIFY_V3}; uint8_t cmd_frame_blink[] = {COMMAND_CLASS_INDICATOR_V3, - INDICATOR_SET_V3, - 0x00, - 0x03, - INDICATOR_SET_NODE_IDENTIFY_V3, - INDICATOR_SET_ON_OFF_PERIOD_V3, - 0x0A, - INDICATOR_SET_NODE_IDENTIFY_V3, - INDICATOR_SET_ON_OFF_CYCLES_V3, - 0x02, - INDICATOR_SET_NODE_IDENTIFY_V3, - INDICATOR_SET_ONE_TIME_ON_OFF_PERIOD_V3, - 0x00}; + INDICATOR_SET_V3, + 0x00, + 0x03, + INDICATOR_SET_NODE_IDENTIFY_V3, + INDICATOR_SET_ON_OFF_PERIOD_V3, + 0x0A, + INDICATOR_SET_NODE_IDENTIFY_V3, + INDICATOR_SET_ON_OFF_CYCLES_V3, + 0x02, + INDICATOR_SET_NODE_IDENTIFY_V3, + INDICATOR_SET_ONE_TIME_ON_OFF_PERIOD_V3, + 0x00}; uint8_t exp_frame_get_blink[] = {COMMAND_CLASS_INDICATOR_V3, INDICATOR_REPORT, 0xFF, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_manufacturer_specific_test_zpc_config_mock.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_manufacturer_specific_test_zpc_config_mock.c index 31d4421c6..01bca23f2 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_manufacturer_specific_test_zpc_config_mock.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_manufacturer_specific_test_zpc_config_mock.c @@ -14,9 +14,9 @@ static zpc_config_t my_test_configuration = { .manufacturer_id = 0x1234, - .product_type = 0x5678, - .product_id = 0x9ABC, - .device_id = "DFCE1324576809", + .product_type = 0x5678, + .product_id = 0x9ABC, + .device_id = "DFCE1324576809", }; const zpc_config_t *zpc_get_config() diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_meter_control_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_meter_control_test.c index 3e798758d..6013a5fc2 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_meter_control_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_meter_control_test.c @@ -254,9 +254,9 @@ void test_meter_version_2_supporting_node() void test_meter_supported_get_v1() { // Simulate a version 1 node. - attribute_store_node_t version_node = attribute_store_add_node( - ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_METER), - endpoint_id_node); + attribute_store_node_t version_node + = attribute_store_add_node(ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_METER), + endpoint_id_node); const zwave_cc_version_t version = 1; attribute_store_set_reported(version_node, &version, sizeof(version)); @@ -315,7 +315,6 @@ void test_meter_get_low_scale() const zwave_cc_version_t version = 2; attribute_store_set_reported(version_node, &version, sizeof(version)); - attribute_store_node_t meter_type_node = attribute_store_add_node(ATTRIBUTE(TYPE), endpoint_id_node); const meter_type_t type = 3; @@ -854,16 +853,18 @@ void test_meter_report_too_short() void test_meter_command_class_no_command() { // Simulate a frame - const uint8_t incoming_frame[] = {COMMAND_CLASS_METER, - METER_REPORT_V5, // Add deterministic valid value for overflow check - }; + const uint8_t incoming_frame[] = { + COMMAND_CLASS_METER, + METER_REPORT_V5, // Add deterministic valid value for overflow check + }; TEST_ASSERT_NOT_NULL(meter_handler.control_handler); - TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, - meter_handler.control_handler(&info, - incoming_frame, - sizeof(incoming_frame) -1 // Remove padding - )); + TEST_ASSERT_EQUAL( + SL_STATUS_NOT_SUPPORTED, + meter_handler.control_handler(&info, + incoming_frame, + sizeof(incoming_frame) - 1 // Remove padding + )); } void test_supported_rate_types_unknown_values() diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c index a93f9f2c4..c266af45b 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c @@ -181,52 +181,50 @@ void test_zwave_command_class_multi_channel_capability_get_happy_case() void test_zwave_command_class_multi_channel_endpoint_find_with_flag() { - attribute_store_node_t test_node = 0x9485; + attribute_store_node_t test_node = 0x9485; attribute_store_node_t test_endpoint_node = 0xf7; attribute_store_get_first_parent_with_type_ExpectAndReturn( test_node, ATTRIBUTE_ENDPOINT_ID, test_endpoint_node); - + // Set legacy flag uint8_t legacy_flag = 1; - attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, - ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, - NULL, - sizeof(uint8_t), - SL_STATUS_OK); + attribute_store_get_child_reported_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_OK); attribute_store_get_child_reported_IgnoreArg_value(); attribute_store_get_child_reported_ReturnMemThruPtr_value( &legacy_flag, sizeof(legacy_flag)); - // Simulate not existing parameter uint8_t generic_device_class = 0xFF; - attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, - ATTRIBUTE_ZWAVE_GENERIC_DEVICE_CLASS, - NULL, - sizeof(uint8_t), - SL_STATUS_FAIL); + attribute_store_get_child_reported_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_ZWAVE_GENERIC_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_FAIL); attribute_store_get_child_reported_IgnoreArg_value(); - // Set specific device class uint8_t specific_device_class = 0xEE; - attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, - ATTRIBUTE_ZWAVE_SPECIFIC_DEVICE_CLASS, - NULL, - sizeof(uint8_t), - SL_STATUS_OK); + attribute_store_get_child_reported_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_ZWAVE_SPECIFIC_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_OK); attribute_store_get_child_reported_IgnoreArg_value(); attribute_store_get_child_reported_ReturnMemThruPtr_value( &specific_device_class, sizeof(specific_device_class)); - - - TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_command_class_multi_channel_endpoint_find( test_node, @@ -244,7 +242,7 @@ void test_zwave_command_class_multi_channel_endpoint_find_with_flag() } void test_zwave_command_class_multi_channel_endpoint_find_no_flag() { - attribute_store_node_t test_node = 0x9485; + attribute_store_node_t test_node = 0x9485; attribute_store_node_t test_endpoint_node = 0xf7; attribute_store_get_first_parent_with_type_ExpectAndReturn( @@ -252,12 +250,12 @@ void test_zwave_command_class_multi_channel_endpoint_find_no_flag() ATTRIBUTE_ENDPOINT_ID, test_endpoint_node); - - attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, - ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, - NULL, - sizeof(uint8_t), - SL_STATUS_FAIL); + attribute_store_get_child_reported_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_FAIL); attribute_store_get_child_reported_IgnoreArg_value(); TEST_ASSERT_EQUAL(SL_STATUS_OK, @@ -278,7 +276,7 @@ void test_zwave_command_class_multi_channel_endpoint_find_no_flag() void test_zwave_command_class_multi_channel_endpoint_find_flag_but_off() { - attribute_store_node_t test_node = 0x9485; + attribute_store_node_t test_node = 0x9485; attribute_store_node_t test_endpoint_node = 0xf7; attribute_store_get_first_parent_with_type_ExpectAndReturn( @@ -288,11 +286,12 @@ void test_zwave_command_class_multi_channel_endpoint_find_flag_but_off() // Set legacy flag uint8_t legacy_flag = 0; - attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, - ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, - NULL, - sizeof(uint8_t), - SL_STATUS_OK); + attribute_store_get_child_reported_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_OK); attribute_store_get_child_reported_IgnoreArg_value(); attribute_store_get_child_reported_ReturnMemThruPtr_value( &legacy_flag, @@ -1010,7 +1009,10 @@ void check_if_all_individual_endpoints_are_found_verification( ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_ALL_INDIVIDUAL_ENDPOINTS_FOUND, 0, 23); - attribute_store_set_reported_ExpectAndReturn(23, NULL,sizeof(uint8_t), SL_STATUS_OK); + attribute_store_set_reported_ExpectAndReturn(23, + NULL, + sizeof(uint8_t), + SL_STATUS_OK); attribute_store_set_reported_IgnoreArg_value(); create_aggregated_endpoints_verification(node_id_node); diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_command_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_command_test.c index c1e5abf1e..734176437 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_command_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_command_test.c @@ -201,28 +201,28 @@ void test_decapsulation_not_happy_case() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = { - COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP, - 0x03, // 3 CMDs - 0x04, // Command Length 1 4 bytes - COMMAND_CLASS_DOOR_LOCK, - 0x08, - 0x06, - 0x07, - 0x05, // Command Length 2 5 bytes - COMMAND_CLASS_DOOR_LOCK, - 0x08, - 0x11, - 0xcb, - 0x03, - 0x07, // Command Length 3 7 bytes - COMMAND_CLASS_DOOR_LOCK, - 0x06, - 0x07, - 0xde, - 0x05, - 0x11, - 0xcb, + COMMAND_CLASS_MULTI_CMD, + MULTI_CMD_ENCAP, + 0x03, // 3 CMDs + 0x04, // Command Length 1 4 bytes + COMMAND_CLASS_DOOR_LOCK, + 0x08, + 0x06, + 0x07, + 0x05, // Command Length 2 5 bytes + COMMAND_CLASS_DOOR_LOCK, + 0x08, + 0x11, + 0xcb, + 0x03, + 0x07, // Command Length 3 7 bytes + COMMAND_CLASS_DOOR_LOCK, + 0x06, + 0x07, + 0xde, + 0x05, + 0x11, + 0xcb, }; happy_case = 0; // Command 1, 3 callback should return SL_STATUS_OK @@ -255,12 +255,12 @@ void test_decapsulation_too_long_command() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = {COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP, - 0x01, - 200, // length more than ZWAVE_MAX_FRAME_SIZE - 0x03, - 0x04, - 0x05}; + MULTI_CMD_ENCAP, + 0x01, + 200, // length more than ZWAVE_MAX_FRAME_SIZE + 0x03, + 0x04, + 0x05}; TEST_ASSERT_EQUAL(SL_STATUS_FAIL, multi_command_handler.support_handler(&connection_info, @@ -275,13 +275,13 @@ void test_decapsulation_command_longer_than_frame_1() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = { - COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP, - 0x01, - 154, // length less than ZWAVE_MAX_FRAME_SIZE, but larger than the current frame - 0x03, - 0x04, - 0x05}; + COMMAND_CLASS_MULTI_CMD, + MULTI_CMD_ENCAP, + 0x01, + 154, // length less than ZWAVE_MAX_FRAME_SIZE, but larger than the current frame + 0x03, + 0x04, + 0x05}; TEST_ASSERT_EQUAL(SL_STATUS_FAIL, multi_command_handler.support_handler(&connection_info, @@ -296,18 +296,18 @@ void test_decapsulation_command_longer_than_frame_2() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = {COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP, - 0x02, // 2 CMDs - 4, // Command Length 1 4 bytes - 0x03, - 0x04, - 0x05, - 0x06, - 4, // Command Length 2 4 bytes - 0x01, - 0x02, - 0x03, - 0x04}; + MULTI_CMD_ENCAP, + 0x02, // 2 CMDs + 4, // Command Length 1 4 bytes + 0x03, + 0x04, + 0x05, + 0x06, + 4, // Command Length 2 4 bytes + 0x01, + 0x02, + 0x03, + 0x04}; // Command 2 requires 4 bytes. Lets emulate 12 bytes only frame lenght // instead of 13 TEST_ASSERT_EQUAL( @@ -324,18 +324,18 @@ void test_decapsulation_command_longer_than_frame() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = {COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP, - 0x02, // 2 CMDs - 4, // Command Length 1 4 bytes - 0x03, - 0x04, - 0x05, - 0x06, - 4, // Command Length 2 4 bytes - 0x01, - 0x02, - 0x03, - 0x04}; + MULTI_CMD_ENCAP, + 0x02, // 2 CMDs + 4, // Command Length 1 4 bytes + 0x03, + 0x04, + 0x05, + 0x06, + 4, // Command Length 2 4 bytes + 0x01, + 0x02, + 0x03, + 0x04}; // Command 2 requires 4 bytes. Lets emulate 10 bytes only frame lenght TEST_ASSERT_EQUAL( SL_STATUS_FAIL, @@ -348,12 +348,12 @@ void test_decapsulation_too_wrong_command() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = {COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP + 1, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05}; + MULTI_CMD_ENCAP + 1, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05}; TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, multi_command_handler.support_handler(&connection_info, @@ -386,12 +386,12 @@ void test_decapsulation_too_wrong_command_number() zwave_controller_connection_info_t connection_info = {}; const uint8_t frame_data[] = {COMMAND_CLASS_MULTI_CMD, - MULTI_CMD_ENCAP, - 0x00, // Should be > 0 - 0x02, - 0x03, - 0x04, - 0x05}; + MULTI_CMD_ENCAP, + 0x00, // Should be > 0 + 0x02, + 0x03, + 0x04, + 0x05}; TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, multi_command_handler.support_handler(&connection_info, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_node_info_resolver_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_node_info_resolver_test.c index 0a88d6ff9..75157dc70 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_node_info_resolver_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_node_info_resolver_test.c @@ -41,10 +41,10 @@ #include "zwave_network_management_mock.h" // Static variables -static attribute_resolver_function_t resolve_secure_node_info = NULL; -static attribute_resolver_function_t resolve_node_info = NULL; -static attribute_resolver_callback_t on_nif_resolution_abort = NULL; -static attribute_resolver_callback_t on_secure_nif_resolution_abort = NULL; +static attribute_resolver_function_t resolve_secure_node_info = NULL; +static attribute_resolver_function_t resolve_node_info = NULL; +static attribute_resolver_callback_t on_nif_resolution_abort = NULL; +static attribute_resolver_callback_t on_secure_nif_resolution_abort = NULL; static const zwave_controller_callbacks_t *controller_callbacks = NULL; diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_notification_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_notification_test.c index 12ae2de81..b13a6a50e 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_notification_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_notification_test.c @@ -206,7 +206,7 @@ void test_zwave_command_class_notification_report() attribute_store_node_t notification_mode_node = 0x019; uint8_t notification_version = 0x6; uint8_t notification_mode = 0x0; - uint8_t u8_size = 1; + uint8_t u8_size = 1; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); zwave_unid_from_node_id_ReturnMemThruPtr_unid(test_unid, sizeof(unid_t)); @@ -222,16 +222,14 @@ void test_zwave_command_class_notification_report() endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -239,8 +237,7 @@ void test_zwave_command_class_notification_report() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( endpoint_node, @@ -259,8 +256,10 @@ void test_zwave_command_class_notification_report() ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, notification_version_node); - attribute_store_get_node_type_IgnoreAndReturn(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); - attribute_store_get_type_name_IgnoreAndReturn("ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); + attribute_store_get_node_type_IgnoreAndReturn( + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); + attribute_store_get_type_name_IgnoreAndReturn( + "ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_version_node, REPORTED_ATTRIBUTE, @@ -274,8 +273,7 @@ void test_zwave_command_class_notification_report() sizeof(notification_version)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); uint8_t state = NOTIFICATION_STATE_ACCESS_CONTROL_DOOR_STATE; attribute_store_get_node_child_by_value_ExpectAndReturn( @@ -307,8 +305,7 @@ void test_zwave_command_class_notification_report() sizeof(uint8_t)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); //attribute_store_get_type_name_IgnoreAndReturn("Type"); attribute_store_set_node_attribute_value_ExpectAndReturn( @@ -355,7 +352,7 @@ void test_zwave_command_class_notification_v2_report() attribute_store_node_t notification_mode_node = 0x019; uint8_t notification_version = 0x2; uint8_t notification_mode = 0x0; - uint8_t u8_size = 1; + uint8_t u8_size = 1; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); zwave_unid_from_node_id_ReturnMemThruPtr_unid(test_unid, sizeof(unid_t)); @@ -371,16 +368,14 @@ void test_zwave_command_class_notification_v2_report() endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -388,8 +383,7 @@ void test_zwave_command_class_notification_v2_report() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( endpoint_node, @@ -408,8 +402,10 @@ void test_zwave_command_class_notification_v2_report() ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, notification_version_node); - attribute_store_get_node_type_IgnoreAndReturn(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); - attribute_store_get_type_name_IgnoreAndReturn("ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); + attribute_store_get_node_type_IgnoreAndReturn( + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); + attribute_store_get_type_name_IgnoreAndReturn( + "ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_version_node, REPORTED_ATTRIBUTE, @@ -423,8 +419,7 @@ void test_zwave_command_class_notification_v2_report() sizeof(notification_version)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_type_ExpectAndReturn( notification_status_node, @@ -452,8 +447,7 @@ void test_zwave_command_class_notification_v2_report() sizeof(uint8_t)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); //attribute_store_get_type_name_IgnoreAndReturn("Type"); attribute_store_set_node_attribute_value_ExpectAndReturn( @@ -492,7 +486,7 @@ void test_zwave_command_class_notification_report_v1_alarm_type() static attribute_store_node_t v1_alarm_level_node_test = 0x03; attribute_store_node_t notification_mode_node = 0x019; uint8_t notification_mode = 0x0; - uint8_t u8_size = 1; + uint8_t u8_size = 1; test_connection_info.remote.node_id = 0x01; test_connection_info.remote.endpoint_id = 0x00; @@ -504,21 +498,19 @@ void test_zwave_command_class_notification_report_v1_alarm_type() test_unid_alarm, test_connection_info.remote.endpoint_id, endpoint_node_test); - - attribute_store_get_node_child_by_type_ExpectAndReturn( + + attribute_store_get_node_child_by_type_ExpectAndReturn( endpoint_node_test, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -526,8 +518,7 @@ void test_zwave_command_class_notification_report_v1_alarm_type() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( endpoint_node_test, @@ -595,7 +586,7 @@ void test_zwave_command_class_notification_report_idle_param() attribute_store_node_t notification_mode_node = 0x019; uint8_t notification_version = 0x6; uint8_t notification_mode = 0x0; - uint8_t u8_size = 1; + uint8_t u8_size = 1; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); zwave_unid_from_node_id_ReturnMemThruPtr_unid(test_unid, sizeof(unid_t)); @@ -605,20 +596,18 @@ void test_zwave_command_class_notification_report_idle_param() test_connection_info.remote.endpoint_id, endpoint_node); - attribute_store_get_node_child_by_type_ExpectAndReturn( + attribute_store_get_node_child_by_type_ExpectAndReturn( endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -626,8 +615,7 @@ void test_zwave_command_class_notification_report_idle_param() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( endpoint_node, @@ -649,8 +637,10 @@ void test_zwave_command_class_notification_report_idle_param() ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, notification_version_node); - attribute_store_get_node_type_IgnoreAndReturn(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); - attribute_store_get_type_name_IgnoreAndReturn("ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); + attribute_store_get_node_type_IgnoreAndReturn( + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); + attribute_store_get_type_name_IgnoreAndReturn( + "ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_version_node, REPORTED_ATTRIBUTE, @@ -664,8 +654,7 @@ void test_zwave_command_class_notification_report_idle_param() sizeof(notification_version)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( notification_status_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_STATE, @@ -694,8 +683,7 @@ void test_zwave_command_class_notification_report_idle_param() sizeof(uint8_t)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_set_node_attribute_value_ExpectAndReturn( notification_event_node, @@ -740,7 +728,7 @@ void test_zwave_command_class_notification_report_idle_no_param() attribute_store_node_t notification_mode_node = 0x019; uint8_t notification_version = 0x6; uint8_t notification_mode = 0x0; - uint8_t u8_size = 1; + uint8_t u8_size = 1; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); zwave_unid_from_node_id_ReturnMemThruPtr_unid(test_unid, sizeof(unid_t)); @@ -750,20 +738,18 @@ void test_zwave_command_class_notification_report_idle_no_param() test_connection_info.remote.endpoint_id, endpoint_node); - attribute_store_get_node_child_by_type_ExpectAndReturn( + attribute_store_get_node_child_by_type_ExpectAndReturn( endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -771,8 +757,7 @@ void test_zwave_command_class_notification_report_idle_no_param() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( endpoint_node, @@ -803,8 +788,10 @@ void test_zwave_command_class_notification_report_idle_no_param() ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, notification_version_node); - attribute_store_get_node_type_IgnoreAndReturn(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); - attribute_store_get_type_name_IgnoreAndReturn("ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); + attribute_store_get_node_type_IgnoreAndReturn( + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); + attribute_store_get_type_name_IgnoreAndReturn( + "ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_version_node, REPORTED_ATTRIBUTE, @@ -818,8 +805,7 @@ void test_zwave_command_class_notification_report_idle_no_param() sizeof(notification_version)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_value_ExpectAndReturn( notification_status_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_STATE, @@ -848,8 +834,7 @@ void test_zwave_command_class_notification_report_idle_no_param() sizeof(uint8_t)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_set_node_attribute_value_ExpectAndReturn( notification_event_node, @@ -979,8 +964,7 @@ void helper_test_zwave_command_class_supported_notification_types_report( ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_SUPPORTED_STATES_OR_EVENTS, notification_type_node, ATTRIBUTE_STORE_INVALID_NODE); - } - else if (version > 1) { + } else if (version > 1) { attribute_store_add_node_ExpectAndReturn( ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_STATE, notification_type_node, @@ -1021,11 +1005,12 @@ void test_zwave_command_class_supported_notification_types_report() void helper_test_discover_agi(bool agi_support) { - attribute_store_node_t test_parent_node = 0xde9e; + attribute_store_node_t test_parent_node = 0xde9e; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); - zwave_unid_from_node_id_ReturnMemThruPtr_unid(supporting_node_unid, sizeof(unid_t)); + zwave_unid_from_node_id_ReturnMemThruPtr_unid(supporting_node_unid, + sizeof(unid_t)); attribute_store_network_helper_get_endpoint_node_ExpectAndReturn( supporting_node_unid, test_connection_info.remote.endpoint_id, @@ -1033,12 +1018,13 @@ void helper_test_discover_agi(bool agi_support) zwave_node_supports_command_class_ExpectAndReturn( COMMAND_CLASS_ASSOCIATION, test_connection_info.remote.node_id, - test_connection_info.remote.endpoint_id, agi_support); + test_connection_info.remote.endpoint_id, + agi_support); zwave_node_supports_command_class_ExpectAndReturn( COMMAND_CLASS_ASSOCIATION_GRP_INFO, test_connection_info.remote.node_id, - test_connection_info.remote.endpoint_id, agi_support); - + test_connection_info.remote.endpoint_id, + agi_support); } // This also test zwave_command_class_notification_types_attribute_update() void test_zwave_command_class_notification_on_version_attribute_update_happy_case() @@ -1103,8 +1089,7 @@ void test_zwave_command_class_notification_on_version_attribute_update_happy_cas attribute_store_add_node_ExpectAndReturn( ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, test_parent_node, - test_notification_mode_node - ); + test_notification_mode_node); helper_test_discover_agi(false); attribute_store_get_node_child_by_type_ExpectAndReturn( test_parent_node, @@ -1118,7 +1103,11 @@ void test_zwave_command_class_notification_on_version_attribute_update_happy_cas &mode_value, sizeof(uint8_t), SL_STATUS_OK); - attribute_store_get_node_child_by_type_ExpectAndReturn(test_parent_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, 0, 0); + attribute_store_get_node_child_by_type_ExpectAndReturn( + test_parent_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, + 0, + 0); attribute_store_node_exists_ExpectAndReturn(0, false); attribute_store_add_node_ExpectAndReturn( ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, @@ -1220,7 +1209,7 @@ void test_zwave_command_class_notification_on_version_attribute_update_v1() test_connection_info.remote.endpoint_id, 1); - // Then find out the parent node: + // Then find out the parent node: attribute_store_get_node_parent_ExpectAndReturn(test_updated_node, test_parent_node); attribute_store_get_node_child_by_type_ExpectAndReturn( @@ -1231,8 +1220,7 @@ void test_zwave_command_class_notification_on_version_attribute_update_v1() attribute_store_add_node_ExpectAndReturn( ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, test_parent_node, - test_notification_mode_node - ); + test_notification_mode_node); helper_test_discover_agi(false); attribute_store_get_node_child_by_type_ExpectAndReturn( test_parent_node, @@ -1708,30 +1696,37 @@ void test_zwave_command_class_support_notification_supported_state_event_types_r void helper_test_agi_test(bool support_push) { - attribute_store_node_t ep_node = 0xde9e; + attribute_store_node_t ep_node = 0xde9e; attribute_store_node_t groups_supp_node = 0xbcdb; - attribute_store_node_t mode_node = 0xbcdc; - attribute_store_node_t group_node = 0xbcdd; - attribute_store_node_t cmd_list_node = 0xbcde; - attribute_store_node_t probe_node = 0xbcdf; - static uint32_t group_count = 1; - static uint8_t group_id = 1; - static uint8_t u32_size = 4; - static uint8_t u8_size = 1; - static uint8_t mode = 0; - static uint8_t push_cmd_list[] = {COMMAND_CLASS_NOTIFICATION_V8, NOTIFICATION_REPORT_V3}; + attribute_store_node_t mode_node = 0xbcdc; + attribute_store_node_t group_node = 0xbcdd; + attribute_store_node_t cmd_list_node = 0xbcde; + attribute_store_node_t probe_node = 0xbcdf; + static uint32_t group_count = 1; + static uint8_t group_id = 1; + static uint8_t u32_size = 4; + static uint8_t u8_size = 1; + static uint8_t mode = 0; + static uint8_t push_cmd_list[] + = {COMMAND_CLASS_NOTIFICATION_V8, NOTIFICATION_REPORT_V3}; static uint8_t cmd_list_size = 2; - mode = !support_push; + mode = !support_push; - attribute_store_get_first_parent_with_type_ExpectAndReturn(groups_supp_node, ATTRIBUTE_ENDPOINT_ID, ep_node); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, 0, groups_supp_node); - attribute_store_get_node_attribute_value_ExpectAndReturn( + attribute_store_get_first_parent_with_type_ExpectAndReturn( groups_supp_node, - REPORTED_ATTRIBUTE, - NULL, - NULL, - SL_STATUS_OK); + ATTRIBUTE_ENDPOINT_ID, + ep_node); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, + 0, + groups_supp_node); + attribute_store_get_node_attribute_value_ExpectAndReturn(groups_supp_node, + REPORTED_ATTRIBUTE, + NULL, + NULL, + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -1739,21 +1734,27 @@ void helper_test_agi_test(bool support_push) sizeof(group_count)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u32_size, - sizeof(uint8_t) - ); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, mode_node); + sizeof(uint8_t)); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, + 0, + mode_node); attribute_store_get_node_child_count_ExpectAndReturn(ep_node, 1); attribute_store_get_node_child_ExpectAndReturn(ep_node, 0, group_node); - attribute_store_get_node_type_ExpectAndReturn(group_node, ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_GROUP_ID); + attribute_store_get_node_type_ExpectAndReturn( + group_node, + ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_GROUP_ID); attribute_store_get_node_child_ExpectAndReturn(ep_node, 0, group_node); attribute_store_get_node_child_count_ExpectAndReturn(ep_node, 1); - attribute_store_is_value_defined_ExpectAndReturn(group_node, REPORTED_ATTRIBUTE, true); - attribute_store_get_node_attribute_value_ExpectAndReturn( - group_node, - REPORTED_ATTRIBUTE, - NULL, - NULL, - SL_STATUS_OK); + attribute_store_is_value_defined_ExpectAndReturn(group_node, + REPORTED_ATTRIBUTE, + true); + attribute_store_get_node_attribute_value_ExpectAndReturn(group_node, + REPORTED_ATTRIBUTE, + NULL, + NULL, + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -1761,19 +1762,25 @@ void helper_test_agi_test(bool support_push) sizeof(group_id)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_node_exists_ExpectAndReturn(group_node, true); - attribute_store_is_value_defined_ExpectAndReturn(group_node, REPORTED_ATTRIBUTE, true); - attribute_store_get_node_child_by_type_ExpectAndReturn(group_node, ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_GROUP_COMMAND_LIST, 0, cmd_list_node); + attribute_store_is_value_defined_ExpectAndReturn(group_node, + REPORTED_ATTRIBUTE, + true); + attribute_store_get_node_child_by_type_ExpectAndReturn( + group_node, + ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_GROUP_COMMAND_LIST, + 0, + cmd_list_node); attribute_store_node_exists_ExpectAndReturn(cmd_list_node, true); - attribute_store_is_value_defined_ExpectAndReturn(cmd_list_node, REPORTED_ATTRIBUTE, true); - attribute_store_get_node_attribute_value_ExpectAndReturn( - cmd_list_node, - REPORTED_ATTRIBUTE, - NULL, - NULL, - SL_STATUS_OK); + attribute_store_is_value_defined_ExpectAndReturn(cmd_list_node, + REPORTED_ATTRIBUTE, + true); + attribute_store_get_node_attribute_value_ExpectAndReturn(cmd_list_node, + REPORTED_ATTRIBUTE, + NULL, + NULL, + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -1781,10 +1788,17 @@ void helper_test_agi_test(bool support_push) sizeof(push_cmd_list)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &cmd_list_size, - sizeof(uint8_t) - ); - is_command_in_array_ExpectAndReturn(COMMAND_CLASS_NOTIFICATION_V8, NOTIFICATION_REPORT_V3, push_cmd_list, cmd_list_size, support_push); - attribute_store_set_node_attribute_value_ExpectAndReturn(mode_node, REPORTED_ATTRIBUTE, &mode, sizeof(uint8_t), SL_STATUS_OK); + sizeof(uint8_t)); + is_command_in_array_ExpectAndReturn(COMMAND_CLASS_NOTIFICATION_V8, + NOTIFICATION_REPORT_V3, + push_cmd_list, + cmd_list_size, + support_push); + attribute_store_set_node_attribute_value_ExpectAndReturn(mode_node, + REPORTED_ATTRIBUTE, + &mode, + sizeof(uint8_t), + SL_STATUS_OK); if (!support_push) { attribute_store_get_node_child_by_type_ExpectAndReturn( ep_node, @@ -1799,68 +1813,97 @@ void helper_test_agi_test(bool support_push) } attribute_resolver_clear_resolution_listener_Expect(groups_supp_node, NULL); - attribute_resolver_clear_resolution_listener_IgnoreArg_callback(); + attribute_resolver_clear_resolution_listener_IgnoreArg_callback(); } void test_zwave_command_class_notification_pull_push_discovery_agi_ready_detect_push() { - attribute_store_node_t ep_node = 0xde9e; + attribute_store_node_t ep_node = 0xde9e; attribute_store_node_t groups_supp_node = 0xbcdb; helper_test_discover_agi(true); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, 0, groups_supp_node); - attribute_store_is_value_defined_ExpectAndReturn(groups_supp_node, REPORTED_ATTRIBUTE, true); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, + 0, + groups_supp_node); + attribute_store_is_value_defined_ExpectAndReturn(groups_supp_node, + REPORTED_ATTRIBUTE, + true); helper_test_agi_test(true); - zwave_command_class_notification_pull_push_discovery(test_connection_info.remote.node_id, test_connection_info.remote.endpoint_id); + zwave_command_class_notification_pull_push_discovery( + test_connection_info.remote.node_id, + test_connection_info.remote.endpoint_id); } void test_zwave_command_class_notification_pull_push_discovery_agi_ready_detect_pull() { - attribute_store_node_t ep_node = 0xde9e; + attribute_store_node_t ep_node = 0xde9e; attribute_store_node_t groups_supp_node = 0xbcdb; helper_test_discover_agi(true); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, 0, groups_supp_node); - attribute_store_is_value_defined_ExpectAndReturn(groups_supp_node, REPORTED_ATTRIBUTE, true); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, + 0, + groups_supp_node); + attribute_store_is_value_defined_ExpectAndReturn(groups_supp_node, + REPORTED_ATTRIBUTE, + true); helper_test_agi_test(false); - zwave_command_class_notification_pull_push_discovery(test_connection_info.remote.node_id, test_connection_info.remote.endpoint_id); + zwave_command_class_notification_pull_push_discovery( + test_connection_info.remote.node_id, + test_connection_info.remote.endpoint_id); } void test_zwave_command_class_notification_pull_push_discovery_agi_not_ready() { - attribute_store_node_t ep_node = 0xde9e; + attribute_store_node_t ep_node = 0xde9e; attribute_store_node_t groups_supp_node = 0xbcdb; helper_test_discover_agi(true); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, 0, groups_supp_node); - attribute_store_is_value_defined_ExpectAndReturn(groups_supp_node, REPORTED_ATTRIBUTE, false); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_ASSOCIATION_SUPPORTED_GROUPINGS, + 0, + groups_supp_node); + attribute_store_is_value_defined_ExpectAndReturn(groups_supp_node, + REPORTED_ATTRIBUTE, + false); attribute_resolver_set_resolution_listener_Expect(groups_supp_node, NULL); attribute_resolver_set_resolution_listener_IgnoreArg_callback(); - zwave_command_class_notification_pull_push_discovery(test_connection_info.remote.node_id, test_connection_info.remote.endpoint_id); + zwave_command_class_notification_pull_push_discovery( + test_connection_info.remote.node_id, + test_connection_info.remote.endpoint_id); } void test_zwave_command_class_notification_probe_happy_case() { - attribute_store_node_t ep_node = 0xde9e; - attribute_store_node_t mode_node = 0xbcda; + attribute_store_node_t ep_node = 0xde9e; + attribute_store_node_t mode_node = 0xbcda; attribute_store_node_t probe_node = 0xbcdb; - uint8_t notification_mode = 0x1; - uint8_t u8_size = 1; - uint16_t frame_size = 0; + uint8_t notification_mode = 0x1; + uint8_t u8_size = 1; + uint16_t frame_size = 0; uint8_t frame_data[10]; - attribute_store_get_first_parent_with_type_ExpectAndReturn(probe_node, ATTRIBUTE_ENDPOINT_ID, ep_node); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, mode_node); - attribute_store_get_node_attribute_value_ExpectAndReturn( - mode_node, - REPORTED_ATTRIBUTE, - NULL, - NULL, - SL_STATUS_OK - ); + attribute_store_get_first_parent_with_type_ExpectAndReturn( + probe_node, + ATTRIBUTE_ENDPOINT_ID, + ep_node); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, + 0, + mode_node); + attribute_store_get_node_attribute_value_ExpectAndReturn(mode_node, + REPORTED_ATTRIBUTE, + NULL, + NULL, + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -1868,9 +1911,9 @@ void test_zwave_command_class_notification_probe_happy_case() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); - TEST_ASSERT_EQUAL(SL_STATUS_OK, probe_get_callback(probe_node, frame_data, &frame_size)); + sizeof(uint8_t)); + TEST_ASSERT_EQUAL(SL_STATUS_OK, + probe_get_callback(probe_node, frame_data, &frame_size)); TEST_ASSERT_EQUAL(5, frame_size); TEST_ASSERT_EQUAL(COMMAND_CLASS_NOTIFICATION_V8, frame_data[0]); TEST_ASSERT_EQUAL(NOTIFICATION_GET_V8, frame_data[1]); @@ -1881,23 +1924,28 @@ void test_zwave_command_class_notification_probe_happy_case() void test_zwave_command_class_notification_probe_pull_check_fail() { - attribute_store_node_t ep_node = 0xde9e; - attribute_store_node_t mode_node = 0xbcda; + attribute_store_node_t ep_node = 0xde9e; + attribute_store_node_t mode_node = 0xbcda; attribute_store_node_t probe_node = 0xbcdb; - uint8_t notification_mode = 0x0; - uint8_t u8_size = 1; - uint16_t frame_size = 0; + uint8_t notification_mode = 0x0; + uint8_t u8_size = 1; + uint16_t frame_size = 0; uint8_t frame_data[10]; - attribute_store_get_first_parent_with_type_ExpectAndReturn(probe_node, ATTRIBUTE_ENDPOINT_ID, ep_node); - attribute_store_get_node_child_by_type_ExpectAndReturn(ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, mode_node); - attribute_store_get_node_attribute_value_ExpectAndReturn( - mode_node, - REPORTED_ATTRIBUTE, - NULL, - NULL, - SL_STATUS_OK - ); + attribute_store_get_first_parent_with_type_ExpectAndReturn( + probe_node, + ATTRIBUTE_ENDPOINT_ID, + ep_node); + attribute_store_get_node_child_by_type_ExpectAndReturn( + ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, + 0, + mode_node); + attribute_store_get_node_attribute_value_ExpectAndReturn(mode_node, + REPORTED_ATTRIBUTE, + NULL, + NULL, + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -1905,77 +1953,118 @@ void test_zwave_command_class_notification_probe_pull_check_fail() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); - TEST_ASSERT_NOT_EQUAL(SL_STATUS_OK, probe_get_callback(probe_node, frame_data, &frame_size)); + sizeof(uint8_t)); + TEST_ASSERT_NOT_EQUAL( + SL_STATUS_OK, + probe_get_callback(probe_node, frame_data, &frame_size)); TEST_ASSERT_EQUAL(0, frame_size); } void test_zwave_command_class_notification_trigger_probe() { - attribute_store_node_t network_node = 0x1230; - attribute_store_node_t end_device_node1 = 0x1231; - attribute_store_node_t end_device_node2 = 0x1232; - attribute_store_node_t end_device_node3 = 0x1233; - attribute_store_node_t end_device1_ep_node = 0x1234; - attribute_store_node_t end_device2_ep_node = 0x1235; - attribute_store_node_t end_device3_ep_node = 0x1236; - attribute_store_node_t end_device1_ver_node = ATTRIBUTE_STORE_INVALID_NODE; - attribute_store_node_t end_device2_ver_node = 0x1237; - attribute_store_node_t end_device3_ver_node = 0x1238; - attribute_store_node_t end_device2_mode_node = 0x1239; - attribute_store_node_t end_device3_mode_node = 0x123A; + attribute_store_node_t network_node = 0x1230; + attribute_store_node_t end_device_node1 = 0x1231; + attribute_store_node_t end_device_node2 = 0x1232; + attribute_store_node_t end_device_node3 = 0x1233; + attribute_store_node_t end_device1_ep_node = 0x1234; + attribute_store_node_t end_device2_ep_node = 0x1235; + attribute_store_node_t end_device3_ep_node = 0x1236; + attribute_store_node_t end_device1_ver_node = ATTRIBUTE_STORE_INVALID_NODE; + attribute_store_node_t end_device2_ver_node = 0x1237; + attribute_store_node_t end_device3_ver_node = 0x1238; + attribute_store_node_t end_device2_mode_node = 0x1239; + attribute_store_node_t end_device3_mode_node = 0x123A; attribute_store_node_t end_device3_probe_node = 0x123B; - uint8_t push_mode = 0x00; - uint8_t pull_mode = 0x01; - uint8_t probe_active = 0x01; - uint8_t u8_size = 1; + uint8_t push_mode = 0x00; + uint8_t pull_mode = 0x01; + uint8_t probe_active = 0x01; + uint8_t u8_size = 1; get_zpc_network_node_ExpectAndReturn(network_node); attribute_store_get_node_child_count_ExpectAndReturn(network_node, 3); - attribute_store_get_node_child_ExpectAndReturn(network_node, 0, end_device_node1); - attribute_store_get_node_type_ExpectAndReturn(end_device_node1, ATTRIBUTE_NODE_ID); - attribute_store_get_node_child_ExpectAndReturn(network_node, 0, end_device_node1); + attribute_store_get_node_child_ExpectAndReturn(network_node, + 0, + end_device_node1); + attribute_store_get_node_type_ExpectAndReturn(end_device_node1, + ATTRIBUTE_NODE_ID); + attribute_store_get_node_child_ExpectAndReturn(network_node, + 0, + end_device_node1); attribute_store_get_node_child_count_ExpectAndReturn(network_node, 3); - attribute_store_get_node_child_ExpectAndReturn(network_node, 1, end_device_node2); - attribute_store_get_node_type_ExpectAndReturn(end_device_node2, ATTRIBUTE_NODE_ID); - attribute_store_get_node_child_ExpectAndReturn(network_node, 1, end_device_node2); + attribute_store_get_node_child_ExpectAndReturn(network_node, + 1, + end_device_node2); + attribute_store_get_node_type_ExpectAndReturn(end_device_node2, + ATTRIBUTE_NODE_ID); + attribute_store_get_node_child_ExpectAndReturn(network_node, + 1, + end_device_node2); attribute_store_get_node_child_count_ExpectAndReturn(network_node, 3); - attribute_store_get_node_child_ExpectAndReturn(network_node, 2, end_device_node3); - attribute_store_get_node_type_ExpectAndReturn(end_device_node3, ATTRIBUTE_NODE_ID); - attribute_store_get_node_child_ExpectAndReturn(network_node, 2, end_device_node3); + attribute_store_get_node_child_ExpectAndReturn(network_node, + 2, + end_device_node3); + attribute_store_get_node_type_ExpectAndReturn(end_device_node3, + ATTRIBUTE_NODE_ID); + attribute_store_get_node_child_ExpectAndReturn(network_node, + 2, + end_device_node3); attribute_store_get_node_child_count_ExpectAndReturn(network_node, 3); // end device 1 : emulate node without Notification CC] attribute_store_get_node_child_count_ExpectAndReturn(end_device_node1, 1); - attribute_store_get_node_child_ExpectAndReturn(end_device_node1, 0, end_device1_ep_node); - attribute_store_get_node_type_ExpectAndReturn(end_device1_ep_node, ATTRIBUTE_ENDPOINT_ID); - attribute_store_get_node_child_ExpectAndReturn(end_device_node1, 0, end_device1_ep_node); + attribute_store_get_node_child_ExpectAndReturn(end_device_node1, + 0, + end_device1_ep_node); + attribute_store_get_node_type_ExpectAndReturn(end_device1_ep_node, + ATTRIBUTE_ENDPOINT_ID); + attribute_store_get_node_child_ExpectAndReturn(end_device_node1, + 0, + end_device1_ep_node); attribute_store_get_node_child_count_ExpectAndReturn(end_device_node1, 1); - attribute_store_get_node_child_by_type_ExpectAndReturn(end_device1_ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, end_device1_ver_node); + attribute_store_get_node_child_by_type_ExpectAndReturn( + end_device1_ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, + 0, + end_device1_ver_node); attribute_store_node_exists_ExpectAndReturn(end_device1_ver_node, false); // end device 2 : emulate Push node attribute_store_get_node_child_count_ExpectAndReturn(end_device_node2, 1); - attribute_store_get_node_child_ExpectAndReturn(end_device_node2, 0, end_device2_ep_node); - attribute_store_get_node_type_ExpectAndReturn(end_device2_ep_node, ATTRIBUTE_ENDPOINT_ID); - attribute_store_get_node_child_ExpectAndReturn(end_device_node2, 0, end_device2_ep_node); + attribute_store_get_node_child_ExpectAndReturn(end_device_node2, + 0, + end_device2_ep_node); + attribute_store_get_node_type_ExpectAndReturn(end_device2_ep_node, + ATTRIBUTE_ENDPOINT_ID); + attribute_store_get_node_child_ExpectAndReturn(end_device_node2, + 0, + end_device2_ep_node); attribute_store_get_node_child_count_ExpectAndReturn(end_device_node2, 1); - attribute_store_get_node_child_by_type_ExpectAndReturn(end_device2_ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, end_device2_ver_node); + attribute_store_get_node_child_by_type_ExpectAndReturn( + end_device2_ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, + 0, + end_device2_ver_node); attribute_store_node_exists_ExpectAndReturn(end_device2_ver_node, true); attribute_store_get_node_child_count_ExpectAndReturn(end_device2_ep_node, 1); - attribute_store_get_node_child_ExpectAndReturn(end_device2_ep_node, 0, end_device2_mode_node); - attribute_store_get_node_type_ExpectAndReturn(end_device2_mode_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE); - attribute_store_get_node_child_ExpectAndReturn(end_device2_ep_node, 0, end_device2_mode_node); + attribute_store_get_node_child_ExpectAndReturn(end_device2_ep_node, + 0, + end_device2_mode_node); + attribute_store_get_node_type_ExpectAndReturn( + end_device2_mode_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE); + attribute_store_get_node_child_ExpectAndReturn(end_device2_ep_node, + 0, + end_device2_mode_node); attribute_store_get_node_child_count_ExpectAndReturn(end_device2_ep_node, 1); - attribute_store_is_value_defined_ExpectAndReturn(end_device2_mode_node, REPORTED_ATTRIBUTE, true); + attribute_store_is_value_defined_ExpectAndReturn(end_device2_mode_node, + REPORTED_ATTRIBUTE, + true); attribute_store_get_node_attribute_value_ExpectAndReturn( end_device2_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -1983,30 +2072,45 @@ void test_zwave_command_class_notification_trigger_probe() sizeof(push_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); // end device 3 : emulate pull node attribute_store_get_node_child_count_ExpectAndReturn(end_device_node3, 1); - attribute_store_get_node_child_ExpectAndReturn(end_device_node3, 0, end_device3_ep_node); - attribute_store_get_node_type_ExpectAndReturn(end_device3_ep_node, ATTRIBUTE_ENDPOINT_ID); - attribute_store_get_node_child_ExpectAndReturn(end_device_node3, 0, end_device3_ep_node); + attribute_store_get_node_child_ExpectAndReturn(end_device_node3, + 0, + end_device3_ep_node); + attribute_store_get_node_type_ExpectAndReturn(end_device3_ep_node, + ATTRIBUTE_ENDPOINT_ID); + attribute_store_get_node_child_ExpectAndReturn(end_device_node3, + 0, + end_device3_ep_node); attribute_store_get_node_child_count_ExpectAndReturn(end_device_node3, 1); - attribute_store_get_node_child_by_type_ExpectAndReturn(end_device3_ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, end_device3_ver_node); + attribute_store_get_node_child_by_type_ExpectAndReturn( + end_device3_ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, + 0, + end_device3_ver_node); attribute_store_node_exists_ExpectAndReturn(end_device3_ver_node, true); attribute_store_get_node_child_count_ExpectAndReturn(end_device3_ep_node, 1); - attribute_store_get_node_child_ExpectAndReturn(end_device3_ep_node, 0, end_device3_mode_node); - attribute_store_get_node_type_ExpectAndReturn(end_device3_mode_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE); - attribute_store_get_node_child_ExpectAndReturn(end_device3_ep_node, 0, end_device3_mode_node); + attribute_store_get_node_child_ExpectAndReturn(end_device3_ep_node, + 0, + end_device3_mode_node); + attribute_store_get_node_type_ExpectAndReturn( + end_device3_mode_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE); + attribute_store_get_node_child_ExpectAndReturn(end_device3_ep_node, + 0, + end_device3_mode_node); attribute_store_get_node_child_count_ExpectAndReturn(end_device3_ep_node, 1); - attribute_store_is_value_defined_ExpectAndReturn(end_device3_mode_node, REPORTED_ATTRIBUTE, true); + attribute_store_is_value_defined_ExpectAndReturn(end_device3_mode_node, + REPORTED_ATTRIBUTE, + true); attribute_store_get_node_attribute_value_ExpectAndReturn( end_device3_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -2014,11 +2118,24 @@ void test_zwave_command_class_notification_trigger_probe() sizeof(pull_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); - attribute_store_get_node_child_by_type_ExpectAndReturn(end_device3_ep_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, 0, end_device3_probe_node); - attribute_store_set_node_attribute_value_ExpectAndReturn(end_device3_probe_node, REPORTED_ATTRIBUTE, &probe_active, 1, SL_STATUS_OK); - attribute_store_set_node_attribute_value_ExpectAndReturn(end_device3_probe_node, REPORTED_ATTRIBUTE, 0, 0, SL_STATUS_OK); + sizeof(uint8_t)); + attribute_store_get_node_child_by_type_ExpectAndReturn( + end_device3_ep_node, + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, + 0, + end_device3_probe_node); + attribute_store_set_node_attribute_value_ExpectAndReturn( + end_device3_probe_node, + REPORTED_ATTRIBUTE, + &probe_active, + 1, + SL_STATUS_OK); + attribute_store_set_node_attribute_value_ExpectAndReturn( + end_device3_probe_node, + REPORTED_ATTRIBUTE, + 0, + 0, + SL_STATUS_OK); //zwave_command_class_notification_trigger_probe(); contiki_test_helper_run(10800000); @@ -2029,13 +2146,13 @@ void test_zwave_command_class_notification_pull_mode_empty_queue_report() // Test a report for Home Security notification type uint8_t test_frame_data_2[] = {0x71, 0x05, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00}; - unid_t test_unid = "zw000001"; - attribute_store_node_t endpoint_node = 0x017; - attribute_store_node_t notification_mode_node = 0x018; - attribute_store_node_t notification_probe_node = 0x019; - uint8_t notification_mode = 0x01; - uint8_t probe_active = false; - uint8_t u8_size = 1; + unid_t test_unid = "zw000001"; + attribute_store_node_t endpoint_node = 0x017; + attribute_store_node_t notification_mode_node = 0x018; + attribute_store_node_t notification_probe_node = 0x019; + uint8_t notification_mode = 0x01; + uint8_t probe_active = false; + uint8_t u8_size = 1; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); zwave_unid_from_node_id_ReturnMemThruPtr_unid(test_unid, sizeof(unid_t)); @@ -2051,16 +2168,14 @@ void test_zwave_command_class_notification_pull_mode_empty_queue_report() endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -2068,8 +2183,7 @@ void test_zwave_command_class_notification_pull_mode_empty_queue_report() sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); attribute_store_get_node_child_by_type_ExpectAndReturn( endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, @@ -2081,7 +2195,7 @@ void test_zwave_command_class_notification_pull_mode_empty_queue_report() &probe_active, 1, SL_STATUS_OK); - + TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, test_frame_data_2, @@ -2107,7 +2221,7 @@ void helper_test_zwave_command_class_notification_pull_mode_report( static uint8_t notification_mode = 0x01; static uint8_t probe_active = true; static uint8_t notification_type = 0x06; - static uint8_t u8_size = 1; + static uint8_t u8_size = 1; zwave_unid_from_node_id_Expect(test_connection_info.remote.node_id, NULL); zwave_unid_from_node_id_IgnoreArg_unid(); @@ -2124,16 +2238,14 @@ void helper_test_zwave_command_class_notification_pull_mode_report( endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_MODE, 0, - notification_mode_node - ); + notification_mode_node); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_mode_node, REPORTED_ATTRIBUTE, NULL, NULL, - SL_STATUS_OK - ); + SL_STATUS_OK); attribute_store_get_node_attribute_value_IgnoreArg_value(); attribute_store_get_node_attribute_value_IgnoreArg_value_size(); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value( @@ -2141,8 +2253,7 @@ void helper_test_zwave_command_class_notification_pull_mode_report( sizeof(notification_mode)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); if (expect_clear) { attribute_store_get_node_child_by_type_ExpectAndReturn( @@ -2189,8 +2300,10 @@ void helper_test_zwave_command_class_notification_pull_mode_report( ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, 0, notification_version_node); - attribute_store_get_node_type_IgnoreAndReturn(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); - attribute_store_get_type_name_IgnoreAndReturn("ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); + attribute_store_get_node_type_IgnoreAndReturn( + ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION); + attribute_store_get_type_name_IgnoreAndReturn( + "ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION"); attribute_store_get_node_attribute_value_ExpectAndReturn( notification_version_node, REPORTED_ATTRIBUTE, @@ -2204,8 +2317,7 @@ void helper_test_zwave_command_class_notification_pull_mode_report( sizeof(notification_version)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); static uint8_t state = NOTIFICATION_STATE_ACCESS_CONTROL_DOOR_STATE; attribute_store_get_node_child_by_value_ExpectAndReturn( @@ -2237,8 +2349,7 @@ void helper_test_zwave_command_class_notification_pull_mode_report( sizeof(uint8_t)); attribute_store_get_node_attribute_value_ReturnMemThruPtr_value_size( &u8_size, - sizeof(uint8_t) - ); + sizeof(uint8_t)); //attribute_store_get_type_name_IgnoreAndReturn("Type"); attribute_store_set_node_attribute_value_ExpectAndReturn( @@ -2260,7 +2371,7 @@ void helper_test_zwave_command_class_notification_pull_mode_report( (uint8_t *)¬ification_event_param_value, sizeof(int32_t), SL_STATUS_OK); - + attribute_store_get_node_child_by_type_ExpectAndReturn( endpoint_node, ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_PROBE_ACTIVE, @@ -2286,7 +2397,9 @@ void test_zwave_command_class_notification_pull_mode_report() uint8_t test_frame_data_2[] = {0x71, 0x05, 0x00, 0x00, 0x00, 0x00, 0x06, 0x16, 0x01, 0x00, 0x00}; - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_2, false); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_2, + false); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, @@ -2300,26 +2413,34 @@ void test_zwave_command_class_notification_pull_mode_report_priority_without_seq uint8_t test_frame_data_2[] = {0x71, 0x05, 0x00, 0x00, 0x00, 0x00, 0x06, 0x16, 0x01, 0x00, 0x00}; - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_2, false); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_2, + false); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, test_frame_data_2, sizeof(test_frame_data_2))); - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_2, false); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_2, + false); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, test_frame_data_2, sizeof(test_frame_data_2))); - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_2, false); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_2, + false); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, test_frame_data_2, sizeof(test_frame_data_2))); - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_2, true); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_2, + true); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, @@ -2333,14 +2454,18 @@ void test_zwave_command_class_notification_pull_mode_report_priority_with_sequen uint8_t test_frame_data_3[] = {0x71, 0x05, 0x00, 0x00, 0x00, 0x00, 0x06, 0x16, 0x81, 0x00, 0x00}; - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_3, false); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_3, + false); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, test_frame_data_3, sizeof(test_frame_data_3))); - helper_test_zwave_command_class_notification_pull_mode_report(test_frame_data_3, true); + helper_test_zwave_command_class_notification_pull_mode_report( + test_frame_data_3, + true); TEST_ASSERT_EQUAL(SL_STATUS_OK, command_handler.control_handler(&test_connection_info, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_protocol_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_protocol_test.c index fcdaf3388..b1401b520 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_protocol_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_protocol_test.c @@ -51,8 +51,9 @@ static sl_status_t zwave_command_handler_register_handler_stub( TEST_ASSERT_EQUAL(ZWAVE_CONTROLLER_ENCAPSULATION_NONE, protocol_handler.minimal_scheme); - TEST_ASSERT_TRUE(ZWAVE_CMD_CLASS_PROTOCOL ==protocol_handler.command_class - || ZWAVE_CMD_CLASS_PROTOCOL_LR == protocol_handler.command_class); + TEST_ASSERT_TRUE(ZWAVE_CMD_CLASS_PROTOCOL == protocol_handler.command_class + || ZWAVE_CMD_CLASS_PROTOCOL_LR + == protocol_handler.command_class); TEST_ASSERT_EQUAL(1, protocol_handler.version); TEST_ASSERT_NULL(protocol_handler.control_handler); TEST_ASSERT_NOT_NULL(protocol_handler.support_handler); @@ -82,7 +83,7 @@ void setUp() // Handler registration zwave_command_handler_register_handler_Stub( &zwave_command_handler_register_handler_stub); - + zwave_controller_register_callbacks_Stub( &zwave_controller_register_callback_stub); @@ -99,36 +100,38 @@ void test_zwave_command_class_protocol_init() void test_zwave_command_class_protocol_handler(void) { - uint8_t test_frame_data[5] = { 0}; + uint8_t test_frame_data[5] = {0}; test_frame_data[0] = ZWAVE_CMD_CLASS_PROTOCOL; - zwave_controller_connection_info_t connection = { 0 }; - connection.encapsulation = ZWAVE_CONTROLLER_ENCAPSULATION_SECURITY_2_AUTHENTICATED; + zwave_controller_connection_info_t connection = {0}; + connection.encapsulation + = ZWAVE_CONTROLLER_ENCAPSULATION_SECURITY_2_AUTHENTICATED; connection.remote.node_id = 2; - connection.local.node_id = 1; + connection.local.node_id = 1; // Test with wrong command length - TEST_ASSERT_EQUAL( - SL_STATUS_NOT_SUPPORTED, - protocol_handler.support_handler(&connection, - test_frame_data, - 1)); // wrong length + TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, + protocol_handler.support_handler(&connection, + test_frame_data, + 1)); // wrong length // Test with correct length - zwave_controller_get_key_from_encapsulation_ExpectAndReturn(ZWAVE_CONTROLLER_ENCAPSULATION_SECURITY_2_AUTHENTICATED, ZWAVE_CONTROLLER_S2_AUTHENTICATED_KEY); - - zwapi_transfer_protocol_cc_ExpectAndReturn(2, - ZWAVE_CONTROLLER_S2_AUTHENTICATED_KEY, - 5, - (uint8_t*) &test_frame_data, - SL_STATUS_OK); - - TEST_ASSERT_EQUAL( - SL_STATUS_OK, - protocol_handler.support_handler(&connection, - test_frame_data, - sizeof(test_frame_data))); + zwave_controller_get_key_from_encapsulation_ExpectAndReturn( + ZWAVE_CONTROLLER_ENCAPSULATION_SECURITY_2_AUTHENTICATED, + ZWAVE_CONTROLLER_S2_AUTHENTICATED_KEY); + + zwapi_transfer_protocol_cc_ExpectAndReturn( + 2, + ZWAVE_CONTROLLER_S2_AUTHENTICATED_KEY, + 5, + (uint8_t *)&test_frame_data, + SL_STATUS_OK); + + TEST_ASSERT_EQUAL(SL_STATUS_OK, + protocol_handler.support_handler(&connection, + test_frame_data, + sizeof(test_frame_data))); } void test_zwave_s2_on_protocol_cc_encryption_request_happy_case() @@ -136,10 +139,11 @@ void test_zwave_s2_on_protocol_cc_encryption_request_happy_case() zwave_node_id_t destination_node_id = 2; uint8_t payload[] = {0x01, 0x02, 0x03}; uint8_t payload_length = sizeof(payload) / sizeof(payload[0]); - uint8_t protocol_metadata[] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7}; - uint8_t protocol_metadata_length = sizeof(protocol_metadata) / sizeof(protocol_metadata[0]); - uint8_t use_supervision = 0; - uint8_t session_id = 1; + uint8_t protocol_metadata[] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7}; + uint8_t protocol_metadata_length + = sizeof(protocol_metadata) / sizeof(protocol_metadata[0]); + uint8_t use_supervision = 0; + uint8_t session_id = 1; zwave_controller_connection_info_t connection_info = {0}; zwave_tx_options_t tx_options = {0}; zwave_tx_session_id_t tx_session_id = NULL; @@ -155,7 +159,10 @@ void test_zwave_s2_on_protocol_cc_encryption_request_happy_case() zwave_tx_scheme_get_node_connection_info_Expect(destination_node_id, 0, NULL); zwave_tx_scheme_get_node_connection_info_IgnoreArg_connection_info(); - zwave_tx_scheme_get_node_tx_options_Expect(ZWAVE_TX_QOS_MAX_PRIORITY, 1, 5000, NULL); + zwave_tx_scheme_get_node_tx_options_Expect(ZWAVE_TX_QOS_MAX_PRIORITY, + 1, + 5000, + NULL); zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_send_data_ExpectWithArrayAndReturn(&connection_info, @@ -186,11 +193,17 @@ void test_zwave_s2_on_protocol_cc_encryption_request_happy_case() zwave_tx_scheme_get_node_connection_info_Expect(destination_node_id, 0, NULL); zwave_tx_scheme_get_node_connection_info_IgnoreArg_connection_info(); - zwave_tx_scheme_get_node_tx_options_Expect(ZWAVE_TX_QOS_MAX_PRIORITY, 1, 5000, NULL); + zwave_tx_scheme_get_node_tx_options_Expect(ZWAVE_TX_QOS_MAX_PRIORITY, + 1, + 5000, + NULL); zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); - uint16_t supervision_frame_size = 4 + payload_length; // sizeof(frame) - SUPERVISION_ENCAPSULATED_COMMAND_MAXIMUM_SIZE - tx_options.number_of_responses += 1; // supervision get expects 1 frame in response + uint16_t supervision_frame_size + = 4 + + payload_length; // sizeof(frame) - SUPERVISION_ENCAPSULATED_COMMAND_MAXIMUM_SIZE + tx_options.number_of_responses + += 1; // supervision get expects 1 frame in response zwave_tx_send_data_ExpectWithArrayAndReturn(&connection_info, sizeof(connection_info), @@ -217,4 +230,3 @@ void test_zwave_s2_on_protocol_cc_encryption_request_happy_case() use_supervision, session_id); } - diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_sound_switch_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_sound_switch_test.c index 2a8a8f340..588385657 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_sound_switch_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_sound_switch_test.c @@ -43,12 +43,12 @@ // Private variables static zwave_command_handler_t handler = {}; -static attribute_resolver_function_t configuration_get = NULL; -static attribute_resolver_function_t configuration_set = NULL; -static attribute_resolver_function_t tone_number_get = NULL; -static attribute_resolver_function_t tone_info_get = NULL; -static attribute_resolver_function_t play_get = NULL; -static attribute_resolver_function_t play_set = NULL; +static attribute_resolver_function_t configuration_get = NULL; +static attribute_resolver_function_t configuration_set = NULL; +static attribute_resolver_function_t tone_number_get = NULL; +static attribute_resolver_function_t tone_info_get = NULL; +static attribute_resolver_function_t play_get = NULL; +static attribute_resolver_function_t play_set = NULL; // Buffer for frame static uint8_t received_frame[255] = {}; static uint16_t received_frame_size = 0; @@ -60,7 +60,8 @@ static sl_status_t attribute_resolver_function_t get_func, int cmock_num_calls) { - if (node_type == ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME) { + if (node_type + == ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME) { TEST_ASSERT_NOT_NULL(set_func); TEST_ASSERT_NOT_NULL(get_func); configuration_get = get_func; @@ -69,7 +70,8 @@ static sl_status_t TEST_ASSERT_NULL(set_func); TEST_ASSERT_NOT_NULL(get_func); tone_number_get = get_func; - } else if (node_type == ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER) { + } else if (node_type + == ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_IDENTIFIER) { TEST_ASSERT_NULL(set_func); TEST_ASSERT_NOT_NULL(get_func); tone_info_get = get_func; @@ -83,7 +85,6 @@ static sl_status_t return SL_STATUS_OK; } - // Stub for registering command classes static sl_status_t zwave_command_handler_register_handler_stub( zwave_command_handler_t new_command_class_handler, int cmock_num_calls) @@ -123,15 +124,16 @@ void setUp() zpc_attribute_store_test_helper_create_network(); // Unset previous definition get/set functions - configuration_get = NULL; - configuration_set = NULL; - tone_number_get = NULL; - tone_info_get = NULL; + configuration_get = NULL; + configuration_set = NULL; + tone_number_get = NULL; + tone_info_get = NULL; memset(received_frame, 0, sizeof(received_frame)); received_frame_size = 0; // Resolution functions attribute_resolver_register_rule_Stub(&attribute_resolver_register_rule_stub); - zwave_command_handler_register_handler_Stub(&zwave_command_handler_register_handler_stub); + zwave_command_handler_register_handler_Stub( + &zwave_command_handler_register_handler_stub); // Call init TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_command_class_sound_switch_init()); } @@ -141,22 +143,33 @@ void tearDown() {} /// Helpers -void set_supported_version(zwave_cc_version_t version) { - attribute_store_node_t version_node = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_VERSION, endpoint_id_node); +void set_supported_version(zwave_cc_version_t version) +{ + attribute_store_node_t version_node + = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_VERSION, + endpoint_id_node); attribute_store_set_reported(version_node, &version, sizeof(version)); } -zwave_cc_version_t get_supported_version() { +zwave_cc_version_t get_supported_version() +{ zwave_cc_version_t version = 0; - attribute_store_get_child_reported(endpoint_id_node, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_VERSION, &version, sizeof(version)); + attribute_store_get_child_reported( + endpoint_id_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_VERSION, + &version, + sizeof(version)); return version; } -void set_volume_and_tone(uint8_t volume, uint8_t tone) { +void set_volume_and_tone(uint8_t volume, uint8_t tone) +{ // Attribute tree is empty as this point so we add it here - attribute_store_node_t volume_node - = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME, endpoint_id_node); - attribute_store_node_t tone_node - = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER, endpoint_id_node); + attribute_store_node_t volume_node = attribute_store_add_node( + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME, + endpoint_id_node); + attribute_store_node_t tone_node = attribute_store_add_node( + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_TONE_IDENTIFIER, + endpoint_id_node); attribute_store_set_desired(volume_node, &volume, sizeof(volume)); attribute_store_set_desired(tone_node, &tone, sizeof(tone)); @@ -165,31 +178,38 @@ void set_volume_and_tone(uint8_t volume, uint8_t tone) { // We can either set the volume_node or tone_here here. configuration_set(volume_node, received_frame, &received_frame_size); - const uint8_t expected_frame[] - = {COMMAND_CLASS_SOUND_SWITCH, SOUND_SWITCH_CONFIGURATION_SET, volume, tone}; + const uint8_t expected_frame[] = {COMMAND_CLASS_SOUND_SWITCH, + SOUND_SWITCH_CONFIGURATION_SET, + volume, + tone}; TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame, received_frame, received_frame_size); } - -void set_play(uint8_t tone_id, uint8_t volume) { +void set_play(uint8_t tone_id, uint8_t volume) +{ // Get supported version zwave_cc_version_t version = get_supported_version(); // Since we are simulating a specific version the attribute should be created. - attribute_store_node_t play_node - = attribute_store_get_node_child_by_type(endpoint_id_node, ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY, 0); + attribute_store_node_t play_node = attribute_store_get_node_child_by_type( + endpoint_id_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY, + 0); attribute_store_node_t volume_node; if (version == 2) { - volume_node = attribute_store_get_node_child_by_type(endpoint_id_node,ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME, 0); + volume_node = attribute_store_get_node_child_by_type( + endpoint_id_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_CONFIGURED_DEFAULT_VOLUME, + 0); } if (tone_id > 0 && tone_id < 255) { // Workaround to allow to send a specific tone ID though this attribute. // - // The OnOff UCL cluster only support boolean states and we need a uint8_t to be able to + // The OnOff UCL cluster only support boolean states and we need a uint8_t to be able to // send specific toneID though the Play Set command. // With this workaround we can : // - Play the default tone (255) with the ZCL OnOff attribute (1) @@ -199,17 +219,25 @@ void set_play(uint8_t tone_id, uint8_t volume) { // WARNING : DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME is on 16 bits not 8 uint16_t tone_id_16 = tone_id; - attribute_store_node_t ontime_node = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME, endpoint_id_node); - sl_status_t result = attribute_store_set_desired(ontime_node, &tone_id_16, sizeof(tone_id_16)); - TEST_ASSERT_EQUAL(SL_STATUS_OK, result ); + attribute_store_node_t ontime_node + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME, + endpoint_id_node); + sl_status_t result = attribute_store_set_desired(ontime_node, + &tone_id_16, + sizeof(tone_id_16)); + TEST_ASSERT_EQUAL(SL_STATUS_OK, result); // Check that the original play mode has been updated uint8_t expected_tone; - result = attribute_store_get_desired(play_node, &expected_tone, sizeof(expected_tone)); + result = attribute_store_get_desired(play_node, + &expected_tone, + sizeof(expected_tone)); TEST_ASSERT_EQUAL(SL_STATUS_OK, result); // Result should be undefined as we only use this as a buffer - result = attribute_store_get_desired(ontime_node, &expected_tone, sizeof(expected_tone)); + result = attribute_store_get_desired(ontime_node, + &expected_tone, + sizeof(expected_tone)); TEST_ASSERT_EQUAL(SL_STATUS_FAIL, result); TEST_ASSERT_EQUAL(expected_tone, tone_id); @@ -225,8 +253,10 @@ void set_play(uint8_t tone_id, uint8_t volume) { play_set(play_node, received_frame, &received_frame_size); if (version == 2) { - const uint8_t expected_frame[] - = {COMMAND_CLASS_SOUND_SWITCH, SOUND_SWITCH_TONE_PLAY_SET, tone_id, volume}; + const uint8_t expected_frame[] = {COMMAND_CLASS_SOUND_SWITCH, + SOUND_SWITCH_TONE_PLAY_SET, + tone_id, + volume}; TEST_ASSERT_EQUAL(sizeof(expected_frame), received_frame_size); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_frame, received_frame, @@ -241,8 +271,8 @@ void set_play(uint8_t tone_id, uint8_t volume) { } } - -void tone_play_report_internal(const uint8_t* frame, int frame_size) { +void tone_play_report_internal(const uint8_t *frame, int frame_size) +{ zwave_controller_connection_info_t info = {}; info.remote.node_id = node_id; info.remote.endpoint_id = endpoint_id; @@ -256,10 +286,10 @@ void tone_play_report_internal(const uint8_t* frame, int frame_size) { handler.control_handler(&info, frame, frame_size)); } -void tone_play_report(uint8_t tone_id) { - const uint8_t frame[] = {COMMAND_CLASS_SOUND_SWITCH, - SOUND_SWITCH_TONE_PLAY_REPORT, - tone_id}; +void tone_play_report(uint8_t tone_id) +{ + const uint8_t frame[] + = {COMMAND_CLASS_SOUND_SWITCH, SOUND_SWITCH_TONE_PLAY_REPORT, tone_id}; tone_play_report_internal(frame, sizeof(frame)); @@ -277,7 +307,8 @@ void tone_play_report(uint8_t tone_id) { TEST_ASSERT_EQUAL(tone_id, attribute_store_get_reported_number(tone_node)); } -void tone_play_report_with_volume(uint8_t tone_id, uint8_t volume) { +void tone_play_report_with_volume(uint8_t tone_id, uint8_t volume) +{ const uint8_t frame[] = {COMMAND_CLASS_SOUND_SWITCH, SOUND_SWITCH_TONE_PLAY_REPORT, tone_id, @@ -335,9 +366,10 @@ void test_sound_switch_configuration_report_volume_over_100() void test_sound_switch_tone_number_report_happy_case() { - // Attribute tree is empty as this point so we add it here - attribute_store_node_t tone_node - = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, endpoint_id_node); + // Attribute tree is empty as this point so we add it here + attribute_store_node_t tone_node = attribute_store_add_node( + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONES_NUMBER, + endpoint_id_node); const uint8_t EXPECTED_TONE_NUMBER = 12; @@ -358,51 +390,63 @@ void test_sound_switch_tone_number_report_happy_case() TEST_ASSERT_EQUAL(SL_STATUS_OK, handler.control_handler(&info, frame, sizeof(frame))); - TEST_ASSERT_EQUAL(attribute_store_get_node_child_count(tone_node), - (size_t)EXPECTED_TONE_NUMBER); + TEST_ASSERT_EQUAL(attribute_store_get_node_child_count(tone_node), + (size_t)EXPECTED_TONE_NUMBER); // Test if all the tone number ID are correctly defined - for (uint8_t i=1; i<=EXPECTED_TONE_NUMBER;i++) { - attribute_store_node_t current_tone_id_node = attribute_store_get_node_child(tone_node, i-1); - uint8_t expected_value; - sl_status_t status = attribute_store_get_desired(current_tone_id_node, &expected_value, sizeof(expected_value)); - TEST_ASSERT_EQUAL(status, SL_STATUS_OK); - TEST_ASSERT_EQUAL(i, expected_value); + for (uint8_t i = 1; i <= EXPECTED_TONE_NUMBER; i++) { + attribute_store_node_t current_tone_id_node + = attribute_store_get_node_child(tone_node, i - 1); + uint8_t expected_value; + sl_status_t status = attribute_store_get_desired(current_tone_id_node, + &expected_value, + sizeof(expected_value)); + TEST_ASSERT_EQUAL(status, SL_STATUS_OK); + TEST_ASSERT_EQUAL(i, expected_value); } // Now we simulate a report for all node and see if their info are correctly updated - for (uint8_t i=1; i= 10 ? '1' : '0', (i % 10) + '0', '\0'}; - - uint8_t report_tone_info[] = {COMMAND_CLASS_SOUND_SWITCH, - SOUND_SWITCH_TONE_INFO_REPORT, - i, // Tone Identifier - 0, // Byte 1 Tone duration - expected_duration, // Byte 2 Tone duration - 2, // Name length - expected_name[0], // Name 1 - expected_name[1] // Name 2 - }; - - TEST_ASSERT_EQUAL(SL_STATUS_OK, - handler.control_handler(&info, report_tone_info, sizeof(report_tone_info))); - - attribute_store_node_t current_tone_id_node = attribute_store_get_node_child(tone_node, i-1); - - // Duration test - uint16_t duration; - attribute_store_get_child_reported(current_tone_id_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_DURATION_SECONDS, &duration, sizeof(duration)); - TEST_ASSERT_EQUAL(duration, (uint16_t)expected_duration); - - // Name test - char name[3]; - attribute_store_node_t name_node = attribute_store_get_node_child_by_type(current_tone_id_node, - ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_NAME, 0); - - attribute_store_get_reported_string(name_node, name, 3); - TEST_ASSERT_EQUAL_CHAR_ARRAY(expected_name, name, 3); + for (uint8_t i = 1; i < EXPECTED_TONE_NUMBER; i++) { + uint8_t expected_duration = i + 12; + char expected_name[3] = {i >= 10 ? '1' : '0', (i % 10) + '0', '\0'}; + + uint8_t report_tone_info[] = { + COMMAND_CLASS_SOUND_SWITCH, + SOUND_SWITCH_TONE_INFO_REPORT, + i, // Tone Identifier + 0, // Byte 1 Tone duration + expected_duration, // Byte 2 Tone duration + 2, // Name length + expected_name[0], // Name 1 + expected_name[1] // Name 2 + }; + + TEST_ASSERT_EQUAL(SL_STATUS_OK, + handler.control_handler(&info, + report_tone_info, + sizeof(report_tone_info))); + + attribute_store_node_t current_tone_id_node + = attribute_store_get_node_child(tone_node, i - 1); + + // Duration test + uint16_t duration; + attribute_store_get_child_reported( + current_tone_id_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_DURATION_SECONDS, + &duration, + sizeof(duration)); + TEST_ASSERT_EQUAL(duration, (uint16_t)expected_duration); + + // Name test + char name[3]; + attribute_store_node_t name_node = attribute_store_get_node_child_by_type( + current_tone_id_node, + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_NAME, + 0); + + attribute_store_get_reported_string(name_node, name, 3); + TEST_ASSERT_EQUAL_CHAR_ARRAY(expected_name, name, 3); } } @@ -419,15 +463,14 @@ void test_sound_switch_configuration_get_happy_case() received_frame_size); } - void test_sound_switch_configuration_set_happy_case() { - set_volume_and_tone(15,30); + set_volume_and_tone(15, 30); } void test_sound_switch_configuration_set_volume_0() { - set_volume_and_tone(0,30); + set_volume_and_tone(0, 30); } void test_sound_switch_play_get_play() @@ -450,64 +493,68 @@ void test_sound_switch_play_report_v1() void test_sound_switch_play_report_v2() { - tone_play_report_with_volume(12,24); + tone_play_report_with_volume(12, 24); } void test_sound_switch_play_set_play_default_v1() { set_supported_version(1); - set_play(255,255); + set_play(255, 255); } void test_sound_switch_play_set_stop_v1() { set_supported_version(1); - set_play(0,255); + set_play(0, 255); } void test_sound_switch_play_set_custom_tone_v1() { set_supported_version(1); - set_play(55,255); + set_play(55, 255); } - void test_sound_switch_play_set_play_default_v2() { set_supported_version(2); - set_play(255,255); + set_play(255, 255); } void test_sound_switch_play_set_stop_v2() { set_supported_version(2); - set_play(0,255); + set_play(0, 255); } void test_sound_switch_play_set_custom_tone_v2() { set_supported_version(2); - set_play(55,255); + set_play(55, 255); } void test_sound_switch_play_set_custom_tone_and_volume_v2() { set_supported_version(2); - set_play(55,15); + set_play(55, 15); } // Test if sound switch attributes are note created if DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME is changed -void test_no_update_if_no_sound_switch() { - // WARNING : DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME is on 16 bits not 8 - uint16_t tone_id_16 = 12; - attribute_store_node_t ontime_node = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME, endpoint_id_node); - sl_status_t result = attribute_store_set_desired(ontime_node, &tone_id_16, sizeof(tone_id_16)); - TEST_ASSERT_EQUAL(SL_STATUS_OK, result ); - - - // This node shouldn't exist since DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME must not create it. - attribute_store_node_t play_node = - attribute_store_get_node_child_by_type(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY, endpoint_id_node, 0); +void test_no_update_if_no_sound_switch() +{ + // WARNING : DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME is on 16 bits not 8 + uint16_t tone_id_16 = 12; + attribute_store_node_t ontime_node + = attribute_store_add_node(DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME, + endpoint_id_node); + sl_status_t result + = attribute_store_set_desired(ontime_node, &tone_id_16, sizeof(tone_id_16)); + TEST_ASSERT_EQUAL(SL_STATUS_OK, result); + + // This node shouldn't exist since DOTDOT_ATTRIBUTE_ID_ON_OFF_ON_TIME must not create it. + attribute_store_node_t play_node = attribute_store_get_node_child_by_type( + ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY, + endpoint_id_node, + 0); - TEST_ASSERT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, play_node); + TEST_ASSERT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, play_node); } \ No newline at end of file diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test_no_mock.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test_no_mock.c index f0e23b846..87f79acc3 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test_no_mock.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test_no_mock.c @@ -82,7 +82,8 @@ void setUp() { zpc_attribute_store_test_helper_create_network(); - zwave_command_handler_register_handler_Stub(&zwave_command_handler_register_handler_stub); + zwave_command_handler_register_handler_Stub( + &zwave_command_handler_register_handler_stub); // Call init TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_command_class_supervision_init()); } @@ -90,7 +91,6 @@ void setUp() /// Called after each and every test void tearDown() {} - // We can't do it in the zwave_command_class_supervision_test since they're too many mocks // on the attribute store side preventing us to test this feature void test_flag_creation_on_startup_happy_case() diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_switch_color_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_switch_color_test.c index 5a69252ac..c53e63c01 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_switch_color_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_switch_color_test.c @@ -70,16 +70,16 @@ static sl_status_t attribute_timeout_set_callback_stub( attribute_timeout_callback_t callback_function, int cmock_num_calls) { - TEST_ASSERT_EQUAL(ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_STATE, attribute_store_get_node_type(node)); + TEST_ASSERT_EQUAL(ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_STATE, + attribute_store_get_node_type(node)); switch_color_undefine_reported = callback_function; return SL_STATUS_OK; } - /// Setup the test suite (called once before all test_xxx functions are called) void suiteSetUp() { - on_send_complete = NULL; + on_send_complete = NULL; switch_color_undefine_reported = NULL; datastore_init(":memory:"); @@ -198,8 +198,10 @@ void test_zwave_command_class_on_send_complete() attribute_store_node_t duration_node = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SWITCH_COLOR_DURATION, state_node); - attribute_store_set_desired(duration_node, &duration_value, sizeof(duration_value)); - + attribute_store_set_desired(duration_node, + &duration_value, + sizeof(duration_value)); + attribute_timeout_set_callback_ExpectAndReturn( state_node, zwave_duration_to_time(duration_value) + PROBE_BACK_OFF, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_mode_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_mode_test.c index d1f1221bb..6942d50d5 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_mode_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_mode_test.c @@ -47,7 +47,6 @@ // Value that is unsupported for all Thermostat Fan Mode versions #define THERMOSTAT_FAN_MODE_UNSUPPORTED 0x0F - static zwave_command_handler_t handler = {}; static attribute_resolver_function_t current_fan_mode_get = NULL; @@ -241,7 +240,8 @@ void helper_fan_mode_set(zwave_cc_version_t version, bool happy_case) supported_fan_mode_type[2] = THERMOSTAT_FAN_MODE_SET_FAN_MODE_AUTO_MEDIUM_V2; supported_fan_mode_type[3] = THERMOSTAT_FAN_MODE_SET_FAN_MODE_QUIET_V4; - supported_fan_mode_type[4] = THERMOSTAT_FAN_MODE_REPORT_FAN_MODE_EXTERNAL_CIRCULATION_V5; + supported_fan_mode_type[4] + = THERMOSTAT_FAN_MODE_REPORT_FAN_MODE_EXTERNAL_CIRCULATION_V5; break; TEST_FAIL_MESSAGE("Version not supported in helper_fan_mode_set()"); } @@ -265,9 +265,8 @@ void helper_fan_mode_set(zwave_cc_version_t version, bool happy_case) endpoint_id_node, ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_FAN_MODE_CURRENT_MODE, 0); - sl_status_t result = attribute_store_set_desired(fan_mode_node, - &fan_mode, - sizeof(fan_mode)); + sl_status_t result + = attribute_store_set_desired(fan_mode_node, &fan_mode, sizeof(fan_mode)); TEST_ASSERT_EQUAL(SL_STATUS_OK, result); // Not existant in v1 @@ -281,8 +280,8 @@ void helper_fan_mode_set(zwave_cc_version_t version, bool happy_case) TEST_ASSERT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, off_flag_node); } else { result = attribute_store_set_desired(off_flag_node, - &off_flag, - sizeof(off_flag)); + &off_flag, + sizeof(off_flag)); TEST_ASSERT_EQUAL(SL_STATUS_OK, result); TEST_ASSERT_NOT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, off_flag_node); } @@ -325,21 +324,19 @@ void helper_fan_mode_set(zwave_cc_version_t version, bool happy_case) set_reported_status, "Set function should NOT have worked"); - - // Now we want to test version mismatch + // Now we want to test version mismatch // Set all supported modes set_supported_modes(0xFFFF); // Set fan mode to one that isn't supported by any of the version - fan_mode = THERMOSTAT_FAN_MODE_UNSUPPORTED; - result = attribute_store_set_desired(fan_mode_node, - &fan_mode, - sizeof(fan_mode)); + fan_mode = THERMOSTAT_FAN_MODE_UNSUPPORTED; + result = attribute_store_set_desired(fan_mode_node, + &fan_mode, + sizeof(fan_mode)); TEST_ASSERT_EQUAL(SL_STATUS_OK, result); - set_reported_status - = current_fan_mode_set(fan_mode_node, - received_frame, - &received_frame_size); + set_reported_status = current_fan_mode_set(fan_mode_node, + received_frame, + &received_frame_size); TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_NOT_SUPPORTED, set_reported_status, "Set function should NOT have worked"); @@ -349,8 +346,7 @@ void helper_fan_mode_set(zwave_cc_version_t version, bool happy_case) } } -void helper_fan_mode_report(zwave_cc_version_t version, - bool happy_case) +void helper_fan_mode_report(zwave_cc_version_t version, bool happy_case) { set_version(version); @@ -363,13 +359,13 @@ void helper_fan_mode_report(zwave_cc_version_t version, TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, handler.control_handler(&info, NULL, 0)); - thermostat_fan_mode_t fan_mode = 0; - thermostat_fan_mode_off_flag_t off_flag = 0; + thermostat_fan_mode_t fan_mode = 0; + thermostat_fan_mode_off_flag_t off_flag = 0; thermostat_fan_supported_modes_t current_supported_bitmask = 0; switch (version) { case 1: - fan_mode = THERMOSTAT_FAN_MODE_SET_FAN_MODE_HIGH; + fan_mode = THERMOSTAT_FAN_MODE_SET_FAN_MODE_HIGH; current_supported_bitmask = 0x08; // Set to 0 to ignore value (not supported) off_flag = 0; @@ -383,25 +379,25 @@ void helper_fan_mode_report(zwave_cc_version_t version, case 3: fan_mode = THERMOSTAT_FAN_MODE_SET_FAN_MODE_CIRCULATION_V3; current_supported_bitmask = 0x40; - off_flag = 1; + off_flag = 1; break; case 4: fan_mode = THERMOSTAT_FAN_MODE_SET_FAN_MODE_LEFT_RIGHT_V4; current_supported_bitmask = 0x100; - off_flag = 0; + off_flag = 0; break; case 5: fan_mode = THERMOSTAT_FAN_MODE_REPORT_FAN_MODE_EXTERNAL_CIRCULATION_V5; current_supported_bitmask = 0x800; - off_flag = 1; + off_flag = 1; break; default: TEST_FAIL_MESSAGE("Version not supported in helper_fan_mode_set"); } uint8_t frame[] = {COMMAND_CLASS_THERMOSTAT_FAN_MODE, - THERMOSTAT_FAN_MODE_REPORT, - fan_mode | (off_flag << 7)}; + THERMOSTAT_FAN_MODE_REPORT, + fan_mode | (off_flag << 7)}; attribute_store_node_t current_fan_mode_node = attribute_store_get_node_child_by_type( @@ -452,19 +448,19 @@ void helper_fan_mode_report(zwave_cc_version_t version, attribute_store_get_reported(current_fan_mode_node, &reported_fan_mode, sizeof(reported_fan_mode))); - + // Now we support all but we test version mismatch - set_supported_modes(0xFFFF); + set_supported_modes(0xFFFF); uint8_t frame[] = {COMMAND_CLASS_THERMOSTAT_FAN_MODE, - THERMOSTAT_FAN_MODE_REPORT, - THERMOSTAT_FAN_MODE_UNSUPPORTED | (off_flag << 7)}; + THERMOSTAT_FAN_MODE_REPORT, + THERMOSTAT_FAN_MODE_UNSUPPORTED | (off_flag << 7)}; - TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, + TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, handler.control_handler(&info, frame, sizeof(frame))); - TEST_ASSERT_EQUAL(SL_STATUS_FAIL, - attribute_store_get_reported(current_fan_mode_node, - &reported_fan_mode, - sizeof(reported_fan_mode))); + TEST_ASSERT_EQUAL(SL_STATUS_FAIL, + attribute_store_get_reported(current_fan_mode_node, + &reported_fan_mode, + sizeof(reported_fan_mode))); } } @@ -631,7 +627,6 @@ void test_thermostat_fan_mode_set_v5_not_supported_types() helper_fan_mode_set(THERMOSTAT_FAN_MODE_VERSION_V5, false); } - void test_thermostat_fan_mode_report_v1_happy_case() { helper_fan_mode_report(THERMOSTAT_FAN_MODE_VERSION, true); diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_state_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_state_test.c index bb29cc8a2..de528756a 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_state_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_fan_state_test.c @@ -42,7 +42,6 @@ #include "dotdot_mqtt_mock.h" #include "dotdot_mqtt_generated_commands_mock.h" - static zwave_command_handler_t handler = {}; static attribute_resolver_function_t current_fan_state_get = NULL; @@ -63,7 +62,7 @@ static sl_status_t TEST_ASSERT_NULL(set_func); TEST_ASSERT_NOT_NULL(get_func); current_fan_state_get = get_func; - } + } return SL_STATUS_OK; } @@ -125,13 +124,13 @@ void setUp() /// Called after each and every test void tearDown() {} - //////////////////////////////////////////////////////////////////////////// // HELPERS //////////////////////////////////////////////////////////////////////////// // Happy case : not setting reserved bit to 1 -void helper_fan_state_report(thermostat_fan_state_t expected_state, bool happy_case) { - +void helper_fan_state_report(thermostat_fan_state_t expected_state, + bool happy_case) +{ uint8_t happy_case_mask = happy_case ? 0x00 : 0xF0; const uint8_t frame[] = {COMMAND_CLASS_THERMOSTAT_FAN_STATE, @@ -153,9 +152,11 @@ void helper_fan_state_report(thermostat_fan_state_t expected_state, bool happy_c 0); TEST_ASSERT_NOT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, fan_state_node); - + thermostat_fan_state_t reported_state = 0x00; - attribute_store_get_reported(fan_state_node, &reported_state, sizeof(reported_state)); + attribute_store_get_reported(fan_state_node, + &reported_state, + sizeof(reported_state)); TEST_ASSERT_EQUAL(expected_state, reported_state); } diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_mode_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_mode_test.c index 8287dea44..69ca86b3c 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_mode_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_mode_test.c @@ -371,9 +371,9 @@ void test_thermostat_mode_incoming_supported_report_happy_case() ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_SUPPORTED_MODES, endpoint_id_node); - const uint8_t bit1 = 0b0000101; - const uint8_t bit2 = 0b0000011; - const uint8_t bit3 = 0b1111111; + const uint8_t bit1 = 0b0000101; + const uint8_t bit2 = 0b0000011; + const uint8_t bit3 = 0b1111111; const uint8_t incoming_report_frame[] = {COMMAND_CLASS_THERMOSTAT_MODE_V3, THERMOSTAT_MODE_SUPPORTED_REPORT_V3, bit1, @@ -386,7 +386,7 @@ void test_thermostat_mode_incoming_supported_report_happy_case() incoming_report_frame, sizeof(incoming_report_frame))); - uint32_t received_bitmask = 0; + uint32_t received_bitmask = 0; attribute_store_get_reported(supported_modes_node, &received_bitmask, sizeof(received_bitmask)); diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_setpoint_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_setpoint_test.c index 1c4af8400..0e485b174 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_setpoint_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_thermostat_setpoint_test.c @@ -307,7 +307,6 @@ void helper_thermostat_setpoint_mode_supported_report( setpoint_mode_excepted_length); } - // WARNING: if version > 3 only support value size = 1 (don't go over/under int8) void helper_setpoint_capabilities( zwave_cc_version_t version, @@ -1459,7 +1458,6 @@ void test_thermostat_setpoint_supported_get_happy_case() "thermostat_setpoint_supported_get : contents mismatch"); } - void test_thermostat_setpoint_capabilities_version_1_happy_case() { helper_setpoint_capabilities(1, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_parameters_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_parameters_test.c index 18a8690c7..2d537efad 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_parameters_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_parameters_test.c @@ -49,7 +49,8 @@ struct tm test_time_info = {.tm_year = TEST_YEAR - 1900, .tm_isdst = -1}; /// Setup the test suite (called once before all test_xxx functions are called) -void suiteSetUp() { +void suiteSetUp() +{ setenv("TZ", "UTC", 1); } @@ -131,68 +132,74 @@ void test_zwave_command_class_time_parameters_multicast_not_allowed() void test_zwave_command_class_time_parameters_get() { - // Prepare the expected date_time_t structure - date_time_t expected_time = { - .year = TEST_YEAR - 1900, // Adjust for tm_year - .mon = TEST_MONTH - 1, // Adjust for tm_mon - .day = TEST_DAY, - .hour = TEST_HOUR & 0xF, - .min = TEST_MIN, - .sec = TEST_SEC - }; - - // Simulate the set time in the system - platform_set_date_time(&expected_time); - - // Prepare command frame for TIME_PARAMETERS_GET command - const uint8_t cmd_frame_time_parameters_command[] = { - COMMAND_CLASS_TIME_PARAMETERS, - TIME_PARAMETERS_GET - }; - - // Prepare expected response frame - const uint8_t exp_frame_time_parameters_command[] = { - COMMAND_CLASS_TIME_PARAMETERS, - TIME_PARAMETERS_REPORT, - (TEST_YEAR >> 8), // MSB of the year - (TEST_YEAR & 0xFF), // LSB of the year - TEST_MONTH, // Month (1-12) - TEST_DAY, // Day - TEST_HOUR & 0xF, // Hour - TEST_MIN, // Minute - TEST_SEC // Second - }; - - // Execute the test - execute_frame_expect_frame( - zwave_command_class_time_parameters_support_handler, - cmd_frame_time_parameters_command, - sizeof(cmd_frame_time_parameters_command), - exp_frame_time_parameters_command, - sizeof(exp_frame_time_parameters_command), - SL_STATUS_OK - ); + // Prepare the expected date_time_t structure + date_time_t expected_time = {.year = TEST_YEAR - 1900, // Adjust for tm_year + .mon = TEST_MONTH - 1, // Adjust for tm_mon + .day = TEST_DAY, + .hour = TEST_HOUR & 0xF, + .min = TEST_MIN, + .sec = TEST_SEC}; + + // Simulate the set time in the system + platform_set_date_time(&expected_time); + + // Prepare command frame for TIME_PARAMETERS_GET command + const uint8_t cmd_frame_time_parameters_command[] + = {COMMAND_CLASS_TIME_PARAMETERS, TIME_PARAMETERS_GET}; + + // Prepare expected response frame + const uint8_t exp_frame_time_parameters_command[] = { + COMMAND_CLASS_TIME_PARAMETERS, + TIME_PARAMETERS_REPORT, + (TEST_YEAR >> 8), // MSB of the year + (TEST_YEAR & 0xFF), // LSB of the year + TEST_MONTH, // Month (1-12) + TEST_DAY, // Day + TEST_HOUR & 0xF, // Hour + TEST_MIN, // Minute + TEST_SEC // Second + }; + + // Execute the test + execute_frame_expect_frame( + zwave_command_class_time_parameters_support_handler, + cmd_frame_time_parameters_command, + sizeof(cmd_frame_time_parameters_command), + exp_frame_time_parameters_command, + sizeof(exp_frame_time_parameters_command), + SL_STATUS_OK); } -void test_zwave_command_class_time_parameters_set(void) { - // Define test frame data for a known date and time - uint8_t valid_frame_data[] = {0x00, 0x00, 0x07, 0xE5, 0x04, 0x15, 0x10, 0x20, 0x30}; // 2021-04-21 16:32:48 - uint16_t valid_frame_length = sizeof(valid_frame_data); - - // Call the function to set time parameters - sl_status_t result = zwave_command_class_time_parameters_set(valid_frame_data, valid_frame_length); - TEST_ASSERT_EQUAL(SL_STATUS_OK, result); - - // Validate that the simulated time has been updated correctly - date_time_t simulated_time = platform_get_date_time(); - - // Adjust expected values for tm_year and tm_mon - TEST_ASSERT_EQUAL(121 , simulated_time.year); // Adjusting years(2021 -1900) - TEST_ASSERT_EQUAL(3, simulated_time.mon); // Adjusting months(4-1) - TEST_ASSERT_EQUAL(21, simulated_time.day); - TEST_ASSERT_EQUAL(16, simulated_time.hour); - TEST_ASSERT_EQUAL(32, simulated_time.min); - TEST_ASSERT_EQUAL(48, simulated_time.sec); +void test_zwave_command_class_time_parameters_set(void) +{ + // Define test frame data for a known date and time + uint8_t valid_frame_data[] = {0x00, + 0x00, + 0x07, + 0xE5, + 0x04, + 0x15, + 0x10, + 0x20, + 0x30}; // 2021-04-21 16:32:48 + uint16_t valid_frame_length = sizeof(valid_frame_data); + + // Call the function to set time parameters + sl_status_t result + = zwave_command_class_time_parameters_set(valid_frame_data, + valid_frame_length); + TEST_ASSERT_EQUAL(SL_STATUS_OK, result); + + // Validate that the simulated time has been updated correctly + date_time_t simulated_time = platform_get_date_time(); + + // Adjust expected values for tm_year and tm_mon + TEST_ASSERT_EQUAL(121, simulated_time.year); // Adjusting years(2021 -1900) + TEST_ASSERT_EQUAL(3, simulated_time.mon); // Adjusting months(4-1) + TEST_ASSERT_EQUAL(21, simulated_time.day); + TEST_ASSERT_EQUAL(16, simulated_time.hour); + TEST_ASSERT_EQUAL(32, simulated_time.min); + TEST_ASSERT_EQUAL(48, simulated_time.sec); } static sl_status_t zwave_command_handler_register_handler_CALLBACK( diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_test.c index fbdf1d219..ca72b2f38 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_time_test.c @@ -125,9 +125,9 @@ void test_zwave_command_class_date_get() { // Prepare the expected date_time_t structure date_time_t expected_time = { - .year = TEST_YEAR - 1900, // Adjust for tm_year - .mon = TEST_MONTH - 1, // Adjust for tm_mon - .day = TEST_DAY, + .year = TEST_YEAR - 1900, // Adjust for tm_year + .mon = TEST_MONTH - 1, // Adjust for tm_mon + .day = TEST_DAY, }; // Simulate the set time in the system @@ -153,11 +153,8 @@ void test_zwave_command_class_date_get() void test_zwave_command_class_time_get() { // Prepare the expected date_time_t structure - date_time_t expected_time = { - .hour = TEST_HOUR & 0xF, - .min = TEST_MIN, - .sec = TEST_SEC - }; + date_time_t expected_time + = {.hour = TEST_HOUR & 0xF, .min = TEST_MIN, .sec = TEST_SEC}; // Simulate the set time in the system platform_set_date_time(&expected_time); diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_user_code_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_user_code_test.c index 4c566702a..e8bc79f1e 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_user_code_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_user_code_test.c @@ -56,10 +56,10 @@ static attribute_resolver_function_t user_code_set = NULL; static zpc_resolver_event_notification_function_t on_delete_all_send_data_complete = NULL; -static zwave_command_handler_t handler = {}; +static zwave_command_handler_t handler = {}; static zwave_controller_connection_info_t info = {}; -static uint8_t received_frame[255] = {}; -static uint16_t received_frame_size = 0; +static uint8_t received_frame[255] = {}; +static uint16_t received_frame_size = 0; #define KEY_BITMASK_SIZE 16 static const uint8_t V1_SUPPORTED_KEYS[KEY_BITMASK_SIZE] = {0x00, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_version_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_version_test.c index a9ac737e0..89e7cb943 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_version_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_version_test.c @@ -884,9 +884,9 @@ void test_zwave_command_class_version_command_class_report_happy_case() // Simulate an incoming report with version cc data zwave_cc_version_t received_version = 34; const uint8_t incoming_frame[] = {COMMAND_CLASS_VERSION_V3, - VERSION_COMMAND_CLASS_REPORT_V3, - COMMAND_CLASS_DOOR_LOCK, - received_version}; + VERSION_COMMAND_CLASS_REPORT_V3, + COMMAND_CLASS_DOOR_LOCK, + received_version}; TEST_ASSERT_EQUAL(SL_STATUS_NOT_SUPPORTED, version_handler.support_handler(&connection_info, diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_classes_utils_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_classes_utils_test.c index b40b3f603..17c8b9326 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_classes_utils_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_classes_utils_test.c @@ -582,11 +582,13 @@ void test_value_size_precision_extraction() TEST_ASSERT_EQUAL_UINT32(test_signed_value * 10, extracted_value); } -void test_zwave_temp_to_ucl_temperature() { +void test_zwave_temp_to_ucl_temperature() +{ int32_t current_temp = 25; for (int i = 0; i < 8; i++) { printf("Current Z-Wave precision : %d\n", i); - TEST_ASSERT_EQUAL(2500, zwave_temperature_to_ucl_temperature(current_temp, i, 0)); + TEST_ASSERT_EQUAL(2500, + zwave_temperature_to_ucl_temperature(current_temp, i, 0)); current_temp *= 10; } @@ -600,18 +602,16 @@ void test_zwave_temp_to_ucl_temperature() { TEST_ASSERT_EQUAL(2562, zwave_temperature_to_ucl_temperature(7812, 2, 1)); } - -void test_ucl_temp_to_zwave_temperature() { - +void test_ucl_temp_to_zwave_temperature() +{ TEST_ASSERT_EQUAL(7700, ucl_temperature_to_zwave_temperature(7700, 2, 0)); TEST_ASSERT_EQUAL(12410, ucl_temperature_to_zwave_temperature(1241, 3, 0)); TEST_ASSERT_EQUAL(781, ucl_temperature_to_zwave_temperature(7815, 1, 0)); - + // Convert F to C TEST_ASSERT_EQUAL(69, ucl_temperature_to_zwave_temperature(2111, 0, 1)); TEST_ASSERT_EQUAL(709, ucl_temperature_to_zwave_temperature(2166, 1, 1)); TEST_ASSERT_EQUAL(7098, ucl_temperature_to_zwave_temperature(2166, 2, 1)); TEST_ASSERT_EQUAL(7154, ucl_temperature_to_zwave_temperature(2197, 2, 1)); TEST_ASSERT_EQUAL(71540, ucl_temperature_to_zwave_temperature(2197, 3, 1)); - } \ No newline at end of file diff --git a/applications/zpc/components/zwave_command_handler/src/zwave_command_handler.cpp b/applications/zpc/components/zwave_command_handler/src/zwave_command_handler.cpp index a2f213b83..2f282d1c6 100644 --- a/applications/zpc/components/zwave_command_handler/src/zwave_command_handler.cpp +++ b/applications/zpc/components/zwave_command_handler/src/zwave_command_handler.cpp @@ -53,7 +53,8 @@ std::multiset static zwave_controller_callbacks_t zwave_command_handler_callbacks = { .on_new_network_entered = zwave_command_handler_on_new_network_entered, .on_application_frame_received = zwave_command_handler_on_frame_received, - .on_protocol_frame_received = zwave_command_handler_on_protocol_frame_received, + .on_protocol_frame_received + = zwave_command_handler_on_protocol_frame_received, }; /////////////////////////////////////////////////////////////////////////////// @@ -93,10 +94,11 @@ sl_status_t zwave_command_handler_dispatch( //Check if this frame is a multicast get if (connection->local.is_multicast) { - if( ZwaveCommandClassType::get_type(frame_data[0],frame_data[1]) == ZwaveCommandClassType::type_t::GET ) { - sl_log_debug(LOG_TAG,"Multicast get frame dropped"); - return SL_STATUS_NOT_SUPPORTED; - } + if (ZwaveCommandClassType::get_type(frame_data[0], frame_data[1]) + == ZwaveCommandClassType::type_t::GET) { + sl_log_debug(LOG_TAG, "Multicast get frame dropped"); + return SL_STATUS_NOT_SUPPORTED; + } } auto [it, end] = command_handler_list.equal_range(handler_to_invoke); diff --git a/applications/zpc/components/zwave_command_handler/src/zwave_command_handler_callbacks.cpp b/applications/zpc/components/zwave_command_handler/src/zwave_command_handler_callbacks.cpp index 995e94660..1ca63bd1b 100644 --- a/applications/zpc/components/zwave_command_handler/src/zwave_command_handler_callbacks.cpp +++ b/applications/zpc/components/zwave_command_handler/src/zwave_command_handler_callbacks.cpp @@ -296,9 +296,10 @@ void zwave_command_handler_on_protocol_frame_received( message << "]"; sl_log_debug(LOG_TAG, "%s", message.str().c_str()); - uint8_t decryption_key = zwave_controller_get_key_from_encapsulation(connection_info->encapsulation); + uint8_t decryption_key = zwave_controller_get_key_from_encapsulation( + connection_info->encapsulation); - // Dispatch and look at the status code + // Dispatch and look at the status code sl_status_t status = zwapi_transfer_protocol_cc(connection_info->remote.node_id, decryption_key, diff --git a/applications/zpc/components/zwave_smartstart_management/include/zwave_smartstart_management_fixt.h b/applications/zpc/components/zwave_smartstart_management/include/zwave_smartstart_management_fixt.h index 7219d4582..017dc2ea8 100644 --- a/applications/zpc/components/zwave_smartstart_management/include/zwave_smartstart_management_fixt.h +++ b/applications/zpc/components/zwave_smartstart_management/include/zwave_smartstart_management_fixt.h @@ -48,4 +48,3 @@ sl_status_t zwave_smartstart_management_setup_fixt(void); #endif //ZWAVE_SMARTSTART_MANAGEMENT_FIXT_H /** @} end zwave_smartstart_management_fixt */ - diff --git a/applications/zpc/components/zwave_smartstart_management/src/zwave_smartstart_management.cpp b/applications/zpc/components/zwave_smartstart_management/src/zwave_smartstart_management.cpp index 12f5e7d34..93cdf5703 100644 --- a/applications/zpc/components/zwave_smartstart_management/src/zwave_smartstart_management.cpp +++ b/applications/zpc/components/zwave_smartstart_management/src/zwave_smartstart_management.cpp @@ -572,12 +572,17 @@ bool find_dsk_obfuscated_bytes_from_smart_start_list(zwave_dsk_t dsk, dsk_internal)) { sl_log_debug(LOG_TAG, "Comparing\n"); sl_log_byte_arr(LOG_TAG, SL_LOG_DEBUG, dsk_internal, sizeof(zwave_dsk_t)) - sl_log_debug(LOG_TAG, "with sent: \n"); - sl_log_byte_arr(LOG_TAG, SL_LOG_DEBUG, dsk, sizeof(zwave_dsk_t)) - if (memcmp(dsk + obfuscated_bytes, - dsk_internal + obfuscated_bytes, - (sizeof(zwave_dsk_t) - obfuscated_bytes)) - == 0) { + sl_log_debug(LOG_TAG, "with sent: \n"); + sl_log_byte_arr( + LOG_TAG, + SL_LOG_DEBUG, + dsk, + sizeof( + zwave_dsk_t)) if (memcmp(dsk + obfuscated_bytes, + dsk_internal + obfuscated_bytes, + (sizeof(zwave_dsk_t) - obfuscated_bytes)) + == 0) + { memcpy(dsk, dsk_internal, obfuscated_bytes); return true; } diff --git a/applications/zpc/components/zwave_smartstart_management/test/zwave_smartstart_management_test.cpp b/applications/zpc/components/zwave_smartstart_management/test/zwave_smartstart_management_test.cpp index 557090e37..7cb2050ad 100644 --- a/applications/zpc/components/zwave_smartstart_management/test/zwave_smartstart_management_test.cpp +++ b/applications/zpc/components/zwave_smartstart_management/test/zwave_smartstart_management_test.cpp @@ -47,7 +47,7 @@ bool is_command_class_in_supported_list(zwave_command_class_t command_class, const uint8_t *nif, uint8_t nif_length) { - return false; + return false; } // clang-format off // Device 4 @@ -518,14 +518,46 @@ void test_zwave_smartstart_inclusion_all_dsk_already_in_network() Management::get_instance()->update_smartstart_cache(smartstart_list); } // Hex conversion of "11161-14532-28714-35861-02690-50097-47954-03920" - zwave_dsk_t dsk = {0x00, 0x00, 0x38, 0xC4, 0x70, 0x2A, 0x8C, 0x15, 0x0A, 0x82, 0xC3, 0xB1, 0xBB, 0x52, 0x0F, 0x50}; - - TEST_ASSERT_EQUAL(find_dsk_obfuscated_bytes_from_smart_start_list(dsk, 2), true); + zwave_dsk_t dsk = {0x00, + 0x00, + 0x38, + 0xC4, + 0x70, + 0x2A, + 0x8C, + 0x15, + 0x0A, + 0x82, + 0xC3, + 0xB1, + 0xBB, + 0x52, + 0x0F, + 0x50}; + + TEST_ASSERT_EQUAL(find_dsk_obfuscated_bytes_from_smart_start_list(dsk, 2), + true); TEST_ASSERT_EQUAL_CHAR(dsk[0], 0x2B); TEST_ASSERT_EQUAL_CHAR(dsk[1], 0x99); // Garbled DS VV - zwave_dsk_t gdsk = {0x00, 0x00, 0x00, 0xC4, 0x70, 0x2A, 0x8C, 0x15, 0x0A, 0x82, 0xC3, 0xB1, 0xBB, 0x52, 0x0F, 0x50}; - TEST_ASSERT_EQUAL(find_dsk_obfuscated_bytes_from_smart_start_list(gdsk, 2), false); + zwave_dsk_t gdsk = {0x00, + 0x00, + 0x00, + 0xC4, + 0x70, + 0x2A, + 0x8C, + 0x15, + 0x0A, + 0x82, + 0xC3, + 0xB1, + 0xBB, + 0x52, + 0x0F, + 0x50}; + TEST_ASSERT_EQUAL(find_dsk_obfuscated_bytes_from_smart_start_list(gdsk, 2), + false); TEST_ASSERT_EQUAL_CHAR(gdsk[0], 0x00); TEST_ASSERT_EQUAL_CHAR(gdsk[1], 0x00); } diff --git a/applications/zpc/main.c b/applications/zpc/main.c index 8ce055310..0c41e3e75 100644 --- a/applications/zpc/main.c +++ b/applications/zpc/main.c @@ -204,7 +204,6 @@ static uic_fixt_shutdown_step_t uic_fixt_shutdown_steps_list[] {&dotdot_mapper_teardown, "DotDot mapper"}, {NULL, "Terminator"}}; - int main(int argc, char **argv) { attribute_mapper_config_init(); //TODO how do we want to do this diff --git a/cmake/include/clang-format.cmake b/cmake/include/clang-format.cmake new file mode 100644 index 000000000..8b7ba88a6 --- /dev/null +++ b/cmake/include/clang-format.cmake @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: Silicon Laboratories Inc. +# SPDX-License-Identifier: ZLIB + +file(GLOB_RECURSE sources_list *.c *.cpp *.h *.hpp) +list(FILTER sources_list EXCLUDE REGEX ".git/.*") +list(FILTER sources_list EXCLUDE REGEX "${CMAKE_BINARY_DIR}/.*") +list(FILTER sources_list EXCLUDE REGEX ".*/ZW_classcmd.h") +if(NOT ENV{uncrustify_args}) + set(uncrustify_args --replace) +endif() + +string(REPLACE ";" "\n" sources_list_text "${sources_list}" ) +file(WRITE "${CMAKE_BINARY_DIR}/sources.lst" ${sources_list_text}) + +add_custom_target(lint + COMMAND clang-format -i --files="${CMAKE_BINARY_DIR}/sources.lst" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + DEPENDS "${CMAKE_BINARY_DIR}/sources.lst" +) diff --git a/helper.mk b/helper.mk index 746ddf4e3..74c9ca3b3 100755 --- a/helper.mk +++ b/helper.mk @@ -30,6 +30,7 @@ export CMAKE_GENERATOR build_dir?=build sudo?=sudo +cmake?=cmake debian_codename?=bookworm @@ -40,6 +41,7 @@ packages+=python3-defusedxml # For extract_get.py # TODO: remove for offline build packages+=curl wget python3-pip packages+=expect +packages+=clang-format # For docs packages+=graphviz @@ -231,6 +233,10 @@ all: ${build_dir}/CMakeCache.txt # cmake --build ${ - /** * @defgroup unify_definitions Unify definitions * @ingroup unify_components * @brief Type definitions and macros for Unify components and applications. */ - /** * @defgroup unify_sl_status_codes Status Codes * @ingroup unify_definitions @@ -46,91 +44,143 @@ *************************** GENERIC ERRORS ******************************** ******************************************************************************/ -#define SL_STATUS_OK ((sl_status_t)0x0000) ///< No error. -#define SL_STATUS_FAIL ((sl_status_t)0x0001) ///< Generic error. +#define SL_STATUS_OK ((sl_status_t)0x0000) ///< No error. +#define SL_STATUS_FAIL ((sl_status_t)0x0001) ///< Generic error. // State Errors -#define SL_STATUS_INVALID_STATE ((sl_status_t)0x0002) ///< Generic invalid state error. -#define SL_STATUS_NOT_READY ((sl_status_t)0x0003) ///< Module is not ready for requested operation. -#define SL_STATUS_BUSY ((sl_status_t)0x0004) ///< Module is busy and cannot carry out requested operation. -#define SL_STATUS_IN_PROGRESS ((sl_status_t)0x0005) ///< Operation is in progress and not yet complete (pass or fail). -#define SL_STATUS_ABORT ((sl_status_t)0x0006) ///< Operation aborted. -#define SL_STATUS_TIMEOUT ((sl_status_t)0x0007) ///< Operation timed out. -#define SL_STATUS_PERMISSION ((sl_status_t)0x0008) ///< Operation not allowed per permissions. -#define SL_STATUS_WOULD_BLOCK ((sl_status_t)0x0009) ///< Non-blocking operation would block. -#define SL_STATUS_IDLE ((sl_status_t)0x000A) ///< Operation/module is Idle, cannot carry requested operation. -#define SL_STATUS_IS_WAITING ((sl_status_t)0x000B) ///< Operation cannot be done while construct is waiting. -#define SL_STATUS_NONE_WAITING ((sl_status_t)0x000C) ///< No task/construct waiting/pending for that action/event. -#define SL_STATUS_SUSPENDED ((sl_status_t)0x000D) ///< Operation cannot be done while construct is suspended. -#define SL_STATUS_NOT_AVAILABLE ((sl_status_t)0x000E) ///< Feature not available due to software configuration. -#define SL_STATUS_NOT_SUPPORTED ((sl_status_t)0x000F) ///< Feature not supported. -#define SL_STATUS_INITIALIZATION ((sl_status_t)0x0010) ///< Initialization failed. -#define SL_STATUS_NOT_INITIALIZED ((sl_status_t)0x0011) ///< Module has not been initialized. -#define SL_STATUS_ALREADY_INITIALIZED ((sl_status_t)0x0012) ///< Module has already been initialized. -#define SL_STATUS_DELETED ((sl_status_t)0x0013) ///< Object/construct has been deleted. -#define SL_STATUS_ISR ((sl_status_t)0x0014) ///< Illegal call from ISR. -#define SL_STATUS_NETWORK_UP ((sl_status_t)0x0015) ///< Illegal call because network is up. -#define SL_STATUS_NETWORK_DOWN ((sl_status_t)0x0016) ///< Illegal call because network is down. -#define SL_STATUS_NOT_JOINED ((sl_status_t)0x0017) ///< Failure due to not being joined in a network. -#define SL_STATUS_NO_BEACONS ((sl_status_t)0x0018) ///< Invalid operation as there are no beacons. +#define SL_STATUS_INVALID_STATE \ + ((sl_status_t)0x0002) ///< Generic invalid state error. +#define SL_STATUS_NOT_READY \ + ((sl_status_t)0x0003) ///< Module is not ready for requested operation. +#define SL_STATUS_BUSY \ + ((sl_status_t)0x0004) ///< Module is busy and cannot carry out requested operation. +#define SL_STATUS_IN_PROGRESS \ + ((sl_status_t)0x0005) ///< Operation is in progress and not yet complete (pass or fail). +#define SL_STATUS_ABORT ((sl_status_t)0x0006) ///< Operation aborted. +#define SL_STATUS_TIMEOUT ((sl_status_t)0x0007) ///< Operation timed out. +#define SL_STATUS_PERMISSION \ + ((sl_status_t)0x0008) ///< Operation not allowed per permissions. +#define SL_STATUS_WOULD_BLOCK \ + ((sl_status_t)0x0009) ///< Non-blocking operation would block. +#define SL_STATUS_IDLE \ + ((sl_status_t)0x000A) ///< Operation/module is Idle, cannot carry requested operation. +#define SL_STATUS_IS_WAITING \ + ((sl_status_t)0x000B) ///< Operation cannot be done while construct is waiting. +#define SL_STATUS_NONE_WAITING \ + ((sl_status_t)0x000C) ///< No task/construct waiting/pending for that action/event. +#define SL_STATUS_SUSPENDED \ + ((sl_status_t)0x000D) ///< Operation cannot be done while construct is suspended. +#define SL_STATUS_NOT_AVAILABLE \ + ((sl_status_t)0x000E) ///< Feature not available due to software configuration. +#define SL_STATUS_NOT_SUPPORTED \ + ((sl_status_t)0x000F) ///< Feature not supported. +#define SL_STATUS_INITIALIZATION \ + ((sl_status_t)0x0010) ///< Initialization failed. +#define SL_STATUS_NOT_INITIALIZED \ + ((sl_status_t)0x0011) ///< Module has not been initialized. +#define SL_STATUS_ALREADY_INITIALIZED \ + ((sl_status_t)0x0012) ///< Module has already been initialized. +#define SL_STATUS_DELETED \ + ((sl_status_t)0x0013) ///< Object/construct has been deleted. +#define SL_STATUS_ISR ((sl_status_t)0x0014) ///< Illegal call from ISR. +#define SL_STATUS_NETWORK_UP \ + ((sl_status_t)0x0015) ///< Illegal call because network is up. +#define SL_STATUS_NETWORK_DOWN \ + ((sl_status_t)0x0016) ///< Illegal call because network is down. +#define SL_STATUS_NOT_JOINED \ + ((sl_status_t)0x0017) ///< Failure due to not being joined in a network. +#define SL_STATUS_NO_BEACONS \ + ((sl_status_t)0x0018) ///< Invalid operation as there are no beacons. // Allocation/ownership Errors -#define SL_STATUS_ALLOCATION_FAILED ((sl_status_t)0x0019) ///< Generic allocation error. -#define SL_STATUS_NO_MORE_RESOURCE ((sl_status_t)0x001A) ///< No more resource available to perform the operation. -#define SL_STATUS_EMPTY ((sl_status_t)0x001B) ///< Item/list/queue is empty. -#define SL_STATUS_FULL ((sl_status_t)0x001C) ///< Item/list/queue is full. -#define SL_STATUS_WOULD_OVERFLOW ((sl_status_t)0x001D) ///< Item would overflow. -#define SL_STATUS_HAS_OVERFLOWED ((sl_status_t)0x001E) ///< Item/list/queue has been overflowed. -#define SL_STATUS_OWNERSHIP ((sl_status_t)0x001F) ///< Generic ownership error. -#define SL_STATUS_IS_OWNER ((sl_status_t)0x0020) ///< Already/still owning resource. +#define SL_STATUS_ALLOCATION_FAILED \ + ((sl_status_t)0x0019) ///< Generic allocation error. +#define SL_STATUS_NO_MORE_RESOURCE \ + ((sl_status_t)0x001A) ///< No more resource available to perform the operation. +#define SL_STATUS_EMPTY ((sl_status_t)0x001B) ///< Item/list/queue is empty. +#define SL_STATUS_FULL ((sl_status_t)0x001C) ///< Item/list/queue is full. +#define SL_STATUS_WOULD_OVERFLOW \ + ((sl_status_t)0x001D) ///< Item would overflow. +#define SL_STATUS_HAS_OVERFLOWED \ + ((sl_status_t)0x001E) ///< Item/list/queue has been overflowed. +#define SL_STATUS_OWNERSHIP ((sl_status_t)0x001F) ///< Generic ownership error. +#define SL_STATUS_IS_OWNER \ + ((sl_status_t)0x0020) ///< Already/still owning resource. // Invalid Parameters Errors -#define SL_STATUS_INVALID_PARAMETER ((sl_status_t)0x0021) ///< Generic invalid argument or consequence of invalid argument. -#define SL_STATUS_NULL_POINTER ((sl_status_t)0x0022) ///< Invalid null pointer received as argument. -#define SL_STATUS_INVALID_CONFIGURATION ((sl_status_t)0x0023) ///< Invalid configuration provided. -#define SL_STATUS_INVALID_MODE ((sl_status_t)0x0024) ///< Invalid mode. -#define SL_STATUS_INVALID_HANDLE ((sl_status_t)0x0025) ///< Invalid handle. -#define SL_STATUS_INVALID_TYPE ((sl_status_t)0x0026) ///< Invalid type for operation. -#define SL_STATUS_INVALID_INDEX ((sl_status_t)0x0027) ///< Invalid index. -#define SL_STATUS_INVALID_RANGE ((sl_status_t)0x0028) ///< Invalid range. -#define SL_STATUS_INVALID_KEY ((sl_status_t)0x0029) ///< Invalid key. -#define SL_STATUS_INVALID_CREDENTIALS ((sl_status_t)0x002A) ///< Invalid credentials. -#define SL_STATUS_INVALID_COUNT ((sl_status_t)0x002B) ///< Invalid count. -#define SL_STATUS_INVALID_SIGNATURE ((sl_status_t)0x002C) ///< Invalid signature / verification failed. -#define SL_STATUS_NOT_FOUND ((sl_status_t)0x002D) ///< Item could not be found. -#define SL_STATUS_ALREADY_EXISTS ((sl_status_t)0x002E) ///< Item already exists. +#define SL_STATUS_INVALID_PARAMETER \ + ((sl_status_t)0x0021) ///< Generic invalid argument or consequence of invalid argument. +#define SL_STATUS_NULL_POINTER \ + ((sl_status_t)0x0022) ///< Invalid null pointer received as argument. +#define SL_STATUS_INVALID_CONFIGURATION \ + ((sl_status_t)0x0023) ///< Invalid configuration provided. +#define SL_STATUS_INVALID_MODE ((sl_status_t)0x0024) ///< Invalid mode. +#define SL_STATUS_INVALID_HANDLE ((sl_status_t)0x0025) ///< Invalid handle. +#define SL_STATUS_INVALID_TYPE \ + ((sl_status_t)0x0026) ///< Invalid type for operation. +#define SL_STATUS_INVALID_INDEX ((sl_status_t)0x0027) ///< Invalid index. +#define SL_STATUS_INVALID_RANGE ((sl_status_t)0x0028) ///< Invalid range. +#define SL_STATUS_INVALID_KEY ((sl_status_t)0x0029) ///< Invalid key. +#define SL_STATUS_INVALID_CREDENTIALS \ + ((sl_status_t)0x002A) ///< Invalid credentials. +#define SL_STATUS_INVALID_COUNT ((sl_status_t)0x002B) ///< Invalid count. +#define SL_STATUS_INVALID_SIGNATURE \ + ((sl_status_t)0x002C) ///< Invalid signature / verification failed. +#define SL_STATUS_NOT_FOUND ((sl_status_t)0x002D) ///< Item could not be found. +#define SL_STATUS_ALREADY_EXISTS \ + ((sl_status_t)0x002E) ///< Item already exists. // IO/Communication Errors -#define SL_STATUS_IO ((sl_status_t)0x002F) ///< Generic I/O failure. -#define SL_STATUS_IO_TIMEOUT ((sl_status_t)0x0030) ///< I/O failure due to timeout. -#define SL_STATUS_TRANSMIT ((sl_status_t)0x0031) ///< Generic transmission error. -#define SL_STATUS_TRANSMIT_UNDERFLOW ((sl_status_t)0x0032) ///< Transmit underflowed. -#define SL_STATUS_TRANSMIT_INCOMPLETE ((sl_status_t)0x0033) ///< Transmit is incomplete. -#define SL_STATUS_TRANSMIT_BUSY ((sl_status_t)0x0034) ///< Transmit is busy. -#define SL_STATUS_RECEIVE ((sl_status_t)0x0035) ///< Generic reception error. -#define SL_STATUS_OBJECT_READ ((sl_status_t)0x0036) ///< Failed to read on/via given object. -#define SL_STATUS_OBJECT_WRITE ((sl_status_t)0x0037) ///< Failed to write on/via given object. -#define SL_STATUS_MESSAGE_TOO_LONG ((sl_status_t)0x0038) ///< Message is too long. +#define SL_STATUS_IO ((sl_status_t)0x002F) ///< Generic I/O failure. +#define SL_STATUS_IO_TIMEOUT \ + ((sl_status_t)0x0030) ///< I/O failure due to timeout. +#define SL_STATUS_TRANSMIT \ + ((sl_status_t)0x0031) ///< Generic transmission error. +#define SL_STATUS_TRANSMIT_UNDERFLOW \ + ((sl_status_t)0x0032) ///< Transmit underflowed. +#define SL_STATUS_TRANSMIT_INCOMPLETE \ + ((sl_status_t)0x0033) ///< Transmit is incomplete. +#define SL_STATUS_TRANSMIT_BUSY ((sl_status_t)0x0034) ///< Transmit is busy. +#define SL_STATUS_RECEIVE ((sl_status_t)0x0035) ///< Generic reception error. +#define SL_STATUS_OBJECT_READ \ + ((sl_status_t)0x0036) ///< Failed to read on/via given object. +#define SL_STATUS_OBJECT_WRITE \ + ((sl_status_t)0x0037) ///< Failed to write on/via given object. +#define SL_STATUS_MESSAGE_TOO_LONG \ + ((sl_status_t)0x0038) ///< Message is too long. // ANSI C/POSIX codes -#define SL_STATUS_ERRNO ((sl_status_t)0x0101) ///< System error: errno is set and strerror can be used to fetch the error-message. +#define SL_STATUS_ERRNO \ + ((sl_status_t)0x0101) ///< System error: errno is set and strerror can be used to fetch the error-message. // Net-MQTT status codes -#define SL_STATUS_NET_MQTT_NO_CONN ((sl_status_t)0x0841) ///< Not connected to a broker. -#define SL_STATUS_NET_MQTT_LOST_CONN ((sl_status_t)0x0842) ///< Connection to broker lost. -#define SL_STATUS_NET_MQTT_PROTOCOL ((sl_status_t)0x0843) ///< Protocol error. -#define SL_STATUS_NET_MQTT_TLS_HANDSHAKE ((sl_status_t)0x0844) ///< TLS negotiation failed. -#define SL_STATUS_NET_MQTT_PAYLOAD_SIZE ((sl_status_t)0x0845) ///< Payload size is too large. -#define SL_STATUS_NET_MQTT_NOT_SUPPORTED ((sl_status_t)0x0846) ///< MQTTv5 properties are set but client is not using MQTTv5. -#define SL_STATUS_NET_MQTT_AUTH ((sl_status_t)0x0847) ///< Authentication failed. -#define SL_STATUS_NET_MQTT_ACL_DENIED ((sl_status_t)0x0848) ///< Access control list deny. -#define SL_STATUS_NET_MQTT_MALFORMED_UTF8 ((sl_status_t)0x0849) ///< Malformed UTF-8 string in the specified MQTT-topic. -#define SL_STATUS_NET_MQTT_DUPLICATE_PROPERTY ((sl_status_t)0x084A) ///< An MQTTv5 property is duplicated where it is forbidden. -#define SL_STATUS_NET_MQTT_QOS_NOT_SUPPORTED ((sl_status_t)0x084B) ///< The requested QoS level is not supported by the broker. -#define SL_STATUS_NET_MQTT_OVERSIZE_PACKET ((sl_status_t)0x084C) ///< Resulting packet will become larger than the broker supports. +#define SL_STATUS_NET_MQTT_NO_CONN \ + ((sl_status_t)0x0841) ///< Not connected to a broker. +#define SL_STATUS_NET_MQTT_LOST_CONN \ + ((sl_status_t)0x0842) ///< Connection to broker lost. +#define SL_STATUS_NET_MQTT_PROTOCOL ((sl_status_t)0x0843) ///< Protocol error. +#define SL_STATUS_NET_MQTT_TLS_HANDSHAKE \ + ((sl_status_t)0x0844) ///< TLS negotiation failed. +#define SL_STATUS_NET_MQTT_PAYLOAD_SIZE \ + ((sl_status_t)0x0845) ///< Payload size is too large. +#define SL_STATUS_NET_MQTT_NOT_SUPPORTED \ + ((sl_status_t)0x0846) ///< MQTTv5 properties are set but client is not using MQTTv5. +#define SL_STATUS_NET_MQTT_AUTH \ + ((sl_status_t)0x0847) ///< Authentication failed. +#define SL_STATUS_NET_MQTT_ACL_DENIED \ + ((sl_status_t)0x0848) ///< Access control list deny. +#define SL_STATUS_NET_MQTT_MALFORMED_UTF8 \ + ((sl_status_t)0x0849) ///< Malformed UTF-8 string in the specified MQTT-topic. +#define SL_STATUS_NET_MQTT_DUPLICATE_PROPERTY \ + ((sl_status_t)0x084A) ///< An MQTTv5 property is duplicated where it is forbidden. +#define SL_STATUS_NET_MQTT_QOS_NOT_SUPPORTED \ + ((sl_status_t)0x084B) ///< The requested QoS level is not supported by the broker. +#define SL_STATUS_NET_MQTT_OVERSIZE_PACKET \ + ((sl_status_t)0x084C) ///< Resulting packet will become larger than the broker supports. // Other codes -#define SL_STATUS_PRINT_INFO_MESSAGE ((sl_status_t)0x0900) ///< Only information message should be printed, without starting an application +#define SL_STATUS_PRINT_INFO_MESSAGE \ + ((sl_status_t)0x0900) ///< Only information message should be printed, without starting an application /* ******************************** DATA TYPES ******************************* diff --git a/include/uic_enum.h b/include/uic_enum.h index 6e5629e46..dbf51f209 100644 --- a/include/uic_enum.h +++ b/include/uic_enum.h @@ -36,7 +36,7 @@ * my_type_enum y; //<< this will be of enum type */ #define UIC_ENUM(name, type) \ - name_enum; \ + name_enum; \ typedef type name /**