Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new on/off cluster implementation based on the Silicon Labs ZigbeePro code #1609

Merged
merged 12 commits into from
Jul 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2304,6 +2304,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"
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 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these files common or intended to be generated in real apps? I suggest to move them to common since I did not see esp32 specific codes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These files are common, but can't compile without the gen bits (which are app-specific) right now. See #1630.

We can move them to examples/common if files in there can include app-specific headers (which is possible if we set up the include paths for the apps correctly).

Once #1630 is fixed, we can move these files somewhere else much more easily, of course.

*
* 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.
*/

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be dual copyright, since SiLabs is already a CHIP Author? Question applies throughout

IANAL

*
* 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out code?

This commented out include seems to occur in other places as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned above, the goal is to land something with as few differences from the original SiLabs code as possible, subject to the "it compiles and runs" constraint. Once this lands, we will definitely be doing a bunch of cleanup, which will include removing the commented-out bits here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed #1611 on this.

//#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