diff --git a/src/app/clusters/ias-zone-client/README.md b/src/app/clusters/ias-zone-client/README.md new file mode 100644 index 00000000000000..f012e706d8cc86 --- /dev/null +++ b/src/app/clusters/ias-zone-client/README.md @@ -0,0 +1 @@ +The code was removed pending a Matter spec. diff --git a/src/app/clusters/ias-zone-client/ias-zone-client.cpp b/src/app/clusters/ias-zone-client/ias-zone-client.cpp deleted file mode 100644 index 0945d5a836564d..00000000000000 --- a/src/app/clusters/ias-zone-client/ias-zone-client.cpp +++ /dev/null @@ -1,567 +0,0 @@ -/** - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ias-zone-client.h" -#include -#include -#include -#include -#include - -using namespace chip; -using namespace chip::app::Clusters::IasZone; -using namespace chip::app::Clusters::IasZone::Commands; - -//----------------------------------------------------------------------------- -// Globals - -IasZoneDevice emberAfIasZoneClientKnownServers[EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES]; - -typedef enum -{ - IAS_ZONE_CLIENT_STATE_NONE, - IAS_ZONE_CLIENT_STATE_DISCOVER_ENDPOINT, - IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS, - IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS, - IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES, -} IasZoneClientState; - -static IasZoneClientState iasZoneClientState = IAS_ZONE_CLIENT_STATE_NONE; -static uint8_t currentIndex = NO_INDEX; -static uint8_t myEndpoint = 0; - -EmberEventControl emberAfPluginIasZoneClientStateMachineEventControl; - -//----------------------------------------------------------------------------- -// Forward Declarations - -void readIasZoneServerAttributes(EmberNodeId nodeId); -static void iasClientSaveCommand(void); -static void iasClientLoadCommand(void); - -//----------------------------------------------------------------------------- -// Functions - -void emberAfIasZoneClusterClientInitCallback(EndpointId endpoint) -{ - emAfClearServers(); - myEndpoint = endpoint; - iasClientLoadCommand(); -} - -void emAfClearServers(void) -{ - MEMSET(emberAfIasZoneClientKnownServers, 0xFF, sizeof(IasZoneDevice) * EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES); -} - -static void clearState(void) -{ - currentIndex = 0; - iasZoneClientState = IAS_ZONE_CLIENT_STATE_NONE; -} - -static void setServerZoneStatus(uint8_t serverIndex, uint16_t zoneStatus) -{ - emberAfIasZoneClientKnownServers[serverIndex].zoneStatus = zoneStatus; - iasClientSaveCommand(); -} - -static void setServerIeee(uint8_t serverIndex, uint8_t * ieeeAddress) -{ - MEMCOPY(emberAfIasZoneClientKnownServers[serverIndex].ieeeAddress, ieeeAddress, EUI64_SIZE); - iasClientSaveCommand(); -} - -static void clearServerIeee(uint8_t serverIndex) -{ - MEMSET(emberAfIasZoneClientKnownServers[serverIndex].ieeeAddress, 0xFF, sizeof(IasZoneDevice)); - iasClientSaveCommand(); -} - -static void setServerNodeId(uint8_t serverIndex, EmberNodeId nodeId) -{ - emberAfIasZoneClientKnownServers[serverIndex].nodeId = nodeId; -} - -static void clearServerNodeId(uint8_t serverIndex) -{ - emberAfIasZoneClientKnownServers[serverIndex].nodeId = EMBER_NULL_NODE_ID; -} - -static void setServerZoneState(uint8_t serverIndex, uint8_t zoneState) -{ - emberAfIasZoneClientKnownServers[serverIndex].zoneState = zoneState; - iasClientSaveCommand(); -} - -static void setServerEndpoint(uint8_t serverIndex, EndpointId endpoint) -{ - emberAfIasZoneClientKnownServers[serverIndex].endpoint = endpoint; - iasClientSaveCommand(); -} - -static void setServerZoneType(uint8_t serverIndex, uint16_t zoneType) -{ - emberAfIasZoneClientKnownServers[serverIndex].zoneType = zoneType; - iasClientSaveCommand(); -} - -static void setServerZoneId(uint8_t serverIndex, uint16_t zoneId) -{ - emberAfIasZoneClientKnownServers[serverIndex].zoneId = zoneId; - iasClientSaveCommand(); -} - -static void setCurrentIndex(uint8_t serverIndex) -{ - currentIndex = serverIndex; - iasClientSaveCommand(); -} - -static void setIasZoneClientState(uint8_t clientState) -{ - iasZoneClientState = clientState; - iasClientSaveCommand(); -} - -static void iasClientSaveCommand(void) -{ -#if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST) - FILE * fp; - uint16_t i, j; - - // save zone server list - fp = fopen("iaszone.txt", "w"); - - for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) - { - if (emberAfIasZoneClientKnownServers[i].zoneId != 0xFF) - { - fprintf(fp, "%x %x %x %x %x ", emberAfIasZoneClientKnownServers[i].zoneId, - emberAfIasZoneClientKnownServers[i].zoneStatus, emberAfIasZoneClientKnownServers[i].zoneState, - emberAfIasZoneClientKnownServers[i].endpoint, emberAfIasZoneClientKnownServers[i].zoneType); - for (j = 0; j < 8; j++) - { - fprintf(fp, "%x ", emberAfIasZoneClientKnownServers[i].ieeeAddress[j]); - } - } - } - // Write something to mark the end of the file. - fprintf(fp, "ff"); - int res = fclose(fp); - assert(res == 0); -#endif //#if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST) -} - -static void iasClientLoadCommand(void) -{ -#if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST) - FILE * fp; - uint16_t i, j; - - unsigned int data1, data2, data3, data4, data5; - - fp = fopen("iaszone.txt", "r"); - - if (!fp) - { - return; - } - - for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) - { - if (feof(fp)) - { - break; - } - fscanf(fp, "%x ", &data1); - if (data1 == 0xff) - { - break; - } - fscanf(fp, "%x %x %x %x ", &data2, &data3, &data4, &data5); - - emberAfIasZoneClientKnownServers[i].zoneId = (uint8_t) data1; - emberAfIasZoneClientKnownServers[i].zoneStatus = (uint16_t) data2; - emberAfIasZoneClientKnownServers[i].zoneState = (uint8_t) data3; - emberAfIasZoneClientKnownServers[i].endpoint = (uint8_t) data4; - emberAfIasZoneClientKnownServers[i].zoneType = (uint16_t) data5; - - for (j = 0; j < 8; j++) - { - fscanf(fp, "%x ", &data1); - emberAfIasZoneClientKnownServers[i].ieeeAddress[j] = (uint8_t) data1; - } - } - int res = fclose(fp); - assert(res == 0); -#endif // #if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST) -} - -static uint8_t findIasZoneServerByIeee(uint8_t * ieeeAddress) -{ - uint8_t i; - for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) - { - if (0 == memcmp(ieeeAddress, emberAfIasZoneClientKnownServers[i].ieeeAddress, EUI64_SIZE)) - { - return i; - } - } - return NO_INDEX; -} - -static uint8_t findIasZoneServerByNodeId(EmberNodeId nodeId) -{ - uint8_t i; - for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) - { - if (nodeId == emberAfIasZoneClientKnownServers[i].nodeId) - { - return i; - } - } - - // If we didn't find the node ID in the table, see if the stack knows about - // it. - EmberEUI64 eui64; - if (emberLookupEui64ByNodeId(nodeId, eui64) == EMBER_SUCCESS) - { - i = findIasZoneServerByIeee(eui64); - if (i != NO_INDEX) - { - setServerNodeId(i, nodeId); - } - } - - return i; -} - -bool emberAfIasZoneClusterZoneStatusChangeNotificationCallback(app::CommandHandler * commandObj, uint16_t zoneStatus, - uint8_t extendedStatus, uint8_t zoneId, uint16_t delay) -{ - uint8_t serverIndex = findIasZoneServerByNodeId(emberAfCurrentCommand()->source); - uint8_t status = EMBER_ZCL_STATUS_NOT_FOUND; - if (serverIndex != NO_INDEX) - { - status = EMBER_ZCL_STATUS_SUCCESS; - setServerZoneStatus(serverIndex, zoneStatus); - - emberAfIasZoneClusterPrintln("Zone %d status change, 0x%2X from 0x%2X", zoneId, zoneStatus, - emberAfCurrentCommand()->source); - - // The Test case calls for readding attributes after status change. - // that is silly for the production device. - // readIasZoneServerAttributes(emberAfCurrentCommand()->source); - } - emberAfSendDefaultResponse(emberAfCurrentCommand(), status); - return true; -} - -bool emberAfIasZoneClusterZoneEnrollRequestCallback(app::CommandHandler * commandObj, uint16_t zoneType, uint16_t manufacturerCode) -{ - EmberAfIasEnrollResponseCode responseCode = EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_NO_ENROLL_PERMIT; - uint8_t zoneId = UNKNOWN_ZONE_ID; - uint8_t serverIndex = findIasZoneServerByNodeId(emberAfCurrentCommand()->source); - EmberStatus status; - - if (serverIndex != NO_INDEX) - { - responseCode = EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS; - zoneId = serverIndex; - setServerZoneId(serverIndex, zoneId); - } - emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), app::Clusters::IasZone::Id, - ZoneEnrollResponse::Id, "uu", responseCode, zoneId); - // Need to send this command with our source EUI because the server will - // check our EUI64 against his CIE Address to see if we're his CIE. - emberAfGetCommandApsFrame()->options |= EMBER_APS_OPTION_SOURCE_EUI64; - status = emberAfSendResponse(); - emberAfCorePrintln("Sent enroll response with responseCode: 0x%X, zoneId: 0x%X, status: 0x%X", responseCode, zoneId, status); - return true; -} - -void emberAfPluginIasZoneClientStateMachineEventHandler(void) -{ - emberAfIasZoneClusterPrintln("IAS Zone Client Timeout waiting for message response."); - emberEventControlSetInactive(emberAfPluginIasZoneClientStateMachineEventControl); - clearState(); -} - -static uint8_t addServer(EmberNodeId nodeId, uint8_t * ieeeAddress) -{ - uint8_t i = findIasZoneServerByIeee(ieeeAddress); - if (i != NO_INDEX) - { - return i; - } - - for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) - { - const uint8_t unsetEui64[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - if (0 == memcmp(emberAfIasZoneClientKnownServers[i].ieeeAddress, unsetEui64, EUI64_SIZE)) - { - setServerIeee(i, ieeeAddress); - setServerNodeId(i, nodeId); - setServerEndpoint(i, UNKNOWN_ENDPOINT); - return i; - } - } - return NO_INDEX; -} - -static void removeServer(uint8_t * ieeeAddress) -{ - uint8_t index = findIasZoneServerByIeee(ieeeAddress); - clearServerIeee(index); - clearServerNodeId(index); -} - -static EmberStatus sendCommand(EmberNodeId destAddress) -{ - emberAfSetCommandEndpoints(myEndpoint, emberAfIasZoneClientKnownServers[currentIndex].endpoint); - EmberStatus status = emberAfSendCommandUnicast(MessageSendDestination::Direct(destAddress)); - emberAfIasZoneClusterPrintln("Sent IAS Zone Client Command to 0x%2X (%d -> %d) status: 0x%X", destAddress, myEndpoint, - emberAfIasZoneClientKnownServers[currentIndex].endpoint, status); - if (status != EMBER_SUCCESS) - { - clearState(); - } - return status; -} - -static void setCieAddress(EmberNodeId destAddress) -{ -#error "This needs to be fixed to handle 4-byte attribute ids" - - uint8_t writeAttributes[] = { - EMBER_LOW_BYTE(Attributes::IasCieAddress::Id), - EMBER_HIGH_BYTE(Attributes::IasCieAddress::Id), - ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // ieee (filled in later) - }; - emberAfGetEui64(&writeAttributes[3]); - emberAfFillExternalBuffer((ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), app::Clusters::IasZone::Id, - ZCL_WRITE_ATTRIBUTES_COMMAND_ID, "b", writeAttributes, sizeof(writeAttributes)); - emberAfIasZoneClusterPrintln("Writing CIE Address to IAS Zone Server"); - if (EMBER_SUCCESS == sendCommand(destAddress)) - { - setIasZoneClientState(IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS); - } -} - -static void iasZoneClientServiceDiscoveryCallback(const EmberAfServiceDiscoveryResult * result) -{ - if (result->status == EMBER_AF_UNICAST_SERVICE_DISCOVERY_COMPLETE_WITH_RESPONSE && - result->zdoRequestClusterId == MATCH_DESCRIPTORS_REQUEST) - { - const EmberAfEndpointList * endpointList = (const EmberAfEndpointList *) result->responseData; - if (endpointList->count > 0) - { - setServerEndpoint(currentIndex, endpointList->list[0]); - emberAfIasZoneClusterPrintln("Device 0x%2X supports IAS Zone Server", result->matchAddress); - setCieAddress(result->matchAddress); - return; - } - } - clearState(); -} - -static void checkForIasZoneServer(EmberNodeId emberNodeId, uint8_t * ieeeAddress) -{ - uint8_t endpointIndex = emberAfIndexFromEndpoint(myEndpoint); - uint8_t serverIndex = addServer(emberNodeId, ieeeAddress); - - if (serverIndex == NO_INDEX) - { - emberAfIasZoneClusterPrintln("Error: Could not add IAS Zone server."); - return; - } - - setCurrentIndex(serverIndex); - - if (emberAfIasZoneClientKnownServers[serverIndex].endpoint != UNKNOWN_ENDPOINT) - { - // If a remote endpoint that you have already seen announces itself, - // write your IEEE in them just in case they left and are rejoining. --agkeesle - // Bug: EMAPPFWKV2-1078 - setCieAddress(emberNodeId); - emberAfIasZoneClusterPrintln("Node 0x%2X already known to IAS client", emberNodeId); - return; - } - - EmberStatus status = emberAfFindDevicesByCluster(emberNodeId, app::Clusters::IasZone::Id, - true, // server cluster? - iasZoneClientServiceDiscoveryCallback); - - if (status != EMBER_SUCCESS) - { - emberAfIasZoneClusterPrintln("Error: Failed to initiate service discovery for IAS Zone Server 0x%2X", emberNodeId); - clearState(); - } -} - -void emberAfPluginIasZoneClientZdoMessageReceivedCallback(EmberNodeId emberNodeId, EmberApsFrame * apsFrame, uint8_t * message, - uint16_t length) -{ - emberAfIasZoneClusterPrintln("Incoming ZDO, Cluster: 0x%2X", apsFrame->clusterId); - if (apsFrame->clusterId == END_DEVICE_ANNOUNCE) - { - checkForIasZoneServer(emberNodeId, &(message[3])); - } -} - -void readIasZoneServerAttributes(EmberNodeId nodeId) -{ -#error "This needs to be fixed to handle 4-byte attribute ids" - - uint8_t iasZoneAttributeIds[] = { - EMBER_LOW_BYTE(Attributes::ZoneState::Id), EMBER_HIGH_BYTE(Attributes::ZoneState::Id), - - EMBER_LOW_BYTE(Attributes::ZoneType::Id), EMBER_HIGH_BYTE(Attributes::ZoneType::Id), - - EMBER_LOW_BYTE(Attributes::ZoneStatus::Id), EMBER_HIGH_BYTE(Attributes::ZoneStatus::Id), - }; - emberAfFillExternalBuffer((ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), app::Clusters::IasZone::Id, - ZCL_READ_ATTRIBUTES_COMMAND_ID, "b", iasZoneAttributeIds, sizeof(iasZoneAttributeIds)); - if (EMBER_SUCCESS == sendCommand(nodeId)) - { - setIasZoneClientState(IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES); - } -} - -void readIasZoneServerCieAddress(EmberNodeId nodeId) -{ -#error "This needs to be fixed to handle 4-byte attribute ids" - - uint8_t iasZoneAttributeIds[] = { - EMBER_LOW_BYTE(Attributes::IasCieAddress::Id), - EMBER_HIGH_BYTE(Attributes::IasCieAddress::Id), - }; - emberAfFillExternalBuffer((ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), app::Clusters::IasZone::Id, - ZCL_READ_ATTRIBUTES_COMMAND_ID, "b", iasZoneAttributeIds, sizeof(iasZoneAttributeIds)); - if (EMBER_SUCCESS == sendCommand(nodeId)) - { - setIasZoneClientState(IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS); - } -} - -void emberAfPluginIasZoneClientWriteAttributesResponseCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) -{ - if (clusterId == app::Clusters::IasZone::Id && iasZoneClientState == IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS && - buffer[0] == EMBER_ZCL_STATUS_SUCCESS) - { - readIasZoneServerCieAddress(emberAfCurrentCommand()->source); - return; - } - return; -} - -void emberAfPluginIasZoneClientReadAttributesResponseCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) -{ - uint8_t zoneStatus, zoneType, zoneState; - if (clusterId == app::Clusters::IasZone::Id && - (iasZoneClientState == IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES || - iasZoneClientState == IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS)) - { - uint16_t i = 0; - while ((i + 3) <= bufLen) - { // 3 to insure we can read at least the attribute ID - // and the status - AttributeId attributeId = buffer[i] + (buffer[i + 1] << 8); - uint8_t status = buffer[i + 2]; - i += 3; - // emberAfIasZoneClusterPrintln("Parsing Attribute 0x%2X, Status: 0x%X", attributeId, status); - if (status == EMBER_ZCL_STATUS_SUCCESS) - { - if ((i + 1) > bufLen) - { - // Too short, dump the message. - return; - } - i++; // skip the type of the attribute. We already know what it should be. - switch (attributeId) - { - case Attributes::ZoneStatus::Id: - if ((i + 2) > bufLen) - { - // Too short, dump the message. - return; - } - zoneStatus = (buffer[i] + (buffer[i + 1] << 8)); - setServerZoneStatus(currentIndex, zoneStatus); - i += 2; - break; - case Attributes::ZoneType::Id: - if ((i + 2) > bufLen) - { - // Too short, dump the message. - return; - } - zoneType = (buffer[i] + (buffer[i + 1] << 8)); - setServerZoneType(currentIndex, zoneType); - i += 2; - break; - case Attributes::ZoneState::Id: - if ((i + 1) > bufLen) - { - // Too short, dump the message - return; - } - zoneState = buffer[i]; - setServerZoneState(currentIndex, zoneState); - i++; - break; - case Attributes::IasCieAddress::Id: { - uint8_t myIeee[EUI64_SIZE]; - emberAfGetEui64(myIeee); - if ((i + 8) > bufLen) - { - // Too short, dump the message - } - else if (0 != memcmp(&(buffer[i]), myIeee, EUI64_SIZE)) - { - emberAfIasZoneClusterPrintln("CIE Address not set to mine, removing IAS zone server."); - removeServer(&(buffer[i])); - clearState(); - } - else - { - readIasZoneServerAttributes(emberAfCurrentCommand()->source); - } - return; - } - } - } - } - emberAfIasZoneClusterPrintln("Retrieved IAS Zone Server attributes from 0x%2X", emberAfCurrentCommand()->source); - clearState(); - } -} - -void emberAfPluginIasZoneClientZdoCallback(EmberNodeId emberNodeId, EmberApsFrame * apsFrame, uint8_t * message, uint16_t length) {} - -void emberAfPluginIasZoneClientWriteAttributesResponseCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) {} - -void emberAfPluginIasZoneClientReadAttributesResponseCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) {} diff --git a/src/app/clusters/ias-zone-client/ias-zone-client.h b/src/app/clusters/ias-zone-client/ias-zone-client.h deleted file mode 100644 index f509b6378df6e6..00000000000000 --- a/src/app/clusters/ias-zone-client/ias-zone-client.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -typedef struct -{ - EmberEUI64 ieeeAddress; - chip::NodeId nodeId; - uint16_t zoneType; - uint16_t zoneStatus; - uint8_t zoneState; - chip::EndpointId endpoint; - uint8_t zoneId; -} IasZoneDevice; - -extern IasZoneDevice emberAfIasZoneClientKnownServers[]; - -#define NO_INDEX 0xFF -#define UNKNOWN_ENDPOINT 0 - -#define UNKNOWN_ZONE_ID 0xFF - -void emAfClearServers(void); - -void emberAfPluginIasZoneClientZdoCallback(EmberNodeId emberNodeId, EmberApsFrame * apsFrame, uint8_t * message, uint16_t length); - -void emberAfPluginIasZoneClientWriteAttributesResponseCallback(chip::ClusterId clusterId, uint8_t * buffer, uint16_t bufLen); - -void emberAfPluginIasZoneClientReadAttributesResponseCallback(chip::ClusterId clusterId, uint8_t * buffer, uint16_t bufLen); diff --git a/src/app/clusters/ias-zone-server/README.md b/src/app/clusters/ias-zone-server/README.md new file mode 100644 index 00000000000000..f012e706d8cc86 --- /dev/null +++ b/src/app/clusters/ias-zone-server/README.md @@ -0,0 +1 @@ +The code was removed pending a Matter spec. diff --git a/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h b/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h deleted file mode 100644 index 9a1c6ab3ea770f..00000000000000 --- a/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -/** - * Custom Application Tokens - */ -#define CREATOR_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD (0x0020) -#define NVM3KEY_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD (NVM3KEY_DOMAIN_USER | 0x0020) - -#ifdef DEFINETYPES -// Include or define any typedef for tokens here -#endif // DEFINETYPES - -#ifdef DEFINETOKENS -// Define the actual token storage information here -DEFINE_BASIC_TOKEN(PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD, uint8_t, 0xFF) - -#endif // DEFINETOKENS diff --git a/src/app/clusters/ias-zone-server/ias-zone-server.cpp b/src/app/clusters/ias-zone-server/ias-zone-server.cpp deleted file mode 100644 index df593f67bfe470..00000000000000 --- a/src/app/clusters/ias-zone-server/ias-zone-server.cpp +++ /dev/null @@ -1,860 +0,0 @@ -/** - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ias-zone-server.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace chip; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::IasZone; -using namespace chip::app::Clusters::IasZone::Commands; - -#define UNDEFINED_ZONE_ID 0xFF -#define DELAY_TIMER_MS (1 * MILLISECOND_TICKS_PER_SECOND) -#define IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX 0x02 -#define ZCL_FRAME_CONTROL_IDX 0x00 - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) -#if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER) -#define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER_QUEUE_SIZE -#else -#define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_IAS_ZONE_SERVER_QUEUE_DEPTH -#endif -#else -#define NUM_QUEUE_ENTRIES 0 -#endif - -#define DEFAULT_ENROLLMENT_METHOD EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST - -// TODO: Need to figure out what needs to happen wrt HAL tokens here, but for -// now define ESZP_HOST to disable it. See -// https://github.com/project-chip/connectedhomeip/issues/3275 -#define EZSP_HOST - -typedef struct -{ - EndpointId endpoint; - uint16_t status; - System::Clock::Timestamp eventTime; -} IasZoneStatusQueueEntry; - -typedef struct -{ - uint8_t entriesInQueue; - uint8_t startIdx; - uint8_t lastIdx; - IasZoneStatusQueueEntry buffer[NUM_QUEUE_ENTRIES]; -} IasZoneStatusQueue; - -//----------------------------------------------------------------------------- -// Globals - -EmberEventControl emberAfPluginIasZoneServerManageQueueEventControl; -static EmberAfIasZoneEnrollmentMode enrollmentMethod; - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) -IasZoneStatusQueue messageQueue; - -// Status queue retry parameters -typedef struct -{ - IasZoneStatusQueueRetryConfig config; - uint32_t currentBackoffTimeSec; - uint8_t currentRetryCount; -} IasZoneStatusQueueRetryParameters; - -// Set up status queue retry parameters. -IasZoneStatusQueueRetryParameters queueRetryParams = { - .config = { .firstBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC, - .backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO, - .maxBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC, -#ifdef EMBER_AF_PLUGIN_IAS_ZONE_SERVER_UNLIMITED_RETRIES - .unlimitedRetries = true, -#else - .unlimitedRetries = false, -#endif - .maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS }, - .currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC, - .currentRetryCount = 0, -}; - -static void resetCurrentQueueRetryParams(void) -{ - queueRetryParams.currentRetryCount = 0; - queueRetryParams.currentBackoffTimeSec = queueRetryParams.config.firstBackoffTimeSec; -} - -#endif // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE - -//----------------------------------------------------------------------------- -// Forward declarations - -static void setZoneId(EndpointId endpoint, uint8_t zoneId); -static bool areZoneServerAttributesNonVolatile(EndpointId endpoint); -static bool isValidEnrollmentMode(EmberAfIasZoneEnrollmentMode method); -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) -static uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry * entry); -static void bufferInit(IasZoneStatusQueue * ring); -static int16_t copyToBuffer(IasZoneStatusQueue * ring, const IasZoneStatusQueueEntry * entry); -static int16_t popFromBuffer(IasZoneStatusQueue * ring, IasZoneStatusQueueEntry * entry); -#endif - -// TODO: https://github.com/project-chip/connectedhomeip/issues/3276 needs to be -// fixed to implement this for real. -EmberNetworkStatus emberAfNetworkState(void) -{ - return EMBER_JOINED_NETWORK; -} - -//----------------------------------------------------------------------------- -// Functions - -static EmberStatus sendToClient(EndpointId endpoint) -{ - EmberStatus status; - - // If the device is not a network, there is no one to send to, so do nothing - if (emberAfNetworkState() != EMBER_JOINED_NETWORK) - { - return EMBER_NETWORK_DOWN; - } - - // Remote endpoint need not be set, since it will be provided by the call to - // emberAfSendCommandUnicastToBindings() - emberAfSetCommandEndpoints(endpoint, 0); - - // TODO: Figure out how this sending should actually work in Matter. -#if 0 - // A binding table entry is created on Zone Enrollment for each endpoint, so - // a simple call to SendCommandUnicastToBinding will handle determining the - // destination endpoint, address, etc for us. - status = emberAfSendCommandUnicastToBindings(); -#else - status = EMBER_ERR_FATAL; -#endif - - if (EMBER_SUCCESS != status) - { - return status; - } - - return status; -} - -static void enrollWithClient(EndpointId endpoint) -{ - EmberStatus status; - emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT), IasZone::Id, - ZoneEnrollRequest::Id, "vv", EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE, EMBER_AF_MANUFACTURER_CODE); - status = sendToClient(endpoint); - if (status == EMBER_SUCCESS) - { - emberAfIasZoneClusterPrintln("Sent enroll request to IAS Zone client."); - } - else - { - emberAfIasZoneClusterPrintln("Error sending enroll request: 0x%x\n", status); - } -} - -Protocols::InteractionModel::Status -MatterIasZoneClusterServerPreAttributeChangedCallback(const app::ConcreteAttributePath & attributePath, - EmberAfAttributeType attributeType, uint16_t size, uint8_t * value) -{ - uint8_t i; - bool zeroAddress; - EmberBindingTableEntry bindingEntry; - NodeId destNodeId; - EndpointId endpoint = attributePath.mEndpointId; - uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - // If this is not a CIE Address write, the CIE address has already been - // written, or the IAS Zone server is already enrolled, do nothing. - if (attributePath.mAttributeId != Attributes::IasCieAddress::Id || emberAfCurrentCommand() == nullptr) - { - return Protocols::InteractionModel::Status::Success; - } - - memcpy(&destNodeId, value, sizeof(NodeId)); - - // Create the binding table entry - - // This code assumes that the endpoint and device that is setting the CIE - // address is the CIE device itself, and as such the remote endpoint to bind - // to is the endpoint that generated the attribute change. This - // assumption is made based on analysis of the behavior of CIE devices - // currently existing in the field. - bindingEntry.type = EMBER_UNICAST_BINDING; - bindingEntry.local = endpoint; - bindingEntry.clusterId = MakeOptional(IasZone::Id); - bindingEntry.remote = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - bindingEntry.nodeId = destNodeId; - - bool foundSameEntry = false; - // Cycle through the binding table until we find a valid entry that is not - // being used, then use the created entry to make the bind. - for (const auto & currentBind : BindingTable::GetInstance()) - { - // If the binding table entry created based on the response already exists - // do nothing. - if ((currentBind.local == bindingEntry.local) && (currentBind.clusterId == bindingEntry.clusterId) && - (currentBind.remote == bindingEntry.remote) && (currentBind.type == bindingEntry.type)) - { - foundSameEntry = true; - break; - } - } - - if (!foundSameEntry) - { - BindingTable::GetInstance().Add(bindingEntry); - } - - zeroAddress = true; - emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::IasCieAddress::Id, (uint8_t *) ieeeAddress, 8); - for (i = 0; i < 8; i++) - { - if (ieeeAddress[i] != 0) - { - zeroAddress = false; - } - } - emberAfAppPrint("\nzero address: %d\n", zeroAddress); - - if ((zeroAddress == true) && (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST)) - { - // Only send the enrollment request if the mode is AUTO-ENROLL-REQUEST. - // We need to delay to get around a bug where we can't send a command - // at this point because then the Write Attributes response will not - // be sent. But we also delay to give the client time to configure us. - emberAfIasZoneClusterPrintln("Sending enrollment after %d ms", DELAY_TIMER_MS); - emberAfScheduleServerTickExtended(endpoint, IasZone::Id, DELAY_TIMER_MS, EMBER_AF_SHORT_POLL, EMBER_AF_STAY_AWAKE); - } - - return Protocols::InteractionModel::Status::Success; -} - -EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(EndpointId endpoint, EmberAfIasZoneEnrollmentMode method) -{ - EmberAfStatus status; - - if (emberAfIasZoneClusterAmIEnrolled(endpoint)) - { - emberAfIasZoneClusterPrintln("Error: Already enrolled"); - status = EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS; - } - else if (!isValidEnrollmentMode(method)) - { - emberAfIasZoneClusterPrintln("Invalid IAS Zone Server Enrollment Mode: %d", method); - status = EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - else - { - enrollmentMethod = method; -#ifndef EZSP_HOST - halCommonSetToken(TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD, &enrollmentMethod); -#endif - emberAfIasZoneClusterPrintln("IAS Zone Server Enrollment Mode: %d", method); - status = EMBER_ZCL_STATUS_SUCCESS; - } - return status; -} - -static bool isValidEnrollmentMode(EmberAfIasZoneEnrollmentMode method) -{ - return ((method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR) || - (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE) || - (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST)); -} - -bool emberAfIasZoneClusterAmIEnrolled(EndpointId endpoint) -{ - EmberAfIasZoneState zoneState = EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED; // Clear this out completely. - EmberAfStatus status; - status = emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::ZoneState::Id, (unsigned char *) &zoneState, - 1); // uint8_t size - - return (status == EMBER_ZCL_STATUS_SUCCESS && zoneState == EMBER_ZCL_IAS_ZONE_STATE_ENROLLED); -} - -static void updateEnrollState(EndpointId endpoint, bool enrolled) -{ - EmberAfIasZoneState zoneState = (enrolled ? EMBER_ZCL_IAS_ZONE_STATE_ENROLLED : EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED); - - emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneState::Id, (uint8_t *) &zoneState, ZCL_INT8U_ATTRIBUTE_TYPE); - emberAfIasZoneClusterPrintln("IAS Zone Server State: %pEnrolled", (enrolled ? "" : "NOT ")); -} - -bool emberAfIasZoneClusterZoneEnrollResponseCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, - const Commands::ZoneEnrollResponse::DecodableType & commandData) -{ - auto & enrollResponseCode = commandData.enrollResponseCode; - auto & zoneId = commandData.zoneId; - - EndpointId endpoint; - uint8_t epZoneId; - EmberAfStatus status; - - endpoint = emberAfCurrentEndpoint(); - status = emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id, &epZoneId, sizeof(uint8_t)); - if (status == EMBER_ZCL_STATUS_SUCCESS) - { - if (enrollResponseCode == EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS) - { - updateEnrollState(endpoint, true); - setZoneId(endpoint, zoneId); - } - else - { - updateEnrollState(endpoint, false); - setZoneId(endpoint, UNDEFINED_ZONE_ID); - } - - return true; - } - - emberAfAppPrintln("ERROR: IAS Zone Server unable to read zone ID attribute"); - return true; -} - -static EmberStatus sendZoneUpdate(uint16_t zoneStatus, uint16_t timeSinceStatusOccurredQs, EndpointId endpoint) -{ - EmberStatus status; - - if (!emberAfIasZoneClusterAmIEnrolled(endpoint)) - { - return EMBER_INVALID_CALL; - } - emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT), IasZone::Id, - ZoneStatusChangeNotification::Id, "vuuv", zoneStatus, 0 /*extended status, must be zero per spec*/, - emberAfPluginIasZoneServerGetZoneId(endpoint), - timeSinceStatusOccurredQs /* called "delay" in the spec */); - status = sendToClient(endpoint); - - return status; -} - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) -static void addNewEntryToQueue(const IasZoneStatusQueueEntry * newEntry) -{ - emberAfIasZoneClusterPrintln("Adding new entry to queue"); - copyToBuffer(&messageQueue, newEntry); -} -#endif - -EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(EndpointId endpoint, uint16_t newStatus, uint16_t timeSinceStatusOccurredQs) -{ -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - IasZoneStatusQueueEntry newBufferEntry; - newBufferEntry.endpoint = endpoint; - newBufferEntry.status = newStatus; - newBufferEntry.eventTime = System::SystemClock().GetMonotonicTimestamp(); -#endif - EmberStatus sendStatus = EMBER_SUCCESS; - - emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneStatus::Id, (uint8_t *) &newStatus, - ZCL_INT16U_ATTRIBUTE_TYPE); - - if (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR) - { - // If unenrolled, send Zone Enroll Request command. - if (!emberAfIasZoneClusterAmIEnrolled(endpoint)) - { - emberAfScheduleServerTick(endpoint, IasZone::Id, DELAY_TIMER_MS); - // Don't send the zone status update since not enrolled. - return EMBER_SUCCESS; - } - } - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - // If there are items in the queue waiting to send, this event should not - // be transmitted, as that could cause the client to receive the events out - // of order. Instead, just add the device to the queue - if (messageQueue.entriesInQueue == 0) - { - sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint); - } - else - { - // Add a new element to the status queue and depending on the network state - // either try to resend the first element in the queue immediately or try to - // restart the parent research pattern. - addNewEntryToQueue(&newBufferEntry); - - EmberNetworkStatus networkState = emberAfNetworkState(); - - if (networkState == EMBER_JOINED_NETWORK_NO_PARENT) - { - emberAfStartMoveCallback(); - } - else if (networkState == EMBER_JOINED_NETWORK) - { - resetCurrentQueueRetryParams(); - emberEventControlSetActive(&emberAfPluginIasZoneServerManageQueueEventControl); - } - - return EMBER_SUCCESS; - } - -#else - sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint); -#endif - - if (sendStatus == EMBER_SUCCESS) - { -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - // Add a new entry to the zoneUpdate buffer - addNewEntryToQueue(&newBufferEntry); -#endif - } - else - { - // If we're not on a network and never were, we don't need to do anything. - // If we used to be on a network and can't talk to our parent, we should - // try to rejoin the network and add the message to the queue - if (emberAfNetworkState() == EMBER_JOINED_NETWORK_NO_PARENT) - { - emberAfStartMoveCallback(); -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - // Add a new entry to the zoneUpdate buffer - addNewEntryToQueue(&newBufferEntry); -#endif - } - emberAfIasZoneClusterPrintln("Failed to send IAS Zone update. Err 0x%x", sendStatus); - } - return sendStatus; -} - -void emberAfPluginIasZoneServerManageQueueEventHandler(void) -{ -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - IasZoneStatusQueueEntry * bufferStart; - uint16_t status; - uint16_t elapsedTimeQs; - uint16_t airTimeRemainingMs; - - // If the queue was emptied without our interaction, do nothing - if (messageQueue.entriesInQueue == 0) - { - emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl); - return; - } - - // Otherwise, pull out the first item and attempt to retransmit it. The - // message complete callback will handle removing items from the queue - - // To prevent an activity storm from flooding with retry requests, only - // re-send a message if it's been at least - // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS since it was sent. - bufferStart = &(messageQueue.buffer[messageQueue.startIdx]); - elapsedTimeQs = computeElapsedTimeQs(bufferStart); - - if (elapsedTimeQs < (EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS / (MILLISECOND_TICKS_PER_SECOND / 4))) - { - airTimeRemainingMs = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS - (elapsedTimeQs * MILLISECOND_TICKS_PER_SECOND / 4); - emberAfIasZoneClusterPrintln("Not enough time passed for a retry, sleeping %d more mS", airTimeRemainingMs); - emberEventControlSetDelayMS(emberAfPluginIasZoneServerManageQueueEventControl, airTimeRemainingMs); - } - else - { - status = bufferStart->status; - emberAfIasZoneClusterPrintln("Attempting to resend a queued zone status update (status: 0x%02X, " - "event time (s): %d) with time of %d. Retry count: %d", - bufferStart->status, bufferStart->eventTime / MILLISECOND_TICKS_PER_SECOND, elapsedTimeQs, - queueRetryParams.currentRetryCount); - sendZoneUpdate(status, elapsedTimeQs, bufferStart->endpoint); - emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl); - } -#else - emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl); -#endif -} - -void emberAfIasZoneClusterServerInitCallback(EndpointId endpoint) -{ - EmberAfIasZoneType zoneType; - if (!areZoneServerAttributesNonVolatile(endpoint)) - { - emberAfAppPrint("WARNING: ATTRIBUTES ARE NOT BEING STORED IN FLASH! "); - emberAfAppPrintln("DEVICE WILL NOT FUNCTION PROPERLY AFTER REBOOTING!!"); - } - -#ifndef EZSP_HOST - halCommonGetToken(&enrollmentMethod, TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD); -#else - enrollmentMethod = DEFAULT_ENROLLMENT_METHOD; -#endif - if (!isValidEnrollmentMode(enrollmentMethod)) - { - // Default Enrollment Method to AUTO-ENROLL-REQUEST. - enrollmentMethod = DEFAULT_ENROLLMENT_METHOD; - } - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - bufferInit(&messageQueue); -#endif - - zoneType = (EmberAfIasZoneType) EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE; - emberAfWriteAttribute(endpoint, IasZone::Id, Attributes::ZoneType::Id, (uint8_t *) &zoneType, ZCL_INT16U_ATTRIBUTE_TYPE); - - emberAfPluginIasZoneServerUpdateZoneStatus(endpoint, - 0, // status: All alarms cleared - 0); // time since status occurred -} - -void emberAfIasZoneClusterServerTickCallback(EndpointId endpoint) -{ - enrollWithClient(endpoint); -} - -uint8_t emberAfPluginIasZoneServerGetZoneId(EndpointId endpoint) -{ - uint8_t zoneId = UNDEFINED_ZONE_ID; - emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id, &zoneId, - emberAfGetDataSize(ZCL_INT8U_ATTRIBUTE_TYPE)); - return zoneId; -} - -//------------------------------------------------------------------------------ -// -// This function will verify that all attributes necessary for the IAS zone -// server to properly retain functionality through a power failure are -// non-volatile. -// -//------------------------------------------------------------------------------ -static bool areZoneServerAttributesNonVolatile(EndpointId endpoint) -{ - if (emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::IasCieAddress::Id) || - emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::ZoneState::Id) || - emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::ZoneType::Id) || - emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id)) - { - return false; - } - - return true; -} - -static void setZoneId(EndpointId endpoint, uint8_t zoneId) -{ - emberAfIasZoneClusterPrintln("IAS Zone Server Zone ID: 0x%X", zoneId); - emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id, &zoneId, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -static void unenrollSecurityDevice(EndpointId endpoint) -{ - uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - uint16_t zoneType = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE; - - emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::IasCieAddress::Id, (uint8_t *) ieeeAddress, - ZCL_NODE_ID_ATTRIBUTE_TYPE); - - emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneType::Id, (uint8_t *) &zoneType, ZCL_INT16U_ATTRIBUTE_TYPE); - - setZoneId(endpoint, UNDEFINED_ZONE_ID); - // Restore the enrollment method back to its default value. - emberAfPluginIasZoneClusterSetEnrollmentMethod(endpoint, DEFAULT_ENROLLMENT_METHOD); - updateEnrollState(endpoint, false); // enrolled? -} - -// If you leave the network, unenroll yourself. -void emberAfPluginIasZoneServerStackStatusCallback(EmberStatus status) -{ - EndpointId endpoint; - - // If the device has left the network, unenroll all endpoints on the device - // that are servers of the IAS Zone Cluster - if (status == EMBER_NETWORK_DOWN && emberAfNetworkState() == EMBER_NO_NETWORK) - { - for (uint16_t i = 0; i < emberAfEndpointCount(); i++) - { - endpoint = emberAfEndpointFromIndex(i); - if (emberAfContainsServer(endpoint, IasZone::Id)) - { - unenrollSecurityDevice(endpoint); - } - } - } - else if (status == EMBER_NETWORK_UP) - { -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - // If we're reconnecting, send any items still in the queue - emberAfIasZoneClusterPrintln("Rejoined network, retransmiting any queued event"); - emberEventControlSetActive(&emberAfPluginIasZoneServerManageQueueEventControl); -#endif - } -} - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) -EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(IasZoneStatusQueueRetryConfig * retryConfig) -{ - if (!(retryConfig->firstBackoffTimeSec) || (!retryConfig->backoffSeqCommonRatio) || - (retryConfig->maxBackoffTimeSec < retryConfig->firstBackoffTimeSec) || - (retryConfig->maxBackoffTimeSec > IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC) || (!retryConfig->maxRetryAttempts)) - { - return EMBER_BAD_ARGUMENT; - } - - queueRetryParams.config.firstBackoffTimeSec = retryConfig->firstBackoffTimeSec; - queueRetryParams.config.backoffSeqCommonRatio = retryConfig->backoffSeqCommonRatio; - queueRetryParams.config.maxBackoffTimeSec = retryConfig->maxBackoffTimeSec; - queueRetryParams.config.unlimitedRetries = retryConfig->unlimitedRetries; - queueRetryParams.config.maxRetryAttempts = retryConfig->maxRetryAttempts; - - queueRetryParams.currentBackoffTimeSec = retryConfig->firstBackoffTimeSec; - queueRetryParams.currentRetryCount = 0; - - return EMBER_SUCCESS; -} - -void emberAfIasZoneServerSetStatusQueueRetryParamsToDefault(void) -{ - queueRetryParams.config.firstBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC; - queueRetryParams.config.backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO; - queueRetryParams.config.maxBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC; -#ifdef EMBER_AF_PLUGIN_IAS_ZONE_SERVER_UNLIMITED_RETRIES - queueRetryParams.config.unlimitedRetries = true; -#else - queueRetryParams.config.unlimitedRetries = false; -#endif - queueRetryParams.config.maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS; - - queueRetryParams.currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC; - queueRetryParams.currentRetryCount = 0; -} - -void emberAfIasZoneServerDiscardPendingEventsInStatusQueue(void) -{ - emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl); - bufferInit(&messageQueue); - resetCurrentQueueRetryParams(); -} - -#if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER) -EmberStatus emberAfWwahAppEventRetryManagerConfigBackoffParamsCallback(uint8_t firstBackoffTimeSeconds, - uint8_t backoffSeqCommonRatio, - uint32_t maxBackoffTimeSeconds, - uint8_t maxRedeliveryAttempts) -{ - IasZoneStatusQueueRetryConfig retryConfig = { firstBackoffTimeSeconds, backoffSeqCommonRatio, maxBackoffTimeSeconds, - (maxRedeliveryAttempts == 0xFF), maxRedeliveryAttempts }; - - // Setting up retry parameters - return emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig); -} - -void emberAfWwahAppEventRetryManagerSetBackoffParamsToDefault(void) -{ - emberAfIasZoneServerSetStatusQueueRetryParamsToDefault(); -} -#endif // defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER) - -void emberAfPluginIasZoneServerPrintQueue(void) -{ - emberAfIasZoneClusterPrintln("%d/%d entries", messageQueue.entriesInQueue, NUM_QUEUE_ENTRIES); - for (int i = 0; i < messageQueue.entriesInQueue; i++) - { - emberAfIasZoneClusterPrintln("Entry %d: Endpoint: %d Status: %d EventTimeMs: %d", i, messageQueue.buffer[i].endpoint, - messageQueue.buffer[i].status, messageQueue.buffer[i].eventTime); - } -} - -void emberAfPluginIasZoneServerPrintQueueConfig(void) -{ - emberAfCorePrintln("First backoff time (sec): %d", queueRetryParams.config.firstBackoffTimeSec); - emberAfCorePrintln("Backoff sequence common ratio: %d", queueRetryParams.config.backoffSeqCommonRatio); - emberAfCorePrintln("Max backoff time (sec): %d", queueRetryParams.config.maxBackoffTimeSec); - emberAfCorePrintln("Max redelivery attempts: %d", queueRetryParams.config.maxRetryAttempts); -} - -#endif // defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - -// This callback will be generated any time the node receives an ACK or a NAK -// for a message transmitted for the IAS Zone Cluster Server. Note that this -// will not be called in the case that the message was not delivered to the -// destination when the destination is the only router the node is joined to. -// In that case, the command will never have been sent, as the device will have -// had no router by which to send the command. -void emberAfIasZoneClusterServerMessageSentCallback(const MessageSendDestination & destination, EmberApsFrame * apsFrame, - uint16_t msgLen, uint8_t * message, EmberStatus status) -{ -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) - uint8_t frameControl; - CommandId commandId; - - IasZoneStatusQueueEntry dummyEntry; - - // Verify that this response is for a ZoneStatusChangeNotification command - // by checking the message length, the command and direction bits of the - // Frame Control byte, and the command ID - if (msgLen < IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX) - { - return; - } - - frameControl = message[ZCL_FRAME_CONTROL_IDX]; - if (!(frameControl & ZCL_CLUSTER_SPECIFIC_COMMAND) || !(frameControl & ZCL_FRAME_CONTROL_SERVER_TO_CLIENT)) - { - return; - } - - commandId = message[IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX]; - if (commandId != ZoneStatusChangeNotification::Id) - { - return; - } - - // If a change status change notification command is not received by the - // client, delay the option specified amount of time and try to resend it. - // The event handler will perform the retransmit per the preset queue retry - // parameters, and the original send request will handle populating the buffer. - // Do not try to retransmit again if the maximum number of retries attempts - // is reached, this is however discarded if configured for unlimited retries. - if ((status == EMBER_DELIVERY_FAILED) && - (queueRetryParams.config.unlimitedRetries || - (queueRetryParams.currentRetryCount < queueRetryParams.config.maxRetryAttempts))) - { - queueRetryParams.currentRetryCount++; - - emberAfIasZoneClusterPrintln("Status command update failed to send... Retrying in %d seconds...", - queueRetryParams.currentBackoffTimeSec); - - // Delay according to the current retransmit backoff time. - emberEventControlSetDelayMS(emberAfPluginIasZoneServerManageQueueEventControl, - queueRetryParams.currentBackoffTimeSec * MILLISECOND_TICKS_PER_SECOND); - - // The backoff time needs to be increased if the maximum backoff time is not reached yet. - if ((queueRetryParams.currentBackoffTimeSec * queueRetryParams.config.backoffSeqCommonRatio) <= - queueRetryParams.config.maxBackoffTimeSec) - { - queueRetryParams.currentBackoffTimeSec *= queueRetryParams.config.backoffSeqCommonRatio; - } - } - else - { - // If a command message was sent or max redelivery attempts were reached, - // remove it from the queue and move on to the next queued message until the queue is empty. - if (status == EMBER_SUCCESS) - { - emberAfIasZoneClusterPrintln("\nZone update successful, remove entry from queue"); - } - else - { - emberAfIasZoneClusterPrintln("\nZone update unsuccessful, max retry attempts reached, remove entry from queue"); - } - popFromBuffer(&messageQueue, &dummyEntry); - - // Reset queue retry parameters. - resetCurrentQueueRetryParams(); - - if (messageQueue.entriesInQueue) - { - emberEventControlSetActive(&emberAfPluginIasZoneServerManageQueueEventControl); - } - } -#endif -} - -#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE) -static void bufferInit(IasZoneStatusQueue * ring) -{ - ring->entriesInQueue = 0; - ring->startIdx = 0; - ring->lastIdx = NUM_QUEUE_ENTRIES - 1; -} - -// Add the entry to the buffer by copying, returning the index at which it was -// added. If the buffer is full, return -1, but still copy the entry over the -// last item of the buffer, to ensure that the last item in the buffer is -// always representative of the last known device state. -static int16_t copyToBuffer(IasZoneStatusQueue * ring, const IasZoneStatusQueueEntry * entry) -{ - if (ring->entriesInQueue == NUM_QUEUE_ENTRIES) - { - ring->buffer[ring->lastIdx] = *entry; - return -1; - } - - // Increment the last pointer. If it rolls over the size, circle it back to - // zero. - ring->lastIdx++; - if (ring->lastIdx >= NUM_QUEUE_ENTRIES) - { - ring->lastIdx = 0; - } - - ring->buffer[ring->lastIdx].endpoint = entry->endpoint; - ring->buffer[ring->lastIdx].status = entry->status; - ring->buffer[ring->lastIdx].eventTime = entry->eventTime; - - ring->entriesInQueue++; - return ring->lastIdx; -} - -// Return the idx of the popped entry, or -1 if the buffer was empty. -static int16_t popFromBuffer(IasZoneStatusQueue * ring, IasZoneStatusQueueEntry * entry) -{ - int16_t retVal; - - if (ring->entriesInQueue == 0) - { - return -1; - } - - // Copy out the first entry, then increment the start pointer. If it rolls - // over, circle it back to zero. - *entry = ring->buffer[ring->startIdx]; - retVal = ring->startIdx; - - ring->startIdx++; - if (ring->startIdx >= NUM_QUEUE_ENTRIES) - { - ring->startIdx = 0; - } - - ring->entriesInQueue--; - - return retVal; -} - -uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry * entry) -{ - System::Clock::Milliseconds64 currentTimeMs = System::SystemClock().GetMonotonicMilliseconds64(); - int64_t deltaTimeMs = currentTimeMs.count() - entry->eventTime.count(); - - if (deltaTimeMs < 0) - { - deltaTimeMs = -deltaTimeMs + (0xFFFFFFFF - currentTimeMs); - } - - return deltaTimeMs / MILLISECOND_TICKS_PER_QUARTERSECOND; -} -#endif - -void MatterIasZonePluginServerInitCallback() {} diff --git a/src/app/clusters/ias-zone-server/ias-zone-server.h b/src/app/clusters/ias-zone-server/ias-zone-server.h deleted file mode 100644 index 0630e96dff3ebf..00000000000000 --- a/src/app/clusters/ias-zone-server/ias-zone-server.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#define EM_AF_UNKNOWN_ENDPOINT 0 -// Absolute max backoff time, at least one retry a day -// (ie. 24 hours * 60 minutes * 60 seconds). -#define IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC (24 * 60 * 60) - -// Definitions for the IAS Zone enrollment mode. -typedef enum -{ - EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR = 0x00, - EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE = 0x01, - EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST = 0x02 -} EmberAfIasZoneEnrollmentMode; - -// Status queue retry parameters -typedef struct -{ - uint8_t firstBackoffTimeSec; - uint8_t backoffSeqCommonRatio; - uint32_t maxBackoffTimeSec; - bool unlimitedRetries; - uint8_t maxRetryAttempts; -} IasZoneStatusQueueRetryConfig; - -/** @brief Updates the zone status for an endpoint. - * - * This function will update the zone status attribute of the specified endpoint - * using the specified new zone status. It will then notify the CIE of the - * updated status. - * - * @param endpoint The endpoint whose zone status attribute is to be updated. - * @param newStatus The new status to write to the attribute. - * @param timeSinceStatusOccurredQs The amount of time (in quarter seconds) that - * has passed since the status change occurred. - * - * @return EMBER_SUCCESS if the attribute update and notify succeeded, error - * code otherwise. - */ -EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(chip::EndpointId endpoint, uint16_t newStatus, - uint16_t timeSinceStatusOccurredQs); - -/** @brief Gets the CIE assigned zone id of a given endpoint. - * - * This function will return the zone ID that was assigned to the given - * endpoint by the CIE at time of enrollment. - * - * @param endpoint The endpoint whose ID is to be queried. - * - * @return The zone ID assigned by the CIE at time of enrollment. - */ -uint8_t emberAfPluginIasZoneServerGetZoneId(chip::EndpointId endpoint); - -/** @brief Determines the enrollment status of a given endpoint. - * - * This function will return true or false depending on whether the specified - * endpoint has undergone IAS Zone Enrollment. - * - * @param endpoint The endpoint whose enrollment status is to be queried. - * - * @return True if enrolled, false otherwise. - */ -bool emberAfIasZoneClusterAmIEnrolled(chip::EndpointId endpoint); - -/** @brief Set the enrollment status. - * - * This function will return the status of the set enrollment method attempt. - * - * @param endpoint The endpoint whose enrollment method is to be set - * @param method The enrollment method that should be set - * - * @return An ::EmberAfStatus value indicating the status of the set action. - */ -EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(chip::EndpointId endpoint, EmberAfIasZoneEnrollmentMode method); - -/** @brief Configure the retry parameters of the status queue. - * - * This function will configure the status queue retry parameters. - * - * @param retryConfig Status queue retry configuration. - */ -EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(IasZoneStatusQueueRetryConfig * retryConfig); - -/** @brief Set the retry parameters of the status queue to default. - * - * This function will set the status queue retry parameters to their default values. - */ -void emberAfIasZoneServerSetStatusQueueRetryParamsToDefault(void); - -/** @brief Discards any pendint events in the status queue and sets it inactive. - * - * This function will discard any pending event pending in the status queue. - * Also, the status queue event control manager will be inactivated. - */ -void emberAfIasZoneServerDiscardPendingEventsInStatusQueue(void); - -/** @brief Prints information on the satus queue. - */ -void emberAfPluginIasZoneServerPrintQueue(void); - -/** @brief Prints the satus queue config. - */ -void emberAfPluginIasZoneServerPrintQueueConfig(void); diff --git a/src/app/zap-templates/zcl/data-model/silabs/types-silabs.xml b/src/app/zap-templates/zcl/data-model/silabs/types-silabs.xml index 10b1e35686fca3..89e3ebb75ab0ee 100644 --- a/src/app/zap-templates/zcl/data-model/silabs/types-silabs.xml +++ b/src/app/zap-templates/zcl/data-model/silabs/types-silabs.xml @@ -43,32 +43,6 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/zzz_generated/app-common/app-common/zap-generated/enums.h b/zzz_generated/app-common/app-common/zap-generated/enums.h index d8c3a44aec3801..e54d42ba5d6843 100644 --- a/zzz_generated/app-common/app-common/zap-generated/enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/enums.h @@ -688,26 +688,6 @@ enum EmberAfWiFiVersionType : uint8_t #define EMBER_AF_FEATURE_POSITION_AWARE_TILT_OFFSET (4) #define EMBER_AF_GROUP_CLUSTER_FEATURE_GROUP_NAMES (1) #define EMBER_AF_GROUP_CLUSTER_FEATURE_GROUP_NAMES_OFFSET (0) -#define EMBER_AF_IAS_ZONE_STATUS_ALARM1 (1) -#define EMBER_AF_IAS_ZONE_STATUS_ALARM1_OFFSET (0) -#define EMBER_AF_IAS_ZONE_STATUS_ALARM2 (2) -#define EMBER_AF_IAS_ZONE_STATUS_ALARM2_OFFSET (1) -#define EMBER_AF_IAS_ZONE_STATUS_TAMPER (4) -#define EMBER_AF_IAS_ZONE_STATUS_TAMPER_OFFSET (2) -#define EMBER_AF_IAS_ZONE_STATUS_BATTERY (8) -#define EMBER_AF_IAS_ZONE_STATUS_BATTERY_OFFSET (3) -#define EMBER_AF_IAS_ZONE_STATUS_SUPERVISION_REPORTS (16) -#define EMBER_AF_IAS_ZONE_STATUS_SUPERVISION_REPORTS_OFFSET (4) -#define EMBER_AF_IAS_ZONE_STATUS_RESTORE_REPORTS (32) -#define EMBER_AF_IAS_ZONE_STATUS_RESTORE_REPORTS_OFFSET (5) -#define EMBER_AF_IAS_ZONE_STATUS_TROUBLE (64) -#define EMBER_AF_IAS_ZONE_STATUS_TROUBLE_OFFSET (6) -#define EMBER_AF_IAS_ZONE_STATUS_AC (128) -#define EMBER_AF_IAS_ZONE_STATUS_AC_OFFSET (7) -#define EMBER_AF_IAS_ZONE_STATUS_TEST (256) -#define EMBER_AF_IAS_ZONE_STATUS_TEST_OFFSET (8) -#define EMBER_AF_IAS_ZONE_STATUS_BATTERY_DEFECT (512) -#define EMBER_AF_IAS_ZONE_STATUS_BATTERY_DEFECT_OFFSET (9) #define EMBER_AF_KEYPAD_INPUT_FEATURE_NAVIGATION_KEY_CODES (1) #define EMBER_AF_KEYPAD_INPUT_FEATURE_NAVIGATION_KEY_CODES_OFFSET (0) #define EMBER_AF_KEYPAD_INPUT_FEATURE_LOCATION_KEYS (2) @@ -866,12 +846,6 @@ enum EmberAfWiFiVersionType : uint8_t #define EMBER_AF_SIMPLE_BITMAP_VALUE_C_OFFSET (2) #define EMBER_AF_SOFTWARE_DIAGNOSTICS_FEATURE_WATER_MARKS (1) #define EMBER_AF_SOFTWARE_DIAGNOSTICS_FEATURE_WATER_MARKS_OFFSET (0) -#define EMBER_AF_SQUAWK_INFO_MODE (240) -#define EMBER_AF_SQUAWK_INFO_MODE_OFFSET (4) -#define EMBER_AF_SQUAWK_INFO_STROBE (8) -#define EMBER_AF_SQUAWK_INFO_STROBE_OFFSET (3) -#define EMBER_AF_SQUAWK_INFO_LEVEL (3) -#define EMBER_AF_SQUAWK_INFO_LEVEL_OFFSET (0) #define EMBER_AF_START_TIME_MINUTES (63) #define EMBER_AF_START_TIME_MINUTES_OFFSET (0) #define EMBER_AF_START_TIME_TIME_ENCODING (192) @@ -922,12 +896,6 @@ enum EmberAfWiFiVersionType : uint8_t #define EMBER_AF_TIME_STATUS_MASK_SUPERSEDING_OFFSET (3) #define EMBER_AF_UNIT_LOCALIZATION_FEATURE_TEMPERATURE_UNIT (1) #define EMBER_AF_UNIT_LOCALIZATION_FEATURE_TEMPERATURE_UNIT_OFFSET (0) -#define EMBER_AF_WARNING_INFO_MODE (240) -#define EMBER_AF_WARNING_INFO_MODE_OFFSET (4) -#define EMBER_AF_WARNING_INFO_STROBE (12) -#define EMBER_AF_WARNING_INFO_STROBE_OFFSET (2) -#define EMBER_AF_WARNING_INFO_SIREN_LEVEL (3) -#define EMBER_AF_WARNING_INFO_SIREN_LEVEL_OFFSET (0) #define EMBER_AF_WI_FI_NETWORK_DIAGNOSTICS_FEATURE_PACKET_COUNTS (1) #define EMBER_AF_WI_FI_NETWORK_DIAGNOSTICS_FEATURE_PACKET_COUNTS_OFFSET (0) #define EMBER_AF_WI_FI_NETWORK_DIAGNOSTICS_FEATURE_ERROR_COUNTS (2)