Skip to content

Commit 4672993

Browse files
sharadb-amazonpull[bot]
authored andcommitted
Send ContentLauncher commands from tv-casting-app to tv-app (#12913)
* Switched to client for Media cluster * Send ContentLauncher.LaunchURL command from the tv-casting-app to tv-app Merged from master and resolved merge conflicts Using InvokeCommand instead of the callback api to LaunchURL Calling GetPeerIdForNode instead of GetPeerID * Added usage/deprecation comment for OperationalDeviceProxy.SetConnectedSession
1 parent 22a1a0b commit 4672993

File tree

16 files changed

+3397
-397
lines changed

16 files changed

+3397
-397
lines changed

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

+75-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* limitations under the License.
1717
*/
1818

19+
#include <app/OperationalDeviceProxy.h>
1920
#include <app/server/Dnssd.h>
2021
#include <app/server/Server.h>
2122
#include <controller/CHIPCommissionableNodeController.h>
@@ -27,8 +28,10 @@
2728
#include <lib/support/SafeInt.h>
2829
#include <platform/CHIPDeviceLayer.h>
2930
#include <platform/ConfigurationManager.h>
31+
#include <platform/DeviceControlServer.h>
3032
#include <system/SystemLayer.h>
3133
#include <transport/raw/PeerAddress.h>
34+
#include <zap-generated/CHIPClusters.h>
3235

3336
#include <list>
3437
#include <string>
@@ -39,6 +42,7 @@ using namespace chip::Credentials;
3942
using chip::ArgParser::HelpOptions;
4043
using chip::ArgParser::OptionDef;
4144
using chip::ArgParser::OptionSet;
45+
using namespace chip::app::Clusters::ContentLauncher::Commands;
4246

4347
struct TVExampleDeviceType
4448
{
@@ -52,10 +56,17 @@ constexpr uint16_t kOptionDeviceType = 't';
5256
constexpr uint16_t kCommissioningWindowTimeoutInSec = 3 * 60;
5357
constexpr uint32_t kCommissionerDiscoveryTimeoutInMs = 5 * 1000;
5458

59+
// TODO: Accept these values over CLI
60+
const char * kContentUrl = "https://www.test.com/videoid";
61+
const char * kContentDisplayStr = "Test video";
62+
constexpr EndpointId kTvEndpoint = 1;
63+
5564
CommissionableNodeController gCommissionableNodeController;
5665
chip::System::SocketWatchToken gToken;
5766
Dnssd::DiscoveryFilter gDiscoveryFilter = Dnssd::DiscoveryFilter();
5867

68+
CASEClientPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_CASE_CLIENTS> gCASEClientPool;
69+
5970
bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue)
6071
{
6172
switch (aIdentifier)
@@ -188,6 +199,68 @@ void InitCommissioningFlow(intptr_t commandArg)
188199
}
189200
}
190201

