-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use the incoming exchange context to send responses in the data model #6438
Use the incoming exchange context to send responses in the data model #6438
Conversation
31d2627
to
fdaeada
Compare
fdaeada
to
3c98260
Compare
3c98260
to
00caede
Compare
EmberAfMessageSentFunction callback); | ||
// EmberStatus emberAfSendBroadcastWithAliasWithCallback(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength, | ||
// uint8_t * message, EmberNodeId alias, uint8_t sequence, | ||
// EmberAfMessageSentFunction callback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just completely delete those methods ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to decide that.... I guess at this point we're not going to pull in any more silabs code that might use them, so you might be right that we can.
f7ec910
to
47868f7
Compare
* @param[in] message The message to send after the APS frame. | ||
* @param[in] sendFlags The SendFlags needed, if any. | ||
*/ | ||
EmberStatus chipSendUnicast(chip::Messaging::ExchangeContext * exchange, EmberApsFrame * apsFrame, uint16_t messageLength, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: capitalize?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is following the existing style (for both this file and this directory), for now. I am happy to change that style, but feel like we should do that in a coordinated way across the whole thing.
/** | ||
* APS frame for the incoming message | ||
*/ | ||
EmberApsFrame * apsFrame; | ||
EmberIncomingMessageType type; | ||
chip::NodeId source; | ||
chip::Messaging::ExchangeContext * source; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exchange on the receiving side is closed immediately within unsolicited message handler.
void OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader,
const PayloadHeader & payloadHeader, System::PacketBufferHandle buffer) override
{
.....
{
HandleDataModelMessage(exchangeContext, std::move(buffer));
}
exit:
exchangeContext->Close();
}
The passed-in exchange in HandleDataModelMessage get populated to returnCmd struct and this struct is used in callback stubs of different bindings, how can we make sure the passed-in exchange is not dangling pointer before use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used to synchronously, before HandleDataModelMessage
returns, send a response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the API contract for now is that HandleDataModelMessage
must respond sync. If that changes, we will need to condition the Close
here on HandleDataModelMessage
not being reached and hand off closing to HandleDataModelMessage
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, all stub functions are not filled
bool attribute((weak)) emberAfPreCommandReceivedCallback(EmberAfClusterCommand * cmd)
{
return false;
}
If we implement those callbacks later, it can not be still synchronously if the response needs to be sent from different bindings, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exchange needs to be closed at the end of the 'conversation', this syntax is defined within the protocol since it has the context to know which message mark the end of the conversation.
For TempZCL protocol without a protocol syntax defined, I feel it is more safe to use a dedicated exchange to send request and response message separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean by "the response needs to be sent from different bindings".
Right now, the contract is that emberAfPreCommandReceivedCallback
would need to send a response, if any, before returning.
Again, we could change this contract. I don't think we should do it in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For TempZCL protocol without a protocol syntax defined, I feel it is more safe to use a dedicated exchange to send request and response message separately.
There are a few problems with that:
- It leads to problems correlating responses with requests.
- It causes our existing tests to not exercise various exchange-related code (like CRMP). Note that in the process of working on this PR I ended up finding various controller and CRMP bugs that were due precisely due to that functionality not being exercised in existing tests.
In general, everything in TempZCL is currently of the form (1 request, 1 response). The one exception I can think of is whether we ever send Default Response from the initiator side (in response to a non-status response). But since the responder side ignores those responses anyway, it doesn't matter too much that it closes its exchange before it receives them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we can still benefit more from this change if we can guarantee HandleDataModelMessage must handle the respond synchronously.
CRMP is disabled since separate exchange is used for request and response, should we enable CRMP now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR enables CRMP on the DeviceController side and enables it for responses to an incoming message on the data model side. The one place we are still disabling it is for data-model-initiated sends to a specific node (e.g. attribute reporting).
15f50f7
to
ba2fa24
Compare
ba2fa24
to
f182a42
Compare
@@ -106,18 +120,15 @@ EmberStatus chipSendUnicast(NodeId destination, EmberApsFrame * apsFrame, uint16 | |||
// receive the ack message. This logic needs to be deleted after we convert all legacy ZCL messages to IM messages. | |||
DeviceExchangeDelegate delegate; | |||
exchange->SetDelegate(&delegate); | |||
|
|||
Messaging::SendFlags sendFlags; | |||
|
|||
sendFlags.Set(Messaging::SendMessageFlags::kFromInitiator).Set(Messaging::SendMessageFlags::kNoAutoRequestAck); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need to disable CRMP after use same exchange to send response?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the codepath where we're sending to a specific node by node id, so still creating a temporary exchange. For attribute reporting, for example. To stop disabling CRMP here we would need to have a nontrivial exchange delegate that actually handles the messages from the other side properly and closes the exchange as needed. We can do that, but I was trying to not scope-creep this PR.
ff268a0
to
c7ad3a4
Compare
@bzbarsky-apple Darwin CI is failing :( |
in addition, @woody-apple @bzbarsky-apple python device controller in cirque test is consistently failing with this change, something wrong inside exchange manager/crmp 2021-05-05 13:32:52,434 [CHIPMobileDevice] INFO Send EnableNetwork command to device 1 |
Sending a reply needs a non-const ExchangeContext.
6cf1e5a
to
c33f55b
Compare
…reating a new one.
c33f55b
to
c0bb202
Compare
Size increase report for "esp32-example-build" from 6b0d0d1
Full report output
|
Size increase report for "nrfconnect-example-build" from 6b0d0d1
Full report output
|
Fixes #3584 and sets us up to more cleanly track what a send-destination is now that it's not just an integer.
Review note: It may well be simpler to review the individual changesets, not the whole diff.