Skip to content

Commit

Permalink
[python] Support shutting down subscription (CLI) (#10375)
Browse files Browse the repository at this point in the history
* [python] Support shutting down subscription

* Update document

* Resolve comments

* Update wordlist
  • Loading branch information
erjiaqing authored and pull[bot] committed Oct 15, 2021
1 parent 7ff2ed9 commit 1fbca19
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 4 deletions.
14 changes: 12 additions & 2 deletions .github/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ APIs
apk
AppConfig
ApplicationBasic
ApplicationIdentifier
ApplicationLauncher
approver
appspot
Expand All @@ -46,6 +47,7 @@ armv
ASYNC
att
attId
attributeValue
attrListName
attrMask
attSizeBytes
Expand Down Expand Up @@ -267,6 +269,7 @@ DISTRO
Distutils
DK
DL
DMG
DNS
Dnsmasq
dnsmasqd
Expand Down Expand Up @@ -441,8 +444,8 @@ Infineon
ini
init
inlined
instantiation
installDebug
instantiation
integrations
IntelliSense
InteractionModelVersion
Expand Down Expand Up @@ -539,6 +542,7 @@ MatterLock
matterSdkSourceBuild
matterUTestLib
MaxInterval
MaxIntervalCeilingSeconds
MaxRtrAdvInterval
mbedTLS
mcu
Expand Down Expand Up @@ -568,6 +572,7 @@ MicroSD
middleware
Minicom
MinInterval
MinIntervalFloorSeconds
MinRtrAdvInterval
mkdir
mlan
Expand Down Expand Up @@ -780,8 +785,8 @@ ScriptBinding
SDC
SDHC
SDK
sdkconfig
SDK's
sdkconfig
SDKs
SDKTARGETSYSROOT
sdl
Expand Down Expand Up @@ -836,6 +841,8 @@ subdirectory
submodule
submodules
subprocess
SubscribeResponse
SubscriptionId
sudo
svg
SVR
Expand Down Expand Up @@ -968,12 +975,14 @@ wrover
WS
WSL
WSTK
xa
xab
xaver
xbef
xcd
Xcode
xd
xdeadbeefcafe
xds
xdsdfu
xef
Expand All @@ -1000,6 +1009,7 @@ zaptool
ZCL
zclconfigure
zclread
zclsubscribe
zclwrite
ZephyrConfig
zephyrproject
Expand Down
33 changes: 31 additions & 2 deletions docs/guides/python_chip_controller_building.md
Original file line number Diff line number Diff line change
Expand Up @@ -574,10 +574,39 @@ chip-device-ctrl > zclwrite TestCluster CharString 1 1 0 233233
Note: The format of the value is the same as the format of argument values for
ZCL cluster commands.

### `zclconfigure <Cluster> <Attribute> <Nodeid> <Endpoint> <MinInterval> <MaxInterval> <Change>`
### `zclsubscribe <Cluster> <Attribute> <Nodeid> <Endpoint> <MinInterval> <MaxInterval>`

Configure ZCL attribute reporting settings. For example:

```
chip-device-ctrl > zclconfigure OccupancySensing Occupancy 1234 1 0 1000 2000 1
chip-device-ctrl > zclsubscribe OccupancySensing Occupancy 1234 1 10 20
```

### `zclsubscribe -shutdown <subscription id>`

Shutdown an existing attribute subscription.

```
chip-device-ctrl > zclsubscribe -shutdown 0xdeadbeefcafe
```

The subscription id can be obtained from previous subscription messages:

```
chip-device-ctrl > zclsubscribe OnOff OnOff 1 1 10 20
(omitted messages)
[1633922898.965587][1117858:1117866] CHIP:DMG: SubscribeResponse =
[1633922898.965599][1117858:1117866] CHIP:DMG: {
[1633922898.965610][1117858:1117866] CHIP:DMG: SubscriptionId = 0xdeadbeefcafe,
[1633922898.965622][1117858:1117866] CHIP:DMG: MinIntervalFloorSeconds = 0xa,
[1633922898.965633][1117858:1117866] CHIP:DMG: MaxIntervalCeilingSeconds = 0x14,
[1633922898.965644][1117858:1117866] CHIP:DMG: }
[1633922898.965662][1117858:1117866] CHIP:ZCL: SubscribeResponse:
[1633922898.965673][1117858:1117866] CHIP:ZCL: SubscriptionId: 0xdeadbeefcafe
[1633922898.965683][1117858:1117866] CHIP:ZCL: ApplicationIdentifier: 0
[1633922898.965694][1117858:1117866] CHIP:ZCL: status: EMBER_ZCL_STATUS_SUCCESS (0x00)
[1633922898.965709][1117858:1117866] CHIP:ZCL: attributeValue: false
(omitted messages)
```

The subscription id is `0xdeadbeefcafe` in this case
16 changes: 16 additions & 0 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,22 @@ CHIP_ERROR InteractionModelEngine::NewReadClient(ReadClient ** const apReadClien
return err;
}

CHIP_ERROR InteractionModelEngine::ShutdownSubscription(uint64_t aSubscriptionId)
{
CHIP_ERROR err = CHIP_ERROR_KEY_NOT_FOUND;

for (auto & readClient : mReadClients)
{
if (!readClient.IsFree() && readClient.IsSubscriptionType() && readClient.IsMatchingClient(aSubscriptionId))
{
readClient.Shutdown();
err = CHIP_NO_ERROR;
}
}

return err;
}

CHIP_ERROR InteractionModelEngine::NewWriteClient(WriteClientHandle & apWriteClient, uint64_t aApplicationIdentifier)
{
apWriteClient.SetWriteClient(nullptr);
Expand Down
8 changes: 8 additions & 0 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate, public Comman
* @retval #CHIP_NO_ERROR On success.
*/
CHIP_ERROR SendSubscribeRequest(ReadPrepareParams & aReadPrepareParams, uint64_t aAppIdentifier = 0);

/**
* Tears down an active subscription.
*
* @retval #CHIP_ERROR_KEY_NOT_FOUND If the subscription is not found.
* @retval #CHIP_NO_ERROR On success.
*/
CHIP_ERROR ShutdownSubscription(uint64_t aSubscriptionId);
/**
* Retrieve a WriteClient that the SDK consumer can use to send a write. If the call succeeds,
* see WriteClient documentation for lifetime handling.
Expand Down
6 changes: 6 additions & 0 deletions src/app/ReadClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ class ReadClient : public Messaging::ExchangeDelegate
CHIP_ERROR OnUnsolicitedReportData(Messaging::ExchangeContext * apExchangeContext, System::PacketBufferHandle && aPayload);
uint64_t GetAppIdentifier() const { return mAppIdentifier; }

auto GetSubscriptionId() const
{
using returnType = Optional<decltype(mSubscriptionId)>;
return mInteractionType == InteractionType::Subscribe ? returnType(mSubscriptionId) : returnType::Missing();
}

NodeId GetPeerNodeId() const { return mPeerNodeId; }
bool IsReadType() { return mInteractionType == InteractionType::Read; }
bool IsSubscriptionType() const { return mInteractionType == InteractionType::Subscribe; };
Expand Down
9 changes: 9 additions & 0 deletions src/app/util/im-client-callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,16 @@ bool IMReadReportAttributesResponseCallback(const app::ReadClient * apReadClient

bool IMSubscribeResponseCallback(const chip::app::ReadClient * apSubscribeClient, EmberAfStatus status)
{
auto subscriptionId = apSubscribeClient->GetSubscriptionId();
ChipLogProgress(Zcl, "SubscribeResponse:");
if (subscriptionId.HasValue())
{
ChipLogProgress(Zcl, " SubscriptionId: 0x%" PRIx64, subscriptionId.Value());
}
else
{
ChipLogProgress(Zcl, " SubscriptionId: <missing>");
}
ChipLogProgress(Zcl, " ApplicationIdentifier: %" PRIx64, apSubscribeClient->GetAppIdentifier());
LogStatus(status);

Expand Down
7 changes: 7 additions & 0 deletions src/controller/python/ChipDeviceController-ScriptBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ ChipError::StorageType pychip_GetConnectedDeviceByNodeId(chip::Controller::Devic
uint64_t pychip_GetCommandSenderHandle(chip::Controller::Device * device);
// CHIP Stack objects
ChipError::StorageType pychip_BLEMgrImpl_ConfigureBle(uint32_t bluetoothAdapterId);

chip::ChipError::StorageType pychip_InteractionModel_ShutdownSubscription(uint64_t subscriptionId);
}

ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl,
Expand Down Expand Up @@ -588,3 +590,8 @@ ChipError::StorageType pychip_DeviceController_PostTaskOnChipThread(ChipThreadTa
PlatformMgr().ScheduleWork(callback, reinterpret_cast<intptr_t>(pythonContext));
return CHIP_NO_ERROR.AsInteger();
}

chip::ChipError::StorageType pychip_InteractionModel_ShutdownSubscription(uint64_t subscriptionId)
{
return chip::app::InteractionModelEngine::GetInstance()->ShutdownSubscription(subscriptionId).AsInteger();
}
6 changes: 6 additions & 0 deletions src/controller/python/chip-device-ctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,9 @@ def do_zclsubscribe(self, line):
"""
To subscribe ZCL attribute reporting:
zclsubscribe <cluster> <attribute> <nodeid> <endpoint> <minInterval> <maxInterval>
To shut down a subscription:
zclsubscribe -shutdown <subscriptionId>
"""
try:
args = shlex.split(line)
Expand All @@ -826,6 +829,9 @@ def do_zclsubscribe(self, line):
raise exceptions.UnknownCluster(args[0])
self.devCtrl.ZCLSubscribeAttribute(args[0], args[1], int(
args[2]), int(args[3]), int(args[4]), int(args[5]))
elif len(args) == 2 and args[0] == '-shutdown':
subscriptionId = int(args[1], base=0)
self.devCtrl.ZCLShutdownSubscription(subscriptionId)
else:
self.do_help("zclsubscribe")
except exceptions.ChipStackException as ex:
Expand Down
10 changes: 10 additions & 0 deletions src/controller/python/chip/ChipDeviceCtrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,12 @@ def ZCLSubscribeAttribute(self, cluster, attribute, nodeid, endpoint, minInterva
# We only send 1 command by this function, so index is always 0
return im.WaitCommandIndexStatus(commandSenderHandle, 1)

def ZCLShutdownSubscription(self, subscriptionId: int):
res = self._ChipStack.Call(
lambda: self._dmLib.pychip_InteractionModel_ShutdownSubscription(subscriptionId))
if res != 0:
raise self._ChipStack.ErrorToException(res)

def ZCLCommandList(self):
return self._Cluster.ListClusterCommands()

Expand Down Expand Up @@ -489,3 +495,7 @@ def _InitLib(self):
self._dmLib.pychip_DeviceController_OpenCommissioningWindow.argtypes = [
c_void_p, c_uint64, c_uint16, c_uint16, c_uint16, c_uint8]
self._dmLib.pychip_DeviceController_OpenCommissioningWindow.restype = c_uint32

self._dmLib.pychip_InteractionModel_ShutdownSubscription.argtypes = [
c_uint64]
self._dmLib.pychip_InteractionModel_ShutdownSubscription.restype = c_uint32

0 comments on commit 1fbca19

Please sign in to comment.