blob: 74a3cf8b0e1c6e49ea1256390bfaa4bb1f488248 [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 "AppImpl.h"
#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/CommandHandler.h>
#include <app/server/Dnssd.h>
#include <app/server/Server.h>
#include <app/util/af.h>
#include <cstdio>
#include <inttypes.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/DataModelTypes.h>
#include <lib/shell/Commands.h>
#include <lib/shell/Engine.h>
#include <lib/shell/commands/Help.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
namespace chip {
namespace AppPlatform {
// BEGIN DYNAMIC ENDPOINTS
// =================================================================================
static const int kNameSize = 32;
// Current ZCL implementation of Struct uses a max-size array of 254 bytes
static const int kDescriptorAttributeArraySize = 254;
// Device types for dynamic endpoints: TODO Need a generated file from ZAP to define these!
// (taken from chip-devices.xml)
#define DEVICE_TYPE_CONTENT_APP 0x0024
// ---------------------------------------------------------------------------
//
// CONTENT APP ENDPOINT: contains the following clusters:
// - Descriptor
// - Application Basic
// Declare Descriptor cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(descriptorAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_DEVICE_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* device list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_SERVER_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* server list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CLIENT_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* client list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_PARTS_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* parts list */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Application Basic information cluster attributes
// TODO: add missing attributes once schema is updated
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(applicationBasicAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_VENDOR_NAME_ATTRIBUTE_ID, CHAR_STRING, kNameSize, 0), /* VendorName */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_VENDOR_ID_ATTRIBUTE_ID, INT16U, 1, 0), /* VendorID */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_NAME_ATTRIBUTE_ID, CHAR_STRING, kNameSize, 0), /* ApplicationName */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_PRODUCT_ID_ATTRIBUTE_ID, INT16U, 1, 0), /* ProductID */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_STATUS_ATTRIBUTE_ID, INT8U, 1, 0), /* ApplicationStatus */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Keypad Input cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(keypadInputAttrs)
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Application Launcher cluster attributes
// TODO: add missing attributes once schema is updated
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(applicationLauncherAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_LAUNCHER_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* catalog list */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Account Login cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(accountLoginAttrs)
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Content Launcher cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(contentLauncherAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CONTENT_LAUNCHER_ACCEPT_HEADER_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize,
0), /* accept header list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CONTENT_LAUNCHER_SUPPORTED_STREAMING_PROTOCOLS_ATTRIBUTE_ID, BITMAP32, 1,
0), /* streaming protocols */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Media Playback cluster attributes
// TODO: add missing attributes once schema is updated
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(mediaPlaybackAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_STATE_ATTRIBUTE_ID, ENUM8, 1, 0), /* current state */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_START_TIME_ATTRIBUTE_ID, EPOCH_US, 1, 0), /* start time */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_DURATION_ATTRIBUTE_ID, INT64U, 1, 0), /* duration */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_SPEED_ATTRIBUTE_ID, SINGLE, 1, 0), /* playback speed */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_SEEK_RANGE_END_ATTRIBUTE_ID, INT64U, 1, 0), /* seek range end */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_SEEK_RANGE_START_ATTRIBUTE_ID, INT64U, 1, 0), /* seek range start */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Target Navigator cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(targetNavigatorAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_TARGET_NAVIGATOR_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* target list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_TARGET_NAVIGATOR_CURRENT_TARGET_ATTRIBUTE_ID, INT8U, 1, 0), /* current target */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Channel cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(channelAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* channel list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_LINEUP_ATTRIBUTE_ID, STRUCT, 1, 0), /* lineup */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_CURRENT_CHANNEL_ATTRIBUTE_ID, STRUCT, 1, 0), /* current channel */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Cluster List for Content App endpoint
DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(contentAppClusters)
DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_BASIC_CLUSTER_ID, applicationBasicAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_KEYPAD_INPUT_CLUSTER_ID, keypadInputAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_LAUNCHER_CLUSTER_ID, applicationLauncherAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_ACCOUNT_LOGIN_CLUSTER_ID, accountLoginAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_CONTENT_LAUNCH_CLUSTER_ID, contentLauncherAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_MEDIA_PLAYBACK_CLUSTER_ID, mediaPlaybackAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_TARGET_NAVIGATOR_CLUSTER_ID, targetNavigatorAttrs),
DECLARE_DYNAMIC_CLUSTER(ZCL_CHANNEL_CLUSTER_ID, channelAttrs) DECLARE_DYNAMIC_CLUSTER_LIST_END;
// Declare Content App endpoint
DECLARE_DYNAMIC_ENDPOINT(contentAppEndpoint, contentAppClusters);
ContentAppImpl::ContentAppImpl(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
const char * szApplicationVersion)
{
mApplicationBasic.SetApplicationName(szApplicationName);
mApplicationBasic.SetVendorName(szApplicationName);
mApplicationBasic.SetVendorId(vendorId);
mApplicationBasic.SetProductId(productId);
mApplicationBasic.SetApplicationVersion(szApplicationVersion);
}
void ApplicationBasicImpl::SetApplicationName(const char * szApplicationName)
{
ChipLogProgress(DeviceLayer, "ApplicationBasic[%s]: Application Name=\"%s\"", szApplicationName, szApplicationName);
strncpy(mApplicationName, szApplicationName, sizeof(mApplicationName));
}
void ApplicationBasicImpl::SetVendorName(const char * szVendorName)
{
ChipLogProgress(DeviceLayer, "ApplicationBasic[%s]: Vendor Name=\"%s\"", mApplicationName, szVendorName);
strncpy(mVendorName, szVendorName, sizeof(mVendorName));
}
void ApplicationBasicImpl::SetApplicationVersion(const char * szApplicationVersion)
{
ChipLogProgress(DeviceLayer, "ApplicationBasic[%s]: Application Version=\"%s\"", mApplicationName, szApplicationVersion);
strncpy(mApplicationVersion, szApplicationVersion, sizeof(mApplicationVersion));
}
bool AccountLoginImpl::Login(const char * tempAccountId, uint32_t setupPin)
{
ChipLogProgress(DeviceLayer, "AccountLogin: Login TempAccountId=\"%s\" SetupPIN=\"%d\"", tempAccountId, setupPin);
return (setupPin == mSetupPIN);
}
uint32_t AccountLoginImpl::GetSetupPIN(const char * tempAccountId)
{
ChipLogProgress(DeviceLayer, "AccountLogin: GetSetupPIN TempAccountId=\"%s\" returning setuppin=%d", tempAccountId, mSetupPIN);
return mSetupPIN;
}
ApplicationLauncherResponse ApplicationLauncherImpl::LaunchApp(Application application, std::string data)
{
std::string appId(application.applicationId.data(), application.applicationId.size());
ChipLogProgress(DeviceLayer,
"ApplicationLauncherResponse: LaunchApp application.catalogVendorId=%d "
"application.applicationId=%s data=%s",
application.catalogVendorId, appId.c_str(), data.c_str());
ApplicationLauncherResponse response;
const char * testData = "data";
response.data = (uint8_t *) testData;
response.status = to_underlying(chip::app::Clusters::ApplicationLauncher::StatusEnum::kSuccess);
return response;
}
LaunchResponse ContentLauncherImpl::LaunchContent(std::list<Parameter> parameterList, bool autoplay, std::string data)
{
ChipLogProgress(DeviceLayer, "ContentLauncherImpl: LaunchContent autoplay=%d data=\"%s\"", autoplay ? 1 : 0, data.c_str());
LaunchResponse response;
response.err = CHIP_NO_ERROR;
response.data = "Example app data";
response.status = chip::app::Clusters::ContentLauncher::StatusEnum::kSuccess;
return response;
}
ContentAppFactoryImpl::ContentAppFactoryImpl()
{
mContentApps[1].GetAccountLogin()->SetSetupPIN(34567890);
mContentApps[2].GetAccountLogin()->SetSetupPIN(20202021);
}
ContentApp * ContentAppFactoryImpl::LoadContentAppByVendorId(uint16_t vendorId)
{
for (unsigned int i = 0; i < APP_LIBRARY_SIZE; i++)
{
ContentAppImpl app = mContentApps[i];
if (app.GetApplicationBasic()->GetVendorId() == vendorId)
{
AppPlatform::GetInstance().AddContentApp(&mContentApps[i], &contentAppEndpoint, DEVICE_TYPE_CONTENT_APP);
return &mContentApps[i];
}
}
ChipLogProgress(DeviceLayer, "LoadContentAppByVendorId() - vendor %d not found ", vendorId);
return nullptr;
}
ContentApp * ContentAppFactoryImpl::LoadContentAppByAppId(Application application)
{
std::string appId(application.applicationId.data(), application.applicationId.size());
ChipLogProgress(DeviceLayer,
"ContentAppFactoryImpl: LoadContentAppByAppId application.catalogVendorId=%d "
"application.applicationIdSize=%ld application.applicationId=%s ",
application.catalogVendorId, application.applicationId.size(), appId.c_str());
for (unsigned int i = 0; i < APP_LIBRARY_SIZE; i++)
{
ContentAppImpl app = mContentApps[i];
ChipLogProgress(DeviceLayer, " Looking next=%s ", app.GetApplicationBasic()->GetApplicationName());
if (strcmp(app.GetApplicationBasic()->GetApplicationName(), appId.c_str()) == 0)
{
AppPlatform::GetInstance().AddContentApp(&mContentApps[i], &contentAppEndpoint, DEVICE_TYPE_CONTENT_APP);
return &mContentApps[i];
}
}
ChipLogProgress(DeviceLayer, "LoadContentAppByAppId() - app id %s not found ", appId.c_str());
return nullptr;
}
} // namespace AppPlatform
} // namespace chip
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED