Skip to content

Commit bb3f54c

Browse files
Fix iOS app crash due to null cpp cluster
1 parent 3a7ddbe commit bb3f54c

11 files changed

+102
-32
lines changed

examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCEndpoint.mm

+56-16
Original file line numberDiff line numberDiff line change
@@ -90,27 +90,67 @@ - (MCCastingPlayer * _Nonnull)castingPlayer
9090
- (MCCluster * _Nullable)clusterForType:(MCEndpointClusterType)type
9191
{
9292
switch (type) {
93-
case MCEndpointClusterTypeApplicationBasic:
94-
return [[MCApplicationBasicCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::application_basic::ApplicationBasicCluster>()];
95-
96-
case MCEndpointClusterTypeApplicationLauncher:
97-
return [[MCApplicationLauncherCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::application_launcher::ApplicationLauncherCluster>()];
98-
99-
case MCEndpointClusterTypeContentLauncher:
100-
return [[MCContentLauncherCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::content_launcher::ContentLauncherCluster>()];
93+
case MCEndpointClusterTypeApplicationBasic: {
94+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::application_basic::ApplicationBasicCluster>();
95+
if (cppCluster == nullptr) {
96+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeApplicationBasic, GetCluster() returned nullptr");
97+
return nil;
98+
}
99+
return [[MCApplicationBasicCluster alloc] initWithCppCluster:cppCluster];
100+
}
101101

102-
case MCEndpointClusterTypeKeypadInput:
103-
return [[MCKeypadInputCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::keypad_input::KeypadInputCluster>()];
102+
case MCEndpointClusterTypeApplicationLauncher: {
103+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::application_launcher::ApplicationLauncherCluster>();
104+
if (cppCluster == nullptr) {
105+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeApplicationLauncher GetCluster() returned nullptr");
106+
return nil;
107+
}
108+
return [[MCApplicationLauncherCluster alloc] initWithCppCluster:cppCluster];
109+
}
104110

105-
case MCEndpointClusterTypeMediaPlayback:
106-
return [[MCMediaPlaybackCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::media_playback::MediaPlaybackCluster>()];
111+
case MCEndpointClusterTypeContentLauncher: {
112+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::content_launcher::ContentLauncherCluster>();
113+
if (cppCluster == nullptr) {
114+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeContentLauncher GetCluster() returned nullptr");
115+
return nil;
116+
}
117+
return [[MCContentLauncherCluster alloc] initWithCppCluster:cppCluster];
118+
}
107119

108-
case MCEndpointClusterTypeOnOff:
109-
return [[MCOnOffCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::on_off::OnOffCluster>()];
120+
case MCEndpointClusterTypeKeypadInput: {
121+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::keypad_input::KeypadInputCluster>();
122+
if (cppCluster == nullptr) {
123+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeKeypadInput GetCluster() returned nullptr");
124+
return nil;
125+
}
126+
return [[MCKeypadInputCluster alloc] initWithCppCluster:cppCluster];
127+
}
110128

111-
case MCEndpointClusterTypeTargetNavigator:
112-
return [[MCTargetNavigatorCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster<matter::casting::clusters::target_navigator::TargetNavigatorCluster>()];
129+
case MCEndpointClusterTypeMediaPlayback: {
130+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::media_playback::MediaPlaybackCluster>();
131+
if (cppCluster == nullptr) {
132+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeMediaPlayback GetCluster() returned nullptr");
133+
return nil;
134+
}
135+
return [[MCMediaPlaybackCluster alloc] initWithCppCluster:cppCluster];
136+
}
113137

138+
case MCEndpointClusterTypeOnOff: {
139+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::on_off::OnOffCluster>();
140+
if (cppCluster == nullptr) {
141+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeOnOff GetCluster() returned nullptr");
142+
return nil;
143+
}
144+
return [[MCOnOffCluster alloc] initWithCppCluster:cppCluster];
145+
}
146+
case MCEndpointClusterTypeTargetNavigator: {
147+
auto cppCluster = _cppEndpoint->GetCluster<matter::casting::clusters::target_navigator::TargetNavigatorCluster>();
148+
if (cppCluster == nullptr) {
149+
ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeTargetNavigator GetCluster() returned nullptr");
150+
return nil;
151+
}
152+
return [[MCTargetNavigatorCluster alloc] initWithCppCluster:cppCluster];
153+
}
114154
default:
115155
ChipLogError(AppServer, "MCEndpointClusterType not found");
116156
break;

examples/tv-casting-app/darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class MCApplicationBasicReadVendorIDExampleViewModel: ObservableObject {
4747
// validate that the selected endpoint supports the ApplicationBasic cluster
4848
if(!endpoint.hasCluster(MCEndpointClusterTypeApplicationBasic))
4949
{
50-
self.Log.error("No ApplicationBasic cluster supporting endpoint found")
50+
self.Log.error("MCApplicationBasicReadVendorIDExampleViewModel.read() No ApplicationBasic cluster supporting endpoint found")
5151
DispatchQueue.main.async
5252
{
5353
self.status = "No ApplicationBasic cluster supporting endpoint found"

examples/tv-casting-app/darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class MCContentLauncherLaunchURLExampleViewModel: ObservableObject {
4747
// validate that the selected endpoint supports the ContentLauncher cluster
4848
if(!endpoint.hasCluster(MCEndpointClusterTypeContentLauncher))
4949
{
50-
self.Log.error("No ContentLauncher cluster supporting endpoint found")
50+
self.Log.error("MCContentLauncherLaunchURLExampleViewModel.invokeCommand() No ContentLauncher cluster supporting endpoint found")
5151
DispatchQueue.main.async
5252
{
5353
self.status = "No ContentLauncher cluster supporting endpoint found"

examples/tv-casting-app/darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class MCMediaPlaybackSubscribeToCurrentStateExampleViewModel: ObservableObject {
4747
// validate that the selected endpoint supports the MediaPlayback cluster
4848
if(!endpoint.hasCluster(MCEndpointClusterTypeMediaPlayback))
4949
{
50-
self.Log.error("No MediaPlayback cluster supporting endpoint found")
50+
self.Log.error("MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.subscribe() No MediaPlayback cluster supporting endpoint found")
5151
DispatchQueue.main.async
5252
{
5353
self.status = "No MediaPlayback cluster supporting endpoint found"

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

+18-2
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,28 @@ class BaseCluster
5858
/**
5959
* @return Pointer to the Attribute registered in this cluster, corresponding to attributeId
6060
*/
61-
void * GetAttribute(const chip::AttributeId attributeId) { return mAttributes[attributeId]; }
61+
void * GetAttribute(const chip::AttributeId attributeId)
62+
{
63+
if (mAttributes.empty())
64+
{
65+
ChipLogError(AppServer, "BaseCluster::GetAttribute() mAttributes is empty");
66+
return nullptr;
67+
}
68+
return mAttributes[attributeId];
69+
}
6270

6371
/**
6472
* @return Pointer to the Command registered in this cluster, corresponding to commandId
6573
*/
66-
void * GetCommand(const chip::CommandId commandId) { return mCommands[commandId]; }
74+
void * GetCommand(const chip::CommandId commandId)
75+
{
76+
if (mCommands.empty())
77+
{
78+
ChipLogError(AppServer, "BaseCluster::GetCommand() mCommands is empty");
79+
return nullptr;
80+
}
81+
return mCommands[commandId];
82+
}
6783

6884
protected:
6985
/**

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

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa
109109
// found the CastingPlayer in cache
110110
if (it != cachedCastingPlayers.end())
111111
{
112+
ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() found this CastingPlayer in app cache");
112113
unsigned index = (unsigned int) std::distance(cachedCastingPlayers.begin(), it);
113114
if (ContainsDesiredTargetApp(&cachedCastingPlayers[index], idOptions.getTargetAppInfoList()))
114115
{

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

-5
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,11 @@ class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
102102
*/
103103
static CastingPlayer * GetTargetCastingPlayer()
104104
{
105-
ChipLogProgress(AppServer, "CastingPlayer::GetTargetCastingPlayer() called");
106105
std::shared_ptr<CastingPlayer> sharedPtr = mTargetCastingPlayer.lock();
107106
CastingPlayer * rawPtr = nullptr;
108107
if (sharedPtr)
109108
{
110109
rawPtr = sharedPtr.get();
111-
ChipLogProgress(
112-
AppServer,
113-
"CastingPlayer::GetTargetCastingPlayer() Got rawPtr from mTargetCastingPlayer, sharedPtr reference count: %lu",
114-
sharedPtr.use_count());
115110
sharedPtr.reset();
116111
}
117112
else

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ void Endpoint::RegisterClusters(std::vector<chip::ClusterId> clusters)
2828
{
2929
for (chip::ClusterId clusterId : clusters)
3030
{
31+
ChipLogProgress(AppServer, "Endpoint::RegisterClusters() Registering clusterId %d for endpointId %d", clusterId, GetId());
3132
switch (clusterId)
3233
{
3334
case chip::app::Clusters::ApplicationBasic::Id:
@@ -67,7 +68,8 @@ void Endpoint::RegisterClusters(std::vector<chip::ClusterId> clusters)
6768
break;
6869

6970
default:
70-
ChipLogProgress(AppServer, "Skipping registration of clusterId %d for endpointId %d", clusterId, GetId());
71+
ChipLogProgress(AppServer, "Endpoint::RegisterClusters() Skipping registration of clusterId %d for endpointId %d",
72+
clusterId, GetId());
7173
break;
7274
}
7375
}

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

+3
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class Endpoint : public std::enable_shared_from_this<Endpoint>
105105
*/
106106
std::vector<chip::ClusterId> GetServerList()
107107
{
108+
ChipLogProgress(AppServer, "Endpoint::GetServerList() mClusters.size(): %d", static_cast<int>(mClusters.size()));
108109
std::vector<chip::ClusterId> serverList;
109110
for (auto const & cluster : mClusters)
110111
{
@@ -122,6 +123,7 @@ class Endpoint : public std::enable_shared_from_this<Endpoint>
122123
template <typename T>
123124
void RegisterCluster(const chip::ClusterId clusterId)
124125
{
126+
ChipLogProgress(AppServer, "Endpoint::RegisterCluster() Registering clusterId %d for endpointId %d", clusterId, GetId());
125127
static_assert(std::is_base_of<BaseCluster, T>::value, "T must be derived from BaseCluster");
126128
auto cluster = std::make_shared<T>(shared_from_this());
127129
cluster->SetUp();
@@ -135,6 +137,7 @@ class Endpoint : public std::enable_shared_from_this<Endpoint>
135137
memory::Strong<T> GetCluster()
136138
{
137139
static_assert(std::is_base_of<BaseCluster, T>::value, "T must be derived from BaseCluster");
140+
ChipLogProgress(AppServer, "Endpoint::GetCluster() mClusters.size(): %d", static_cast<int>(mClusters.size()));
138141
for (const auto & pair : mClusters)
139142
{
140143
auto cluster = std::dynamic_pointer_cast<T>(pair.second);

examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,14 @@ std::vector<core::CastingPlayer> CastingStore::ReadAll()
427427
for (auto & endpointAttributes : endpointAttributesList)
428428
{
429429
std::shared_ptr<core::Endpoint> endpoint(new core::Endpoint(castingPlayer, endpointAttributes));
430+
ChipLogProgress(AppServer, "CastingStore::ReadAll() endpointServerListMap[endpointAttributes.mId].size(): %d",
431+
static_cast<int>(endpointServerListMap[endpointAttributes.mId].size()));
430432
endpoint->RegisterClusters(endpointServerListMap[endpointAttributes.mId]);
431433
castingPlayer->RegisterEndpoint(endpoint);
434+
ChipLogProgress(AppServer, "CastingStore::ReadAll() Registered endpointID: %d", endpoint->GetId());
432435
}
436+
ChipLogProgress(AppServer, "CastingStore::ReadAll() Created CastingPlayer with deviceName: %s",
437+
castingPlayer->GetDeviceName());
433438
castingPlayers.push_back(*castingPlayer);
434439
continue;
435440
}
@@ -453,7 +458,7 @@ std::vector<core::CastingPlayer> CastingStore::ReadAll()
453458

454459
CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayers)
455460
{
456-
ChipLogProgress(AppServer, "CastingStore::WriteAll called");
461+
ChipLogProgress(AppServer, "CastingStore::WriteAll() called");
457462

458463
chip::TLV::TLVWriter tlvWriter;
459464
uint8_t castingStoreData[kCastingStoreDataMaxBytes];
@@ -470,6 +475,7 @@ CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayer
470475

471476
for (auto & castingPlayer : castingPlayers)
472477
{
478+
ChipLogProgress(AppServer, "CastingStore::WriteAll() writing castingPlayer:");
473479
chip::TLV::TLVType castingPlayerContainerType;
474480
// CastingPlayer container starts
475481
ReturnErrorOnFailure(
@@ -502,6 +508,8 @@ CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayer
502508
std::vector<memory::Strong<core::Endpoint>> endpoints = core::CastingPlayer::GetTargetCastingPlayer()->GetEndpoints();
503509
for (auto & endpoint : endpoints)
504510
{
511+
ChipLogProgress(AppServer, "CastingStore::WriteAll() writing CastingPlayer Endpoint with endpointId: %d",
512+
endpoint->GetId());
505513
chip::TLV::TLVType endpointContainerType;
506514
// Endpoint container starts
507515
ReturnErrorOnFailure(
@@ -539,8 +547,10 @@ CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayer
539547
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointServerListContainerTag),
540548
chip::TLV::kTLVType_Structure, serverListContainerType));
541549
std::vector<chip::ClusterId> serverList = endpoint->GetServerList();
550+
ChipLogProgress(AppServer, "CastingStore::WriteAll() writing CastingPlayer Endpoint ServerList:");
542551
for (chip::ClusterId clusterId : serverList)
543552
{
553+
ChipLogProgress(AppServer, "CastingStore::WriteAll() clusterId: %d", clusterId);
544554
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointServerClusterIdTag), clusterId));
545555
}
546556
// ServerList container ends
@@ -562,7 +572,7 @@ CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayer
562572

563573
ReturnErrorOnFailure(tlvWriter.Finalize());
564574
ChipLogProgress(AppServer,
565-
"CastingStore::WriteAll TLV(CastingStoreData).LengthWritten: %d bytes, CastingPlayers size: %lu "
575+
"CastingStore::WriteAll() TLV(CastingStoreData).LengthWritten: %d bytes, CastingPlayers size: %lu "
566576
"and version: %d",
567577
tlvWriter.GetLengthWritten(), static_cast<unsigned long>(castingPlayers.size()),
568578
kCurrentCastingStoreDataVersion);

examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ CHIP_ERROR EndpointListLoader::Load()
9090
if (binding.type == MATTER_UNICAST_BINDING && CastingPlayer::GetTargetCastingPlayer()->GetNodeId() == binding.nodeId)
9191
{
9292
// if we discovered a new Endpoint from the bindings, read its EndpointAttributes
93-
chip::EndpointId endpointId = binding.remote;
93+
chip::EndpointId endpointId = binding.remote;
94+
ChipLogProgress(AppServer, "EndpointListLoader::Load() Found new endpointId: %d", endpointId);
9495
std::vector<memory::Strong<Endpoint>> endpoints = CastingPlayer::GetTargetCastingPlayer()->GetEndpoints();
9596
if (std::find_if(endpoints.begin(), endpoints.end(), [&endpointId](const memory::Strong<Endpoint> & endpoint) {
9697
return endpoint->GetId() == endpointId;
@@ -128,17 +129,19 @@ void EndpointListLoader::Complete()
128129

129130
if (mPendingAttributeReads == 0)
130131
{
131-
ChipLogProgress(AppServer, "EndpointListLoader::Complete Loading %lu endpoint(s)", mNewEndpointsToLoad);
132+
ChipLogProgress(AppServer, "EndpointListLoader::Complete() Loading %lu endpoint(s)", mNewEndpointsToLoad);
132133
for (unsigned long i = 0; i < mNewEndpointsToLoad; i++)
133134
{
134135
EndpointAttributes endpointAttributes = mEndpointAttributesList[i];
135136
std::shared_ptr<Endpoint> endpoint =
136137
std::make_shared<Endpoint>(CastingPlayer::GetTargetCastingPlayer(), endpointAttributes);
138+
ChipLogProgress(AppServer, "EndpointListLoader::Complete() mEndpointServerLists[i].size: %lu ",
139+
mEndpointServerLists[i].size());
137140
endpoint->RegisterClusters(mEndpointServerLists[i]);
138141
CastingPlayer::GetTargetCastingPlayer()->RegisterEndpoint(endpoint);
139142
}
140143

141-
ChipLogProgress(AppServer, "EndpointListLoader::Complete finished Loading %lu endpoints", mNewEndpointsToLoad);
144+
ChipLogProgress(AppServer, "EndpointListLoader::Complete() Finished Loading %lu endpoints", mNewEndpointsToLoad);
142145

143146
// TODO cleanup
144147
// delete mEndpointAttributesList;

0 commit comments

Comments
 (0)