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

Restyle WIP: Basic data model structure #1469

Closed
wants to merge 5 commits into from
Closed
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
29 changes: 17 additions & 12 deletions examples/wifi-echo/server/esp32/main/EchoDeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "EchoDeviceCallbacks.h"
#include "esp_log.h"
#include <lib/core/CHIPClusterServer.h>
#include <platform/CHIPDeviceLayer.h>
#include <support/CodeUtils.h>

Expand All @@ -34,6 +35,7 @@
static const char * TAG = "echo-devicecallbacks";
using namespace ::chip::Inet;
using namespace ::chip::DeviceLayer;
using namespace ::chip::DataModel;

extern LEDWidget statusLED; // In wifi-echo.cpp

Expand Down Expand Up @@ -70,22 +72,25 @@ void EchoDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, int
}
}

extern CHIPClusterServer server;
/* This function can be eliminated, and instead its contents will get executed */
void EchoDeviceCallbacks::PostAttributeChangeCallback(uint8_t endpoint, ChipZclClusterId clusterId, ChipZclAttributeId attributeId,
uint8_t mask, uint16_t manufacturerCode, uint8_t type, uint8_t size,
uint8_t * value)
{
if (clusterId != CHIP_ZCL_CLUSTER_ON_OFF)
/* TODO: For some reason, the first endpoint is 1 instead of 0 */
endpoint--;
printf("endpoint: %d, clusterId: %d, attrId: %d type: %d\n", endpoint, clusterId, attributeId, type);
for (int i = 0; i < kMaxClustersPerEndPoint; i++)
{
ESP_LOGI(TAG, "Unknown cluster ID: %d", clusterId);
return;
}

if (attributeId != CHIP_ZCL_CLUSTER_ON_OFF_SERVER_ATTRIBUTE_ON_OFF)
{
ESP_LOGI(TAG, "Unknown attribute ID: %d", attributeId);
return;
if (server.mEndPoints[endpoint] && server.mEndPoints[endpoint]->mClusters[i] &&
server.mEndPoints[endpoint]->mClusters[i]->mClusterId == clusterId)
{
// At this point we can assume that value points to a boolean value.
CHIPValue cValue(kCHIPValueType_Bool);
memcpy((void *) &cValue.Int64, (void *) value, size);
printf("Value is %lld type is %d\n", cValue.Int64, type);
server.mEndPoints[endpoint]->mClusters[i]->Set(attributeId, cValue);
}
}
ESP_LOGI(TAG, "Got the post attribute callback");
// At this point we can assume that value points to a boolean value.
statusLED.Set(*value);
}
16 changes: 15 additions & 1 deletion examples/wifi-echo/server/esp32/main/LEDWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "esp_log.h"
#include "esp_system.h"
#include "esp_timer.h"
#include <lib/core/CHIPStandardAttributes.h>

#if CONFIG_HAVE_DISPLAY
// The Y position of the LED Status message on screen as a
Expand All @@ -45,7 +46,7 @@ static const char * onMsg = "LIGHT: ON";
static const char * offMsg = "LIGHT: OFF";

#endif

using namespace ::chip::DataModel;
extern const char * TAG;

void LEDWidget::Init(gpio_num_t gpioNum)
Expand All @@ -68,6 +69,19 @@ void LEDWidget::Set(bool state)
{
mBlinkOnTimeMS = mBlinkOffTimeMS = 0;
DoSet(state);
CHIPBaseCluster::Set(kAttributeIdOnOff, CHIPValueBool(state));
}

int LEDWidget::Set(uint8_t attrId, const CHIPValue & value)
{
if (attrId == kAttributeIdOnOff)
{
printf("Setting value to %d\n", CHIPValueToBool(value));
DoSet(CHIPValueToBool(value));
/* Update our internal data model as well */
CHIPBaseCluster::Set(attrId, value);
}
return SUCCESS;
}

