Skip to content

Commit c282b38

Browse files
Vietrzr
authored andcommitted
UIC-3275: Application Status CC
1 parent f546499 commit c282b38

File tree

9 files changed

+620
-0
lines changed

9 files changed

+620
-0
lines changed

applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,23 @@ DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_INFO_NAME,
12711271
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_SOUND_SWITCH_TONE_PLAY,
12721272
((COMMAND_CLASS_SOUND_SWITCH << 8) | 0x08))
12731273

1274+
/////////////////////////////////////////////////
1275+
// Application Status Command Class
1276+
///< This represents the version of the Sound Switch Command class.
1277+
/// zwave_cc_version_t
1278+
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_VERSION,
1279+
ZWAVE_CC_VERSION_ATTRIBUTE(COMMAND_CLASS_APPLICATION_STATUS))
1280+
// Application Status Busy Status
1281+
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_BUSY_STATUS,
1282+
((COMMAND_CLASS_APPLICATION_STATUS << 8) | 0x02))
1283+
// Application Status Busy Wait time
1284+
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_WAIT_TIME,
1285+
((COMMAND_CLASS_APPLICATION_STATUS << 8) | 0x03))
1286+
// Application Status Reject Status
1287+
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_REJECT_STATUS,
1288+
((COMMAND_CLASS_APPLICATION_STATUS << 8) | 0x04))
1289+
1290+
12741291
/////////////////////////////////////////////////
12751292
// Z-Wave Plus Info CC
12761293
DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_ZWAVEPLUS_INFO_VERSION,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
4+
******************************************************************************
5+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
6+
* software is governed by the terms of Silicon Labs Master Software License
7+
* Agreement (MSLA) available at
8+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
9+
* software is distributed to you in Source Code format and is governed by the
10+
* sections of the MSLA applicable to Source Code.
11+
*
12+
*****************************************************************************/
13+
14+
15+
#ifndef ZWAVE_COMMAND_CLASS_APPLICATION_STATUS_TYPES_H
16+
#define ZWAVE_COMMAND_CLASS_APPLICATION_STATUS_TYPES_H
17+
18+
#include <stdint.h>
19+
20+
///> Application busy status. uint8_t
21+
typedef uint8_t application_busy_status;
22+
23+
///> Application busy wait time. uint8_t
24+
typedef uint8_t application_busy_wait_time;
25+
26+
///> Application reject request. uint8_t
27+
typedef uint8_t application_reject_request;
28+
29+
typedef enum {
30+
TRY_AGAIN_LATER = 0,
31+
TRY_AGAIN_WAIT_TIME = 1,
32+
REQUEST_QUEUED = 2
33+
} application_busy_status_enum;
34+
35+
#endif //ZWAVE_COMMAND_CLASS_APPLICATION_STATUS_TYPES_H
36+
/** @} end zwave_command_class_application_status_types */

applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,17 @@ static const std::vector<attribute_schema_t> attribute_schema = {
557557
{ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_START_MINUTE, "Daily Repeating Start Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE},
558558
{ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_HOUR, "Daily Repeating Duration Hour", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE},
559559
{ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_DURATION_MINUTE, "Daily Repeating Duration Minute", ATTRIBUTE_COMMAND_CLASS_SCHEDULE_ENTRY_LOCK_DAILY_REPEATING_SCHEDULE_SLOT_ID, U8_STORAGE_TYPE},
560+
/////////////////////////////////////////////////////////////////////
561+
// Application Status Command Class attributes
562+
/////////////////////////////////////////////////////////////////////
563+
{ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_VERSION, "Application Status Version", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
564+
{ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_BUSY_STATUS, "Application Busy Status", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
565+
{ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_WAIT_TIME, "Application Busy Wait Time", ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_BUSY_STATUS, U8_STORAGE_TYPE},
566+
{ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_REJECT_STATUS, "Application Reject Status", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE},
560567

568+
//DoorLock Command Class attributes
569+
{ATTRIBUTE_DOOR_LOCK_CONFIGURATION_OPERATION_TYPE, "Door Lock Configuration Operation Type", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE },
570+
{ATTRIBUTE_DOOR_LOCK_CONFIGURATION_INSIDE_DOOR_HANDLES_STATE, "Door Lock Configuration Inside Handles State", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE },
561571
//DoorLock Command Class attributes
562572
{ATTRIBUTE_DOOR_LOCK_CONFIGURATION_OPERATION_TYPE, "Door Lock Configuration Operation Type", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE },
563573
{ATTRIBUTE_DOOR_LOCK_CONFIGURATION_INSIDE_DOOR_HANDLES_STATE, "Door Lock Configuration Inside Handles State", ATTRIBUTE_ENDPOINT_ID, I32_STORAGE_TYPE },

applications/zpc/components/zwave_command_classes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ add_library(
6464
src/zwave_command_classes_utils.c
6565
src/zwave_command_class_inclusion_controller.cpp
6666
src/zwave_command_class_transport_service.c
67+
src/zwave_command_class_application_status.cpp
6768
src/zwave_command_class_protocol.c)
6869
install(TARGETS zwave_command_classes LIBRARY DESTINATION lib)
6970

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
4+
******************************************************************************
5+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
6+
* software is governed by the terms of Silicon Labs Master Software License
7+
* Agreement (MSLA) available at
8+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
9+
* software is distributed to you in Source Code format and is governed by the
10+
* sections of the MSLA applicable to Source Code.
11+
*
12+
*****************************************************************************/
13+
// Includes from this component
14+
#include "zwave_command_class_application_status.h"
15+
#include "zwave_command_class_application_status_types.h"
16+
#include "zwave_command_classes_utils.h"
17+
18+
// Generic includes
19+
#include <stdlib.h>
20+
#include <assert.h>
21+
22+
// Includes from other ZPC Components
23+
#include "zwave_command_class_indices.h"
24+
#include "zwave_command_handler.h"
25+
#include "zpc_attribute_store_network_helper.h"
26+
#include "attribute_store_defined_attribute_types.h"
27+
#include "ZW_classcmd.h"
28+
#include "zpc_attribute_resolver.h"
29+
30+
// Includes from other Unify Components
31+
#include "dotdot_mqtt.h"
32+
#include "dotdot_mqtt_generated_commands.h"
33+
#include "attribute_store_helper.h"
34+
#include "attribute_store.h"
35+
#include "attribute_resolver.h"
36+
#include "attribute_timeouts.h"
37+
#include "sl_log.h"
38+
39+
// Cpp include
40+
#include "attribute.hpp"
41+
#include "zwave_frame_generator.hpp"
42+
#include "zwave_frame_parser.hpp"
43+
44+
// Attribute macro, shortening those long defines for attribute types:
45+
#define ATTRIBUTE(type) ATTRIBUTE_COMMAND_CLASS_APPLICATION_STATUS_##type
46+
47+
// Log tag
48+
constexpr char LOG_TAG[] = "zwave_command_class_application_status";
49+
50+
namespace
51+
{
52+
zwave_frame_generator frame_generator(COMMAND_CLASS_APPLICATION_STATUS);
53+
}
54+
55+
///////////////////////////////////////////////////////////////////////////////
56+
// Helper functions
57+
///////////////////////////////////////////////////////////////////////////////
58+
zwave_cc_version_t
59+
get_current_application_status_version(attribute_store_node_t node)
60+
{
61+
zwave_cc_version_t version = zwave_command_class_get_version_from_node(
62+
node,
63+
COMMAND_CLASS_APPLICATION_STATUS);
64+
65+
if (version == 0) {
66+
sl_log_error(LOG_TAG, "Application_status Command Class Version not found");
67+
}
68+
69+
return version;
70+
}
71+
72+
///////////////////////////////////////////////////////////////////////////////
73+
// Validation function
74+
///////////////////////////////////////////////////////////////////////////////
75+
bool zwave_command_class_application_status_validate_reject_value(uint8_t value)
76+
{
77+
return (value == 0x00 || value == 0x01);
78+
}
79+
80+
///////////////////////////////////////////////////////////////////////////////
81+
// Frame parsing functions
82+
///////////////////////////////////////////////////////////////////////////////
83+
static sl_status_t zwave_command_class_application_status_handle_status_busy(
84+
const zwave_controller_connection_info_t *connection_info,
85+
const uint8_t *frame_data,
86+
uint16_t frame_length)
87+
{
88+
// Setup
89+
attribute_store::attribute endpoint_node(
90+
zwave_command_class_get_endpoint_node(connection_info));
91+
92+
sl_log_debug(LOG_TAG,
93+
"Application Status Report Application Busy frame received");
94+
95+
// Compute expected size for report frame
96+
const uint8_t expected_size = sizeof(ZW_APPLICATION_BUSY_FRAME);
97+
98+
// Parse the frame
99+
try {
100+
zwave_frame_parser parser(frame_data, frame_length);
101+
102+
// Validate frame size with desired size
103+
if (!parser.is_frame_size_valid(expected_size)) {
104+
sl_log_error(LOG_TAG,
105+
"Invalid frame size for Application Status Report "
106+
"Application Busy frame");
107+
return SL_STATUS_FAIL;
108+
}
109+
110+
// Create the busy status attributes if not exists
111+
auto busy_status_node = endpoint_node.emplace_node(ATTRIBUTE(BUSY_STATUS));
112+
113+
//Read Status value from report frame and store attribute
114+
parser.read_byte(busy_status_node);
115+
116+
// Create the wait time attributes if not exists, Read Wait time from report frame store attribute
117+
parser.read_byte(busy_status_node.emplace_node(ATTRIBUTE(WAIT_TIME)));
118+
119+
} catch (const std::exception &e) {
120+
sl_log_error(LOG_TAG,
121+
"Error while parsing Application Status Report Application "
122+
"Busy frame : %s",
123+
e.what());
124+
return SL_STATUS_FAIL;
125+
}
126+
return SL_STATUS_OK;
127+
}
128+
129+
static sl_status_t zwave_command_class_application_status_handle_status_reject(
130+
const zwave_controller_connection_info_t *connection_info,
131+
const uint8_t *frame_data,
132+
uint16_t frame_length)
133+
{
134+
// Setup
135+
attribute_store::attribute endpoint_node(
136+
zwave_command_class_get_endpoint_node(connection_info));
137+
138+
sl_log_debug(LOG_TAG,
139+
"Application Status Report Application Reject frame received");
140+
141+
// Compute expected size for report frame
142+
const uint8_t expected_size = sizeof(ZW_APPLICATION_REJECTED_REQUEST_FRAME);
143+
144+
// Parse the frame
145+
try {
146+
zwave_frame_parser parser(frame_data, frame_length);
147+
148+
// Validate frame size with desired size
149+
if (!parser.is_frame_size_valid(expected_size)) {
150+
sl_log_error(LOG_TAG,
151+
"Invalid frame size for Application Status Report "
152+
"Application Reject frame");
153+
return SL_STATUS_FAIL;
154+
}
155+
156+
//Read Status and store attribute
157+
application_busy_status status = parser.read_byte();
158+
sl_log_debug(LOG_TAG, "Application Status Reject Status : %d", status);
159+
160+
if (!zwave_command_class_application_status_validate_reject_value(status)) {
161+
return SL_STATUS_FAIL;
162+
}
163+
164+
// Create the reject status attributes if not exists
165+
auto reject_status_node
166+
= endpoint_node.emplace_node(ATTRIBUTE(REJECT_STATUS));
167+
reject_status_node.set_reported<application_reject_request>(status);
168+
169+
} catch (const std::exception &e) {
170+
sl_log_error(LOG_TAG,
171+
"Error while parsing Application Status Report Application "
172+
"Reject frame : %s",
173+
e.what());
174+
return SL_STATUS_FAIL;
175+
}
176+
return SL_STATUS_OK;
177+
}
178+
179+
///////////////////////////////////////////////////////////////////////////////
180+
// Incoming commands handler
181+
///////////////////////////////////////////////////////////////////////////////
182+
sl_status_t zwave_command_class_application_status_control_handler(
183+
const zwave_controller_connection_info_t *connection_info,
184+
const uint8_t *frame_data,
185+
uint16_t frame_length)
186+
{
187+
// Frame too short, it should have not come here.
188+
if (frame_length <= COMMAND_INDEX) {
189+
return SL_STATUS_NOT_SUPPORTED;
190+
}
191+
192+
switch (frame_data[COMMAND_INDEX]) {
193+
case APPLICATION_BUSY:
194+
return zwave_command_class_application_status_handle_status_busy(
195+
connection_info,
196+
frame_data,
197+
frame_length);
198+
case APPLICATION_REJECTED_REQUEST:
199+
return zwave_command_class_application_status_handle_status_reject(
200+
connection_info,
201+
frame_data,
202+
frame_length);
203+
default:
204+
return SL_STATUS_NOT_SUPPORTED;
205+
}
206+
}
207+
208+
///////////////////////////////////////////////////////////////////////////////
209+
// Attribute Store callback functions
210+
///////////////////////////////////////////////////////////////////////////////
211+
static void zwave_command_class_application_status_on_version_attribute_update(
212+
attribute_store_node_t updated_node, attribute_store_change_t change)
213+
{
214+
if (change == ATTRIBUTE_DELETED) {
215+
return;
216+
}
217+
218+
// Confirm that we have a version attribute update
219+
assert(ATTRIBUTE(VERSION) == attribute_store_get_node_type(updated_node));
220+
221+
attribute_store::attribute version_node(updated_node);
222+
// Do not create the attributes until we are sure of the version
223+
zwave_cc_version_t supporting_node_version = 0;
224+
225+
// Wait for the version
226+
if (!version_node.reported_exists()) {
227+
return;
228+
}
229+
supporting_node_version = version_node.reported<uint8_t>();
230+
231+
// Wait that the version becomes non-zero.
232+
if (supporting_node_version == 0) {
233+
return;
234+
}
235+
}
236+
237+
///////////////////////////////////////////////////////////////////////////////
238+
// Public interface functions
239+
///////////////////////////////////////////////////////////////////////////////
240+
sl_status_t zwave_command_class_application_status_init()
241+
{
242+
// Attribute store callbacks
243+
attribute_store_register_callback_by_type(
244+
zwave_command_class_application_status_on_version_attribute_update,
245+
ATTRIBUTE(VERSION));
246+
247+
// The support side of things: Register our handler to the Z-Wave CC framework:
248+
zwave_command_handler_t handler = {};
249+
handler.support_handler = NULL;
250+
handler.control_handler
251+
= &zwave_command_class_application_status_control_handler;
252+
// Not supported, so this does not really matter
253+
handler.minimal_scheme = ZWAVE_CONTROLLER_ENCAPSULATION_NETWORK_SCHEME;
254+
handler.manual_security_validation = false;
255+
handler.command_class = COMMAND_CLASS_APPLICATION_STATUS;
256+
handler.version = APPLICATION_STATUS_VERSION;
257+
handler.command_class_name = "Application Status";
258+
handler.comments = "";
259+
260+
zwave_command_handler_register_handler(handler);
261+
262+
return SL_STATUS_OK;
263+
}

0 commit comments

Comments
 (0)