Skip to content

Commit

Permalink
Add auto-resubscribe support to chip-tool. (#21587)
Browse files Browse the repository at this point in the history
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Jun 29, 2023
1 parent 5a04b2f commit e734b87
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 55 deletions.
15 changes: 13 additions & 2 deletions examples/chip-tool/commands/clusters/ReportCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ class ReportCommand : public InteractionModelReports, public ModelCommand, publi
mError = error;
}

void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override
{
InteractionModelReports::OnDeallocatePaths(std::move(aReadPrepareParams));
}

void Shutdown() override
{
// We don't shut down InteractionModelReports here; we leave it for
Expand Down Expand Up @@ -265,7 +270,7 @@ class SubscribeAttribute : public SubscribeCommand
CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
{
return SubscribeCommand::SubscribeAttribute(device, endpointIds, mClusterIds, mAttributeIds, mMinInterval, mMaxInterval,
mFabricFiltered, mDataVersion, mKeepSubscriptions);
mFabricFiltered, mDataVersion, mKeepSubscriptions, mAutoResubscribe);
}

private:
Expand All @@ -288,6 +293,8 @@ class SubscribeAttribute : public SubscribeCommand
"Comma-separated list of data versions for the clusters being subscribed to.");
AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions,
"Boolean indicating whether to keep existing subscriptions when creating the new one. Defaults to false.");
AddArgument("auto-resubscribe", 0, 1, &mAutoResubscribe,
"Boolean indicating whether the subscription should auto-resubscribe. Defaults to false.");
}

std::vector<chip::ClusterId> mClusterIds;
Expand All @@ -298,6 +305,7 @@ class SubscribeAttribute : public SubscribeCommand
chip::Optional<bool> mFabricFiltered;
chip::Optional<std::vector<chip::DataVersion>> mDataVersion;
chip::Optional<bool> mKeepSubscriptions;
chip::Optional<bool> mAutoResubscribe;
};

class ReadEvent : public ReadCommand
Expand Down Expand Up @@ -393,14 +401,16 @@ class SubscribeEvent : public SubscribeCommand
" This argument takes a comma separated list of true/false values.\n"
" If the number of paths exceeds the number of entries provided to is-urgent, then isUrgent will be false for the "
"extra paths.");
AddArgument("auto-resubscribe", 0, 1, &mAutoResubscribe,
"Boolean indicating whether the subscription should auto-resubscribe. Defaults to false.");
}

~SubscribeEvent() {}

CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
{
return SubscribeCommand::SubscribeEvent(device, endpointIds, mClusterIds, mEventIds, mMinInterval, mMaxInterval,
mFabricFiltered, mEventNumber, mKeepSubscriptions, mIsUrgents);
mFabricFiltered, mEventNumber, mKeepSubscriptions, mIsUrgents, mAutoResubscribe);
}

private:
Expand All @@ -413,6 +423,7 @@ class SubscribeEvent : public SubscribeCommand
chip::Optional<chip::EventNumber> mEventNumber;
chip::Optional<bool> mKeepSubscriptions;
chip::Optional<std::vector<bool>> mIsUrgents;
chip::Optional<bool> mAutoResubscribe;
};

