Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 17b77c5

Browse files
lazarkovrestyled-commits
authored andcommittedJul 18, 2024
Update ACL after content app is installed (project-chip#34229)
* Add code to update ACL after app is installed * Restyled by whitespace * Restyled by clang-format * Update code per comments * Restyled by whitespace * Restyled by clang-format * Minor code updates * Restyled by clang-format * Update description * Update logic to support extern DeviceCommissioner & CommissionerDiscoveryController * Restyled by clang-format * Test the change to see if it will fix the tests * Update AppTv.cpp * Update code as it failed tests * Restyled by whitespace * Restyled by clang-format --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent b72dd3e commit 17b77c5

File tree

9 files changed

+293
-17
lines changed

9 files changed

+293
-17
lines changed
 

‎examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<meta-data android:name="com.matter.tv.app.api.clusters" android:resource="@raw/static_matter_clusters" />
2020
<meta-data android:name="com.matter.tv.app.api.vendor_name" android:value="CSA" />
2121
<meta-data android:name="com.matter.tv.app.api.vendor_id" android:value="65521" />
22-
<meta-data android:name="com.matter.tv.app.api.product_id" android:value="5678" />
22+
<meta-data android:name="com.matter.tv.app.api.product_id" android:value="32769" />
2323
<activity
2424
android:name="com.example.contentapp.MainActivity"
2525
android:exported="true">

‎examples/tv-app/android/java/AppImpl.cpp

+87
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,87 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend
355355
return nullptr;
356356
}
357357

358+
class DevicePairedCommand : public Controller::DevicePairingDelegate
359+
{
360+
public:
361+
struct CallbackContext
362+
{
363+
uint16_t vendorId;
364+
uint16_t productId;
365+
chip::NodeId nodeId;
366+
367+
CallbackContext(uint16_t vId, uint16_t pId, chip::NodeId nId) : vendorId(vId), productId(pId), nodeId(nId) {}
368+
};
369+
DevicePairedCommand(uint16_t vendorId, uint16_t productId, chip::NodeId nodeId) :
370+
mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this)
371+
{
372+
mContext = std::make_shared<CallbackContext>(vendorId, productId, nodeId);
373+
}
374+
375+
static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
376+
const chip::SessionHandle & sessionHandle)
377+
{
378+
auto * pairingCommand = static_cast<DevicePairedCommand *>(context);
379+
auto cbContext = pairingCommand->mContext;
380+
381+
if (pairingCommand)
382+
{
383+
ChipLogProgress(DeviceLayer,
384+
"OnDeviceConnectedFn - Updating ACL for node id: " ChipLogFormatX64
385+
" and vendor id: %d and product id: %d",
386+
ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId);
387+
388+
GetCommissionerDiscoveryController()->CommissioningSucceeded(cbContext->vendorId, cbContext->productId,
389+
cbContext->nodeId, exchangeMgr, sessionHandle);
390+
}
391+
}
392+
393+
static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error)
394+
{
395+
auto * pairingCommand = static_cast<DevicePairedCommand *>(context);
396+
auto cbContext = pairingCommand->mContext;
397+
398+
if (pairingCommand)
399+
{
400+
ChipLogProgress(DeviceLayer,
401+
"OnDeviceConnectionFailureFn - Not updating ACL for node id: " ChipLogFormatX64
402+
" and vendor id: %d and product id: %d",
403+
ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId);
404+
// TODO: Remove Node Id
405+
}
406+
}
407+
408+
chip::Callback::Callback<chip::OnDeviceConnected> mOnDeviceConnectedCallback;
409+
chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
410+
std::shared_ptr<CallbackContext> mContext;
411+
};
412+
413+
void refreshConnectedClientsAcl(uint16_t vendorId, uint16_t productId, ContentAppImpl * app)
414+
{
415+
416+
std::set<NodeId> nodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForContentApp(vendorId, productId);
417+
418+
for (const auto & allowedVendor : app->GetApplicationBasicDelegate()->GetAllowedVendorList())
419+
{
420+
std::set<NodeId> tempNodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForAllowVendorId(allowedVendor);
421+
422+
nodeIds.insert(tempNodeIds.begin(), tempNodeIds.end());
423+
}
424+
425+
for (const auto & nodeId : nodeIds)
426+
{
427+
428+
ChipLogProgress(DeviceLayer,
429+
"Creating Pairing Command with node id: " ChipLogFormatX64 " and vendor id: %d and product id: %d",
430+
ChipLogValueX64(nodeId), vendorId, productId);
431+
432+
std::shared_ptr<DevicePairedCommand> pairingCommand = std::make_shared<DevicePairedCommand>(vendorId, productId, nodeId);
433+
434+
GetDeviceCommissioner()->GetConnectedDevice(nodeId, &pairingCommand->mOnDeviceConnectedCallback,
435+
&pairingCommand->mOnDeviceConnectionFailureCallback);
436+
}
437+
}
438+
358439
EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName,
359440
uint16_t productId, const char * szApplicationVersion,
360441
std::vector<SupportedCluster> supportedClusters, jobject manager)
@@ -369,6 +450,9 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1
369450
app->GetEndpointId());
370451
mContentApps.push_back(app);
371452
mDataVersions.push_back(dataVersionBuf);
453+
454+
refreshConnectedClientsAcl(vendorId, productId, app);
455+
372456
return epId;
373457
}
374458

