blob: c94f966e5ca1b581c8d75e1f2204af12926f27d3 [file] [log] [blame]
/**
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2018 Silicon Laboratories Inc. www.silabs.com
*
* 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.
*/
/**
* @file
* This file provides an implementation of the CHIP ZCL Application
* Layer's Identify Cluster Server
*/
#include "chip-zcl.h"
#include "gen.h"
static uint16_t getIdentifyTimeS(ChipZclEndpointId_t endpointId);
static void setIdentifyTimeS(ChipZclEndpointId_t endpointId, uint16_t identifyTimeS, bool external);
static bool allIdentifyTimesAre0(void);
ChipZclEventControl emZclIdentifyServerEventControl;
static bool notify = true;
void emZclIdentifyServerPostAttributeChangeHandler(ChipZclEndpointId_t endpointId, const ChipZclClusterSpec_t * clusterSpec,
ChipZclAttributeId_t attributeId, const void * buffer, size_t bufferLength)
{
if (chipZclAreClusterSpecsEqual(&chipZclClusterIdentifyServerSpec, clusterSpec) &&
attributeId == CHIP_ZCL_CLUSTER_IDENTIFY_SERVER_ATTRIBUTE_IDENTIFY_TIME)
{
uint16_t identifyTimeS = getIdentifyTimeS(endpointId);
if (identifyTimeS == 0)
{
if (chipZclEventControlGetActive(emZclIdentifyServerEventControl))
{
if (allIdentifyTimesAre0())
{
chipZclEventControlSetInactive(emZclIdentifyServerEventControl);
}
chipZclIdentifyServerStopIdentifyingCallback(endpointId);
}
}
else
{
if (notify)
{
chipZclIdentifyServerStartIdentifyingCallback(endpointId, identifyTimeS);
}
chipZclEventControlSetDelayMS(emZclIdentifyServerEventControl, MILLISECOND_TICKS_PER_SECOND);
}
}
}
void emZclIdentifyServerEventHandler(void)
{
for (ChipZclEndpointIndex_t index = 0; index < CHIP_ZCL_CLUSTER_IDENTIFY_SERVER_COUNT; index++)
{
ChipZclEndpointId_t endpointId = chipZclEndpointIndexToId(index, &chipZclClusterIdentifyServerSpec);
uint16_t identifyTimeS = getIdentifyTimeS(endpointId);
if (identifyTimeS > 0)
{
setIdentifyTimeS(endpointId, identifyTimeS - 1,
false); // internal change
}
}
}
void chipZclClusterIdentifyServerCommandIdentifyRequestHandler(const ChipZclCommandContext_t * context,
const ChipZclClusterIdentifyServerCommandIdentifyRequest_t * request)
{
chipZclCorePrintln("RX: Identify");
setIdentifyTimeS(context->endpointId, request->identifyTime,
true); // external change
chipZclSendDefaultResponse(context, CHIP_ZCL_STATUS_SUCCESS);
}
void chipZclClusterIdentifyServerCommandIdentifyQueryRequestHandler(
const ChipZclCommandContext_t * context, const ChipZclClusterIdentifyServerCommandIdentifyQueryRequest_t * request)
{
ChipZclClusterIdentifyServerCommandIdentifyQueryResponse_t response;
chipZclCorePrintln("RX: IdentifyQuery");
response.timeout = getIdentifyTimeS(context->endpointId);
chipZclSendClusterIdentifyServerCommandIdentifyQueryResponse(context, &response);
}
static uint16_t getIdentifyTimeS(ChipZclEndpointId_t endpointId)
{
uint16_t identifyTimeS;
if (chipZclReadAttribute(endpointId, &chipZclClusterIdentifyServerSpec,
CHIP_ZCL_CLUSTER_IDENTIFY_SERVER_ATTRIBUTE_IDENTIFY_TIME, &identifyTimeS,
sizeof(identifyTimeS)) == CHIP_ZCL_STATUS_SUCCESS)
{
return identifyTimeS;
}
else
{
return 0;
}
}
static void setIdentifyTimeS(ChipZclEndpointId_t endpointId, uint16_t identifyTimeS, bool external)
{
notify = external;
chipZclWriteAttribute(endpointId, &chipZclClusterIdentifyServerSpec, CHIP_ZCL_CLUSTER_IDENTIFY_SERVER_ATTRIBUTE_IDENTIFY_TIME,
&identifyTimeS, sizeof(identifyTimeS));
notify = true;
}
static bool allIdentifyTimesAre0(void)
{
for (ChipZclEndpointIndex_t index = 0; index < CHIP_ZCL_CLUSTER_IDENTIFY_SERVER_COUNT; index++)
{
ChipZclEndpointId_t endpointId = chipZclEndpointIndexToId(index, &chipZclClusterIdentifyServerSpec);
if (getIdentifyTimeS(endpointId) > 0)
{
return false;
}
}
return true;
}