Skip to content

Commit

Permalink
Draft: Add configurable ep1 ACLs and bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdecenzo committed Oct 17, 2022
1 parent f366165 commit d9523e4
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 34 deletions.
24 changes: 24 additions & 0 deletions examples/tv-app/android/java/AppImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,30 @@ Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId)
return Access::Privilege::kOperate;
}

constexpr ClusterId kClusterIdDescriptor = 0x001d;
constexpr ClusterId kClusterIdOnOff = 0x0006;
constexpr ClusterId kClusterIdWakeOnLAN = 0x0503;
// constexpr ClusterId kClusterIdChannel = 0x0504;
// constexpr ClusterId kClusterIdTargetNavigator = 0x0505;
constexpr ClusterId kClusterIdMediaPlayback = 0x0506;
// constexpr ClusterId kClusterIdMediaInput = 0x0507;
constexpr ClusterId kClusterIdLowPower = 0x0508;
constexpr ClusterId kClusterIdKeypadInput = 0x0509;
constexpr ClusterId kClusterIdContentLauncher = 0x050a;
constexpr ClusterId kClusterIdAudioOutput = 0x050b;
// constexpr ClusterId kClusterIdApplicationLauncher = 0x050c;
// constexpr ClusterId kClusterIdAccountLogin = 0x050e;

std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId)
{
if (endpointId == kLocalVideoPlayerEndpointId)
{
return { kClusterIdDescriptor, kClusterIdOnOff, kClusterIdWakeOnLAN, kClusterIdMediaPlayback,
kClusterIdLowPower, kClusterIdKeypadInput, kClusterIdContentLauncher, kClusterIdAudioOutput };
}
return {};
}

} // namespace AppPlatform
} // namespace chip

Expand Down
4 changes: 4 additions & 0 deletions examples/tv-app/android/java/AppImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory
// When a vendor has admin privileges, it will get access to all clusters on ep1
Access::Privilege GetVendorPrivilege(uint16_t vendorId) override;

// Get the cluster list this vendorId should have on static endpoints such as ep1 for casting video clients.
// When a vendor has admin privileges, it will get access to all clusters on ep1
std::list<ClusterId> GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId) override;

void AddAdminVendorId(uint16_t vendorId);

void setContentAppAttributeDelegate(ContentAppAttributeDelegate * attributeDelegate);
Expand Down
95 changes: 93 additions & 2 deletions examples/tv-app/android/java/TVApp-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
#include <lib/support/CHIPJNIError.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <zap-generated/CHIPClusters.h>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::AppPlatform;
using namespace chip::Credentials;

Expand Down Expand Up @@ -201,9 +203,44 @@ class MyPostCommissioningListener : public PostCommissioningListener
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
SessionHandle & sessionHandle) override
{
// read current binding list
chip::Controller::BindingCluster cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);

ContentAppPlatform::GetInstance().ManageClientAccess(
exchangeMgr, sessionHandle, vendorId, GetDeviceCommissioner()->GetNodeId(), OnSuccessResponse, OnFailureResponse);
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);

CHIP_ERROR err =
cluster.ReadAttribute<Binding::Attributes::Binding::TypeInfo>(this, OnReadSuccessResponse, OnReadFailureResponse);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Failed in reading binding. Error %s", ErrorStr(err));
clearContext();
}
}

/* Callback when command results in success */
static void
OnReadSuccessResponse(void * context,
const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseData)
{
ChipLogProgress(Controller, "OnReadSuccessResponse - Binding Read Successfully");

MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
listener->finishTargetConfiguration(responseData);
}

/* Callback when command results in failure */
static void OnReadFailureResponse(void * context, CHIP_ERROR error)
{
ChipLogProgress(Controller, "OnReadFailureResponse - Binding Read Failed");

MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
listener->clearContext();

CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
if (cdc != nullptr)
{
cdc->PostCommissioningFailed(error);
}
}

