pub unsafe extern "C" fn otPlatRadioScheduleTx(
aInstance: *mut otInstance,
aTxTime: otRadioTime64,
) -> otErrorExpand description
Schedule a radio frame transmission at a specific target time.
This API requires the radio platform to support the OT_RADIO_CAPS_SCHEDULED_TX capability. Its primary purpose is
to support Thread Direct, though it may also be used for other time-sensitive transmission use cases in the future.
The caller forms the IEEE 802.15.4 frame in the buffer provided by otPlatRadioGetScheduledTxFrame() before calling
this function to schedule the transmission at @p aTxTime.
The radio platform MUST execute the scheduled transmission according to the following rules:
-
Target Transmission Time and Strict On-Time Requirement:
- The radio platform MUST transmit the requested frame at the exact specified time @p aTxTime.
- @p aTxTime is an
otRadioTime64value in microseconds relative to the local radio clock (seeotPlatRadioGetNow()). - @p aTxTime SHALL point to the exact point in time when the end of the Start of Frame Delimiter (SFD) will be present at the local antenna. The radio platform driver MUST account for any necessary radio ramp-up, channel switching, Clear Channel Assessment (CCA, if enabled), and SHR (preamble and SFD) transmission durations so that the end of the SFD aligns with @p aTxTime.
- Strict on-time execution (no early or late transmission): It is critical that the frame is transmitted at
@p aTxTime. If at the target transmission time the radio driver determines that it cannot transmit the frame at
@p aTxTime (for example, due to Coex denial or hardware unavailability), it MUST NOT transmit the frame earlier
or later. Instead, it MUST abort the transmission and invoke
otPlatRadioScheduledTxDone()withOT_ERROR_ABORTto indicate that the frame was not sent. - Past or missed @p aTxTime at schedule time: The OpenThread stack calls
otPlatRadioScheduleTx()as early as possible (as soon as it knows a scheduled transmission is needed), providing the radio platform with ample lead time ahead of @p aTxTime (for example, to account for radio ramp-up, Coex requests, etc.). However, @p aTxTime may still occasionally be in the past or too close to the current radio timeotPlatRadioGetNow()(for example, if a frame is queued very close to the target slot, or if a blocking operation such as a flash re-write stalls execution). In this case, the radio platform MUST NOT transmit the frame.otPlatRadioScheduleTx()MUST still returnOT_ERROR_NONEand asynchronously report the failure by invokingotPlatRadioScheduledTxDone()withOT_ERROR_ABORT. The radio platform MUST NOT invokeotPlatRadioScheduledTxDone()synchronously from withinotPlatRadioScheduleTx(). IfotPlatRadioCancelScheduledTx()is called before this deferredOT_ERROR_ABORTcallback is invoked, the radio platform MAY either cancel the pending callback and returnOT_ERROR_NONE, or returnOT_ERROR_BUSYand proceed with invoking theotPlatRadioScheduledTxDone()callback.
-
Operational Precedence, Preemption, and State Restoration:
- A scheduled transmission SHOULD be prioritized over other radio operations when @p aTxTime arrives:
- Ongoing Receive or Acknowledgment TX: If the radio is in Receive mode and is in the middle of receiving a
frame (e.g., after SHR detection) or transmitting an acknowledgment for a received frame when the radio needs
to prepare/transmit for @p aTxTime, the scheduled transmission SHOULD take precedence—the active reception or
acknowledgment transmission SHOULD be stopped/aborted so that the scheduled transmission goes out on time at
@p aTxTime. When an ongoing reception or acknowledgment transmission is aborted, the radio platform MAY either
invoke
otPlatRadioReceiveDone()withOT_ERROR_ABORTor not invokeotPlatRadioReceiveDone()at all (if the radio platform still delivers a received frame whose acknowledgment transmission was aborted viaotPlatRadioReceiveDone()withOT_ERROR_NONE,mAckedWithFramePendingandmAckedWithSecEnhAckMUST be set tofalse). - Concurrent
otPlatRadioTransmit(): If the radio is instructed to transmit a frame viaotPlatRadioTransmit()close to or overlapping with a previously scheduled transmission, the scheduled transmission SHOULD take precedence and be performed at @p aTxTime. For the conflictingotPlatRadioTransmit()operation, the radio platform MAY either:- Abort the
otPlatRadioTransmit()operation and invokeotPlatRadioTxDone()withOT_ERROR_ABORT(so the OpenThread stack does not remain blocked waiting forotPlatRadioTxDone()and can handle any retries), or - Defer the
otPlatRadioTransmit()operation until after the scheduled transmission completes, provided that theotPlatRadioTransmit()has not yet started on the air (otPlatRadioTxStarted()has not been invoked) and is not a timed transmission (mTxDelay != 0) whose target time would be missed. If theotPlatRadioTransmit()has already started on the air or is a timed transmission whose target time would be missed, it MUST be aborted viaotPlatRadioTxDone()withOT_ERROR_ABORT.
- Abort the
- Ongoing Receive or Acknowledgment TX: If the radio is in Receive mode and is in the middle of receiving a
frame (e.g., after SHR detection) or transmitting an acknowledgment for a received frame when the radio needs
to prepare/transmit for @p aTxTime, the scheduled transmission SHOULD take precedence—the active reception or
acknowledgment transmission SHOULD be stopped/aborted so that the scheduled transmission goes out on time at
@p aTxTime. When an ongoing reception or acknowledgment transmission is aborted, the radio platform MAY either
invoke
- Radio State and Post-Transmission Restoration:
- If this function is called while the radio is disabled (
OT_RADIO_STATE_DISABLED), it MUST returnOT_ERROR_INVALID_STATE. CallingotPlatRadioDisable()while a scheduled TX is pending or active MUST immediately abort and cancel it without invokingotPlatRadioScheduledTxDone()(and MUST NOT fail withOT_ERROR_INVALID_STATEdue to the active scheduled TX when the underlying state isSleep). - When the radio is enabled,
otPlatRadioScheduleTx()can be called from any radio state (Sleep,Receive, orTransmit). Conversely, subsequent calls tootPlatRadioSleep(),otPlatRadioReceive(),otPlatRadioReceiveAt(), orotPlatRadioTransmit()while a scheduled TX is pending MUST NOT cancel or alter the pending scheduled transmission (onlyotPlatRadioCancelScheduledTx()orotPlatRadioDisable()cancels it). - If
otPlatRadioSleep()orotPlatRadioReceive()is called while the scheduled transmission is actively in progress on the air (or waiting for its acknowledgment) at @p aTxTime, the radio platform MUST NOT abort the ongoing scheduled transmission and MUST NOT fail the call withOT_ERROR_BUSYorOT_ERROR_INVALID_STATE. Instead, it MUST returnOT_ERROR_NONE, complete the scheduled transmission, and then transition to the newly requested state (SleeporReceiveon the requested channel). - Once the scheduled transmission completes (after transmitting the frame and receiving the acknowledgment or
timing out when an acknowledgment is requested, or if CCA fails or the transmission is aborted), the radio
platform MUST automatically return to its target state (the state prior to the scheduled transmission, or any
updated state requested via
otPlatRadioSleep()orotPlatRadioReceive()while the scheduled transmission was pending/active) and resume what it was doing:- If the target state is
Receiveon a channel (fromotPlatRadioReceive()), it MUST return toReceiveon that receive channel (mRxChannelAfterTxDoneinotRadioFrameMUST be ignored). - If the target state is
Sleepwith an active timed reception window (fromotPlatRadioReceiveAt()whose window has not yet expired), it MUST return toReceiveon that window’s channel for the remaining duration of the window before transitioning back toSleep. - If the target state is
Sleep(and not in an active timed reception window), it MUST return toSleep. - If a transmission requested via
otPlatRadioTransmit()was deferred for the scheduled transmission, the radio platform SHOULD proceed with that transmission.
- If the target state is
- If this function is called while the radio is disabled (
- A scheduled transmission SHOULD be prioritized over other radio operations when @p aTxTime arrives:
-
Single Active Schedule and Frame Buffer Ownership:
- At most one scheduled transmission request can be active at any time, using the single
otRadioFrameprovided byotPlatRadioGetScheduledTxFrame(). - After a successful
otPlatRadioScheduleTx()call (and before it is canceled viaotPlatRadioCancelScheduledTx()orotPlatRadioDisable(), or completed viaotPlatRadioScheduledTxDone()), any new call tootPlatRadioScheduleTx()MUST be rejected by returningOT_ERROR_BUSYwithout affecting the active schedule. The OpenThread stack will generally not callotPlatRadioScheduleTx()again until the previous schedule is canceled or completed viaotPlatRadioScheduledTxDone(). - Upon a successful
otPlatRadioScheduleTx()call, the radio platform takes ownership of the frame buffer fromotPlatRadioGetScheduledTxFrame(). The OpenThread stack guarantees that it will not touch or modify the frame buffer or its contents while owned by the radio platform. - Invoking the
otPlatRadioScheduledTxDone()callback, a successfulotPlatRadioCancelScheduledTx()call (returningOT_ERROR_NONE), orotPlatRadioDisable()releases ownership of the frame buffer back to the OpenThread stack, allowing the stack to modify the frame again.
- At most one scheduled transmission request can be active at any time, using the single
-
Handling of
otRadioFrame(mTxInfo) fields:mTxDelayBaseTimeandmTxDelay: MUST be ignored. The target transmission time is specified solely by the @p aTxTime parameter.mCsmaCaEnabled: Indicates whether CCA MUST be performed before transmitting the frame:- When set to
false, the frame MUST be transmitted at @p aTxTime without performing CCA. - When set to
true, CCA MUST be performed prior to transmission (timed so that the end of the SFD still occurs at @p aTxTime). If CCA fails, the radio platform MUST NOT transmit the frame and MUST reportOT_ERROR_CHANNEL_ACCESS_FAILUREviaotPlatRadioScheduledTxDone().
- When set to
mMaxCsmaBackoffs: MUST always be ignored (treated as0). The radio platform MUST NOT perform any CSMA backoff for a scheduled transmission.mMaxFrameRetries: MUST always be ignored (treated as0). A scheduled transmission is a single transmission attempt with no retries by the radio platform (the OpenThread stack manages any retransmissions in subsequent time slots).mRxChannelAfterTxDone: MUST be ignored. Upon completing the scheduled transmission, the radio MUST return to its previous state and receive channel (if it was receiving).mIsARetxandmCslPresent: MUST be ignored.mTimestamp: When the frame is transmitted, the radio platform MUST update this field with the local radio clock timestamp (in microseconds) when the end of the SFD was present at the local antenna before invokingotPlatRadioScheduledTxDone().mIsHeaderUpdatedandmIsSecurityProcessed: Follow their existing behavior as defined forotPlatRadioTransmit()whenOT_RADIO_CAPS_TRANSMIT_SECis supported. WhenmIsHeaderUpdatedisfalse, the radio platform MUST assign the MAC frame counter and perform security processing when preparing the frame for transmission at @p aTxTime (rather than whenotPlatRadioScheduleTx()is called), ensuring that frame counters are used in order on the air if other transmissions or enhanced acknowledgments occur before @p aTxTime and that no frame counter is wasted if the scheduled transmission is canceled or aborted before the frame is prepared at @p aTxTime.- All other fields (
mChannel,mAesKey,mIeInfo,mTxPower) MUST follow their existing behavior as defined forotPlatRadioTransmit().
-
Completion and Callbacks:
- The radio platform MUST report the outcome of the scheduled transmission using the
otPlatRadioScheduledTxDone()callback. - Aside from
OT_ERROR_INVALID_STATE(when the radio is disabled) andOT_ERROR_BUSY(when a previously scheduled transmission is still active),otPlatRadioScheduleTx()MUST NOT return any other error synchronously. Any other runtime failure to schedule or transmit the frame (for example, ifmChannelon the scheduled TX frame is invalid or unsupported) MUST still returnOT_ERROR_NONEfromotPlatRadioScheduleTx()and be reported asynchronously by invokingotPlatRadioScheduledTxDone()withOT_ERROR_ABORT. - A scheduled transmission MUST NOT invoke
otPlatRadioTxStarted()orotPlatRadioTxDone(). Those callbacks are used exclusively for transmissions initiated viaotPlatRadioTransmit().
- The radio platform MUST report the outcome of the scheduled transmission using the
Why a dedicated scheduled TX API is used (and comparison with OT_RADIO_CAPS_TRANSMIT_TIMING):
-
Coexistence (Coex) and Radio Arbitration: While the OpenThread stack can track time and schedule radio operations in software, it does not have visibility into platform-level radio coexistence (Coex) with other radios sharing the same device or antenna (such as Wi-Fi or Bluetooth/BLE). The radio platform driver is responsible for managing Coex arbitration and is therefore in a much better position to request appropriate Coex priority ahead of time and ensure the scheduled transmission goes out at the exact specified target time @p aTxTime. Similarly, the radio platform can directly preempt ongoing radio activity (such as an active frame reception, acknowledgment transmission, or a regular
otPlatRadioTransmit()operation) when @p aTxTime arrives. -
Differences from
OT_RADIO_CAPS_TRANSMIT_TIMING(mTxDelayBaseTimeandmTxDelay):OT_RADIO_CAPS_TRANSMIT_TIMINGwas originally introduced to support CSL in Thread 1.2 by extending the existingotPlatRadioTransmit()API usingmTxDelayBaseTimeandmTxDelay. That model has several limitations for more strict protocols like Thread Direct:- Existing vendor implementations of
OT_RADIO_CAPS_TRANSMIT_TIMINGvary in their behavior when the target transmission time is missed (for example, some implementations still transmit the frame after a delay even if the target time has passed). While a slightly delayed transmission may still fall within a peer’s CSL sample window, transmitting late or outside the designated time slot in Thread Direct could result in unpredictable failures.otPlatRadioScheduleTx()defines strict, explicit requirements on timing accuracy, operational precedence, and missed-target handling. otPlatRadioTransmit()is a blocking state-transition operation: once called, the OpenThread stack must wait forotPlatRadioTxDone()before it can issue any other transmit, receive, or sleep commands to the radio (which also forces the stack to wait until just before the target time to issue a timedotPlatRadioTransmit()so the radio is not tied up prematurely). In contrast,otPlatRadioScheduleTx()schedules a future transmission using a dedicated frame buffer as soon as the stack knows a scheduled transmission is needed—allowing the radio to continue other operations in the meantime and supporting explicit cancellation viaotPlatRadioCancelScheduledTx().
- Existing vendor implementations of
@param[in] aInstance The OpenThread instance structure.
@param[in] aTxTime The target transmission time (end of SFD at the local antenna) in microseconds relative to the
local radio clock (see otPlatRadioGetNow()).
@retval OT_ERROR_NONE Successfully scheduled the frame transmission. @retval OT_ERROR_BUSY A previously scheduled transmission is still active. @retval OT_ERROR_INVALID_STATE The radio is disabled.