class ReadAll : public ReadCommand
Expand Down
4 changes: 2 additions & 2 deletions examples/chip-tool/templates/tests/partials/test_step.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@
{{#if (isTestOnlyCluster cluster)}}{{>testOnlyClusterArguments}}, value
{{else if isWait}} {{>waitArguments}}
{{else if isReadAttribute}} {{>attributeArguments}}{{>maybeFabricFiltered}}{{>maybeDataVersion~}}
{{else if isSubscribeAttribute}} {{>attributeArguments}}, {{minInterval}}, {{maxInterval}}{{>maybeFabricFiltered}}{{>maybeDataVersion}}{{>maybeKeepSubscriptions~}}
{{else if isSubscribeAttribute}} {{>attributeArguments}}, {{minInterval}}, {{maxInterval}}{{>maybeFabricFiltered}}{{>maybeDataVersion}}{{>maybeKeepSubscriptions~}}, /* autoResubscribe = */ chip::NullOptional
{{else if isWriteGroupAttribute}} {{>groupAttributeArguments}}, value{{>maybeDataVersion~}}
{{else if isWriteAttribute}} {{>attributeArguments}}, value{{>maybeTimedInteractionTimeoutMs}}{{>maybeSuppressResponse}}{{>maybeDataVersion~}}
{{else if isReadEvent}} {{>eventArguments}}{{>maybeFabricFiltered}}{{>maybeEventNumber~}}
{{else if isSubscribeEvent}} {{>eventArguments}}, {{minInterval}}, {{maxInterval}}{{>maybeFabricFiltered}}{{>maybeEventNumber}}{{>maybeKeepSubscriptions~}}
{{else if isSubscribeEvent}} {{>eventArguments}}, {{minInterval}}, {{maxInterval}}{{>maybeFabricFiltered}}{{>maybeEventNumber}}{{>maybeKeepSubscriptions~}}, /* autoResubscribe = */ chip::NullOptional
{{else if isGroupCommand}} {{>groupCommandArguments}}, value
{{else if isCommand}} {{>commandArguments}}, value{{>maybeTimedInteractionTimeoutMs}}{{>maybeSuppressResponse}}
{{/if}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ CHIP_ERROR InteractionModel::ReadEvent(const char * identity, EndpointId endpoin
CHIP_ERROR InteractionModel::SubscribeAttribute(const char * identity, EndpointId endpointId, ClusterId clusterId,
AttributeId attributeId, uint16_t minInterval, uint16_t maxInterval,
bool fabricFiltered, const Optional<DataVersion> & dataVersion,
const Optional<bool> & keepSubscriptions)
const Optional<bool> & keepSubscriptions, const Optional<bool> & autoResubscribe)
{
DeviceProxy * device = GetDevice(identity);
VerifyOrReturnError(device != nullptr, CHIP_ERROR_INCORRECT_STATE);
Expand All @@ -73,12 +73,14 @@ CHIP_ERROR InteractionModel::SubscribeAttribute(const char * identity, EndpointI
}

return InteractionModelReports::SubscribeAttribute(device, endpointIds, clusterIds, attributeIds, minInterval, maxInterval,
Optional<bool>(fabricFiltered), dataVersions, keepSubscriptions);
Optional<bool>(fabricFiltered), dataVersions, keepSubscriptions,
autoResubscribe);
}

CHIP_ERROR InteractionModel::SubscribeEvent(const char * identity, EndpointId endpointId, ClusterId clusterId, EventId eventId,
uint16_t minInterval, uint16_t maxInterval, bool fabricFiltered,
const Optional<EventNumber> & eventNumber, const Optional<bool> & keepSubscriptions)
const Optional<EventNumber> & eventNumber, const Optional<bool> & keepSubscriptions,
const Optional<bool> & autoResubscribe)
{
DeviceProxy * device = GetDevice(identity);
VerifyOrReturnError(device != nullptr, CHIP_ERROR_INCORRECT_STATE);
Expand All @@ -87,7 +89,8 @@ CHIP_ERROR InteractionModel::SubscribeEvent(const char * identity, EndpointId en
std::vector<ClusterId> clusterIds = { clusterId };
std::vector<EventId> eventIds = { eventId };
return InteractionModelReports::SubscribeEvent(device, endpointIds, clusterIds, eventIds, minInterval, maxInterval,
Optional<bool>(fabricFiltered), eventNumber, keepSubscriptions);
Optional<bool>(fabricFiltered), eventNumber, keepSubscriptions, NullOptional,
autoResubscribe);
}

void InteractionModel::Shutdown()
Expand Down Expand Up @@ -120,6 +123,11 @@ void InteractionModel::OnDone(ReadClient * aReadClient)
ContinueOnChipMainThread(CHIP_NO_ERROR);
}

void InteractionModel::OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams)
{
InteractionModelReports::OnDeallocatePaths(std::move(aReadPrepareParams));
}

