Skip to content

Commit

Permalink
Add ability for chip-repl to grab MaxPathsPerInvoke of remote node (#…
Browse files Browse the repository at this point in the history
…30880)

* Add ability for chip-repl to grab MaxPathsPerInvoke of remote node

* Fix CI

* Address PR comments

* Restyle

* Address PR comments

* Address PR comments
  • Loading branch information
tehampson authored Dec 11, 2023
1 parent 696975f commit 1a3f256
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
32 changes: 31 additions & 1 deletion src/controller/python/chip/ChipDeviceCtrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
from .clusters.CHIPClusters import ChipClusters
from .crypto import p256keypair
from .exceptions import UnknownAttribute, UnknownCommand
from .interaction_model import InteractionModelError
from .interaction_model import InteractionModelError, SessionParameters, SessionParametersStruct
from .interaction_model import delegate as im
from .native import PyChipError

Expand Down Expand Up @@ -809,6 +809,36 @@ def ComputeRoundTripTimeout(self, nodeid, upperLayerProcessingTimeoutMs: int = 0
device.deviceProxy, upperLayerProcessingTimeoutMs))
return res

def GetRemoteSessionParameters(self, nodeid) -> typing.Optional[SessionParameters]:
''' Returns the SessionParameters of reported by the remote node associated with `nodeid`.
If there is some error in getting SessionParameters None is returned.
This will result in a session being established if one wasn't already established.
'''

# First creating the struct to make building the ByteArray to be sent to CFFI easier.
sessionParametersStruct = SessionParametersStruct.parse(b'\x00' * SessionParametersStruct.sizeof())
sessionParametersByteArray = SessionParametersStruct.build(sessionParametersStruct)
device = self.GetConnectedDeviceSync(nodeid)
res = self._ChipStack.Call(lambda: self._dmLib.pychip_DeviceProxy_GetRemoteSessionParameters(
device.deviceProxy, ctypes.c_char_p(sessionParametersByteArray)))

# 0 is CHIP_NO_ERROR
if res != 0:
return None

sessionParametersStruct = SessionParametersStruct.parse(sessionParametersByteArray)
return SessionParameters(
sessionIdleInterval=sessionParametersStruct.SessionIdleInterval if sessionParametersStruct.SessionIdleInterval != 0 else None,
sessionActiveInterval=sessionParametersStruct.SessionActiveInterval if sessionParametersStruct.SessionActiveInterval != 0 else None,
sessionActiveThreshold=sessionParametersStruct.SessionActiveThreshold if sessionParametersStruct.SessionActiveThreshold != 0 else None,
dataModelRevision=sessionParametersStruct.DataModelRevision if sessionParametersStruct.DataModelRevision != 0 else None,
interactionModelRevision=sessionParametersStruct.InteractionModelRevision if sessionParametersStruct.InteractionModelRevision != 0 else None,
specficiationVersion=sessionParametersStruct.SpecificationVersion if sessionParametersStruct.SpecificationVersion != 0 else None,
maxPathsPerInvoke=sessionParametersStruct.MaxPathsPerInvoke)

return res

async def TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke(self, nodeid: int, endpoint: int,
payload: ClusterObjects.ClusterCommand, responseType=None):
'''
Expand Down
6 changes: 4 additions & 2 deletions src/controller/python/chip/interaction_model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@

from chip.exceptions import ChipStackException

from .delegate import AttributePath, AttributePathIBstruct, DataVersionFilterIBstruct, EventPath, EventPathIBstruct
from .delegate import (AttributePath, AttributePathIBstruct, DataVersionFilterIBstruct, EventPath, EventPathIBstruct,
SessionParameters, SessionParametersStruct)

__all__ = ["AttributePath", "AttributePathIBstruct", "DataVersionFilterIBstruct",
"EventPath", "EventPathIBstruct", "Status", "InteractionModelError"]
"EventPath", "EventPathIBstruct", "InteractionModelError",
"SessionParameters", "SessionParametersStruct", "Status"]


# defined src/controller/python/chip/interaction_model/Delegate.h
Expand Down
21 changes: 21 additions & 0 deletions src/controller/python/chip/interaction_model/delegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@
"DataVersion" / Int32ul,
)

SessionParametersStruct = Struct(
"SessionIdleInterval" / Int32ul,
"SessionActiveInterval" / Int32ul,
"SessionActiveThreshold" / Int16ul,
"DataModelRevision" / Int16ul,
"InteractionModelRevision" / Int16ul,
"SpecificationVersion" / Int32ul,
"MaxPathsPerInvoke" / Int16ul,
)


@dataclass
class AttributePath:
Expand Down Expand Up @@ -107,6 +117,17 @@ class AttributeWriteResult:
status: int


@dataclass
class SessionParameters:
sessionIdleInterval: typing.Optional[int]
sessionActiveInterval: typing.Optional[int]
sessionActiveThreshold: typing.Optional[int]
dataModelRevision: typing.Optional[int]
interactionModelRevision: typing.Optional[int]
specficiationVersion: typing.Optional[int]
maxPathsPerInvoke: int


# typedef void (*PythonInteractionModelDelegate_OnCommandResponseStatusCodeReceivedFunct)(uint64_t commandSenderPtr,
# void * commandStatusBuf);
# typedef void (*PythonInteractionModelDelegate_OnCommandResponseProtocolErrorFunct)(uint64_t commandSenderPtr,
Expand Down
42 changes: 42 additions & 0 deletions src/controller/python/chip/utils/DeviceProxyUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@

using namespace chip;

namespace python {

struct __attribute__((packed)) SessionParametersStruct
{
uint32_t sessionIdleInterval = 0;
uint32_t sessionActiveInterval = 0;
uint16_t sessionActiveThreshold = 0;
uint16_t dataModelRevision = 0;
uint16_t interactionModelRevision = 0;
uint32_t specificationVersion = 0;
uint16_t maxPathsPerInvoke = 0;
};

} // namespace python

extern "C" {

/**
Expand All @@ -59,4 +74,31 @@ uint32_t pychip_DeviceProxy_ComputeRoundTripTimeout(DeviceProxy * device, uint32
->ComputeRoundTripTimeout(System::Clock::Milliseconds32(upperLayerProcessingTimeoutMs))
.count();
}

/**
* @brief This gets the Session Parameters reported by remote node.
*
* A valid DeviceProxy pointer with a valid established session is required for this method.
*/
PyChipError pychip_DeviceProxy_GetRemoteSessionParameters(DeviceProxy * device, void * sessionParametersStructPointer)
{
VerifyOrReturnError(device != nullptr || sessionParametersStructPointer, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));

auto * deviceProxy = static_cast<DeviceProxy *>(device);
VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_INCORRECT_STATE));

auto remoteSessionParameters = deviceProxy->GetSecureSession().Value()->GetRemoteSessionParameters();
auto remoteMrpConfig = remoteSessionParameters.GetMRPConfig();

python::SessionParametersStruct * sessionParam = static_cast<python::SessionParametersStruct *>(sessionParametersStructPointer);

sessionParam->sessionIdleInterval = remoteMrpConfig.mIdleRetransTimeout.count();
sessionParam->sessionActiveInterval = remoteMrpConfig.mActiveRetransTimeout.count();
sessionParam->sessionActiveThreshold = remoteMrpConfig.mActiveThresholdTime.count();
sessionParam->dataModelRevision = remoteSessionParameters.GetDataModelRevision().ValueOr(0);
sessionParam->interactionModelRevision = remoteSessionParameters.GetInteractionModelRevision().ValueOr(0);
sessionParam->specificationVersion = remoteSessionParameters.GetSpecificationVersion().ValueOr(0);
sessionParam->maxPathsPerInvoke = remoteSessionParameters.GetMaxPathsPerInvoke();
return ToPyChipError(CHIP_NO_ERROR);
}
}

0 comments on commit 1a3f256

Please sign in to comment.