blob: 26d35b443c0e67f106dd404236bf44b9e57f93bf [file] [log] [blame]
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* 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.
*/
#include "simple-app-helper.h"
#include "core/CastingPlayer.h"
#include "core/CastingPlayerDiscovery.h"
#include "core/Types.h"
#include <LinuxCommissionableDataProvider.h>
#include <Options.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <lib/core/CHIPError.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/TestOnlyCommissionableDataProvider.h>
#if defined(ENABLE_CHIP_SHELL)
#include <lib/shell/Engine.h> // nogncheck
#include <thread>
using chip::Shell::Engine;
#endif
using namespace matter::casting::core;
using namespace matter::casting::support;
// To hold SPAKE2+ verifier, discriminator, passcode
LinuxCommissionableDataProvider gCommissionableDataProvider;
CHIP_ERROR InitCommissionableDataProvider(LinuxCommissionableDataProvider & provider, LinuxDeviceOptions & options)
{
chip::Optional<uint32_t> setupPasscode;
if (options.payload.setUpPINCode != 0)
{
setupPasscode.SetValue(options.payload.setUpPINCode);
}
else if (!options.spake2pVerifier.HasValue())
{
uint32_t defaultTestPasscode = 0;
chip::DeviceLayer::TestOnlyCommissionableDataProvider TestOnlyCommissionableDataProvider;
VerifyOrDie(TestOnlyCommissionableDataProvider.GetSetupPasscode(defaultTestPasscode) == CHIP_NO_ERROR);
ChipLogError(Support,
"*** WARNING: Using temporary passcode %u due to no neither --passcode or --spake2p-verifier-base64 "
"given on command line. This is temporary and will be deprecated. Please update your scripts "
"to explicitly configure onboarding credentials. ***",
static_cast<unsigned>(defaultTestPasscode));
setupPasscode.SetValue(defaultTestPasscode);
options.payload.setUpPINCode = defaultTestPasscode;
}
else
{
// Passcode is 0, so will be ignored, and verifier will take over. Onboarding payload
// printed for debug will be invalid, but if the onboarding payload had been given
// properly to the commissioner later, PASE will succeed.
}
// Default to minimum PBKDF iterations
uint32_t spake2pIterationCount = chip::Crypto::kSpake2p_Min_PBKDF_Iterations;
if (options.spake2pIterations != 0)
{
spake2pIterationCount = options.spake2pIterations;
}
ChipLogError(Support, "PASE PBKDF iterations set to %u", static_cast<unsigned>(spake2pIterationCount));
return provider.Init(options.spake2pVerifier, options.spake2pSalt, spake2pIterationCount, setupPasscode,
options.payload.discriminator.GetLongValue());
}
/**
* @brief Provides the unique ID that is used by the SDK to generate the Rotating Device ID.
*/
class RotatingDeviceIdUniqueIdProvider : public MutableByteSpanDataProvider
{
private:
chip::MutableByteSpan rotatingDeviceIdUniqueIdSpan;
uint8_t rotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
public:
RotatingDeviceIdUniqueIdProvider()
{
// generate a random Unique ID for this example app
for (size_t i = 0; i < sizeof(rotatingDeviceIdUniqueId); i++)
{
rotatingDeviceIdUniqueId[i] = chip::Crypto::GetRandU8();
}
rotatingDeviceIdUniqueIdSpan = chip::MutableByteSpan(rotatingDeviceIdUniqueId);
}
chip::MutableByteSpan * Get() { return &rotatingDeviceIdUniqueIdSpan; }
};
/**
* @brief Provides the ServerInitParams required to start the CastingApp, which in turn starts the Matter server
*/
class CommonCaseDeviceServerInitParamsProvider : public ServerInitParamsProvider
{
private:
// For this example, we'll use CommonCaseDeviceServerInitParams
chip::CommonCaseDeviceServerInitParams serverInitParams;
public:
chip::ServerInitParams * Get()
{
CHIP_ERROR err = serverInitParams.InitializeStaticResourcesBeforeServerInit();
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
ChipLogError(AppServer, "Initialization of ServerInitParams failed %" CHIP_ERROR_FORMAT, err.Format()));
return &serverInitParams;
}
};
int main(int argc, char * argv[])
{
// Create AppParameters that need to be passed to CastingApp.Initialize()
AppParameters appParameters;
RotatingDeviceIdUniqueIdProvider rotatingDeviceIdUniqueIdProvider;
CommonCaseDeviceServerInitParamsProvider serverInitParamsProvider;
CHIP_ERROR err = CHIP_NO_ERROR;
err = InitCommissionableDataProvider(gCommissionableDataProvider, LinuxDeviceOptions::GetInstance());
VerifyOrReturnValue(
err == CHIP_NO_ERROR, 0,
ChipLogError(AppServer, "Initialization of CommissionableDataProvider failed %" CHIP_ERROR_FORMAT, err.Format()));
err = appParameters.Create(&rotatingDeviceIdUniqueIdProvider, &gCommissionableDataProvider,
chip::Credentials::Examples::GetExampleDACProvider(),
GetDefaultDACVerifier(chip::Credentials::GetTestAttestationTrustStore()), &serverInitParamsProvider);
VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
ChipLogError(AppServer, "Creation of AppParameters failed %" CHIP_ERROR_FORMAT, err.Format()));
// Initialize the CastingApp
err = CastingApp::GetInstance()->Initialize(appParameters);
VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
ChipLogError(AppServer, "Initialization of CastingApp failed %" CHIP_ERROR_FORMAT, err.Format()));
// Initialize Linux KeyValueStoreMgr
chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(CHIP_CONFIG_KVS_PATH);
// Start the CastingApp
err = CastingApp::GetInstance()->Start();
VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
ChipLogError(AppServer, "CastingApp::Start failed %" CHIP_ERROR_FORMAT, err.Format()));
#if defined(ENABLE_CHIP_SHELL)
chip::Shell::Engine::Root().Init();
std::thread shellThread([]() { chip::Shell::Engine::Root().RunMainLoop(); });
RegisterCommands();
#endif
CastingPlayerDiscovery::GetInstance()->SetDelegate(DiscoveryDelegateImpl::GetInstance());
// Discover CastingPlayers
err = CastingPlayerDiscovery::GetInstance()->StartDiscovery(kTargetPlayerDeviceType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, -1,
ChipLogError(AppServer, "CastingPlayerDiscovery::StartDiscovery failed %" CHIP_ERROR_FORMAT, err.Format()));
chip::DeviceLayer::PlatformMgr().RunEventLoop();
return 0;
}