Skip to content

Commit

Permalink
Linux/tv-casting-app: Cache/recall/re-target previously connected Vid…
Browse files Browse the repository at this point in the history
…eoPlayers/Endpoints
  • Loading branch information
sharadb-amazon committed Oct 14, 2022
1 parent 26dab6c commit 2dcba7c
Show file tree
Hide file tree
Showing 14 changed files with 906 additions and 214 deletions.
9 changes: 6 additions & 3 deletions examples/tv-casting-app/linux/CastingShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ static CHIP_ERROR CastingHandler(int argc, char ** argv)
char * eptr;
chip::NodeId nodeId = (chip::NodeId) strtoull(argv[1], &eptr, 10);
chip::FabricIndex fabricIndex = (chip::FabricIndex) strtol(argv[2], &eptr, 10);
return CastingServer::GetInstance()->TargetVideoPlayerInfoInit(nodeId, fabricIndex);
return CastingServer::GetInstance()->TargetVideoPlayerInfoInit(nodeId, fabricIndex, OnConnectionSuccess,
OnConnectionFailure, OnNewOrUpdatedEndpoint);
}
if (strcmp(argv[0], "discover") == 0)
{
Expand Down Expand Up @@ -120,7 +121,8 @@ static CHIP_ERROR CastingHandler(int argc, char ** argv)
}
char * url = argv[1];
char * display = argv[2];
return CastingServer::GetInstance()->ContentLauncherLaunchURL(url, display, LaunchURLResponseCallback);
return CastingServer::GetInstance()->ContentLauncherLaunchURL(
CastingServer::GetInstance()->GetActiveTargetVideoPlayer()->GetEndpoint(4), url, display, LaunchURLResponseCallback);
}
if (strcmp(argv[0], "access") == 0)
{
Expand Down Expand Up @@ -173,7 +175,8 @@ static CHIP_ERROR CastingHandler(int argc, char ** argv)
streamer_printf(streamer_get(), "ERROR - invalid fabric or video player nodeId not found\r\n");
return CHIP_ERROR_INVALID_ARGUMENT;
}
return CastingServer::GetInstance()->TargetVideoPlayerInfoInit(nodeId, fabricIndex);
return CastingServer::GetInstance()->TargetVideoPlayerInfoInit(nodeId, fabricIndex, OnConnectionSuccess,
OnConnectionFailure, OnNewOrUpdatedEndpoint);
}
if (strcmp(argv[0], "cluster") == 0)
{
Expand Down
118 changes: 101 additions & 17 deletions examples/tv-casting-app/linux/CastingUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ void PrepareForCommissioning(const Dnssd::DiscoveredNodeData * selectedCommissio
{
CastingServer::GetInstance()->Init();

CastingServer::GetInstance()->OpenBasicCommissioningWindow(HandleCommissioningCompleteCallback);
CastingServer::GetInstance()->OpenBasicCommissioningWindow(HandleCommissioningCompleteCallback, OnConnectionSuccess,
OnConnectionFailure, OnNewOrUpdatedEndpoint);

// Display onboarding payload
chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig();
Expand Down Expand Up @@ -158,27 +159,112 @@ void OnCurrentStateSubscriptionEstablished(void * context)
}
}

void HandleCommissioningCompleteCallback(CHIP_ERROR err)
void doCastingDemoActions(TargetEndpointInfo * endpoint)
{
ChipLogProgress(AppServer, "HandleCommissioningCompleteCallback called with %" CHIP_ERROR_FORMAT, err.Format());
if (err == CHIP_NO_ERROR)
if (endpoint != nullptr && endpoint->IsInitialized())
{
if (endpoint->HasCluster(chip::app::Clusters::MediaPlayback::Id))
{
// Subscribe to MediaPlayback::CurrentState
ChipLogProgress(AppServer,
"doCastingDemoActions requesting subscription on MediaPlayback:CurrentState on endpoint ID: %d",
endpoint->GetEndpointId());
CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState(
endpoint, static_cast<void *>(&gInitialContextVal), OnCurrentStateReadResponseSuccess,
OnCurrentStateReadResponseFailure, 0, 4000, OnCurrentStateSubscriptionEstablished);
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "MediaPlayback_SubscribeToCurrentState call failed!");
}
}
else
{
ChipLogProgress(AppServer,
"doCastingDemoActions: Not subscribing to MediaPlayback:CurrentState on endpoint ID %d as it does not "
"support the MediaPlayback cluster",
endpoint->GetEndpointId());
}

if (endpoint->HasCluster(chip::app::Clusters::ContentLauncher::Id))
{
// Send a ContentLauncher::LaunchURL command
ChipLogProgress(AppServer, "doCastingDemoActions sending ContentLauncher:LaunchURL on endpoint ID: %d",
endpoint->GetEndpointId());
CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncherLaunchURL(endpoint, kContentUrl, kContentDisplayStr,
LaunchURLResponseCallback);
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "ContentLauncherLaunchURL call failed!");
}
}
else
{
ChipLogProgress(AppServer,
"doCastingDemoActions: Not sending ContentLauncher:LaunchURL on endpoint ID %d as it does not support "
"the ContentLauncher cluster",
endpoint->GetEndpointId());
}
}
}

