blob: f7865910832ec904d0895c995fc5dc0974db5b4b [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 "CastingApp.h"
#include "support/CastingStore.h"
#include "support/ChipDeviceEventHandler.h"
#include <app/InteractionModelEngine.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)
{
ChipLogProgress(Discovery, "CastingApp::Initialize() called");
VerifyOrReturnError(mState == CASTING_APP_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)
{
chip::MutableByteSpan * uniqueId = uniqueIdProvider->Get();
if (uniqueId != nullptr)
{
ReturnErrorOnFailure(chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(*uniqueId));
}
else
{
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID
mState = CASTING_APP_NOT_RUNNING; // initialization done, set state to NOT_RUNNING
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::Start()
{
ChipLogProgress(Discovery, "CastingApp::Start() called");
VerifyOrReturnError(mState == CASTING_APP_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());
// reconnect (or verify connection) to the CastingPlayer that the app was connected to before being stopped, if any
if (CastingPlayer::GetTargetCastingPlayer() != nullptr)
{
CastingPlayer::GetTargetCastingPlayer()->VerifyOrEstablishConnection(
[](CHIP_ERROR err, matter::casting::core::CastingPlayer * castingPlayer) {
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "CastingApp::Start Could not reconnect to CastingPlayer %" CHIP_ERROR_FORMAT,
err.Format());
}
else
{
ChipLogProgress(AppServer, "CastingApp::Start Reconnected to CastingPlayer(ID: %s)", castingPlayer->GetId());
}
});
}
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::PostStartRegistrations()
{
ChipLogProgress(Discovery, "CastingApp::PostStartRegistrations() called");
VerifyOrReturnError(mState == CASTING_APP_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() });
// Set FabricDelegate
chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(support::CastingStore::GetInstance());
// Register DeviceEvent Handler
ReturnErrorOnFailure(chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(ChipDeviceEventHandler::Handle, 0));
mState = CASTING_APP_RUNNING; // CastingApp started successfully, set state to RUNNING
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::Stop()
{
ChipLogProgress(Discovery, "CastingApp::Stop() called");
VerifyOrReturnError(mState == CASTING_APP_RUNNING, CHIP_ERROR_INCORRECT_STATE);
// Shutdown the Matter server
chip::Server::GetInstance().Shutdown();
mState = CASTING_APP_NOT_RUNNING; // CastingApp stopped successfully, set state to NOT_RUNNING
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::ShutdownAllSubscriptions()
{
VerifyOrReturnError(mState == CASTING_APP_RUNNING, CHIP_ERROR_INCORRECT_STATE);
chip::app::InteractionModelEngine::GetInstance()->ShutdownAllSubscriptions();
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::ClearCache()
{
return support::CastingStore::GetInstance()->DeleteAll();
}
}; // namespace core
}; // namespace casting
}; // namespace matter