@@ -387,6 +471,9 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1
387471
app->GetEndpointId());
388472
mContentApps.push_back(app);
389473
mDataVersions.push_back(dataVersionBuf);
474+
475+
refreshConnectedClientsAcl(vendorId, productId, app);
476+
390477
return epId;
391478
}
392479

‎examples/tv-app/android/java/TVApp-JNI.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ class MyPostCommissioningListener : public PostCommissioningListener
258258
// read current binding list
259259
chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);
260260

261+
ContentAppPlatform::GetInstance().StoreNodeIdForContentApp(vendorId, productId, nodeId);
262+
261263
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
262264

263265
CHIP_ERROR err =

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

+25
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,31 @@ void ApplicationInit()
4545
ChipLogDetail(DeviceLayer, "TV Linux App: Warning - Fixed Content App Endpoint Not Disabled");
4646
// Can't disable this without breaking CI unit tests that act upon account login cluster (only available on ep3)
4747
// emberAfEndpointEnableDisable(3, false);
48+
49+
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
50+
// Install Content Apps
51+
ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
52+
53+
// Content App 1
54+
constexpr uint16_t kApp1VendorId = 65521;
55+
constexpr uint16_t kApp1ProductId = 32769;
56+
factory->InstallContentApp(kApp1VendorId, kApp1ProductId);
57+
58+
// Content App 2
59+
constexpr uint16_t kApp2VendorId = 1;
60+
constexpr uint16_t kApp2ProductId = 11;
61+
factory->InstallContentApp(kApp2VendorId, kApp2ProductId);
62+
63+
// Content App 3
64+
constexpr uint16_t kApp3VendorId = 9050;
65+
constexpr uint16_t kApp3ProductId = 22;
66+
factory->InstallContentApp(kApp3VendorId, kApp3ProductId);
67+
68+
// Content App 4
69+
constexpr uint16_t kApp4VendorId = 1111;
70+
constexpr uint16_t kApp4ProductId = 22;
71+
factory->InstallContentApp(kApp4VendorId, kApp4ProductId);
72+
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
4873
}
4974

5075
void ApplicationShutdown() {}

