Skip to content

Commit

Permalink
Linux tv-casting-app: refactored Initialization (#28662)
Browse files Browse the repository at this point in the history
* Linux tv-casting-app: refactored Initialization

* Addressing rawadhilal88@'s comment

* Addressing feedback from cliffamzn@
  • Loading branch information
sharadb-amazon authored Aug 16, 2023
1 parent 2bec5d5 commit 69f6a90
Show file tree
Hide file tree
Showing 8 changed files with 619 additions and 6 deletions.
23 changes: 17 additions & 6 deletions examples/tv-casting-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,24 @@ import("${chip_root}/src/lib/lib.gni")

assert(chip_build_tools)

declare_args() {
chip_casting_simplified = false
}

executable("chip-tv-casting-app") {
sources = [
"${chip_root}/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h",
"CastingUtils.cpp",
"CastingUtils.h",
"main.cpp",
]
if (chip_casting_simplified) {
sources = [
"${chip_root}/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h",
"simple-app.cpp",
]
} else {
sources = [
"${chip_root}/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h",
"CastingUtils.cpp",
"CastingUtils.h",
"main.cpp",
]
}

deps = [
"${chip_root}/examples/common/tracing:commandline",
Expand Down
154 changes: 154 additions & 0 deletions examples/tv-casting-app/linux/simple-app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
*
* 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 "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>

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()));

chip::DeviceLayer::PlatformMgr().RunEventLoop();

return 0;
}
9 changes: 9 additions & 0 deletions examples/tv-casting-app/tv-casting-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ chip_data_model("tv-casting-common") {
"src/TargetVideoPlayerInfo.cpp",
]

# Add simplified casting API files here
sources += [
"core/CastingApp.cpp",
"core/CastingApp.h",
"core/Types.h",
"support/AppParameters.h",
"support/DataProvider.h",
]

deps = [
"${chip_root}/examples/common/tracing:commandline",
"${chip_root}/src/app/tests/suites/commands/interaction_model",
Expand Down
128 changes: 128 additions & 0 deletions examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
*
* 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 "CastingApp.h"

#include <app/clusters/bindings/BindingManager.h>
#include <app/server/Server.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>

namespace matter {
namespace casting {
namespace core {

using namespace matter::casting::support;

CastingApp * CastingApp::_castingApp = nullptr;

CastingApp::CastingApp() {}

CastingApp * CastingApp::GetInstance()
{
if (_castingApp == nullptr)
{
_castingApp = new CastingApp();
}
return _castingApp;
}

CHIP_ERROR CastingApp::Initialize(const AppParameters & appParameters)
{
VerifyOrReturnError(mState == UNINITIALIZED, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(appParameters.GetCommissionableDataProvider() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(appParameters.GetDeviceAttestationCredentialsProvider() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(appParameters.GetServerInitParamsProvider() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

ReturnErrorOnFailure(chip::Platform::MemoryInit());
ReturnErrorOnFailure(chip::DeviceLayer::PlatformMgr().InitChipStack());

mAppParameters = &appParameters;

chip::DeviceLayer::SetCommissionableDataProvider(appParameters.GetCommissionableDataProvider());
chip::Credentials::SetDeviceAttestationCredentialsProvider(appParameters.GetDeviceAttestationCredentialsProvider());
chip::Credentials::SetDeviceAttestationVerifier(appParameters.GetDeviceAttestationVerifier());

#if CHIP_ENABLE_ROTATING_DEVICE_ID
MutableByteSpanDataProvider * uniqueIdProvider = appParameters.GetRotatingDeviceIdUniqueIdProvider();
if (uniqueIdProvider != nullptr && uniqueIdProvider->Get() != nullptr)
{
ReturnErrorOnFailure(chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(*uniqueIdProvider->Get()));
}
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID

mState = NOT_RUNNING; // initialization done, set state to NOT_RUNNING

return CHIP_NO_ERROR;
}

CHIP_ERROR CastingApp::Start()
{
VerifyOrReturnError(mState == NOT_RUNNING, CHIP_ERROR_INCORRECT_STATE);

// start Matter server
chip::ServerInitParams * serverInitParams = mAppParameters->GetServerInitParamsProvider()->Get();
VerifyOrReturnError(serverInitParams != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
ReturnErrorOnFailure(chip::Server::GetInstance().Init(*serverInitParams));

// perform post server startup registrations
ReturnErrorOnFailure(PostStartRegistrations());

return CHIP_NO_ERROR;
}

CHIP_ERROR CastingApp::PostStartRegistrations()
{
VerifyOrReturnError(mState == NOT_RUNNING, CHIP_ERROR_INCORRECT_STATE);
auto & server = chip::Server::GetInstance();

// TODO: Set CastingApp as AppDelegate
// &server.GetCommissioningWindowManager().SetAppDelegate(??);

// Initialize binding handlers
chip::BindingManager::GetInstance().Init(
{ &server.GetFabricTable(), server.GetCASESessionManager(), &server.GetPersistentStorage() });

// TODO: Set FabricDelegate
// chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&mPersistenceManager);

// TODO: Add DeviceEvent Handler
// ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(DeviceEventCallback, 0));

mState = RUNNING; // CastingApp started successfully, set state to RUNNING
return CHIP_NO_ERROR;
}

CHIP_ERROR CastingApp::Stop()
{
VerifyOrReturnError(mState == RUNNING, CHIP_ERROR_INCORRECT_STATE);

// TODO: add logic to capture CastingPlayers that we are currently connected to, so we can automatically reconnect with them on
// Start() again

// Shutdown the Matter server
chip::Server::GetInstance().Shutdown();

mState = NOT_RUNNING; // CastingApp started successfully, set state to RUNNING

return CHIP_ERROR_NOT_IMPLEMENTED;
}

}; // namespace core
}; // namespace casting
}; // namespace matter
Loading

0 comments on commit 69f6a90

Please sign in to comment.