void OnConnectionSuccess(TargetVideoPlayerInfo * videoPlayer)
{
ChipLogProgress(AppServer,
"OnConnectionSuccess with Video Player(nodeId: %llu, fabricIndex: %d, deviceName: %s, vendorId: %d, productId: "
"%d, deviceType: %d)",
videoPlayer->GetNodeId(), videoPlayer->GetFabricIndex(), videoPlayer->GetDeviceName(),
videoPlayer->GetVendorId(), videoPlayer->GetProductId(), videoPlayer->GetDeviceType());

TargetEndpointInfo * endpoints = videoPlayer->GetEndpoints();
if (endpoints != nullptr)
{
// Subscribe to a media attribute
err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState(
static_cast<void *>(&gInitialContextVal), OnCurrentStateReadResponseSuccess, OnCurrentStateReadResponseFailure, 0, 4000,
OnCurrentStateSubscriptionEstablished);
if (err != CHIP_NO_ERROR)
for (size_t i = 0; i < kMaxNumberOfEndpoints && endpoints[i].IsInitialized(); i++)
{
ChipLogError(AppServer, "MediaPlayback_SubscribeToCurrentState call failed!");
doCastingDemoActions(&endpoints[i]); // LaunchURL and Subscribe to CurrentState
}
}
}

void OnConnectionFailure(CHIP_ERROR err)
{
ChipLogError(AppServer, "OnConnectionFailure error: %" CHIP_ERROR_FORMAT, err.AsString());
}

void OnNewOrUpdatedEndpoint(TargetEndpointInfo * endpoint)
{
ChipLogProgress(AppServer, "OnNewOrUpdatedEndpoint called");
doCastingDemoActions(endpoint); // LaunchURL and Subscribe to CurrentState
}

// Send a media command
err = CastingServer::GetInstance()->ContentLauncherLaunchURL(kContentUrl, kContentDisplayStr, LaunchURLResponseCallback);
if (err != CHIP_NO_ERROR)
CHIP_ERROR ConnectToCachedVideoPlayer()
{
TargetVideoPlayerInfo * cachedVideoPlayers = CastingServer::GetInstance()->ReadCachedTargetVideoPlayerInfos();
if (cachedVideoPlayers != nullptr)
{
for (size_t i = 0; i < kMaxCachedVideoPlayers; i++)
{
ChipLogError(AppServer, "ContentLauncherLaunchURL call failed!");
if (cachedVideoPlayers[i].IsInitialized())
{
ChipLogProgress(AppServer, "Found a Cached video player with nodeId: %llu, fabricIndex: %d",
cachedVideoPlayers[i].GetNodeId(), cachedVideoPlayers[i].GetFabricIndex());
if (CastingServer::GetInstance()->VerifyOrEstablishConnection(
cachedVideoPlayers[i], OnConnectionSuccess, OnConnectionFailure, OnNewOrUpdatedEndpoint) == CHIP_NO_ERROR)
{
ChipLogProgress(
AppServer,
"FindOrEstablish CASESession attempted for cached video player with nodeId: %llu, fabricIndex: %d",
cachedVideoPlayers[i].GetNodeId(), cachedVideoPlayers[i].GetFabricIndex());
return CHIP_NO_ERROR;
}
}
}
}
return CHIP_ERROR_INVALID_CASE_PARAMETER;
}

void HandleCommissioningCompleteCallback(CHIP_ERROR err)
{
ChipLogProgress(AppServer, "HandleCommissioningCompleteCallback called with %" CHIP_ERROR_FORMAT, err.Format());
}

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
Expand All @@ -187,9 +273,7 @@ void HandleUDCSendExpiration(System::Layer * aSystemLayer, void * context)
Dnssd::DiscoveredNodeData * selectedCommissioner = (Dnssd::DiscoveredNodeData *) context;