‎examples/tv-app/tv-common/shell/AppTvShellCommands.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ static CHIP_ERROR PrintAllCommands()
209209
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
210210
streamer_printf(sout, " print-app-access Print all ACLs for app platform fabric. Usage: app print-app-access\r\n");
211211
streamer_printf(sout, " remove-app-access Remove all ACLs for app platform fabric. Usage: app remove-app-access\r\n");
212+
streamer_printf(
213+
sout,
214+
" print-installed-apps Print all installed content apps with their endpoints. Usage: app print-installed-apps\r\n");
215+
212216
streamer_printf(sout,
213217
" commission <udc-entry> Commission given udc-entry using given pincode from corresponding app. Usage: "
214218
"app commission 0\r\n");
@@ -436,6 +440,13 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv)
436440
Access::GetAccessControl().DeleteAllEntriesForFabric(GetDeviceCommissioner()->GetFabricIndex());
437441
return CHIP_NO_ERROR;
438442
}
443+
else if (strcmp(argv[0], "print-installed-apps") == 0)
444+
{
445+
ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
446+
factory->LogInstalledApps();
447+
448+
return CHIP_NO_ERROR;
449+
}
439450
else if (strcmp(argv[0], "commission") == 0)
440451
{
441452
if (argc < 2)

‎examples/tv-app/tv-common/src/AppTv.cpp

+101-15
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class MyPostCommissioningListener : public PostCommissioningListener
164164
// read current binding list
165165
chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);
166166

167+
ContentAppPlatform::GetInstance().StoreNodeIdForContentApp(vendorId, productId, nodeId);
168+
167169
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
168170

169171
CHIP_ERROR err =
@@ -565,6 +567,63 @@ void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId)
565567
mAdminVendorIds.push_back(vendorId);
566568
}
567569

570+
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
571+
class DevicePairedCommand : public Controller::DevicePairingDelegate
572+
{
573+
public:
574+
struct CallbackContext
575+
{
576+
uint16_t vendorId;
577+
uint16_t productId;
578+
chip::NodeId nodeId;
579+
580+
CallbackContext(uint16_t vId, uint16_t pId, chip::NodeId nId) : vendorId(vId), productId(pId), nodeId(nId) {}
581+
};
582+
DevicePairedCommand(uint16_t vendorId, uint16_t productId, chip::NodeId nodeId) :
583+
mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this)
584+
{
585+
mContext = std::make_shared<CallbackContext>(vendorId, productId, nodeId);
586+
}
587+
588+
static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
589+
const chip::SessionHandle & sessionHandle)
590+
{
591+
auto * pairingCommand = static_cast<DevicePairedCommand *>(context);
592+
auto cbContext = pairingCommand->mContext;
593+
594+
if (pairingCommand)
595+
{
596+
ChipLogProgress(DeviceLayer,
597+
"OnDeviceConnectedFn - Updating ACL for node id: " ChipLogFormatX64
598+
" and vendor id: %d and product id: %d",
599+
ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId);
600+
601+
GetCommissionerDiscoveryController()->CommissioningSucceeded(cbContext->vendorId, cbContext->productId,
602+
cbContext->nodeId, exchangeMgr, sessionHandle);
603+
}
604+
}
605+
606+
static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error)
607+
{
608+
auto * pairingCommand = static_cast<DevicePairedCommand *>(context);
609+
auto cbContext = pairingCommand->mContext;
610+
611+
if (pairingCommand)
612+
{
613+
ChipLogProgress(DeviceLayer,
614+
"OnDeviceConnectionFailureFn - Not updating ACL for node id: " ChipLogFormatX64
615+
" and vendor id: %d and product id: %d",
616+
ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId);
617+
// TODO: Remove Node Id
618+
}
619+
}
620+
621+
chip::Callback::Callback<chip::OnDeviceConnected> mOnDeviceConnectedCallback;
622+
chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
623+
std::shared_ptr<CallbackContext> mContext;
624+
};
625+
#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
626+
568627
void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t productId)
569628
{
570629
auto make_default_supported_clusters = []() {
@@ -605,6 +664,46 @@ void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t produc
605664
make_default_supported_clusters());
606665
mContentApps.emplace_back(std::move(ptr));
607666
}
667+
668+
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
669+
// Get the list of node ids
670+
std::set<NodeId> nodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForContentApp(vendorId, productId);
671+
672+
// update ACLs
673+
for (auto & contentApp : mContentApps)
674+
{
675+
auto app = contentApp.get();
676+
677+
if (app->MatchesPidVid(productId, vendorId))
678+
{
679+
CatalogVendorApp vendorApp = app->GetApplicationBasicDelegate()->GetCatalogVendorApp();
680+
681+
GetContentAppFactoryImpl()->LoadContentApp(vendorApp);
682+
}
683+
684+
// update the list of node ids with content apps allowed vendor list
685+
for (const auto & allowedVendor : app->GetApplicationBasicDelegate()->GetAllowedVendorList())
686+
{
687+
std::set<NodeId> tempNodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForAllowVendorId(allowedVendor);
688+
689+
nodeIds.insert(tempNodeIds.begin(), tempNodeIds.end());
690+
}
691+
}
692+
693+
// refresh ACLs
694+
for (const auto & nodeId : nodeIds)
695+
{
696+
697+
ChipLogProgress(DeviceLayer,
698+
"Creating Pairing Command with node id: " ChipLogFormatX64 " and vendor id: %d and product id: %d",
699+
ChipLogValueX64(nodeId), vendorId, productId);
700+
701+
std::shared_ptr<DevicePairedCommand> pairingCommand = std::make_shared<DevicePairedCommand>(vendorId, productId, nodeId);
702+
703+
GetDeviceCommissioner()->GetConnectedDevice(nodeId, &pairingCommand->mOnDeviceConnectedCallback,
704+
&pairingCommand->mOnDeviceConnectionFailureCallback);
705+
}
706+
#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
608707
}
609708

