blob: 5b2aee2c5337e3ef6adf61daaaef4545b2fd8e6a [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 On Off Cluster Server
*/
#include "on-off-server.h"
#include "chip-zcl.h"
#include "gen.h"
// Globals
static void setOnOffHandler(const ChipZclCommandContext_t * context, bool onOff);
static bool getOnOff(ChipZclEndpointId_t endpointId);
void chipZclClusterOnOffServerCommandOffRequestHandler(const ChipZclCommandContext_t * context,
const ChipZclClusterOnOffServerCommandOffRequest_t * request)
{
chipZclCorePrintln("RX: Off");
setOnOffHandler(context, false); // off
}
void chipZclClusterOnOffServerCommandOnRequestHandler(const ChipZclCommandContext_t * context,
const ChipZclClusterOnOffServerCommandOnRequest_t * request)
{
chipZclCorePrintln("RX: On");
setOnOffHandler(context, true); // on
}
void chipZclClusterOnOffServerCommandToggleRequestHandler(const ChipZclCommandContext_t * context,
const ChipZclClusterOnOffServerCommandToggleRequest_t * request)
{
chipZclCorePrintln("RX: Toggle");
setOnOffHandler(context, !getOnOff(context->endpointId));
}
static bool getOnOff(ChipZclEndpointId_t endpointId)
{
bool onOff;
if (chipZclReadAttribute(endpointId, &chipZclClusterOnOffServerSpec, CHIP_ZCL_CLUSTER_ON_OFF_SERVER_ATTRIBUTE_ON_OFF, &onOff,
sizeof(onOff)) == CHIP_ZCL_STATUS_SUCCESS)
{
return onOff;
}
else
{
return false;
}
}
static void setOnOff(ChipZclEndpointId_t endpointId, bool onOff)
{
chipZclWriteAttribute(endpointId, &chipZclClusterOnOffServerSpec, CHIP_ZCL_CLUSTER_ON_OFF_SERVER_ATTRIBUTE_ON_OFF, &onOff,
sizeof(onOff));
}
static void setOnOffHandler(const ChipZclCommandContext_t * context, bool onOff)
{
setOnOff(context->endpointId, onOff);
chipZclSendDefaultResponse(context, CHIP_ZCL_STATUS_SUCCESS);
}
#ifdef CHIP_AF_API_ZCL_SCENES_SERVER
// Scenes callback handlers...
void zapOnOffServerEraseSceneHandler(uint8_t tableIdx)
{
ChipZclOnOffSceneSubTableEntry_t entry;
entry.hasOnOffValue = false;
saveSceneSubTableEntry(entry, tableIdx);
}
bool zapOnOffServerAddSceneHandler(ChipZclClusterId_t clusterId, uint8_t tableIdx, const uint8_t * sceneData, uint8_t length)
{
if (clusterId == CHIP_ZCL_CLUSTER_ON_OFF)
{
if (length < 1)
{
return false; // ext field format error (OnOffValue byte must be present).
}
// Extract bytes from input data block and update scene subtable fields.
ChipZclOnOffSceneSubTableEntry_t entry = { 0 };
uint8_t * pData = (uint8_t *) sceneData;
// We only know of one extension for the On/Off cluster and it is just one byte,
// which means we can skip some logic for this cluster.
// If other extensions are added in this cluster, more logic will be needed here.
entry.hasOnOffValue = true;
entry.onOffValue = zapPluginScenesServerGetUint8FromBuffer(&pData);
saveSceneSubTableEntry(entry, tableIdx);
return true;
}
return false;
}
void zapOnOffServerRecallSceneHandler(ChipZclEndpointId_t endpointId, uint8_t tableIdx, uint32_t transitionTime100mS)
{
// Handles the recallScene command for the onOff cluster.
// Note- this handler presently just updates (writes) the relevant cluster
// attribute(s), in a production system this could be replaced by a call
// to the relevant onOff command handler to actually change the hw state.
ChipZclOnOffSceneSubTableEntry_t entry;
retrieveSceneSubTableEntry(entry, tableIdx);
if (entry.hasOnOffValue)
{
chipZclWriteAttribute(endpointId, &chipZclClusterOnOffServerSpec, CHIP_ZCL_CLUSTER_ON_OFF_SERVER_ATTRIBUTE_ON_OFF,
(uint8_t *) &entry.onOffValue, sizeof(entry.onOffValue));
}
}
void zapOnOffServerStoreSceneHandler(ChipZclEndpointId_t endpointId, uint8_t tableIdx)
{
ChipZclOnOffSceneSubTableEntry_t entry;
entry.hasOnOffValue =
(chipZclReadAttribute(endpointId, &chipZclClusterOnOffServerSpec, CHIP_ZCL_CLUSTER_ON_OFF_SERVER_ATTRIBUTE_ON_OFF,
(uint8_t *) &entry.onOffValue, sizeof(entry.onOffValue)) == CHIP_ZCL_STATUS_SUCCESS);
saveSceneSubTableEntry(entry, tableIdx);
}
void zapOnOffServerCopySceneHandler(uint8_t srcTableIdx, uint8_t dstTableIdx)
{
ChipZclOnOffSceneSubTableEntry_t entry;
retrieveSceneSubTableEntry(entry, srcTableIdx);
saveSceneSubTableEntry(entry, dstTableIdx);
}
void zapOnOffServerViewSceneHandler(uint8_t tableIdx, uint8_t ** ppExtFldData)
{
ChipZclOnOffSceneSubTableEntry_t entry;
retrieveSceneSubTableEntry(entry, tableIdx);
if (entry.hasOnOffValue)
{
zapPluginScenesServerPutUint16InBuffer(ppExtFldData, CHIP_ZCL_CLUSTER_ON_OFF);
zapPluginScenesServerPutUint8InBuffer(ppExtFldData, 1); // length=1
zapPluginScenesServerPutUint8InBuffer(ppExtFldData, entry.onOffValue);
}
}
void zapOnOffServerPrintInfoSceneHandler(uint8_t tableIdx)
{
ChipZclOnOffSceneSubTableEntry_t entry;
retrieveSceneSubTableEntry(entry, tableIdx);
zapCorePrint(" on/off:%x", entry.onOffValue);
}
#endif