Skip to content

Commit

Permalink
Add new on/off cluster implementation based on the Silicon Labs Zigbe…
Browse files Browse the repository at this point in the history
…ePro code (#1609)

* Add initial Silicon Labs ZCL data model files.

All except type_stubs.h come from
#1164

types_stub.h comes from
#1425 (comment)
and
#1425 (comment)

* Add generated files from the Silicon Labs sample app provided by Ezra Hale.

The sample app only implements the On/Off cluster.

Most of the files have the same exact name as in the sample app, with
the following exceptions:

* endpoint_config.h was originally ZigbeeMinimalSoc_endpoint_config.h
* gen_config.h was originally ZigbeeMinimalSoc.h
* gen_tokens.h was originally ZigbeeMinimalSoc_tokens.h

* Fix compile errors in types_stub.h

This corrects various obvious problems in the file that prevent files
that include it from compiling.

* Fix #includes in the imported Silicon Labs code to not include nonexistent things.

There are a few categories of fixes here:

* Adjusting paths to match out directory structure (which is not
  identical to the one Silicon Labs apps normally use).
* Commenting out includes of headers that we don't think we actually
  need.
* Hardcoding some header names that are represented by preprocessor
  macros in the Silicon Labs build system.

* Include various missing headers to allow the Silicon Labs code to compile.

* Comment or ifdef out various calls to Silicon Labs functions we are not pulling in.

For some of these we are not even pulling in the declaration.  For
some, we have a declaration, but no definition.  At first glance, all
of these are either there to solve problems that we will solve in a
different way in CHIP, or the callsites are in code that CHIP is
almost certainly not going to use.

* Copy declaration of emberAfPluginOnOffClusterServerPostInitCallback from the zll-color-light sample app in the SiLabs ZCL code.

* Restyle the Silicon Labs files to CHIP style

* Add utilities for encoding and decoding messages that the Silicon Labs ZigbeePro implementation can handle.

The actual encoding we are using is not quite the APS encoding, but
it's still a throwaway, so that does not matter too much.

* Switch the echo server to using the new On/Off implementation.

We no longer compile the Dotdot-based ZCL data model files into
libCHIP, because those have symbols whose names conflict with the new
ZigbeePro-based ZCL data model files.

* Switch command-line chip-tool to using the new On/Off implementation.

* Switch iOS CHIPTool to using the new On/Off implementation.

Co-authored-by: Bhaskar Sarma <[email protected]>
  • Loading branch information
bzbarsky-apple and Bhaskar Sarma authored Jul 21, 2020
1 parent b61a35b commit 4dd5230
Show file tree
Hide file tree
Showing 58 changed files with 62,682 additions and 101 deletions.
1 change: 1 addition & 0 deletions config/nrf5/nrf5-chip.mk
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ STD_LDFLAGS += -L$(CHIP_OUTPUT_DIR)/lib
STD_LIBS += \
-lDeviceLayer \
-lCHIP \
-lCHIPDataModel \
-lInetLayer \
-lSystemLayer \
-llwip
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,7 @@ src/Makefile
src/include/Makefile
src/app/Makefile
src/app/chip-zcl/Makefile
src/app/chip-zcl-zpro/Makefile
src/app/gen/Makefile
src/app/plugin/Makefile
src/app/plugin/tests/Makefile
Expand Down
52 changes: 15 additions & 37 deletions examples/chip-tool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@

extern "C" {
#include "chip-zcl/chip-zcl.h"
#include "gen/gen-cluster-id.h"
#include "gen/gen-command-id.h"
#include "gen/gen-types.h"
} // extern "C"

#include "chip-zcl/chip-zcl-zpro-codec.h"

// Delay, in seconds, between sends for the echo case.
#define SEND_DELAY 5

Expand Down Expand Up @@ -202,7 +201,7 @@ bool DetermineCommand(int argc, char * argv[], Command * command)

union CommandArgs
{
ChipZclEndpointId_t endpointId;
uint8_t endpointId;
};

bool DetermineCommandArgs(int argc, char * argv[], Command command, CommandArgs * commandArgs)
Expand Down Expand Up @@ -266,51 +265,37 @@ void DoEcho(DeviceController::ChipDeviceController * controller, const IPAddress

// Handle the on/off/toggle case, where we are sending a ZCL command and not
// expecting a response at all.
void DoOnOff(DeviceController::ChipDeviceController * controller, Command command, ChipZclEndpointId_t endpoint)
void DoOnOff(DeviceController::ChipDeviceController * controller, Command command, uint8_t endpoint)
{
ChipZclCommandId_t zclCommand;
// Make sure our buffer is big enough, but this will need a better setup!
static const size_t bufferSize = 1024;
auto * buffer = System::PacketBuffer::NewWithAvailableSize(bufferSize);

uint16_t dataLength = 0;
switch (command)
{
case Command::Off:
zclCommand = CHIP_ZCL_CLUSTER_ON_OFF_SERVER_COMMAND_OFF;
dataLength = encodeOffCommand(buffer->Start(), bufferSize, endpoint);
break;
case Command::On:
zclCommand = CHIP_ZCL_CLUSTER_ON_OFF_SERVER_COMMAND_ON;
dataLength = encodeOnCommand(buffer->Start(), bufferSize, endpoint);
break;
case Command::Toggle:
zclCommand = CHIP_ZCL_CLUSTER_ON_OFF_SERVER_COMMAND_TOGGLE;
dataLength = encodeToggleCommand(buffer->Start(), bufferSize, endpoint);
break;
default:
fprintf(stderr, "Unknown command: %d\n", command);
return;
}

// Make sure our buffer is big enough, but this will need a better setup!
static const size_t bufferSize = 1024;
auto * buffer = System::PacketBuffer::NewWithAvailableSize(bufferSize);

ChipZclBuffer_t * zcl_buffer = (ChipZclBuffer_t *) buffer;
ChipZclCommandContext_t ctx = {
endpoint, // endpointId
CHIP_ZCL_CLUSTER_ON_OFF, // clusterId
true, // clusterSpecific
false, // mfgSpecific
0, // mfgCode
zclCommand, // commandId
ZCL_DIRECTION_CLIENT_TO_SERVER, // direction
0, // payloadStartIndex
nullptr, // request
nullptr // response
};
chipZclEncodeZclHeader(zcl_buffer, &ctx);
buffer->SetDataLength(dataLength);

#ifdef DEBUG
const size_t data_len = chipZclBufferDataLength(zcl_buffer);
const size_t data_len = buffer->DataLength();

fprintf(stderr, "SENDING: %zu ", data_len);
for (size_t i = 0; i < data_len; ++i)
{
fprintf(stderr, "%d ", chipZclBufferPointer(zcl_buffer)[i]);
fprintf(stderr, "%d ", buffer->Start()[i]);
}
fprintf(stderr, "\n");
#endif
Expand Down Expand Up @@ -362,10 +347,3 @@ int main(int argc, char * argv[])

return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE;
}

extern "C" {
// We have to have this empty callback, because the ZCL code links against it.
void chipZclPostAttributeChangeCallback(uint8_t endpoint, ChipZclClusterId clusterId, ChipZclAttributeId attributeId, uint8_t mask,
uint16_t manufacturerCode, uint8_t type, uint8_t size, uint8_t * value)
{}
} // extern "C"
2 changes: 1 addition & 1 deletion examples/wifi-echo/server/esp32/main/CHIPDeviceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ CHIP_ERROR CHIPDeviceManager::Init(CHIPDeviceManagerCallbacks * cb)
}

extern "C" {
void chipZclPostAttributeChangeCallback(uint8_t endpoint, ChipZclClusterId clusterId, ChipZclAttributeId attributeId, uint8_t mask,
void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clusterId, EmberAfAttributeId attributeId, uint8_t mask,
uint16_t manufacturerCode, uint8_t type, uint8_t size, uint8_t * value)
{
CHIPDeviceManagerCallbacks * cb = CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks();
Expand Down
45 changes: 37 additions & 8 deletions examples/wifi-echo/server/esp32/main/DataModelHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
#include "LEDWidget.h"

extern "C" {
#include "chip-zcl/chip-zcl.h"
#include "gen/gen-cluster-id.h"
#include "gen/gen-types.h"
#include "attribute-storage.h"
#include "chip-zcl/chip-zcl-zpro-codec.h"
#include "gen/attribute-id.h"
#include "gen/cluster-id.h"
#include "gen/znet-bookkeeping.h"
#include "util.h"
}

using namespace ::chip;
Expand All @@ -38,19 +41,45 @@ static const char * TAG = "data_model_server";

void InitDataModelHandler()
{
chipZclEndpointInit();
emberAfEndpointConfigure();
emAfInit();
}

void HandleDataModelMessage(System::PacketBuffer * buffer)
{
ChipZclStatus_t zclStatus = chipZclProcessIncoming((ChipZclBuffer_t *) buffer);
if (zclStatus == CHIP_ZCL_STATUS_SUCCESS)
EmberApsFrame frame;
bool ok = extractApsFrame(buffer->Start(), buffer->DataLength(), &frame);
if (ok)
{
ESP_LOGI(TAG, "Data model processing success!");
ESP_LOGI(TAG, "APS frame processing success!");
}
else
{
ESP_LOGI(TAG, "Data model processing failure: %d", zclStatus);
ESP_LOGI(TAG, "APS frame processing failure");
System::PacketBuffer::Free(buffer);
return;
}

// FIXME: Callee needs to be told the buffer length, so it can fail out if
// we don't have enough buffer!!!
void * raw_message;
uint32_t messageLen = extractMessage(buffer->Start(), &raw_message);
auto message = static_cast<uint8_t *>(raw_message);

ok = emberAfProcessMessage(&frame,
0, // type
message, messageLen,
0, // source node id
NULL);

System::PacketBuffer::Free(buffer);

if (ok)
{
ESP_LOGI(TAG, "Data model processing success!");
}
else
{
ESP_LOGI(TAG, "Data model processing failure");
}
}
11 changes: 8 additions & 3 deletions examples/wifi-echo/server/esp32/main/EchoDeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
#include "LEDWidget.h"
#include <inet/IPAddress.h>

extern "C" {
#include "gen/attribute-id.h"
#include "gen/cluster-id.h"
} // extern "C"

static const char * TAG = "echo-devicecallbacks";
using namespace ::chip::Inet;
using namespace ::chip::DeviceLayer;
Expand Down Expand Up @@ -70,17 +75,17 @@ void EchoDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, int
}
}

void EchoDeviceCallbacks::PostAttributeChangeCallback(uint8_t endpoint, ChipZclClusterId clusterId, ChipZclAttributeId attributeId,
void EchoDeviceCallbacks::PostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clusterId, EmberAfAttributeId attributeId,
uint8_t mask, uint16_t manufacturerCode, uint8_t type, uint8_t size,
uint8_t * value)
{
if (clusterId != CHIP_ZCL_CLUSTER_ON_OFF)
if (clusterId != ZCL_ON_OFF_CLUSTER_ID)
{
ESP_LOGI(TAG, "Unknown cluster ID: %d", clusterId);
return;
}

if (attributeId != CHIP_ZCL_CLUSTER_ON_OFF_SERVER_ATTRIBUTE_ON_OFF)
if (attributeId != ZCL_ON_OFF_ATTRIBUTE_ID)
{
ESP_LOGI(TAG, "Unknown attribute ID: %d", attributeId);
return;
Expand Down
162 changes: 162 additions & 0 deletions examples/wifi-echo/server/esp32/main/af-main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/**
*
* 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.
*/

/**
*
* Copyright (c) 2020 Silicon Labs
*
* 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
* @brief
*******************************************************************************
******************************************************************************/

#ifndef SILABS_AF_MAIN_H
#define SILABS_AF_MAIN_H

#include "af-types.h"

//#include CONFIGURATION_HEADER
//#include PLATFORM_HEADER // Micro and compiler specific typedefs and macros
//#include "stack/include/ember-types.h"

#define MFG_STRING_MAX_LENGTH 16

typedef struct
{
EmberAfMessageSentFunction callback;
uint8_t tag;
} CallbackTableEntry;

#if defined(EZSP_HOST)
bool emberAfMemoryByteCompare(const uint8_t * pointer, uint8_t count, uint8_t byteValue);
#else
bool emMemoryByteCompare(const uint8_t * bytes, uint8_t count, uint8_t target);

#define emberAfMemoryByteCompare(pointer, count, byteValue) emMemoryByteCompare((pointer), (count), (byteValue))
#endif

// returnData must be MFG_STRING_MAX_LENGTH in length and
// is NOT expected to be NULL terminated (could be though)
void emberAfGetMfgString(uint8_t * returnData);

// Functions common to both SOC and Host versions of the application.
void emAfInitializeMessageSentCallbackArray(void);

EmberAfCbkeKeyEstablishmentSuite emberAfIsFullSmartEnergySecurityPresent(void);

#if defined(EZSP_HOST)
void emAfClearNetworkCache(uint8_t networkIndex);
#else
#define emAfClearNetworkCache(index)
uint8_t emAfCopyMessageIntoRamBuffer(EmberMessageBuffer message, uint8_t * buffer, uint16_t bufLen);
#endif

#if defined EZSP_HOST
// utility for setting an EZSP config value and printing the result
EzspStatus emberAfSetEzspConfigValue(EzspConfigId configId, uint16_t value, const char * configIdName);

// utility for setting an EZSP policy and printing the result
EzspStatus emberAfSetEzspPolicy(EzspPolicyId policyId, EzspDecisionId decisionId, const char * policyName,
const char * decisionName);

// utility for setting an EZSP value and printing the result
EzspStatus emberAfSetEzspValue(EzspValueId valueId, uint8_t valueLength, uint8_t * value, const char * valueName);

bool emberAfNcpNeedsReset(void);

#endif // EZSP_HOST

void emAfPrintStatus(const char * task, EmberStatus status);

uint8_t emberAfGetSecurityLevel(void);
uint8_t emberAfGetKeyTableSize(void);
uint8_t emberAfGetBindingTableSize(void);
uint8_t emberAfGetAddressTableSize(void);
uint8_t emberAfGetChildTableSize(void);
uint8_t emberAfGetRouteTableSize(void);
uint8_t emberAfGetNeighborTableSize(void);
uint8_t emberAfGetStackProfile(void);
uint8_t emberAfGetSleepyMulticastConfig(void);

uint8_t emAfGetPacketBufferFreeCount(void);
uint8_t emAfGetPacketBufferTotalCount(void);

EmberStatus emberAfGetSourceRouteTableEntry(uint8_t index, EmberNodeId * destination, uint8_t * closerIndex);

uint8_t emberAfGetSourceRouteTableTotalSize(void);
uint8_t emberAfGetSourceRouteTableFilledSize(void);

EmberStatus emberAfGetChildData(uint8_t index, EmberChildData * childData);

void emAfCliVersionCommand(void);

EmberStatus emAfPermitJoin(uint8_t duration, bool broadcastMgmtPermitJoin);
void emAfStopSmartEnergyStartup(void);

bool emAfProcessZdo(EmberNodeId sender, EmberApsFrame * apsFrame, uint8_t * message, uint16_t length);

void emAfIncomingMessageHandler(EmberIncomingMessageType type, EmberApsFrame * apsFrame, uint8_t lastHopLqi, int8_t lastHopRssi,
uint16_t messageLength, uint8_t * messageContents);
EmberStatus emAfSend(EmberOutgoingMessageType type, uint16_t indexOrDestination, EmberApsFrame * apsFrame, uint8_t messageLength,
uint8_t * message, uint8_t * messageTag, EmberNodeId alias, uint8_t sequence);
void emAfMessageSentHandler(EmberOutgoingMessageType type, uint16_t indexOrDestination, EmberApsFrame * apsFrame,
EmberStatus status, uint16_t messageLength, uint8_t * messageContents, uint8_t messageTag);

void emAfStackStatusHandler(EmberStatus status);
void emAfNetworkInit(void);

// For testing purposes only, we suppress the normal call to emberNetworkInit()
// at reboot. This allows us to call it manually later and prevent the node
// from immediately coming back up on the network after reboot.
#ifdef EMBER_AF_TC_SWAP_OUT_TEST
#define EM_AF_NETWORK_INIT()
#else
#define EM_AF_NETWORK_INIT() emAfNetworkInit()
#endif

#define emberAfCopyBigEndianEui64Argument emberCopyBigEndianEui64Argument
void emAfScheduleFindAndRejoinEvent(void);

extern const EmberEUI64 emberAfNullEui64;

void emberAfFormatMfgString(uint8_t * mfgString);

extern bool emberAfPrintReceivedMessages;

void emAfParseAndPrintVersion(EmberVersion versionStruct);
void emAfPrintEzspEndpointFlags(uint8_t endpoint);

// Old names
#define emberAfMoveInProgress() emberAfMoveInProgressCallback()
#define emberAfStartMove() emberAfStartMoveCallback()
#define emberAfStopMove() emberAfStopMoveCallback()

#endif // SILABS_AF_MAIN_H
Loading

0 comments on commit 4dd5230

Please sign in to comment.