610709
bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t productId)
@@ -625,8 +724,9 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod
625724
ChipLogProgress(DeviceLayer, "Found an app vid=%d pid=%d. Uninstalling it.",
626725
app->GetApplicationBasicDelegate()->HandleGetVendorId(),
627726
app->GetApplicationBasicDelegate()->HandleGetProductId());
727+
EndpointId removedEndpointID = ContentAppPlatform::GetInstance().RemoveContentApp(app);
728+
ChipLogProgress(DeviceLayer, "Removed content app at endpoint id: %d", removedEndpointID);
628729
mContentApps.erase(mContentApps.begin() + index);
629-
// TODO: call ContentAppPlatform->RemoveContentApp(ids...)
630730
return true;
631731
}
632732

@@ -701,22 +801,8 @@ std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoi
701801
CHIP_ERROR AppTvInit()
702802
{
703803
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
704-
// test data for apps
705-
constexpr uint16_t kApp1VendorId = 1;
706-
constexpr uint16_t kApp1ProductId = 11;
707-
constexpr uint16_t kApp2VendorId = 65521;
708-
constexpr uint16_t kApp2ProductId = 32769;
709-
constexpr uint16_t kApp3VendorId = 9050;
710-
constexpr uint16_t kApp3ProductId = 22;
711-
constexpr uint16_t kApp4VendorId = 1111;
712-
constexpr uint16_t kApp4ProductId = 22;
713-
714804
ContentAppPlatform::GetInstance().SetupAppPlatform();
715805
ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory);
716-
gFactory.InstallContentApp(kApp1VendorId, kApp1ProductId);
717-
gFactory.InstallContentApp(kApp2VendorId, kApp2ProductId);
718-
gFactory.InstallContentApp(kApp3VendorId, kApp3ProductId);
719-
gFactory.InstallContentApp(kApp4VendorId, kApp4ProductId);
720806
uint16_t value;
721807
if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR)
722808
{

‎src/app/app-platform/ContentAppPlatform.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,57 @@ ContentApp * ContentAppPlatform::GetContentApp(EndpointId id)
387387
return nullptr;
388388
}
389389

