Closed JKRhb closed 1 year ago
Ah, ouch. The token for the "overarching" request is set in the exchange when fireRespond
is called: https://github.com/shamblett/coap/blob/4.2.1/lib/src/net/coap_exchange.dart#L154
For blockwise this is the last token in the blockwise exchange.
I can test a bit too. Just for reference, server that could be used for testing (can be modified to return blockwise): https://github.com/plgd-dev/go-coap/tree/master/examples/mcast/server
Client:
FutureOr<void> main(final List<String> args) async {
final conf = CoapConfig();
final uri = Uri(
scheme: 'coap',
host: CoapDefinedAddress.allCOAPNodesIPV4,
port: conf.defaultPort,
);
final client = CoapClient(uri, conf);
try {
final req = CoapRequest.newGet()..uriPath = '/oic/res';
await client.send(
req,
onMulticastResponse: CoapMulticastResponseHandler(print),
);
} on Exception catch (e) {
print('CoAP encountered an exception: $e');
}
client.close();
}
Maybe the check could simply return true if multicast is being used, like so?
I think this wouldn't work if you have two different multicast requests running concurrently, then there would be no filtering mechanism between responses for the two?
EDIT: I think multicast block1
requests are not supported as per the RFC, which leaves block2
for us to investigate: https://datatracker.ietf.org/doc/html/rfc7959#section-2.8
Other uses of the Block options [than block2] in conjunction with multicast messages are for further study.
The go-coap
server seems to ignore block1
requests, emitting the error "message is truncated", since it's not anticipating a block1
request, but block2
seems to work for me with multicast?
Thank you, @JosefWN, for your investigation and the minimal example :)
I think this wouldn't work if you have two different multicast requests running concurrently, then there would be no filtering mechanism between responses for the two?
Yeah, I just realized this as well :/ Maybe a handler method could simply check if a final response with the same token from the same endpoint already has arrived and ignore it if that should be the case?
I think multicast
block1
requests are not supported as per the RFC, which leavesblock2
for us to investigate: https://datatracker.ietf.org/doc/html/rfc7959#section-2.8
Good point :)
The go-coap server seems to ignore block1 requests, emitting the error "message is truncated", since it's not anticipating a block1 request, but block2 seems to work for me with multicast?
Hmm, I haven't tried out the go-coap server yet, but sending a multicast request for retrieving a block-wise resource also works fine in theory for me (see the Wireshark log below where I used an ESP32 for running a CoAP server). However, after the exchange is completed, the result is not passed to the CoapMulticastResponseHandler
and is also not returned as a response, causing the example to hang for me.
Ah, my bad, I was printing all of the events and must have mistaken CoapRespondingEvent
for CoapRespondEvent
. Will dig a bit more, it could have to do with how the exchange is duplicated.
Yeah, tried and it works in v3.5.0
, so it was my refactor.
An attempt at a fix with a multicast token like you were thinking of: https://github.com/shamblett/coap/pull/102
We can keep this open until this is fixed:
Thank you, @JosefWN, block-wise multicast requests now work again :) The only thing I noticed is that the client seems to hang if you use multicast even if you explicitly close it. Unfortunately, I haven't been able to find the point where to fix the issue yet. Destroying the eventBus in the client, for example, does not have an effect on the behavior.
EDIT: Just in case, can you try with this PR: https://github.com/shamblett/coap/pull/109
See if it makes any difference.
Believe this has been addressed. Package re released at version 5.0.0.
In the current version of the library, using multicast with block-wise transfer currently does not work anymore, as the client checks if the response's token matches the one of the original request.
https://github.com/shamblett/coap/blob/3f03f45e66ca4102ce729a95a0477fab4acd1292/lib/src/coap_client.dart#L474
However, because the client switches to unicast when using block-wise transfer with a server, this check always returns
false
because a new token is assigned once the switch is made. I will try to come up with a fix for this problem in the next couple of days.Maybe the check could simply return
true
if multicast is being used, like so?Or could we add a field for an "original token" somewhere, which could be used for matching instead?