void InteractionModel::OnSubscriptionEstablished(SubscriptionId subscriptionId)
{
ContinueOnChipMainThread(CHIP_NO_ERROR);
Expand Down Expand Up @@ -231,7 +239,9 @@ CHIP_ERROR InteractionModelConfig::GetAttributePaths(std::vector<EndpointId> end
return CHIP_ERROR_INVALID_ARGUMENT;
}

pathsConfig.count = pathsCount;
pathsConfig.count = pathsCount;
pathsConfig.attributePathParams = std::make_unique<AttributePathParams[]>(pathsCount);
pathsConfig.dataVersionFilter = std::make_unique<DataVersionFilter[]>(pathsCount);

for (size_t i = 0; i < pathsCount; i++)
{
Expand Down Expand Up @@ -274,7 +284,8 @@ CHIP_ERROR InteractionModelReports::ReportAttribute(DeviceProxy * device, std::v
ReadClient::InteractionType interactionType, uint16_t minInterval,
uint16_t maxInterval, const Optional<bool> & fabricFiltered,
const Optional<std::vector<DataVersion>> & dataVersions,
const Optional<bool> & keepSubscriptions)
const Optional<bool> & keepSubscriptions,
const Optional<bool> & autoResubscribe)
{
InteractionModelConfig::AttributePathsConfig pathsConfig;
ReturnErrorOnFailure(
Expand All @@ -286,7 +297,7 @@ CHIP_ERROR InteractionModelReports::ReportAttribute(DeviceProxy * device, std::v
ReadPrepareParams params(device->GetSecureSession().Value());
params.mpEventPathParamsList = nullptr;
params.mEventPathParamsListSize = 0;
params.mpAttributePathParamsList = pathsConfig.attributePathParams;
params.mpAttributePathParamsList = pathsConfig.attributePathParams.get();
params.mAttributePathParamsListSize = pathsConfig.count;

if (fabricFiltered.HasValue())
Expand All @@ -296,7 +307,7 @@ CHIP_ERROR InteractionModelReports::ReportAttribute(DeviceProxy * device, std::v

if (dataVersions.HasValue())
{
params.mpDataVersionFilterList = pathsConfig.dataVersionFilter;
params.mpDataVersionFilterList = pathsConfig.dataVersionFilter.get();
params.mDataVersionFilterListSize = pathsConfig.count;
}

Expand All @@ -316,6 +327,15 @@ CHIP_ERROR InteractionModelReports::ReportAttribute(DeviceProxy * device, std::v
{
ReturnErrorOnFailure(client->SendRequest(params));
}
else if (autoResubscribe.ValueOr(false))
{
pathsConfig.attributePathParams.release();
if (dataVersions.HasValue())
{
pathsConfig.dataVersionFilter.release();
}
ReturnErrorOnFailure(client->SendAutoResubscribeRequest(std::move(params)));
}
else
{
// We want to allow certain kinds of spec-invalid subscriptions so we
Expand All @@ -331,7 +351,8 @@ CHIP_ERROR InteractionModelReports::ReportEvent(DeviceProxy * device, std::vecto
ReadClient::InteractionType interactionType, uint16_t minInterval,
uint16_t maxInterval, const Optional<bool> & fabricFiltered,
const Optional<EventNumber> & eventNumber, const Optional<bool> & keepSubscriptions,
const Optional<std::vector<bool>> & isUrgents)
const Optional<std::vector<bool>> & isUrgents,
const Optional<bool> & autoResubscribe)
{
const size_t clusterCount = clusterIds.size();
const size_t eventCount = eventIds.size();
Expand Down Expand Up @@ -378,7 +399,7 @@ CHIP_ERROR InteractionModelReports::ReportEvent(DeviceProxy * device, std::vecto
return CHIP_ERROR_INVALID_ARGUMENT;
}

EventPathParams eventPathParams[kMaxAllowedPaths];
auto eventPathParams = std::make_unique<EventPathParams[]>(pathsCount);

ChipLogProgress(chipTool,
"Sending %sEvent to:", interactionType == ReadClient::InteractionType::Subscribe ? "Subscribe" : "Read");
Expand Down Expand Up @@ -412,7 +433,7 @@ CHIP_ERROR InteractionModelReports::ReportEvent(DeviceProxy * device, std::vecto
}

ReadPrepareParams params(device->GetSecureSession().Value());
params.mpEventPathParamsList = eventPathParams;
params.mpEventPathParamsList = eventPathParams.get();
params.mEventPathParamsListSize = pathsCount;
params.mEventNumber = eventNumber;
params.mpAttributePathParamsList = nullptr;
Expand All @@ -435,7 +456,15 @@ CHIP_ERROR InteractionModelReports::ReportEvent(DeviceProxy * device, std::vecto

auto client = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance(), device->GetExchangeManager(),
mBufferedReadAdapter, interactionType);
ReturnErrorOnFailure(client->SendRequest(params));
if (autoResubscribe.ValueOr(false))
{
eventPathParams.release();
ReturnErrorOnFailure(client->SendAutoResubscribeRequest(std::move(params)));
}
else
{
ReturnErrorOnFailure(client->SendRequest(params));
}
mReadClients.push_back(std::move(client));
return CHIP_NO_ERROR;
}
Expand Down Expand Up @@ -574,3 +603,21 @@ CHIP_ERROR InteractionModelReports::ReportAll(chip::DeviceProxy * device, std::v
mReadClients.push_back(std::move(client));
return CHIP_NO_ERROR;
}

void InteractionModelReports::OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams)
{
if (aReadPrepareParams.mpAttributePathParamsList != nullptr)
{
delete[] aReadPrepareParams.mpAttributePathParamsList;
}

if (aReadPrepareParams.mpDataVersionFilterList != nullptr)
{
delete[] aReadPrepareParams.mpDataVersionFilterList;
}

if (aReadPrepareParams.mpEventPathParamsList != nullptr)
{
delete[] aReadPrepareParams.mpEventPathParamsList;
}
}
Loading

0 comments on commit e734b87

Please sign in to comment.