/* Callback when command results in success */
Expand All @@ -227,6 +264,60 @@ class MyPostCommissioningListener : public PostCommissioningListener
cdc->PostCommissioningFailed(error);
}
}

void
finishTargetConfiguration(const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseList)
{
std::vector<app::Clusters::Binding::Structs::TargetStruct::Type> bindings;
NodeId localNodeId = GetDeviceCommissioner()->GetNodeId();

auto iter = responseList.begin();
while (iter.Next())
{
auto & binding = iter.GetValue();
ChipLogProgress(Controller, "Binding found nodeId=0x" ChipLogFormatX64 " my nodeId=0x" ChipLogFormatX64,
ChipLogValueX64(binding.node.ValueOr(0)), ChipLogValueX64(localNodeId));
if (binding.node.ValueOr(0) != localNodeId)
{
ChipLogProgress(Controller, "Found a binding for a different node, preserving");
bindings.push_back(binding);
}
else
{
ChipLogProgress(Controller, "Found a binding for a matching node, dropping");
}
}

Optional<SessionHandle> opt = mSecureSession.Get();
SessionHandle & sessionHandle = opt.Value();
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, localNodeId, bindings,
OnSuccessResponse, OnFailureResponse);
clearContext();
}

void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
SessionHandle & sessionHandle)
{
mVendorId = vendorId;
mProductId = productId;
mNodeId = nodeId;
mExchangeMgr = &exchangeMgr;
mSecureSession.ShiftToSession(sessionHandle);
}

void clearContext()
{
mVendorId = 0;
mProductId = 0;
mNodeId = 0;
mExchangeMgr = nullptr;
mSecureSession.SessionReleased();
}
uint16_t mVendorId = 0;
uint16_t mProductId = 0;
NodeId mNodeId = 0;
Messaging::ExchangeManager * mExchangeMgr = nullptr;
SessionHolder mSecureSession;
};

MyPostCommissioningListener gMyPostCommissioningListener;
Expand Down
119 changes: 117 additions & 2 deletions examples/tv-app/linux/AppImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@
#include <lib/support/CodeUtils.h>
#include <lib/support/ZclString.h>
#include <platform/CHIPDeviceLayer.h>
#include <zap-generated/CHIPClusters.h>

using namespace chip;
using namespace chip::AppPlatform;
using namespace chip::app::Clusters;

#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
class MyUserPrompter : public UserPrompter
Expand Down Expand Up @@ -89,9 +91,44 @@ class MyPostCommissioningListener : public PostCommissioningListener
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
SessionHandle & sessionHandle) override
{
// read current binding list
chip::Controller::BindingCluster cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);

ContentAppPlatform::GetInstance().ManageClientAccess(
exchangeMgr, sessionHandle, vendorId, GetDeviceCommissioner()->GetNodeId(), OnSuccessResponse, OnFailureResponse);
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);

CHIP_ERROR err =
cluster.ReadAttribute<Binding::Attributes::Binding::TypeInfo>(this, OnReadSuccessResponse, OnReadFailureResponse);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Failed in reading binding. Error %s", ErrorStr(err));
clearContext();
}
}

/* Callback when command results in success */
static void
OnReadSuccessResponse(void * context,
const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseData)
{
ChipLogProgress(Controller, "OnReadSuccessResponse - Binding Read Successfully");

MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
listener->finishTargetConfiguration(responseData);
}

/* Callback when command results in failure */
static void OnReadFailureResponse(void * context, CHIP_ERROR error)
{
ChipLogProgress(Controller, "OnReadFailureResponse - Binding Read Failed");

MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
listener->clearContext();

CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
if (cdc != nullptr)
{
cdc->PostCommissioningFailed(error);
}
}

/* Callback when command results in success */
Expand All @@ -115,6 +152,60 @@ class MyPostCommissioningListener : public PostCommissioningListener
cdc->PostCommissioningFailed(error);
}
}