void LEDWidget::Blink(uint32_t changeRateMS)
Expand Down
4 changes: 3 additions & 1 deletion examples/wifi-echo/server/esp32/main/include/LEDWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include <lib/core/CHIPStandardClusters.h>

class LEDWidget
class LEDWidget : public chip::DataModel::CHIPClusterOnOff
{
public:
void Init(gpio_num_t gpioNum);
void Set(bool state);
int Set(uint8_t attrId, const chip::DataModel::CHIPValue & value);
void Blink(uint32_t changeRateMS);
void Blink(uint32_t onTimeMS, uint32_t offTimeMS);
void BlinkOnError();
Expand Down
45 changes: 45 additions & 0 deletions examples/wifi-echo/server/esp32/main/wifi-echo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@
#include <stdio.h>

#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPClusterServer.h>
#include <platform/CHIPDeviceLayer.h>
#include <support/ErrorStr.h>
#include <transport/SecureSessionMgr.h>

using namespace ::chip;
using namespace ::chip::DeviceLayer;
using namespace ::chip::DataModel;

extern void startServer(SecureSessionMgr * transportIPv4, SecureSessionMgr * transportIPv6);
#if CONFIG_USE_ECHO_CLIENT
Expand Down Expand Up @@ -80,6 +82,11 @@ static Button attentionButton;
const char * TAG = "wifi-echo-demo";

static EchoDeviceCallbacks EchoCallbacks;
const uint8_t ZCLVersion = 10;
const uint8_t applicationVersion = 20;
const uint8_t stackVersion = 1;
const uint8_t HWVersion = 1;
CHIPClusterServer server(ZCLVersion, applicationVersion, stackVersion, HWVersion);

namespace {

Expand All @@ -89,6 +96,41 @@ SecureSessionMgr sTransportIPv6;

} // namespace

void PrintDataModel(CHIPClusterServer & server)
{
printf("Server:\n");
for (int i = 0; i < kMaxEndPointPerServer; i++)
{
/* EndPoints */
if (server.mEndPoints[i])
{
auto endpoint = server.mEndPoints[i];
printf(" EndPoint: %d\n", i);
for (int j = 0; j < kMaxClustersPerEndPoint; j++)
{
/* Clusters */
if (endpoint->mClusters[j])
{
auto cluster = endpoint->mClusters[j];
printf(" ClusterId: 0x%04x\n", cluster->mClusterId);
for (int k = 0; k < kMaxAttributesPerCluster; k++)
{
/* Attributes */
if (cluster->mAttrs[k])
{
auto attr = cluster->mAttrs[k];
printf(" Attribute: 0x%04x\n", attr->mAttrId);
char printstr[20];
attr->mValue.ValueToStr(printstr, sizeof(printstr));
printf(" Value: %s\n", printstr);
}
}
}
}
}
}
}

extern "C" void app_main()
{
ESP_LOGI(TAG, "WiFi Echo Demo!");
Expand Down Expand Up @@ -131,6 +173,9 @@ extern "C" void app_main()

statusLED.Init(STATUS_LED_GPIO_NUM);

/* Add a cluster to the primary endpoint of our cluster server */
server.AddCluster(&statusLED);

// Start the Echo Server
InitDataModelHandler();
startServer(&sTransportIPv4, &sTransportIPv6);
Expand Down
106 changes: 106 additions & 0 deletions src/lib/core/CHIPBaseAttribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
*
* 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.
*/

/**
* @file
* This file contains definitions for working with CHIP values.
*
*/

#ifndef CHIPATTRIBUTES_H_
#define CHIPATTRIBUTES_H_

#include <lib/core/CHIPValues.h>

namespace chip {
namespace DataModel {

class CHIPBaseAttribute
{
public:
uint16_t mAttrId;
CHIPValue mValue;
CHIPValue mMin;
CHIPValue mMax;

CHIPBaseAttribute(uint16_t attrId, CHIPValueTypes type) : mAttrId(attrId), mValue(type), mMin(type), mMax(type) {}
CHIPBaseAttribute(uint16_t attrId, CHIPValue value) : mAttrId(attrId), mValue(value), mMin(value.mType), mMax(value.mType) {}
CHIPBaseAttribute(uint16_t attrId, CHIPValueTypes type, uint64_t min, uint64_t max) :
mAttrId(attrId), mValue(type), mMin(type, min), mMax(type, max)
{}

/* An attribute is typically set in either of the following 2 ways:
*
* - From the top of the stack or the most derived class, like
* brightness.Set(45). This is handled through the derived
* class's Set method.
*
* - From the bottom of the stack when the stack receives a schema
* with just a list of values. This will typically get called
* with a Set() call on the base-ptr. In this case the argument
* will be CHIPValue.
*/
int Set(const CHIPValue & newValue)
{
/* We have to check the element type match in this case */
if (mValue.mType != newValue.mType)
{
return FAIL;
}
if (withinRange(newValue))
{
mValue = newValue;
return SUCCESS;
}
return FAIL;
}

/* Need to define the behaviour when CHIPValue contains pointers
* to allocated data
*/
CHIPValue Get() { return mValue; }

protected:
bool withinRange(const uint64_t & value) { return (value >= mMin.Int64) && (value <= mMax.Int64); }

bool withinRange(const CHIPValue value)
{
switch (mValue.mType)
{
case kCHIPValueType_Int8:
case kCHIPValueType_Int16:
case kCHIPValueType_Int32:
case kCHIPValueType_Int64:
case kCHIPValueType_UInt8:
case kCHIPValueType_UInt16:
case kCHIPValueType_UInt32:
case kCHIPValueType_UInt64:
return withinRange(value.Int64);
break;
case kCHIPValueType_Bool:
return true;
default:
return false;
}
return false;
}
};

} // namespace DataModel
} // namespace chip

#endif /* CHIPATTRIBUTES_H_ */
94 changes: 94 additions & 0 deletions src/lib/core/CHIPBaseCluster.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
*
* 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.
*/

/**
* @file
* This file contains base class for CHIP Clusters
*
*/

#ifndef CHIPBASECLUSTER_H_
#define CHIPBASECLUSTER_H_

#include <lib/core/CHIPBaseAttribute.h>

namespace chip {
namespace DataModel {

/* TODO: To be converted to a template version or Kconfig later on */
static const uint8_t kMaxAttributesPerCluster = 10;
class CHIPBaseCluster
{
public:
uint16_t mClusterId;
CHIPBaseAttribute * mAttrs[kMaxAttributesPerCluster];

CHIPBaseCluster(uint16_t clusterId) : mClusterId(clusterId), mAttrs() {}

virtual ~CHIPBaseCluster()
{
for (int i = 0; i < kMaxAttributesPerCluster; i++)
{
if (mAttrs[i] != nullptr)
{
delete mAttrs[i];
mAttrs[i] = nullptr;
}
}
}

int AddAttribute(CHIPBaseAttribute * attr)
{
for (int i = 0; i < kMaxAttributesPerCluster; i++)
{
if (mAttrs[i] == nullptr)
{
mAttrs[i] = attr;
return SUCCESS;
}
}
return FAIL;
}

CHIPBaseAttribute * GetAttribute(uint8_t attrId)
{
for (int i = 0; i < kMaxAttributesPerCluster; i++)
{
if (mAttrs[i] && (mAttrs[i]->mAttrId == attrId))
{
return mAttrs[i];
}
}
return nullptr;
}

virtual int Set(uint8_t attrId, const CHIPValue & value)
{
/* Just hand-off to update the value internally */
auto attr = GetAttribute(attrId);
if (attr)
{
return attr->Set(value);
}
return FAIL;
}
};

} // namespace DataModel
} // namespace chip

#endif /* CHIPBASECLUSTER_H_ */
Loading