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 c4fe14b8e4..84324704e9 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_supports_command_class(COMMAND_CLASS_SUPERVISION, - node_id, + = zwave_node_want_supervision_frame(node_id, endpoint_id); // Node details validation. can this node be part of a multicast? 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 1af14d1b78..cd390123da 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 @@ -83,8 +83,7 @@ sl_status_t attribute_resolver_send(attribute_store_node_t node, zwave_tx_session_id_t tx_session_id = NULL; if (is_set == true && true - == zwave_node_supports_command_class(COMMAND_CLASS_SUPERVISION, - node_id, + == zwave_node_want_supervision_frame(node_id, endpoint_id)) { // Send with Supervision send_status = zwave_command_class_supervision_send_data( 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 8bd48a76d7..d3dece4d2f 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 @@ -352,8 +352,7 @@ void test_zpc_attribute_resolver_send_send_status_fail_with_supervision() zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_2); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_2, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_2, zwave_endpoint_id_2, true); @@ -426,8 +425,7 @@ void test_zpc_attribute_resolver_send_set_no_supervision_happy_case() zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_1); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, false); @@ -508,8 +506,7 @@ void test_zpc_attribute_resolver_send_set_supervision_working_happy_case() zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_1); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, true); @@ -617,11 +614,9 @@ void test_zpc_attribute_resolver_group_2_nodes_happy_case() attribute_store_get_node_type_ExpectAndReturn(test_node_2, test_node_2_type); attribute_resolver_set_function_ExpectAndReturn(test_node_2_type, &rule_function_stub); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_2, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_2, zwave_endpoint_id_1, true); - // assigning test_node_1 in a multicast pool is_node_or_parent_paused_ExpectAndReturn(test_node_1, false); attribute_store_is_value_defined_ExpectAndReturn(test_node_1, @@ -647,8 +642,7 @@ void test_zpc_attribute_resolver_group_2_nodes_happy_case() attribute_store_get_node_type_ExpectAndReturn(test_node_1, test_node_1_type); attribute_resolver_set_function_ExpectAndReturn(test_node_1_type, &rule_function_stub); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, true); @@ -857,8 +851,7 @@ void test_zpc_attribute_resolver_group_unknown_protocol() attribute_store_get_node_type_ExpectAndReturn(test_node_1, test_node_1_type); attribute_resolver_set_function_ExpectAndReturn(test_node_1_type, &rule_function_stub); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, true); @@ -889,9 +882,7 @@ void test_zpc_attribute_resolver_group_unknown_protocol() NULL); zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_1); - - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, false); @@ -988,8 +979,7 @@ void test_zpc_attribute_resolver_group_no_reported_value() attribute_store_get_node_type_ExpectAndReturn(test_node_1, test_node_1_type); attribute_resolver_set_function_ExpectAndReturn(test_node_1_type, &rule_function_stub); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, true); @@ -1021,8 +1011,7 @@ void test_zpc_attribute_resolver_group_no_reported_value() zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_1); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, false); @@ -1105,8 +1094,7 @@ void test_zpc_attribute_resolver_register_custom_handler() zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_1); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, false); @@ -1196,8 +1184,7 @@ void test_zpc_attribute_resolver_send_set_abort_pending() zwave_tx_scheme_get_node_tx_options_IgnoreArg_tx_options(); zwave_tx_scheme_get_node_tx_options_ReturnThruPtr_tx_options(&tx_options_1); - zwave_node_supports_command_class_ExpectAndReturn(0x6C, - zwave_node_id_1, + zwave_node_want_supervision_frame_ExpectAndReturn(zwave_node_id_1, zwave_endpoint_id_1, true); 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 78ca2909e5..107221cd01 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 @@ -650,6 +650,9 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_V1_ALARM_LEVEL, DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SUPERVISION_VERSION, ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_SUPERVISION)) +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, + ((COMMAND_CLASS_SUPERVISION << 8) | 0x02)) + ///////////////////////////////////////////////// // Thermostat Mode Command Class DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_THERMOSTAT_MODE_VERSION, 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 719d049a25..9ced078b4d 100644 --- a/applications/zpc/components/zpc_attribute_store/include/zwave_utils.h +++ b/applications/zpc/components/zpc_attribute_store/include/zwave_utils.h @@ -122,6 +122,20 @@ bool zwave_node_supports_command_class(zwave_command_class_t command_class, zwave_node_id_t node_id, zwave_endpoint_id_t endpoint_id); +/** + * @brief Verify whether a node/endpoint supports Supervision CC + * AND wants to use it. + * + * @param node_id The NodeID to verify for support. + * @param endpoint_id The Endpoint to verify for support. + + * @returns + * - true if the node/endpoint supports the Supervision CC + has the enabled supervision flag (or if the flag is not defined) + * - false otherwise + */ +bool zwave_node_want_supervision_frame(zwave_node_id_t node_id, + zwave_endpoint_id_t endpoint_id); + /** * @brief Return the version of a Command Class implemented by a node. * diff --git a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp index 774ba2882d..a7074d618c 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp +++ b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp @@ -306,6 +306,8 @@ static const std::vector attribute_schema = { // Supervision Command Class attributes ///////////////////////////////////////////////////////////////////// {ATTRIBUTE_COMMAND_CLASS_SUPERVISION_VERSION, "Supervision Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, "Supervision Enabled flag", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + ///////////////////////////////////////////////////////////////////// // Wake Up Command Class attributes ///////////////////////////////////////////////////////////////////// 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 9ce3485caf..16facce5ef 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zwave_utils.c +++ b/applications/zpc/components/zpc_attribute_store/src/zwave_utils.c @@ -160,6 +160,41 @@ sl_status_t zwave_get_node_granted_keys(zwave_node_id_t node_id, sizeof(zwave_keyset_t)); } +bool zwave_node_want_supervision_frame(zwave_node_id_t node_id, + zwave_endpoint_id_t endpoint_id) +{ + // First we check if node supports supervision + if (!zwave_node_supports_command_class(COMMAND_CLASS_SUPERVISION, + node_id, + endpoint_id)) { + return false; + } + + // If it is, we check if the supervision flag is set + + // Find out the UNID of the node + unid_t unid; + zwave_unid_from_node_id(node_id, unid); + + attribute_store_node_t endpoint_node + = attribute_store_network_helper_get_endpoint_node(unid, endpoint_id); + + uint8_t supervision_flag; + sl_status_t result = attribute_store_get_child_reported( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, + &supervision_flag, + sizeof(supervision_flag)); + + // If enabled attribute is not defined we send a supervision frame anyway + // This behavior can be changed in future release, but for now we try to enable supervision frame by default to maintain compatibility with previous versions + if (result != SL_STATUS_OK) { + return true; + } + + return (supervision_flag == 1); +} + bool zwave_node_supports_command_class(zwave_command_class_t command_class, zwave_node_id_t node_id, zwave_endpoint_id_t endpoint_id) 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 e7efe75465..df875170f2 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 @@ -1023,4 +1023,125 @@ void test_is_command_in_array() is_command_in_array(0x01, 0x02, command_list_4, sizeof(command_list_4))); TEST_ASSERT_TRUE( 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( + test_unid, + test_endpoint_id, + test_endpoint_node); + + attribute_store_get_node_child_by_type_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_ZWAVE_NIF, + 0, + test_non_secure_nif_node); + + attribute_store_get_node_attribute_value_ExpectAndReturn( + test_non_secure_nif_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( + test_nif, + (uint8_t)sizeof(test_nif)); + attribute_store_get_node_attribute_value_ReturnThruPtr_value_size( + &test_nif_length); + is_command_class_in_supported_list_ExpectAndReturn(COMMAND_CLASS_SUPERVISION, + test_nif, + test_nif_length, + 1); +} + +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(); + + attribute_store_network_helper_get_endpoint_node_IgnoreAndReturn(0); + // Set child reported to SL_STATUS_FAIL so we can simulate no flag + attribute_store_get_child_reported_IgnoreAndReturn(SL_STATUS_FAIL); + TEST_ASSERT_TRUE( + zwave_node_want_supervision_frame(test_node_id, test_endpoint_id)); +} + +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); + attribute_store_get_child_reported_ExpectAndReturn( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, + NULL, + sizeof(supervision_flag), + SL_STATUS_OK); + attribute_store_get_child_reported_IgnoreArg_value(); + attribute_store_get_child_reported_ReturnThruPtr_value(&supervision_flag); + + TEST_ASSERT_TRUE( + zwave_node_want_supervision_frame(test_node_id, test_endpoint_id)); +} + +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); + attribute_store_get_child_reported_ExpectAndReturn( + endpoint_node, + ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, + NULL, + sizeof(supervision_flag), + SL_STATUS_OK); + attribute_store_get_child_reported_IgnoreArg_value(); + attribute_store_get_child_reported_ReturnThruPtr_value(&supervision_flag); + + TEST_ASSERT_FALSE( + 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( + test_unid, + test_endpoint_id, + test_endpoint_node); + + attribute_store_get_node_child_by_type_ExpectAndReturn( + test_endpoint_node, + ATTRIBUTE_ZWAVE_NIF, + 0, + test_non_secure_nif_node); + + attribute_store_get_node_attribute_value_ExpectAndReturn( + test_non_secure_nif_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( + test_nif, + (uint8_t)sizeof(test_nif)); + attribute_store_get_node_attribute_value_ReturnThruPtr_value_size( + &test_nif_length); + is_command_class_in_supported_list_ExpectAndReturn(COMMAND_CLASS_SUPERVISION, + test_nif, + test_nif_length, + false); + 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)); } \ No newline at end of file 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 673723d579..cb98ea4345 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 @@ -21,6 +21,10 @@ // Interface includes #include "zwave_command_class_wake_up_types.h" +// Attribute store helpers +#include "attribute_store_defined_attribute_types.h" +#include "attribute_store_helper.h" + // Includes from other components #include "sl_log.h" #include "attribute_store.h" @@ -349,6 +353,36 @@ void zwave_command_class_supervision_on_send_data_complete( memcpy(&ongoing_session->tx_info, tx_info, sizeof(zwapi_tx_report_t)); } +static void zwave_command_class_supervision_on_version_attribute_update( + attribute_store_node_t updated_node, attribute_store_change_t change) +{ + if (change == ATTRIBUTE_DELETED) { + return; + } + + zwave_cc_version_t version = 0; + attribute_store_get_reported(updated_node, &version, sizeof(version)); + + if (version == 0) { + return; + } + + attribute_store_node_t endpoint_node + = attribute_store_get_first_parent_with_type(updated_node, + ATTRIBUTE_ENDPOINT_ID); + + attribute_store_node_t supervision_version_node + = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED, + endpoint_node); + + // By default the supervision is enabled + // This can be changed in the future, we enable it by default to keep compatibility with previous versions + uint8_t supervision_enabled_flag = 1; + attribute_store_set_reported(supervision_version_node, + &supervision_enabled_flag, + sizeof(supervision_enabled_flag)); +} + /////////////////////////////////////////////////////////////////////////////// // Init function /////////////////////////////////////////////////////////////////////////////// @@ -360,6 +394,10 @@ sl_status_t zwave_command_class_supervision_init() // Clean up our "Wake on demand" list memset(wake_on_demand_list, 0, sizeof(zwave_nodemask_t)); + attribute_store_register_callback_by_type( + &zwave_command_class_supervision_on_version_attribute_update, + ATTRIBUTE_COMMAND_CLASS_SUPERVISION_VERSION); + // Register Supervision CC handler to the Z-Wave CC framework zwave_command_handler_t handler = {}; handler.support_handler = &zwave_command_class_supervision_support_handler; diff --git a/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt b/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt index 4d72dfb0ef..01487c4463 100644 --- a/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt +++ b/applications/zpc/components/zwave_command_classes/test/CMakeLists.txt @@ -116,6 +116,21 @@ target_add_unittest( zwave_tx_groups ${MOCK_LIBS}) +target_add_unittest( + zwave_command_classes + NAME + zwave_command_class_supervision_test_no_mock + SOURCES + zwave_command_class_supervision_test_no_mock.c + DEPENDS + zpc_attribute_store_test_helper + zwave_controller + zwave_command_handler_mock + uic_attribute_resolver_mock + zpc_attribute_resolver_mock + uic_dotdot_mqtt_mock +) + # Wake Up Command Class target_add_unittest( zwave_command_classes diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test.c index 2f8bc885b2..639441d702 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test.c @@ -175,6 +175,9 @@ void setUp() // Handler registration zwave_command_handler_register_handler_Stub( &zwave_command_handler_register_handler_stub); + + attribute_store_register_callback_by_type_IgnoreAndReturn(SL_STATUS_OK); + zwave_command_class_supervision_init(); // get through the init event and get a non-zero clock contiki_test_helper_run(10); 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 new file mode 100644 index 0000000000..146a008727 --- /dev/null +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_supervision_test_no_mock.c @@ -0,0 +1,114 @@ +#include "zwave_command_class_supervision.h" +#include "zwave_command_classes_utils.h" +#include "unity.h" + +// Generic includes +#include + +// Includes from other components +#include "datastore.h" +#include "attribute_store.h" +#include "attribute_store_helper.h" +#include "attribute_store_fixt.h" +#include "zpc_attribute_store_type_registration.h" + +// Interface includes +#include "attribute_store_defined_attribute_types.h" +#include "ZW_classcmd.h" +#include "zwave_utils.h" +#include "zwave_controller_types.h" + +// Test helpers +#include "zpc_attribute_store_test_helper.h" + +// Mock includes +#include "attribute_resolver_mock.h" +#include "zpc_attribute_resolver_mock.h" +#include "zwave_command_handler_mock.h" +#include "dotdot_mqtt_mock.h" +#include "dotdot_mqtt_generated_commands_mock.h" + +// Private variables +static zwave_command_handler_t handler = {}; + +// 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) +{ + handler = new_command_class_handler; + + TEST_ASSERT_EQUAL(ZWAVE_CONTROLLER_ENCAPSULATION_NONE, + handler.minimal_scheme); + TEST_ASSERT_EQUAL(COMMAND_CLASS_SUPERVISION, handler.command_class); + TEST_ASSERT_EQUAL(2, handler.version); + TEST_ASSERT_NOT_NULL(handler.control_handler); + TEST_ASSERT_NOT_NULL(handler.support_handler); + TEST_ASSERT_FALSE(handler.manual_security_validation); + + return SL_STATUS_OK; +} + +/// Setup the test suite (called once before all test_xxx functions are called) +void suiteSetUp() +{ + datastore_init(":memory:"); + attribute_store_init(); + zpc_attribute_store_register_known_attribute_types(); +} + +/// Teardown the test suite (called once after all test_xxx functions are called) +int suiteTearDown(int num_failures) +{ + attribute_store_teardown(); + datastore_teardown(); + return num_failures; +} + +/// Called before each and every test +void setUp() +{ + zpc_attribute_store_test_helper_create_network(); + + 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()); +} + +/// 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() +{ + // Flag not present + attribute_store_node_t supervision_flag_node + = attribute_store_get_first_child_by_type( + endpoint_id_node, + ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED); + + TEST_ASSERT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, supervision_flag_node); + + // Add it on creation + attribute_store_node_t version_node + = attribute_store_add_node(ATTRIBUTE_COMMAND_CLASS_SUPERVISION_VERSION, + endpoint_id_node); + + zwave_cc_version_t version = 2; + attribute_store_set_reported(version_node, &version, sizeof(version)); + + // Check flag node + supervision_flag_node = attribute_store_get_first_child_by_type( + endpoint_id_node, + ATTRIBUTE_COMMAND_CLASS_SUPERVISION_ENABLED); + + TEST_ASSERT_NOT_EQUAL(ATTRIBUTE_STORE_INVALID_NODE, supervision_flag_node); + + uint8_t flag_value = 255; + + attribute_store_get_reported(supervision_flag_node, + &flag_value, + sizeof(flag_value)); + TEST_ASSERT_EQUAL(1, flag_value); +} \ No newline at end of file