@@ -608,6 +608,10 @@ sl_status_t zwave_command_class_user_credential_credential_handle_report(
608608 {credential_slot, DESIRED_ATTRIBUTE});
609609
610610 nodes.slot_node .delete_node ();
611+ sl_log_debug (LOG_TAG, " Cleaning temporary credential slot node : %d (credential type %d, user %d)" ,
612+ credential_slot,
613+ credential_type,
614+ user_id);
611615 };
612616
613617 // We should have a valid user id if we receive this report
@@ -746,18 +750,57 @@ sl_status_t zwave_command_class_user_credential_credential_handle_report(
746750 credential_slot_node.delete_node ();
747751 return SL_STATUS_OK;
748752 // Duplicate Credential : 0x02
749- case credential_report_type_t ::CREDENTIAL_DUPLICATE_ERROR:
753+ case credential_report_type_t ::CREDENTIAL_DUPLICATE_ERROR: {
750754 // Do nothing, the credential GET will clean up for us
751755 sl_log_warning (LOG_TAG,
752- " Duplicate Credential for user %d, credential type %d, "
753- " credential slot %d" ,
756+ " Duplicate Credential (Already present for user %d, "
757+ " credential type %d, "
758+ " credential slot %d)" ,
754759 user_id,
755760 credential_type,
756761 credential_slot);
757762
758- // This should contains the duplicated credential
759- clean_up_pending_credentials_slot_nodes ();
760- return SL_STATUS_OK;
763+ // So this is the fun part when we hunt down the faulty credential slot node
764+ parser.read_byte (); // We don't care about this one
765+ uint8_t cred_data_size = parser.read_byte ();
766+ auto duplicate_data
767+ = parser.read_sequential <std::vector<uint8_t >>(cred_data_size);
768+
769+ bool found_duplicate = false ;
770+ // We need to find the credential slot node that contains the same data
771+ for_each_credential_type_nodes (
772+ endpoint_node,
773+ [&](attribute_store::attribute &credential_type_node) {
774+ for (auto &credential_slot_node:
775+ credential_type_node.children (ATTRIBUTE (CREDENTIAL_SLOT))) {
776+ if (credential_slot_node.desired_exists ()) {
777+ auto current_data
778+ = credential_slot_node
779+ .child_by_type (ATTRIBUTE (CREDENTIAL_DATA))
780+ .get <std::vector<uint8_t >>(DESIRED_OR_REPORTED_ATTRIBUTE);
781+ if (current_data == duplicate_data) {
782+ sl_log_debug (
783+ LOG_TAG,
784+ " Found the faulty credential slot node : %d" ,
785+ credential_slot_node.desired <user_credential_slot_t >());
786+ credential_slot_node.delete_node ();
787+ found_duplicate = true ;
788+ return ;
789+ }
790+ }
791+ }
792+ },
793+ credential_type);
794+
795+ if (!found_duplicate) {
796+ // If we are here that means we din't find the duplicate data
797+ sl_log_error (LOG_TAG,
798+ " Couldn't find the duplicate credential slot node." );
799+ return SL_STATUS_FAIL;
800+ } else {
801+ return SL_STATUS_OK;
802+ }
803+ }
761804 case credential_report_type_t ::CREDENTIAL_MANUFACTURER_SECURITY_RULE:
762805 sl_log_warning (
763806 LOG_TAG,
@@ -808,6 +851,7 @@ sl_status_t zwave_command_class_user_credential_credential_handle_report(
808851 parser.read_byte_with_bitmask (
809852 {CREDENTIAL_REPORT_PROPERTIES1_CRB_BIT_MASK,
810853 credential_slot_node.emplace_node (ATTRIBUTE (CREDENTIAL_READ_BACK))});
854+
811855 uint8_t cred_data_size = parser.read_byte ();
812856 parser.read_sequential <std::vector<uint8_t >>(
813857 cred_data_size,
0 commit comments