Skip to content

Commit 59631af

Browse files
Adding Media subscriptions support to Linux tv-casting-app
1 parent 2466360 commit 59631af

14 files changed

+685
-32
lines changed

examples/tv-casting-app/linux/CastingUtils.cpp

+59-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ using namespace chip::Dnssd;
2626
// TODO: Accept these values over CLI
2727
const char * kContentUrl = "https://www.test.com/videoid";
2828
const char * kContentDisplayStr = "Test video";
29+
int gInitialContextVal = 121212;
2930

3031
CHIP_ERROR DiscoverCommissioners()
3132
{
@@ -114,14 +115,69 @@ void LaunchURLResponseCallback(CHIP_ERROR err)
114115
ChipLogProgress(AppServer, "LaunchURLResponseCallback called with %" CHIP_ERROR_FORMAT, err.Format());
115116
}
116117

118+
void OnCurrentStateReadResponseSuccess(
119+
void * context, chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType responseData)
120+
{
121+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess called");
122+
switch (responseData)
123+
{
124+
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPlaying:
125+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Playing");
126+
break;
127+
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPaused:
128+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Paused");
129+
break;
130+
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kNotPlaying:
131+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Not Playing");
132+
break;
133+
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kBuffering:
134+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Buffering");
135+
break;
136+
default:
137+
ChipLogError(AppServer, "OnCurrentStateReadResponseSuccess Invalid CurrentState!");
138+
break;
139+
}
140+
141+
if (context != nullptr)
142+
{
143+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess context value: %d", *(static_cast<int *>(context)));
144+
}
145+
}
146+
147+
void OnCurrentStateReadResponseFailure(void * context, CHIP_ERROR err)
148+
{
149+
ChipLogProgress(AppServer, "OnCurrentStateReadResponseFailure called with %" CHIP_ERROR_FORMAT, err.Format());
150+
}
151+
152+
void OnCurrentStateSubscriptionEstablished(void * context)
153+
{
154+
ChipLogProgress(AppServer, "OnCurrentStateSubscriptionEstablished called");
155+
if (context != nullptr)
156+
{
157+
ChipLogProgress(AppServer, "OnCurrentStateSubscriptionEstablished context value: %d", *(static_cast<int *>(context)));
158+
}
159+
}
160+
117161
void HandleCommissioningCompleteCallback(CHIP_ERROR err)
118162
{
119163
ChipLogProgress(AppServer, "HandleCommissioningCompleteCallback called with %" CHIP_ERROR_FORMAT, err.Format());
120164
if (err == CHIP_NO_ERROR)
121165
{
122-
ReturnOnFailure(
123-
CastingServer::GetInstance()->ContentLauncherLaunchURL(kContentUrl, kContentDisplayStr, LaunchURLResponseCallback));
124-
ChipLogProgress(AppServer, "ContentLauncherLaunchURL called successfully");
166+
// Subscribe to a media attribute
167+
err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState(
168+
static_cast<void *>(&gInitialContextVal), OnCurrentStateReadResponseSuccess, OnCurrentStateReadResponseFailure, 0, 4000,
169+
OnCurrentStateSubscriptionEstablished);
170+
if (err != CHIP_NO_ERROR)
171+
{
172+
ChipLogError(AppServer, "MediaPlayback_SubscribeToCurrentState call failed!");
173+
}
174+
175+
// Send a media command
176+
err = CastingServer::GetInstance()->ContentLauncherLaunchURL(kContentUrl, kContentDisplayStr, LaunchURLResponseCallback);
177+
if (err != CHIP_NO_ERROR)
178+
{
179+
ChipLogError(AppServer, "ContentLauncherLaunchURL call failed!");
180+
}
125181
}
126182
}
127183

examples/tv-casting-app/linux/CastingUtils.h

+7
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ void HandleCommissioningCompleteCallback(CHIP_ERROR err);
4242

4343
void LaunchURLResponseCallback(CHIP_ERROR err);
4444

45+
void OnCurrentStateReadResponseSuccess(
46+
void * context, chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType responseData);
47+
48+
void OnCurrentStateReadResponseFailure(void * context, CHIP_ERROR err);
49+
50+
void OnCurrentStateSubscriptionEstablished(void * context);
51+
4552
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
4653
void HandleUDCSendExpiration(chip::System::Layer * aSystemLayer, void * context);
4754
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT

examples/tv-casting-app/tv-casting-common/BUILD.gn

+4
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,20 @@ chip_data_model("tv-casting-common") {
4949
"commands/common/CHIPCommand.cpp",
5050
"include/ApplicationLauncher.h",
5151
"include/CastingServer.h",
52+
"include/Channel.h",
5253
"include/ContentLauncher.h",
5354
"include/KeypadInput.h",
5455
"include/LevelControl.h",
56+
"include/MediaBase.h",
5557
"include/MediaCommandBase.h",
5658
"include/MediaPlayback.h",
59+
"include/MediaSubscriptionBase.h",
5760
"include/TargetEndpointInfo.h",
5861
"include/TargetNavigator.h",
5962
"include/TargetVideoPlayerInfo.h",
6063
"src/ApplicationLauncher.cpp",
6164
"src/CastingServer.cpp",
65+
"src/Channel.cpp",
6266
"src/ContentLauncher.cpp",
6367
"src/KeypadInput.cpp",
6468
"src/LevelControl.cpp",

examples/tv-casting-app/tv-casting-common/include/ApplicationLauncher.h

+10
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
*/
1818

1919
#include "MediaCommandBase.h"
20+
#include "MediaSubscriptionBase.h"
2021

2122
#include <functional>
2223
#include <zap-generated/CHIPClusters.h>
2324

25+
// COMMAND CLASSES
2426
class LaunchAppCommand
2527
: public MediaCommandBase<chip::app::Clusters::ApplicationLauncher::Commands::LaunchApp::Type,
2628
chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::DecodableType>
@@ -51,3 +53,11 @@ class HideAppCommand : public MediaCommandBase<chip::app::Clusters::ApplicationL
5153
CHIP_ERROR Invoke(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
5254
std::function<void(CHIP_ERROR)> responseCallback);
5355
};
56+
57+
// SUBSCRIBER CLASSES
58+
class CurrentAppSubscriber
59+
: public MediaSubscriptionBase<chip::app::Clusters::ApplicationLauncher::Attributes::CurrentApp::TypeInfo>
60+
{
61+
public:
62+
CurrentAppSubscriber() : MediaSubscriptionBase(chip::app::Clusters::ApplicationLauncher::Id) {}
63+
};

examples/tv-casting-app/tv-casting-common/include/CastingServer.h

+162
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#pragma once
2020

2121
#include "ApplicationLauncher.h"
22+
#include "Channel.h"
2223
#include "ContentLauncher.h"
2324
#include "KeypadInput.h"
2425
#include "LevelControl.h"
@@ -27,9 +28,11 @@
2728
#include "TargetNavigator.h"
2829
#include "TargetVideoPlayerInfo.h"
2930

31+
#include <app-common/zap-generated/cluster-objects.h>
3032
#include <app/server/Server.h>
3133
#include <controller/CHIPCommissionableNodeController.h>
3234
#include <functional>
35+
#include <tv-casting-app/zap-generated/CHIPClientCallbacks.h>
3336
#include <zap-generated/CHIPClusters.h>
3437

3538
constexpr chip::System::Clock::Seconds16 kCommissioningWindowTimeout = chip::System::Clock::Seconds16(3 * 60);
@@ -73,35 +76,170 @@ class CastingServer
7376
chip::FabricIndex CurrentFabricIndex() { return mTargetVideoPlayerInfo.GetFabricIndex(); }
7477
void SetDefaultFabricIndex();
7578

