blob: 18c108d70fd95bd2cac2bf23550c39fe6df0c5af [file] [log] [blame]
/*
*
* Copyright (c) 2023-2024 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 "CommissionerDeclarationHandler.h"
#include "ConnectionCallbacks.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::UpdateCommissionableDataProvider(chip::DeviceLayer::CommissionableDataProvider * commissionableDataProvider)
{
ChipLogProgress(Discovery, "CastingApp::UpdateCommissionableDataProvider()");
chip::DeviceLayer::SetCommissionableDataProvider(commissionableDataProvider);
return mAppParameters->SetCommissionableDataProvider(commissionableDataProvider);
}
void ReconnectHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * castingPlayer)
{
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "CastingApp::ConnectionHandler() Could not reconnect to CastingPlayer %" CHIP_ERROR_FORMAT,
err.Format());
}
else
{
ChipLogProgress(AppServer, "CastingApp::ConnectionHandler() Reconnected to CastingPlayer(ID: %s)", castingPlayer->GetId());
}
}
CHIP_ERROR CastingApp::Start()
{
ChipLogProgress(Discovery, "CastingApp::Start()");
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)
{
matter::casting::core::ConnectionCallbacks connectionCallbacks;
connectionCallbacks.mOnConnectionComplete = ReconnectHandler;
// Re-connecting to a CastingPLayer does not require a full User Directed Commissioning (UDC) process so
// CommissionerDeclaration messages are not expected. Leaving ConnectionCallbacks mCommissionerDeclarationCallback as
// nullptr.
ChipLogProgress(
Discovery,
"CastingApp::Start() calling VerifyOrEstablishConnection() to reconnect (or verify connection) to a CastingPlayer");
CastingPlayer::GetTargetCastingPlayer()->VerifyOrEstablishConnection(connectionCallbacks);
}
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::PostStartRegistrations()
{
ChipLogProgress(Discovery, "CastingApp::PostStartRegistrations()");
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));
ChipLogProgress(
Discovery,
"CastingApp::PostStartRegistrations() calling GetUserDirectedCommissioningClient()->SetCommissionerDeclarationHandler()");
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
// Set a handler for Commissioner's CommissionerDeclaration messages. This is set in
// connectedhomeip/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h
chip::Server::GetInstance().GetUserDirectedCommissioningClient()->SetCommissionerDeclarationHandler(
CommissionerDeclarationHandler::GetInstance());
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
mState = CASTING_APP_RUNNING; // CastingApp started successfully, set state to RUNNING
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::Stop()
{
ChipLogProgress(Discovery, "CastingApp::Stop()");
VerifyOrReturnError(mState == CASTING_APP_RUNNING, CHIP_ERROR_INCORRECT_STATE);
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
// Remove the handler previously set for Commissioner's CommissionerDeclaration messages.
chip::Server::GetInstance().GetUserDirectedCommissioningClient()->SetCommissionerDeclarationHandler(nullptr);
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
// 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()
{
chip::app::InteractionModelEngine::GetInstance()->ShutdownAllSubscriptions();
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingApp::ClearCache()
{
return support::CastingStore::GetInstance()->DeleteAll();
}
}; // namespace core
}; // namespace casting
}; // namespace matter