// Send User Directed commissioning request
ReturnOnFailure(CastingServer::GetInstance()->SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP(
selectedCommissioner->resolutionData.ipAddress[0], selectedCommissioner->resolutionData.port,
selectedCommissioner->resolutionData.interfaceId)));
ReturnOnFailure(CastingServer::GetInstance()->SendUserDirectedCommissioningRequest(selectedCommissioner));
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT

Expand Down
10 changes: 10 additions & 0 deletions examples/tv-casting-app/linux/CastingUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,18 @@ void PrepareForCommissioning(const chip::Dnssd::DiscoveredNodeData * selectedCom

void InitCommissioningFlow(intptr_t commandArg);

void doCastingDemoActions(TargetEndpointInfo * endpoint);

void HandleCommissioningCompleteCallback(CHIP_ERROR err);

CHIP_ERROR ConnectToCachedVideoPlayer();

void OnConnectionSuccess(TargetVideoPlayerInfo * videoPlayer);

void OnConnectionFailure(CHIP_ERROR err);

void OnNewOrUpdatedEndpoint(TargetEndpointInfo * endpoint);

void LaunchURLResponseCallback(CHIP_ERROR err);

void OnCurrentStateReadResponseSuccess(
Expand Down
24 changes: 15 additions & 9 deletions examples/tv-casting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ using namespace chip;
using chip::ArgParser::HelpOptions;
using chip::ArgParser::OptionDef;
using chip::ArgParser::OptionSet;
using namespace chip::app::Clusters::ContentLauncher::Commands;

#if defined(ENABLE_CHIP_SHELL)
using chip::Shell::Engine;
Expand Down Expand Up @@ -97,9 +96,9 @@ Commands gCommands;

CHIP_ERROR ProcessClusterCommand(int argc, char ** argv)
{
if (!CastingServer::GetInstance()->GetTargetVideoPlayerInfo()->IsInitialized())
if (!CastingServer::GetInstance()->GetActiveTargetVideoPlayer()->IsInitialized())
{
CastingServer::GetInstance()->SetDefaultFabricIndex();
CastingServer::GetInstance()->SetDefaultFabricIndex(OnConnectionSuccess, OnConnectionFailure, OnNewOrUpdatedEndpoint);
}
gCommands.Run(argc, argv);
return CHIP_NO_ERROR;
Expand Down Expand Up @@ -140,13 +139,20 @@ int main(int argc, char * argv[])
VerifyOrDie(CHIP_NO_ERROR == initParams.InitializeStaticResourcesBeforeServerInit());
VerifyOrDie(CHIP_NO_ERROR == chip::Server::GetInstance().Init(initParams));

// Send discover commissioners request
SuccessOrExit(err = CastingServer::GetInstance()->DiscoverCommissioners());
if (ConnectToCachedVideoPlayer() == CHIP_NO_ERROR)
{
ChipLogProgress(AppServer, "Skipping commissioner discovery / User directed commissioning flow.");
}
else
{
// Send discover commissioners request
SuccessOrExit(err = CastingServer::GetInstance()->DiscoverCommissioners());

// Give commissioners some time to respond and then ScheduleWork to initiate commissioning
DeviceLayer::SystemLayer().StartTimer(
chip::System::Clock::Milliseconds32(kCommissionerDiscoveryTimeoutInMs),
[](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr);
// Give commissioners some time to respond and then ScheduleWork to initiate commissioning
DeviceLayer::SystemLayer().StartTimer(
chip::System::Clock::Milliseconds32(kCommissionerDiscoveryTimeoutInMs),
[](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr);
}

registerClusters(gCommands, &gCredIssuerCommands);
registerClusterSubscriptions(gCommands, &gCredIssuerCommands);
Expand Down
2 changes: 2 additions & 0 deletions examples/tv-casting-app/tv-casting-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ chip_data_model("tv-casting-common") {
"include/MediaCommandBase.h",
"include/MediaPlayback.h",
"include/MediaSubscriptionBase.h",
"include/PersistenceManager.h",
"include/TargetEndpointInfo.h",
"include/TargetNavigator.h",
"include/TargetVideoPlayerInfo.h",
Expand All @@ -68,6 +69,7 @@ chip_data_model("tv-casting-common") {
"src/KeypadInput.cpp",
"src/LevelControl.cpp",
"src/MediaPlayback.cpp",
"src/PersistenceManager.cpp",
"src/TargetEndpointInfo.cpp",
"src/TargetNavigator.cpp",
"src/TargetVideoPlayerInfo.cpp",
Expand Down
Loading

0 comments on commit 2dcba7c

Please sign in to comment.