79+
/**
80+
* @brief Content Launcher cluster
81+
*/
7682
CHIP_ERROR ContentLauncher_LaunchURL(
7783
const char * contentUrl, const char * contentDisplayStr,
7884
chip::Optional<chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type> brandingInformation,
7985
std::function<void(CHIP_ERROR)> responseCallback);
8086
CHIP_ERROR ContentLauncher_LaunchContent(chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type search,
8187
bool autoPlay, chip::Optional<chip::CharSpan> data,
8288
std::function<void(CHIP_ERROR)> responseCallback);
89+
90+
/**
91+
* @brief Level Control cluster
92+
*/
8393
CHIP_ERROR LevelControl_Step(chip::app::Clusters::LevelControl::StepMode stepMode, uint8_t stepSize, uint16_t transitionTime,
8494
uint8_t optionMask, uint8_t optionOverride, std::function<void(CHIP_ERROR)> responseCallback);
8595
CHIP_ERROR LevelControl_MoveToLevel(uint8_t level, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride,
8696
std::function<void(CHIP_ERROR)> responseCallback);
97+
98+
CHIP_ERROR
99+
LevelControl_SubscribeToCurrentLevel(
100+
void * context,
101+
chip::Controller::ReadResponseSuccessCallback<
102+
chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo::DecodableArgType>
103+
successFn,
104+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
105+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
106+
CHIP_ERROR
107+
LevelControl_SubscribeToMinLevel(void * context,
108+
chip::Controller::ReadResponseSuccessCallback<
109+
chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo::DecodableArgType>
110+
successFn,
111+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
112+
uint16_t maxInterval,
113+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
114+
CHIP_ERROR
115+
LevelControl_SubscribeToMaxLevel(void * context,
116+
chip::Controller::ReadResponseSuccessCallback<
117+
chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo::DecodableArgType>
118+
successFn,
119+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
120+
uint16_t maxInterval,
121+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
122+
123+
/**
124+
* @brief Media Playback cluster
125+
*/
87126
CHIP_ERROR MediaPlayback_Play(std::function<void(CHIP_ERROR)> responseCallback);
88127
CHIP_ERROR MediaPlayback_Pause(std::function<void(CHIP_ERROR)> responseCallback);
89128
CHIP_ERROR MediaPlayback_StopPlayback(std::function<void(CHIP_ERROR)> responseCallback);
90129
CHIP_ERROR MediaPlayback_Next(std::function<void(CHIP_ERROR)> responseCallback);
91130
CHIP_ERROR MediaPlayback_Seek(uint64_t position, std::function<void(CHIP_ERROR)> responseCallback);
92131
CHIP_ERROR MediaPlayback_SkipForward(uint64_t deltaPositionMilliseconds, std::function<void(CHIP_ERROR)> responseCallback);
93132
CHIP_ERROR MediaPlayback_SkipBackward(uint64_t deltaPositionMilliseconds, std::function<void(CHIP_ERROR)> responseCallback);
133+
134+
CHIP_ERROR MediaPlayback_SubscribeToCurrentState(
135+
void * context,
136+
chip::Controller::ReadResponseSuccessCallback<
137+
chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType>
138+
successFn,
139+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
140+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
141+
CHIP_ERROR
142+
MediaPlayback_SubscribeToStartTime(void * context,
143+
chip::Controller::ReadResponseSuccessCallback<
144+
chip::app::Clusters::MediaPlayback::Attributes::StartTime::TypeInfo::DecodableArgType>
145+
successFn,
146+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
147+
uint16_t maxInterval,
148+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
149+
CHIP_ERROR
150+
MediaPlayback_SubscribeToDuration(void * context,
151+
chip::Controller::ReadResponseSuccessCallback<
152+
chip::app::Clusters::MediaPlayback::Attributes::Duration::TypeInfo::DecodableArgType>
153+
successFn,
154+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
155+
uint16_t maxInterval,
156+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
157+
CHIP_ERROR MediaPlayback_SubscribeToSampledPosition(
158+
void * context,
159+
chip::Controller::ReadResponseSuccessCallback<
160+
chip::app::Clusters::MediaPlayback::Attributes::SampledPosition::TypeInfo::DecodableArgType>
161+
successFn,
162+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
163+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
164+
CHIP_ERROR MediaPlayback_SubscribeToPlaybackSpeed(
165+
void * context,
166+
chip::Controller::ReadResponseSuccessCallback<
167+
chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::TypeInfo::DecodableArgType>
168+
successFn,
169+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
170+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
171+
CHIP_ERROR MediaPlayback_SubscribeToSeekRangeEnd(
172+
void * context,
173+
chip::Controller::ReadResponseSuccessCallback<
174+
chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType>
175+
successFn,
176+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
177+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
178+
CHIP_ERROR MediaPlayback_SubscribeToSeekRangeStart(
179+
void * context,
180+
chip::Controller::ReadResponseSuccessCallback<
181+
chip::app::Clusters::MediaPlayback::Attributes::SeekRangeStart::TypeInfo::DecodableArgType>
182+
successFn,
183+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
184+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
185+
186+
/**
187+
* @brief Application Launcher cluster
188+
*/
94189
CHIP_ERROR ApplicationLauncher_LaunchApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
95190
chip::Optional<chip::ByteSpan> data, std::function<void(CHIP_ERROR)> responseCallback);
96191
CHIP_ERROR ApplicationLauncher_StopApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
97192
std::function<void(CHIP_ERROR)> responseCallback);
98193
CHIP_ERROR ApplicationLauncher_HideApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
99194
std::function<void(CHIP_ERROR)> responseCallback);
195+
196+
CHIP_ERROR
197+
ApplicationLauncher_SubscribeToCurrentApp(
198+
void * context,
199+
chip::Controller::ReadResponseSuccessCallback<
200+
chip::app::Clusters::ApplicationLauncher::Attributes::CurrentApp::TypeInfo::DecodableArgType>
201+
successFn,
202+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
203+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
204+
205+
/**
206+
* @brief Target Navigator cluster
207+
*/
100208
CHIP_ERROR TargetNavigator_NavigateTarget(const uint8_t target, const chip::Optional<chip::CharSpan> data,
101209
std::function<void(CHIP_ERROR)> responseCallback);
210+
211+
CHIP_ERROR TargetNavigator_SubscribeToTargetList(
212+
void * context,
213+
chip::Controller::ReadResponseSuccessCallback<
214+
chip::app::Clusters::TargetNavigator::Attributes::TargetList::TypeInfo::DecodableArgType>
215+
successFn,
216+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
217+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
218+
CHIP_ERROR TargetNavigator_SubscribeToCurrentTarget(
219+
void * context,
220+
chip::Controller::ReadResponseSuccessCallback<
221+
chip::app::Clusters::TargetNavigator::Attributes::CurrentTarget::TypeInfo::DecodableArgType>
222+
successFn,
223+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
224+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
225+
226+
/**
227+
* @brief Keypad Input cluster
228+
*/
102229
CHIP_ERROR KeypadInput_SendKey(const chip::app::Clusters::KeypadInput::CecKeyCode keyCode,
103230
std::function<void(CHIP_ERROR)> responseCallback);
104231

232+
/**
233+
* @brief Channel cluster
234+
*/
235+
CHIP_ERROR Channel_ChangeChannelCommand(const chip::CharSpan & match, std::function<void(CHIP_ERROR)> responseCallback);
236+
CHIP_ERROR Channel_SubscribeToLineup(
237+
void * context,
238+
chip::Controller::ReadResponseSuccessCallback<chip::app::Clusters::Channel::Attributes::Lineup::TypeInfo::DecodableArgType>
239+
successFn,
240+
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
241+
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
242+
105243
private:
106244
CHIP_ERROR InitBindingHandlers();
107245
static void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
@@ -127,6 +265,10 @@ class CastingServer
127265
StepCommand mStepCommand;
128266
MoveToLevelCommand mMoveToLevelCommand;
129267

268+
CurrentLevelSubscriber mCurrentLevelSubscriber;
269+
MinLevelSubscriber mMinLevelSubscriber;
270+
MaxLevelSubscriber mMaxLevelSubscriber;
271+
130272
/**
131273
* @brief Media Playback cluster
132274
*/
@@ -138,20 +280,40 @@ class CastingServer
138280
SkipForwardCommand mSkipForwardCommand;
139281
SkipBackwardCommand mSkipBackwardCommand;
140282

283+
CurrentStateSubscriber mCurrentStateSubscriber;
284+
StartTimeSubscriber mStartTimeSubscriber;
285+
DurationSubscriber mDurationSubscriber;
286+
SampledPositionSubscriber mSampledPositionSubscriber;
287+
PlaybackSpeedSubscriber mPlaybackSpeedSubscriber;
288+
SeekRangeEndSubscriber mSeekRangeEndSubscriber;
289+
SeekRangeStartSubscriber mSeekRangeStartSubscriber;
290+
141291
/**
142292
* @brief Application Launcher cluster
143293
*/
144294
LaunchAppCommand mLaunchAppCommand;
145295
StopAppCommand mStopAppCommand;
146296
HideAppCommand mHideAppCommand;
147297

298+
CurrentAppSubscriber mCurrentAppSubscriber;
299+
148300
/**
149301
* @brief Target Navigator cluster
150302
*/
151303
NavigateTargetCommand mNavigateTargetCommand;
152304

305+
TargetListSubscriber mTargetListSubscriber;
306+
CurrentTargetSubscriber mCurrentTargetSubscriber;
307+
153308
/**
154309
* @brief Keypad Input cluster
155310
*/
156311
SendKeyCommand mSendKeyCommand;
312+
313+
/**
314+
* @brief Channel cluster
315+
*/
316+
ChangeChannelCommand mChangeChannelCommand;
317+
318+
LineupSubscriber mLineupSubscriber;
157319
};

0 commit comments

Comments
 (0)