blob: d4b18158a6f33a7b827d92bc42b4a4e5c6814f9b [file] [log] [blame]
/*
*
* Copyright (c) 2021 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 Contains shell commands for a commissionee (eg. end device) related to commissioning.
*/
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/util/ContentAppPlatform.h>
#include <cstdio>
#include <inttypes.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/ZclString.h>
#include <platform/CHIPDeviceLayer.h>
using namespace chip;
using namespace chip::AppPlatform;
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
// Device Version for dynamic endpoints:
#define DEVICE_VERSION_DEFAULT 1
EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId,
EmberAfAttributeMetadata * attributeMetadata, uint16_t manufacturerCode,
uint8_t * buffer, uint16_t maxReadLength)
{
uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint);
ChipLogProgress(DeviceLayer, "emberAfExternalAttributeReadCallback endpoint %d ", endpointIndex);
EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE;
ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetContentAppByEndpointId(endpoint);
if (app != NULL)
{
ret = app->HandleReadAttribute(clusterId, attributeMetadata->attributeId, buffer, maxReadLength);
}
return ret;
}
EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId,
EmberAfAttributeMetadata * attributeMetadata, uint16_t manufacturerCode,
uint8_t * buffer)
{
uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint);
ChipLogProgress(DeviceLayer, "emberAfExternalAttributeWriteCallback endpoint %d ", endpointIndex);
EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE;
ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetContentAppByEndpointId(endpoint);
if (app != NULL)
{
ret = app->HandleWriteAttribute(clusterId, attributeMetadata->attributeId, buffer);
}
return ret;
}
namespace chip {
namespace AppPlatform {
int AppPlatform::AddContentApp(ContentApp * app, EmberAfEndpointType * ep, uint16_t deviceType)
{
ChipLogProgress(DeviceLayer, "Adding device %s ", app->GetApplicationBasic()->GetApplicationName());
uint8_t index = 0;
// check if already loaded
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
if (mContentApps[index] == app)
{
ChipLogProgress(DeviceLayer, "Already added");
return index;
}
index++;
}
index = 0;
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
if (NULL == mContentApps[index])
{
mContentApps[index] = app;
EmberAfStatus ret;
while (1)
{
ret = emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, deviceType, DEVICE_VERSION_DEFAULT);
if (ret == EMBER_ZCL_STATUS_SUCCESS)
{
ChipLogProgress(DeviceLayer, "Added device %s to dynamic endpoint %d (index=%d)",
app->GetApplicationBasic()->GetApplicationName(), mCurrentEndpointId, index);
app->SetEndpointId(mCurrentEndpointId);
return index;
}
else if (ret != EMBER_ZCL_STATUS_DUPLICATE_EXISTS)
{
ChipLogProgress(DeviceLayer, "Adding device error=%d", ret);
return -1;
}
// Handle wrap condition
if (++mCurrentEndpointId < mFirstDynamicEndpointId)
{
mCurrentEndpointId = mFirstDynamicEndpointId;
}
}
}
index++;
}
ChipLogProgress(DeviceLayer, "Failed to add dynamic endpoint: No endpoints available!");
return -1;
}
int AppPlatform::RemoveContentApp(ContentApp * app)
{
uint8_t index = 0;
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
if (mContentApps[index] == app)
{
EndpointId ep = emberAfClearDynamicEndpoint(index);
mContentApps[index] = NULL;
ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)",
app->GetApplicationBasic()->GetApplicationName(), ep, index);
// Silence complaints about unused ep when progress logging
// disabled.
UNUSED_VAR(ep);
return index;
}
index++;
}
return -1;
}
void AppPlatform::SetupAppPlatform()
{
ChipLogProgress(DeviceLayer, "AppPlatform::SetupAppPlatform()");
// Clear out the device database
uint8_t index = 0;
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
mContentApps[index] = NULL;
index++;
}
// Set starting endpoint id where dynamic endpoints will be assigned, which
// will be the next consecutive endpoint id after the last fixed endpoint.
mFirstDynamicEndpointId = static_cast<chip::EndpointId>(
static_cast<int>(emberAfEndpointFromIndex(static_cast<uint16_t>(emberAfFixedEndpointCount() - 1))) + 1);
mCurrentEndpointId = mFirstDynamicEndpointId;
{
for (int i = 0; i < emberAfFixedEndpointCount(); i++)
{
ChipLogProgress(DeviceLayer, "endpoint index=%d, id=%d", i,
static_cast<chip::EndpointId>(static_cast<int>(emberAfEndpointFromIndex(static_cast<uint16_t>(i)))));
}
}
if (mCurrentEndpointId < emberAfFixedEndpointCount())
{
mCurrentEndpointId = emberAfFixedEndpointCount();
}
ChipLogProgress(DeviceLayer, "emberAfFixedEndpointCount()=%d mCurrentEndpointId=%d", emberAfFixedEndpointCount(),
mCurrentEndpointId);
// Disable last fixed endpoint, which is used as a placeholder for all of the
// supported clusters so that ZAP will generated the requisite code.
// emberAfEndpointEnableDisable(emberAfEndpointFromIndex(static_cast<uint16_t>(emberAfFixedEndpointCount() - 1)), false);
}
void AppPlatform::UnloadContentAppByVendorId(uint16_t vendorId)
{
uint8_t index = 0;
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
ContentApp * app = mContentApps[index];
if (app != NULL && app->GetApplicationBasic()->GetVendorId() == vendorId)
{
EndpointId ep = emberAfClearDynamicEndpoint(index);
mContentApps[index] = NULL;
ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)",
app->GetApplicationBasic()->GetApplicationName(), ep, index);
// Silence complaints about unused ep when progress logging
// disabled.
UNUSED_VAR(ep);
return;
}
index++;
}
return;
}
ContentApp * AppPlatform::GetLoadContentAppByVendorId(uint16_t vendorId)
{
ChipLogProgress(DeviceLayer, "GetLoadContentAppByVendorId() - vendorId %d ", vendorId);
uint8_t index = 0;
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
ContentApp * app = mContentApps[index];
if (app != NULL && app->GetApplicationBasic()->GetVendorId() == vendorId)
{
return app;
}
index++;
}
if (mContentAppFactory != NULL)
{
return mContentAppFactory->LoadContentAppByVendorId(vendorId);
}
return NULL;
}
ContentApp * AppPlatform::GetLoadContentAppByAppId(Application application)
{
ChipLogProgress(DeviceLayer, "GetLoadContentAppByAppId()");
if (mContentAppFactory != NULL)
{
return mContentAppFactory->LoadContentAppByAppId(application);
}
return NULL;
}
ContentApp * AppPlatform::GetContentAppByEndpointId(chip::EndpointId id)
{
uint8_t index = 0;
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
{
ContentApp * app = mContentApps[index];
if (app != NULL && app->GetEndpointId() == id)
{
return app;
}
index++;
}
ChipLogProgress(DeviceLayer, "GetContentAppByEndpointId() - endpoint %d not found ", id);
return NULL;
}
} // namespace AppPlatform
} // namespace chip
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED