Separate Radio-model from Dispatcher to allow different Radio-models
EskoDijk opened this issue · comments
This proposal is to rework the Dispatcher so that the Radio-model can be separated into its own class. This would then easily allow multiple radio models to be defined and used.
It would also allow to use a Radio-model that communicates (over sockets) with an equivalent radio-model that is running in an external RF simulator. For example in Whitefield (https://github.com/whitefield-framework/whitefield) this kind of approach is used.
To get started we could first develop two simple radio models:
- Current model - mutual interference is not modeled and packets have a configurable loss probability.
- Simplest mutual interference model - any transmission takes some time (~5 ms) in the RF medium; and 'blocks' access to the RF medium for all other nodes. So a bit pessimistic model. Prior to transmit of a node the Radio-model checks CCA and if not clear it will return a CCA-Failure back to the OpenThread Posix/simulated node.
To realize this a few additional event-types need to be defined; and these events can also flow between Dispatcher/Radio-model and between Dispatcher/OpenThread-nodes. To reduce the amount of low-level code dealing with bits 'n bytes I'd like to add a generic 'Serialize()' method to event which creates the bytes to be sent over the socket. Also 'Deserialize()' for the reverse.
Event types foreseen:
- Radio Frame: indicates a transmission attempt starting from OpenThread-node to Radio-model
- Rx Start: signals from Radio-model to OpenThread-node that the radio has started receiving something
- Tx Done: signals from Radio-model to OpenThread-node that transmission attempt is done (and returns status also, e.g. CCA fail or success)
- Radio Frame: signals frame delivery and successful Rx Done from Radio-model to OpenThread-node.
RSSI of received packet is also communicated to the OpenThread-node, using either the Rx Start or Radio Frame event.
Of course some changes on the OpenThread repo, 'simulation' target platform, are also needed for this but that looks relatively simple. (All the virtual-time related code that's needed is already there.)
any transmission takes some time (~5 ms) in the RF medium
I was actually trying to implement this simple enhancement for OpenThread CI (Python virtual time simulator) as in openthread/openthread#6476, where the packet transmission time is calculated from the actual frame size. However, it's causing CI failures, which I still haven't got a chance to investigate.
Radio Frame: indicates a transmission attempt starting from OpenThread-node to Radio-model
The radio event already does that?
Rx Start: signals from Radio-model to OpenThread-node that the radio has started receiving something
I wonder why this radio event is necessary.
Tx Done: signals from Radio-model to OpenThread-node that transmission attempt is done (and returns status also, e.g. CCA fail or success)
Currently, the TX done event is signalled by sending the exact same frame back to the sender. It works if every transmission always leads to success, but apparently need some change if we want to return CCA failures back to node.
Radio Frame: signals frame delivery and successful Rx Done from Radio-model to OpenThread-node.
Radio event already does that?
@simonlingoogle There's now a draft implementation of the separate radiomodel available at https://github.com/EskoDijk/ot-ns/tree/sim-radiomodel. Because the event structure and contents are updated, it only works together with the adapted OT node at https://github.com/EskoDijk/openthread/tree/sim-radio-model .
The event "Rx Start" to signal the OT-node that Rx has started turned out to be not needed. I thought initially this was needed for accurate start of frame time determination in the OT-node, however, this can just as well be calculated at the end of Rx if needed. Currently it just timestamps the frame at end of Rx like for existing simulation platform and for some other radio drivers.
The Tx Done event is signaled now as a separate event, not the echo-frame, so that some status data can be included. In this case an OT-error code is sent back to signal e.g. success or CCA failure, or even Abort (in case the radio was already transmitting something)
The Radio Frame event also signals RSSI value of the Rx frame as a parameter.
There are 2 test radiomodels in there, one "ideal" and one slightly more realistic (but a bit pessimistic in the sense that it considers the entire RF medium everywhere to be occupied when 1 node is transmitting.)
There was quite some refactoring and commenting done (latter was needed for myself to keep track of what the code does.) The sendQueue was generalized to an any-event-except-Alarm queue. Event serialization and deserialization was separated from the dispatcher package for clarity. (It depends fully on the OT-node event definition, so keeping it separate in the 'types' package seemed best.)
@simonlingoogle There's now a draft implementation of the separate radiomodel available at https://github.com/EskoDijk/ot-ns/tree/sim-radiomodel. Because the event structure and contents are updated, it only works together with the adapted OT node at https://github.com/EskoDijk/openthread/tree/sim-radio-model .
Looking forward to the PR.
The event "Rx Start" to signal the OT-node that Rx has started turned out to be not needed. I thought initially this was needed for accurate start of frame time determination in the OT-node, however, this can just as well be calculated at the end of Rx if needed. Currently it just timestamps the frame at end of Rx like for existing simulation platform and for some other radio drivers.
Theoretically speaking, simulator can tell both RX start
and RX end
in one radio event?
The Tx Done event is signaled now as a separate event, not the echo-frame, so that some status data can be included. In this case an OT-error code is sent back to signal e.g. success or CCA failure, or even Abort (in case the radio was already transmitting something)
If we are not using echo-frame
anymore, we also need to adapt the Python VT simulator used in CIs.
We can also keep echo-frame
so that Python VT simulator still works.
But I am not sure which is the better solution.
The Radio Frame event also signals RSSI value of the Rx frame as a parameter.
Do you mean radio received or radio sent event?
There are 2 test radiomodels in there, one "ideal" and one slightly more realistic (but a bit pessimistic in the sense that it considers the entire RF medium everywhere to be occupied when 1 node is transmitting.)
The realistic
should be suitable for a small home environment where all nodes are in the radio range of every nodes.
We can also keep echo-frame so that Python VT simulator still works.
But I am not sure which is the better solution.
I had the same thought; the echo-frame can be kept alongside the new events in principle.
The events that use the changed/new event format could also be assigned different numbers so there's no overlap with the "legacy" event types/format.
Do you mean radio received or radio sent event?
The event type EventTypeRadioFrameToNode (1) includes the RSSI. The event type EventTypeRadioFrameToSim includes the Tx-Power and the current CCA ED threshold as parameters. The latter isn't used yet by the radiomodels, but a next version radio model could use it.
Note that the new code isn't tested yet with real-time nodes; still to check if that would work. Is the real-time OT-NS simulation mode is still of interest? (e.g. does it have particular use cases not covered by virtual-time mode?)
The associated PR is #316 - this will need some more work to address comments and to fix bugs (so we can run all the tests reliably.)
closing this issue - now obsoleted by newer developments in OTNS2 (https://github.com/EskoDijk/ot-ns). Will open a new issue for OTNS2 merging into main.