390+
// create a string key from vendorId and productId
391+
std::string createKey(uint16_t vendorId, uint16_t productId)
392+
{
393+
return std::to_string(vendorId) + ":" + std::to_string(productId);
394+
}
395+
396+
void ContentAppPlatform::StoreNodeIdForContentApp(uint16_t vendorId, uint16_t productId, NodeId nodeId)
397+
{
398+
std::string key = createKey(vendorId, productId);
399+
400+
ChipLogProgress(DeviceLayer, "Stored node id: " ChipLogFormatX64 " for key: %s", ChipLogValueX64(nodeId), key.c_str());
401+
402+
mConnectedContentAppNodeIds[key].insert(nodeId);
403+
}
404+
405+
std::set<NodeId> ContentAppPlatform::GetNodeIdsForContentApp(uint16_t vendorId, uint16_t productId)
406+
{
407+
std::string key = createKey(vendorId, productId);
408+
409+
ChipLogProgress(DeviceLayer, "Retrieving node id for key: %s", key.c_str());
410+
411+
auto it = mConnectedContentAppNodeIds.find(key);
412+
if (it != mConnectedContentAppNodeIds.end())
413+
{
414+
ChipLogProgress(DeviceLayer, "Found node id");
415+
return it->second;
416+
}
417+
418+
ChipLogProgress(DeviceLayer, "Didn't find node id");
419+
// If key not found, return an empty set
420+
return {};
421+
}
422+
423+
std::set<NodeId> ContentAppPlatform::GetNodeIdsForAllowVendorId(uint16_t vendorId)
424+
{
425+
std::set<NodeId> result;
426+
std::string vendorPrefix = std::to_string(vendorId) + ":";
427+
428+
for (const auto & pair : mConnectedContentAppNodeIds)
429+
{
430+
const std::string & key = pair.first;
431+
if (key.find(vendorPrefix) == 0)
432+
{ // Check if the key starts with the vendor prefix
433+
const std::set<NodeId> & nodeIds = pair.second;
434+
result.insert(nodeIds.begin(), nodeIds.end());
435+
}
436+
}
437+
438+
return result;
439+
}
440+
390441
void ContentAppPlatform::SetCurrentApp(ContentApp * app)
391442
{
392443
if (!HasCurrentApp())

‎src/app/app-platform/ContentAppPlatform.h

+14
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ class DLL_EXPORT ContentAppPlatform
161161
bool HasTargetContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId,
162162
Protocols::UserDirectedCommissioning::TargetAppInfo & info, uint32_t & passcode);
163163

164+
// returns set of connected nodes for a given content app
165+
std::set<NodeId> GetNodeIdsForContentApp(uint16_t vendorId, uint16_t productId);
166+
167+
// returns set of connected nodes for a given allowed vendor id
168+
std::set<NodeId> GetNodeIdsForAllowVendorId(uint16_t vendorId);
169+
170+
// store node id for content app after commissioning
171+
// node id can be used later on to update ACL
172+
// in case app is not installed
173+
// Note: This is in memory storing, the values are deleted after reboot
174+
void StoreNodeIdForContentApp(uint16_t vendorId, uint16_t productId, NodeId nodeId);
175+
164176
/**
165177
* @brief
166178
* Add ACLs on this device for the given client,
@@ -201,6 +213,8 @@ class DLL_EXPORT ContentAppPlatform
201213
EndpointId mCurrentEndpointId;
202214
EndpointId mFirstDynamicEndpointId;
203215
ContentApp * mContentApps[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT];
216+
// key is string -> vendorId:producTid
217+
std::map<std::string, std::set<NodeId>> mConnectedContentAppNodeIds;
204218

205219
private:
206220
void IncrementCurrentEndpointID();

0 commit comments

Comments
 (0)
Please sign in to comment.