diff --git a/examples/all-clusters-app/linux/include/tv-callbacks.cpp b/examples/all-clusters-app/linux/include/tv-callbacks.cpp index b479ac6779bd2e..79a6ee8413daac 100644 --- a/examples/all-clusters-app/linux/include/tv-callbacks.cpp +++ b/examples/all-clusters-app/linux/include/tv-callbacks.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for TV stubs diff --git a/examples/chip-tool/commands/tests/Commands.h b/examples/chip-tool/commands/tests/Commands.h index 9d39a75d2177f7..ac3344fd18b9e1 100644 --- a/examples/chip-tool/commands/tests/Commands.h +++ b/examples/chip-tool/commands/tests/Commands.h @@ -21,6 +21,3241 @@ #include "TestCommand.h" +class TV_TargetNavigatorCluster : public TestCommand +{ +public: + TV_TargetNavigatorCluster() : TestCommand("TV_TargetNavigatorCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_TargetNavigatorCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterTargetNavigatorCommandReadAttribute_0(); + break; + case 1: + err = TestSendClusterTargetNavigatorCommandNavigateTarget_1(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_TargetNavigatorCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 2; + + // + // Tests methods + // + + // Test Read attribute Target Navigator list + typedef void (*SuccessCallback_0)(void * context, uint16_t count, _NavigateTargetTargetInfo * targetNavigatorList); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterTargetNavigatorCommandReadAttribute_0() + { + ChipLogProgress(chipTool, "Target Navigator - Read attribute Target Navigator list: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterTargetNavigatorCommandReadAttribute_0_FailureResponse, this); + mOnSuccessCallback_0 = new chip::Callback::Callback( + OnTestSendClusterTargetNavigatorCommandReadAttribute_0_SuccessResponse, this); + + chip::Controller::TargetNavigatorCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeTargetNavigatorList(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterTargetNavigatorCommandReadAttribute_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Target Navigator - Read attribute Target Navigator list: Failure Response"); + + TV_TargetNavigatorCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void + OnTestSendClusterTargetNavigatorCommandReadAttribute_0_SuccessResponse(void * context, uint16_t count, + _NavigateTargetTargetInfo * targetNavigatorList) + { + ChipLogProgress(chipTool, "Target Navigator - Read attribute Target Navigator list: Success Response"); + + TV_TargetNavigatorCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (count != 2) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "[object Object],[object Object]"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Navigate Target Command + typedef void (*SuccessCallback_1)(void * context, uint8_t status, chip::ByteSpan data); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterTargetNavigatorCommandNavigateTarget_1() + { + ChipLogProgress(chipTool, "Target Navigator - Navigate Target Command: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterTargetNavigatorCommandNavigateTarget_1_FailureResponse, this); + mOnSuccessCallback_1 = new chip::Callback::Callback( + OnTestSendClusterTargetNavigatorCommandNavigateTarget_1_SuccessResponse, this); + + chip::Controller::TargetNavigatorCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t targetArgument = 1; + chip::ByteSpan dataArgument = chip::ByteSpan(chip::Uint8::from_const_char("1"), strlen("1")); + err = cluster.NavigateTarget(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel(), targetArgument, dataArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterTargetNavigatorCommandNavigateTarget_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Target Navigator - Navigate Target Command: Failure Response"); + + TV_TargetNavigatorCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterTargetNavigatorCommandNavigateTarget_1_SuccessResponse(void * context, uint8_t status, + chip::ByteSpan data) + { + ChipLogProgress(chipTool, "Target Navigator - Navigate Target Command: Success Response"); + + TV_TargetNavigatorCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_AudioOutputCluster : public TestCommand +{ +public: + TV_AudioOutputCluster() : TestCommand("TV_AudioOutputCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_AudioOutputCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterAudioOutputCommandReadAttribute_0(); + break; + case 1: + err = TestSendClusterAudioOutputCommandSelectOutput_1(); + break; + case 2: + err = TestSendClusterAudioOutputCommandRenameOutput_2(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_AudioOutputCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 3; + + // + // Tests methods + // + + // Test Read attribute Audio Output list + typedef void (*SuccessCallback_0)(void * context, uint16_t count, _AudioOutputInfo * audioOutputList); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterAudioOutputCommandReadAttribute_0() + { + ChipLogProgress(chipTool, "Audio Output - Read attribute Audio Output list: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterAudioOutputCommandReadAttribute_0_FailureResponse, this); + mOnSuccessCallback_0 = new chip::Callback::Callback( + OnTestSendClusterAudioOutputCommandReadAttribute_0_SuccessResponse, this); + + chip::Controller::AudioOutputCluster cluster; + cluster.Associate(mDevice, 2); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeAudioOutputList(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterAudioOutputCommandReadAttribute_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Audio Output - Read attribute Audio Output list: Failure Response"); + + TV_AudioOutputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterAudioOutputCommandReadAttribute_0_SuccessResponse(void * context, uint16_t count, + _AudioOutputInfo * audioOutputList) + { + ChipLogProgress(chipTool, "Audio Output - Read attribute Audio Output list: Success Response"); + + TV_AudioOutputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (count != 3) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "[object Object],[object Object],[object Object]"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Select Output Command + typedef void (*SuccessCallback_1)(void * context); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterAudioOutputCommandSelectOutput_1() + { + ChipLogProgress(chipTool, "Audio Output - Select Output Command: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterAudioOutputCommandSelectOutput_1_FailureResponse, this); + mOnSuccessCallback_1 = new chip::Callback::Callback( + OnTestSendClusterAudioOutputCommandSelectOutput_1_SuccessResponse, this); + + chip::Controller::AudioOutputCluster cluster; + cluster.Associate(mDevice, 2); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t indexArgument = 1; + err = cluster.SelectOutput(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel(), indexArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterAudioOutputCommandSelectOutput_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Audio Output - Select Output Command: Failure Response"); + + TV_AudioOutputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterAudioOutputCommandSelectOutput_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Audio Output - Select Output Command: Success Response"); + + TV_AudioOutputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Rename Output Command + typedef void (*SuccessCallback_2)(void * context); + chip::Callback::Callback * mOnSuccessCallback_2 = nullptr; + chip::Callback::Callback * mOnFailureCallback_2 = nullptr; + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterAudioOutputCommandRenameOutput_2() + { + ChipLogProgress(chipTool, "Audio Output - Rename Output Command: Sending command..."); + + mOnFailureCallback_2 = new chip::Callback::Callback( + OnTestSendClusterAudioOutputCommandRenameOutput_2_FailureResponse, this); + mOnSuccessCallback_2 = new chip::Callback::Callback( + OnTestSendClusterAudioOutputCommandRenameOutput_2_SuccessResponse, this); + + chip::Controller::AudioOutputCluster cluster; + cluster.Associate(mDevice, 2); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t indexArgument = 1; + chip::ByteSpan nameArgument = chip::ByteSpan(chip::Uint8::from_const_char("exampleName"), strlen("exampleName")); + err = cluster.RenameOutput(mOnSuccessCallback_2->Cancel(), mOnFailureCallback_2->Cancel(), indexArgument, nameArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_2; + delete mOnSuccessCallback_2; + } + + return err; + } + + static void OnTestSendClusterAudioOutputCommandRenameOutput_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Audio Output - Rename Output Command: Failure Response"); + + TV_AudioOutputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterAudioOutputCommandRenameOutput_2_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Audio Output - Rename Output Command: Success Response"); + + TV_AudioOutputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_ApplicationLauncherCluster : public TestCommand +{ +public: + TV_ApplicationLauncherCluster() : TestCommand("TV_ApplicationLauncherCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_ApplicationLauncherCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterApplicationLauncherCommandReadAttribute_0(); + break; + case 1: + err = TestSendClusterApplicationLauncherCommandLaunchApp_1(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_ApplicationLauncherCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 2; + + // + // Tests methods + // + + // Test Read attribute Application Launcher list + typedef void (*SuccessCallback_0)(void * context, uint16_t count, uint16_t * applicationLauncherList); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterApplicationLauncherCommandReadAttribute_0() + { + ChipLogProgress(chipTool, "Application Launcher - Read attribute Application Launcher list: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterApplicationLauncherCommandReadAttribute_0_FailureResponse, this); + mOnSuccessCallback_0 = new chip::Callback::Callback( + OnTestSendClusterApplicationLauncherCommandReadAttribute_0_SuccessResponse, this); + + chip::Controller::ApplicationLauncherCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeApplicationLauncherList(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterApplicationLauncherCommandReadAttribute_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Launcher - Read attribute Application Launcher list: Failure Response"); + + TV_ApplicationLauncherCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationLauncherCommandReadAttribute_0_SuccessResponse(void * context, uint16_t count, + uint16_t * applicationLauncherList) + { + ChipLogProgress(chipTool, "Application Launcher - Read attribute Application Launcher list: Success Response"); + + TV_ApplicationLauncherCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (count != 2) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "123,456"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Launch App Command + typedef void (*SuccessCallback_1)(void * context, uint8_t status, chip::ByteSpan data); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterApplicationLauncherCommandLaunchApp_1() + { + ChipLogProgress(chipTool, "Application Launcher - Launch App Command: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterApplicationLauncherCommandLaunchApp_1_FailureResponse, this); + mOnSuccessCallback_1 = new chip::Callback::Callback( + OnTestSendClusterApplicationLauncherCommandLaunchApp_1_SuccessResponse, this); + + chip::Controller::ApplicationLauncherCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::ByteSpan dataArgument = chip::ByteSpan(chip::Uint8::from_const_char("exampleData"), strlen("exampleData")); + uint16_t catalogVendorIdArgument = 1U; + chip::ByteSpan applicationIdArgument = chip::ByteSpan(chip::Uint8::from_const_char("appId"), strlen("appId")); + err = cluster.LaunchApp(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel(), dataArgument, + catalogVendorIdArgument, applicationIdArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterApplicationLauncherCommandLaunchApp_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Launcher - Launch App Command: Failure Response"); + + TV_ApplicationLauncherCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationLauncherCommandLaunchApp_1_SuccessResponse(void * context, uint8_t status, + chip::ByteSpan data) + { + ChipLogProgress(chipTool, "Application Launcher - Launch App Command: Success Response"); + + TV_ApplicationLauncherCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_KeypadInputCluster : public TestCommand +{ +public: + TV_KeypadInputCluster() : TestCommand("TV_KeypadInputCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_KeypadInputCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterKeypadInputCommandSendKey_0(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_KeypadInputCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 1; + + // + // Tests methods + // + + // Test Send Key Command + typedef void (*SuccessCallback_0)(void * context, uint8_t status); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterKeypadInputCommandSendKey_0() + { + ChipLogProgress(chipTool, "Keypad Input - Send Key Command: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterKeypadInputCommandSendKey_0_FailureResponse, this); + mOnSuccessCallback_0 = + new chip::Callback::Callback(OnTestSendClusterKeypadInputCommandSendKey_0_SuccessResponse, this); + + chip::Controller::KeypadInputCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t keyCodeArgument = 3; + err = cluster.SendKey(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel(), keyCodeArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterKeypadInputCommandSendKey_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Keypad Input - Send Key Command: Failure Response"); + + TV_KeypadInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterKeypadInputCommandSendKey_0_SuccessResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Keypad Input - Send Key Command: Success Response"); + + TV_KeypadInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_AccountLoginCluster : public TestCommand +{ +public: + TV_AccountLoginCluster() : TestCommand("TV_AccountLoginCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_AccountLoginCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterAccountLoginCommandGetSetupPIN_0(); + break; + case 1: + err = TestSendClusterAccountLoginCommandLogin_1(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_AccountLoginCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 2; + + // + // Tests methods + // + + // Test Get Setup PIN Command + typedef void (*SuccessCallback_0)(void * context, chip::ByteSpan setupPIN); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterAccountLoginCommandGetSetupPIN_0() + { + ChipLogProgress(chipTool, "Account Login - Get Setup PIN Command: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterAccountLoginCommandGetSetupPIN_0_FailureResponse, this); + mOnSuccessCallback_0 = new chip::Callback::Callback( + OnTestSendClusterAccountLoginCommandGetSetupPIN_0_SuccessResponse, this); + + chip::Controller::AccountLoginCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::ByteSpan tempAccountIdentifierArgument = chip::ByteSpan(chip::Uint8::from_const_char("asdf"), strlen("asdf")); + err = cluster.GetSetupPIN(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel(), tempAccountIdentifierArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterAccountLoginCommandGetSetupPIN_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Account Login - Get Setup PIN Command: Failure Response"); + + TV_AccountLoginCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterAccountLoginCommandGetSetupPIN_0_SuccessResponse(void * context, chip::ByteSpan setupPIN) + { + ChipLogProgress(chipTool, "Account Login - Get Setup PIN Command: Success Response"); + + TV_AccountLoginCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Login Command + typedef void (*SuccessCallback_1)(void * context); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterAccountLoginCommandLogin_1() + { + ChipLogProgress(chipTool, "Account Login - Login Command: Sending command..."); + + mOnFailureCallback_1 = + new chip::Callback::Callback(OnTestSendClusterAccountLoginCommandLogin_1_FailureResponse, this); + mOnSuccessCallback_1 = + new chip::Callback::Callback(OnTestSendClusterAccountLoginCommandLogin_1_SuccessResponse, this); + + chip::Controller::AccountLoginCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::ByteSpan tempAccountIdentifierArgument = chip::ByteSpan(chip::Uint8::from_const_char("asdf"), strlen("asdf")); + chip::ByteSpan setupPINArgument = chip::ByteSpan(chip::Uint8::from_const_char("tempPin123"), strlen("tempPin123")); + err = cluster.Login(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel(), tempAccountIdentifierArgument, + setupPINArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterAccountLoginCommandLogin_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Account Login - Login Command: Failure Response"); + + TV_AccountLoginCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterAccountLoginCommandLogin_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Account Login - Login Command: Success Response"); + + TV_AccountLoginCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_ApplicationBasicCluster : public TestCommand +{ +public: + TV_ApplicationBasicCluster() : TestCommand("TV_ApplicationBasicCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_ApplicationBasicCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterApplicationBasicCommandChangeStatus_0(); + break; + case 1: + err = TestSendClusterApplicationBasicCommandReadAttribute_1(); + break; + case 2: + err = TestSendClusterApplicationBasicCommandReadAttribute_2(); + break; + case 3: + err = TestSendClusterApplicationBasicCommandReadAttribute_3(); + break; + case 4: + err = TestSendClusterApplicationBasicCommandReadAttribute_4(); + break; + case 5: + err = TestSendClusterApplicationBasicCommandReadAttribute_5(); + break; + case 6: + err = TestSendClusterApplicationBasicCommandReadAttribute_6(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_ApplicationBasicCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 7; + + // + // Tests methods + // + + // Test Change Status Command + typedef void (*SuccessCallback_0)(void * context); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandChangeStatus_0() + { + ChipLogProgress(chipTool, "Application Basic - Change Status Command: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandChangeStatus_0_FailureResponse, this); + mOnSuccessCallback_0 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandChangeStatus_0_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t statusArgument = 1; + err = cluster.ChangeStatus(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel(), statusArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandChangeStatus_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Change Status Command: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandChangeStatus_0_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Application Basic - Change Status Command: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Read attribute vendor name + typedef void (*SuccessCallback_1)(void * context, chip::ByteSpan vendorName); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_1() + { + ChipLogProgress(chipTool, "Application Basic - Read attribute vendor name: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_1_FailureResponse, this); + mOnSuccessCallback_1 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_1_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeVendorName(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute vendor name: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_1_SuccessResponse(void * context, chip::ByteSpan vendorName) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute vendor name: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Read attribute vendor id + typedef void (*SuccessCallback_2)(void * context, uint16_t vendorId); + chip::Callback::Callback * mOnSuccessCallback_2 = nullptr; + chip::Callback::Callback * mOnFailureCallback_2 = nullptr; + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_2() + { + ChipLogProgress(chipTool, "Application Basic - Read attribute vendor id: Sending command..."); + + mOnFailureCallback_2 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_2_FailureResponse, this); + mOnSuccessCallback_2 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_2_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeVendorId(mOnSuccessCallback_2->Cancel(), mOnFailureCallback_2->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_2; + delete mOnSuccessCallback_2; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute vendor id: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_2_SuccessResponse(void * context, uint16_t vendorId) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute vendor id: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (vendorId != 1U) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "1"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Read attribute name + typedef void (*SuccessCallback_3)(void * context, chip::ByteSpan applicationName); + chip::Callback::Callback * mOnSuccessCallback_3 = nullptr; + chip::Callback::Callback * mOnFailureCallback_3 = nullptr; + bool mIsFailureExpected_3 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_3() + { + ChipLogProgress(chipTool, "Application Basic - Read attribute name: Sending command..."); + + mOnFailureCallback_3 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_3_FailureResponse, this); + mOnSuccessCallback_3 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_3_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeApplicationName(mOnSuccessCallback_3->Cancel(), mOnFailureCallback_3->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_3; + delete mOnSuccessCallback_3; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_3_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute name: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_3; + delete runner->mOnSuccessCallback_3; + + if (runner->mIsFailureExpected_3 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_3_SuccessResponse(void * context, + chip::ByteSpan applicationName) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute name: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_3; + delete runner->mOnSuccessCallback_3; + + if (runner->mIsFailureExpected_3 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Read attribute product id + typedef void (*SuccessCallback_4)(void * context, uint16_t productId); + chip::Callback::Callback * mOnSuccessCallback_4 = nullptr; + chip::Callback::Callback * mOnFailureCallback_4 = nullptr; + bool mIsFailureExpected_4 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_4() + { + ChipLogProgress(chipTool, "Application Basic - Read attribute product id: Sending command..."); + + mOnFailureCallback_4 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_4_FailureResponse, this); + mOnSuccessCallback_4 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_4_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeProductId(mOnSuccessCallback_4->Cancel(), mOnFailureCallback_4->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_4; + delete mOnSuccessCallback_4; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_4_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute product id: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_4; + delete runner->mOnSuccessCallback_4; + + if (runner->mIsFailureExpected_4 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_4_SuccessResponse(void * context, uint16_t productId) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute product id: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_4; + delete runner->mOnSuccessCallback_4; + + if (runner->mIsFailureExpected_4 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (productId != 1U) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "1"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Read attribute id + typedef void (*SuccessCallback_5)(void * context, chip::ByteSpan applicationId); + chip::Callback::Callback * mOnSuccessCallback_5 = nullptr; + chip::Callback::Callback * mOnFailureCallback_5 = nullptr; + bool mIsFailureExpected_5 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_5() + { + ChipLogProgress(chipTool, "Application Basic - Read attribute id: Sending command..."); + + mOnFailureCallback_5 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_5_FailureResponse, this); + mOnSuccessCallback_5 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_5_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeApplicationId(mOnSuccessCallback_5->Cancel(), mOnFailureCallback_5->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_5; + delete mOnSuccessCallback_5; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_5_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute id: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_5; + delete runner->mOnSuccessCallback_5; + + if (runner->mIsFailureExpected_5 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_5_SuccessResponse(void * context, + chip::ByteSpan applicationId) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute id: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_5; + delete runner->mOnSuccessCallback_5; + + if (runner->mIsFailureExpected_5 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Read attribute catalog vendor id + typedef void (*SuccessCallback_6)(void * context, uint16_t catalogVendorId); + chip::Callback::Callback * mOnSuccessCallback_6 = nullptr; + chip::Callback::Callback * mOnFailureCallback_6 = nullptr; + bool mIsFailureExpected_6 = 0; + + CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_6() + { + ChipLogProgress(chipTool, "Application Basic - Read attribute catalog vendor id: Sending command..."); + + mOnFailureCallback_6 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_6_FailureResponse, this); + mOnSuccessCallback_6 = new chip::Callback::Callback( + OnTestSendClusterApplicationBasicCommandReadAttribute_6_SuccessResponse, this); + + chip::Controller::ApplicationBasicCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeCatalogVendorId(mOnSuccessCallback_6->Cancel(), mOnFailureCallback_6->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_6; + delete mOnSuccessCallback_6; + } + + return err; + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_6_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute catalog vendor id: Failure Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_6; + delete runner->mOnSuccessCallback_6; + + if (runner->mIsFailureExpected_6 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterApplicationBasicCommandReadAttribute_6_SuccessResponse(void * context, uint16_t catalogVendorId) + { + ChipLogProgress(chipTool, "Application Basic - Read attribute catalog vendor id: Success Response"); + + TV_ApplicationBasicCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_6; + delete runner->mOnSuccessCallback_6; + + if (runner->mIsFailureExpected_6 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (catalogVendorId != 1U) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "1"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_MediaPlaybackCluster : public TestCommand +{ +public: + TV_MediaPlaybackCluster() : TestCommand("TV_MediaPlaybackCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_MediaPlaybackCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterMediaPlaybackCommandMediaPlay_0(); + break; + case 1: + err = TestSendClusterMediaPlaybackCommandMediaPause_1(); + break; + case 2: + err = TestSendClusterMediaPlaybackCommandMediaStop_2(); + break; + case 3: + err = TestSendClusterMediaPlaybackCommandMediaStartOver_3(); + break; + case 4: + err = TestSendClusterMediaPlaybackCommandMediaPrevious_4(); + break; + case 5: + err = TestSendClusterMediaPlaybackCommandMediaNext_5(); + break; + case 6: + err = TestSendClusterMediaPlaybackCommandMediaRewind_6(); + break; + case 7: + err = TestSendClusterMediaPlaybackCommandMediaFastForward_7(); + break; + case 8: + err = TestSendClusterMediaPlaybackCommandMediaSkipForward_8(); + break; + case 9: + err = TestSendClusterMediaPlaybackCommandMediaSkipBackward_9(); + break; + case 10: + err = TestSendClusterMediaPlaybackCommandMediaSeek_10(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_MediaPlaybackCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 11; + + // + // Tests methods + // + + // Test Media Playback Play Command + typedef void (*SuccessCallback_0)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaPlay_0() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Play Command: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaPlay_0_FailureResponse, this); + mOnSuccessCallback_0 = + new chip::Callback::Callback(OnTestSendClusterMediaPlaybackCommandMediaPlay_0_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaPlay(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaPlay_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Play Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaPlay_0_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Play Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Pause Command + typedef void (*SuccessCallback_1)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaPause_1() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Pause Command: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaPause_1_FailureResponse, this); + mOnSuccessCallback_1 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaPause_1_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaPause(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaPause_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Pause Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaPause_1_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Pause Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Stop Command + typedef void (*SuccessCallback_2)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_2 = nullptr; + chip::Callback::Callback * mOnFailureCallback_2 = nullptr; + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaStop_2() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Stop Command: Sending command..."); + + mOnFailureCallback_2 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaStop_2_FailureResponse, this); + mOnSuccessCallback_2 = + new chip::Callback::Callback(OnTestSendClusterMediaPlaybackCommandMediaStop_2_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaStop(mOnSuccessCallback_2->Cancel(), mOnFailureCallback_2->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_2; + delete mOnSuccessCallback_2; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaStop_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Stop Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaStop_2_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Stop Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Start Over Command + typedef void (*SuccessCallback_3)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_3 = nullptr; + chip::Callback::Callback * mOnFailureCallback_3 = nullptr; + bool mIsFailureExpected_3 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaStartOver_3() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Start Over Command: Sending command..."); + + mOnFailureCallback_3 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaStartOver_3_FailureResponse, this); + mOnSuccessCallback_3 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaStartOver_3_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaStartOver(mOnSuccessCallback_3->Cancel(), mOnFailureCallback_3->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_3; + delete mOnSuccessCallback_3; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaStartOver_3_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Start Over Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_3; + delete runner->mOnSuccessCallback_3; + + if (runner->mIsFailureExpected_3 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaStartOver_3_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Start Over Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_3; + delete runner->mOnSuccessCallback_3; + + if (runner->mIsFailureExpected_3 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Previous Command + typedef void (*SuccessCallback_4)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_4 = nullptr; + chip::Callback::Callback * mOnFailureCallback_4 = nullptr; + bool mIsFailureExpected_4 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaPrevious_4() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Previous Command: Sending command..."); + + mOnFailureCallback_4 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaPrevious_4_FailureResponse, this); + mOnSuccessCallback_4 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaPrevious_4_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaPrevious(mOnSuccessCallback_4->Cancel(), mOnFailureCallback_4->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_4; + delete mOnSuccessCallback_4; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaPrevious_4_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Previous Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_4; + delete runner->mOnSuccessCallback_4; + + if (runner->mIsFailureExpected_4 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaPrevious_4_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Previous Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_4; + delete runner->mOnSuccessCallback_4; + + if (runner->mIsFailureExpected_4 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Next Command + typedef void (*SuccessCallback_5)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_5 = nullptr; + chip::Callback::Callback * mOnFailureCallback_5 = nullptr; + bool mIsFailureExpected_5 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaNext_5() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Next Command: Sending command..."); + + mOnFailureCallback_5 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaNext_5_FailureResponse, this); + mOnSuccessCallback_5 = + new chip::Callback::Callback(OnTestSendClusterMediaPlaybackCommandMediaNext_5_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaNext(mOnSuccessCallback_5->Cancel(), mOnFailureCallback_5->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_5; + delete mOnSuccessCallback_5; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaNext_5_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Next Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_5; + delete runner->mOnSuccessCallback_5; + + if (runner->mIsFailureExpected_5 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaNext_5_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Next Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_5; + delete runner->mOnSuccessCallback_5; + + if (runner->mIsFailureExpected_5 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Rewind Command + typedef void (*SuccessCallback_6)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_6 = nullptr; + chip::Callback::Callback * mOnFailureCallback_6 = nullptr; + bool mIsFailureExpected_6 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaRewind_6() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Rewind Command: Sending command..."); + + mOnFailureCallback_6 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaRewind_6_FailureResponse, this); + mOnSuccessCallback_6 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaRewind_6_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaRewind(mOnSuccessCallback_6->Cancel(), mOnFailureCallback_6->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_6; + delete mOnSuccessCallback_6; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaRewind_6_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Rewind Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_6; + delete runner->mOnSuccessCallback_6; + + if (runner->mIsFailureExpected_6 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaRewind_6_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Rewind Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_6; + delete runner->mOnSuccessCallback_6; + + if (runner->mIsFailureExpected_6 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Fast Forward Command + typedef void (*SuccessCallback_7)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_7 = nullptr; + chip::Callback::Callback * mOnFailureCallback_7 = nullptr; + bool mIsFailureExpected_7 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaFastForward_7() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Fast Forward Command: Sending command..."); + + mOnFailureCallback_7 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaFastForward_7_FailureResponse, this); + mOnSuccessCallback_7 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaFastForward_7_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.MediaFastForward(mOnSuccessCallback_7->Cancel(), mOnFailureCallback_7->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_7; + delete mOnSuccessCallback_7; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaFastForward_7_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Fast Forward Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_7; + delete runner->mOnSuccessCallback_7; + + if (runner->mIsFailureExpected_7 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaFastForward_7_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Fast Forward Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_7; + delete runner->mOnSuccessCallback_7; + + if (runner->mIsFailureExpected_7 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Skip Forward Command + typedef void (*SuccessCallback_8)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_8 = nullptr; + chip::Callback::Callback * mOnFailureCallback_8 = nullptr; + bool mIsFailureExpected_8 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaSkipForward_8() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Skip Forward Command: Sending command..."); + + mOnFailureCallback_8 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaSkipForward_8_FailureResponse, this); + mOnSuccessCallback_8 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaSkipForward_8_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint64_t deltaPositionMillisecondsArgument = 100ULL; + err = cluster.MediaSkipForward(mOnSuccessCallback_8->Cancel(), mOnFailureCallback_8->Cancel(), + deltaPositionMillisecondsArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_8; + delete mOnSuccessCallback_8; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaSkipForward_8_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Skip Forward Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_8; + delete runner->mOnSuccessCallback_8; + + if (runner->mIsFailureExpected_8 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaSkipForward_8_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Skip Forward Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_8; + delete runner->mOnSuccessCallback_8; + + if (runner->mIsFailureExpected_8 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Skip Backward Command + typedef void (*SuccessCallback_9)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_9 = nullptr; + chip::Callback::Callback * mOnFailureCallback_9 = nullptr; + bool mIsFailureExpected_9 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaSkipBackward_9() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Skip Backward Command: Sending command..."); + + mOnFailureCallback_9 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaSkipBackward_9_FailureResponse, this); + mOnSuccessCallback_9 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaSkipBackward_9_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint64_t deltaPositionMillisecondsArgument = 100ULL; + err = cluster.MediaSkipBackward(mOnSuccessCallback_9->Cancel(), mOnFailureCallback_9->Cancel(), + deltaPositionMillisecondsArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_9; + delete mOnSuccessCallback_9; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaSkipBackward_9_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Skip Backward Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_9; + delete runner->mOnSuccessCallback_9; + + if (runner->mIsFailureExpected_9 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaSkipBackward_9_SuccessResponse(void * context, + uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Skip Backward Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_9; + delete runner->mOnSuccessCallback_9; + + if (runner->mIsFailureExpected_9 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Media Playback Seek Command + typedef void (*SuccessCallback_10)(void * context, uint8_t mediaPlaybackStatus); + chip::Callback::Callback * mOnSuccessCallback_10 = nullptr; + chip::Callback::Callback * mOnFailureCallback_10 = nullptr; + bool mIsFailureExpected_10 = 0; + + CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaSeek_10() + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Seek Command: Sending command..."); + + mOnFailureCallback_10 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaSeek_10_FailureResponse, this); + mOnSuccessCallback_10 = new chip::Callback::Callback( + OnTestSendClusterMediaPlaybackCommandMediaSeek_10_SuccessResponse, this); + + chip::Controller::MediaPlaybackCluster cluster; + cluster.Associate(mDevice, 3); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint64_t positionArgument = 100ULL; + err = cluster.MediaSeek(mOnSuccessCallback_10->Cancel(), mOnFailureCallback_10->Cancel(), positionArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_10; + delete mOnSuccessCallback_10; + } + + return err; + } + + static void OnTestSendClusterMediaPlaybackCommandMediaSeek_10_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Seek Command: Failure Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_10; + delete runner->mOnSuccessCallback_10; + + if (runner->mIsFailureExpected_10 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaPlaybackCommandMediaSeek_10_SuccessResponse(void * context, uint8_t mediaPlaybackStatus) + { + ChipLogProgress(chipTool, "Media Playback - Media Playback Seek Command: Success Response"); + + TV_MediaPlaybackCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_10; + delete runner->mOnSuccessCallback_10; + + if (runner->mIsFailureExpected_10 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (mediaPlaybackStatus != 0) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "0"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_TvChannelCluster : public TestCommand +{ +public: + TV_TvChannelCluster() : TestCommand("TV_TvChannelCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_TvChannelCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterTvChannelCommandReadAttribute_0(); + break; + case 1: + err = TestSendClusterTvChannelCommandChangeChannelByNumber_1(); + break; + case 2: + err = TestSendClusterTvChannelCommandSkipChannel_2(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_TvChannelCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 3; + + // + // Tests methods + // + + // Test Read attribute TV Channel list + typedef void (*SuccessCallback_0)(void * context, uint16_t count, _TvChannelInfo * tvChannelList); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterTvChannelCommandReadAttribute_0() + { + ChipLogProgress(chipTool, "TV Channel - Read attribute TV Channel list: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterTvChannelCommandReadAttribute_0_FailureResponse, this); + mOnSuccessCallback_0 = + new chip::Callback::Callback(OnTestSendClusterTvChannelCommandReadAttribute_0_SuccessResponse, this); + + chip::Controller::TvChannelCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeTvChannelList(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterTvChannelCommandReadAttribute_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "TV Channel - Read attribute TV Channel list: Failure Response"); + + TV_TvChannelCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterTvChannelCommandReadAttribute_0_SuccessResponse(void * context, uint16_t count, + _TvChannelInfo * tvChannelList) + { + ChipLogProgress(chipTool, "TV Channel - Read attribute TV Channel list: Success Response"); + + TV_TvChannelCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (count != 2) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "[object Object],[object Object]"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Change Channel By Number Command + typedef void (*SuccessCallback_1)(void * context); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterTvChannelCommandChangeChannelByNumber_1() + { + ChipLogProgress(chipTool, "TV Channel - Change Channel By Number Command: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterTvChannelCommandChangeChannelByNumber_1_FailureResponse, this); + mOnSuccessCallback_1 = new chip::Callback::Callback( + OnTestSendClusterTvChannelCommandChangeChannelByNumber_1_SuccessResponse, this); + + chip::Controller::TvChannelCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint16_t majorNumberArgument = 1U; + uint16_t minorNumberArgument = 2U; + err = cluster.ChangeChannelByNumber(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel(), majorNumberArgument, + minorNumberArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterTvChannelCommandChangeChannelByNumber_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "TV Channel - Change Channel By Number Command: Failure Response"); + + TV_TvChannelCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterTvChannelCommandChangeChannelByNumber_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "TV Channel - Change Channel By Number Command: Success Response"); + + TV_TvChannelCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Skip Channel Command + typedef void (*SuccessCallback_2)(void * context); + chip::Callback::Callback * mOnSuccessCallback_2 = nullptr; + chip::Callback::Callback * mOnFailureCallback_2 = nullptr; + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterTvChannelCommandSkipChannel_2() + { + ChipLogProgress(chipTool, "TV Channel - Skip Channel Command: Sending command..."); + + mOnFailureCallback_2 = new chip::Callback::Callback( + OnTestSendClusterTvChannelCommandSkipChannel_2_FailureResponse, this); + mOnSuccessCallback_2 = + new chip::Callback::Callback(OnTestSendClusterTvChannelCommandSkipChannel_2_SuccessResponse, this); + + chip::Controller::TvChannelCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint16_t countArgument = 1U; + err = cluster.SkipChannel(mOnSuccessCallback_2->Cancel(), mOnFailureCallback_2->Cancel(), countArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_2; + delete mOnSuccessCallback_2; + } + + return err; + } + + static void OnTestSendClusterTvChannelCommandSkipChannel_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "TV Channel - Skip Channel Command: Failure Response"); + + TV_TvChannelCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterTvChannelCommandSkipChannel_2_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "TV Channel - Skip Channel Command: Success Response"); + + TV_TvChannelCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_LowPowerCluster : public TestCommand +{ +public: + TV_LowPowerCluster() : TestCommand("TV_LowPowerCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_LowPowerCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterLowPowerCommandSleep_0(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_LowPowerCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 1; + + // + // Tests methods + // + + // Test Sleep Input Status Command + typedef void (*SuccessCallback_0)(void * context); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterLowPowerCommandSleep_0() + { + ChipLogProgress(chipTool, "Low Power - Sleep Input Status Command: Sending command..."); + + mOnFailureCallback_0 = + new chip::Callback::Callback(OnTestSendClusterLowPowerCommandSleep_0_FailureResponse, this); + mOnSuccessCallback_0 = + new chip::Callback::Callback(OnTestSendClusterLowPowerCommandSleep_0_SuccessResponse, this); + + chip::Controller::LowPowerCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.Sleep(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterLowPowerCommandSleep_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Low Power - Sleep Input Status Command: Failure Response"); + + TV_LowPowerCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterLowPowerCommandSleep_0_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Low Power - Sleep Input Status Command: Success Response"); + + TV_LowPowerCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + +class TV_MediaInputCluster : public TestCommand +{ +public: + TV_MediaInputCluster() : TestCommand("TV_MediaInputCluster"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TV_MediaInputCluster: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterMediaInputCommandReadAttribute_0(); + break; + case 1: + err = TestSendClusterMediaInputCommandSelectInput_1(); + break; + case 2: + err = TestSendClusterMediaInputCommandHideInputStatus_2(); + break; + case 3: + err = TestSendClusterMediaInputCommandShowInputStatus_3(); + break; + case 4: + err = TestSendClusterMediaInputCommandRenameInput_4(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TV_MediaInputCluster: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 5; + + // + // Tests methods + // + + // Test Read attribute media input list + typedef void (*SuccessCallback_0)(void * context, uint16_t count, _MediaInputInfo * mediaInputList); + chip::Callback::Callback * mOnSuccessCallback_0 = nullptr; + chip::Callback::Callback * mOnFailureCallback_0 = nullptr; + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterMediaInputCommandReadAttribute_0() + { + ChipLogProgress(chipTool, "Media Input - Read attribute media input list: Sending command..."); + + mOnFailureCallback_0 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandReadAttribute_0_FailureResponse, this); + mOnSuccessCallback_0 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandReadAttribute_0_SuccessResponse, this); + + chip::Controller::MediaInputCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ReadAttributeMediaInputList(mOnSuccessCallback_0->Cancel(), mOnFailureCallback_0->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_0; + delete mOnSuccessCallback_0; + } + + return err; + } + + static void OnTestSendClusterMediaInputCommandReadAttribute_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Input - Read attribute media input list: Failure Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaInputCommandReadAttribute_0_SuccessResponse(void * context, uint16_t count, + _MediaInputInfo * mediaInputList) + { + ChipLogProgress(chipTool, "Media Input - Read attribute media input list: Success Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_0; + delete runner->mOnSuccessCallback_0; + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (count != 2) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "[object Object],[object Object]"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Select Input Command + typedef void (*SuccessCallback_1)(void * context); + chip::Callback::Callback * mOnSuccessCallback_1 = nullptr; + chip::Callback::Callback * mOnFailureCallback_1 = nullptr; + bool mIsFailureExpected_1 = 0; + + CHIP_ERROR TestSendClusterMediaInputCommandSelectInput_1() + { + ChipLogProgress(chipTool, "Media Input - Select Input Command: Sending command..."); + + mOnFailureCallback_1 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandSelectInput_1_FailureResponse, this); + mOnSuccessCallback_1 = + new chip::Callback::Callback(OnTestSendClusterMediaInputCommandSelectInput_1_SuccessResponse, this); + + chip::Controller::MediaInputCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t indexArgument = 1; + err = cluster.SelectInput(mOnSuccessCallback_1->Cancel(), mOnFailureCallback_1->Cancel(), indexArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_1; + delete mOnSuccessCallback_1; + } + + return err; + } + + static void OnTestSendClusterMediaInputCommandSelectInput_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Input - Select Input Command: Failure Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaInputCommandSelectInput_1_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Media Input - Select Input Command: Success Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_1; + delete runner->mOnSuccessCallback_1; + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Hide Input Status Command + typedef void (*SuccessCallback_2)(void * context); + chip::Callback::Callback * mOnSuccessCallback_2 = nullptr; + chip::Callback::Callback * mOnFailureCallback_2 = nullptr; + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterMediaInputCommandHideInputStatus_2() + { + ChipLogProgress(chipTool, "Media Input - Hide Input Status Command: Sending command..."); + + mOnFailureCallback_2 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandHideInputStatus_2_FailureResponse, this); + mOnSuccessCallback_2 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandHideInputStatus_2_SuccessResponse, this); + + chip::Controller::MediaInputCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.HideInputStatus(mOnSuccessCallback_2->Cancel(), mOnFailureCallback_2->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_2; + delete mOnSuccessCallback_2; + } + + return err; + } + + static void OnTestSendClusterMediaInputCommandHideInputStatus_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Input - Hide Input Status Command: Failure Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaInputCommandHideInputStatus_2_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Media Input - Hide Input Status Command: Success Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_2; + delete runner->mOnSuccessCallback_2; + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Show Input Status Command + typedef void (*SuccessCallback_3)(void * context); + chip::Callback::Callback * mOnSuccessCallback_3 = nullptr; + chip::Callback::Callback * mOnFailureCallback_3 = nullptr; + bool mIsFailureExpected_3 = 0; + + CHIP_ERROR TestSendClusterMediaInputCommandShowInputStatus_3() + { + ChipLogProgress(chipTool, "Media Input - Show Input Status Command: Sending command..."); + + mOnFailureCallback_3 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandShowInputStatus_3_FailureResponse, this); + mOnSuccessCallback_3 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandShowInputStatus_3_SuccessResponse, this); + + chip::Controller::MediaInputCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.ShowInputStatus(mOnSuccessCallback_3->Cancel(), mOnFailureCallback_3->Cancel()); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_3; + delete mOnSuccessCallback_3; + } + + return err; + } + + static void OnTestSendClusterMediaInputCommandShowInputStatus_3_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Input - Show Input Status Command: Failure Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_3; + delete runner->mOnSuccessCallback_3; + + if (runner->mIsFailureExpected_3 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaInputCommandShowInputStatus_3_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Media Input - Show Input Status Command: Success Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_3; + delete runner->mOnSuccessCallback_3; + + if (runner->mIsFailureExpected_3 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Rename Input Command + typedef void (*SuccessCallback_4)(void * context); + chip::Callback::Callback * mOnSuccessCallback_4 = nullptr; + chip::Callback::Callback * mOnFailureCallback_4 = nullptr; + bool mIsFailureExpected_4 = 0; + + CHIP_ERROR TestSendClusterMediaInputCommandRenameInput_4() + { + ChipLogProgress(chipTool, "Media Input - Rename Input Command: Sending command..."); + + mOnFailureCallback_4 = new chip::Callback::Callback( + OnTestSendClusterMediaInputCommandRenameInput_4_FailureResponse, this); + mOnSuccessCallback_4 = + new chip::Callback::Callback(OnTestSendClusterMediaInputCommandRenameInput_4_SuccessResponse, this); + + chip::Controller::MediaInputCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + uint8_t indexArgument = 1; + chip::ByteSpan nameArgument = chip::ByteSpan(chip::Uint8::from_const_char("newName"), strlen("newName")); + err = cluster.RenameInput(mOnSuccessCallback_4->Cancel(), mOnFailureCallback_4->Cancel(), indexArgument, nameArgument); + + if (CHIP_NO_ERROR != err) + { + delete mOnFailureCallback_4; + delete mOnSuccessCallback_4; + } + + return err; + } + + static void OnTestSendClusterMediaInputCommandRenameInput_4_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "Media Input - Rename Input Command: Failure Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_4; + delete runner->mOnSuccessCallback_4; + + if (runner->mIsFailureExpected_4 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterMediaInputCommandRenameInput_4_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "Media Input - Rename Input Command: Success Response"); + + TV_MediaInputCluster * runner = reinterpret_cast(context); + + delete runner->mOnFailureCallback_4; + delete runner->mOnSuccessCallback_4; + + if (runner->mIsFailureExpected_4 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } +}; + class TestCluster : public TestCommand { public: @@ -11831,9 +15066,23 @@ void registerCommandsTests(Commands & commands) const char * clusterName = "Tests"; commands_list clusterCommands = { - make_unique(), make_unique(), make_unique(), - make_unique(), make_unique(), make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), + make_unique(), }; commands.Register(clusterName, clusterCommands); -} \ No newline at end of file +} diff --git a/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp index 10b1871e71ad59..056669bbd73226 100644 --- a/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp +++ b/examples/tv-app/linux/include/application-launcher/ApplicationLauncherManager.cpp @@ -17,12 +17,7 @@ */ #include "ApplicationLauncherManager.h" -#include #include -#include -#include -#include -#include #include #include @@ -49,9 +44,9 @@ ApplicationLauncherResponse applicationLauncherClusterLaunchApp(EmberAfApplicati { // TODO: Insert your code ApplicationLauncherResponse response; - char testData[] = "data"; - response.data = (uint8_t *) testData; - response.status = EMBER_ZCL_APPLICATION_LAUNCHER_STATUS_SUCCESS; + const char * testData = "data"; + response.data = (uint8_t *) testData; + response.status = EMBER_ZCL_APPLICATION_LAUNCHER_STATUS_SUCCESS; // TODO: Update once storing a structure attribute is supported // emberAfWriteServerAttribute(endpoint, ZCL_APPLICATION_LAUNCH_CLUSTER_ID, ZCL_APPLICATION_LAUNCHER_CURRENT_APP_APPLICATION_ID, // (uint8_t *) &application, ZCL_STRUCT_ATTRIBUTE_TYPE); diff --git a/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp b/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp index 8fbd7856693ab0..0c0331dedd5c6d 100644 --- a/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp +++ b/examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp @@ -18,11 +18,6 @@ #include "AudioOutputManager.h" -#include -#include -#include -#include -#include #include #include #include diff --git a/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp b/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp index 7bd49fc94071da..58a39ab91bb6b4 100644 --- a/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp +++ b/examples/tv-app/linux/include/keypad-input/KeypadInputManager.cpp @@ -18,11 +18,6 @@ #include "KeypadInputManager.h" -#include -#include -#include -#include -#include #include #include diff --git a/examples/tv-app/linux/include/low-power/LowPowerManager.cpp b/examples/tv-app/linux/include/low-power/LowPowerManager.cpp index a4fff8ff02393f..97016d4b01a74f 100644 --- a/examples/tv-app/linux/include/low-power/LowPowerManager.cpp +++ b/examples/tv-app/linux/include/low-power/LowPowerManager.cpp @@ -18,13 +18,6 @@ #include "LowPowerManager.h" -#include -#include -#include -#include -#include -#include - bool lowPowerClusterSleep() { // TODO: Insert code here diff --git a/examples/tv-app/linux/include/media-input/MediaInputManager.cpp b/examples/tv-app/linux/include/media-input/MediaInputManager.cpp index 48542edaaa5070..610defa80816a0 100644 --- a/examples/tv-app/linux/include/media-input/MediaInputManager.cpp +++ b/examples/tv-app/linux/include/media-input/MediaInputManager.cpp @@ -16,10 +16,7 @@ */ #include "MediaInputManager.h" -#include -#include -#include -#include + #include #include #include diff --git a/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp b/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp index df249a8902e046..2e69bbcbb9efdc 100644 --- a/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp +++ b/examples/tv-app/linux/include/target-navigator/TargetNavigatorManager.cpp @@ -16,12 +16,7 @@ */ #include "TargetNavigatorManager.h" -#include #include -#include -#include -#include -#include #include #include #include @@ -63,8 +58,8 @@ TargetNavigatorResponse targetNavigatorClusterNavigateTarget(uint8_t target, std { // TODO: Insert code here TargetNavigatorResponse response; - char testData[] = "data response"; - response.data = (uint8_t *) testData; - response.status = EMBER_ZCL_APPLICATION_LAUNCHER_STATUS_SUCCESS; + const char * testData = "data response"; + response.data = (uint8_t *) testData; + response.status = EMBER_ZCL_APPLICATION_LAUNCHER_STATUS_SUCCESS; return response; } diff --git a/examples/tv-app/linux/include/tv-channel/TvChannelManager.cpp b/examples/tv-app/linux/include/tv-channel/TvChannelManager.cpp index 744e4774b82eeb..a9012e7fd58e47 100644 --- a/examples/tv-app/linux/include/tv-channel/TvChannelManager.cpp +++ b/examples/tv-app/linux/include/tv-channel/TvChannelManager.cpp @@ -16,12 +16,6 @@ */ #include "TvChannelManager.h" -#include -#include -#include -#include -#include -#include #include #include #include diff --git a/examples/tv-app/tv-common/gen/IMClusterCommandHandler.cpp b/examples/tv-app/tv-common/gen/IMClusterCommandHandler.cpp index 9f5be67ab42f8d..30634007af3a40 100644 --- a/examples/tv-app/tv-common/gen/IMClusterCommandHandler.cpp +++ b/examples/tv-app/tv-common/gen/IMClusterCommandHandler.cpp @@ -38,6 +38,182 @@ namespace app { namespace clusters { +namespace AccountLogin { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::AccountLogin::Commands::Ids::GetSetupPIN: { + expectArgumentCount = 1; + const uint8_t * tempAccountIdentifier; + bool argExists[1]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 1) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(tempAccountIdentifier); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = + emberAfAccountLoginClusterGetSetupPINCallback(apCommandObj, const_cast(tempAccountIdentifier)); + } + break; + } + case Clusters::AccountLogin::Commands::Ids::Login: { + expectArgumentCount = 2; + const uint8_t * tempAccountIdentifier; + const uint8_t * setupPIN; + bool argExists[2]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 2) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(tempAccountIdentifier); + break; + case 1: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(setupPIN); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfAccountLoginClusterLoginCallback(apCommandObj, const_cast(tempAccountIdentifier), + const_cast(setupPIN)); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::AccountLogin::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::AccountLogin::Id); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::AccountLogin::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace AccountLogin + namespace ApplicationBasic { void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) @@ -146,6 +322,125 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } // namespace ApplicationBasic +namespace ApplicationLauncher { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::ApplicationLauncher::Commands::Ids::LaunchApp: { + expectArgumentCount = 3; + const uint8_t * data; + uint16_t catalogVendorId; + const uint8_t * applicationId; + bool argExists[3]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 3) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(data); + break; + case 1: + TLVUnpackError = aDataTlv.Get(catalogVendorId); + break; + case 2: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(applicationId); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfApplicationLauncherClusterLaunchAppCallback( + apCommandObj, const_cast(data), catalogVendorId, const_cast(applicationId)); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::ApplicationLauncher::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::ApplicationLauncher::Id); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::ApplicationLauncher::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace ApplicationLauncher + namespace AudioOutput { void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) @@ -968,7 +1263,126 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 4) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(location); + break; + case 1: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(countryCode); + break; + case 2: + TLVUnpackError = aDataTlv.Get(breadcrumb); + break; + case 3: + TLVUnpackError = aDataTlv.Get(timeoutMs); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback( + apCommandObj, location, const_cast(countryCode), breadcrumb, timeoutMs); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::GeneralCommissioning::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::GeneralCommissioning::Id); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::GeneralCommissioning::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace GeneralCommissioning + +namespace KeypadInput { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::KeypadInput::Commands::Ids::SendKey: { + expectArgumentCount = 1; + uint8_t keyCode; + bool argExists[1]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 1) { if (argExists[currentDecodeTagId]) { @@ -985,17 +1399,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(location); - break; - case 1: - // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. - TLVUnpackError = aDataTlv.GetDataPtr(countryCode); - break; - case 2: - TLVUnpackError = aDataTlv.Get(breadcrumb); - break; - case 3: - TLVUnpackError = aDataTlv.Get(timeoutMs); + TLVUnpackError = aDataTlv.Get(keyCode); break; default: // Unsupported tag, ignore it. @@ -1014,11 +1418,10 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback( - apCommandObj, location, const_cast(countryCode), breadcrumb, timeoutMs); + wasHandled = emberAfKeypadInputClusterSendKeyCallback(apCommandObj, keyCode); } break; } @@ -1026,12 +1429,12 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En // Unrecognized command ID, error status will apply. chip::app::CommandPathParams returnStatusParam = { aEndpointId, 0, // GroupId - Clusters::GeneralCommissioning::Id, aCommandId, + Clusters::KeypadInput::Id, aCommandId, (chip::app::CommandPathFlags::kEndpointIdValid) }; apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); - ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::GeneralCommissioning::Id); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::KeypadInput::Id); return; } } @@ -1041,7 +1444,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En { chip::app::CommandPathParams returnStatusParam = { aEndpointId, 0, // GroupId - Clusters::GeneralCommissioning::Id, aCommandId, + Clusters::KeypadInput::Id, aCommandId, (chip::app::CommandPathFlags::kEndpointIdValid) }; apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); @@ -1052,7 +1455,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } } -} // namespace GeneralCommissioning +} // namespace KeypadInput namespace LevelControl { @@ -1584,6 +1987,245 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } // namespace LevelControl +namespace LowPower { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::LowPower::Commands::Ids::Sleep: { + + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfLowPowerClusterSleepCallback(apCommandObj); + break; + } + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::LowPower::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::LowPower::Id); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::LowPower::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace LowPower + +namespace MediaInput { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::MediaInput::Commands::Ids::HideInputStatus: { + + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfMediaInputClusterHideInputStatusCallback(apCommandObj); + break; + } + case Clusters::MediaInput::Commands::Ids::RenameInput: { + expectArgumentCount = 2; + uint8_t index; + const uint8_t * name; + bool argExists[2]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 2) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(index); + break; + case 1: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(name); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfMediaInputClusterRenameInputCallback(apCommandObj, index, const_cast(name)); + } + break; + } + case Clusters::MediaInput::Commands::Ids::SelectInput: { + expectArgumentCount = 1; + uint8_t index; + bool argExists[1]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 1) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(index); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfMediaInputClusterSelectInputCallback(apCommandObj, index); + } + break; + } + case Clusters::MediaInput::Commands::Ids::ShowInputStatus: { + + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfMediaInputClusterShowInputStatusCallback(apCommandObj); + break; + } + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::MediaInput::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::MediaInput::Id); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::MediaInput::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace MediaInput + namespace MediaPlayback { void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) @@ -1637,9 +2279,9 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En wasHandled = emberAfMediaPlaybackClusterMediaRewindCallback(apCommandObj); break; } - case Clusters::MediaPlayback::Commands::Ids::MediaSkipBackward: { + case Clusters::MediaPlayback::Commands::Ids::MediaSeek: { expectArgumentCount = 1; - uint64_t deltaPositionMilliseconds; + uint64_t position; bool argExists[1]; memset(argExists, 0, sizeof argExists); @@ -1670,7 +2312,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(deltaPositionMilliseconds); + TLVUnpackError = aDataTlv.Get(position); break; default: // Unsupported tag, ignore it. @@ -1692,11 +2334,11 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfMediaPlaybackClusterMediaSkipBackwardCallback(apCommandObj, deltaPositionMilliseconds); + wasHandled = emberAfMediaPlaybackClusterMediaSeekCallback(apCommandObj, position); } break; } - case Clusters::MediaPlayback::Commands::Ids::MediaSkipForward: { + case Clusters::MediaPlayback::Commands::Ids::MediaSkipBackward: { expectArgumentCount = 1; uint64_t deltaPositionMilliseconds; bool argExists[1]; @@ -1751,13 +2393,13 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfMediaPlaybackClusterMediaSkipForwardCallback(apCommandObj, deltaPositionMilliseconds); + wasHandled = emberAfMediaPlaybackClusterMediaSkipBackwardCallback(apCommandObj, deltaPositionMilliseconds); } break; } - case Clusters::MediaPlayback::Commands::Ids::MediaSkipSeek: { + case Clusters::MediaPlayback::Commands::Ids::MediaSkipForward: { expectArgumentCount = 1; - uint64_t position; + uint64_t deltaPositionMilliseconds; bool argExists[1]; memset(argExists, 0, sizeof argExists); @@ -1788,7 +2430,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(position); + TLVUnpackError = aDataTlv.Get(deltaPositionMilliseconds); break; default: // Unsupported tag, ignore it. @@ -1810,7 +2452,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfMediaPlaybackClusterMediaSkipSeekCallback(apCommandObj, position); + wasHandled = emberAfMediaPlaybackClusterMediaSkipForwardCallback(apCommandObj, deltaPositionMilliseconds); } break; } @@ -2932,7 +3574,279 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 4) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: { + const uint8_t * data = nullptr; + TLVUnpackError = aDataTlv.GetDataPtr(data); + NOCArray = chip::ByteSpan(data, aDataTlv.GetLength()); + } + break; + case 1: { + const uint8_t * data = nullptr; + TLVUnpackError = aDataTlv.GetDataPtr(data); + IPKValue = chip::ByteSpan(data, aDataTlv.GetLength()); + } + break; + case 2: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 3: + TLVUnpackError = aDataTlv.Get(AdminVendorId); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfOperationalCredentialsClusterAddOpCertCallback(apCommandObj, NOCArray, IPKValue, CaseAdminNode, + AdminVendorId); + } + break; + } + case Clusters::OperationalCredentials::Commands::Ids::AddTrustedRootCertificate: { + expectArgumentCount = 1; + chip::ByteSpan RootCertificate; + bool argExists[1]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 1) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: { + const uint8_t * data = nullptr; + TLVUnpackError = aDataTlv.GetDataPtr(data); + RootCertificate = chip::ByteSpan(data, aDataTlv.GetLength()); + } + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfOperationalCredentialsClusterAddTrustedRootCertificateCallback(apCommandObj, RootCertificate); + } + break; + } + case Clusters::OperationalCredentials::Commands::Ids::OpCSRRequest: { + expectArgumentCount = 1; + chip::ByteSpan CSRNonce; + bool argExists[1]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 1) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: { + const uint8_t * data = nullptr; + TLVUnpackError = aDataTlv.GetDataPtr(data); + CSRNonce = chip::ByteSpan(data, aDataTlv.GetLength()); + } + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfOperationalCredentialsClusterOpCSRRequestCallback(apCommandObj, CSRNonce); + } + break; + } + case Clusters::OperationalCredentials::Commands::Ids::RemoveAllFabrics: { + + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfOperationalCredentialsClusterRemoveAllFabricsCallback(apCommandObj); + break; + } + case Clusters::OperationalCredentials::Commands::Ids::RemoveFabric: { + expectArgumentCount = 3; + chip::FabricId FabricId; + chip::NodeId NodeId; + uint16_t VendorId; + bool argExists[3]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 3) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(FabricId); + break; + case 1: + TLVUnpackError = aDataTlv.Get(NodeId); + break; + case 2: + TLVUnpackError = aDataTlv.Get(VendorId); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount) + { + // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. + wasHandled = emberAfOperationalCredentialsClusterRemoveFabricCallback(apCommandObj, FabricId, NodeId, VendorId); + } + break; + } + case Clusters::OperationalCredentials::Commands::Ids::RemoveTrustedRootCertificate: { + expectArgumentCount = 1; + chip::ByteSpan TrustedRootIdentifier; + bool argExists[1]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 1) { if (argExists[currentDecodeTagId]) { @@ -2949,23 +3863,11 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: { - const uint8_t * data = nullptr; - TLVUnpackError = aDataTlv.GetDataPtr(data); - NOCArray = chip::ByteSpan(data, aDataTlv.GetLength()); - } - break; - case 1: { - const uint8_t * data = nullptr; - TLVUnpackError = aDataTlv.GetDataPtr(data); - IPKValue = chip::ByteSpan(data, aDataTlv.GetLength()); + const uint8_t * data = nullptr; + TLVUnpackError = aDataTlv.GetDataPtr(data); + TrustedRootIdentifier = chip::ByteSpan(data, aDataTlv.GetLength()); } break; - case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); - break; - case 3: - TLVUnpackError = aDataTlv.Get(AdminVendorId); - break; default: // Unsupported tag, ignore it. ChipLogProgress(Zcl, "Unknown TLV tag during processing."); @@ -2983,17 +3885,17 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfOperationalCredentialsClusterAddOpCertCallback(apCommandObj, NOCArray, IPKValue, CaseAdminNode, - AdminVendorId); + wasHandled = + emberAfOperationalCredentialsClusterRemoveTrustedRootCertificateCallback(apCommandObj, TrustedRootIdentifier); } break; } - case Clusters::OperationalCredentials::Commands::Ids::AddTrustedRootCertificate: { + case Clusters::OperationalCredentials::Commands::Ids::SetFabric: { expectArgumentCount = 1; - chip::ByteSpan RootCertificate; + uint16_t VendorId; bool argExists[1]; memset(argExists, 0, sizeof argExists); @@ -3023,12 +3925,9 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } switch (currentDecodeTagId) { - case 0: { - const uint8_t * data = nullptr; - TLVUnpackError = aDataTlv.GetDataPtr(data); - RootCertificate = chip::ByteSpan(data, aDataTlv.GetLength()); - } - break; + case 0: + TLVUnpackError = aDataTlv.Get(VendorId); + break; default: // Unsupported tag, ignore it. ChipLogProgress(Zcl, "Unknown TLV tag during processing."); @@ -3049,13 +3948,13 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfOperationalCredentialsClusterAddTrustedRootCertificateCallback(apCommandObj, RootCertificate); + wasHandled = emberAfOperationalCredentialsClusterSetFabricCallback(apCommandObj, VendorId); } break; } - case Clusters::OperationalCredentials::Commands::Ids::OpCSRRequest: { + case Clusters::OperationalCredentials::Commands::Ids::UpdateFabricLabel: { expectArgumentCount = 1; - chip::ByteSpan CSRNonce; + const uint8_t * Label; bool argExists[1]; memset(argExists, 0, sizeof argExists); @@ -3085,12 +3984,10 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } switch (currentDecodeTagId) { - case 0: { - const uint8_t * data = nullptr; - TLVUnpackError = aDataTlv.GetDataPtr(data); - CSRNonce = chip::ByteSpan(data, aDataTlv.GetLength()); - } - break; + case 0: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(Label); + break; default: // Unsupported tag, ignore it. ChipLogProgress(Zcl, "Unknown TLV tag during processing."); @@ -3111,22 +4008,64 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfOperationalCredentialsClusterOpCSRRequestCallback(apCommandObj, CSRNonce); + wasHandled = + emberAfOperationalCredentialsClusterUpdateFabricLabelCallback(apCommandObj, const_cast(Label)); } break; } - case Clusters::OperationalCredentials::Commands::Ids::RemoveAllFabrics: { - - // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfOperationalCredentialsClusterRemoveAllFabricsCallback(apCommandObj); - break; + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::OperationalCredentials::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::OperationalCredentials::Id); + return; } - case Clusters::OperationalCredentials::Commands::Ids::RemoveFabric: { - expectArgumentCount = 3; - chip::FabricId FabricId; - chip::NodeId NodeId; - uint16_t VendorId; - bool argExists[3]; + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::OperationalCredentials::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace OperationalCredentials + +namespace TvChannel { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::TvChannel::Commands::Ids::ChangeChannel: { + expectArgumentCount = 1; + const uint8_t * match; + bool argExists[1]; memset(argExists, 0, sizeof argExists); @@ -3139,7 +4078,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 3) + if (currentDecodeTagId < 1) { if (argExists[currentDecodeTagId]) { @@ -3156,13 +4095,8 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(FabricId); - break; - case 1: - TLVUnpackError = aDataTlv.Get(NodeId); - break; - case 2: - TLVUnpackError = aDataTlv.Get(VendorId); + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(match); break; default: // Unsupported tag, ignore it. @@ -3181,17 +4115,18 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfOperationalCredentialsClusterRemoveFabricCallback(apCommandObj, FabricId, NodeId, VendorId); + wasHandled = emberAfTvChannelClusterChangeChannelCallback(apCommandObj, const_cast(match)); } break; } - case Clusters::OperationalCredentials::Commands::Ids::RemoveTrustedRootCertificate: { - expectArgumentCount = 1; - chip::ByteSpan TrustedRootIdentifier; - bool argExists[1]; + case Clusters::TvChannel::Commands::Ids::ChangeChannelByNumber: { + expectArgumentCount = 2; + uint16_t majorNumber; + uint16_t minorNumber; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -3204,7 +4139,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -3220,12 +4155,12 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } switch (currentDecodeTagId) { - case 0: { - const uint8_t * data = nullptr; - TLVUnpackError = aDataTlv.GetDataPtr(data); - TrustedRootIdentifier = chip::ByteSpan(data, aDataTlv.GetLength()); - } - break; + case 0: + TLVUnpackError = aDataTlv.Get(majorNumber); + break; + case 1: + TLVUnpackError = aDataTlv.Get(minorNumber); + break; default: // Unsupported tag, ignore it. ChipLogProgress(Zcl, "Unknown TLV tag during processing."); @@ -3243,17 +4178,16 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = - emberAfOperationalCredentialsClusterRemoveTrustedRootCertificateCallback(apCommandObj, TrustedRootIdentifier); + wasHandled = emberAfTvChannelClusterChangeChannelByNumberCallback(apCommandObj, majorNumber, minorNumber); } break; } - case Clusters::OperationalCredentials::Commands::Ids::SetFabric: { + case Clusters::TvChannel::Commands::Ids::SkipChannel: { expectArgumentCount = 1; - uint16_t VendorId; + uint16_t Count; bool argExists[1]; memset(argExists, 0, sizeof argExists); @@ -3284,7 +4218,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(VendorId); + TLVUnpackError = aDataTlv.Get(Count); break; default: // Unsupported tag, ignore it. @@ -3306,14 +4240,64 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfOperationalCredentialsClusterSetFabricCallback(apCommandObj, VendorId); + wasHandled = emberAfTvChannelClusterSkipChannelCallback(apCommandObj, Count); } break; } - case Clusters::OperationalCredentials::Commands::Ids::UpdateFabricLabel: { - expectArgumentCount = 1; - const uint8_t * Label; - bool argExists[1]; + default: { + // Unrecognized command ID, error status will apply. + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::TvChannel::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, + Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::TvChannel::Id); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + chip::app::CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::TvChannel::Id, aCommandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId); + } +} + +} // namespace TvChannel + +namespace TargetNavigator { + +void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::TargetNavigator::Commands::Ids::NavigateTarget: { + expectArgumentCount = 2; + uint8_t target; + const uint8_t * data; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -3326,7 +4310,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -3343,8 +4327,11 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En switch (currentDecodeTagId) { case 0: + TLVUnpackError = aDataTlv.Get(target); + break; + case 1: // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. - TLVUnpackError = aDataTlv.GetDataPtr(Label); + TLVUnpackError = aDataTlv.GetDataPtr(data); break; default: // Unsupported tag, ignore it. @@ -3363,11 +4350,10 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = - emberAfOperationalCredentialsClusterUpdateFabricLabelCallback(apCommandObj, const_cast(Label)); + wasHandled = emberAfTargetNavigatorClusterNavigateTargetCallback(apCommandObj, target, const_cast(data)); } break; } @@ -3375,12 +4361,12 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En // Unrecognized command ID, error status will apply. chip::app::CommandPathParams returnStatusParam = { aEndpointId, 0, // GroupId - Clusters::OperationalCredentials::Id, aCommandId, + Clusters::TargetNavigator::Id, aCommandId, (chip::app::CommandPathFlags::kEndpointIdValid) }; apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); - ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::OperationalCredentials::Id); + ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::TargetNavigator::Id); return; } } @@ -3390,7 +4376,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En { chip::app::CommandPathParams returnStatusParam = { aEndpointId, 0, // GroupId - Clusters::OperationalCredentials::Id, aCommandId, + Clusters::TargetNavigator::Id, aCommandId, (chip::app::CommandPathFlags::kEndpointIdValid) }; apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); @@ -3401,7 +4387,7 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En } } -} // namespace OperationalCredentials +} // namespace TargetNavigator } // namespace clusters @@ -3415,9 +4401,15 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC SuccessOrExit(aReader.EnterContainer(dataTlvType)); switch (aClusterId) { + case Clusters::AccountLogin::Id: + clusters::AccountLogin::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; case Clusters::ApplicationBasic::Id: clusters::ApplicationBasic::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; + case Clusters::ApplicationLauncher::Id: + clusters::ApplicationLauncher::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; case Clusters::AudioOutput::Id: clusters::AudioOutput::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; @@ -3436,9 +4428,18 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC case Clusters::GeneralCommissioning::Id: clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; + case Clusters::KeypadInput::Id: + clusters::KeypadInput::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; case Clusters::LevelControl::Id: clusters::LevelControl::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; + case Clusters::LowPower::Id: + clusters::LowPower::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; + case Clusters::MediaInput::Id: + clusters::MediaInput::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; case Clusters::MediaPlayback::Id: clusters::MediaPlayback::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; @@ -3454,6 +4455,12 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC case Clusters::OperationalCredentials::Id: clusters::OperationalCredentials::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); break; + case Clusters::TvChannel::Id: + clusters::TvChannel::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; + case Clusters::TargetNavigator::Id: + clusters::TargetNavigator::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; default: // Unrecognized cluster ID, error status will apply. chip::app::CommandPathParams returnStatusParam = { aEndPointId, @@ -3471,4 +4478,4 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC } } // namespace app -} // namespace chip \ No newline at end of file +} // namespace chip 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 1ac4f2ef3075c2..4df1fbe994f2cc 100644 --- a/src/app/clusters/account-login-server/account-login-server.cpp +++ b/src/app/clusters/account-login-server/account-login-server.cpp @@ -14,23 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Application Launcher plugin, the @@ -65,24 +48,25 @@ void sendResponse(chip::app::Command * command, const char * responseSetupPin) } } -bool emberAfAccountLoginClusterGetSetupPINCallback(chip::app::Command * command, unsigned char * tempAccountIdentifier) +bool emberAfAccountLoginClusterGetSetupPINCallback(chip::app::Command * command, uint8_t * tempAccountIdentifier) { + // TODO: char is not null terminated, verify this code once #7963 gets merged. std::string tempAccountIdentifierString(reinterpret_cast(tempAccountIdentifier)); std::string responseSetupPin = accountLoginClusterGetSetupPin(tempAccountIdentifierString, emberAfCurrentEndpoint()); sendResponse(command, responseSetupPin.c_str()); return true; } -bool emberAfAccountLoginClusterLoginCallback(chip::app::Command * command, unsigned char * tempAccountIdentifier, - unsigned char * tempSetupPin) +bool emberAfAccountLoginClusterLoginCallback(chip::app::Command * command, uint8_t * tempAccountIdentifier, uint8_t * tempSetupPin) { + // TODO: char is not null terminated, verify this code once #7963 gets merged. std::string tempAccountIdentifierString(reinterpret_cast(tempAccountIdentifier)); std::string tempSetupPinString(reinterpret_cast(tempSetupPin)); bool isLoggedIn = accountLoginClusterIsUserLoggedIn(tempAccountIdentifierString, tempSetupPinString); EmberAfStatus status = isLoggedIn ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_NOT_AUTHORIZED; if (!isLoggedIn) { - ChipLogError(Zcl, "User is not authorized. Error:%s", chip::ErrorStr(EMBER_ZCL_STATUS_NOT_AUTHORIZED)); + ChipLogError(Zcl, "User is not authorized."); } emberAfSendImmediateDefaultResponse(status); return true; 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 2b79952c35d281..069f839bcf98f8 100644 --- a/src/app/clusters/application-basic-server/application-basic-server.cpp +++ b/src/app/clusters/application-basic-server/application-basic-server.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Application Launcher plugin, the 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 d59c91b4910257..a21f1bcb8aa873 100644 --- a/src/app/clusters/application-launcher-server/application-launcher-server.cpp +++ b/src/app/clusters/application-launcher-server/application-launcher-server.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Application Launcher plugin, the @@ -48,7 +32,7 @@ ApplicationLauncherResponse applicationLauncherClusterLaunchApp(EmberAfApplicationLauncherApp application, std::string data); -bool emberAfApplicationLauncherClusterLaunchAppCallback(chip::app::Command * commandObj, unsigned char *, unsigned char *) +bool emberAfApplicationLauncherClusterLaunchAppCallback(chip::app::Command * commandObj, uint8_t *, uint8_t *) { EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; emberAfSendImmediateDefaultResponse(status); @@ -74,7 +58,7 @@ void sendResponse(chip::app::Command * command, ApplicationLauncherResponse resp } } -EmberAfApplicationLauncherApp getApplicationFromCommand(unsigned short catalogVendorId, unsigned char * applicationId) +EmberAfApplicationLauncherApp getApplicationFromCommand(uint16_t catalogVendorId, uint8_t * applicationId) { EmberAfApplicationLauncherApp application = {}; application.applicationId = applicationId; @@ -82,11 +66,11 @@ EmberAfApplicationLauncherApp getApplicationFromCommand(unsigned short catalogVe return application; } -bool emberAfApplicationLauncherClusterLaunchAppCallback(chip::app::Command * command, unsigned char * requestData, - unsigned short requestApplicationCatalogVendorId, - unsigned char * requestApplicationId) +bool emberAfApplicationLauncherClusterLaunchAppCallback(chip::app::Command * command, uint8_t * requestData, + uint16_t requestApplicationCatalogVendorId, uint8_t * requestApplicationId) { EmberAfApplicationLauncherApp application = getApplicationFromCommand(requestApplicationCatalogVendorId, requestApplicationId); + // TODO: Char is not null terminated, verify this code once #7963 gets merged. std::string reqestDataString(reinterpret_cast(requestData)); ApplicationLauncherResponse response = applicationLauncherClusterLaunchApp(application, reqestDataString); sendResponse(command, response); diff --git a/src/app/clusters/application-launcher-server/application-launcher-server.h b/src/app/clusters/application-launcher-server/application-launcher-server.h index 1cf0c22b3586c6..5c71e3d93fc82a 100644 --- a/src/app/clusters/application-launcher-server/application-launcher-server.h +++ b/src/app/clusters/application-launcher-server/application-launcher-server.h @@ -14,31 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Application Launcher plugin, the *server implementation of the Application Launcher cluster. ******************************************************************************* ******************************************************************************/ -typedef struct _ApplicationLauncherResponse +struct ApplicationLauncherResponse { uint8_t status; uint8_t * data; -} ApplicationLauncherResponse; +}; 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 2e98abeb549007..969b41fffed6a0 100644 --- a/src/app/clusters/audio-output-server/audio-output-server.cpp +++ b/src/app/clusters/audio-output-server/audio-output-server.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Audio Output plugin, the @@ -44,7 +28,7 @@ bool audioOutputClusterSelectOutput(uint8_t index); bool audioOutputClusterRenameOutput(uint8_t index, uint8_t * name); -bool emberAfAudioOutputClusterRenameOutputCallback(chip::app::Command * command, unsigned char index, uint8_t * name) +bool emberAfAudioOutputClusterRenameOutputCallback(chip::app::Command * command, uint8_t index, uint8_t * name) { bool success = audioOutputClusterRenameOutput(index, name); EmberAfStatus status = success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE; @@ -52,7 +36,7 @@ bool emberAfAudioOutputClusterRenameOutputCallback(chip::app::Command * command, return true; } -bool emberAfAudioOutputClusterSelectOutputCallback(chip::app::Command * command, unsigned char index) +bool emberAfAudioOutputClusterSelectOutputCallback(chip::app::Command * command, uint8_t index) { bool success = audioOutputClusterSelectOutput(index); EmberAfStatus status = success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE; 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 6bde5852a84b81..1fca897e19851f 100644 --- a/src/app/clusters/keypad-input-server/keypad-input-server.cpp +++ b/src/app/clusters/keypad-input-server/keypad-input-server.cpp @@ -14,23 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Keypad Input plugin, the @@ -48,7 +31,6 @@ EmberAfKeypadInputStatus keypadInputClusterSendKey(EmberAfKeypadInputCecKeyCode static void sendResponse(chip::app::Command * command, EmberAfKeypadInputStatus keypadInputStatus) { - static_assert(std::is_same, uint8_t>::value, "Wrong enum size"); CHIP_ERROR err = CHIP_NO_ERROR; chip::app::CommandPathParams cmdParams = { emberAfCurrentEndpoint(), /* group id */ 0, ZCL_KEYPAD_INPUT_CLUSTER_ID, ZCL_SEND_KEY_RESPONSE_COMMAND_ID, (chip::app::CommandPathFlags::kEndpointIdValid) }; @@ -67,7 +49,7 @@ static void sendResponse(chip::app::Command * command, EmberAfKeypadInputStatus } } -bool emberAfKeypadInputClusterSendKeyCallback(chip::app::Command * command, unsigned char keyCode) +bool emberAfKeypadInputClusterSendKeyCallback(chip::app::Command * command, uint8_t keyCode) { EmberAfKeypadInputStatus status = keypadInputClusterSendKey(static_cast(keyCode)); sendResponse(command, status); diff --git a/src/app/clusters/low-power-server/low-power-server.cpp b/src/app/clusters/low-power-server/low-power-server.cpp index d43ba54f29576b..aaf56bfefc8ea0 100644 --- a/src/app/clusters/low-power-server/low-power-server.cpp +++ b/src/app/clusters/low-power-server/low-power-server.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Low Power plugin, the diff --git a/src/app/clusters/media-input-server/media-input-server.cpp b/src/app/clusters/media-input-server/media-input-server.cpp index 10ca4367821e7d..eccf01dcd1ed3e 100644 --- a/src/app/clusters/media-input-server/media-input-server.cpp +++ b/src/app/clusters/media-input-server/media-input-server.cpp @@ -14,23 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Media Input plugin, the @@ -53,16 +36,15 @@ bool mediaInputClusterRenameInput(uint8_t input, std::string name); static void storeCurrentInput(chip::EndpointId endpoint, uint8_t currentInput) { - EmberAfStatus status = - emberAfWriteServerAttribute(endpoint, ZCL_MEDIA_INPUT_CLUSTER_ID, ZCL_MEDIA_INPUT_CURRENT_INPUT_ATTRIBUTE_ID, - (uint8_t *) ¤tInput, ZCL_INT8U_ATTRIBUTE_TYPE); + EmberAfStatus status = emberAfWriteServerAttribute( + endpoint, ZCL_MEDIA_INPUT_CLUSTER_ID, ZCL_MEDIA_INPUT_CURRENT_INPUT_ATTRIBUTE_ID, ¤tInput, ZCL_INT8U_ATTRIBUTE_TYPE); if (status != EMBER_ZCL_STATUS_SUCCESS) { ChipLogError(Zcl, "Failed to store media playback attribute."); } } -bool emberAfMediaInputClusterSelectInputCallback(chip::app::Command * command, unsigned char input) +bool emberAfMediaInputClusterSelectInputCallback(chip::app::Command * command, uint8_t input) { bool success = mediaInputClusterSelectInput(input); EmberAfStatus status = success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE; @@ -90,8 +72,9 @@ bool emberAfMediaInputClusterHideInputStatusCallback(chip::app::Command * comman return true; } -bool emberAfMediaInputClusterRenameInputCallback(chip::app::Command * command, unsigned char input, unsigned char * name) +bool emberAfMediaInputClusterRenameInputCallback(chip::app::Command * command, uint8_t input, uint8_t * name) { + // TODO: char is not null terminated, verify this code once #7963 gets merged. std::string nameString(reinterpret_cast(name)); bool success = mediaInputClusterRenameInput(input, nameString); EmberAfStatus status = success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE; 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 3a159987011a95..d86f48c9f4672f 100644 --- a/src/app/clusters/media-playback-server/media-playback-server.cpp +++ b/src/app/clusters/media-playback-server/media-playback-server.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Media Playback plugin, the @@ -50,13 +34,10 @@ EmberAfMediaPlaybackStatus mediaPlaybackClusterSendMediaPlaybackRequest(MediaPlaybackRequest mediaPlaybackRequest, uint64_t deltaPositionMilliseconds); -uint8_t mediaPlaybackClusterPlaybackState; - static void writePlaybackState(chip::EndpointId endpoint, uint8_t playbackState) { - EmberAfStatus status = - emberAfWriteServerAttribute(endpoint, ZCL_MEDIA_PLAYBACK_CLUSTER_ID, ZCL_MEDIA_PLAYBACK_STATE_ATTRIBUTE_ID, - (uint8_t *) &playbackState, ZCL_INT8U_ATTRIBUTE_TYPE); + EmberAfStatus status = emberAfWriteServerAttribute( + endpoint, ZCL_MEDIA_PLAYBACK_CLUSTER_ID, ZCL_MEDIA_PLAYBACK_STATE_ATTRIBUTE_ID, &playbackState, ZCL_INT8U_ATTRIBUTE_TYPE); if (status != EMBER_ZCL_STATUS_SUCCESS) { ChipLogError(Zcl, "Failed to store media playback attribute."); @@ -66,9 +47,8 @@ static void writePlaybackState(chip::EndpointId endpoint, uint8_t playbackState) static uint8_t readPlaybackStatus(chip::EndpointId endpoint) { uint8_t playbackState; - EmberAfStatus status = - emberAfReadServerAttribute(endpoint, ZCL_MEDIA_PLAYBACK_CLUSTER_ID, ZCL_MEDIA_PLAYBACK_STATE_ATTRIBUTE_ID, - (uint8_t *) &playbackState, sizeof(uint8_t)); + EmberAfStatus status = emberAfReadServerAttribute(endpoint, ZCL_MEDIA_PLAYBACK_CLUSTER_ID, + ZCL_MEDIA_PLAYBACK_STATE_ATTRIBUTE_ID, &playbackState, sizeof(uint8_t)); if (status != EMBER_ZCL_STATUS_SUCCESS) { ChipLogError(Zcl, "Failed to read media playback attribute."); @@ -79,7 +59,7 @@ static uint8_t readPlaybackStatus(chip::EndpointId endpoint) void storeNewPlaybackState(chip::EndpointId endpoint, uint8_t newPlaybackState) { - mediaPlaybackClusterPlaybackState = readPlaybackStatus(endpoint); + uint8_t mediaPlaybackClusterPlaybackState = readPlaybackStatus(endpoint); if (mediaPlaybackClusterPlaybackState == newPlaybackState) { @@ -94,7 +74,6 @@ void storeNewPlaybackState(chip::EndpointId endpoint, uint8_t newPlaybackState) static void sendResponse(chip::app::Command * command, const char * responseName, chip::CommandId commandId, EmberAfMediaPlaybackStatus mediaPlaybackStatus) { - static_assert(std::is_same, uint8_t>::value, "Wrong enum size"); CHIP_ERROR err = CHIP_NO_ERROR; chip::app::CommandPathParams cmdParams = { emberAfCurrentEndpoint(), /* group id */ 0, ZCL_MEDIA_PLAYBACK_CLUSTER_ID, commandId, (chip::app::CommandPathFlags::kEndpointIdValid) }; diff --git a/src/app/clusters/media-playback-server/media-playback-server.h b/src/app/clusters/media-playback-server/media-playback-server.h index f9be35bff5b383..2850f97851b1a7 100644 --- a/src/app/clusters/media-playback-server/media-playback-server.h +++ b/src/app/clusters/media-playback-server/media-playback-server.h @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Media Playback plugin, the 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 c07c3aed645d27..6bb7b2e50c0939 100644 --- a/src/app/clusters/target-navigator-server/target-navigator-server.cpp +++ b/src/app/clusters/target-navigator-server/target-navigator-server.cpp @@ -15,22 +15,6 @@ * limitations under the License. */ -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Target Navigator plugin, the @@ -67,8 +51,9 @@ void sendResponse(chip::app::Command * command, TargetNavigatorResponse response } } -bool emberAfTargetNavigatorClusterNavigateTargetCallback(chip::app::Command * command, unsigned char target, unsigned char * data) +bool emberAfTargetNavigatorClusterNavigateTargetCallback(chip::app::Command * command, uint8_t target, uint8_t * data) { + // TODO: char is not null terminated, verify this code once #7963 gets merged. std::string dataString(reinterpret_cast(data)); TargetNavigatorResponse response = targetNavigatorClusterNavigateTarget(target, dataString); sendResponse(command, response); diff --git a/src/app/clusters/target-navigator-server/target-navigator-server.h b/src/app/clusters/target-navigator-server/target-navigator-server.h index 8c34a24f98c103..9cfb1f06dd6fc7 100644 --- a/src/app/clusters/target-navigator-server/target-navigator-server.h +++ b/src/app/clusters/target-navigator-server/target-navigator-server.h @@ -14,23 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * - * Copyright (c) 2021 Silicon Labs - * - * 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 * @brief Routines for the Target Navigator plugin, the @@ -38,8 +21,8 @@ ******************************************************************************* ******************************************************************************/ -typedef struct _TargetNavigatorResponse +struct TargetNavigatorResponse { uint8_t status; uint8_t * data; -} TargetNavigatorResponse; +}; diff --git a/src/app/clusters/tv-channel-server/tv-channel-server.cpp b/src/app/clusters/tv-channel-server/tv-channel-server.cpp index 652aba27bc3c9f..10db39de675120 100644 --- a/src/app/clusters/tv-channel-server/tv-channel-server.cpp +++ b/src/app/clusters/tv-channel-server/tv-channel-server.cpp @@ -71,6 +71,7 @@ void sendResponse(chip::app::Command * command, EmberAfTvChannelInfo channelInfo bool emberAfTvChannelClusterChangeChannelCallback(chip::app::Command * command, uint8_t * match) { + // TODO: char is not null terminated, verify this code once #7963 gets merged. std::string matchString(reinterpret_cast(match)); // TODO: Enable this once struct as param is supported // EmberAfTvChannelInfo channelInfo = tvChannelClusterChangeChannel(matchString); @@ -79,8 +80,7 @@ bool emberAfTvChannelClusterChangeChannelCallback(chip::app::Command * command, return true; } -bool emberAfTvChannelClusterChangeChannelByNumberCallback(chip::app::Command * command, unsigned short majorNumber, - unsigned short minorNumber) +bool emberAfTvChannelClusterChangeChannelByNumberCallback(chip::app::Command * command, uint16_t majorNumber, uint16_t minorNumber) { bool success = tvChannelClusterChangeChannelByNumber(majorNumber, minorNumber); EmberAfStatus status = success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE; @@ -88,7 +88,7 @@ bool emberAfTvChannelClusterChangeChannelByNumberCallback(chip::app::Command * c return true; } -bool emberAfTvChannelClusterSkipChannelCallback(chip::app::Command * command, unsigned short count) +bool emberAfTvChannelClusterSkipChannelCallback(chip::app::Command * command, uint16_t count) { bool success = tvChannelClusterSkipChannel(count); EmberAfStatus status = success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE; diff --git a/src/app/tests/suites/TV_AccountLoginCluster.yaml b/src/app/tests/suites/TV_AccountLoginCluster.yaml index 06bc8224ad437e..a713295169922b 100644 --- a/src/app/tests/suites/TV_AccountLoginCluster.yaml +++ b/src/app/tests/suites/TV_AccountLoginCluster.yaml @@ -26,6 +26,11 @@ tests: - name: "tempAccountIdentifier" value: "asdf" + # TODO: Enable these once they are able to work + # response: + # values: + # - name: "setupPIN" + # value: "tempPin123" - label: "Login Command" command: "Login" arguments: diff --git a/src/app/tests/suites/TV_MediaPlaybackCluster.yaml b/src/app/tests/suites/TV_MediaPlaybackCluster.yaml index c5326f1008820b..6607a3f21abea5 100644 --- a/src/app/tests/suites/TV_MediaPlaybackCluster.yaml +++ b/src/app/tests/suites/TV_MediaPlaybackCluster.yaml @@ -21,27 +21,59 @@ config: tests: - label: "Media Playback Play Command" command: "MediaPlay" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Pause Command" command: "MediaPause" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Stop Command" command: "MediaStop" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Start Over Command" command: "MediaStartOver" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Previous Command" command: "MediaPrevious" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Next Command" command: "MediaNext" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Rewind Command" command: "MediaRewind" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Fast Forward Command" command: "MediaFastForward" + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Skip Forward Command" command: "MediaSkipForward" @@ -49,6 +81,10 @@ tests: values: - name: "deltaPositionMilliseconds" value: 100 + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Skip Backward Command" command: "MediaSkipBackward" @@ -56,6 +92,10 @@ tests: values: - name: "deltaPositionMilliseconds" value: 100 + response: + values: + - name: "mediaPlaybackStatus" + value: 0 - label: "Media Playback Seek Command" command: "MediaSeek" @@ -63,3 +103,7 @@ tests: values: - name: "position" value: 100 + response: + values: + - name: "mediaPlaybackStatus" + value: 0 diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml index 330505e950c31b..462bddb35e47a3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml @@ -26,14 +26,14 @@ limitations under the License. This cluster provides an interface for launching content on a media player device such as a TV or Speaker. application launcher list - + catalog vendor id application id Upon receipt, this SHALL launch the specified app with optional data. The TV Device SHALL launch and bring to foreground the identified application in the command if the application is not already launched and in foreground. The TV Device SHALL update state attribute on the Application Basic cluster of the Endpoint corresponding to the launched application. This command returns a Launch Response. - + diff --git a/src/controller/data_model/gen/IMClusterCommandHandler.cpp b/src/controller/data_model/gen/IMClusterCommandHandler.cpp index ce2fdd92da6c29..2e696574fcc7fb 100644 --- a/src/controller/data_model/gen/IMClusterCommandHandler.cpp +++ b/src/controller/data_model/gen/IMClusterCommandHandler.cpp @@ -3110,7 +3110,7 @@ void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, En } break; } - case Clusters::MediaPlayback::Commands::Ids::MediaSkipBackwardResponse: { + case Clusters::MediaPlayback::Commands::Ids::MediaSeekResponse: { expectArgumentCount = 1; uint8_t mediaPlaybackStatus; bool argExists[1]; @@ -3165,11 +3165,11 @@ void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfMediaPlaybackClusterMediaSkipBackwardResponseCallback(apCommandObj, mediaPlaybackStatus); + wasHandled = emberAfMediaPlaybackClusterMediaSeekResponseCallback(apCommandObj, mediaPlaybackStatus); } break; } - case Clusters::MediaPlayback::Commands::Ids::MediaSkipForwardResponse: { + case Clusters::MediaPlayback::Commands::Ids::MediaSkipBackwardResponse: { expectArgumentCount = 1; uint8_t mediaPlaybackStatus; bool argExists[1]; @@ -3224,11 +3224,11 @@ void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfMediaPlaybackClusterMediaSkipForwardResponseCallback(apCommandObj, mediaPlaybackStatus); + wasHandled = emberAfMediaPlaybackClusterMediaSkipBackwardResponseCallback(apCommandObj, mediaPlaybackStatus); } break; } - case Clusters::MediaPlayback::Commands::Ids::MediaSkipSeekResponse: { + case Clusters::MediaPlayback::Commands::Ids::MediaSkipForwardResponse: { expectArgumentCount = 1; uint8_t mediaPlaybackStatus; bool argExists[1]; @@ -3283,7 +3283,7 @@ void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, En if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) { // TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks. - wasHandled = emberAfMediaPlaybackClusterMediaSkipSeekResponseCallback(apCommandObj, mediaPlaybackStatus); + wasHandled = emberAfMediaPlaybackClusterMediaSkipForwardResponseCallback(apCommandObj, mediaPlaybackStatus); } break; } @@ -5381,4 +5381,4 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC } } // namespace app -} // namespace chip \ No newline at end of file +} // namespace chip