@@ -2203,7 +2203,7 @@ sl_status_t zwave_command_class_user_credential_credential_handle_report(
22032203}
22042204
22052205// ///////////////////////////////////////////////////////////////////////////
2206- // User Set/Get/Report
2206+ // User Set/Get/Report/Set Error Report
22072207// ///////////////////////////////////////////////////////////////////////////
22082208
22092209// Start user interview process by starting a user get with ID 0
@@ -2513,6 +2513,68 @@ sl_status_t zwave_command_class_user_credential_user_handle_report(
25132513 return SL_STATUS_OK;
25142514}
25152515
2516+ sl_status_t zwave_command_class_user_credential_user_set_error_handle_report (
2517+ const zwave_controller_connection_info_t *connection_info,
2518+ const uint8_t *frame_data,
2519+ uint16_t frame_length)
2520+ {
2521+ if (frame_length < 14 ) {
2522+ sl_log_warning (LOG_TAG, " USER_SET_ERROR_REPORT frame length is not valid" );
2523+ return SL_STATUS_NOT_SUPPORTED;
2524+ }
2525+ attribute_store_node_t endpoint_node
2526+ = zwave_command_class_get_endpoint_node (connection_info);
2527+
2528+ // We don't need the rest of the frame, we just ensure that the attribute store is in a valid state
2529+ uint8_t error_code = frame_data[2 ];
2530+ user_credential_user_unique_id_t user_id = get_uint16_value (frame_data, 6 );
2531+
2532+ auto remove_user_node_if_possible =
2533+ [&](attribute_store_node_t user_unique_id_node) {
2534+ if (attribute_store_node_exists (user_unique_id_node)) {
2535+ sl_log_debug (LOG_TAG, " Remove faulty user state" , user_id);
2536+ attribute_store_delete_node (user_unique_id_node);
2537+ } else {
2538+ sl_log_debug (
2539+ LOG_TAG,
2540+ " Didn't find an user with id %d in desired state. Not doing anything" ,
2541+ user_id);
2542+ }
2543+ };
2544+
2545+ // This case should not happens often since we are doing preemptive checks
2546+ switch (error_code) {
2547+ // USER_ADD_REJECTED_LOCATION_OCCUPIED : 0x00
2548+ // A user add operation is rejected due to the User Unique Identifier already being occupied
2549+ case USER_SET_ERROR_REPORT_USERADDREJECTEDLOCATIONOCCUPIED: {
2550+ sl_log_error (LOG_TAG,
2551+ " Error when setting user : user ID %d is not available. Try "
2552+ " to modify it instead." ,
2553+ user_id);
2554+ // It should be in desired state since we are using ADD operation
2555+ attribute_store_node_t user_unique_id_node
2556+ = get_desired_user_id_node (endpoint_node, user_id);
2557+ remove_user_node_if_possible (user_unique_id_node);
2558+ } break ;
2559+ // USER_MODIFY_REJECTED_LOCATION_EMPTY : 0x01
2560+ // A user modify operation is rejected due to the User Unique Identifier location being empty
2561+ case USER_SET_ERROR_REPORT_USERMODIFYREJECTEDLOCATIONEMPTY: {
2562+ sl_log_error (LOG_TAG,
2563+ " Error when modifying user : user ID %d does not exists." ,
2564+ user_id);
2565+ // Hunt down the invalid user ID and remove it
2566+ attribute_store_node_t user_unique_id_node
2567+ = get_desired_user_id_node (endpoint_node, user_id);
2568+ // Check for reported value if it doesn't exists
2569+ if (!attribute_store_node_exists (user_unique_id_node)) {
2570+ user_unique_id_node = get_reported_user_id_node (endpoint_node, user_id);
2571+ }
2572+ remove_user_node_if_possible (user_unique_id_node);
2573+ } break ;
2574+ }
2575+
2576+ return SL_STATUS_OK;
2577+ }
25162578// ///////////////////////////////////////////////////////////////////////////
25172579// Post interview actions
25182580// ///////////////////////////////////////////////////////////////////////////
@@ -3145,6 +3207,11 @@ sl_status_t zwave_command_class_user_credential_control_handler(
31453207 }
31463208
31473209 switch (frame_data[COMMAND_INDEX]) {
3210+ case USER_SET_ERROR_REPORT:
3211+ return zwave_command_class_user_credential_user_set_error_handle_report (
3212+ connection_info,
3213+ frame_data,
3214+ frame_length);
31483215 case USER_CAPABILITIES_REPORT:
31493216 return zwave_command_class_user_credential_user_capabilities_handle_report (
31503217 connection_info,
0 commit comments