Skip to content

Commit 1498716

Browse files
sharadb-amazonpull[bot]
authored andcommitted
Linux tv-casting-app: simplified CastingPlayerDiscovery API (#29444)
* Linux tv-casting-app: simplified CastingPlayerDiscovery API
1 parent 29cebed commit 1498716

14 files changed

+1061
-14
lines changed

.github/.wordlist.txt

+89-3
Large diffs are not rendered by default.

docs/examples/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ tv-app/**/README
273273
:maxdepth: 1
274274
275275
tv-casting-app/**/README
276+
tv-casting-app/APIs.md
276277
```
277278

278279
## Window example

examples/tv-casting-app/APIs.md

+470
Large diffs are not rendered by default.

examples/tv-casting-app/android/App/.idea/gradle.xml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

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

19+
#include "core/CastingPlayer.h"
20+
#include "core/CastingPlayerDiscovery.h"
1921
#include "core/Types.h"
2022

2123
#include <LinuxCommissionableDataProvider.h>
@@ -76,6 +78,33 @@ CHIP_ERROR InitCommissionableDataProvider(LinuxCommissionableDataProvider & prov
7678
options.payload.discriminator.GetLongValue());
7779
}
7880

81+
/**
82+
* @brief React to discovery results
83+
*/
84+
class DiscoveryDelegateImpl : public DiscoveryDelegate
85+
{
86+
private:
87+
int commissionersCount = 0;
88+
89+
public:
90+
void HandleOnAdded(matter::casting::memory::Strong<CastingPlayer> player) override
91+
{
92+
if (commissionersCount == 0)
93+
{
94+
ChipLogProgress(AppServer, "Select discovered CastingPlayer to request commissioning");
95+
96+
ChipLogProgress(AppServer, "Example: cast request 0");
97+
}
98+
++commissionersCount;
99+
ChipLogProgress(AppServer, "Discovered CastingPlayer #%d", commissionersCount);
100+
player->LogDetail();
101+
}
102+
void HandleOnUpdated(matter::casting::memory::Strong<CastingPlayer> player) override
103+
{
104+
ChipLogProgress(AppServer, "Updated CastingPlayer with ID: %s", player->GetId());
105+
}
106+
};
107+
79108
/**
80109
* @brief Provides the unique ID that is used by the SDK to generate the Rotating Device ID.
81110
*/
@@ -148,6 +177,17 @@ int main(int argc, char * argv[])
148177
VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
149178
ChipLogError(AppServer, "CastingApp::Start failed %" CHIP_ERROR_FORMAT, err.Format()));
150179

180+
DiscoveryDelegateImpl delegate;
181+
CastingPlayerDiscovery::GetInstance()->SetDelegate(&delegate);
182+
VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
183+
ChipLogError(AppServer, "CastingPlayerDiscovery::SetDelegate failed %" CHIP_ERROR_FORMAT, err.Format()));
184+
185+
// Discover CastingPlayers
186+
const uint64_t kTargetPlayerDeviceType = 35; // 35 represents device type of Matter Video Player
187+
err = CastingPlayerDiscovery::GetInstance()->StartDiscovery(kTargetPlayerDeviceType);
188+
VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
189+
ChipLogError(AppServer, "CastingPlayerDiscovery::StartDiscovery failed %" CHIP_ERROR_FORMAT, err.Format()));
190+
151191
chip::DeviceLayer::PlatformMgr().RunEventLoop();
152192

153193
return 0;

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

+3
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ chip_data_model("tv-casting-common") {
8989
sources += [
9090
"core/CastingApp.cpp",
9191
"core/CastingApp.h",
92+
"core/CastingPlayer.h",
93+
"core/CastingPlayerDiscovery.cpp",
94+
"core/CastingPlayerDiscovery.h",
9295
"core/Types.h",
9396
"support/AppParameters.h",
9497
"support/DataProvider.h",

examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ CastingApp * CastingApp::GetInstance()
4444

4545
CHIP_ERROR CastingApp::Initialize(const AppParameters & appParameters)
4646
{
47-
VerifyOrReturnError(mState == UNINITIALIZED, CHIP_ERROR_INCORRECT_STATE);
47+
VerifyOrReturnError(mState == CASTING_APP_UNINITIALIZED, CHIP_ERROR_INCORRECT_STATE);
4848
VerifyOrReturnError(appParameters.GetCommissionableDataProvider() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
4949
VerifyOrReturnError(appParameters.GetDeviceAttestationCredentialsProvider() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
5050
VerifyOrReturnError(appParameters.GetServerInitParamsProvider() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
@@ -74,14 +74,14 @@ CHIP_ERROR CastingApp::Initialize(const AppParameters & appParameters)
7474
}
7575
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID
7676

77-
mState = NOT_RUNNING; // initialization done, set state to NOT_RUNNING
77+
mState = CASTING_APP_NOT_RUNNING; // initialization done, set state to NOT_RUNNING
7878

7979
return CHIP_NO_ERROR;
8080
}
8181

8282
CHIP_ERROR CastingApp::Start()
8383
{
84-
VerifyOrReturnError(mState == NOT_RUNNING, CHIP_ERROR_INCORRECT_STATE);
84+
VerifyOrReturnError(mState == CASTING_APP_NOT_RUNNING, CHIP_ERROR_INCORRECT_STATE);
8585

8686
// start Matter server
8787
chip::ServerInitParams * serverInitParams = mAppParameters->GetServerInitParamsProvider()->Get();
@@ -96,7 +96,7 @@ CHIP_ERROR CastingApp::Start()
9696

9797
CHIP_ERROR CastingApp::PostStartRegistrations()
9898
{
99-
VerifyOrReturnError(mState == NOT_RUNNING, CHIP_ERROR_INCORRECT_STATE);
99+
VerifyOrReturnError(mState == CASTING_APP_NOT_RUNNING, CHIP_ERROR_INCORRECT_STATE);
100100
auto & server = chip::Server::GetInstance();
101101

102102
// TODO: Set CastingApp as AppDelegate
@@ -112,21 +112,21 @@ CHIP_ERROR CastingApp::PostStartRegistrations()
112112
// TODO: Add DeviceEvent Handler
113113
// ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(DeviceEventCallback, 0));
114114

115-
mState = RUNNING; // CastingApp started successfully, set state to RUNNING
115+
mState = CASTING_APP_RUNNING; // CastingApp started successfully, set state to RUNNING
116116
return CHIP_NO_ERROR;
117117
}
118118

119119
CHIP_ERROR CastingApp::Stop()
120120
{
121-
VerifyOrReturnError(mState == RUNNING, CHIP_ERROR_INCORRECT_STATE);
121+
VerifyOrReturnError(mState == CASTING_APP_RUNNING, CHIP_ERROR_INCORRECT_STATE);
122122

123123
// TODO: add logic to capture CastingPlayers that we are currently connected to, so we can automatically reconnect with them on
124124
// Start() again
125125

126126
// Shutdown the Matter server
127127
chip::Server::GetInstance().Shutdown();
128128

129-
mState = NOT_RUNNING; // CastingApp stopped successfully, set state to NOT_RUNNING
129+
mState = CASTING_APP_NOT_RUNNING; // CastingApp stopped successfully, set state to NOT_RUNNING
130130

131131
return CHIP_ERROR_NOT_IMPLEMENTED;
132132
}

examples/tv-casting-app/tv-casting-common/core/CastingApp.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ namespace core {
3030
*/
3131
enum CastingAppState
3232
{
33-
UNINITIALIZED, // Before Initialize() success
34-
NOT_RUNNING, // After Initialize() success before Start()ing, OR After stop() success
35-
RUNNING, // After Start() success
33+
CASTING_APP_UNINITIALIZED, // Before Initialize() success
34+
CASTING_APP_NOT_RUNNING, // After Initialize() success before Start()ing, OR After stop() success
35+
CASTING_APP_RUNNING, // After Start() success
3636
};
3737

3838
/**
@@ -83,7 +83,7 @@ class CastingApp
8383

8484
const matter::casting::support::AppParameters * mAppParameters;
8585

86-
CastingAppState mState = UNINITIALIZED;
86+
CastingAppState mState = CASTING_APP_UNINITIALIZED;
8787
};
8888

8989
}; // namespace core
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
*
3+
* Copyright (c) 2023 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
#include "Types.h"
22+
#include "lib/support/logging/CHIPLogging.h"
23+
24+
#include <inet/IPAddress.h>
25+
#include <inet/InetInterface.h>
26+
#include <string.h>
27+
#include <vector>
28+
29+
namespace matter {
30+
namespace casting {
31+
namespace core {
32+
33+
enum ConnectionError
34+
{
35+
NO_CONNECTION_ERROR = 0,
36+
FAILED_TO_CONNECT = 1
37+
};
38+
39+
using ConnectCallback = std::function<void(ConnectionError)>;
40+
using DisconnectCallback = std::function<void(void)>;
41+
42+
const int kPortMaxLength = 5; // port is uint16_t
43+
const int kIdMaxLength = chip::Dnssd::kHostNameMaxLength + kPortMaxLength;
44+
45+
class CastingPlayerAttributes
46+
{
47+
public:
48+
char id[kIdMaxLength] = {};
49+
char deviceName[chip::Dnssd::kMaxDeviceNameLen + 1] = {};
50+
char hostName[chip::Dnssd::kHostNameMaxLength + 1] = {};
51+
char instanceName[chip::Dnssd::kHostNameMaxLength + 1] = {};
52+
unsigned int numIPs; // number of valid IP addresses
53+
chip::Inet::IPAddress ipAddresses[chip::Dnssd::CommonResolutionData::kMaxIPAddresses];
54+
uint16_t port;
55+
uint16_t productId;
56+
uint16_t vendorId;
57+
uint32_t deviceType;
58+
};
59+
60+
/**
61+
* @brief CastingPlayer represents a Matter commissioner that is able to play media to a physical
62+
* output or to a display screen which is part of the device.
63+
*/
64+
class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
65+
{
66+
private:
67+
// std::vector<memory::Strong<Endpoint>> endpoints;
68+
bool mConnected = false;
69+
CastingPlayerAttributes mAttributes;
70+
71+
public:
72+
CastingPlayer(CastingPlayerAttributes playerAttributes) { mAttributes = playerAttributes; }
73+
const char * GetId() const { return mAttributes.id; }
74+
75+
const char * GetDeviceName() const { return mAttributes.deviceName; }
76+
77+
const char * GetHostName() const { return mAttributes.hostName; }
78+
79+
const char * GetInstanceName() const { return mAttributes.instanceName; }
80+
81+
uint GetNumIPs() const { return mAttributes.numIPs; }
82+
83+
chip::Inet::IPAddress * GetIPAddresses() { return mAttributes.ipAddresses; }
84+
85+
uint16_t GetPort() { return mAttributes.port; }
86+
87+
uint16_t GetProductId() const { return mAttributes.productId; }
88+
89+
uint16_t GetVendorId() const { return mAttributes.vendorId; }
90+
91+
uint32_t GetDeviceType() const { return mAttributes.deviceType; }
92+
93+
// public:
94+
// void RegisterEndpoint(const memory::Strong<Endpoint> endpoint) { endpoints.push_back(endpoint); }
95+
96+
// const std::vector<memory::Strong<Endpoint>> GetEndpoints() const { return endpoints; }
97+
98+
/**
99+
* @brief Compares based on the Id
100+
*/
101+
bool operator==(const CastingPlayer & other) const
102+
{
103+
int compareResult = strcmp(this->mAttributes.id, other.mAttributes.id);
104+
return (compareResult == 0) ? 1 : 0;
105+
}
106+
107+
public:
108+
/**
109+
* @return true if this CastingPlayer is connected to the CastingApp
110+
*/
111+
bool IsConnected() const { return mConnected; }
112+
113+
void Connect(const long timeout, ConnectCallback onCompleted);
114+
void Disconnect(const long timeout, DisconnectCallback onCompleted);
115+
116+
void LogDetail() const
117+
{
118+
if (strlen(mAttributes.id) != 0)
119+
{
120+
ChipLogDetail(Discovery, "\tID: %s", mAttributes.id);
121+
}
122+
if (strlen(mAttributes.deviceName) != 0)
123+
{
124+
ChipLogDetail(Discovery, "\tName: %s", mAttributes.deviceName);
125+
}
126+
if (strlen(mAttributes.hostName) != 0)
127+
{
128+
ChipLogDetail(Discovery, "\tHost Name: %s", mAttributes.hostName);
129+
}
130+
if (strlen(mAttributes.instanceName) != 0)
131+
{
132+
ChipLogDetail(Discovery, "\tInstance Name: %s", mAttributes.instanceName);
133+
}
134+
if (mAttributes.numIPs > 0)
135+
{
136+
ChipLogDetail(Discovery, "\tNumber of IPs: %u", mAttributes.numIPs);
137+
}
138+
char buf[chip::Inet::IPAddress::kMaxStringLength];
139+
if (strlen(mAttributes.ipAddresses[0].ToString(buf)) != 0)
140+
{
141+
for (unsigned j = 0; j < mAttributes.numIPs; j++)
142+
{
143+
char * ipAddressOut = mAttributes.ipAddresses[j].ToString(buf);
144+
ChipLogDetail(AppServer, "\tIP Address #%d: %s", j + 1, ipAddressOut);
145+
}
146+
}
147+
if (mAttributes.port > 0)
148+
{
149+
ChipLogDetail(Discovery, "\tPort: %u", mAttributes.port);
150+
}
151+
if (mAttributes.productId > 0)
152+
{
153+
ChipLogDetail(Discovery, "\tProduct ID: %u", mAttributes.productId);
154+
}
155+
if (mAttributes.vendorId > 0)
156+
{
157+
ChipLogDetail(Discovery, "\tVendor ID: %u", mAttributes.vendorId);
158+
}
159+
if (mAttributes.deviceType > 0)
160+
{
161+
ChipLogDetail(Discovery, "\tDevice Type: %" PRIu32, mAttributes.deviceType);
162+
}
163+
}
164+
};
165+
166+
}; // namespace core
167+
}; // namespace casting
168+
}; // namespace matter

0 commit comments

Comments
 (0)