202+
void OnContentLauncherSuccessResponse(void * context, const LaunchURLResponse::DecodableType & response)
203+
{
204+
ChipLogProgress(AppServer, "ContentLauncher: Default Success Response");
205+
}
206+
207+
void OnContentLauncherFailureResponse(void * context, EmberAfStatus status)
208+
{
209+
ChipLogError(AppServer, "ContentLauncher: Default Failure Response: %" PRIu8, status);
210+
}
211+
212+
void DeviceEventCallback(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
213+
{
214+
if (event->Type == DeviceLayer::DeviceEventType::kCommissioningComplete)
215+
{
216+
chip::NodeId tvNodeId = chip::DeviceLayer::DeviceControlServer::DeviceControlSvr().GetPeerNodeId();
217+
chip::FabricIndex peerFabricIndex = chip::DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFabricIndex();
218+
219+
Server * server = &(chip::Server::GetInstance());
220+
chip::FabricInfo * fabric = server->GetFabricTable().FindFabricWithIndex(peerFabricIndex);
221+
if (fabric == nullptr)
222+
{
223+
ChipLogError(AppServer, "Did not find fabric for index %d", peerFabricIndex);
224+
return;
225+
}
226+
227+
chip::DeviceProxyInitParams initParams = {
228+
.sessionManager = &(server->GetSecureSessionManager()),
229+
.exchangeMgr = &(server->GetExchangeManager()),
230+
.idAllocator = &(server->GetSessionIDAllocator()),
231+
.fabricTable = &(server->GetFabricTable()),
232+
.clientPool = &gCASEClientPool,
233+
.imDelegate = chip::Platform::New<chip::Controller::DeviceControllerInteractionModelDelegate>(),
234+
};
235+
236+
PeerId peerID = fabric->GetPeerIdForNode(tvNodeId);
237+
chip::OperationalDeviceProxy * operationalDeviceProxy =
238+
chip::Platform::New<chip::OperationalDeviceProxy>(initParams, peerID);
239+
if (operationalDeviceProxy == nullptr)
240+
{
241+
ChipLogError(AppServer, "Failed in creating an instance of OperationalDeviceProxy");
242+
return;
243+
}
244+
245+
SessionHandle handle = server->GetSecureSessionManager().FindSecureSessionForNode(tvNodeId);
246+
operationalDeviceProxy->SetConnectedSession(handle);
247+
248+
ContentLauncherCluster cluster;
249+
CHIP_ERROR err = cluster.Associate(operationalDeviceProxy, kTvEndpoint);
250+
if (err != CHIP_NO_ERROR)
251+
{
252+
ChipLogError(AppServer, "Associate() failed: %" CHIP_ERROR_FORMAT, err.Format());
253+
return;
254+
}
255+
LaunchURL::Type request;
256+
request.contentURL = chip::CharSpan(kContentUrl, strlen(kContentUrl));
257+
request.displayString = chip::CharSpan(kContentDisplayStr, strlen(kContentDisplayStr));
258+
request.brandingInformation = chip::app::DataModel::List<
259+
const chip::app::Clusters::ContentLauncher::Structs::ContentLaunchBrandingInformation::Type>();
260+
cluster.InvokeCommand(request, nullptr, OnContentLauncherSuccessResponse, OnContentLauncherFailureResponse);
261+
}
262+
}
263+
191264
int main(int argc, char * argv[])
192265
{
193266
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -218,7 +291,8 @@ int main(int argc, char * argv[])
218291
chip::System::Clock::Milliseconds32(kCommissionerDiscoveryTimeoutInMs),
219292
[](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr);
220293

221-
// TBD: Content casting commands
294+
// Add callback to send Content casting commands after commissioning completes
295+
chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(DeviceEventCallback, 0);
222296

223297
DeviceLayer::PlatformMgr().RunEventLoop();
224298
exit:

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

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ chip_data_model("tv-casting-common") {
2222
zap_pregenerated_dir =
2323
"${chip_root}/zzz_generated/tv-casting-app/zap-generated"
2424
is_server = true
25+
use_default_client_callbacks = true
2526
}

examples/tv-casting-app/tv-casting-common/tv-casting-app.zap

+22-21
Original file line numberDiff line numberDiff line change
@@ -11854,7 +11854,7 @@
1185411854
"mfgCode": null,
1185511855
"define": "CHANNEL_CLUSTER",
1185611856
"side": "client",
11857-
"enabled": 0,
11857+
"enabled": 1,
1185811858
"commands": [
1185911859
{
1186011860
"name": "ChangeChannel",
@@ -11905,7 +11905,7 @@
1190511905
"mfgCode": null,
1190611906
"define": "CHANNEL_CLUSTER",
1190711907
"side": "server",
11908-
"enabled": 1,
11908+
"enabled": 0,
1190911909
"commands": [
1191011910
{
1191111911
"name": "ChangeChannelResponse",
@@ -11985,7 +11985,7 @@
1198511985
"mfgCode": null,
1198611986
"define": "TARGET_NAVIGATOR_CLUSTER",
1198711987
"side": "client",
11988-
"enabled": 0,
11988+
"enabled": 1,
1198911989
"commands": [
1199011990
{
1199111991
"name": "NavigateTarget",
@@ -12020,7 +12020,7 @@
1202012020
"mfgCode": null,
1202112021
"define": "TARGET_NAVIGATOR_CLUSTER",
1202212022
"side": "server",
12023-
"enabled": 1,
12023+
"enabled": 0,
1202412024
"commands": [
1202512025
{
1202612026
"name": "NavigateTargetResponse",
@@ -12070,7 +12070,7 @@
1207012070
"mfgCode": null,
1207112071
"define": "MEDIA_PLAYBACK_CLUSTER",
1207212072
"side": "client",
12073-
"enabled": 0,
12073+
"enabled": 1,
1207412074
"commands": [
1207512075
{
1207612076
"name": "MediaPlay",
@@ -12185,7 +12185,7 @@
1218512185
"mfgCode": null,
1218612186
"define": "MEDIA_PLAYBACK_CLUSTER",
1218712187
"side": "server",
12188-
"enabled": 1,
12188+
"enabled": 0,
1218912189
"commands": [
1219012190
{
1219112191
"name": "MediaPlayResponse",
@@ -12292,7 +12292,7 @@
1229212292
"mfgCode": null,
1229312293
"define": "MEDIA_INPUT_CLUSTER",
1229412294
"side": "client",
12295-
"enabled": 0,
12295+
"enabled": 1,
1229612296
"commands": [
1229712297
{
1229812298
"name": "SelectInput",
@@ -12351,7 +12351,7 @@
1235112351
"mfgCode": null,
1235212352
"define": "MEDIA_INPUT_CLUSTER",
1235312353
"side": "server",
12354-
"enabled": 1,
12354+
"enabled": 0,
1235512355
"commands": [],
1235612356
"attributes": [
1235712357
{
@@ -12392,7 +12392,7 @@
1239212392
"mfgCode": null,
1239312393
"define": "KEYPAD_INPUT_CLUSTER",
1239412394
"side": "client",
12395-
"enabled": 0,
12395+
"enabled": 1,
1239612396
"commands": [
1239712397
{
1239812398
"name": "SendKey",
@@ -12427,7 +12427,7 @@
1242712427
"mfgCode": null,
1242812428
"define": "KEYPAD_INPUT_CLUSTER",
1242912429
"side": "server",
12430-
"enabled": 1,
12430+
"enabled": 0,
1243112431
"commands": [
1243212432
{
1243312433
"name": "SendKeyResponse",
@@ -12462,7 +12462,7 @@
1246212462
"mfgCode": null,
1246312463
"define": "CONTENT_LAUNCH_CLUSTER",
1246412464
"side": "client",
12465-
"enabled": 0,
12465+
"enabled": 1,
1246612466
"commands": [
1246712467
{
1246812468
"name": "LaunchContent",
@@ -12505,7 +12505,7 @@
1250512505
"mfgCode": null,
1250612506
"define": "CONTENT_LAUNCH_CLUSTER",
1250712507
"side": "server",
12508-
"enabled": 1,
12508+
"enabled": 0,
1250912509
"commands": [
1251012510
{
1251112511
"name": "LaunchContentResponse",
@@ -12578,7 +12578,7 @@
1257812578
"mfgCode": null,
1257912579
"define": "AUDIO_OUTPUT_CLUSTER",
1258012580
"side": "client",
12581-
"enabled": 0,
12581+
"enabled": 1,
1258212582
"commands": [
1258312583
{
1258412584
"name": "SelectOutput",
@@ -12621,7 +12621,7 @@
1262112621
"mfgCode": null,
1262212622
"define": "AUDIO_OUTPUT_CLUSTER",
1262312623
"side": "server",
12624-
"enabled": 1,
12624+
"enabled": 0,
1262512625
"commands": [],
1262612626
"attributes": [
1262712627
{
@@ -12662,7 +12662,7 @@
1266212662
"mfgCode": null,
1266312663
"define": "APPLICATION_LAUNCHER_CLUSTER",
1266412664
"side": "client",
12665-
"enabled": 0,
12665+
"enabled": 1,
1266612666
"commands": [
1266712667
{
1266812668
"name": "LaunchApp",
@@ -12697,7 +12697,7 @@
1269712697
"mfgCode": null,
1269812698
"define": "APPLICATION_LAUNCHER_CLUSTER",
1269912699
"side": "server",
12700-
"enabled": 1,
12700+
"enabled": 0,
1270112701
"commands": [
1270212702
{
1270312703
"name": "LaunchAppResponse",
@@ -12747,7 +12747,7 @@
1274712747
"mfgCode": null,
1274812748
"define": "APPLICATION_BASIC_CLUSTER",
1274912749
"side": "client",
12750-
"enabled": 0,
12750+
"enabled": 1,
1275112751
"commands": [],
1275212752
"attributes": [
1275312753
{
@@ -12773,7 +12773,7 @@
1277312773
"mfgCode": null,
1277412774
"define": "APPLICATION_BASIC_CLUSTER",
1277512775
"side": "server",
12776-
"enabled": 1,
12776+
"enabled": 0,
1277712777
"commands": [],
1277812778
"attributes": [
1277912779
{
@@ -12889,7 +12889,7 @@
1288912889
"mfgCode": null,
1289012890
"define": "ACCOUNT_LOGIN_CLUSTER",
1289112891
"side": "client",
12892-
"enabled": 0,
12892+
"enabled": 1,
1289312893
"commands": [
1289412894
{
1289512895
"name": "GetSetupPIN",
@@ -12932,7 +12932,7 @@
1293212932
"mfgCode": null,
1293312933
"define": "ACCOUNT_LOGIN_CLUSTER",
1293412934
"side": "server",
12935-
"enabled": 1,
12935+
"enabled": 0,
1293612936
"commands": [
1293712937
{
1293812938
"name": "GetSetupPINResponse",
@@ -16286,5 +16286,6 @@
1628616286
"endpointVersion": 1,
1628716287
"deviceIdentifier": 22
1628816288
}
16289-
]
16289+
],
16290+
"log": []
1629016291
}

src/app/OperationalDeviceProxy.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ CHIP_ERROR OperationalDeviceProxy::Disconnect()
262262
return CHIP_NO_ERROR;
263263
}
264264

265+
void OperationalDeviceProxy::SetConnectedSession(SessionHandle handle)
266+
{
267+
mSecureSession.Grab(handle);
268+
mState = State::SecureConnected;
269+
}
270+
265271
void OperationalDeviceProxy::Clear()
266272
{
267273
if (mCASEClient)

src/app/OperationalDeviceProxy.h

+9
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, SessionReleaseDele
143143
*/
144144
CHIP_ERROR Disconnect() override;
145145

146+
/**
147+
* Use SetConnectedSession if 'this' object is a newly allocated device proxy.
148+
* It will take an existing session, such as the one established
149+
* during commissioning, and use it for this device proxy.
150+
*
151+
* Note: Avoid using this function generally as it is Deprecated
152+
*/
153+
void SetConnectedSession(SessionHandle handle);
154+
146155
NodeId GetDeviceId() const override { return mPeerId.GetNodeId(); }
147156

148157
/**

src/app/clusters/general-commissioning-server/general-commissioning-server.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,19 @@ bool emberAfGeneralCommissioningClusterArmFailSafeCallback(app::CommandHandler *
110110
return true;
111111
}
112112

113+
/**
114+
* Pass fabric and nodeId of commissioner to DeviceControlSvr.
115+
* This allows device to send messages back to commissioner.
116+
* Once bindings are implemented, this may no longer be needed.
117+
*/
113118
bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback(
114119
app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
115120
const Commands::CommissioningComplete::DecodableType & commandData)
116121
{
122+
SessionHandle handle = commandObj->GetExchangeContext()->GetSessionHandle();
123+
DeviceLayer::DeviceControlServer::DeviceControlSvr().SetFabricIndex(handle.GetFabricIndex());
124+
DeviceLayer::DeviceControlServer::DeviceControlSvr().SetPeerNodeId(handle.GetPeerNodeId());
125+
117126
CHIP_ERROR err = DeviceLayer::DeviceControlServer::DeviceControlSvr().CommissioningComplete();
118127
emberAfSendImmediateDefaultResponse(err == CHIP_NO_ERROR ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE);
119128

src/include/platform/DeviceControlServer.h

+7
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ class DeviceControlServer final
9494

9595
CHIP_ERROR ConnectNetworkForOperational(ByteSpan networkID);
9696

97+
inline FabricIndex GetFabricIndex() { return mFabric; }
98+
inline void SetFabricIndex(FabricIndex fabricId) { mFabric = fabricId; }
99+
inline NodeId GetPeerNodeId() { return mPeerNodeId; }
100+
inline void SetPeerNodeId(NodeId peerNodeId) { mPeerNodeId = peerNodeId; }
97101
void SetSwitchDelegate(SwitchDeviceControlDelegate * delegate) { mSwitchDelegate = delegate; }
98102
SwitchDeviceControlDelegate * GetSwitchDelegate() const { return mSwitchDelegate; }
99103

@@ -116,6 +120,9 @@ class DeviceControlServer final
116120
DeviceControlServer(const DeviceControlServer &) = delete;
117121
DeviceControlServer(const DeviceControlServer &&) = delete;
118122
DeviceControlServer & operator=(const DeviceControlServer &) = delete;
123+
124+
NodeId mPeerNodeId = 0;
125+
FabricIndex mFabric = 0;
119126
};
120127

121128
} // namespace DeviceLayer

src/transport/SessionManager.h

+1
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate
244244
}
245245

246246
// TODO: this is a temporary solution for legacy tests which use nodeId to send packets
247+
// and tv-casting-app that uses the TV's node ID to find the associated secure session
247248
SessionHandle FindSecureSessionForNode(NodeId peerNodeId);
248249

249250
private:

0 commit comments

Comments
 (0)