void
finishTargetConfiguration(const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseList)
{
std::vector<app::Clusters::Binding::Structs::TargetStruct::Type> bindings;
NodeId localNodeId = GetDeviceCommissioner()->GetNodeId();

auto iter = responseList.begin();
while (iter.Next())
{
auto & binding = iter.GetValue();
ChipLogProgress(Controller, "Binding found nodeId=0x" ChipLogFormatX64 " my nodeId=0x" ChipLogFormatX64,
ChipLogValueX64(binding.node.ValueOr(0)), ChipLogValueX64(localNodeId));
if (binding.node.ValueOr(0) != localNodeId)
{
ChipLogProgress(Controller, "Found a binding for a different node, preserving");
bindings.push_back(binding);
}
else
{
ChipLogProgress(Controller, "Found a binding for a matching node, dropping");
}
}

Optional<SessionHandle> opt = mSecureSession.Get();
SessionHandle & sessionHandle = opt.Value();
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, localNodeId, bindings,
OnSuccessResponse, OnFailureResponse);
clearContext();
}

void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
SessionHandle & sessionHandle)
{
mVendorId = vendorId;
mProductId = productId;
mNodeId = nodeId;
mExchangeMgr = &exchangeMgr;
mSecureSession.ShiftToSession(sessionHandle);
}

void clearContext()
{
mVendorId = 0;
mProductId = 0;
mNodeId = 0;
mExchangeMgr = nullptr;
mSecureSession.SessionReleased();
}
uint16_t mVendorId = 0;
uint16_t mProductId = 0;
NodeId mNodeId = 0;
Messaging::ExchangeManager * mExchangeMgr = nullptr;
SessionHolder mSecureSession;
};

MyPostCommissioningListener gMyPostCommissioningListener;
Expand Down Expand Up @@ -407,6 +498,30 @@ Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId)
return Access::Privilege::kOperate;
}

constexpr ClusterId kClusterIdDescriptor = 0x001d;
constexpr ClusterId kClusterIdOnOff = 0x0006;
constexpr ClusterId kClusterIdWakeOnLAN = 0x0503;
// constexpr ClusterId kClusterIdChannel = 0x0504;
// constexpr ClusterId kClusterIdTargetNavigator = 0x0505;
constexpr ClusterId kClusterIdMediaPlayback = 0x0506;
// constexpr ClusterId kClusterIdMediaInput = 0x0507;
constexpr ClusterId kClusterIdLowPower = 0x0508;
constexpr ClusterId kClusterIdKeypadInput = 0x0509;
constexpr ClusterId kClusterIdContentLauncher = 0x050a;
constexpr ClusterId kClusterIdAudioOutput = 0x050b;
// constexpr ClusterId kClusterIdApplicationLauncher = 0x050c;
// constexpr ClusterId kClusterIdAccountLogin = 0x050e;

std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId)
{
if (endpointId == kLocalVideoPlayerEndpointId)
{
return { kClusterIdDescriptor, kClusterIdOnOff, kClusterIdWakeOnLAN, kClusterIdMediaPlayback,
kClusterIdLowPower, kClusterIdKeypadInput, kClusterIdContentLauncher, kClusterIdAudioOutput };
}
return {};
}

} // namespace AppPlatform
} // namespace chip

Expand Down
4 changes: 4 additions & 0 deletions examples/tv-app/linux/AppImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory
// When a vendor has admin privileges, it will get access to all clusters on ep1
Access::Privilege GetVendorPrivilege(uint16_t vendorId) override;

// Get the cluster list this vendorId should have on static endpoints such as ep1 for casting video clients.
// When a vendor has admin privileges, it will get access to all clusters on ep1
std::list<ClusterId> GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId) override;

void AddAdminVendorId(uint16_t vendorId);

protected:
Expand Down
Loading

0 comments on commit d9523e4

Please sign in to comment.