From aba8046761fb57781abb723ae5acc85273d2f808 Mon Sep 17 00:00:00 2001 From: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> Date: Thu, 27 Jan 2022 09:05:43 -0800 Subject: [PATCH] Link attribute reads to Content Apps, refactor content app platform to leverage latest cluster lib conventions (#12969) * link attribute reads to Content Apps * address some comments * route attribute reads and writes to per-cluster handlers * refactor content app * straggler * use MEI log format commands * fix tv-app test suites * fix tv-app test suites * fix CI test suites * fix CI test suites * add bindings call * migrate content app to use new account login delegate * refactor ContentApp to use delegates * fix CI errors * fix CI errors * fix CI errors * more ContentApp to app-platform directory * address issue 13144 * address issue 12543 * address comments * address comments * fix handling of application launcher, application basic status and content platform * fix build * fix android build * fix android build * add Commissioner Discovery Controller to manage UDC workflow * address comments * address comments * fix builds * fix builds * fix builds * address comments * fix potential leak on commands * fix potential leak on attribute reads * fix potential leak on attribute reads * argument and naming consistency * fix android build * fix android build * fix android build * fix android build * address easy comments * fix android build * fix android * fix merge issue * optimize image size * fix build * attempt to fix CI build * attempt to fix CI build * attempt to fix CI build * reduce dependencies Co-authored-by: Christopher DeCenzo --- examples/platform/linux/AppMain.cpp | 141 +++++-- examples/platform/linux/AppMain.h | 8 +- .../linux/ControllerShellCommands.cpp | 42 +- .../account-login/AccountLoginManager.cpp | 5 +- .../account-login/AccountLoginManager.h | 20 +- .../ApplicationBasicManager.cpp | 38 +- .../ApplicationBasicManager.h | 15 +- .../ApplicationLauncherManager.cpp | 40 +- .../ApplicationLauncherManager.h | 25 +- .../audio-output/AudioOutputManager.cpp | 27 +- .../include/audio-output/AudioOutputManager.h | 7 +- .../TargetNavigatorManager.cpp | 33 +- .../target-navigator/TargetNavigatorManager.h | 15 +- .../tv-app/android/java/ChannelManager.cpp | 15 +- examples/tv-app/android/java/ChannelManager.h | 18 +- .../android/java/ContentLauncherManager.cpp | 21 +- .../android/java/ContentLauncherManager.h | 22 +- .../android/java/KeypadInputManager.cpp | 4 +- .../tv-app/android/java/KeypadInputManager.h | 10 +- .../android/java/MediaPlaybackManager.cpp | 52 +-- .../android/java/MediaPlaybackManager.h | 36 +- examples/tv-app/linux/AppImpl.cpp | 127 ++---- examples/tv-app/linux/AppImpl.h | 200 ++++----- .../tv-app/linux/AppPlatformShellCommands.cpp | 66 ++- .../tv-app/linux/AppPlatformShellCommands.h | 2 +- .../account-login/AccountLoginManager.cpp | 33 +- .../account-login/AccountLoginManager.h | 27 +- .../ApplicationBasicManager.cpp | 41 +- .../ApplicationBasicManager.h | 45 +- .../ApplicationLauncherManager.cpp | 57 +-- .../ApplicationLauncherManager.h | 30 +- .../audio-output/AudioOutputManager.cpp | 27 +- .../include/audio-output/AudioOutputManager.h | 7 +- .../linux/include/channel/ChannelManager.cpp | 15 +- .../linux/include/channel/ChannelManager.h | 18 +- .../ContentLauncherManager.cpp | 63 ++- .../content-launcher/ContentLauncherManager.h | 32 +- .../keypad-input/KeypadInputManager.cpp | 4 +- .../include/keypad-input/KeypadInputManager.h | 10 +- .../media-playback/MediaPlaybackManager.cpp | 52 +-- .../media-playback/MediaPlaybackManager.h | 36 +- .../TargetNavigatorManager.cpp | 57 ++- .../target-navigator/TargetNavigatorManager.h | 24 +- examples/tv-app/linux/main.cpp | 86 +++- src/app/app-platform/ContentApp.cpp | 70 ++++ src/app/app-platform/ContentApp.h | 80 ++++ src/app/app-platform/ContentAppPlatform.cpp | 392 ++++++++++++++++++ src/app/app-platform/ContentAppPlatform.h | 130 ++++++ src/app/chip_data_model.gni | 4 +- .../account-login-delegate.h | 8 +- .../account-login-server.cpp | 34 +- .../application-basic-delegate.h | 62 ++- .../application-basic-server.cpp | 84 ++-- .../application-basic-server.h | 1 + .../application-launcher-delegate.h | 40 +- .../application-launcher-server.cpp | 255 ++++++++++-- .../audio-output-delegate.h | 5 +- .../audio-output-server.cpp | 9 +- .../channel-server/channel-delegate.h | 8 +- .../channel-server/channel-server.cpp | 30 +- .../content-launch-delegate.h | 9 +- .../content-launch-server.cpp | 45 +- .../content-launch-server.h | 2 +- .../keypad-input-delegate.h | 3 +- .../keypad-input-server.cpp | 30 +- .../media-playback-delegate.h | 43 +- .../media-playback-server.cpp | 89 ++-- .../target-navigator-delegate.h | 9 +- .../target-navigator-server.cpp | 43 +- src/app/util/ContentApp.cpp | 297 ------------- src/app/util/ContentApp.h | 173 -------- src/app/util/ContentAppPlatform.cpp | 266 ------------ src/app/util/ContentAppPlatform.h | 80 ---- src/controller/BUILD.gn | 2 + src/controller/CHIPDeviceController.cpp | 41 +- src/controller/CHIPDeviceController.h | 32 +- .../CommissionerDiscoveryController.cpp | 159 +++++++ .../CommissionerDiscoveryController.h | 184 ++++++++ .../UDCClientState.h | 8 +- .../UserDirectedCommissioningServer.cpp | 2 +- 80 files changed, 2602 insertions(+), 1780 deletions(-) create mode 100644 src/app/app-platform/ContentApp.cpp create mode 100644 src/app/app-platform/ContentApp.h create mode 100644 src/app/app-platform/ContentAppPlatform.cpp create mode 100644 src/app/app-platform/ContentAppPlatform.h delete mode 100644 src/app/util/ContentApp.cpp delete mode 100644 src/app/util/ContentApp.h delete mode 100644 src/app/util/ContentAppPlatform.cpp delete mode 100644 src/app/util/ContentAppPlatform.h create mode 100644 src/controller/CommissionerDiscoveryController.cpp create mode 100644 src/controller/CommissionerDiscoveryController.h diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 78509b2fcdd2f0..ff34984ec8829c 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -103,10 +103,10 @@ static constexpr uint8_t kWiFiStartCheckAttempts = 5; #endif namespace { -void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +void EventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) { (void) arg; - if (event->Type == chip::DeviceLayer::DeviceEventType::kCHIPoBLEConnectionEstablished) + if (event->Type == DeviceLayer::DeviceEventType::kCHIPoBLEConnectionEstablished) { ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished"); } @@ -120,7 +120,7 @@ static bool EnsureWiFiIsStarted() { for (int cnt = 0; cnt < kWiFiStartCheckAttempts; cnt++) { - if (chip::DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) + if (DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) { return true; } @@ -128,7 +128,7 @@ static bool EnsureWiFiIsStarted() usleep(kWiFiStartCheckTimeUsec); } - return chip::DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted(); + return DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted(); } #endif @@ -136,19 +136,19 @@ int ChipLinuxAppInit(int argc, char ** argv) { CHIP_ERROR err = CHIP_NO_ERROR; #if CONFIG_NETWORK_LAYER_BLE - chip::RendezvousInformationFlags rendezvousFlags = chip::RendezvousInformationFlag::kBLE; + RendezvousInformationFlags rendezvousFlags = RendezvousInformationFlag::kBLE; #else // CONFIG_NETWORK_LAYER_BLE - chip::RendezvousInformationFlag rendezvousFlags = RendezvousInformationFlag::kOnNetwork; + RendezvousInformationFlag rendezvousFlags = RendezvousInformationFlag::kOnNetwork; #endif // CONFIG_NETWORK_LAYER_BLE #ifdef CONFIG_RENDEZVOUS_MODE - rendezvousFlags = static_cast(CONFIG_RENDEZVOUS_MODE); + rendezvousFlags = static_cast(CONFIG_RENDEZVOUS_MODE); #endif - err = chip::Platform::MemoryInit(); + err = Platform::MemoryInit(); SuccessOrExit(err); - err = chip::DeviceLayer::PlatformMgr().InitChipStack(); + err = DeviceLayer::PlatformMgr().InitChipStack(); SuccessOrExit(err); err = GetSetupPayload(LinuxDeviceOptions::GetInstance().payload, rendezvousFlags); @@ -164,22 +164,22 @@ int ChipLinuxAppInit(int argc, char ** argv) Access::Examples::SetAccessControlDelegateStorage(&gAclStorageDelegate); #if defined(PW_RPC_ENABLED) - chip::rpc::Init(); + rpc::Init(); ChipLogProgress(NotSpecified, "PW_RPC initialized."); #endif // defined(PW_RPC_ENABLED) - chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0); + DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0); #if CONFIG_NETWORK_LAYER_BLE - chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX) - chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false); - chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true); + DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX) + DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false); + DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true); #endif #if CHIP_DEVICE_CONFIG_ENABLE_WPA if (LinuxDeviceOptions::GetInstance().mWiFi) { - chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); + DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); if (!EnsureWiFiIsStarted()) { ChipLogError(NotSpecified, "Wi-Fi Management taking too long to start - device configuration will be reset."); @@ -190,7 +190,7 @@ int ChipLinuxAppInit(int argc, char ** argv) #if CHIP_ENABLE_OPENTHREAD if (LinuxDeviceOptions::GetInstance().mThread) { - SuccessOrExit(err = chip::DeviceLayer::ThreadStackMgrImpl().InitThreadStack()); + SuccessOrExit(err = DeviceLayer::ThreadStackMgrImpl().InitThreadStack()); ChipLogProgress(NotSpecified, "Thread initialized."); } #endif // CHIP_ENABLE_OPENTHREAD @@ -236,17 +236,26 @@ class MyServerStorageDelegate : public PersistentStorageDelegate } }; +class MyCommissionerCallback : public CommissionerCallback +{ + void ReadyForCommissioning(uint32_t pincode, uint16_t longDiscriminator, PeerAddress peerAddress) override + { + CommissionerPairOnNetwork(pincode, longDiscriminator, peerAddress); + } +}; + DeviceCommissioner gCommissioner; +CommissionerDiscoveryController gCommissionerDiscoveryController; +MyCommissionerCallback gCommissionerCallback; MyServerStorageDelegate gServerStorage; -chip::SimpleFabricStorage gFabricStorage; +SimpleFabricStorage gFabricStorage; ExampleOperationalCredentialsIssuer gOpCredsIssuer; +NodeId gLocalId = kPlaceholderNodeId; CHIP_ERROR InitCommissioner() { - NodeId localId = chip::kPlaceholderNodeId; - - chip::Controller::FactoryInitParams factoryParams; - chip::Controller::SetupParams params; + Controller::FactoryInitParams factoryParams; + Controller::SetupParams params; ReturnErrorOnFailure(gFabricStorage.Initialize(&gServerStorage)); @@ -264,49 +273,60 @@ CHIP_ERROR InitCommissioner() // Initialize device attestation verifier // TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available - const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); + const Credentials::AttestationTrustStore * testingRootStore = Credentials::GetTestAttestationTrustStore(); SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore)); - chip::Platform::ScopedMemoryBuffer noc; - VerifyOrReturnError(noc.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); - chip::MutableByteSpan nocSpan(noc.Get(), chip::Controller::kMaxCHIPDERCertLength); + Platform::ScopedMemoryBuffer noc; + VerifyOrReturnError(noc.Alloc(Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); + MutableByteSpan nocSpan(noc.Get(), Controller::kMaxCHIPDERCertLength); - chip::Platform::ScopedMemoryBuffer icac; - VerifyOrReturnError(icac.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); - chip::MutableByteSpan icacSpan(icac.Get(), chip::Controller::kMaxCHIPDERCertLength); + Platform::ScopedMemoryBuffer icac; + VerifyOrReturnError(icac.Alloc(Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); + MutableByteSpan icacSpan(icac.Get(), Controller::kMaxCHIPDERCertLength); - chip::Platform::ScopedMemoryBuffer rcac; - VerifyOrReturnError(rcac.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); - chip::MutableByteSpan rcacSpan(rcac.Get(), chip::Controller::kMaxCHIPDERCertLength); + Platform::ScopedMemoryBuffer rcac; + VerifyOrReturnError(rcac.Alloc(Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); + MutableByteSpan rcacSpan(rcac.Get(), Controller::kMaxCHIPDERCertLength); - chip::Crypto::P256Keypair ephemeralKey; + Crypto::P256Keypair ephemeralKey; ReturnErrorOnFailure(ephemeralKey.Initialize()); ReturnErrorOnFailure( - gOpCredsIssuer.GenerateNOCChainAfterValidation(localId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan)); + gOpCredsIssuer.GenerateNOCChainAfterValidation(gLocalId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan)); params.operationalKeypair = &ephemeralKey; params.controllerRCAC = rcacSpan; params.controllerICAC = icacSpan; params.controllerNOC = nocSpan; - auto & factory = chip::Controller::DeviceControllerFactory::GetInstance(); + auto & factory = Controller::DeviceControllerFactory::GetInstance(); ReturnErrorOnFailure(factory.Init(factoryParams)); ReturnErrorOnFailure(factory.SetupCommissioner(params, gCommissioner)); + gCommissionerDiscoveryController.SetUserDirectedCommissioningServer(gCommissioner.GetUserDirectedCommissioningServer()); + gCommissionerDiscoveryController.SetCommissionerCallback(&gCommissionerCallback); return CHIP_NO_ERROR; } CHIP_ERROR ShutdownCommissioner() { + UserDirectedCommissioningServer * udcServer = gCommissioner.GetUserDirectedCommissioningServer(); + if (udcServer != nullptr) + { + udcServer->SetUserConfirmationProvider(nullptr); + } + gCommissioner.Shutdown(); return CHIP_NO_ERROR; } -class PairingCommand : public chip::Controller::DevicePairingDelegate, public chip::Controller::DeviceAddressUpdateDelegate +class PairingCommand : public Controller::DevicePairingDelegate, public Controller::DeviceAddressUpdateDelegate { +public: + PairingCommand() : mSuccessCallback(OnSuccessResponse, this), mFailureCallback(OnFailureResponse, this){}; + /////////// DevicePairingDelegate Interface ///////// - void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override; + void OnStatusUpdate(Controller::DevicePairingDelegate::Status status) override; void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; @@ -315,6 +335,14 @@ class PairingCommand : public chip::Controller::DevicePairingDelegate, public ch void OnAddressUpdateComplete(NodeId nodeId, CHIP_ERROR error) override; CHIP_ERROR UpdateNetworkAddress(); + + /* Callback when command results in success */ + static void OnSuccessResponse(void * context); + /* Callback when command results in failure */ + static void OnFailureResponse(void * context, uint8_t status); + + Callback::Callback mSuccessCallback; + Callback::Callback mFailureCallback; }; PairingCommand gPairingCommand; @@ -373,11 +401,37 @@ void PairingCommand::OnPairingDeleted(CHIP_ERROR err) } } +void PairingCommand::OnSuccessResponse(void * context) +{ + ChipLogProgress(Controller, "OnSuccessResponse"); +} + +void PairingCommand::OnFailureResponse(void * context, uint8_t status) +{ + ChipLogProgress(Controller, "OnFailureResponse"); +} + void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) { if (err == CHIP_NO_ERROR) { ChipLogProgress(AppServer, "Device commissioning completed with success"); + + // TODO: + // - this code needs to be conditional based upon Content App Platform enablement + // - the endpointId chosen should come from the App Platform (determined based upon vid/pid of node) + // - the cluster(s) chosen should come from the App Platform + constexpr EndpointId kBindingClusterEndpoint = 0; + + Callback::Cancelable * successCallback = mSuccessCallback.Cancel(); + Callback::Cancelable * failureCallback = mFailureCallback.Cancel(); + + GroupId groupId = kUndefinedGroupId; + EndpointId endpointId = 1; + ClusterId clusterId = kInvalidClusterId; + + gCommissioner.CreateBindingWithCallback(nodeId, kBindingClusterEndpoint, gLocalId, groupId, endpointId, clusterId, + successCallback, failureCallback); } else { @@ -385,7 +439,7 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) } } -CHIP_ERROR CommissionerPairOnNetwork(uint32_t pincode, uint16_t disc, chip::Transport::PeerAddress address) +CHIP_ERROR CommissionerPairOnNetwork(uint32_t pincode, uint16_t disc, Transport::PeerAddress address) { RendezvousParameters params = RendezvousParameters().SetSetupPINCode(pincode).SetDiscriminator(disc).SetPeerAddress(address); @@ -419,6 +473,11 @@ DeviceCommissioner * GetDeviceCommissioner() return &gCommissioner; } +CommissionerDiscoveryController * GetCommissionerDiscoveryController() +{ + return &gCommissionerDiscoveryController; +} + #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE void ChipLinuxAppMainLoop() @@ -426,7 +485,7 @@ void ChipLinuxAppMainLoop() #if defined(ENABLE_CHIP_SHELL) Engine::Root().Init(); std::thread shellThread([]() { Engine::Root().RunMainLoop(); }); - chip::Shell::RegisterCommissioneeCommands(); + Shell::RegisterCommissioneeCommands(); #endif uint16_t securePort = CHIP_PORT; uint16_t unsecurePort = CHIP_UDC_PORT; @@ -438,7 +497,7 @@ void ChipLinuxAppMainLoop() #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE // Init ZCL Data Model and CHIP App Server - chip::Server::GetInstance().Init(nullptr, securePort, unsecurePort); + Server::GetInstance().Init(nullptr, securePort, unsecurePort); // Now that the server has started and we are done with our startup logging, // log our discovery/onboarding information again so it's not lost in the @@ -453,13 +512,13 @@ void ChipLinuxAppMainLoop() #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE InitCommissioner(); #if defined(ENABLE_CHIP_SHELL) - chip::Shell::RegisterControllerCommands(); + Shell::RegisterControllerCommands(); #endif // defined(ENABLE_CHIP_SHELL) #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE ApplicationInit(); - chip::DeviceLayer::PlatformMgr().RunEventLoop(); + DeviceLayer::PlatformMgr().RunEventLoop(); #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE ShutdownCommissioner(); diff --git a/examples/platform/linux/AppMain.h b/examples/platform/linux/AppMain.h index 914499e4f851eb..67396b7a918642 100644 --- a/examples/platform/linux/AppMain.h +++ b/examples/platform/linux/AppMain.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -32,13 +33,14 @@ void ChipLinuxAppMainLoop(); #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE -using namespace chip::Transport; -using namespace ::chip::Controller; +using chip::Controller::DeviceCommissioner; +using chip::Transport::PeerAddress; -CHIP_ERROR CommissionerPairOnNetwork(uint32_t pincode, uint16_t disc, chip::Transport::PeerAddress address); +CHIP_ERROR CommissionerPairOnNetwork(uint32_t pincode, uint16_t disc, PeerAddress address); CHIP_ERROR CommissionerPairUDC(uint32_t pincode, size_t index); DeviceCommissioner * GetDeviceCommissioner(); +CommissionerDiscoveryController * GetCommissionerDiscoveryController(); #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE diff --git a/examples/platform/linux/ControllerShellCommands.cpp b/examples/platform/linux/ControllerShellCommands.cpp index ff231eb5341c50..81d21ece09ae16 100644 --- a/examples/platform/linux/ControllerShellCommands.cpp +++ b/examples/platform/linux/ControllerShellCommands.cpp @@ -36,6 +36,7 @@ namespace chip { namespace Shell { +using namespace chip; using namespace ::chip::Controller; #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY @@ -116,7 +117,7 @@ static CHIP_ERROR display(bool printHeader) for (int i = 0; i < 10; i++) { - const chip::Dnssd::DiscoveredNodeData * next = GetDeviceCommissioner()->GetDiscoveredDevice(i); + const Dnssd::DiscoveredNodeData * next = GetDeviceCommissioner()->GetDiscoveredDevice(i); if (next == nullptr) { streamer_printf(sout, " Entry %d null\r\n", i); @@ -133,7 +134,7 @@ static CHIP_ERROR display(bool printHeader) return CHIP_NO_ERROR; } -static CHIP_ERROR pairOnNetwork(bool printHeader, uint32_t pincode, uint16_t disc, chip::Transport::PeerAddress address) +static CHIP_ERROR pairOnNetwork(bool printHeader, uint32_t pincode, uint16_t disc, Transport::PeerAddress address) { streamer_t * sout = streamer_get(); @@ -176,6 +177,7 @@ static CHIP_ERROR PrintAllCommands() sout, " udc-print Print all pending UDC sessions from this UDC server. Usage: controller udc-print\r\n"); #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + streamer_printf(sout, " ux ok|cancel [] User input. Usage: controller ux ok 34567890\r\n"); streamer_printf(sout, " udc-commission Commission given udc-entry using given pincode. Usage: controller " "udc-commission 34567890 0\r\n"); @@ -240,12 +242,42 @@ static CHIP_ERROR ControllerHandler(int argc, char ** argv) uint32_t pincode = (uint32_t) strtol(argv[1], &eptr, 10); uint16_t disc = (uint16_t) strtol(argv[2], &eptr, 10); - chip::Inet::IPAddress address; - chip::Inet::IPAddress::FromString(argv[3], address); + Inet::IPAddress address; + Inet::IPAddress::FromString(argv[3], address); uint16_t port = (uint16_t) strtol(argv[4], &eptr, 10); - return error = pairOnNetwork(true, pincode, disc, chip::Transport::PeerAddress::UDP(address, port)); + return error = pairOnNetwork(true, pincode, disc, Transport::PeerAddress::UDP(address, port)); + } + else if (strcmp(argv[0], "ux") == 0) + { + // ux ok|cancel [pincode] + if (argc < 2) + { + return PrintAllCommands(); + } + char * eptr; + char * response = argv[1]; + if (strcmp(response, "cancel") == 0) + { + GetCommissionerDiscoveryController()->Cancel(); + return CHIP_NO_ERROR; + } + else if (strcmp(response, "ok") == 0) + { + if (argc >= 3) + { + uint32_t pincode = (uint32_t) strtol(argv[2], &eptr, 10); + GetCommissionerDiscoveryController()->CommissionWithPincode(pincode); + return CHIP_NO_ERROR; + } + GetCommissionerDiscoveryController()->Ok(); + return CHIP_NO_ERROR; + } + else + { + return PrintAllCommands(); + } } else if (strcmp(argv[0], "udc-commission") == 0) { diff --git a/examples/tv-app/android/include/account-login/AccountLoginManager.cpp b/examples/tv-app/android/include/account-login/AccountLoginManager.cpp index cabd7e77fb9fa0..1d2ae613d56cd2 100644 --- a/examples/tv-app/android/include/account-login/AccountLoginManager.cpp +++ b/examples/tv-app/android/include/account-login/AccountLoginManager.cpp @@ -40,12 +40,13 @@ bool AccountLoginManager::HandleLogout() return true; } -Commands::GetSetupPINResponse::Type AccountLoginManager::HandleGetSetupPin(const chip::CharSpan & tempAccountIdentifier) +void AccountLoginManager::HandleGetSetupPin(CommandResponseHelper & helper, + const CharSpan & tempAccountIdentifier) { string tempAccountIdentifierString(tempAccountIdentifier.data(), tempAccountIdentifier.size()); ChipLogProgress(Zcl, "temporary account id: %s", tempAccountIdentifierString.c_str()); // TODO: Insert your code here to handle get setup pin Commands::GetSetupPINResponse::Type response; response.setupPIN = chip::CharSpan::fromCharString("tempPin123"); - return response; + helper.Success(response); } diff --git a/examples/tv-app/android/include/account-login/AccountLoginManager.h b/examples/tv-app/android/include/account-login/AccountLoginManager.h index 68584ae6ec7bd5..3f4e8da90f72d8 100644 --- a/examples/tv-app/android/include/account-login/AccountLoginManager.h +++ b/examples/tv-app/android/include/account-login/AccountLoginManager.h @@ -22,11 +22,23 @@ #include -class AccountLoginManager : public chip::app::Clusters::AccountLogin::Delegate +using chip::CharSpan; +using chip::app::CommandResponseHelper; +using chip::Platform::CopyString; +using AccountLoginDelegate = chip::app::Clusters::AccountLogin::Delegate; +using GetSetupPINResponse = chip::app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Type; + +class AccountLoginManager : public AccountLoginDelegate { public: - bool HandleLogin(const chip::CharSpan & tempAccountIdentifierString, const chip::CharSpan & setupPinString) override; + inline void SetSetupPin(char * setupPin) override { return; }; + + bool HandleLogin(const CharSpan & tempAccountIdentifierString, const CharSpan & setupPinString) override; bool HandleLogout() override; - chip::app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Type - HandleGetSetupPin(const chip::CharSpan & tempAccountIdentifierString) override; + void HandleGetSetupPin(CommandResponseHelper & helper, + const CharSpan & tempAccountIdentifierString) override; + inline void GetSetupPin(char * setupPin, size_t setupPinSize, const CharSpan & tempAccountIdentifierString) override + { + CopyString(setupPin, setupPinSize, ""); + }; }; diff --git a/examples/tv-app/android/include/application-basic/ApplicationBasicManager.cpp b/examples/tv-app/android/include/application-basic/ApplicationBasicManager.cpp index 7b1019815fd199..4ca4fcea73f254 100644 --- a/examples/tv-app/android/include/application-basic/ApplicationBasicManager.cpp +++ b/examples/tv-app/android/include/application-basic/ApplicationBasicManager.cpp @@ -19,11 +19,13 @@ #include "ApplicationBasicManager.h" using namespace std; +using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters::ApplicationBasic; -chip::CharSpan ApplicationBasicManager::HandleGetVendorName() +CHIP_ERROR ApplicationBasicManager::HandleGetVendorName(AttributeValueEncoder & aEncoder) { - return chip::CharSpan::fromCharString("exampleVendorName1"); + return aEncoder.Encode(CharSpan::fromCharString("exampleVendorName1")); } uint16_t ApplicationBasicManager::HandleGetVendorId() @@ -31,9 +33,9 @@ uint16_t ApplicationBasicManager::HandleGetVendorId() return 1; } -chip::CharSpan ApplicationBasicManager::HandleGetApplicationName() +CHIP_ERROR ApplicationBasicManager::HandleGetApplicationName(AttributeValueEncoder & aEncoder) { - return chip::CharSpan::fromCharString("exampleName1"); + return aEncoder.Encode(CharSpan::fromCharString("exampleName1")); } uint16_t ApplicationBasicManager::HandleGetProductId() @@ -41,25 +43,19 @@ uint16_t ApplicationBasicManager::HandleGetProductId() return 1; } -chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type ApplicationBasicManager::HandleGetApplication() +CHIP_ERROR ApplicationBasicManager::HandleGetApplicationVersion(AttributeValueEncoder & aEncoder) { - chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type application; - application.catalogVendorId = 123; - application.applicationId = chip::CharSpan::fromCharString("applicationId"); - return application; + return aEncoder.Encode(CharSpan::fromCharString("exampleVersion")); } -ApplicationStatusEnum ApplicationBasicManager::HandleGetStatus() +CHIP_ERROR ApplicationBasicManager::HandleGetAllowedVendorList(AttributeValueEncoder & aEncoder) { - return ApplicationStatusEnum::kStopped; -} - -chip::CharSpan ApplicationBasicManager::HandleGetApplicationVersion() -{ - return chip::CharSpan::fromCharString("exampleVersion"); -} - -std::list ApplicationBasicManager::HandleGetAllowedVendorList() -{ - return { 123, 456 }; + std::list allowedVendorList = { 123, 456 }; + return aEncoder.EncodeList([allowedVendorList](const auto & encoder) -> CHIP_ERROR { + for (const auto & allowedVendor : allowedVendorList) + { + ReturnErrorOnFailure(encoder.Encode(allowedVendor)); + } + return CHIP_NO_ERROR; + }); } diff --git a/examples/tv-app/android/include/application-basic/ApplicationBasicManager.h b/examples/tv-app/android/include/application-basic/ApplicationBasicManager.h index ec8904fa581ff8..e48fe2eb3e24ed 100644 --- a/examples/tv-app/android/include/application-basic/ApplicationBasicManager.h +++ b/examples/tv-app/android/include/application-basic/ApplicationBasicManager.h @@ -20,15 +20,16 @@ #include -class ApplicationBasicManager : public chip::app::Clusters::ApplicationBasic::Delegate +using chip::app::AttributeValueEncoder; +using ApplicationBasicDelegate = chip::app::Clusters::ApplicationBasic::Delegate; + +class ApplicationBasicManager : public ApplicationBasicDelegate { public: - chip::CharSpan HandleGetVendorName() override; + CHIP_ERROR HandleGetVendorName(AttributeValueEncoder & aEncoder) override; uint16_t HandleGetVendorId() override; - chip::CharSpan HandleGetApplicationName() override; + CHIP_ERROR HandleGetApplicationName(AttributeValueEncoder & aEncoder) override; uint16_t HandleGetProductId() override; - chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type HandleGetApplication() override; - chip::app::Clusters::ApplicationBasic::ApplicationStatusEnum HandleGetStatus() override; - chip::CharSpan HandleGetApplicationVersion() override; - std::list HandleGetAllowedVendorList() override; + CHIP_ERROR HandleGetApplicationVersion(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAllowedVendorList(AttributeValueEncoder & aEncoder) override; }; diff --git a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp index a4fd66fab1a1ee..003a20d84ce3f7 100644 --- a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp +++ b/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp @@ -19,49 +19,47 @@ #include "ApplicationLauncherManager.h" using namespace std; +using namespace chip::app; using namespace chip::app::Clusters::ApplicationLauncher; -Structs::ApplicationEP::Type ApplicationLauncherManager::HandleGetCurrentApp() +CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncoder & aEncoder) { - Structs::ApplicationEP::Type currentApp; - currentApp.application.catalogVendorId = 123; - currentApp.application.applicationId = chip::CharSpan::fromCharString("applicationId"); - currentApp.endpoint = chip::CharSpan::fromCharString("endpointId"); - return currentApp; + std::list catalogList = { 123, 456 }; + return aEncoder.EncodeList([catalogList](const auto & encoder) -> CHIP_ERROR { + for (const auto & catalog : catalogList) + { + ReturnErrorOnFailure(encoder.Encode(catalog)); + } + return CHIP_NO_ERROR; + }); } -std::list ApplicationLauncherManager::HandleGetCatalogList() -{ - return { 123, 456 }; -} - -Commands::LauncherResponse::Type ApplicationLauncherManager::HandleLaunchApp( - const chip::CharSpan & data, - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) +void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper & helper, const CharSpan & data, + const ApplicationLauncherApplicationType & application) { // TODO: Insert code here Commands::LauncherResponse::Type response; response.data = chip::CharSpan::fromCharString("data"); response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::LauncherResponse::Type ApplicationLauncherManager::HandleStopApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) +void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) { // TODO: Insert code here Commands::LauncherResponse::Type response; response.data = chip::CharSpan::fromCharString("data"); response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::LauncherResponse::Type ApplicationLauncherManager::HandleHideApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) +void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) { // TODO: Insert code here Commands::LauncherResponse::Type response; response.data = chip::CharSpan::fromCharString("data"); response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } diff --git a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h b/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h index 122b03e865c15a..529f4d440acbe6 100644 --- a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h +++ b/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h @@ -21,17 +21,22 @@ #include #include -class ApplicationLauncherManager : public chip::app::Clusters::ApplicationLauncher::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using ApplicationLauncherDelegate = chip::app::Clusters::ApplicationLauncher::Delegate; +using ApplicationLauncherApplicationType = chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type; +using LauncherResponseType = chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type; + +class ApplicationLauncherManager : public ApplicationLauncherDelegate { public: - chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEP::Type HandleGetCurrentApp() override; - std::list HandleGetCatalogList() override; + CHIP_ERROR HandleGetCatalogList(AttributeValueEncoder & aEncoder) override; - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type HandleLaunchApp( - const chip::CharSpan & data, - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) override; - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type HandleStopApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) override; - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type HandleHideApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) override; + void HandleLaunchApp(CommandResponseHelper & helper, const CharSpan & data, + const ApplicationLauncherApplicationType & application) override; + void HandleStopApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) override; + void HandleHideApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) override; }; diff --git a/examples/tv-app/android/include/audio-output/AudioOutputManager.cpp b/examples/tv-app/android/include/audio-output/AudioOutputManager.cpp index 5b94bff20b1a76..c0d806994549ec 100644 --- a/examples/tv-app/android/include/audio-output/AudioOutputManager.cpp +++ b/examples/tv-app/android/include/audio-output/AudioOutputManager.cpp @@ -19,6 +19,7 @@ #include "AudioOutputManager.h" using namespace std; +using namespace chip::app; using namespace chip::app::Clusters::AudioOutput; uint8_t AudioOutputManager::HandleGetCurrentOutput() @@ -26,21 +27,21 @@ uint8_t AudioOutputManager::HandleGetCurrentOutput() return 0; } -std::list AudioOutputManager::HandleGetOutputList() +CHIP_ERROR AudioOutputManager::HandleGetOutputList(AttributeValueEncoder & aEncoder) { - std::list list; // TODO: Insert code here - int maximumVectorSize = 3; - - for (int i = 0; i < maximumVectorSize; ++i) - { - chip::app::Clusters::AudioOutput::Structs::OutputInfo::Type outputInfo; - outputInfo.outputType = chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi; - outputInfo.name = chip::CharSpan::fromCharString("exampleName"); - outputInfo.index = static_cast(1 + i); - list.push_back(outputInfo); - } - return list; + return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { + int maximumVectorSize = 3; + for (int i = 0; i < maximumVectorSize; ++i) + { + chip::app::Clusters::AudioOutput::Structs::OutputInfo::Type outputInfo; + outputInfo.outputType = chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi; + outputInfo.name = chip::CharSpan::fromCharString("exampleName"); + outputInfo.index = static_cast(1 + i); + ReturnErrorOnFailure(encoder.Encode(outputInfo)); + } + return CHIP_NO_ERROR; + }); } bool AudioOutputManager::HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) diff --git a/examples/tv-app/android/include/audio-output/AudioOutputManager.h b/examples/tv-app/android/include/audio-output/AudioOutputManager.h index 8dcd3ed344fc9a..44359fa75c8e1f 100644 --- a/examples/tv-app/android/include/audio-output/AudioOutputManager.h +++ b/examples/tv-app/android/include/audio-output/AudioOutputManager.h @@ -20,11 +20,14 @@ #include -class AudioOutputManager : public chip::app::Clusters::AudioOutput::Delegate +using chip::app::AttributeValueEncoder; +using AudioOutputDelegate = chip::app::Clusters::AudioOutput::Delegate; + +class AudioOutputManager : public AudioOutputDelegate { public: uint8_t HandleGetCurrentOutput() override; - std::list HandleGetOutputList() override; + CHIP_ERROR HandleGetOutputList(AttributeValueEncoder & aEncoder) override; bool HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) override; bool HandleSelectOutput(const uint8_t & index) override; }; diff --git a/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.cpp b/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.cpp index 145531d5aa82d1..9f04faa15c9ff1 100644 --- a/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.cpp +++ b/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.cpp @@ -18,22 +18,23 @@ #include "TargetNavigatorManager.h" using namespace std; +using namespace chip::app; using namespace chip::app::Clusters::TargetNavigator; -std::list TargetNavigatorManager::HandleGetTargetList() +CHIP_ERROR TargetNavigatorManager::HandleGetTargetList(AttributeValueEncoder & aEncoder) { - std::list list; - // TODO: Insert code here - int maximumVectorSize = 2; - - for (int i = 0; i < maximumVectorSize; ++i) - { - Structs::TargetInfo::Type outputInfo; - outputInfo.identifier = static_cast(i + 1); - outputInfo.name = chip::CharSpan::fromCharString("exampleName"); - list.push_back(outputInfo); - } - return list; + // NOTE: the ids for each target start at 1 so that we can reserve 0 as "no current target" + return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { + int maximumVectorSize = 2; + for (int i = 0; i < maximumVectorSize; ++i) + { + Structs::TargetInfo::Type outputInfo; + outputInfo.identifier = static_cast(i + 1); + outputInfo.name = chip::CharSpan::fromCharString("exampleName"); + ReturnErrorOnFailure(encoder.Encode(outputInfo)); + } + return CHIP_NO_ERROR; + }); } uint8_t TargetNavigatorManager::HandleGetCurrentTarget() @@ -41,12 +42,12 @@ uint8_t TargetNavigatorManager::HandleGetCurrentTarget() return 0; } -Commands::NavigateTargetResponse::Type TargetNavigatorManager::HandleNavigateTarget(const uint64_t & target, - const chip::CharSpan & data) +void TargetNavigatorManager::HandleNavigateTarget(CommandResponseHelper & helper, + const uint64_t & target, const CharSpan & data) { // TODO: Insert code here Commands::NavigateTargetResponse::Type response; response.data = chip::CharSpan::fromCharString("data response"); response.status = chip::app::Clusters::TargetNavigator::StatusEnum::kSuccess; - return response; + helper.Success(response); } diff --git a/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.h b/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.h index 7da10ea51448f5..b09b2775adbe91 100644 --- a/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.h +++ b/examples/tv-app/android/include/target-navigator/TargetNavigatorManager.h @@ -19,11 +19,18 @@ #include -class TargetNavigatorManager : public chip::app::Clusters::TargetNavigator::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using TargetNavigatorDelegate = chip::app::Clusters::TargetNavigator::Delegate; +using TargetInfoType = chip::app::Clusters::TargetNavigator::Structs::TargetInfo::Type; +using NavigateTargetResponseType = chip::app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type; + +class TargetNavigatorManager : public TargetNavigatorDelegate { public: - std::list HandleGetTargetList() override; + CHIP_ERROR HandleGetTargetList(AttributeValueEncoder & aEncoder) override; uint8_t HandleGetCurrentTarget() override; - chip::app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type - HandleNavigateTarget(const uint64_t & target, const chip::CharSpan & data) override; + void HandleNavigateTarget(CommandResponseHelper & responser, const uint64_t & target, + const CharSpan & data) override; }; diff --git a/examples/tv-app/android/java/ChannelManager.cpp b/examples/tv-app/android/java/ChannelManager.cpp index fa4969e489b2c8..cda334cb0022a9 100644 --- a/examples/tv-app/android/java/ChannelManager.cpp +++ b/examples/tv-app/android/java/ChannelManager.cpp @@ -25,6 +25,7 @@ #include using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters::Channel; /** @brief Channel Cluster Init @@ -50,7 +51,7 @@ void ChannelManager::NewManager(jint endpoint, jobject manager) chip::app::Clusters::Channel::SetDefaultDelegate(static_cast(endpoint), mgr); } -CHIP_ERROR ChannelManager::HandleGetChannelList(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder) { CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -125,7 +126,7 @@ CHIP_ERROR ChannelManager::HandleGetChannelList(chip::app::AttributeValueEncoder return err; } -CHIP_ERROR ChannelManager::HandleGetLineup(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder) { chip::app::Clusters::Channel::Structs::LineupInfo::Type lineupInfo; CHIP_ERROR err = CHIP_NO_ERROR; @@ -180,7 +181,7 @@ CHIP_ERROR ChannelManager::HandleGetLineup(chip::app::AttributeValueEncoder & aE return err; } -CHIP_ERROR ChannelManager::HandleGetCurrentChannel(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) { chip::app::Clusters::Channel::Structs::ChannelInfo::Type channelInfo; CHIP_ERROR err = CHIP_NO_ERROR; @@ -238,14 +239,12 @@ CHIP_ERROR ChannelManager::HandleGetCurrentChannel(chip::app::AttributeValueEnco return err; } -void ChannelManager::HandleChangeChannel( - const chip::CharSpan & match, - chip::app::CommandResponseHelper & responser) +void ChannelManager::HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) { std::string name(match.data(), match.size()); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - Commands::ChangeChannelResponse::Type response; + ChangeChannelResponseType response; response.channelMatch.majorNumber = 0; response.channelMatch.minorNumber = 0; @@ -303,7 +302,7 @@ void ChannelManager::HandleChangeChannel( jint jminorNum = env->GetIntField(channelObject, minorNumField); response.channelMatch.minorNumber = static_cast(jminorNum); - responser.Success(response); + helper.Success(response); } exit: diff --git a/examples/tv-app/android/java/ChannelManager.h b/examples/tv-app/android/java/ChannelManager.h index e898c56c7e5093..e7fb8e3411b7f8 100644 --- a/examples/tv-app/android/java/ChannelManager.h +++ b/examples/tv-app/android/java/ChannelManager.h @@ -20,19 +20,23 @@ #include #include -class ChannelManager : public chip::app::Clusters::Channel::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using ChannelDelegate = chip::app::Clusters::Channel::Delegate; +using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; + +class ChannelManager : public ChannelDelegate { public: static void NewManager(jint endpoint, jobject manager); void InitializeWithObjects(jobject managerObject); - virtual CHIP_ERROR HandleGetChannelList(chip::app::AttributeValueEncoder & aEncoder) override; - virtual CHIP_ERROR HandleGetLineup(chip::app::AttributeValueEncoder & aEncoder) override; - virtual CHIP_ERROR HandleGetCurrentChannel(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetChannelList(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetLineup(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) override; - virtual void HandleChangeChannel( - const chip::CharSpan & match, - chip::app::CommandResponseHelper & responser) override; + void HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) override; bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) override; bool HandleSkipChannel(const uint16_t & count) override; diff --git a/examples/tv-app/android/java/ContentLauncherManager.cpp b/examples/tv-app/android/java/ContentLauncherManager.cpp index e5fa67e9d6916b..8a79df7ea32ffb 100644 --- a/examples/tv-app/android/java/ContentLauncherManager.cpp +++ b/examples/tv-app/android/java/ContentLauncherManager.cpp @@ -40,12 +40,12 @@ void ContentLauncherManager::NewManager(jint endpoint, jobject manager) ChipLogProgress(Zcl, "TV Android App: ContentLauncher::SetDefaultDelegate"); ContentLauncherManager * mgr = new ContentLauncherManager(); mgr->InitializeWithObjects(manager); - chip::app::Clusters::ContentLauncher::SetDelegate(static_cast(endpoint), mgr); + chip::app::Clusters::ContentLauncher::SetDefaultDelegate(static_cast(endpoint), mgr); } -void ContentLauncherManager::HandleLaunchContent( - const std::list & parameterList, bool autoplay, const chip::CharSpan & data, - chip::app::CommandResponseHelper & responser) +void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper & helper, + const std::list & parameterList, bool autoplay, + const chip::CharSpan & data) { Commands::LaunchResponse::Type response; CHIP_ERROR err = CHIP_NO_ERROR; @@ -87,7 +87,7 @@ void ContentLauncherManager::HandleLaunchContent( response.status = static_cast(status); response.data = dataStr.charSpan(); - err = responser.Success(response); + err = helper.Success(response); } exit: @@ -97,10 +97,9 @@ void ContentLauncherManager::HandleLaunchContent( } } -void ContentLauncherManager::HandleLaunchUrl( - const chip::CharSpan & contentUrl, const chip::CharSpan & displayString, - const std::list & brandingInformation, - chip::app::CommandResponseHelper & responser) +void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelper & helper, const chip::CharSpan & contentUrl, + const chip::CharSpan & displayString, + const std::list & brandingInformation) { Commands::LaunchResponse::Type response; CHIP_ERROR err = CHIP_NO_ERROR; @@ -143,7 +142,7 @@ void ContentLauncherManager::HandleLaunchUrl( response.status = static_cast(status); response.data = dataStr.charSpan(); - err = responser.Success(response); + err = helper.Success(response); } exit: @@ -153,7 +152,7 @@ void ContentLauncherManager::HandleLaunchUrl( } } -CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) { CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); diff --git a/examples/tv-app/android/java/ContentLauncherManager.h b/examples/tv-app/android/java/ContentLauncherManager.h index 22d4a099f58144..2c942e1b2911b0 100644 --- a/examples/tv-app/android/java/ContentLauncherManager.h +++ b/examples/tv-app/android/java/ContentLauncherManager.h @@ -26,21 +26,23 @@ #include #include -class ContentLauncherManager : public chip::app::Clusters::ContentLauncher::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; + +class ContentLauncherManager : public ContentLauncherDelegate { public: static void NewManager(jint endpoint, jobject manager); void InitializeWithObjects(jobject managerObject); - void - HandleLaunchContent(const std::list & parameterList, bool autoplay, const chip::CharSpan & data, - chip::app::CommandResponseHelper & - responser) override; - void HandleLaunchUrl(const chip::CharSpan & contentUrl, const chip::CharSpan & displayString, - const std::list & brandingInformation, - chip::app::CommandResponseHelper & - responser) override; - CHIP_ERROR HandleGetAcceptHeaderList(chip::app::AttributeValueEncoder & aEncoder) override; + void HandleLaunchContent(CommandResponseHelper & helper, const std::list & parameterList, + bool autoplay, const CharSpan & data) override; + void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, + const CharSpan & displayString, const std::list & brandingInformation) override; + CHIP_ERROR HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) override; uint32_t HandleGetSupportedStreamingProtocols() override; private: diff --git a/examples/tv-app/android/java/KeypadInputManager.cpp b/examples/tv-app/android/java/KeypadInputManager.cpp index dbe9db273bb392..18492edad71084 100644 --- a/examples/tv-app/android/java/KeypadInputManager.cpp +++ b/examples/tv-app/android/java/KeypadInputManager.cpp @@ -39,7 +39,7 @@ void KeypadInputManager::NewManager(jint endpoint, jobject manager) chip::app::Clusters::KeypadInput::SetDefaultDelegate(static_cast(endpoint), mgr); } -Commands::SendKeyResponse::Type KeypadInputManager::HandleSendKey(const CecKeyCode & keyCode) +void KeypadInputManager::HandleSendKey(CommandResponseHelper & helper, const CecKeyCode & keyCode) { Commands::SendKeyResponse::Type response; @@ -65,7 +65,7 @@ Commands::SendKeyResponse::Type KeypadInputManager::HandleSendKey(const CecKeyCo { response.status = static_cast(ret); } - return response; + helper.Success(response); } void KeypadInputManager::InitializeWithObjects(jobject managerObject) diff --git a/examples/tv-app/android/java/KeypadInputManager.h b/examples/tv-app/android/java/KeypadInputManager.h index a623a5e335e46c..416c878699b70c 100644 --- a/examples/tv-app/android/java/KeypadInputManager.h +++ b/examples/tv-app/android/java/KeypadInputManager.h @@ -21,14 +21,18 @@ #include #include -class KeypadInputManager : public chip::app::Clusters::KeypadInput::Delegate +using chip::app::CommandResponseHelper; +using KeypadInputDelegate = chip::app::Clusters::KeypadInput::Delegate; +using SendKeyResponseType = chip::app::Clusters::KeypadInput::Commands::SendKeyResponse::Type; + +class KeypadInputManager : public KeypadInputDelegate { public: static void NewManager(jint endpoint, jobject manager); void InitializeWithObjects(jobject managerObject); - chip::app::Clusters::KeypadInput::Commands::SendKeyResponse::Type - HandleSendKey(const chip::app::Clusters::KeypadInput::CecKeyCode & keyCode) override; + void HandleSendKey(CommandResponseHelper & helper, + const chip::app::Clusters::KeypadInput::CecKeyCode & keyCode) override; private: jobject mKeypadInputManagerObject = nullptr; diff --git a/examples/tv-app/android/java/MediaPlaybackManager.cpp b/examples/tv-app/android/java/MediaPlaybackManager.cpp index 02e6707bdf2628..a4201452d0e578 100644 --- a/examples/tv-app/android/java/MediaPlaybackManager.cpp +++ b/examples/tv-app/android/java/MediaPlaybackManager.cpp @@ -27,6 +27,7 @@ #include "MediaPlaybackManager.h" using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters::MediaPlayback; /** @brief Media PlayBack Cluster Init @@ -84,59 +85,62 @@ uint64_t MediaPlaybackManager::HandleGetSeekRangeEnd() return HandleMediaRequestGetAttribute(MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandlePlay() +void MediaPlaybackManager::HandlePlay(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PLAY, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PLAY, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandlePause() +void MediaPlaybackManager::HandlePause(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PAUSE, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PAUSE, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleStop() +void MediaPlaybackManager::HandleStop(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_STOP, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_STOP, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleFastForward() +void MediaPlaybackManager::HandleFastForward(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_FAST_FORWARD, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_FAST_FORWARD, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandlePrevious() +void MediaPlaybackManager::HandlePrevious(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PREVIOUS, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PREVIOUS, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleRewind() +void MediaPlaybackManager::HandleRewind(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_REWIND, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_REWIND, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleSkipBackward(const uint64_t & deltaPositionMilliseconds) +void MediaPlaybackManager::HandleSkipBackward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_SKIP_BACKWARD, deltaPositionMilliseconds); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_SKIP_BACKWARD, deltaPositionMilliseconds)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleSkipForward(const uint64_t & deltaPositionMilliseconds) +void MediaPlaybackManager::HandleSkipForward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_SKIP_FORWARD, deltaPositionMilliseconds); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_SKIP_FORWARD, deltaPositionMilliseconds)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleSeekRequest(const uint64_t & positionMilliseconds) +void MediaPlaybackManager::HandleSeekRequest(CommandResponseHelper & helper, + const uint64_t & positionMilliseconds) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_SEEK, positionMilliseconds); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_SEEK, positionMilliseconds)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleNext() +void MediaPlaybackManager::HandleNext(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_NEXT, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_NEXT, 0)); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleStartOverRequest() +void MediaPlaybackManager::HandleStartOverRequest(CommandResponseHelper & helper) { - return HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_START_OVER, 0); + helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_START_OVER, 0)); } void MediaPlaybackManager::InitializeWithObjects(jobject managerObject) @@ -250,7 +254,7 @@ Commands::PlaybackResponse::Type MediaPlaybackManager::HandleMediaRequest(MediaP return response; } -Structs::PlaybackPosition::Type MediaPlaybackManager::HandleGetSampledPosition() +CHIP_ERROR MediaPlaybackManager::HandleGetSampledPosition(AttributeValueEncoder & aEncoder) { Structs::PlaybackPosition::Type response; response.updatedAt = 0; @@ -289,5 +293,5 @@ Structs::PlaybackPosition::Type MediaPlaybackManager::HandleGetSampledPosition() ChipLogError(Zcl, "MediaPlaybackManager::GetAttribute status error: %s", err.AsString()); } - return response; + return aEncoder.Encode(response); } diff --git a/examples/tv-app/android/java/MediaPlaybackManager.h b/examples/tv-app/android/java/MediaPlaybackManager.h index a9479011294c26..5e255aa7aa8f4f 100644 --- a/examples/tv-app/android/java/MediaPlaybackManager.h +++ b/examples/tv-app/android/java/MediaPlaybackManager.h @@ -48,7 +48,12 @@ enum MediaPlaybackRequest : uint8_t MEDIA_PLAYBACK_REQUEST_SEEK = 10, }; -class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using MediaPlaybackDelegate = chip::app::Clusters::MediaPlayback::Delegate; +using PlaybackResponseType = chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type; + +class MediaPlaybackManager : public MediaPlaybackDelegate { public: static void NewManager(jint endpoint, jobject manager); @@ -57,25 +62,24 @@ class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate chip::app::Clusters::MediaPlayback::PlaybackStateEnum HandleGetCurrentState() override; uint64_t HandleGetStartTime() override; uint64_t HandleGetDuration() override; - chip::app::Clusters::MediaPlayback::Structs::PlaybackPosition::Type HandleGetSampledPosition() override; + CHIP_ERROR HandleGetSampledPosition(AttributeValueEncoder & aEncoder) override; float HandleGetPlaybackSpeed() override; uint64_t HandleGetSeekRangeStart() override; uint64_t HandleGetSeekRangeEnd() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandlePlay() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandlePause() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleStop() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleFastForward() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandlePrevious() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleRewind() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type - HandleSkipBackward(const uint64_t & deltaPositionMilliseconds) override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type - HandleSkipForward(const uint64_t & deltaPositionMilliseconds) override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type - HandleSeekRequest(const uint64_t & positionMilliseconds) override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleNext() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleStartOverRequest() override; + void HandlePlay(CommandResponseHelper & helper) override; + void HandlePause(CommandResponseHelper & helper) override; + void HandleStop(CommandResponseHelper & helper) override; + void HandleFastForward(CommandResponseHelper & helper) override; + void HandlePrevious(CommandResponseHelper & helper) override; + void HandleRewind(CommandResponseHelper & helper) override; + void HandleSkipBackward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) override; + void HandleSkipForward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) override; + void HandleSeekRequest(CommandResponseHelper & helper, const uint64_t & positionMilliseconds) override; + void HandleNext(CommandResponseHelper & helper) override; + void HandleStartOverRequest(CommandResponseHelper & helper) override; private: jobject mMediaPlaybackManagerObject = nullptr; diff --git a/examples/tv-app/linux/AppImpl.cpp b/examples/tv-app/linux/AppImpl.cpp index 088bf88075054b..00ad81b37086e2 100644 --- a/examples/tv-app/linux/AppImpl.cpp +++ b/examples/tv-app/linux/AppImpl.cpp @@ -16,7 +16,7 @@ */ /** - * @file Contains shell commands for a commissionee (eg. end device) related to commissioning. + * @file Contains Implementation of the ContentApp and the ContentAppPlatform. */ #include "AppImpl.h" @@ -43,9 +43,9 @@ #include using namespace chip; -using namespace chip::AppPlatform; #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; namespace chip { namespace AppPlatform { @@ -147,117 +147,54 @@ DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs), // 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); -} +ContentAppFactoryImpl::ContentAppFactoryImpl() {} -uint32_t AccountLoginImpl::GetSetupPIN(const char * tempAccountId) +uint16_t ContentAppFactoryImpl::GetPlatformCatalogVendorId() { - ChipLogProgress(DeviceLayer, "AccountLogin: GetSetupPIN TempAccountId=\"%s\" returning setuppin=%d", tempAccountId, mSetupPIN); - return mSetupPIN; + return kCatalogVendorId; } -chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type -ApplicationLauncherImpl::LaunchApp(ApplicationLauncherApplication application, std::string data) +CHIP_ERROR ContentAppFactoryImpl::LookupCatalogVendorApp(uint16_t vendorId, uint16_t productId, CatalogVendorApp * destinationApp) { - 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()); - - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type response; - response.data = chip::CharSpan::fromCharString("data"); - response.status = chip::app::Clusters::ApplicationLauncher::StatusEnum::kSuccess; - - return response; + std::string appId = BuildAppId(vendorId); + destinationApp->catalogVendorId = GetPlatformCatalogVendorId(); + Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), appId.c_str()); + return CHIP_NO_ERROR; } -chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type -ContentLauncherImpl::LaunchContent(std::list parameterList, bool autoplay, std::string data) +CHIP_ERROR ContentAppFactoryImpl::ConvertToPlatformCatalogVendorApp(CatalogVendorApp sourceApp, CatalogVendorApp * destinationApp) { - ChipLogProgress(DeviceLayer, "ContentLauncherImpl: LaunchContent autoplay=%d data=\"%s\"", autoplay ? 1 : 0, data.c_str()); - - chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type response; - response.data = chip::CharSpan::fromCharString("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++) + destinationApp->catalogVendorId = GetPlatformCatalogVendorId(); + std::string appId(sourceApp.applicationId); + if (appId == "applicationId") { - ContentAppImpl app = mContentApps[i]; - if (app.GetApplicationBasic()->GetVendorId() == vendorId) - { - AppPlatform::GetInstance().AddContentApp(&mContentApps[i], &contentAppEndpoint, DEVICE_TYPE_CONTENT_APP); - return &mContentApps[i]; - } + // test case passes "applicationId", map this to our test suite app + Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "1111"); } - ChipLogProgress(DeviceLayer, "LoadContentAppByVendorId() - vendor %d not found ", vendorId); - - return nullptr; + else + { + // for now, just return the applicationId passed in + Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), sourceApp.applicationId); + } + return CHIP_NO_ERROR; } -ContentApp * ContentAppFactoryImpl::LoadContentAppByAppId(ApplicationLauncherApplication application) +ContentApp * ContentAppFactoryImpl::LoadContentApp(CatalogVendorApp vendorApp) { - 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()); + ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: LoadContentAppByAppId catalogVendorId=%d applicationId=%s ", + vendorApp.catalogVendorId, vendorApp.applicationId); - for (unsigned int i = 0; i < APP_LIBRARY_SIZE; i++) + for (auto & app : mContentApps) { - ContentAppImpl app = mContentApps[i]; - ChipLogProgress(DeviceLayer, " Looking next=%s ", app.GetApplicationBasic()->GetApplicationName()); - if (strcmp(app.GetApplicationBasic()->GetApplicationName(), appId.c_str()) == 0) + ChipLogProgress(DeviceLayer, " Looking next=%s ", app.GetApplicationBasicDelegate()->GetCatalogVendorApp()->applicationId); + if (app.GetApplicationBasicDelegate()->GetCatalogVendorApp()->Matches(vendorApp)) { - AppPlatform::GetInstance().AddContentApp(&mContentApps[i], &contentAppEndpoint, DEVICE_TYPE_CONTENT_APP); - return &mContentApps[i]; + ContentAppPlatform::GetInstance().AddContentApp(&app, &contentAppEndpoint, DEVICE_TYPE_CONTENT_APP); + return &app; } } - ChipLogProgress(DeviceLayer, "LoadContentAppByAppId() - app id %s not found ", appId.c_str()); + ChipLogProgress(DeviceLayer, "LoadContentAppByAppId NOT FOUND catalogVendorId=%d applicationId=%s ", vendorApp.catalogVendorId, + vendorApp.applicationId); return nullptr; } diff --git a/examples/tv-app/linux/AppImpl.h b/examples/tv-app/linux/AppImpl.h index 81150ef0d19be6..b044f900c1f226 100644 --- a/examples/tv-app/linux/AppImpl.h +++ b/examples/tv-app/linux/AppImpl.h @@ -23,148 +23,81 @@ #pragma once #include -#include -#include +#include +#include #include #include #include #include +#include "include/account-login/AccountLoginManager.h" +#include "include/application-basic/ApplicationBasicManager.h" +#include "include/application-launcher/ApplicationLauncherManager.h" +#include "include/channel/ChannelManager.h" +#include "include/content-launcher/ContentLauncherManager.h" +#include "include/keypad-input/KeypadInputManager.h" +#include "include/media-playback/MediaPlaybackManager.h" +#include "include/target-navigator/TargetNavigatorManager.h" +#include +#include +#include +#include +#include +#include +#include +#include + #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED namespace chip { namespace AppPlatform { -class DLL_EXPORT ApplicationBasicImpl : public ApplicationBasic -{ -public: - virtual ~ApplicationBasicImpl() {} - - inline const char * GetVendorName() override { return mVendorName; }; - inline uint16_t GetVendorId() override { return mVendorId; }; - inline const char * GetApplicationName() override { return mApplicationName; }; - inline uint16_t GetProductId() override { return mProductId; }; - inline app::Clusters::ApplicationBasic::ApplicationStatusEnum GetApplicationStatus() override { return mApplicationStatus; }; - inline const char * GetApplicationVersion() override { return mApplicationVersion; }; - - inline void SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum applicationStatus) override - { - mApplicationStatus = applicationStatus; - }; - - void SetVendorName(const char * szVendorName); - inline void SetVendorId(uint16_t vendorId) { mVendorId = vendorId; }; - void SetApplicationName(const char * szApplicationName); - inline void SetProductId(uint16_t productId) { mProductId = productId; }; - void SetApplicationVersion(const char * szApplicationVersion); - -protected: - static const int kVendorNameSize = 32; - static const int kApplicationNameSize = 32; - static const int kApplicationVersionSize = 32; - - char mVendorName[kVendorNameSize]; - uint16_t mVendorId; - char mApplicationName[kApplicationNameSize]; - uint16_t mProductId; - app::Clusters::ApplicationBasic::ApplicationStatusEnum mApplicationStatus = - app::Clusters::ApplicationBasic::ApplicationStatusEnum::kStopped; - char mApplicationVersion[kApplicationVersionSize]; -}; - -class DLL_EXPORT AccountLoginImpl : public AccountLogin -{ -public: - virtual ~AccountLoginImpl() {} - - inline void SetSetupPIN(uint32_t setupPIN) override { mSetupPIN = setupPIN; }; - uint32_t GetSetupPIN(const char * tempAccountId) override; - bool Login(const char * tempAccountId, uint32_t setupPin) override; - -protected: - uint32_t mSetupPIN = 0; -}; - -class DLL_EXPORT KeypadInputImpl : public KeypadInput -{ -public: - virtual ~KeypadInputImpl() {} - -protected: -}; - -class DLL_EXPORT ApplicationLauncherImpl : public ApplicationLauncher -{ -public: - virtual ~ApplicationLauncherImpl() {} - - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type LaunchApp(ApplicationLauncherApplication application, - std::string data) override; - -protected: -}; - -class DLL_EXPORT ContentLauncherImpl : public ContentLauncher -{ -public: - virtual ~ContentLauncherImpl() {} - - chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type LaunchContent(std::list parameterList, - bool autoplay, std::string data) override; - -protected: -}; - -class DLL_EXPORT MediaPlaybackImpl : public MediaPlayback -{ -public: - virtual ~MediaPlaybackImpl() {} - -protected: -}; - -class DLL_EXPORT TargetNavigatorImpl : public TargetNavigator -{ -public: - TargetNavigatorImpl() : TargetNavigator{ { "home", "search", "info", "guide", "menu" }, 0 } {}; - virtual ~TargetNavigatorImpl() {} +using AccountLoginDelegate = app::Clusters::AccountLogin::Delegate; +using ApplicationBasicDelegate = app::Clusters::ApplicationBasic::Delegate; +using ApplicationLauncherDelegate = app::Clusters::ApplicationLauncher::Delegate; +using ChannelDelegate = app::Clusters::Channel::Delegate; +using ContentLauncherDelegate = app::Clusters::ContentLauncher::Delegate; +using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; +using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; +using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; +using SupportedStreamingProtocol = app::Clusters::ContentLauncher::SupportedStreamingProtocol; -protected: -}; +static const int kCatalogVendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; -class DLL_EXPORT ChannelImpl : public Channel -{ -public: - virtual ~ChannelImpl() {} - -protected: -}; +// for this platform, appid is just vendor id +#define BuildAppId(vid) std::to_string(vid).c_str() class DLL_EXPORT ContentAppImpl : public ContentApp { public: ContentAppImpl(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId, - const char * szApplicationVersion); + const char * szApplicationVersion, const char * setupPIN) : + mApplicationBasicDelegate(kCatalogVendorId, BuildAppId(vendorId), szVendorName, vendorId, szApplicationName, productId, + szApplicationVersion), + mAccountLoginDelegate(setupPIN), mContentLauncherDelegate({ "image/*", "video/*" }, + to_underlying(SupportedStreamingProtocol::kDash) | + to_underlying(SupportedStreamingProtocol::kHls)), + mTargetNavigatorDelegate({ "home", "search", "info", "guide", "menu" }, 0){}; virtual ~ContentAppImpl() {} - inline ApplicationBasic * GetApplicationBasic() override { return &mApplicationBasic; }; - inline AccountLogin * GetAccountLogin() override { return &mAccountLogin; }; - inline KeypadInput * GetKeypadInput() override { return &mKeypadInput; }; - inline ApplicationLauncher * GetApplicationLauncher() override { return &mApplicationLauncher; }; - inline ContentLauncher * GetContentLauncher() override { return &mContentLauncher; }; - inline MediaPlayback * GetMediaPlayback() override { return &mMediaPlayback; }; - inline TargetNavigator * GetTargetNavigator() override { return &mTargetNavigator; }; - inline Channel * GetChannel() override { return &mChannel; }; + AccountLoginDelegate * GetAccountLoginDelegate() override { return &mAccountLoginDelegate; }; + ApplicationBasicDelegate * GetApplicationBasicDelegate() override { return &mApplicationBasicDelegate; }; + ApplicationLauncherDelegate * GetApplicationLauncherDelegate() override { return &mApplicationLauncherDelegate; }; + ChannelDelegate * GetChannelDelegate() override { return &mChannelDelegate; }; + ContentLauncherDelegate * GetContentLauncherDelegate() override { return &mContentLauncherDelegate; }; + KeypadInputDelegate * GetKeypadInputDelegate() override { return &mKeypadInputDelegate; }; + MediaPlaybackDelegate * GetMediaPlaybackDelegate() override { return &mMediaPlaybackDelegate; }; + TargetNavigatorDelegate * GetTargetNavigatorDelegate() override { return &mTargetNavigatorDelegate; }; protected: - ApplicationBasicImpl mApplicationBasic; - AccountLoginImpl mAccountLogin; - KeypadInputImpl mKeypadInput; - ApplicationLauncherImpl mApplicationLauncher; - ContentLauncherImpl mContentLauncher; - MediaPlaybackImpl mMediaPlayback; - TargetNavigatorImpl mTargetNavigator; - ChannelImpl mChannel; + ApplicationBasicManager mApplicationBasicDelegate; + AccountLoginManager mAccountLoginDelegate; + ApplicationLauncherManager mApplicationLauncherDelegate; + ChannelManager mChannelDelegate; + ContentLauncherManager mContentLauncherDelegate; + KeypadInputManager mKeypadInputDelegate; + MediaPlaybackManager mMediaPlaybackDelegate; + TargetNavigatorManager mTargetNavigatorDelegate; }; class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory @@ -174,14 +107,27 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory ContentAppFactoryImpl(); virtual ~ContentAppFactoryImpl() {} - ContentApp * LoadContentAppByVendorId(uint16_t vendorId); - ContentApp * LoadContentAppByAppId(ApplicationLauncherApplication application); + // Lookup CatalogVendor App for this client (vendor id/product id client) + // and then write it to destinationApp + // return error if not found + CHIP_ERROR LookupCatalogVendorApp(uint16_t vendorId, uint16_t productId, CatalogVendorApp * destinationApp) override; + + // Lookup ContentApp for this catalog id / app id and load it + ContentApp * LoadContentApp(CatalogVendorApp vendorApp) override; + + // Gets the catalog vendor ID used by this platform + uint16_t GetPlatformCatalogVendorId() override; + + // Converts application (any catalog) into the platform's catalog Vendor + // and then writes it to destinationApp + CHIP_ERROR ConvertToPlatformCatalogVendorApp(CatalogVendorApp sourceApp, CatalogVendorApp * destinationApp) override; protected: - ContentAppImpl mContentApps[APP_LIBRARY_SIZE] = { ContentAppImpl("Vendor1", 1, "App1", 11, "Version1"), - ContentAppImpl("Vendor2", 2222, "App2", 22, "Version2"), - ContentAppImpl("Vendor3", 9050, "App3", 22, "Version3"), - ContentAppImpl("TestSuiteVendor", 1111, "applicationId", 22, "v2") }; + ContentAppImpl mContentApps[APP_LIBRARY_SIZE] = { ContentAppImpl("Vendor1", 1, "App1", 11, "Version1", "34567890"), + ContentAppImpl("Vendor2", 2222, "App2", 22, "Version2", "34567890"), + ContentAppImpl("Vendor3", 9050, "App3", 22, "Version3", "20202021"), + ContentAppImpl("TestSuiteVendor", 1111, "applicationId", 22, "v2", + "20202021") }; }; } // namespace AppPlatform diff --git a/examples/tv-app/linux/AppPlatformShellCommands.cpp b/examples/tv-app/linux/AppPlatformShellCommands.cpp index 96acfed6270709..85343e893a750f 100644 --- a/examples/tv-app/linux/AppPlatformShellCommands.cpp +++ b/examples/tv-app/linux/AppPlatformShellCommands.cpp @@ -16,13 +16,12 @@ */ /** - * @file Contains shell commands for a commissionee (eg. end device) related to commissioning. + * @file Contains shell commands for a ContentApp relating to Content App platform of the Video Player. */ #include "AppPlatformShellCommands.h" #include "ControllerShellCommands.h" #include -#include #include #include #include @@ -33,8 +32,15 @@ #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + using namespace ::chip::Controller; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::app::Clusters; #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED @@ -58,24 +64,33 @@ static CHIP_ERROR pairApp(bool printHeader, size_t index) } else { - ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetLoadContentAppByVendorId(state->GetVendorId()); + ContentApp * app = ContentAppPlatform::GetInstance().LoadContentAppByClient(state->GetVendorId(), state->GetProductId()); if (app == nullptr) { streamer_printf(sout, "no app found for vendor id=%d \r\n", state->GetVendorId()); return CHIP_ERROR_BAD_REQUEST; } - if (app->GetAccountLogin() == nullptr) + if (app->GetAccountLoginDelegate() == nullptr) { streamer_printf(sout, "no AccountLogin cluster for app with vendor id=%d \r\n", state->GetVendorId()); return CHIP_ERROR_BAD_REQUEST; } char rotatingIdString[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = ""; - Encoding::BytesToUppercaseHexString(state->GetRotatingId(), chip::Dnssd::kMaxRotatingIdLen, rotatingIdString, + Encoding::BytesToUppercaseHexString(state->GetRotatingId(), state->GetRotatingIdLength(), rotatingIdString, sizeof(rotatingIdString)); - uint32_t pincode = app->GetAccountLogin()->GetSetupPIN(rotatingIdString); + CharSpan rotatingIdSpan = CharSpan(rotatingIdString, strlen(rotatingIdString)); + + static const size_t kSetupPinSize = 12; + char setupPin[kSetupPinSize]; + + app->GetAccountLoginDelegate()->GetSetupPin(setupPin, kSetupPinSize, rotatingIdSpan); + std::string pinString(setupPin); + + char * eptr; + uint32_t pincode = (uint32_t) strtol(pinString.c_str(), &eptr, 10); if (pincode == 0) { streamer_printf(sout, "udc no pin returned for vendor id=%d rotating ID=%s \r\n", state->GetVendorId(), @@ -91,11 +106,11 @@ static CHIP_ERROR pairApp(bool printHeader, size_t index) static CHIP_ERROR PrintAllCommands() { streamer_t * sout = streamer_get(); - streamer_printf(sout, " help Usage: app \r\n"); - streamer_printf(sout, " add Add app with given vendor ID [1, 2, 9050]. Usage: app add 9050\r\n"); - streamer_printf(sout, " remove Remove app with given vendor ID [1, 2, 9050]. Usage: app remove 9050\r\n"); + streamer_printf(sout, " help Usage: app \r\n"); + streamer_printf(sout, " add [] Add app with given vendor ID [1, 2, 9050]. Usage: app add 9050\r\n"); + streamer_printf(sout, " remove Remove app at given endpoint [6, 7, etc]. Usage: app remove 6\r\n"); streamer_printf(sout, - " setpin Set pincode for app with given vendor ID. Usage: app setpin 9050 34567890\r\n"); + " setpin Set pincode for app with given endpoint ID. Usage: app setpin 6 34567890\r\n"); streamer_printf(sout, " commission Commission given udc-entry using given pincode from corresponding app. Usage: " "app commission 0\r\n"); @@ -121,7 +136,12 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv) char * eptr; uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10); - chip::AppPlatform::AppPlatform::GetInstance().GetLoadContentAppByVendorId(vid); + uint16_t pid = 0; + if (argc >= 3) + { + pid = (uint16_t) strtol(argv[1], &eptr, 10); + } + ContentAppPlatform::GetInstance().LoadContentAppByClient(vid, pid); ChipLogProgress(DeviceLayer, "added app"); @@ -135,8 +155,14 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv) } char * eptr; - uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10); - chip::AppPlatform::AppPlatform::GetInstance().UnloadContentAppByVendorId(vid); + uint16_t endpoint = (uint16_t) strtol(argv[1], &eptr, 10); + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app == nullptr) + { + ChipLogProgress(DeviceLayer, "app not found"); + return CHIP_ERROR_BAD_REQUEST; + } + ContentAppPlatform::GetInstance().RemoveContentApp(app); ChipLogProgress(DeviceLayer, "removed app"); @@ -150,20 +176,20 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv) } char * eptr; - uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10); - uint32_t pincode = (uint32_t) strtol(argv[2], &eptr, 10); - ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetLoadContentAppByVendorId(vid); + uint16_t endpoint = (uint16_t) strtol(argv[1], &eptr, 10); + char * pincode = argv[2]; + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); if (app == nullptr) { - ChipLogProgress(DeviceLayer, "no app found for vendor id=%d ", vid); + ChipLogProgress(DeviceLayer, "app not found"); return CHIP_ERROR_BAD_REQUEST; } - if (app->GetAccountLogin() == nullptr) + if (app->GetAccountLoginDelegate() == nullptr) { - ChipLogProgress(DeviceLayer, "no AccountLogin cluster for app with vendor id=%d ", vid); + ChipLogProgress(DeviceLayer, "no AccountLogin cluster for app with endpoint id=%d ", endpoint); return CHIP_ERROR_BAD_REQUEST; } - app->GetAccountLogin()->SetSetupPIN(pincode); + app->GetAccountLoginDelegate()->SetSetupPin(pincode); ChipLogProgress(DeviceLayer, "set pin success"); diff --git a/examples/tv-app/linux/AppPlatformShellCommands.h b/examples/tv-app/linux/AppPlatformShellCommands.h index f3c8317e7c86b8..bee89009f17d16 100644 --- a/examples/tv-app/linux/AppPlatformShellCommands.h +++ b/examples/tv-app/linux/AppPlatformShellCommands.h @@ -17,7 +17,7 @@ */ /** - * @brief Registers shell commands for a commissionee (eg. end device) related to commissioning. + * @brief Contains shell commands for a ContentApp relating to Content App platform of the Video Player. */ #include diff --git a/examples/tv-app/linux/include/account-login/AccountLoginManager.cpp b/examples/tv-app/linux/include/account-login/AccountLoginManager.cpp index cabd7e77fb9fa0..edf79a5367ed91 100644 --- a/examples/tv-app/linux/include/account-login/AccountLoginManager.cpp +++ b/examples/tv-app/linux/include/account-login/AccountLoginManager.cpp @@ -23,15 +23,28 @@ using namespace std; using namespace chip::app::Clusters::AccountLogin; -bool AccountLoginManager::HandleLogin(const chip::CharSpan & tempAccountIdentifier, const chip::CharSpan & setupPin) +AccountLoginManager::AccountLoginManager(const char * setupPin) +{ + CopyString(mSetupPin, sizeof(mSetupPin), setupPin); +} + +bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, const CharSpan & setupPin) { string tempAccountIdentifierString(tempAccountIdentifier.data(), tempAccountIdentifier.size()); string setupPinString(setupPin.data(), setupPin.size()); ChipLogProgress(Zcl, "temporary account id: %s", tempAccountIdentifierString.c_str()); ChipLogProgress(Zcl, "setup pin %s", setupPinString.c_str()); - // TODO: Insert your code here to handle login request - return true; + if (strcmp(mSetupPin, setupPinString.c_str()) == 0) + { + ChipLogProgress(Zcl, "AccountLoginManager::HandleLogin success"); + return true; + } + else + { + ChipLogProgress(Zcl, "AccountLoginManager::HandleLogin failed expected pin %s", mSetupPin); + return false; + } } bool AccountLoginManager::HandleLogout() @@ -40,12 +53,14 @@ bool AccountLoginManager::HandleLogout() return true; } -Commands::GetSetupPINResponse::Type AccountLoginManager::HandleGetSetupPin(const chip::CharSpan & tempAccountIdentifier) +void AccountLoginManager::HandleGetSetupPin(CommandResponseHelper & helper, + const CharSpan & tempAccountIdentifier) { string tempAccountIdentifierString(tempAccountIdentifier.data(), tempAccountIdentifier.size()); - ChipLogProgress(Zcl, "temporary account id: %s", tempAccountIdentifierString.c_str()); - // TODO: Insert your code here to handle get setup pin - Commands::GetSetupPINResponse::Type response; - response.setupPIN = chip::CharSpan::fromCharString("tempPin123"); - return response; + + GetSetupPINResponse response; + ChipLogProgress(Zcl, "temporary account id: %s returning pin: %s", tempAccountIdentifierString.c_str(), mSetupPin); + + response.setupPIN = CharSpan::fromCharString(mSetupPin); + helper.Success(response); } diff --git a/examples/tv-app/linux/include/account-login/AccountLoginManager.h b/examples/tv-app/linux/include/account-login/AccountLoginManager.h index 68584ae6ec7bd5..86326f9440a610 100644 --- a/examples/tv-app/linux/include/account-login/AccountLoginManager.h +++ b/examples/tv-app/linux/include/account-login/AccountLoginManager.h @@ -22,11 +22,30 @@ #include -class AccountLoginManager : public chip::app::Clusters::AccountLogin::Delegate +using chip::CharSpan; +using chip::app::CommandResponseHelper; +using chip::Platform::CopyString; +using AccountLoginDelegate = chip::app::Clusters::AccountLogin::Delegate; +using GetSetupPINResponse = chip::app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Type; + +class AccountLoginManager : public AccountLoginDelegate { public: - bool HandleLogin(const chip::CharSpan & tempAccountIdentifierString, const chip::CharSpan & setupPinString) override; + AccountLoginManager() : AccountLoginManager("tempPin123"){}; + AccountLoginManager(const char * setupPin); + + inline void SetSetupPin(char * setupPin) override { CopyString(mSetupPin, sizeof(mSetupPin), setupPin); }; + + bool HandleLogin(const CharSpan & tempAccountIdentifierString, const CharSpan & setupPinString) override; bool HandleLogout() override; - chip::app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Type - HandleGetSetupPin(const chip::CharSpan & tempAccountIdentifierString) override; + void HandleGetSetupPin(CommandResponseHelper & helper, + const CharSpan & tempAccountIdentifierString) override; + inline void GetSetupPin(char * setupPin, size_t setupPinSize, const CharSpan & tempAccountIdentifierString) override + { + CopyString(setupPin, setupPinSize, mSetupPin); + }; + +protected: + static const size_t kSetupPinSize = 12; + char mSetupPin[kSetupPinSize]; }; diff --git a/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.cpp b/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.cpp index 7b1019815fd199..88e08934dfaa76 100644 --- a/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.cpp +++ b/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.cpp @@ -19,47 +19,42 @@ #include "ApplicationBasicManager.h" using namespace std; +using namespace chip::app; using namespace chip::app::Clusters::ApplicationBasic; -chip::CharSpan ApplicationBasicManager::HandleGetVendorName() +CHIP_ERROR ApplicationBasicManager::HandleGetVendorName(AttributeValueEncoder & aEncoder) { - return chip::CharSpan::fromCharString("exampleVendorName1"); + return aEncoder.Encode(CharSpan::fromCharString(mVendorName)); } uint16_t ApplicationBasicManager::HandleGetVendorId() { - return 1; + return mVendorId; } -chip::CharSpan ApplicationBasicManager::HandleGetApplicationName() +CHIP_ERROR ApplicationBasicManager::HandleGetApplicationName(AttributeValueEncoder & aEncoder) { - return chip::CharSpan::fromCharString("exampleName1"); + return aEncoder.Encode(CharSpan::fromCharString(mApplicationName)); } uint16_t ApplicationBasicManager::HandleGetProductId() { - return 1; + return mProductId; } -chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type ApplicationBasicManager::HandleGetApplication() +CHIP_ERROR ApplicationBasicManager::HandleGetApplicationVersion(AttributeValueEncoder & aEncoder) { - chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type application; - application.catalogVendorId = 123; - application.applicationId = chip::CharSpan::fromCharString("applicationId"); - return application; + return aEncoder.Encode(CharSpan::fromCharString(mApplicationVersion)); } -ApplicationStatusEnum ApplicationBasicManager::HandleGetStatus() +CHIP_ERROR ApplicationBasicManager::HandleGetAllowedVendorList(AttributeValueEncoder & aEncoder) { - return ApplicationStatusEnum::kStopped; -} - -chip::CharSpan ApplicationBasicManager::HandleGetApplicationVersion() -{ - return chip::CharSpan::fromCharString("exampleVersion"); -} - -std::list ApplicationBasicManager::HandleGetAllowedVendorList() -{ - return { 123, 456 }; + std::list allowedVendorList = { mVendorId, 456 }; + return aEncoder.EncodeList([allowedVendorList](const auto & encoder) -> CHIP_ERROR { + for (const auto & allowedVendor : allowedVendorList) + { + ReturnErrorOnFailure(encoder.Encode(allowedVendor)); + } + return CHIP_NO_ERROR; + }); } diff --git a/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.h b/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.h index ec8904fa581ff8..bc7918fa957b06 100644 --- a/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.h +++ b/examples/tv-app/linux/include/application-basic/ApplicationBasicManager.h @@ -20,15 +20,46 @@ #include -class ApplicationBasicManager : public chip::app::Clusters::ApplicationBasic::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::Platform::CopyString; +using ApplicationBasicDelegate = chip::app::Clusters::ApplicationBasic::Delegate; + +class ApplicationBasicManager : public ApplicationBasicDelegate { public: - chip::CharSpan HandleGetVendorName() override; + ApplicationBasicManager() : + ApplicationBasicManager(123, "applicationId", "exampleVendorName1", 1, "exampleName1", 1, "exampleVersion"){}; + ApplicationBasicManager(uint16_t szCatalogVendorId, const char * szApplicationId, const char * szVendorName, uint16_t vendorId, + const char * szApplicationName, uint16_t productId, const char * szApplicationVersion) : + ApplicationBasicDelegate(szCatalogVendorId, szApplicationId) + { + + ChipLogProgress(DeviceLayer, "ApplicationBasic[%s]: Application Name=\"%s\"", szApplicationId, szApplicationName); + + CopyString(mApplicationName, sizeof(mApplicationName), szApplicationName); + CopyString(mVendorName, sizeof(mVendorName), szVendorName); + mVendorId = vendorId; + CopyString(mApplicationVersion, sizeof(mApplicationVersion), szApplicationVersion); + mProductId = productId; + }; + virtual ~ApplicationBasicManager(){}; + + CHIP_ERROR HandleGetVendorName(AttributeValueEncoder & aEncoder) override; uint16_t HandleGetVendorId() override; - chip::CharSpan HandleGetApplicationName() override; + CHIP_ERROR HandleGetApplicationName(AttributeValueEncoder & aEncoder) override; uint16_t HandleGetProductId() override; - chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type HandleGetApplication() override; - chip::app::Clusters::ApplicationBasic::ApplicationStatusEnum HandleGetStatus() override; - chip::CharSpan HandleGetApplicationVersion() override; - std::list HandleGetAllowedVendorList() override; + CHIP_ERROR HandleGetApplicationVersion(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAllowedVendorList(AttributeValueEncoder & aEncoder) override; + +protected: + static const int kVendorNameSize = 32; + static const int kApplicationNameSize = 32; + static const int kApplicationVersionSize = 32; + + char mVendorName[kVendorNameSize]; + uint16_t mVendorId; + char mApplicationName[kApplicationNameSize]; + uint16_t mProductId; + char mApplicationVersion[kApplicationVersionSize]; }; diff --git a/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp index a4fd66fab1a1ee..333160e12cedf4 100644 --- a/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp +++ b/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp @@ -19,49 +19,54 @@ #include "ApplicationLauncherManager.h" using namespace std; +using namespace chip::app; +using namespace chip::app::Clusters; using namespace chip::app::Clusters::ApplicationLauncher; -Structs::ApplicationEP::Type ApplicationLauncherManager::HandleGetCurrentApp() +CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncoder & aEncoder) { - Structs::ApplicationEP::Type currentApp; - currentApp.application.catalogVendorId = 123; - currentApp.application.applicationId = chip::CharSpan::fromCharString("applicationId"); - currentApp.endpoint = chip::CharSpan::fromCharString("endpointId"); - return currentApp; + std::list catalogList = { 123, 456 }; + return aEncoder.EncodeList([catalogList](const auto & encoder) -> CHIP_ERROR { + for (const auto & catalog : catalogList) + { + ReturnErrorOnFailure(encoder.Encode(catalog)); + } + return CHIP_NO_ERROR; + }); } -std::list ApplicationLauncherManager::HandleGetCatalogList() +void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper & helper, const CharSpan & data, + const ApplicationLauncherApplicationType & application) { - return { 123, 456 }; -} + ChipLogError(Zcl, "ApplicationLauncherManager::HandleLaunchApp"); -Commands::LauncherResponse::Type ApplicationLauncherManager::HandleLaunchApp( - const chip::CharSpan & data, - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) -{ // TODO: Insert code here - Commands::LauncherResponse::Type response; - response.data = chip::CharSpan::fromCharString("data"); + LauncherResponseType response; + response.data = CharSpan::fromCharString("data"); response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::LauncherResponse::Type ApplicationLauncherManager::HandleStopApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) +void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) { + ChipLogError(Zcl, "ApplicationLauncherManager::HandleStopApp"); + // TODO: Insert code here - Commands::LauncherResponse::Type response; - response.data = chip::CharSpan::fromCharString("data"); + LauncherResponseType response; + response.data = CharSpan::fromCharString("data"); response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::LauncherResponse::Type ApplicationLauncherManager::HandleHideApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) +void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) { + ChipLogError(Zcl, "ApplicationLauncherManager::HandleHideApp"); + // TODO: Insert code here - Commands::LauncherResponse::Type response; - response.data = chip::CharSpan::fromCharString("data"); + LauncherResponseType response; + response.data = CharSpan::fromCharString("data"); response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } diff --git a/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.h b/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.h index 14ed65ce00b52d..e3778d3e8fb05a 100644 --- a/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.h +++ b/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.h @@ -18,20 +18,28 @@ #pragma once -#include +#include #include -class ApplicationLauncherManager : public chip::app::Clusters::ApplicationLauncher::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using ApplicationLauncherDelegate = chip::app::Clusters::ApplicationLauncher::Delegate; +using ApplicationLauncherApplicationType = chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type; +using LauncherResponseType = chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type; + +class ApplicationLauncherManager : public ApplicationLauncherDelegate { public: - chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEP::Type HandleGetCurrentApp() override; - std::list HandleGetCatalogList() override; + ApplicationLauncherManager() : ApplicationLauncherDelegate(){}; + ApplicationLauncherManager(bool featureMapContentPlatform) : ApplicationLauncherDelegate(featureMapContentPlatform){}; + + CHIP_ERROR HandleGetCatalogList(AttributeValueEncoder & aEncoder) override; - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type HandleLaunchApp( - const chip::CharSpan & data, - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) override; - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type HandleStopApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) override; - chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type HandleHideApp( - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) override; + void HandleLaunchApp(CommandResponseHelper & helper, const CharSpan & data, + const ApplicationLauncherApplicationType & application) override; + void HandleStopApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) override; + void HandleHideApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) override; }; diff --git a/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp b/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp index 5b94bff20b1a76..c0d806994549ec 100644 --- a/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp +++ b/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp @@ -19,6 +19,7 @@ #include "AudioOutputManager.h" using namespace std; +using namespace chip::app; using namespace chip::app::Clusters::AudioOutput; uint8_t AudioOutputManager::HandleGetCurrentOutput() @@ -26,21 +27,21 @@ uint8_t AudioOutputManager::HandleGetCurrentOutput() return 0; } -std::list AudioOutputManager::HandleGetOutputList() +CHIP_ERROR AudioOutputManager::HandleGetOutputList(AttributeValueEncoder & aEncoder) { - std::list list; // TODO: Insert code here - int maximumVectorSize = 3; - - for (int i = 0; i < maximumVectorSize; ++i) - { - chip::app::Clusters::AudioOutput::Structs::OutputInfo::Type outputInfo; - outputInfo.outputType = chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi; - outputInfo.name = chip::CharSpan::fromCharString("exampleName"); - outputInfo.index = static_cast(1 + i); - list.push_back(outputInfo); - } - return list; + return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { + int maximumVectorSize = 3; + for (int i = 0; i < maximumVectorSize; ++i) + { + chip::app::Clusters::AudioOutput::Structs::OutputInfo::Type outputInfo; + outputInfo.outputType = chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi; + outputInfo.name = chip::CharSpan::fromCharString("exampleName"); + outputInfo.index = static_cast(1 + i); + ReturnErrorOnFailure(encoder.Encode(outputInfo)); + } + return CHIP_NO_ERROR; + }); } bool AudioOutputManager::HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) diff --git a/examples/tv-app/linux/include/audio-output/AudioOutputManager.h b/examples/tv-app/linux/include/audio-output/AudioOutputManager.h index 8dcd3ed344fc9a..44359fa75c8e1f 100644 --- a/examples/tv-app/linux/include/audio-output/AudioOutputManager.h +++ b/examples/tv-app/linux/include/audio-output/AudioOutputManager.h @@ -20,11 +20,14 @@ #include -class AudioOutputManager : public chip::app::Clusters::AudioOutput::Delegate +using chip::app::AttributeValueEncoder; +using AudioOutputDelegate = chip::app::Clusters::AudioOutput::Delegate; + +class AudioOutputManager : public AudioOutputDelegate { public: uint8_t HandleGetCurrentOutput() override; - std::list HandleGetOutputList() override; + CHIP_ERROR HandleGetOutputList(AttributeValueEncoder & aEncoder) override; bool HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) override; bool HandleSelectOutput(const uint8_t & index) override; }; diff --git a/examples/tv-app/linux/include/channel/ChannelManager.cpp b/examples/tv-app/linux/include/channel/ChannelManager.cpp index 55c1422b6ddc1f..6fc84cb2e71a58 100644 --- a/examples/tv-app/linux/include/channel/ChannelManager.cpp +++ b/examples/tv-app/linux/include/channel/ChannelManager.cpp @@ -18,9 +18,10 @@ #include "ChannelManager.h" using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters::Channel; -CHIP_ERROR ChannelManager::HandleGetChannelList(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder) { // TODO: Insert code here return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { @@ -42,7 +43,7 @@ CHIP_ERROR ChannelManager::HandleGetChannelList(chip::app::AttributeValueEncoder }); } -CHIP_ERROR ChannelManager::HandleGetLineup(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder) { chip::app::Clusters::Channel::Structs::LineupInfo::Type lineup; lineup.operatorName = chip::CharSpan::fromCharString("operatorName"); @@ -53,7 +54,7 @@ CHIP_ERROR ChannelManager::HandleGetLineup(chip::app::AttributeValueEncoder & aE return aEncoder.Encode(lineup); } -CHIP_ERROR ChannelManager::HandleGetCurrentChannel(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) { chip::app::Clusters::Channel::Structs::ChannelInfo::Type currentChannel; currentChannel.affiliateCallSign = chip::CharSpan::fromCharString("exampleASign"); @@ -65,11 +66,9 @@ CHIP_ERROR ChannelManager::HandleGetCurrentChannel(chip::app::AttributeValueEnco return aEncoder.Encode(currentChannel); } -void ChannelManager::HandleChangeChannel( - const chip::CharSpan & match, - chip::app::CommandResponseHelper & responser) +void ChannelManager::HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) { - Commands::ChangeChannelResponse::Type response; + ChangeChannelResponseType response; response.channelMatch.majorNumber = 1; response.channelMatch.minorNumber = 0; response.channelMatch.name = chip::CharSpan::fromCharString("name"); @@ -77,7 +76,7 @@ void ChannelManager::HandleChangeChannel( response.channelMatch.affiliateCallSign = chip::CharSpan::fromCharString("affiliateCallSign"); response.errorType = chip::app::Clusters::Channel::ErrorTypeEnum::kMultipleMatches; - responser.Success(response); + helper.Success(response); } bool ChannelManager::HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) diff --git a/examples/tv-app/linux/include/channel/ChannelManager.h b/examples/tv-app/linux/include/channel/ChannelManager.h index 372523fe9f426e..6dfce8cc2a9751 100644 --- a/examples/tv-app/linux/include/channel/ChannelManager.h +++ b/examples/tv-app/linux/include/channel/ChannelManager.h @@ -19,16 +19,20 @@ #include -class ChannelManager : public chip::app::Clusters::Channel::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using ChannelDelegate = chip::app::Clusters::Channel::Delegate; +using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; + +class ChannelManager : public ChannelDelegate { public: - virtual CHIP_ERROR HandleGetChannelList(chip::app::AttributeValueEncoder & aEncoder) override; - virtual CHIP_ERROR HandleGetLineup(chip::app::AttributeValueEncoder & aEncoder) override; - virtual CHIP_ERROR HandleGetCurrentChannel(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetChannelList(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetLineup(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) override; - virtual void HandleChangeChannel( - const chip::CharSpan & match, - chip::app::CommandResponseHelper & responser) override; + void HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) override; bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) override; bool HandleSkipChannel(const uint16_t & count) override; }; diff --git a/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.cpp b/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.cpp index a41cd29009e835..4194a6c9d24f37 100644 --- a/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.cpp +++ b/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.cpp @@ -17,41 +17,33 @@ */ #include "ContentLauncherManager.h" -#include using namespace std; +using namespace chip::app; +using namespace chip::app::Clusters; using namespace chip::app::Clusters::ContentLauncher; -using namespace chip::AppPlatform; -void ContentLauncherManager::HandleLaunchContent( - const std::list & parameterList, bool autoplay, const chip::CharSpan & data, - chip::app::CommandResponseHelper & responser) +ContentLauncherManager::ContentLauncherManager(list acceptHeaderList, uint32_t supportedStreamingProtocols) +{ + mAcceptHeaderList = acceptHeaderList; + mSupportedStreamingProtocols = supportedStreamingProtocols; +} + +void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper & helper, + const list & parameterList, bool autoplay, const CharSpan & data) { ChipLogProgress(Zcl, "ContentLauncherManager::HandleLaunchContent for endpoint %d", mEndpointId); string dataString(data.data(), data.size()); - Commands::LaunchResponse::Type response; - -#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetContentAppByEndpointId(mEndpointId); - if (app != NULL) - { - response = app->GetContentLauncher()->LaunchContent(parameterList, autoplay, dataString); - responser.Success(response); - return; - } -#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - + LaunchResponseType response; // TODO: Insert code here - response.data = chip::CharSpan::fromCharString("exampleData"); - response.status = chip::app::Clusters::ContentLauncher::StatusEnum::kSuccess; - responser.Success(response); + response.data = CharSpan::fromCharString("exampleData"); + response.status = ContentLauncher::StatusEnum::kSuccess; + helper.Success(response); } -void ContentLauncherManager::HandleLaunchUrl( - const chip::CharSpan & contentUrl, const chip::CharSpan & displayString, - const std::list & brandingInformation, - chip::app::CommandResponseHelper & responser) +void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, + const CharSpan & displayString, const list & brandingInformation) { ChipLogProgress(Zcl, "ContentLauncherManager::HandleLaunchUrl"); @@ -59,19 +51,21 @@ void ContentLauncherManager::HandleLaunchUrl( string displayStringString(displayString.data(), displayString.size()); // TODO: Insert code here - Commands::LaunchResponse::Type response; - response.data = chip::CharSpan::fromCharString("exampleData"); - response.status = chip::app::Clusters::ContentLauncher::StatusEnum::kSuccess; - responser.Success(response); + LaunchResponseType response; + response.data = CharSpan::fromCharString("exampleData"); + response.status = ContentLauncher::StatusEnum::kSuccess; + helper.Success(response); } -CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) { ChipLogProgress(Zcl, "ContentLauncherManager::HandleGetAcceptHeaderList"); - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { - chip::CharSpan data = chip::CharSpan::fromCharString("example"); - ReturnErrorOnFailure(encoder.Encode(data)); - ReturnErrorOnFailure(encoder.Encode(data)); + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (std::string & entry : mAcceptHeaderList) + { + CharSpan data = CharSpan::fromCharString(entry.c_str()); + ReturnErrorOnFailure(encoder.Encode(data)); + } return CHIP_NO_ERROR; }); } @@ -79,6 +73,5 @@ CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(chip::app::Attribut uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols() { ChipLogProgress(Zcl, "ContentLauncherManager::HandleGetSupportedStreamingProtocols"); - uint32_t streamingProtocols = 0; - return streamingProtocols; + return mSupportedStreamingProtocols; } diff --git a/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.h b/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.h index 0429c945548b8f..c8389c6074f193 100644 --- a/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.h +++ b/examples/tv-app/linux/include/content-launcher/ContentLauncherManager.h @@ -20,22 +20,30 @@ #include -class ContentLauncherManager : public chip::app::Clusters::ContentLauncher::Delegate +using chip::CharSpan; +using chip::EndpointId; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; + +class ContentLauncherManager : public ContentLauncherDelegate { public: - ContentLauncherManager(chip::EndpointId endpointId) : mEndpointId(endpointId) {} + ContentLauncherManager() : ContentLauncherManager({ "example", "example" }, 0){}; + ContentLauncherManager(std::list acceptHeaderList, uint32_t supportedStreamingProtocols); - void - HandleLaunchContent(const std::list & parameterList, bool autoplay, const chip::CharSpan & data, - chip::app::CommandResponseHelper & - responser) override; - void HandleLaunchUrl(const chip::CharSpan & contentUrl, const chip::CharSpan & displayString, - const std::list & brandingInformation, - chip::app::CommandResponseHelper & - responser) override; - CHIP_ERROR HandleGetAcceptHeaderList(chip::app::AttributeValueEncoder & aEncoder) override; + void HandleLaunchContent(CommandResponseHelper & helper, const std::list & parameterList, + bool autoplay, const CharSpan & data) override; + void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, + const CharSpan & displayString, const std::list & brandingInformation) override; + CHIP_ERROR HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) override; uint32_t HandleGetSupportedStreamingProtocols() override; +protected: + std::list mAcceptHeaderList; + uint32_t mSupportedStreamingProtocols; + private: - chip::EndpointId mEndpointId; + EndpointId mEndpointId; }; diff --git a/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp b/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp index 32bcc0342cb36d..cbcf48380aa509 100644 --- a/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp +++ b/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp @@ -21,10 +21,10 @@ using namespace chip; using namespace chip::app::Clusters::KeypadInput; -Commands::SendKeyResponse::Type KeypadInputManager::HandleSendKey(const CecKeyCode & keycCode) +void KeypadInputManager::HandleSendKey(CommandResponseHelper & helper, const CecKeyCode & keycCode) { // TODO: Insert code here Commands::SendKeyResponse::Type response; response.status = chip::app::Clusters::KeypadInput::StatusEnum::kSuccess; - return response; + helper.Success(response); } diff --git a/examples/tv-app/linux/include/keypad-input/KeypadInputManager.h b/examples/tv-app/linux/include/keypad-input/KeypadInputManager.h index 93d3f66e8a003a..3ebc70fc249282 100644 --- a/examples/tv-app/linux/include/keypad-input/KeypadInputManager.h +++ b/examples/tv-app/linux/include/keypad-input/KeypadInputManager.h @@ -20,9 +20,13 @@ #include -class KeypadInputManager : public chip::app::Clusters::KeypadInput::Delegate +using chip::app::CommandResponseHelper; +using KeypadInputDelegate = chip::app::Clusters::KeypadInput::Delegate; +using SendKeyResponseType = chip::app::Clusters::KeypadInput::Commands::SendKeyResponse::Type; + +class KeypadInputManager : public KeypadInputDelegate { public: - chip::app::Clusters::KeypadInput::Commands::SendKeyResponse::Type - HandleSendKey(const chip::app::Clusters::KeypadInput::CecKeyCode & keyCode) override; + void HandleSendKey(CommandResponseHelper & helper, + const chip::app::Clusters::KeypadInput::CecKeyCode & keyCode) override; }; diff --git a/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.cpp b/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.cpp index 81e6872e14d83a..23a89c4aaebdfe 100644 --- a/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.cpp +++ b/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.cpp @@ -35,12 +35,13 @@ uint64_t MediaPlaybackManager::HandleGetDuration() return 0; } -Structs::PlaybackPosition::Type MediaPlaybackManager::HandleGetSampledPosition() +CHIP_ERROR MediaPlaybackManager::HandleGetSampledPosition(AttributeValueEncoder & aEncoder) { Structs::PlaybackPosition::Type sampledPosition; sampledPosition.updatedAt = 0; sampledPosition.position = 0; - return sampledPosition; + + return aEncoder.Encode(sampledPosition); } float MediaPlaybackManager::HandleGetPlaybackSpeed() @@ -58,90 +59,93 @@ uint64_t MediaPlaybackManager::HandleGetSeekRangeEnd() return 0; } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandlePlay() +void MediaPlaybackManager::HandlePlay(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandlePause() +void MediaPlaybackManager::HandlePause(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleStop() +void MediaPlaybackManager::HandleStop(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleFastForward() +void MediaPlaybackManager::HandleFastForward(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandlePrevious() +void MediaPlaybackManager::HandlePrevious(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleRewind() +void MediaPlaybackManager::HandleRewind(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleSkipBackward(const uint64_t & deltaPositionMilliseconds) +void MediaPlaybackManager::HandleSkipBackward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleSkipForward(const uint64_t & deltaPositionMilliseconds) +void MediaPlaybackManager::HandleSkipForward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleSeekRequest(const uint64_t & positionMilliseconds) +void MediaPlaybackManager::HandleSeekRequest(CommandResponseHelper & helper, + const uint64_t & positionMilliseconds) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleNext() +void MediaPlaybackManager::HandleNext(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } -Commands::PlaybackResponse::Type MediaPlaybackManager::HandleStartOverRequest() +void MediaPlaybackManager::HandleStartOverRequest(CommandResponseHelper & helper) { // TODO: Insert code here Commands::PlaybackResponse::Type response; response.status = StatusEnum::kSuccess; - return response; + helper.Success(response); } diff --git a/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.h b/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.h index 9bf4c6607cf2f9..e5bc2aeed5ab4e 100644 --- a/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.h +++ b/examples/tv-app/linux/include/media-playback/MediaPlaybackManager.h @@ -20,29 +20,33 @@ #include -class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using MediaPlaybackDelegate = chip::app::Clusters::MediaPlayback::Delegate; +using PlaybackResponseType = chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type; + +class MediaPlaybackManager : public MediaPlaybackDelegate { public: chip::app::Clusters::MediaPlayback::PlaybackStateEnum HandleGetCurrentState() override; uint64_t HandleGetStartTime() override; uint64_t HandleGetDuration() override; - chip::app::Clusters::MediaPlayback::Structs::PlaybackPosition::Type HandleGetSampledPosition() override; + CHIP_ERROR HandleGetSampledPosition(AttributeValueEncoder & aEncoder) override; float HandleGetPlaybackSpeed() override; uint64_t HandleGetSeekRangeStart() override; uint64_t HandleGetSeekRangeEnd() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandlePlay() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandlePause() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleStop() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleFastForward() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandlePrevious() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleRewind() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type - HandleSkipBackward(const uint64_t & deltaPositionMilliseconds) override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type - HandleSkipForward(const uint64_t & deltaPositionMilliseconds) override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type - HandleSeekRequest(const uint64_t & positionMilliseconds) override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleNext() override; - chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type HandleStartOverRequest() override; + void HandlePlay(CommandResponseHelper & helper) override; + void HandlePause(CommandResponseHelper & helper) override; + void HandleStop(CommandResponseHelper & helper) override; + void HandleFastForward(CommandResponseHelper & helper) override; + void HandlePrevious(CommandResponseHelper & helper) override; + void HandleRewind(CommandResponseHelper & helper) override; + void HandleSkipBackward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) override; + void HandleSkipForward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) override; + void HandleSeekRequest(CommandResponseHelper & helper, const uint64_t & positionMilliseconds) override; + void HandleNext(CommandResponseHelper & helper) override; + void HandleStartOverRequest(CommandResponseHelper & helper) override; }; diff --git a/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp b/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp index 145531d5aa82d1..576fa443ca9fd4 100644 --- a/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp +++ b/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp @@ -18,35 +18,52 @@ #include "TargetNavigatorManager.h" using namespace std; +using namespace chip::app; using namespace chip::app::Clusters::TargetNavigator; -std::list TargetNavigatorManager::HandleGetTargetList() +TargetNavigatorManager::TargetNavigatorManager(std::list targets, uint8_t currentTarget) { - std::list list; - // TODO: Insert code here - int maximumVectorSize = 2; + mTargets = targets; + mCurrentTarget = currentTarget; +} - for (int i = 0; i < maximumVectorSize; ++i) - { - Structs::TargetInfo::Type outputInfo; - outputInfo.identifier = static_cast(i + 1); - outputInfo.name = chip::CharSpan::fromCharString("exampleName"); - list.push_back(outputInfo); - } - return list; +CHIP_ERROR TargetNavigatorManager::HandleGetTargetList(AttributeValueEncoder & aEncoder) +{ + // NOTE: the ids for each target start at 1 so that we can reserve 0 as "no current target" + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + int i = 0; + for (std::string & entry : mTargets) + { + Structs::TargetInfo::Type outputInfo; + outputInfo.identifier = static_cast(i + 1); + outputInfo.name = CharSpan::fromCharString(entry.c_str()); + ReturnErrorOnFailure(encoder.Encode(outputInfo)); + i++; + } + return CHIP_NO_ERROR; + }); } uint8_t TargetNavigatorManager::HandleGetCurrentTarget() { - return 0; + return mCurrentTarget; } -Commands::NavigateTargetResponse::Type TargetNavigatorManager::HandleNavigateTarget(const uint64_t & target, - const chip::CharSpan & data) +void TargetNavigatorManager::HandleNavigateTarget(CommandResponseHelper & helper, + const uint64_t & target, const CharSpan & data) { - // TODO: Insert code here - Commands::NavigateTargetResponse::Type response; - response.data = chip::CharSpan::fromCharString("data response"); - response.status = chip::app::Clusters::TargetNavigator::StatusEnum::kSuccess; - return response; + NavigateTargetResponseType response; + if (target == kNoCurrentTarget || target > mTargets.size()) + { + response.data = CharSpan::fromCharString("error"); + // TODO: should be TARGET_NOT_FOUND + response.status = StatusEnum::kAppNotAvailable; + helper.Success(response); + return; + } + mCurrentTarget = static_cast(target); + + response.data = CharSpan::fromCharString("data response"); + response.status = StatusEnum::kSuccess; + helper.Success(response); } diff --git a/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.h b/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.h index 7da10ea51448f5..f4cb0b372bc7e3 100644 --- a/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.h +++ b/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.h @@ -19,11 +19,27 @@ #include -class TargetNavigatorManager : public chip::app::Clusters::TargetNavigator::Delegate +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; +using TargetNavigatorDelegate = chip::app::Clusters::TargetNavigator::Delegate; +using TargetInfoType = chip::app::Clusters::TargetNavigator::Structs::TargetInfo::Type; +using NavigateTargetResponseType = chip::app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type; + +class TargetNavigatorManager : public TargetNavigatorDelegate { public: - std::list HandleGetTargetList() override; + TargetNavigatorManager() : TargetNavigatorManager({ "exampleName", "exampleName" }, kNoCurrentTarget){}; + TargetNavigatorManager(std::list targets, uint8_t currentTarget); + + CHIP_ERROR HandleGetTargetList(AttributeValueEncoder & aEncoder) override; uint8_t HandleGetCurrentTarget() override; - chip::app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type - HandleNavigateTarget(const uint64_t & target, const chip::CharSpan & data) override; + void HandleNavigateTarget(CommandResponseHelper & responser, const uint64_t & target, + const CharSpan & data) override; + +protected: + // NOTE: the ids for each target start at 1 so that we can reserve 0 as "no current target" + static const uint8_t kNoCurrentTarget = 0; + std::list mTargets; + uint8_t mCurrentTarget; }; diff --git a/examples/tv-app/linux/main.cpp b/examples/tv-app/linux/main.cpp index f6133e5217dda2..f67a35ed028ad8 100644 --- a/examples/tv-app/linux/main.cpp +++ b/examples/tv-app/linux/main.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -49,8 +49,9 @@ using namespace chip; using namespace chip::Transport; using namespace chip::DeviceLayer; using namespace chip::AppPlatform; +using namespace chip::app::Clusters; -bool emberAfBasicClusterMfgSpecificPingCallback(chip::app::CommandHandler * commandObj) +bool emberAfBasicClusterMfgSpecificPingCallback(app::CommandHandler * commandObj) { emberAfSendDefaultResponse(emberAfCurrentCommand(), EMBER_ZCL_STATUS_SUCCESS); return true; @@ -59,9 +60,14 @@ bool emberAfBasicClusterMfgSpecificPingCallback(chip::app::CommandHandler * comm namespace { static AccountLoginManager accountLoginManager; static ApplicationBasicManager applicationBasicManager; -static ApplicationLauncherManager applicationLauncherManager; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +static ApplicationLauncherManager applicationLauncherManager(true); +#else // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +static ApplicationLauncherManager applicationLauncherManager(false); +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED static AudioOutputManager audioOutputManager; static ChannelManager channelManager; +static ContentLauncherManager contentLauncherManager; static KeypadInputManager keypadInputManager; static LowPowerManager lowPowerManager; static MediaInputManager mediaInputManager; @@ -72,23 +78,61 @@ static WakeOnLanManager wakeOnLanManager; void ApplicationInit() {} +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE +class MyUserPrompter : public UserPrompter +{ + // TODO: tv should override this with a dialog prompt + inline void PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override + { + return; + } + + // TODO: tv should override this with a dialog prompt + inline void PromptForCommissionPincode(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override + { + return; + } +}; + +MyUserPrompter gMyUserPrompter; +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +class MyPincodeService : public PincodeService +{ + uint32_t FetchCommissionPincodeFromContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId) override + { + return ContentAppPlatform::GetInstance().GetPincodeFromContentApp(vendorId, productId, rotatingId); + } +}; +MyPincodeService gMyPincodeService; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + int main(int argc, char * argv[]) { #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - chip::AppPlatform::ContentAppFactoryImpl factory; + ContentAppFactoryImpl factory; #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - chip::AppPlatform::AppPlatform::GetInstance().SetupAppPlatform(); - chip::AppPlatform::AppPlatform::GetInstance().SetContentAppFactory(&factory); + ContentAppPlatform::GetInstance().SetupAppPlatform(); + ContentAppPlatform::GetInstance().SetContentAppFactory(&factory); +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController(); + if (cdc != nullptr) + { + cdc->SetPincodeService(&gMyPincodeService); + cdc->SetUserPrompter(&gMyUserPrompter); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #if defined(ENABLE_CHIP_SHELL) #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - chip::Shell::RegisterAppPlatformCommands(); + Shell::RegisterAppPlatformCommands(); #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #endif @@ -99,72 +143,72 @@ int main(int argc, char * argv[]) void emberAfContentLauncherClusterInitCallback(EndpointId endpoint) { - ChipLogProgress(Zcl, "TV Linux App: ContentLauncher::SetDelegate"); - chip::app::Clusters::ContentLauncher::SetDelegate(endpoint, new ContentLauncherManager(endpoint)); + ChipLogProgress(Zcl, "TV Linux App: ContentLauncher::SetDefaultDelegate"); + ContentLauncher::SetDefaultDelegate(endpoint, &contentLauncherManager); } void emberAfAccountLoginClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: AccountLogin::SetDefaultDelegate"); - chip::app::Clusters::AccountLogin::SetDefaultDelegate(endpoint, &accountLoginManager); + AccountLogin::SetDefaultDelegate(endpoint, &accountLoginManager); } void emberAfApplicationBasicClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: ApplicationBasic::SetDefaultDelegate"); - chip::app::Clusters::ApplicationBasic::SetDefaultDelegate(endpoint, &applicationBasicManager); + ApplicationBasic::SetDefaultDelegate(endpoint, &applicationBasicManager); } void emberAfApplicationLauncherClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: ApplicationLauncher::SetDefaultDelegate"); - chip::app::Clusters::ApplicationLauncher::SetDefaultDelegate(endpoint, &applicationLauncherManager); + ApplicationLauncher::SetDefaultDelegate(endpoint, &applicationLauncherManager); } void emberAfAudioOutputClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: AudioOutput::SetDefaultDelegate"); - chip::app::Clusters::AudioOutput::SetDefaultDelegate(endpoint, &audioOutputManager); + AudioOutput::SetDefaultDelegate(endpoint, &audioOutputManager); } void emberAfChannelClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: Channel::SetDefaultDelegate"); - chip::app::Clusters::Channel::SetDefaultDelegate(endpoint, &channelManager); + Channel::SetDefaultDelegate(endpoint, &channelManager); } void emberAfKeypadInputClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: KeypadInput::SetDefaultDelegate"); - chip::app::Clusters::KeypadInput::SetDefaultDelegate(endpoint, &keypadInputManager); + KeypadInput::SetDefaultDelegate(endpoint, &keypadInputManager); } void emberAfLowPowerClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: LowPower::SetDefaultDelegate"); - chip::app::Clusters::LowPower::SetDefaultDelegate(endpoint, &lowPowerManager); + LowPower::SetDefaultDelegate(endpoint, &lowPowerManager); } void emberAfMediaInputClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate"); - chip::app::Clusters::MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager); + MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager); } void emberAfMediaPlaybackClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: MediaPlayback::SetDefaultDelegate"); - chip::app::Clusters::MediaPlayback::SetDefaultDelegate(endpoint, &mediaPlaybackManager); + MediaPlayback::SetDefaultDelegate(endpoint, &mediaPlaybackManager); } void emberAfTargetNavigatorClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: TargetNavigator::SetDefaultDelegate"); - chip::app::Clusters::TargetNavigator::SetDefaultDelegate(endpoint, &targetNavigatorManager); + TargetNavigator::SetDefaultDelegate(endpoint, &targetNavigatorManager); } -void emberAfWakeOnLanClusterInitCallback(chip::EndpointId endpoint) +void emberAfWakeOnLanClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: WakeOnLanManager::SetDefaultDelegate"); - chip::app::Clusters::WakeOnLan::SetDefaultDelegate(endpoint, &wakeOnLanManager); + WakeOnLan::SetDefaultDelegate(endpoint, &wakeOnLanManager); } diff --git a/src/app/app-platform/ContentApp.cpp b/src/app/app-platform/ContentApp.cpp new file mode 100644 index 00000000000000..53ee9fe5bcdb9d --- /dev/null +++ b/src/app/app-platform/ContentApp.cpp @@ -0,0 +1,70 @@ +/* + * + * 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 functions relating to Content App of the Video Player. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + +using namespace chip; +using namespace chip::AppPlatform; + +namespace chip { +namespace AppPlatform { + +#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) +#define ZCL_APPLICATION_BASIC_CLUSTER_REVISION (1u) + +EmberAfStatus ContentApp::HandleReadAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t * buffer, + uint16_t maxReadLength) +{ + ChipLogProgress(DeviceLayer, + "Read Attribute for endpoint " ChipLogFormatMEI " cluster " ChipLogFormatMEI " attribute " ChipLogFormatMEI, + ChipLogValueMEI(mEndpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId)); + + return EMBER_ZCL_STATUS_FAILURE; +} + +EmberAfStatus ContentApp::HandleWriteAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t * buffer) +{ + ChipLogProgress(DeviceLayer, + "Read Attribute for endpoint " ChipLogFormatMEI " cluster " ChipLogFormatMEI " attribute " ChipLogFormatMEI, + ChipLogValueMEI(mEndpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId)); + + return EMBER_ZCL_STATUS_FAILURE; +} + +} // namespace AppPlatform +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED diff --git a/src/app/app-platform/ContentApp.h b/src/app/app-platform/ContentApp.h new file mode 100644 index 00000000000000..dfbda366d8a3e1 --- /dev/null +++ b/src/app/app-platform/ContentApp.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2021 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. + */ + +/** + * @brief classes relating to Content App of the Video Player. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace AppPlatform { + +using AccountLoginDelegate = app::Clusters::AccountLogin::Delegate; +using ApplicationBasicDelegate = app::Clusters::ApplicationBasic::Delegate; +using ApplicationLauncherDelegate = app::Clusters::ApplicationLauncher::Delegate; +using ChannelDelegate = app::Clusters::Channel::Delegate; +using ContentLauncherDelegate = app::Clusters::ContentLauncher::Delegate; +using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; +using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; +using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; + +class DLL_EXPORT ContentApp +{ +public: + virtual ~ContentApp() = default; + + inline void SetEndpointId(EndpointId id) { mEndpointId = id; }; + inline EndpointId GetEndpointId() { return mEndpointId; }; + + virtual AccountLoginDelegate * GetAccountLoginDelegate() = 0; + virtual ApplicationBasicDelegate * GetApplicationBasicDelegate() = 0; + virtual ApplicationLauncherDelegate * GetApplicationLauncherDelegate() = 0; + virtual ChannelDelegate * GetChannelDelegate() = 0; + virtual ContentLauncherDelegate * GetContentLauncherDelegate() = 0; + virtual KeypadInputDelegate * GetKeypadInputDelegate() = 0; + virtual MediaPlaybackDelegate * GetMediaPlaybackDelegate() = 0; + virtual TargetNavigatorDelegate * GetTargetNavigatorDelegate() = 0; + + EmberAfStatus HandleReadAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength); + EmberAfStatus HandleWriteAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t * buffer); + +protected: + EndpointId mEndpointId = 0; +}; + +} // namespace AppPlatform +} // namespace chip diff --git a/src/app/app-platform/ContentAppPlatform.cpp b/src/app/app-platform/ContentAppPlatform.cpp new file mode 100644 index 00000000000000..fc3f5fbac2a936 --- /dev/null +++ b/src/app/app-platform/ContentAppPlatform.cpp @@ -0,0 +1,392 @@ +/* + * + * 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 functions relating to Content App platform of the Video Player. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + +using namespace chip; +using namespace chip::AppPlatform; +using namespace chip::app::Clusters; +using ApplicationStatusEnum = app::Clusters::ApplicationBasic::ApplicationStatusEnum; +using GetSetupPINResponseType = app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Type; + +// Device Version for dynamic endpoints: +#define DEVICE_VERSION_DEFAULT 1 + +EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, + EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, + uint16_t maxReadLength) +{ + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + + ChipLogProgress(DeviceLayer, "emberAfExternalAttributeReadCallback endpoint %d ", endpointIndex); + + EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; + + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ret = app->HandleReadAttribute(clusterId, attributeMetadata->attributeId, buffer, maxReadLength); + } + + return ret; +} + +EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, + EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer) +{ + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + + ChipLogProgress(DeviceLayer, "emberAfExternalAttributeWriteCallback endpoint %d ", endpointIndex); + + EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; + + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ret = app->HandleWriteAttribute(clusterId, attributeMetadata->attributeId, buffer); + } + + return ret; +} + +namespace chip { +namespace AppPlatform { + +EndpointId ContentAppPlatform::AddContentApp(ContentApp * app, EmberAfEndpointType * ep, uint16_t deviceType) +{ + CatalogVendorApp vendorApp = app->GetApplicationBasicDelegate()->GetCatalogVendorApp(); + + ChipLogProgress(DeviceLayer, "Adding ContentApp with appid %s ", vendorApp.applicationId); + uint8_t index = 0; + // check if already loaded + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + if (mContentApps[index] == app) + { + ChipLogProgress(DeviceLayer, "Already added"); + return app->GetEndpointId(); + } + index++; + } + + index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + if (nullptr == mContentApps[index]) + { + mContentApps[index] = app; + EmberAfStatus ret; + while (1) + { + ret = emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, deviceType, DEVICE_VERSION_DEFAULT); + if (ret == EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogProgress(DeviceLayer, "Added ContentApp %s to dynamic endpoint %d (index=%d)", vendorApp.applicationId, + mCurrentEndpointId, index); + app->SetEndpointId(mCurrentEndpointId); + return app->GetEndpointId(); + } + else if (ret != EMBER_ZCL_STATUS_DUPLICATE_EXISTS) + { + ChipLogProgress(DeviceLayer, "Adding ContentApp error=%d", ret); + return kNoCurrentEndpointId; + } + // Handle wrap condition + if (++mCurrentEndpointId < mFirstDynamicEndpointId) + { + mCurrentEndpointId = mFirstDynamicEndpointId; + } + } + } + index++; + } + ChipLogProgress(DeviceLayer, "Failed to add dynamic endpoint: No endpoints available!"); + return kNoCurrentEndpointId; +} + +EndpointId ContentAppPlatform::RemoveContentApp(ContentApp * app) +{ + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + if (mContentApps[index] == app) + { + EndpointId curEndpoint = app->GetEndpointId(); + EndpointId ep = emberAfClearDynamicEndpoint(index); + mContentApps[index] = nullptr; + ChipLogProgress(DeviceLayer, "Removed device %d from dynamic endpoint %d (index=%d)", + app->GetApplicationBasicDelegate()->HandleGetVendorId(), ep, index); + // Silence complaints about unused ep when progress logging + // disabled. + UNUSED_VAR(ep); + if (curEndpoint == mCurrentAppEndpointId) + { + mCurrentAppEndpointId = kNoCurrentEndpointId; + } + return curEndpoint; + } + index++; + } + return kNoCurrentEndpointId; +} + +void ContentAppPlatform::SetupAppPlatform() +{ + ChipLogProgress(DeviceLayer, "AppPlatform::SetupAppPlatform()"); + + // Clear out the device database + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + mContentApps[index] = nullptr; + index++; + } + + // Set starting endpoint id where dynamic endpoints will be assigned, which + // will be the next consecutive endpoint id after the last fixed endpoint. + mFirstDynamicEndpointId = static_cast( + static_cast(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1))) + 1); + mCurrentEndpointId = mFirstDynamicEndpointId; + + if (mCurrentEndpointId < emberAfFixedEndpointCount()) + { + mCurrentEndpointId = emberAfFixedEndpointCount(); + } + + ChipLogProgress(DeviceLayer, "emberAfFixedEndpointCount()=%d mCurrentEndpointId=%d", emberAfFixedEndpointCount(), + mCurrentEndpointId); + + // Disable last fixed endpoint, which is used as a placeholder for all of the + // supported clusters so that ZAP will generated the requisite code. + // emberAfEndpointEnableDisable(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1)), false); +} + +ContentApp * ContentAppPlatform::GetContentAppInternal(CatalogVendorApp vendorApp) +{ + if (vendorApp.catalogVendorId != mContentAppFactory->GetPlatformCatalogVendorId()) + { + return nullptr; + } + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + ContentApp * app = mContentApps[index]; + if (app != nullptr && app->GetApplicationBasicDelegate()->GetCatalogVendorApp()->Matches(vendorApp)) + { + return app; + } + index++; + } + return nullptr; +} + +ContentApp * ContentAppPlatform::LoadContentAppInternal(CatalogVendorApp vendorApp) +{ + ContentApp * app = GetContentAppInternal(vendorApp); + if (app != nullptr) + { + return app; + } + if (mContentAppFactory != nullptr) + { + return mContentAppFactory->LoadContentApp(vendorApp); + } + return nullptr; +} + +ContentApp * ContentAppPlatform::LoadContentAppByClient(uint16_t vendorId, uint16_t productId) +{ + ChipLogProgress(DeviceLayer, "GetLoadContentAppByVendorId() - vendorId %d, productId %d", vendorId, productId); + + CatalogVendorApp vendorApp; + CHIP_ERROR err = mContentAppFactory->LookupCatalogVendorApp(vendorId, productId, &vendorApp); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "GetLoadContentAppByVendorId() - failed to find an app for vendorId %d, productId %d", + vendorId, productId); + return nullptr; + } + return LoadContentAppInternal(vendorApp); +} + +ContentApp * ContentAppPlatform::LoadContentApp(CatalogVendorApp vendorApp) +{ + if (vendorApp.catalogVendorId == mContentAppFactory->GetPlatformCatalogVendorId()) + { + return LoadContentAppInternal(vendorApp); + } + CatalogVendorApp destinationApp; + CHIP_ERROR err = mContentAppFactory->ConvertToPlatformCatalogVendorApp(vendorApp, &destinationApp); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "GetLoadContentApp() - failed to find an app for catalog vendorId %d, appId %s", + vendorApp.catalogVendorId, vendorApp.applicationId); + return nullptr; + } + return LoadContentAppInternal(destinationApp); +} + +ContentApp * ContentAppPlatform::GetContentApp(CatalogVendorApp vendorApp) +{ + if (vendorApp.catalogVendorId == mContentAppFactory->GetPlatformCatalogVendorId()) + { + return GetContentAppInternal(vendorApp); + } + CatalogVendorApp destinationApp; + CHIP_ERROR err = mContentAppFactory->ConvertToPlatformCatalogVendorApp(vendorApp, &destinationApp); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "GetContentApp() - failed to find an app for catalog vendorId %d, appId %s", + vendorApp.catalogVendorId, vendorApp.applicationId); + return nullptr; + } + return GetContentAppInternal(destinationApp); +} + +ContentApp * ContentAppPlatform::GetContentApp(EndpointId id) +{ + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + ContentApp * app = mContentApps[index]; + if (app != nullptr && app->GetEndpointId() == id) + { + return app; + } + index++; + } + ChipLogProgress(DeviceLayer, "GetContentAppByEndpointId() - endpoint %d not found ", id); + return nullptr; +} + +void ContentAppPlatform::SetCurrentApp(ContentApp * app) +{ + if (!HasCurrentApp()) + { + mCurrentAppEndpointId = app->GetEndpointId(); + app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kActiveVisibleFocus); + return; + } + + // if this is the current app, then no action + if (mCurrentAppEndpointId == app->GetEndpointId()) + { + ChipLogProgress(DeviceLayer, "AppPlatform::SetCurrentApp already current app"); + app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kActiveVisibleFocus); + return; + } + // if there is another current app, then need to hide it + ContentApp * previousApp = GetContentApp(mCurrentAppEndpointId); + if (previousApp == nullptr) + { + ChipLogProgress(DeviceLayer, "AppPlatform::SetCurrentApp current app not found"); + mCurrentAppEndpointId = app->GetEndpointId(); + app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kActiveVisibleFocus); + return; + } + + ChipLogProgress(DeviceLayer, "AppPlatform::SetCurrentApp has a current app"); + // make sure to mark previousApp as hidden + previousApp->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kActiveHidden); + + mCurrentAppEndpointId = app->GetEndpointId(); + app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kActiveVisibleFocus); + return; +} // namespace AppPlatform + +bool ContentAppPlatform::IsCurrentApp(ContentApp * app) +{ + if (HasCurrentApp()) + { + return false; + } + if (mCurrentAppEndpointId != app->GetEndpointId()) + { + return false; + } + if (app != GetContentApp(mCurrentAppEndpointId)) + { + // current app us not there, fix our state and exit + ChipLogProgress(DeviceLayer, "AppPlatform::IsCurrentApp current app not found"); + mCurrentAppEndpointId = kNoCurrentEndpointId; + return false; + } + return true; +} + +void ContentAppPlatform::UnsetIfCurrentApp(ContentApp * app) +{ + if (IsCurrentApp(app)) + { + ChipLogProgress(DeviceLayer, "UnsetIfCurrentApp setting to no current app"); + mCurrentAppEndpointId = kNoCurrentEndpointId; + app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kActiveHidden); + } + else + { + ChipLogProgress(DeviceLayer, "UnsetIfCurrentApp not current app"); + } +} + +uint32_t ContentAppPlatform::GetPincodeFromContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId) +{ + ContentApp * app = LoadContentAppByClient(vendorId, productId); + if (app == nullptr) + { + ChipLogProgress(DeviceLayer, "no app found for vendor id=%d \r\n", vendorId); + return 0; + } + + if (app->GetAccountLoginDelegate() == nullptr) + { + ChipLogProgress(DeviceLayer, "no AccountLogin cluster for app with vendor id=%d \r\n", vendorId); + return 0; + } + + static const size_t kSetupPINSize = 12; + char mSetupPIN[kSetupPINSize]; + + app->GetAccountLoginDelegate()->GetSetupPin(mSetupPIN, kSetupPINSize, rotatingId); + std::string pinString(mSetupPIN); + + char * eptr; + return (uint32_t) strtol(pinString.c_str(), &eptr, 10); +} + +} // namespace AppPlatform +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED diff --git a/src/app/app-platform/ContentAppPlatform.h b/src/app/app-platform/ContentAppPlatform.h new file mode 100644 index 00000000000000..addd06d78424bb --- /dev/null +++ b/src/app/app-platform/ContentAppPlatform.h @@ -0,0 +1,130 @@ +/* + * + * Copyright (c) 2021 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. + */ + +/** + * @brief classes relating to Content App platform of the Video Player. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +using chip::app::Clusters::ApplicationBasic::CatalogVendorApp; + +namespace chip { +namespace AppPlatform { + +class DLL_EXPORT ContentAppFactory +{ +public: + virtual ~ContentAppFactory() = default; + + // Lookup CatalogVendor App for this client (vendor id/product id client) + // and then write it to destinationApp + // return error if not found + virtual CHIP_ERROR LookupCatalogVendorApp(uint16_t vendorId, uint16_t productId, CatalogVendorApp * destinationApp) = 0; + + // Lookup ContentApp for this catalog id / app id and load it + virtual ContentApp * LoadContentApp(CatalogVendorApp vendorApp) = 0; + + // Gets the catalog vendor ID used by this platform + virtual uint16_t GetPlatformCatalogVendorId() = 0; + + // Converts application (any catalog) into the platform's catalog Vendor + // and then writes it to destinationApp + virtual CHIP_ERROR ConvertToPlatformCatalogVendorApp(CatalogVendorApp sourceApp, CatalogVendorApp * destinationApp) = 0; +}; + +class DLL_EXPORT ContentAppPlatform +{ +public: + static ContentAppPlatform & GetInstance() + { + static ContentAppPlatform instance; + return instance; + } + + void SetupAppPlatform(); + + inline void SetContentAppFactory(ContentAppFactory * factory) { mContentAppFactory = factory; }; + + // add apps to the platform. + // This will assign the app to an endpoint (if it is not already added) and make it accessible via Matter + // returns the global endpoint for this app, or 0 if an error occurred + EndpointId AddContentApp(ContentApp * app, EmberAfEndpointType * ep, uint16_t deviceType); + + // remove app from the platform. + // returns the endpoint id where the app was, or 0 if app was not loaded + EndpointId RemoveContentApp(ContentApp * app); + + // load and unload by vendor id + // void UnloadContentAppByVendorId(uint16_t vendorId, uint16_t productId); + + // Lookup ContentApp for this client (vendor id/product id client) and load it + ContentApp * LoadContentAppByClient(uint16_t vendorId, uint16_t productId); + + // Lookup ContentApp described by this application and load it + ContentApp * LoadContentApp(CatalogVendorApp application); + + // helpful method to get a Content App by endpoint in order to perform attribute or command ops + ContentApp * GetContentApp(EndpointId id); + + // helpful method to get a Content App by application, does not load if not found + ContentApp * GetContentApp(CatalogVendorApp application); + + // sets the current app for this platform + void SetCurrentApp(ContentApp * app); + + // returns true if there is a current app for this platform + inline bool HasCurrentApp() { return mCurrentAppEndpointId != kNoCurrentEndpointId; } + + // returns true if the vendor/app arguments are the current app + bool IsCurrentApp(ContentApp * app); + + // returns the current app endpoint + inline EndpointId GetCurrentAppEndpointId() { return mCurrentAppEndpointId; }; + + // unset this as current app, if it is current app + void UnsetIfCurrentApp(ContentApp * app); + + // loads content app identified by vid/pid of client and calls HandleGetSetupPin. + // Returns 0 if pin cannot be obtained. + uint32_t GetPincodeFromContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId); + +protected: + // requires vendorApp to be in the catalog of the platform + ContentApp * LoadContentAppInternal(CatalogVendorApp vendorApp); + ContentApp * GetContentAppInternal(CatalogVendorApp vendorApp); + + static const int kNoCurrentEndpointId = 0; + EndpointId mCurrentAppEndpointId = kNoCurrentEndpointId; + + ContentAppFactory * mContentAppFactory = nullptr; + EndpointId mCurrentEndpointId; + EndpointId mFirstDynamicEndpointId; + ContentApp * mContentApps[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; +}; + +} // namespace AppPlatform +} // namespace chip diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 0e18514f229d9a..50204cc7b6db25 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -142,9 +142,9 @@ template("chip_data_model") { ] } else if (cluster == "application-launcher-server") { sources += [ + "${_app_root}/app-platform/ContentApp.cpp", + "${_app_root}/app-platform/ContentAppPlatform.cpp", "${_app_root}/clusters/${cluster}/${cluster}.cpp", - "${_app_root}/util/ContentApp.cpp", - "${_app_root}/util/ContentAppPlatform.cpp", ] } else if (cluster == "ota-requestor") { sources += [ diff --git a/src/app/clusters/account-login-server/account-login-delegate.h b/src/app/clusters/account-login-server/account-login-delegate.h index 3880b7aa7f6456..3842412f40d7a2 100644 --- a/src/app/clusters/account-login-server/account-login-delegate.h +++ b/src/app/clusters/account-login-server/account-login-delegate.h @@ -20,6 +20,7 @@ #include +#include #include namespace chip { @@ -33,9 +34,14 @@ namespace AccountLogin { class Delegate { public: + // helper method to allow the platform to facilitate providing the pin + virtual void SetSetupPin(char * setupPin) = 0; + virtual bool HandleLogin(const chip::CharSpan & tempAccountIdentifierString, const chip::CharSpan & setupPinString) = 0; virtual bool HandleLogout() = 0; - virtual Commands::GetSetupPINResponse::Type HandleGetSetupPin(const chip::CharSpan & tempAccountIdentifierString) = 0; + virtual void HandleGetSetupPin(CommandResponseHelper & helper, + const chip::CharSpan & tempAccountIdentifierString) = 0; + virtual void GetSetupPin(char * setupPin, size_t setupPinSize, const chip::CharSpan & tempAccountIdentifierString) = 0; virtual ~Delegate() = default; }; diff --git a/src/app/clusters/account-login-server/account-login-server.cpp b/src/app/clusters/account-login-server/account-login-server.cpp index a095944282f97c..06b807b63f0abf 100644 --- a/src/app/clusters/account-login-server/account-login-server.cpp +++ b/src/app/clusters/account-login-server/account-login-server.cpp @@ -29,23 +29,39 @@ #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::AccountLogin; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using chip::app::Clusters::AccountLogin::Delegate; // ----------------------------------------------------------------------------- // Delegate Implementation -using chip::app::Clusters::AccountLogin::Delegate; - namespace { Delegate * gDelegateTable[EMBER_AF_ACCOUNT_LOGIN_CLUSTER_SERVER_ENDPOINT_COUNT] = { nullptr }; Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::AccountLogin::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "AccountLogin returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetAccountLoginDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "AccountLogin NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, AccountLogin::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_ACCOUNT_LOGIN_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -66,8 +82,9 @@ namespace AccountLogin { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::AccountLogin::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, AccountLogin::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_ACCOUNT_LOGIN_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -91,14 +108,13 @@ bool emberAfAccountLoginClusterGetSetupPINRequestCallback(app::CommandHandler * CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; auto & tempAccountIdentifier = commandData.tempAccountIdentifier; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::GetSetupPINResponse::Type response = delegate->HandleGetSetupPin(tempAccountIdentifier); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleGetSetupPin(responder, tempAccountIdentifier); } exit: diff --git a/src/app/clusters/application-basic-server/application-basic-delegate.h b/src/app/clusters/application-basic-server/application-basic-delegate.h index e2641dabbad38f..8d25382b128464 100644 --- a/src/app/clusters/application-basic-server/application-basic-delegate.h +++ b/src/app/clusters/application-basic-server/application-basic-delegate.h @@ -18,8 +18,10 @@ #pragma once +#include #include +#include #include #include @@ -28,22 +30,66 @@ namespace app { namespace Clusters { namespace ApplicationBasic { +using ApplicationBasicApplicationType = chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type; + +class DLL_EXPORT CatalogVendorApp +{ +public: + CatalogVendorApp(){}; + CatalogVendorApp(CatalogVendorApp * app) + { + catalogVendorId = app->catalogVendorId; + Platform::CopyString(applicationId, sizeof(applicationId), app->applicationId); + }; + CatalogVendorApp(uint16_t vendorId, const char * appId) { Set(vendorId, appId); }; + + bool Matches(CatalogVendorApp app) + { + std::string appId1(applicationId); + std::string appId2(app.applicationId); + + return catalogVendorId == app.catalogVendorId && appId1 == appId2; + } + + void Set(uint16_t vendorId, const char * appId) + { + catalogVendorId = vendorId; + Platform::CopyString(applicationId, sizeof(applicationId), appId); + } + + static const int kApplicationIdSize = 32; + char applicationId[kApplicationIdSize]; + uint16_t catalogVendorId; +}; + /** @brief * Defines methods for implementing application-specific logic for the Application Basic Cluster. */ class Delegate { public: - virtual chip::CharSpan HandleGetVendorName() = 0; - virtual uint16_t HandleGetVendorId() = 0; - virtual chip::CharSpan HandleGetApplicationName() = 0; - virtual uint16_t HandleGetProductId() = 0; - virtual chip::app::Clusters::ApplicationBasic::Structs::ApplicationBasicApplication::Type HandleGetApplication() = 0; - virtual ApplicationStatusEnum HandleGetStatus() = 0; - virtual chip::CharSpan HandleGetApplicationVersion() = 0; - virtual std::list HandleGetAllowedVendorList() = 0; + Delegate() : Delegate(123, "applicationId"){}; + Delegate(uint16_t szCatalogVendorId, const char * szApplicationId) : mCatalogVendorApp(szCatalogVendorId, szApplicationId){}; + + virtual CHIP_ERROR HandleGetVendorName(app::AttributeValueEncoder & aEncoder) = 0; + virtual uint16_t HandleGetVendorId() = 0; + virtual CHIP_ERROR HandleGetApplicationName(app::AttributeValueEncoder & aEncoder) = 0; + virtual uint16_t HandleGetProductId() = 0; + CHIP_ERROR HandleGetApplication(app::AttributeValueEncoder & aEncoder); + inline ApplicationStatusEnum HandleGetStatus() { return mApplicationStatus; } + virtual CHIP_ERROR HandleGetApplicationVersion(app::AttributeValueEncoder & aEncoder) = 0; + virtual CHIP_ERROR HandleGetAllowedVendorList(app::AttributeValueEncoder & aEncoder) = 0; + + inline void SetApplicationStatus(ApplicationStatusEnum status) { mApplicationStatus = status; } + bool Matches(ApplicationBasicApplication match); + + inline CatalogVendorApp * GetCatalogVendorApp() { return &mCatalogVendorApp; } virtual ~Delegate() = default; + +protected: + CatalogVendorApp mCatalogVendorApp; + ApplicationStatusEnum mApplicationStatus = ApplicationStatusEnum::kStopped; }; } // namespace ApplicationBasic diff --git a/src/app/clusters/application-basic-server/application-basic-server.cpp b/src/app/clusters/application-basic-server/application-basic-server.cpp index bf36d0f84186d6..d061b45aeb8863 100644 --- a/src/app/clusters/application-basic-server/application-basic-server.cpp +++ b/src/app/clusters/application-basic-server/application-basic-server.cpp @@ -26,6 +26,9 @@ #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include #include #include @@ -33,6 +36,9 @@ using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::ApplicationBasic; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation @@ -45,8 +51,18 @@ Delegate * gDelegateTable[EMBER_AF_APPLICATION_BASIC_CLUSTER_SERVER_ENDPOINT_COU Delegate * GetDelegate(EndpointId endpoint) { +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "ApplicationBasic returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetApplicationBasicDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "ApplicationBasic NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::ApplicationBasic::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); + return ((ep == 0xFFFF || ep >= EMBER_AF_APPLICATION_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -67,8 +83,9 @@ namespace ApplicationBasic { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::ApplicationBasic::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ApplicationBasic::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_APPLICATION_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -77,6 +94,26 @@ void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) } } +Delegate * GetDefaultDelegate(EndpointId endpoint) +{ + return GetDelegate(endpoint); +} + +CHIP_ERROR Delegate::HandleGetApplication(app::AttributeValueEncoder & aEncoder) +{ + ApplicationBasicApplicationType application; + application.catalogVendorId = mCatalogVendorApp.catalogVendorId; + application.applicationId = CharSpan(mCatalogVendorApp.applicationId, strlen(mCatalogVendorApp.applicationId)); + return aEncoder.Encode(application); +} + +bool Delegate::Matches(ApplicationBasicApplication match) +{ + std::string appId(match.applicationId.data(), match.applicationId.size()); + CatalogVendorApp matchApp(match.catalogVendorId, appId.c_str()); + return mCatalogVendorApp.Matches(matchApp); +} + } // namespace ApplicationBasic } // namespace Clusters } // namespace app @@ -90,9 +127,7 @@ namespace { class ApplicationBasicAttrAccess : public app::AttributeAccessInterface { public: - ApplicationBasicAttrAccess() : - app::AttributeAccessInterface(Optional::Missing(), chip::app::Clusters::ApplicationBasic::Id) - {} + ApplicationBasicAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), ApplicationBasic::Id) {} CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override; @@ -125,28 +160,28 @@ CHIP_ERROR ApplicationBasicAttrAccess::Read(const app::ConcreteReadAttributePath switch (aPath.mAttributeId) { - case app::Clusters::ApplicationBasic::Attributes::VendorName::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::VendorName::Id: { return ReadVendorNameAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::VendorId::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::VendorId::Id: { return ReadVendorIdAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::ApplicationName::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::ApplicationName::Id: { return ReadApplicationNameAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::ProductId::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::ProductId::Id: { return ReadProductIdAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::ApplicationApp::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::ApplicationApp::Id: { return ReadApplicationAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::ApplicationStatus::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::ApplicationStatus::Id: { return ReadStatusAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::ApplicationVersion::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::ApplicationVersion::Id: { return ReadApplicationVersionAttribute(aEncoder, delegate); } - case app::Clusters::ApplicationBasic::Attributes::AllowedVendorList::Id: { + case chip::app::Clusters::ApplicationBasic::Attributes::AllowedVendorList::Id: { return ReadAllowedVendorListAttribute(aEncoder, delegate); } default: { @@ -159,8 +194,7 @@ CHIP_ERROR ApplicationBasicAttrAccess::Read(const app::ConcreteReadAttributePath CHIP_ERROR ApplicationBasicAttrAccess::ReadVendorNameAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - chip::CharSpan vendorName = delegate->HandleGetVendorName(); - return aEncoder.Encode(vendorName); + return delegate->HandleGetVendorName(aEncoder); } CHIP_ERROR ApplicationBasicAttrAccess::ReadVendorIdAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) @@ -171,8 +205,7 @@ CHIP_ERROR ApplicationBasicAttrAccess::ReadVendorIdAttribute(app::AttributeValue CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationNameAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - chip::CharSpan applicationName = delegate->HandleGetApplicationName(); - return aEncoder.Encode(applicationName); + return delegate->HandleGetApplicationName(aEncoder); } CHIP_ERROR ApplicationBasicAttrAccess::ReadProductIdAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) @@ -183,8 +216,7 @@ CHIP_ERROR ApplicationBasicAttrAccess::ReadProductIdAttribute(app::AttributeValu CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - Structs::ApplicationBasicApplication::Type application = delegate->HandleGetApplication(); - return aEncoder.Encode(application); + return delegate->HandleGetApplication(aEncoder); } CHIP_ERROR ApplicationBasicAttrAccess::ReadStatusAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) @@ -195,20 +227,12 @@ CHIP_ERROR ApplicationBasicAttrAccess::ReadStatusAttribute(app::AttributeValueEn CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationVersionAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - chip::CharSpan applicationVersion = delegate->HandleGetApplicationVersion(); - return aEncoder.Encode(applicationVersion); + return delegate->HandleGetApplicationVersion(aEncoder); } CHIP_ERROR ApplicationBasicAttrAccess::ReadAllowedVendorListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - std::list allowedVendorList = delegate->HandleGetAllowedVendorList(); - return aEncoder.EncodeList([allowedVendorList](const auto & encoder) -> CHIP_ERROR { - for (const auto & allowedVendor : allowedVendorList) - { - ReturnErrorOnFailure(encoder.Encode(allowedVendor)); - } - return CHIP_NO_ERROR; - }); + return delegate->HandleGetAllowedVendorList(aEncoder); } } // anonymous namespace diff --git a/src/app/clusters/application-basic-server/application-basic-server.h b/src/app/clusters/application-basic-server/application-basic-server.h index 05fa4b69ce106b..5e18b868d62463 100644 --- a/src/app/clusters/application-basic-server/application-basic-server.h +++ b/src/app/clusters/application-basic-server/application-basic-server.h @@ -26,6 +26,7 @@ namespace Clusters { namespace ApplicationBasic { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); +Delegate * GetDefaultDelegate(EndpointId endpoint); } // namespace ApplicationBasic } // namespace Clusters diff --git a/src/app/clusters/application-launcher-server/application-launcher-delegate.h b/src/app/clusters/application-launcher-server/application-launcher-delegate.h index f8a7d80f56e36a..c1b608c47d6886 100644 --- a/src/app/clusters/application-launcher-server/application-launcher-delegate.h +++ b/src/app/clusters/application-launcher-server/application-launcher-delegate.h @@ -20,6 +20,8 @@ #include +#include +#include #include #include @@ -28,24 +30,44 @@ namespace app { namespace Clusters { namespace ApplicationLauncher { +using ApplicationLauncherApplicationType = chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type; +using ApplicationEPType = chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEP::Type; +using LauncherResponseType = chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type; + /** @brief * Defines methods for implementing application-specific logic for the Application Launcher Cluster. */ class Delegate { public: - virtual chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEP::Type HandleGetCurrentApp() = 0; - virtual std::list HandleGetCatalogList() = 0; + Delegate() : Delegate(false){}; + Delegate(bool featureMapContentPlatform) { mFeatureMapContentPlatform = featureMapContentPlatform; }; + + inline bool HasFeature(ApplicationLauncherFeature feature) + { + if (feature == ApplicationLauncherFeature::kApplicationPlatform) + { + return mFeatureMapContentPlatform; + } + return false; + } + + // this attribute should only be enabled for app platform instance (endpoint 1) + CHIP_ERROR HandleGetCurrentApp(app::AttributeValueEncoder & aEncoder); - virtual Commands::LauncherResponse::Type HandleLaunchApp( - const chip::CharSpan & data, - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) = 0; - virtual Commands::LauncherResponse::Type - HandleStopApp(const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) = 0; - virtual Commands::LauncherResponse::Type - HandleHideApp(const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationLauncherApplication::Type & application) = 0; + virtual CHIP_ERROR HandleGetCatalogList(app::AttributeValueEncoder & aEncoder) = 0; + + virtual void HandleLaunchApp(CommandResponseHelper & helper, const CharSpan & data, + const ApplicationLauncherApplicationType & application) = 0; + virtual void HandleStopApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) = 0; + virtual void HandleHideApp(CommandResponseHelper & helper, + const ApplicationLauncherApplicationType & application) = 0; virtual ~Delegate() = default; + +protected: + bool mFeatureMapContentPlatform = false; }; } // namespace ApplicationLauncher diff --git a/src/app/clusters/application-launcher-server/application-launcher-server.cpp b/src/app/clusters/application-launcher-server/application-launcher-server.cpp index c9a7ee0726f95d..e2cec4eca02c2b 100644 --- a/src/app/clusters/application-launcher-server/application-launcher-server.cpp +++ b/src/app/clusters/application-launcher-server/application-launcher-server.cpp @@ -22,23 +22,33 @@ ******************************************************************************* ******************************************************************************/ +#include +#include #include #include #include #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include #include using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::ApplicationLauncher; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation +using chip::app::Clusters::ApplicationBasic::CatalogVendorApp; using chip::app::Clusters::ApplicationLauncher::Delegate; +using ApplicationStatusEnum = app::Clusters::ApplicationBasic::ApplicationStatusEnum; namespace { @@ -46,8 +56,18 @@ Delegate * gDelegateTable[EMBER_AF_APPLICATION_LAUNCHER_CLUSTER_SERVER_ENDPOINT_ Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::ApplicationLauncher::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetApplicationLauncherDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "ApplicationLauncher NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ApplicationLauncher::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_APPLICATION_LAUNCHER_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -68,8 +88,9 @@ namespace ApplicationLauncher { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::ApplicationLauncher::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ApplicationLauncher::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_APPLICATION_LAUNCHER_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -78,6 +99,38 @@ void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) } } +// this attribute should only be enabled for app platform instance (endpoint 1) +CHIP_ERROR Delegate::HandleGetCurrentApp(app::AttributeValueEncoder & aEncoder) +{ +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + if (HasFeature(ApplicationLauncherFeature::kApplicationPlatform)) + { + auto & platform = ContentAppPlatform::GetInstance(); + if (platform.HasCurrentApp()) + { + ContentApp * app = platform.GetContentApp(platform.GetCurrentAppEndpointId()); + if (app != nullptr) + { + ApplicationEPType currentApp; + CatalogVendorApp * vendorApp = app->GetApplicationBasicDelegate()->GetCatalogVendorApp(); + std::string endpointStr = std::to_string(app->GetEndpointId()); + currentApp.application.catalogVendorId = vendorApp->catalogVendorId; + currentApp.application.applicationId = CharSpan(vendorApp->applicationId, strlen(vendorApp->applicationId)); + currentApp.endpoint = CharSpan(endpointStr.c_str(), endpointStr.length()); + return aEncoder.Encode(currentApp); + } + } + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + + // TODO: change to return null once 13606 is fixed + ApplicationEPType currentApp; + currentApp.application.catalogVendorId = 123; + currentApp.application.applicationId = CharSpan("applicationId", strlen("applicationId")); + currentApp.endpoint = CharSpan("endpointId", strlen("endpointId")); + return aEncoder.Encode(currentApp); +} + } // namespace ApplicationLauncher } // namespace Clusters } // namespace app @@ -91,9 +144,7 @@ namespace { class ApplicationLauncherAttrAccess : public app::AttributeAccessInterface { public: - ApplicationLauncherAttrAccess() : - app::AttributeAccessInterface(Optional::Missing(), chip::app::Clusters::ApplicationLauncher::Id) - {} + ApplicationLauncherAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), ApplicationLauncher::Id) {} CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override; @@ -137,20 +188,12 @@ CHIP_ERROR ApplicationLauncherAttrAccess::Read(const app::ConcreteReadAttributeP CHIP_ERROR ApplicationLauncherAttrAccess::ReadCatalogListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - std::list catalogList = delegate->HandleGetCatalogList(); - return aEncoder.EncodeList([catalogList](const auto & encoder) -> CHIP_ERROR { - for (const auto & catalog : catalogList) - { - ReturnErrorOnFailure(encoder.Encode(catalog)); - } - return CHIP_NO_ERROR; - }); + return delegate->HandleGetCatalogList(aEncoder); } CHIP_ERROR ApplicationLauncherAttrAccess::ReadCurrentAppAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - Structs::ApplicationEP::Type currentApp = delegate->HandleGetCurrentApp(); - return aEncoder.Encode(currentApp); + return delegate->HandleGetCurrentApp(aEncoder); } } // anonymous namespace @@ -166,14 +209,71 @@ bool emberAfApplicationLauncherClusterLaunchAppRequestCallback(app::CommandHandl EndpointId endpoint = commandPath.mEndpointId; auto & data = commandData.data; auto & application = commandData.application; + app::CommandResponseHelper responder(command, commandPath); + + std::string appId(application.applicationId.data(), application.applicationId.size()); + if (appId.length() == 0) + { + // chip-tool can't send structs from command line so treat data value as appid if appid is blank + // TODO: fix this once chip-tool support sending structs from command line + ChipLogError(Zcl, "ApplicationLauncher blank content id, taking data as appid"); + appId = std::string(data.data(), data.size()); + } + CatalogVendorApp vendorApp(application.catalogVendorId, appId.c_str()); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::LauncherResponse::Type response = delegate->HandleLaunchApp(data, application); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // if the feature flag is APP_Plaform, then this is a call to endpoint 1 to launching an app + // 1. Find target Content App and load if not loaded + // 2. Set current app to Content App + // 3. Set Content App status (basic cluster) to ACTIVE_VISIBLE_FOCUS + // 4. Call launch app command on Content App + if (delegate->HasFeature(ApplicationLauncherFeature::kApplicationPlatform)) + { + ChipLogError(Zcl, "ApplicationLauncher has content platform feature"); + ContentApp * app = ContentAppPlatform::GetInstance().LoadContentApp(vendorApp); + if (app == nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher target app not found"); + LauncherResponseType response; + response.data = CharSpan("data", strlen("data")); + response.status = StatusEnum::kAppNotAvailable; + responder.Success(response); + return true; + } + + ContentAppPlatform::GetInstance().SetCurrentApp(app); + + ChipLogError(Zcl, "ApplicationLauncher handling launch on ContentApp"); + app->GetApplicationLauncherDelegate()->HandleLaunchApp(responder, data, application); + return true; + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // otherwise, assume this is for managing status of the Content App on this endpoint + // 1. Set Content App status (basic cluster) to ACTIVE_VISIBLE_FOCUS + // 2. Call launch app command on the given endpoint + + ChipLogError(Zcl, "ApplicationLauncher no content platform feature"); + ApplicationBasic::Delegate * appBasic = ApplicationBasic::GetDefaultDelegate(endpoint); + if (appBasic != nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher setting basic cluster status to visible"); + appBasic->SetApplicationStatus(ApplicationStatusEnum::kActiveVisibleFocus); + } + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().LoadContentApp(vendorApp); + if (app != nullptr) + { + ContentAppPlatform::GetInstance().SetCurrentApp(app); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + + ChipLogError(Zcl, "ApplicationLauncher handling launch"); + delegate->HandleLaunchApp(responder, data, application); } exit: @@ -196,14 +296,67 @@ bool emberAfApplicationLauncherClusterStopAppRequestCallback(app::CommandHandler CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; auto & application = commandData.application; + app::CommandResponseHelper responder(command, commandPath); + + std::string appId(application.applicationId.data(), application.applicationId.size()); + CatalogVendorApp vendorApp(application.catalogVendorId, appId.c_str()); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::LauncherResponse::Type response = delegate->HandleStopApp(application); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // if the feature flag is APP_Plaform, then this is a call to endpoint 1 to stop an app + // 1. Find target Content App + // 3. If this was the current app then stop it + // 2. Set Content App status (basic cluster) to ACTIVE_STOPPED + // 4. Call stop app command on Content App + if (delegate->HasFeature(ApplicationLauncherFeature::kApplicationPlatform)) + { + ChipLogError(Zcl, "ApplicationLauncher has content platform feature"); + ContentApp * app = ContentAppPlatform::GetInstance().LoadContentApp(vendorApp); + if (app == nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher target app not loaded"); + LauncherResponseType response; + response.data = CharSpan("data", strlen("data")); + response.status = StatusEnum::kAppNotAvailable; + responder.Success(response); + return true; + } + + ContentAppPlatform::GetInstance().UnsetIfCurrentApp(app); + + ChipLogError(Zcl, "ApplicationLauncher setting app status"); + app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kStopped); + + ChipLogError(Zcl, "ApplicationLauncher handling stop on ContentApp"); + app->GetApplicationLauncherDelegate()->HandleStopApp(responder, application); + return true; + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // otherwise, assume this is for managing status of the Content App on this endpoint + // 1. Set Content App status (basic cluster) to ACTIVE_STOPPED + // 2. Call launch app command on the given endpoint + + ChipLogError(Zcl, "ApplicationLauncher no content platform feature"); + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(vendorApp); + if (app != nullptr) + { + ContentAppPlatform::GetInstance().UnsetIfCurrentApp(app); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + + ApplicationBasic::Delegate * appBasic = ApplicationBasic::GetDefaultDelegate(endpoint); + if (appBasic != nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher setting basic cluster status to stopped"); + appBasic->SetApplicationStatus(ApplicationStatusEnum::kStopped); + } + + delegate->HandleStopApp(responder, application); } exit: @@ -226,14 +379,64 @@ bool emberAfApplicationLauncherClusterHideAppRequestCallback(app::CommandHandler CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; auto & application = commandData.application; + app::CommandResponseHelper responder(command, commandPath); + + std::string appId(application.applicationId.data(), application.applicationId.size()); + CatalogVendorApp vendorApp(application.catalogVendorId, appId.c_str()); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::LauncherResponse::Type response = delegate->HandleHideApp(application); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // if the feature flag is APP_Plaform, then this is a call to endpoint 1 to stop an app + // 1. Find target Content App + // 3. If this was the current app then hide it + // 2. Set Content App status (basic cluster) to ACTIVE_VISIBLE_NOT_FOCUS + // 4. Call stop app command on Content App + if (delegate->HasFeature(ApplicationLauncherFeature::kApplicationPlatform)) + { + ChipLogError(Zcl, "ApplicationLauncher has content platform feature"); + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(vendorApp); + if (app == nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher target app not loaded"); + LauncherResponseType response; + response.data = CharSpan("data", strlen("data")); + response.status = StatusEnum::kAppNotAvailable; + responder.Success(response); + return true; + } + + ContentAppPlatform::GetInstance().UnsetIfCurrentApp(app); + + ChipLogError(Zcl, "ApplicationLauncher handling stop on ContentApp"); + app->GetApplicationLauncherDelegate()->HandleHideApp(responder, application); + return true; + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // otherwise, assume this is for managing status of the Content App on this endpoint + // 1. Set Content App status (basic cluster) to ACTIVE_VISIBLE_NOT_FOCUS + // 2. Call launch app command on the given endpoint + + ChipLogError(Zcl, "ApplicationLauncher no content platform feature"); + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(vendorApp); + if (app != nullptr) + { + ContentAppPlatform::GetInstance().UnsetIfCurrentApp(app); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + + ApplicationBasic::Delegate * appBasic = ApplicationBasic::GetDefaultDelegate(endpoint); + if (appBasic != nullptr) + { + ChipLogError(Zcl, "ApplicationLauncher setting basic cluster status to stopped"); + appBasic->SetApplicationStatus(ApplicationStatusEnum::kActiveHidden); + } + + delegate->HandleHideApp(responder, application); } exit: diff --git a/src/app/clusters/audio-output-server/audio-output-delegate.h b/src/app/clusters/audio-output-server/audio-output-delegate.h index daa1f0f084a6d2..46b7d2ef1b36c7 100644 --- a/src/app/clusters/audio-output-server/audio-output-delegate.h +++ b/src/app/clusters/audio-output-server/audio-output-delegate.h @@ -20,6 +20,7 @@ #include +#include #include #include @@ -34,8 +35,8 @@ namespace AudioOutput { class Delegate { public: - virtual uint8_t HandleGetCurrentOutput() = 0; - virtual std::list HandleGetOutputList() = 0; + virtual uint8_t HandleGetCurrentOutput() = 0; + virtual CHIP_ERROR HandleGetOutputList(app::AttributeValueEncoder & aEncoder) = 0; virtual bool HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) = 0; virtual bool HandleSelectOutput(const uint8_t & index) = 0; diff --git a/src/app/clusters/audio-output-server/audio-output-server.cpp b/src/app/clusters/audio-output-server/audio-output-server.cpp index 6d835d17e0232d..38ba765ad725ff 100644 --- a/src/app/clusters/audio-output-server/audio-output-server.cpp +++ b/src/app/clusters/audio-output-server/audio-output-server.cpp @@ -135,14 +135,7 @@ CHIP_ERROR AudioOutputAttrAccess::Read(const app::ConcreteReadAttributePath & aP CHIP_ERROR AudioOutputAttrAccess::ReadOutputListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - std::list outputList = delegate->HandleGetOutputList(); - return aEncoder.EncodeList([outputList](const auto & encoder) -> CHIP_ERROR { - for (const auto & output : outputList) - { - ReturnErrorOnFailure(encoder.Encode(output)); - } - return CHIP_NO_ERROR; - }); + return delegate->HandleGetOutputList(aEncoder); } CHIP_ERROR AudioOutputAttrAccess::ReadCurrentOutputAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) diff --git a/src/app/clusters/channel-server/channel-delegate.h b/src/app/clusters/channel-server/channel-delegate.h index 6c382bb83dd09b..4845858cc490a3 100644 --- a/src/app/clusters/channel-server/channel-delegate.h +++ b/src/app/clusters/channel-server/channel-delegate.h @@ -39,10 +39,10 @@ class Delegate virtual CHIP_ERROR HandleGetLineup(app::AttributeValueEncoder & aEncoder) = 0; virtual CHIP_ERROR HandleGetCurrentChannel(app::AttributeValueEncoder & aEncoder) = 0; - virtual void HandleChangeChannel(const chip::CharSpan & match, - CommandResponseHelper & responser) = 0; - virtual bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) = 0; - virtual bool HandleSkipChannel(const uint16_t & count) = 0; + virtual void HandleChangeChannel(CommandResponseHelper & helper, + const chip::CharSpan & match) = 0; + virtual bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) = 0; + virtual bool HandleSkipChannel(const uint16_t & count) = 0; virtual ~Delegate() = default; }; diff --git a/src/app/clusters/channel-server/channel-server.cpp b/src/app/clusters/channel-server/channel-server.cpp index 2482503f5d9c0a..9ec8401090a082 100644 --- a/src/app/clusters/channel-server/channel-server.cpp +++ b/src/app/clusters/channel-server/channel-server.cpp @@ -41,13 +41,20 @@ #include #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include #include #include #include using namespace chip; +using namespace chip::app::Clusters; using namespace chip::app::Clusters::Channel; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation @@ -60,8 +67,18 @@ Delegate * gDelegateTable[EMBER_AF_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT] = { nu Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::Channel::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "Channel returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetChannelDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "Channel NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, Channel::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -82,8 +99,9 @@ namespace Channel { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::Channel::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, Channel::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -105,7 +123,7 @@ namespace { class ChannelAttrAccess : public app::AttributeAccessInterface { public: - ChannelAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), chip::app::Clusters::Channel::Id) {} + ChannelAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), Channel::Id) {} CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override; @@ -189,7 +207,7 @@ bool emberAfChannelClusterChangeChannelRequestCallback(app::CommandHandler * com Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - delegate->HandleChangeChannel(match, responder); + delegate->HandleChangeChannel(responder, match); } exit: diff --git a/src/app/clusters/content-launch-server/content-launch-delegate.h b/src/app/clusters/content-launch-server/content-launch-delegate.h index 766f8aff26907a..a8b6e955344dfb 100644 --- a/src/app/clusters/content-launch-server/content-launch-delegate.h +++ b/src/app/clusters/content-launch-server/content-launch-delegate.h @@ -37,12 +37,11 @@ namespace ContentLauncher { class Delegate { public: - virtual void HandleLaunchContent(const std::list & parameterList, bool autoplay, const chip::CharSpan & data, - CommandResponseHelper & responser) = 0; + virtual void HandleLaunchContent(CommandResponseHelper & helper, + const std::list & parameterList, bool autoplay, const CharSpan & data) = 0; - virtual void HandleLaunchUrl(const chip::CharSpan & contentUrl, const chip::CharSpan & displayString, - const std::list & brandingInformation, - CommandResponseHelper & responser) = 0; + virtual void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, + const CharSpan & displayString, const std::list & brandingInformation) = 0; virtual CHIP_ERROR HandleGetAcceptHeaderList(app::AttributeValueEncoder & aEncoder) = 0; diff --git a/src/app/clusters/content-launch-server/content-launch-server.cpp b/src/app/clusters/content-launch-server/content-launch-server.cpp index b70efd7b220672..7b8f932a883675 100644 --- a/src/app/clusters/content-launch-server/content-launch-server.cpp +++ b/src/app/clusters/content-launch-server/content-launch-server.cpp @@ -44,13 +44,21 @@ #include #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include +#include #include #include using namespace chip; using namespace chip::app; +using namespace chip::app::Clusters; using namespace chip::app::Clusters::ContentLauncher; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation @@ -63,8 +71,18 @@ Delegate * gDelegateTable[EMBER_AF_CONTENT_LAUNCH_CLUSTER_SERVER_ENDPOINT_COUNT] Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::ContentLauncher::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "Content Launcher returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetContentLauncherDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "Content Launcher NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ContentLauncher::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_CONTENT_LAUNCH_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -83,10 +101,11 @@ namespace app { namespace Clusters { namespace ContentLauncher { -void SetDelegate(EndpointId endpoint, Delegate * delegate) +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::ContentLauncher::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ContentLauncher::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_CONTENT_LAUNCH_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -108,9 +127,7 @@ namespace { class ContentLauncherAttrAccess : public app::AttributeAccessInterface { public: - ContentLauncherAttrAccess() : - app::AttributeAccessInterface(Optional::Missing(), chip::app::Clusters::ContentLauncher::Id) - {} + ContentLauncherAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), ContentLauncher::Id) {} CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override; @@ -170,8 +187,8 @@ CHIP_ERROR ContentLauncherAttrAccess::ReadSupportedStreamingProtocolsAttribute(a // Matter Framework Callbacks Implementation bool emberAfContentLauncherClusterLaunchContentRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ContentLauncher::Commands::LaunchContentRequest::DecodableType & commandData) + CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const ContentLauncher::Commands::LaunchContentRequest::DecodableType & commandData) { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; @@ -187,7 +204,7 @@ bool emberAfContentLauncherClusterLaunchContentRequestCallback( Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - delegate->HandleLaunchContent(parameterList, autoplay, data, responder); + delegate->HandleLaunchContent(responder, parameterList, autoplay, data); } exit: @@ -206,8 +223,8 @@ bool emberAfContentLauncherClusterLaunchContentRequestCallback( } bool emberAfContentLauncherClusterLaunchURLRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ContentLauncher::Commands::LaunchURLRequest::DecodableType & commandData) + CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const ContentLauncher::Commands::LaunchURLRequest::DecodableType & commandData) { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; @@ -223,7 +240,7 @@ bool emberAfContentLauncherClusterLaunchURLRequestCallback( Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - delegate->HandleLaunchUrl(contentUrl, displayString, brandingInformationList, responder); + delegate->HandleLaunchUrl(responder, contentUrl, displayString, brandingInformationList); } exit: diff --git a/src/app/clusters/content-launch-server/content-launch-server.h b/src/app/clusters/content-launch-server/content-launch-server.h index b41472a3af1a35..42401858a9cd01 100644 --- a/src/app/clusters/content-launch-server/content-launch-server.h +++ b/src/app/clusters/content-launch-server/content-launch-server.h @@ -25,7 +25,7 @@ namespace app { namespace Clusters { namespace ContentLauncher { -void SetDelegate(EndpointId endpoint, Delegate * delegate); +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); } // namespace ContentLauncher } // namespace Clusters diff --git a/src/app/clusters/keypad-input-server/keypad-input-delegate.h b/src/app/clusters/keypad-input-server/keypad-input-delegate.h index 633b9a4cfa2f87..24fd57573eff0a 100644 --- a/src/app/clusters/keypad-input-server/keypad-input-delegate.h +++ b/src/app/clusters/keypad-input-server/keypad-input-delegate.h @@ -20,6 +20,7 @@ #include +#include #include namespace chip { @@ -33,7 +34,7 @@ namespace KeypadInput { class Delegate { public: - virtual Commands::SendKeyResponse::Type HandleSendKey(const CecKeyCode & keyCode) = 0; + virtual void HandleSendKey(CommandResponseHelper & helper, const CecKeyCode & keyCode) = 0; virtual ~Delegate() = default; }; diff --git a/src/app/clusters/keypad-input-server/keypad-input-server.cpp b/src/app/clusters/keypad-input-server/keypad-input-server.cpp index bd97df20f97fc1..c908a5de90f0de 100644 --- a/src/app/clusters/keypad-input-server/keypad-input-server.cpp +++ b/src/app/clusters/keypad-input-server/keypad-input-server.cpp @@ -26,11 +26,17 @@ #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::KeypadInput; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation @@ -43,8 +49,18 @@ Delegate * gDelegateTable[EMBER_AF_KEYPAD_INPUT_CLUSTER_SERVER_ENDPOINT_COUNT] = Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::KeypadInput::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "KeypadInput returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetKeypadInputDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "KeypadInput NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, KeypadInput::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_KEYPAD_INPUT_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -65,8 +81,9 @@ namespace KeypadInput { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::KeypadInput::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, KeypadInput::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_KEYPAD_INPUT_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -89,13 +106,12 @@ bool emberAfKeypadInputClusterSendKeyRequestCallback(app::CommandHandler * comma CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; auto & keyCode = commandData.keyCode; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::SendKeyResponse::Type response = delegate->HandleSendKey(keyCode); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleSendKey(responder, keyCode); } exit: diff --git a/src/app/clusters/media-playback-server/media-playback-delegate.h b/src/app/clusters/media-playback-server/media-playback-delegate.h index ed7b43d1b3b98f..6634a814c16470 100644 --- a/src/app/clusters/media-playback-server/media-playback-delegate.h +++ b/src/app/clusters/media-playback-server/media-playback-delegate.h @@ -20,6 +20,8 @@ #include +#include +#include #include #include @@ -34,25 +36,28 @@ namespace MediaPlayback { class Delegate { public: - virtual PlaybackStateEnum HandleGetCurrentState() = 0; - virtual uint64_t HandleGetStartTime() = 0; - virtual uint64_t HandleGetDuration() = 0; - virtual Structs::PlaybackPosition::Type HandleGetSampledPosition() = 0; - virtual float HandleGetPlaybackSpeed() = 0; - virtual uint64_t HandleGetSeekRangeStart() = 0; - virtual uint64_t HandleGetSeekRangeEnd() = 0; - - virtual Commands::PlaybackResponse::Type HandlePlay() = 0; - virtual Commands::PlaybackResponse::Type HandlePause() = 0; - virtual Commands::PlaybackResponse::Type HandleStop() = 0; - virtual Commands::PlaybackResponse::Type HandleFastForward() = 0; - virtual Commands::PlaybackResponse::Type HandlePrevious() = 0; - virtual Commands::PlaybackResponse::Type HandleRewind() = 0; - virtual Commands::PlaybackResponse::Type HandleSkipBackward(const uint64_t & deltaPositionMilliseconds) = 0; - virtual Commands::PlaybackResponse::Type HandleSkipForward(const uint64_t & deltaPositionMilliseconds) = 0; - virtual Commands::PlaybackResponse::Type HandleSeekRequest(const uint64_t & positionMilliseconds) = 0; - virtual Commands::PlaybackResponse::Type HandleNext() = 0; - virtual Commands::PlaybackResponse::Type HandleStartOverRequest() = 0; + virtual PlaybackStateEnum HandleGetCurrentState() = 0; + virtual uint64_t HandleGetStartTime() = 0; + virtual uint64_t HandleGetDuration() = 0; + virtual CHIP_ERROR HandleGetSampledPosition(app::AttributeValueEncoder & aEncoder) = 0; + virtual float HandleGetPlaybackSpeed() = 0; + virtual uint64_t HandleGetSeekRangeStart() = 0; + virtual uint64_t HandleGetSeekRangeEnd() = 0; + + virtual void HandlePlay(CommandResponseHelper & helper) = 0; + virtual void HandlePause(CommandResponseHelper & helper) = 0; + virtual void HandleStop(CommandResponseHelper & helper) = 0; + virtual void HandleFastForward(CommandResponseHelper & helper) = 0; + virtual void HandlePrevious(CommandResponseHelper & helper) = 0; + virtual void HandleRewind(CommandResponseHelper & helper) = 0; + virtual void HandleSkipBackward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) = 0; + virtual void HandleSkipForward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) = 0; + virtual void HandleSeekRequest(CommandResponseHelper & helper, + const uint64_t & positionMilliseconds) = 0; + virtual void HandleNext(CommandResponseHelper & helper) = 0; + virtual void HandleStartOverRequest(CommandResponseHelper & helper) = 0; virtual ~Delegate() = default; }; diff --git a/src/app/clusters/media-playback-server/media-playback-server.cpp b/src/app/clusters/media-playback-server/media-playback-server.cpp index 38746abdf612b5..9a22d9cf42d6c8 100644 --- a/src/app/clusters/media-playback-server/media-playback-server.cpp +++ b/src/app/clusters/media-playback-server/media-playback-server.cpp @@ -28,12 +28,18 @@ #include #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include #include using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::MediaPlayback; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation @@ -46,8 +52,18 @@ Delegate * gDelegateTable[EMBER_AF_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT] Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::MediaPlayback::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "MediaPlayback returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetMediaPlaybackDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "MediaPlayback NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, MediaPlayback::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -68,8 +84,9 @@ namespace MediaPlayback { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::MediaPlayback::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, MediaPlayback::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -91,9 +108,7 @@ namespace { class MediaPlaybackAttrAccess : public app::AttributeAccessInterface { public: - MediaPlaybackAttrAccess() : - app::AttributeAccessInterface(Optional::Missing(), chip::app::Clusters::MediaPlayback::Id) - {} + MediaPlaybackAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), MediaPlayback::Id) {} CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override; @@ -152,7 +167,7 @@ CHIP_ERROR MediaPlaybackAttrAccess::Read(const app::ConcreteReadAttributePath & CHIP_ERROR MediaPlaybackAttrAccess::ReadCurrentStateAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - chip::app::Clusters::MediaPlayback::PlaybackStateEnum currentState = delegate->HandleGetCurrentState(); + MediaPlayback::PlaybackStateEnum currentState = delegate->HandleGetCurrentState(); return aEncoder.Encode(currentState); } @@ -170,8 +185,7 @@ CHIP_ERROR MediaPlaybackAttrAccess::ReadDurationAttribute(app::AttributeValueEnc CHIP_ERROR MediaPlaybackAttrAccess::ReadSampledPositionAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - Structs::PlaybackPosition::Type sampledPosition = delegate->HandleGetSampledPosition(); - return aEncoder.Encode(sampledPosition); + return delegate->HandleGetSampledPosition(aEncoder); } CHIP_ERROR MediaPlaybackAttrAccess::ReadPlaybackSpeedAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) @@ -202,14 +216,13 @@ bool emberAfMediaPlaybackClusterPlayRequestCallback(app::CommandHandler * comman { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandlePlay(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandlePlay(responder); } exit: @@ -227,14 +240,13 @@ bool emberAfMediaPlaybackClusterPauseRequestCallback(app::CommandHandler * comma { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandlePause(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandlePause(responder); } exit: @@ -252,14 +264,13 @@ bool emberAfMediaPlaybackClusterStopRequestCallback(app::CommandHandler * comman { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleStop(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleStop(responder); } exit: @@ -278,14 +289,13 @@ bool emberAfMediaPlaybackClusterFastForwardRequestCallback(app::CommandHandler * { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleFastForward(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleFastForward(responder); } exit: @@ -303,14 +313,13 @@ bool emberAfMediaPlaybackClusterPreviousRequestCallback(app::CommandHandler * co { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandlePrevious(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandlePrevious(responder); } exit: @@ -328,14 +337,13 @@ bool emberAfMediaPlaybackClusterRewindRequestCallback(app::CommandHandler * comm { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleRewind(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleRewind(responder); } exit: @@ -354,6 +362,7 @@ bool emberAfMediaPlaybackClusterSkipBackwardRequestCallback(app::CommandHandler { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); auto & deltaPositionMilliseconds = commandData.deltaPositionMilliseconds; @@ -361,9 +370,7 @@ bool emberAfMediaPlaybackClusterSkipBackwardRequestCallback(app::CommandHandler VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleSkipBackward(deltaPositionMilliseconds); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleSkipBackward(responder, deltaPositionMilliseconds); } exit: @@ -383,14 +390,13 @@ bool emberAfMediaPlaybackClusterSkipForwardRequestCallback(app::CommandHandler * CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; auto & deltaPositionMilliseconds = commandData.deltaPositionMilliseconds; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleSkipForward(deltaPositionMilliseconds); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleSkipForward(responder, deltaPositionMilliseconds); } exit: @@ -409,14 +415,13 @@ bool emberAfMediaPlaybackClusterSeekRequestCallback(app::CommandHandler * comman CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; auto & positionMilliseconds = commandData.position; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleSeekRequest(positionMilliseconds); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleSeekRequest(responder, positionMilliseconds); } exit: @@ -434,14 +439,13 @@ bool emberAfMediaPlaybackClusterNextRequestCallback(app::CommandHandler * comman { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleNext(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleNext(responder); } exit: @@ -460,14 +464,13 @@ bool emberAfMediaPlaybackClusterStartOverRequestCallback(app::CommandHandler * c { CHIP_ERROR err = CHIP_NO_ERROR; EndpointId endpoint = commandPath.mEndpointId; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::PlaybackResponse::Type response = delegate->HandleStartOverRequest(); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleStartOverRequest(responder); } exit: diff --git a/src/app/clusters/target-navigator-server/target-navigator-delegate.h b/src/app/clusters/target-navigator-server/target-navigator-delegate.h index 5c2de2a23d7287..0dd47f56d4de85 100644 --- a/src/app/clusters/target-navigator-server/target-navigator-delegate.h +++ b/src/app/clusters/target-navigator-server/target-navigator-delegate.h @@ -20,6 +20,8 @@ #include +#include +#include #include #include @@ -34,9 +36,10 @@ namespace TargetNavigator { class Delegate { public: - virtual std::list HandleGetTargetList() = 0; - virtual uint8_t HandleGetCurrentTarget() = 0; - virtual Commands::NavigateTargetResponse::Type HandleNavigateTarget(const uint64_t & target, const chip::CharSpan & data) = 0; + virtual CHIP_ERROR HandleGetTargetList(app::AttributeValueEncoder & aEncoder) = 0; + virtual uint8_t HandleGetCurrentTarget() = 0; + virtual void HandleNavigateTarget(CommandResponseHelper & helper, + const uint64_t & target, const CharSpan & data) = 0; virtual ~Delegate() = default; }; diff --git a/src/app/clusters/target-navigator-server/target-navigator-server.cpp b/src/app/clusters/target-navigator-server/target-navigator-server.cpp index d8507acf3f19d9..505fe5f4a9b947 100644 --- a/src/app/clusters/target-navigator-server/target-navigator-server.cpp +++ b/src/app/clusters/target-navigator-server/target-navigator-server.cpp @@ -28,12 +28,18 @@ #include #include #include +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED #include #include using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::TargetNavigator; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED // ----------------------------------------------------------------------------- // Delegate Implementation @@ -46,8 +52,18 @@ Delegate * gDelegateTable[EMBER_AF_TARGET_NAVIGATOR_CLUSTER_SERVER_ENDPOINT_COUN Delegate * GetDelegate(EndpointId endpoint) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::TargetNavigator::Id); - return (ep == 0xFFFF ? NULL : gDelegateTable[ep]); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogError(Zcl, "TargetNavigator returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + return app->GetTargetNavigatorDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogError(Zcl, "TargetNavigator NOT returning ContentApp delegate for endpoint:%" PRIu16, endpoint); + + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, TargetNavigator::Id); + return ((ep == 0xFFFF || ep >= EMBER_AF_TARGET_NAVIGATOR_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr : gDelegateTable[ep]); } bool isDelegateNull(Delegate * delegate, EndpointId endpoint) @@ -68,8 +84,9 @@ namespace TargetNavigator { void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) { - uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, chip::app::Clusters::TargetNavigator::Id); - if (ep != 0xFFFF) + uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, TargetNavigator::Id); + // if endpoint is found and is not a dynamic endpoint + if (ep != 0xFFFF && ep < EMBER_AF_TARGET_NAVIGATOR_CLUSTER_SERVER_ENDPOINT_COUNT) { gDelegateTable[ep] = delegate; } @@ -91,9 +108,7 @@ namespace { class TargetNavigatorAttrAccess : public app::AttributeAccessInterface { public: - TargetNavigatorAttrAccess() : - app::AttributeAccessInterface(Optional::Missing(), chip::app::Clusters::TargetNavigator::Id) - {} + TargetNavigatorAttrAccess() : app::AttributeAccessInterface(Optional::Missing(), TargetNavigator::Id) {} CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override; @@ -137,14 +152,7 @@ CHIP_ERROR TargetNavigatorAttrAccess::Read(const app::ConcreteReadAttributePath CHIP_ERROR TargetNavigatorAttrAccess::ReadTargetListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) { - std::list targetList = delegate->HandleGetTargetList(); - return aEncoder.EncodeList([targetList](const auto & encoder) -> CHIP_ERROR { - for (const auto & target : targetList) - { - ReturnErrorOnFailure(encoder.Encode(target)); - } - return CHIP_NO_ERROR; - }); + return delegate->HandleGetTargetList(aEncoder); } CHIP_ERROR TargetNavigatorAttrAccess::ReadCurrentTargetAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) @@ -166,14 +174,13 @@ bool emberAfTargetNavigatorClusterNavigateTargetRequestCallback(app::CommandHand EndpointId endpoint = commandPath.mEndpointId; auto & target = commandData.target; auto & data = commandData.data; + app::CommandResponseHelper responder(command, commandPath); Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - Commands::NavigateTargetResponse::Type response = delegate->HandleNavigateTarget(target, data); - err = command->AddResponseData(commandPath, response); - SuccessOrExit(err); + delegate->HandleNavigateTarget(responder, target, data); } exit: diff --git a/src/app/util/ContentApp.cpp b/src/app/util/ContentApp.cpp deleted file mode 100644 index a7566882e8300d..00000000000000 --- a/src/app/util/ContentApp.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace chip; -using namespace chip::AppPlatform; - -namespace chip { -namespace AppPlatform { - -#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) -#define ZCL_APPLICATION_BASIC_CLUSTER_REVISION (1u) - -EmberAfStatus ContentApp::HandleReadAttribute(ClusterId clusterId, chip::AttributeId attributeId, uint8_t * buffer, - uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "Read Attribute for device %s cluster %d attribute=%d)", - GetApplicationBasic()->GetApplicationName(), static_cast(clusterId), - static_cast(attributeId)); - - EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; - if (clusterId == ZCL_APPLICATION_BASIC_CLUSTER_ID) - { - ret = GetApplicationBasic()->HandleReadAttribute(attributeId, buffer, maxReadLength); - } - if (clusterId == ZCL_ACCOUNT_LOGIN_CLUSTER_ID) - { - ret = GetAccountLogin()->HandleReadAttribute(attributeId, buffer, maxReadLength); - } - return ret; -} - -EmberAfStatus ContentApp::HandleWriteAttribute(ClusterId clusterId, chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "Read Attribute for device %s cluster %d attribute=%d)", - GetApplicationBasic()->GetApplicationName(), static_cast(clusterId), - static_cast(attributeId)); - - EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; - - if (clusterId == ZCL_APPLICATION_BASIC_CLUSTER_ID) - { - ret = GetApplicationBasic()->HandleWriteAttribute(attributeId, buffer); - } - if (clusterId == ZCL_ACCOUNT_LOGIN_CLUSTER_ID) - { - ret = GetAccountLogin()->HandleWriteAttribute(attributeId, buffer); - } - return ret; -} - -EmberAfStatus ApplicationBasic::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "ApplicationBasic::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - - if ((attributeId == ZCL_APPLICATION_VENDOR_NAME_ATTRIBUTE_ID) && (maxReadLength == 32)) - { - uint8_t bufferMemory[254]; - MutableByteSpan zclString(bufferMemory); - MakeZclCharString(zclString, GetVendorName()); - buffer = zclString.data(); - } - else if ((attributeId == ZCL_APPLICATION_VENDOR_ID_ATTRIBUTE_ID) && (maxReadLength == 1)) - { - *(uint16_t *) buffer = GetVendorId(); - } - else if ((attributeId == ZCL_APPLICATION_NAME_ATTRIBUTE_ID) && (maxReadLength == 32)) - { - uint8_t bufferMemory[254]; - MutableByteSpan zclString(bufferMemory); - MakeZclCharString(zclString, GetApplicationName()); - buffer = zclString.data(); - } - else if ((attributeId == ZCL_APPLICATION_PRODUCT_ID_ATTRIBUTE_ID) && (maxReadLength == 1)) - { - *(uint16_t *) buffer = GetProductId(); - } - else if ((attributeId == ZCL_APPLICATION_STATUS_ATTRIBUTE_ID) && (maxReadLength == 1)) - { - *buffer = (uint8_t) GetApplicationStatus(); - } - else if ((attributeId == ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID) && (maxReadLength == 2)) - { - *buffer = (uint16_t) ZCL_APPLICATION_BASIC_CLUSTER_REVISION; - } - else - { - return EMBER_ZCL_STATUS_FAILURE; - } - - return EMBER_ZCL_STATUS_SUCCESS; -} - -EmberAfStatus ApplicationBasic::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "ApplicationBasic::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - - if (attributeId == ZCL_APPLICATION_STATUS_ATTRIBUTE_ID) - { - if (*buffer) - { - SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kActiveVisibleFocus); - } - else - { - SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kActiveVisibleNotFocus); - } - } - else - { - return EMBER_ZCL_STATUS_FAILURE; - } - - return EMBER_ZCL_STATUS_SUCCESS; -} - -EmberAfStatus AccountLogin::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "AccountLogin::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus AccountLogin::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "AccountLogin::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus KeypadInput::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "KeypadInput::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus KeypadInput::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "KeypadInput::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus ApplicationLauncher::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "ApplicationLauncher::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus ApplicationLauncher::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "ApplicationLauncher::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus ContentLauncher::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "ContentLauncher::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus ContentLauncher::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "ContentLauncher::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus MediaPlayback::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "MediaPlayback::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus MediaPlayback::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "MediaPlayback::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -TargetNavigator::TargetNavigator(std::list targets, uint8_t currentTarget) -{ - mTargets = targets; - mCurrentTarget = currentTarget; -} - -CHIP_ERROR TargetNavigator::GetTargetInfoList(chip::app::AttributeValueEncoder & aEncoder) -{ - ChipLogProgress(DeviceLayer, "TargetNavigator: GetTargetInfoList "); - - return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { - int i = 0; - for (std::string entry : mTargets) - { - // ReturnErrorOnFailure(encoder.Encode(chip::CharSpan(entry.c_str(), entry.length()))); - - chip::app::Clusters::TargetNavigator::Structs::TargetInfo::Type targetInfo; - targetInfo.name = chip::CharSpan(entry.c_str(), entry.length()); - targetInfo.identifier = static_cast(i++); - ReturnErrorOnFailure(encoder.Encode(targetInfo)); - } - return CHIP_NO_ERROR; - }); -} - -app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type TargetNavigator::NavigateTarget(uint8_t target, - std::string data) -{ - ChipLogProgress(DeviceLayer, "TargetNavigator: NavigateTarget target=%d data=\"%s\"", target, data.c_str()); - - app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type response; - response.data = chip::CharSpan::fromCharString("data response"); - - if (target >= mTargets.size()) - { - response.status = app::Clusters::TargetNavigator::StatusEnum::kAppNotAvailable; - } - else - { - response.status = app::Clusters::TargetNavigator::StatusEnum::kSuccess; - mCurrentTarget = target; - } - return response; -} - -EmberAfStatus TargetNavigator::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "TargetNavigator::HandleReadAttribute: attrId=%d, maxReadLength=%d", - static_cast(attributeId), maxReadLength); - - if ((attributeId == ZCL_TARGET_NAVIGATOR_CURRENT_TARGET_ATTRIBUTE_ID) && (maxReadLength == 1)) - { - *(uint8_t *) buffer = mCurrentTarget; - } - else - { - return EMBER_ZCL_STATUS_FAILURE; - } - - return EMBER_ZCL_STATUS_SUCCESS; -} - -EmberAfStatus TargetNavigator::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "TargetNavigator::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus Channel::HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) -{ - ChipLogProgress(DeviceLayer, "Channel::HandleReadAttribute: attrId=%d, maxReadLength=%d", static_cast(attributeId), - maxReadLength); - return EMBER_ZCL_STATUS_FAILURE; -} - -EmberAfStatus Channel::HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) -{ - ChipLogProgress(DeviceLayer, "Channel::HandleWriteAttribute: attrId=%d", static_cast(attributeId)); - return EMBER_ZCL_STATUS_FAILURE; -} - -} // namespace AppPlatform -} // namespace chip diff --git a/src/app/util/ContentApp.h b/src/app/util/ContentApp.h deleted file mode 100644 index a931aeb4d0c343..00000000000000 --- a/src/app/util/ContentApp.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * - * Copyright (c) 2021 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. - */ - -/** - * @brief Manages Content Apps - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace chip { -namespace AppPlatform { - -class DLL_EXPORT ContentAppCluster -{ -public: - virtual ~ContentAppCluster() = default; - - virtual EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) = 0; - virtual EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) = 0; -}; - -class DLL_EXPORT ApplicationBasic : public ContentAppCluster -{ -public: - virtual ~ApplicationBasic() = default; - - virtual const char * GetVendorName() = 0; - virtual uint16_t GetVendorId() = 0; - virtual const char * GetApplicationName() = 0; - virtual uint16_t GetProductId() = 0; - virtual app::Clusters::ApplicationBasic::ApplicationStatusEnum GetApplicationStatus() = 0; - virtual const char * GetApplicationVersion() = 0; - virtual void SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum applicationStatus) = 0; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT AccountLogin : public ContentAppCluster -{ -public: - virtual ~AccountLogin() = default; - - virtual void SetSetupPIN(uint32_t setupPIN) = 0; - virtual uint32_t GetSetupPIN(const char * tempAccountId) = 0; - virtual bool Login(const char * tempAccountId, uint32_t setupPin) = 0; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT KeypadInput : public ContentAppCluster -{ -public: - virtual ~KeypadInput() = default; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT ApplicationLauncher : public ContentAppCluster -{ -public: - virtual ~ApplicationLauncher() = default; - - virtual app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type - LaunchApp(ApplicationLauncherApplication application, std::string data) = 0; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT ContentLauncher : public ContentAppCluster -{ -public: - virtual ~ContentLauncher() = default; - - virtual app::Clusters::ContentLauncher::Commands::LaunchResponse::Type LaunchContent(std::list parameterList, - bool autoplay, std::string data) = 0; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT MediaPlayback : public ContentAppCluster -{ -public: - virtual ~MediaPlayback() = default; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT TargetNavigator : public ContentAppCluster -{ -public: - TargetNavigator(std::list targets, uint8_t currentTarget); - virtual ~TargetNavigator() = default; - - app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type NavigateTarget(uint8_t target, std::string data); - CHIP_ERROR GetTargetInfoList(chip::app::AttributeValueEncoder & aEncoder); - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; - -protected: - std::list mTargets; - uint8_t mCurrentTarget; -}; - -class DLL_EXPORT Channel : public ContentAppCluster -{ -public: - virtual ~Channel() = default; - - EmberAfStatus HandleReadAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) override; - EmberAfStatus HandleWriteAttribute(chip::AttributeId attributeId, uint8_t * buffer) override; -}; - -class DLL_EXPORT ContentApp -{ -public: - virtual ~ContentApp() = default; - - inline void SetEndpointId(chip::EndpointId id) { mEndpointId = id; }; - inline chip::EndpointId GetEndpointId() { return mEndpointId; }; - - virtual ApplicationBasic * GetApplicationBasic() = 0; - virtual AccountLogin * GetAccountLogin() = 0; - virtual KeypadInput * GetKeypadInput() = 0; - virtual ApplicationLauncher * GetApplicationLauncher() = 0; - virtual ContentLauncher * GetContentLauncher() = 0; - virtual MediaPlayback * GetMediaPlayback() = 0; - virtual TargetNavigator * GetTargetNavigator() = 0; - virtual Channel * GetChannel() = 0; - - EmberAfStatus HandleReadAttribute(ClusterId clusterId, chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength); - EmberAfStatus HandleWriteAttribute(ClusterId clusterId, chip::AttributeId attributeId, uint8_t * buffer); - -protected: - chip::EndpointId mEndpointId = 0; -}; - -} // namespace AppPlatform -} // namespace chip diff --git a/src/app/util/ContentAppPlatform.cpp b/src/app/util/ContentAppPlatform.cpp deleted file mode 100644 index e0a2951e230704..00000000000000 --- a/src/app/util/ContentAppPlatform.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace chip; -using namespace chip::AppPlatform; - -#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - -// Device Version for dynamic endpoints: -#define DEVICE_VERSION_DEFAULT 1 - -EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, - EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, - uint16_t maxReadLength) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - - ChipLogProgress(DeviceLayer, "emberAfExternalAttributeReadCallback endpoint %d ", endpointIndex); - - EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; - - ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetContentAppByEndpointId(endpoint); - if (app != NULL) - { - ret = app->HandleReadAttribute(clusterId, attributeMetadata->attributeId, buffer, maxReadLength); - } - - return ret; -} - -EmberAfStatus emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, - EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - - ChipLogProgress(DeviceLayer, "emberAfExternalAttributeWriteCallback endpoint %d ", endpointIndex); - - EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; - - ContentApp * app = chip::AppPlatform::AppPlatform::GetInstance().GetContentAppByEndpointId(endpoint); - if (app != NULL) - { - ret = app->HandleWriteAttribute(clusterId, attributeMetadata->attributeId, buffer); - } - - return ret; -} - -namespace chip { -namespace AppPlatform { - -int AppPlatform::AddContentApp(ContentApp * app, EmberAfEndpointType * ep, uint16_t deviceType) -{ - ChipLogProgress(DeviceLayer, "Adding device %s ", app->GetApplicationBasic()->GetApplicationName()); - uint8_t index = 0; - // check if already loaded - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - if (mContentApps[index] == app) - { - ChipLogProgress(DeviceLayer, "Already added"); - return index; - } - index++; - } - - index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - if (NULL == mContentApps[index]) - { - mContentApps[index] = app; - EmberAfStatus ret; - while (1) - { - ret = emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, deviceType, DEVICE_VERSION_DEFAULT); - if (ret == EMBER_ZCL_STATUS_SUCCESS) - { - ChipLogProgress(DeviceLayer, "Added device %s to dynamic endpoint %d (index=%d)", - app->GetApplicationBasic()->GetApplicationName(), mCurrentEndpointId, index); - app->SetEndpointId(mCurrentEndpointId); - return index; - } - else if (ret != EMBER_ZCL_STATUS_DUPLICATE_EXISTS) - { - ChipLogProgress(DeviceLayer, "Adding device error=%d", ret); - return -1; - } - // Handle wrap condition - if (++mCurrentEndpointId < mFirstDynamicEndpointId) - { - mCurrentEndpointId = mFirstDynamicEndpointId; - } - } - } - index++; - } - ChipLogProgress(DeviceLayer, "Failed to add dynamic endpoint: No endpoints available!"); - return -1; -} - -int AppPlatform::RemoveContentApp(ContentApp * app) -{ - uint8_t index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - if (mContentApps[index] == app) - { - EndpointId ep = emberAfClearDynamicEndpoint(index); - mContentApps[index] = NULL; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", - app->GetApplicationBasic()->GetApplicationName(), ep, index); - // Silence complaints about unused ep when progress logging - // disabled. - UNUSED_VAR(ep); - return index; - } - index++; - } - return -1; -} - -void AppPlatform::SetupAppPlatform() -{ - ChipLogProgress(DeviceLayer, "AppPlatform::SetupAppPlatform()"); - - // Clear out the device database - uint8_t index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - mContentApps[index] = NULL; - index++; - } - - // Set starting endpoint id where dynamic endpoints will be assigned, which - // will be the next consecutive endpoint id after the last fixed endpoint. - mFirstDynamicEndpointId = static_cast( - static_cast(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1))) + 1); - mCurrentEndpointId = mFirstDynamicEndpointId; - - { - for (int i = 0; i < emberAfFixedEndpointCount(); i++) - { - ChipLogProgress(DeviceLayer, "endpoint index=%d, id=%d", i, - static_cast(static_cast(emberAfEndpointFromIndex(static_cast(i))))); - } - } - - if (mCurrentEndpointId < emberAfFixedEndpointCount()) - { - mCurrentEndpointId = emberAfFixedEndpointCount(); - } - - ChipLogProgress(DeviceLayer, "emberAfFixedEndpointCount()=%d mCurrentEndpointId=%d", emberAfFixedEndpointCount(), - mCurrentEndpointId); - - // Disable last fixed endpoint, which is used as a placeholder for all of the - // supported clusters so that ZAP will generated the requisite code. - // emberAfEndpointEnableDisable(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1)), false); -} - -void AppPlatform::UnloadContentAppByVendorId(uint16_t vendorId) -{ - uint8_t index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - ContentApp * app = mContentApps[index]; - if (app != NULL && app->GetApplicationBasic()->GetVendorId() == vendorId) - { - EndpointId ep = emberAfClearDynamicEndpoint(index); - mContentApps[index] = NULL; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", - app->GetApplicationBasic()->GetApplicationName(), ep, index); - // Silence complaints about unused ep when progress logging - // disabled. - UNUSED_VAR(ep); - return; - } - index++; - } - return; -} - -ContentApp * AppPlatform::GetLoadContentAppByVendorId(uint16_t vendorId) -{ - ChipLogProgress(DeviceLayer, "GetLoadContentAppByVendorId() - vendorId %d ", vendorId); - uint8_t index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - ContentApp * app = mContentApps[index]; - if (app != NULL && app->GetApplicationBasic()->GetVendorId() == vendorId) - { - return app; - } - index++; - } - if (mContentAppFactory != NULL) - { - return mContentAppFactory->LoadContentAppByVendorId(vendorId); - } - return NULL; -} - -ContentApp * AppPlatform::GetLoadContentAppByAppId(ApplicationLauncherApplication application) -{ - ChipLogProgress(DeviceLayer, "GetLoadContentAppByAppId()"); - if (mContentAppFactory != NULL) - { - return mContentAppFactory->LoadContentAppByAppId(application); - } - return NULL; -} - -ContentApp * AppPlatform::GetContentAppByEndpointId(chip::EndpointId id) -{ - uint8_t index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - ContentApp * app = mContentApps[index]; - if (app != NULL && app->GetEndpointId() == id) - { - return app; - } - index++; - } - ChipLogProgress(DeviceLayer, "GetContentAppByEndpointId() - endpoint %d not found ", id); - return NULL; -} - -} // namespace AppPlatform -} // namespace chip - -#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED diff --git a/src/app/util/ContentAppPlatform.h b/src/app/util/ContentAppPlatform.h deleted file mode 100644 index 5f891e3216501c..00000000000000 --- a/src/app/util/ContentAppPlatform.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * Copyright (c) 2021 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. - */ - -/** - * @brief Manages Content Apps - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED -namespace chip { -namespace AppPlatform { - -class DLL_EXPORT ContentAppFactory -{ -public: - virtual ~ContentAppFactory() = default; - virtual ContentApp * LoadContentAppByVendorId(uint16_t vendorId) = 0; - virtual ContentApp * LoadContentAppByAppId(ApplicationLauncherApplication application) = 0; -}; - -class DLL_EXPORT AppPlatform -{ -public: - static AppPlatform & GetInstance() - { - static AppPlatform instance; - return instance; - } - - void SetupAppPlatform(); - - inline void SetContentAppFactory(ContentAppFactory * factory) { mContentAppFactory = factory; }; - - // add and remove apps from the platform. - // This will assign the app to an endpoint and make it accessible via Matter - int AddContentApp(ContentApp * app, EmberAfEndpointType * ep, uint16_t deviceType); - int RemoveContentApp(ContentApp * app); - - // load and unload by vendor id - void UnloadContentAppByVendorId(uint16_t vendorId); - ContentApp * GetLoadContentAppByVendorId(uint16_t vendorId); - ContentApp * GetLoadContentAppByAppId(ApplicationLauncherApplication application); - - // helpful method to get a Content App by endpoint in order to perform attribute or command ops - ContentApp * GetContentAppByEndpointId(chip::EndpointId id); - -protected: - ContentAppFactory * mContentAppFactory = nullptr; - EndpointId mCurrentEndpointId; - EndpointId mFirstDynamicEndpointId; - ContentApp * mContentApps[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; -}; - -} // namespace AppPlatform -} // namespace chip -#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED diff --git a/src/controller/BUILD.gn b/src/controller/BUILD.gn index 38dd3540fd9cd2..f08596c4cb7b3b 100644 --- a/src/controller/BUILD.gn +++ b/src/controller/BUILD.gn @@ -44,6 +44,8 @@ static_library("controller") { "CHIPDeviceControllerFactory.h", "CommissioneeDeviceProxy.cpp", "CommissioneeDeviceProxy.h", + "CommissionerDiscoveryController.cpp", + "CommissionerDiscoveryController.h", "DeviceAddressUpdateDelegate.h", "DeviceDiscoveryDelegate.h", "EmptyDataModelHandler.cpp", diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 6701d1c36f0dc5..5ecbf30fcf20e7 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -560,6 +560,33 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowInternal() return CHIP_NO_ERROR; } +CHIP_ERROR DeviceController::CreateBindingWithCallback(chip::NodeId deviceId, chip::EndpointId deviceEndpointId, + chip::NodeId bindingNodeId, chip::GroupId bindingGroupId, + chip::EndpointId bindingEndpointId, chip::ClusterId bindingClusterId, + Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + PeerId peerId; + peerId.SetNodeId(deviceId); + peerId.SetCompressedFabricId(GetCompressedFabricId()); + + OperationalDeviceProxy * device = mCASESessionManager->FindExistingSession(peerId); + if (device == nullptr) + { + ChipLogProgress(AppServer, "No OperationalDeviceProxy returned from device commissioner"); + return CHIP_ERROR_INCORRECT_STATE; + } + + chip::Controller::BindingCluster cluster; + cluster.Associate(device, deviceEndpointId); + + ReturnErrorOnFailure( + cluster.Bind(onSuccessCallback, onFailureCallback, bindingNodeId, bindingGroupId, bindingEndpointId, bindingClusterId)); + + ChipLogDetail(Controller, "Sent Bind command request, waiting for response"); + return CHIP_NO_ERROR; +} + #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD Transport::PeerAddress DeviceController::ToPeerAddress(const chip::Dnssd::ResolvedNodeData & nodeData) const { @@ -675,7 +702,6 @@ CHIP_ERROR DeviceCommissioner::Init(CommissionerInitParams params) mUdcTransportMgr->SetSessionManager(mUdcServer); mUdcServer->SetInstanceNameResolver(this); - mUdcServer->SetUserConfirmationProvider(this); #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY #if CONFIG_NETWORK_LAYER_BLE @@ -699,7 +725,6 @@ CHIP_ERROR DeviceCommissioner::Shutdown() if (mUdcServer != nullptr) { mUdcServer->SetInstanceNameResolver(nullptr); - mUdcServer->SetUserConfirmationProvider(nullptr); chip::Platform::Delete(mUdcServer); mUdcServer = nullptr; } @@ -1454,18 +1479,6 @@ void DeviceCommissioner::FindCommissionableNode(char * instanceName) DiscoverCommissionableNodes(filter); } -void DeviceCommissioner::OnUserDirectedCommissioningRequest(UDCClientState state) -{ - ChipLogDetail(Controller, "------PROMPT USER!! OnUserDirectedCommissioningRequest instance=%s deviceName=%s", - state.GetInstanceName(), state.GetDeviceName()); - - if (mUdcServer != nullptr) - { - mUdcServer->PrintUDCClients(); - } - - ChipLogDetail(Controller, "------To Accept Enter: discover udc-commission "); -} #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 220f9c74079b2f..5730ac4d328717 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -308,6 +308,26 @@ class DLL_EXPORT DeviceController : public SessionRecoveryDelegate, uint8_t option, Callback::Callback * callback, bool readVIDPIDAttributes = false); + /** + * @brief + * Add a binding. + * + * @param[in] deviceId The device Id. + * @param[in] deviceEndpointId The endpoint on the device containing the binding cluster. + * @param[in] bindingNodeId The NodeId for the binding that will be created. + * @param[in] bindingGroupId The GroupId for the binding that will be created. + * @param[in] bindingEndpointId The EndpointId for the binding that will be created. + * @param[in] bindingClusterId The ClusterId for the binding that will be created. + * @param[in] onSuccessCallback The function to be called on success of adding the binding. + * @param[in] onFailureCallback The function to be called on failure of adding the binding. + * + * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error + */ + CHIP_ERROR CreateBindingWithCallback(chip::NodeId deviceId, chip::EndpointId deviceEndpointId, chip::NodeId bindingNodeId, + chip::GroupId bindingGroupId, chip::EndpointId bindingEndpointId, + chip::ClusterId bindingClusterId, Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback); + #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD void RegisterDeviceAddressUpdateDelegate(DeviceAddressUpdateDelegate * delegate) { mDeviceAddressUpdateDelegate = delegate; } void RegisterDeviceDiscoveryDelegate(DeviceDiscoveryDelegate * delegate) { mDeviceDiscoveryDelegate = delegate; } @@ -431,7 +451,6 @@ class DLL_EXPORT DeviceController : public SessionRecoveryDelegate, class DLL_EXPORT DeviceCommissioner : public DeviceController, #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable public Protocols::UserDirectedCommissioning::InstanceNameResolver, - public Protocols::UserDirectedCommissioning::UserConfirmationProvider, #endif public SessionEstablishmentDelegate { @@ -636,17 +655,6 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, */ void FindCommissionableNode(char * instanceName) override; - /** - * @brief - * Called when a UDC message has been received and corresponding nodeData has been found. - * It is expected that the implementer will prompt the user to confirm their intention to - * commission the given node, and provide the setup code to allow commissioning to proceed. - * - * @param nodeData DNS-SD node information for the client requesting commissioning - * - */ - void OnUserDirectedCommissioningRequest(UDCClientState state) override; - /** * @brief * Return the UDC Server instance diff --git a/src/controller/CommissionerDiscoveryController.cpp b/src/controller/CommissionerDiscoveryController.cpp new file mode 100644 index 00000000000000..7cb3171968364e --- /dev/null +++ b/src/controller/CommissionerDiscoveryController.cpp @@ -0,0 +1,159 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2013-2017 Nest Labs, Inc. + * 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. + */ + +/** + * @file + * Declaration of Commissioner Discovery Controller, + * a common class that manages state and callbacks + * for handling the Commissioner Discovery + * and User Directed Commissioning workflow + * + */ +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + +using namespace ::chip; +using namespace chip::Protocols::UserDirectedCommissioning; + +void CommissionerDiscoveryController::OnUserDirectedCommissioningRequest(UDCClientState state) +{ + strncpy(mCurrentInstance, state.GetInstanceName(), sizeof(mCurrentInstance)); + mPendingConsent = true; + ChipLogDetail(Controller, + "------PROMPT USER: %s is requesting permission to cast to this TV, approve? [" ChipLogFormatMEI + "," ChipLogFormatMEI ",%s]", + state.GetDeviceName(), ChipLogValueMEI(state.GetVendorId()), ChipLogValueMEI(state.GetProductId()), + state.GetInstanceName()); + if (mUserPrompter != nullptr) + { + mUserPrompter->PromptForCommissionOKPermission(state.GetVendorId(), state.GetProductId(), state.GetDeviceName()); + } + ChipLogDetail(Controller, "------Via Shell Enter: controller ux ok|cancel"); +} + +void CommissionerDiscoveryController::Ok() +{ + if (!mPendingConsent) + { + ChipLogError(AppServer, "UX Cancel: no current instance"); + return; + } + if (mUdcServer == nullptr) + { + ChipLogError(AppServer, "UX Ok: no udc server"); + return; + } + UDCClientState * client = mUdcServer->GetUDCClients().FindUDCClientState(mCurrentInstance); + if (client == nullptr) + { + ChipLogError(AppServer, "UX Ok: could not find instance=%s", mCurrentInstance); + return; + } + if (client->GetUDCClientProcessingState() != UDCClientProcessingState::kPromptingUser) + { + ChipLogError(AppServer, "UX Ok: invalid state for ok"); + return; + } + client->SetUDCClientProcessingState(UDCClientProcessingState::kObtainingOnboardingPayload); + + if (mPincodeService != nullptr) + { + char rotatingIdString[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = ""; + Encoding::BytesToUppercaseHexString(client->GetRotatingId(), client->GetRotatingIdLength(), rotatingIdString, + sizeof(rotatingIdString)); + // Encoding::BytesToUppercaseHexString(client->GetRotatingId(), chip::Dnssd::kMaxRotatingIdLen, rotatingIdString, + // sizeof(rotatingIdString)); + + CharSpan rotatingIdSpan = chip::CharSpan(rotatingIdString, sizeof(rotatingIdString)); + uint32_t pincode = + mPincodeService->FetchCommissionPincodeFromContentApp(client->GetVendorId(), client->GetProductId(), rotatingIdSpan); + if (pincode != 0) + { + CommissionWithPincode(pincode); + return; + } + } + + ChipLogDetail(Controller, "------PROMPT USER: please enter pin displayed in casting app "); + if (mUserPrompter != nullptr) + { + mUserPrompter->PromptForCommissionPincode(client->GetVendorId(), client->GetProductId(), client->GetDeviceName()); + } + ChipLogDetail(Controller, "------Via Shell Enter: controller ux ok [pincode]"); + return; +} + +void CommissionerDiscoveryController::CommissionWithPincode(uint32_t pincode) +{ + if (!mPendingConsent) + { + ChipLogError(AppServer, "UX Cancel: no current instance"); + return; + } + if (mUdcServer == nullptr) + { + ChipLogError(AppServer, "UX CommissionWithPincode: no udc server"); + return; + } + UDCClientState * client = mUdcServer->GetUDCClients().FindUDCClientState(mCurrentInstance); + if (client == nullptr) + { + ChipLogError(AppServer, "UX Ok: could not find instance=%s", mCurrentInstance); + return; + } + // state needs to be either kPromptingUser or kObtainingOnboardingPayload + if (!(client->GetUDCClientProcessingState() == UDCClientProcessingState::kPromptingUser || + client->GetUDCClientProcessingState() == UDCClientProcessingState::kObtainingOnboardingPayload)) + { + ChipLogError(AppServer, "UX CommissionWithPincode: invalid state for CommissionWithPincode"); + return; + } + Transport::PeerAddress peerAddress = client->GetPeerAddress(); + client->SetUDCClientProcessingState(UDCClientProcessingState::kCommissioningNode); + if (mCommissionerCallback != nullptr) + { + mCommissionerCallback->ReadyForCommissioning(pincode, client->GetLongDiscriminator(), peerAddress); + } +} + +void CommissionerDiscoveryController::Cancel() +{ + if (!mPendingConsent) + { + ChipLogError(AppServer, "UX Cancel: no current instance"); + return; + } + if (mUdcServer == nullptr) + { + ChipLogError(AppServer, "UX Cancel: no udc server"); + return; + } + UDCClientState * client = mUdcServer->GetUDCClients().FindUDCClientState(mCurrentInstance); + if (client == nullptr || client->GetUDCClientProcessingState() != UDCClientProcessingState::kPromptingUser) + { + ChipLogError(AppServer, "UX Cancel: invalid state for cancel"); + return; + } + client->SetUDCClientProcessingState(UDCClientProcessingState::kUserDeclined); + mPendingConsent = false; + return; +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY diff --git a/src/controller/CommissionerDiscoveryController.h b/src/controller/CommissionerDiscoveryController.h new file mode 100644 index 00000000000000..38eb2db7887960 --- /dev/null +++ b/src/controller/CommissionerDiscoveryController.h @@ -0,0 +1,184 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2013-2017 Nest Labs, Inc. + * 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. + */ + +/** + * @file + * Declaration of Commissioner Discovery Controller, + * a common class that manages state and callbacks + * for handling the Commissioner Discovery + * and User Directed Commissioning workflow + * + */ + +#pragma once + +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + +using chip::Protocols::UserDirectedCommissioning::UDCClientState; +using chip::Protocols::UserDirectedCommissioning::UserConfirmationProvider; +using chip::Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer; +using chip::Transport::PeerAddress; + +class DLL_EXPORT UserPrompter +{ +public: + /** + * @brief + * Called to prompt the user for consent to allow the given commissioneeName/vendorId/productId to be commissioned. + * For example "[commissioneeName] is requesting permission to cast to this TV, approve?" + * + * If user responds with OK then implementor should call CommissionerRespondOk(); + * If user responds with Cancel then implementor should call CommissionerRespondCancel(); + * + * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] commissioneeName The commissioneeName in the DNS-SD advertisement of the requesting commissionee. + * + */ + virtual void PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0; + + /** + * @brief + * Called to prompt the user to enter the setup pincode displayed by the given commissioneeName/vendorId/productId to be + * commissioned. For example "Please enter pin displayed in casting app." + * + * If user enters with pin then implementor should call CommissionerRespondPincode(uint32_t pincode); + * If user responds with Cancel then implementor should call CommissionerRespondCancel(); + * + * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] commissioneeName The commissioneeName in the DNS-SD advertisement of the requesting commissionee. + * + */ + virtual void PromptForCommissionPincode(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0; + + virtual ~UserPrompter() = default; +}; + +class DLL_EXPORT PincodeService +{ +public: + /** + * @brief + * Called to get the setup pincode from the content app corresponding to the given vendorId/productId + * Returns 0 if pincode cannot be obtained + * + * If user responds with OK then implementor should call CommissionerRespondOk(); + * If user responds with Cancel then implementor should call CommissionerRespondCancel(); + * + * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] rotatingId The rotatingId in the DNS-SD advertisement of the requesting commissionee. + * + */ + virtual uint32_t FetchCommissionPincodeFromContentApp(uint16_t vendorId, uint16_t productId, chip::CharSpan rotatingId) = 0; + + virtual ~PincodeService() = default; +}; + +class DLL_EXPORT CommissionerCallback +{ +public: + /** + * @brief + * Called to notify the commissioner that commissioning can now proceed for + * the node identified by the given arguments. + * + * @param[in] pincode The pin code to use for the commissionee. + * @param[in] longDiscriminator The long discriminator for the commissionee. + * @param[in] peerAddress The peerAddress for the commissionee. + * + */ + virtual void ReadyForCommissioning(uint32_t pincode, uint16_t longDiscriminator, PeerAddress peerAddress) = 0; + + virtual ~CommissionerCallback() = default; +}; + +class CommissionerDiscoveryController : public chip::Protocols::UserDirectedCommissioning::UserConfirmationProvider +{ +public: + /** + * UserConfirmationProvider callback. + * + * Notification that a UDC protocol message was received. + * + * This code will call the registered UserPrompter's PromptForCommissionOKPermission + */ + void OnUserDirectedCommissioningRequest(UDCClientState state); + + /** + * This method should be called after the user has given consent for commissioning of the client + * indicated in the UserPrompter's PromptForCommissionOKPermission callback + */ + void Ok(); + + /** + * This method should be called after the user has declined to give consent for commissioning of the client + * indicated in the UserPrompter's PromptForCommissionOKPermission callback + */ + void Cancel(); + + /** + * This method should be called with the pincode for the client + * indicated in the UserPrompter's PromptForCommissionPincode callback + */ + void CommissionWithPincode(uint32_t pincode); + + /** + * Assign a DeviceCommissioner + */ + inline void SetUserDirectedCommissioningServer(UserDirectedCommissioningServer * udcServer) + { + mUdcServer = udcServer; + mUdcServer->SetUserConfirmationProvider(this); + } + + /** + * Assign a UserPromper + */ + inline void SetUserPrompter(UserPrompter * userPrompter) { mUserPrompter = userPrompter; } + + /** + * Assign a PincodeService + */ + inline void SetPincodeService(PincodeService * pincodeService) { mPincodeService = pincodeService; } + + /** + * Assign a Commissioner Callback to perform commissioning once user consent has been given + */ + inline void SetCommissionerCallback(CommissionerCallback * commissionerCallback) + { + mCommissionerCallback = commissionerCallback; + } + +protected: + bool mPendingConsent = false; + char mCurrentInstance[chip::Dnssd::Commission::kInstanceNameMaxLength + 1]; + UserDirectedCommissioningServer * mUdcServer = nullptr; + UserPrompter * mUserPrompter = nullptr; + PincodeService * mPincodeService = nullptr; + CommissionerCallback * mCommissionerCallback = nullptr; +}; + +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY diff --git a/src/protocols/user_directed_commissioning/UDCClientState.h b/src/protocols/user_directed_commissioning/UDCClientState.h index 3e15df04017bb8..25a47f55e2a1eb 100644 --- a/src/protocols/user_directed_commissioning/UDCClientState.h +++ b/src/protocols/user_directed_commissioning/UDCClientState.h @@ -82,7 +82,12 @@ class UDCClientState void SetProductId(uint16_t value) { mProductId = value; } const uint8_t * GetRotatingId() const { return mRotatingId; } - void SetRotatingId(const uint8_t * rotatingId) { memcpy(mRotatingId, rotatingId, sizeof(mRotatingId)); } + size_t GetRotatingIdLength() const { return mRotatingIdLen; } + void SetRotatingId(const uint8_t * rotatingId, size_t rotatingIdLen) + { + memcpy(mRotatingId, rotatingId, rotatingIdLen); + mRotatingIdLen = rotatingIdLen; + } UDCClientProcessingState GetUDCClientProcessingState() const { return mUDCClientProcessingState; } void SetUDCClientProcessingState(UDCClientProcessingState state) { mUDCClientProcessingState = state; } @@ -114,6 +119,7 @@ class UDCClientState uint16_t mVendorId; uint16_t mProductId; uint8_t mRotatingId[chip::Dnssd::kMaxRotatingIdLen]; + size_t mRotatingIdLen = 0; UDCClientProcessingState mUDCClientProcessingState; System::Clock::Timestamp mExpirationTime = System::Clock::kZero; }; diff --git a/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp b/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp index fc73925bf75c6c..2777db627a5b85 100644 --- a/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp +++ b/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp @@ -149,7 +149,7 @@ void UserDirectedCommissioningServer::OnCommissionableNodeFound(const Dnssd::Dis client->SetVendorId(nodeData.vendorId); client->SetProductId(nodeData.productId); client->SetDeviceName(nodeData.deviceName); - client->SetRotatingId(nodeData.rotatingId); + client->SetRotatingId(nodeData.rotatingId, nodeData.rotatingIdLen); // Call the registered mUserConfirmationProvider, if any. if (mUserConfirmationProvider != nullptr)