|
|
@@ -22,10 +22,16 @@
|
|
|
#include "rom/ets_sys.h"
|
|
|
|
|
|
#include "openthread-core-config.h"
|
|
|
+#include "openthread/link.h"
|
|
|
#include "openthread/platform/diag.h"
|
|
|
#include "openthread/platform/radio.h"
|
|
|
+#include "utils/link_metrics.h"
|
|
|
+#include "utils/mac_frame.h"
|
|
|
|
|
|
#define ESP_RECEIVE_SENSITIVITY -120
|
|
|
+#define ESP_OPENTHREAD_XTAL_ACCURACY 130
|
|
|
+#define ESP_OPENTHREAD_CSL_ACCURACY 1
|
|
|
+#define ESP_OPENTHREAD_CSL_UNCERTAIN 1
|
|
|
|
|
|
#define EVENT_TX_DONE (1 << 0)
|
|
|
#define EVENT_TX_FAILED (1 << 1)
|
|
|
@@ -46,16 +52,38 @@ typedef struct {
|
|
|
static otRadioFrame s_transmit_frame;
|
|
|
|
|
|
static esp_openthread_radio_tx_psdu s_transmit_psdu;
|
|
|
+static uint8_t *s_enhack;
|
|
|
static otRadioFrame s_receive_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE];
|
|
|
static otRadioFrame s_ack_frame;
|
|
|
static int s_ed_power;
|
|
|
-static int s_rssi = 127;
|
|
|
static esp_ieee802154_tx_error_t s_tx_error;
|
|
|
static int s_radio_event_fd = -1;
|
|
|
static bool s_diag_mode = false;
|
|
|
static const char *s_radio_workflow = "radio";
|
|
|
static uint8_t s_txrx_events;
|
|
|
|
|
|
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
|
|
+static otRadioIeInfo s_transmit_ie_info;
|
|
|
+#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+static uint32_t s_csl_period;
|
|
|
+static uint32_t s_csl_sample_time;
|
|
|
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
+static uint32_t s_mac_frame_counter;
|
|
|
+static uint8_t s_key_id;
|
|
|
+static struct otMacKeyMaterial s_pervious_key;
|
|
|
+static struct otMacKeyMaterial s_current_key;
|
|
|
+static struct otMacKeyMaterial s_next_key;
|
|
|
+static bool s_with_security_enh_ack = false;
|
|
|
+static uint32_t s_ack_frame_counter;
|
|
|
+static uint8_t s_ack_key_id;
|
|
|
+static uint8_t s_security_key[16];
|
|
|
+static uint8_t s_security_addr[8];
|
|
|
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
+
|
|
|
static esp_openthread_circular_queue_info_t s_recv_queue = {.head = 0, .tail = 0, .used = 0};
|
|
|
|
|
|
static void set_event(uint8_t event)
|
|
|
@@ -92,6 +120,10 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf
|
|
|
s_ack_frame.mPsdu = NULL;
|
|
|
memset(&s_recv_queue, 0, sizeof(esp_openthread_circular_queue_info_t));
|
|
|
|
|
|
+#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
|
|
+ s_transmit_frame.mInfo.mTxInfo.mIeInfo = &s_transmit_ie_info;
|
|
|
+#endif
|
|
|
+
|
|
|
esp_ieee802154_enable();
|
|
|
esp_ieee802154_set_promiscuous(false);
|
|
|
esp_ieee802154_set_rx_when_idle(true);
|
|
|
@@ -266,7 +298,31 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
|
|
|
|
|
|
aFrame->mPsdu[-1] = aFrame->mLength; // lenth locates one byte before the psdu (esp_openthread_radio_tx_psdu);
|
|
|
|
|
|
- esp_ieee802154_transmit(&aFrame->mPsdu[-1], aFrame->mInfo.mTxInfo.mCsmaCaEnabled);
|
|
|
+// TODO: remove this macro check when esp32h4 unsupported.
|
|
|
+#if !CONFIG_IDF_TARGET_ESP32H4
|
|
|
+ // esp32h4 do not support tx security
|
|
|
+ if (otMacFrameIsSecurityEnabled(aFrame) && !aFrame->mInfo.mTxInfo.mIsSecurityProcessed) {
|
|
|
+ otMacFrameSetFrameCounter(aFrame, s_mac_frame_counter++);
|
|
|
+ if (otMacFrameIsKeyIdMode1(aFrame)) {
|
|
|
+ s_transmit_frame.mInfo.mTxInfo.mAesKey = &s_current_key;
|
|
|
+ if (!s_transmit_frame.mInfo.mTxInfo.mIsARetx) {
|
|
|
+ otMacFrameSetKeyId(aFrame, s_key_id);
|
|
|
+ }
|
|
|
+ esp_ieee802154_get_extended_address(s_security_addr);
|
|
|
+ }
|
|
|
+ memcpy(s_security_key, s_current_key.mKeyMaterial.mKey.m8, sizeof(s_current_key.mKeyMaterial.mKey.m8));
|
|
|
+ esp_ieee802154_set_transmit_security(&aFrame->mPsdu[-1], s_security_key, s_security_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ // esp32h4 do not support transmit at
|
|
|
+ if (aFrame->mInfo.mTxInfo.mTxDelay != 0) {
|
|
|
+ esp_ieee802154_transmit_at(&aFrame->mPsdu[-1], aFrame->mInfo.mTxInfo.mCsmaCaEnabled,
|
|
|
+ (aFrame->mInfo.mTxInfo.mTxDelayBaseTime + aFrame->mInfo.mTxInfo.mTxDelay));
|
|
|
+ } else
|
|
|
+#endif
|
|
|
+ {
|
|
|
+ esp_ieee802154_transmit(&aFrame->mPsdu[-1], aFrame->mInfo.mTxInfo.mCsmaCaEnabled);
|
|
|
+ }
|
|
|
|
|
|
otPlatRadioTxStarted(aInstance, aFrame);
|
|
|
|
|
|
@@ -280,14 +336,29 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
|
|
|
|
|
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
|
|
{
|
|
|
- return s_rssi;
|
|
|
+ return esp_ieee802154_get_recent_rssi();
|
|
|
}
|
|
|
|
|
|
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
|
|
|
{
|
|
|
- return (otRadioCaps)(OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_SLEEP_TO_TX);
|
|
|
+ return (otRadioCaps)(OT_RADIO_CAPS_ENERGY_SCAN |
|
|
|
+// TODO: remove this macro check when esp32h4 unsupported.
|
|
|
+#if !CONFIG_IDF_TARGET_ESP32H4
|
|
|
+ OT_RADIO_CAPS_TRANSMIT_SEC | OT_RADIO_CAPS_RECEIVE_TIMING | OT_RADIO_CAPS_TRANSMIT_TIMING |
|
|
|
+#endif
|
|
|
+ OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_SLEEP_TO_TX);
|
|
|
}
|
|
|
|
|
|
+// TODO: remove this macro check when esp32h4 unsupported.
|
|
|
+#if !CONFIG_IDF_TARGET_ESP32H4
|
|
|
+// esp32h4 do not support receive at
|
|
|
+otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
|
|
|
+{
|
|
|
+ esp_ieee802154_receive_at((aStart + aDuration));
|
|
|
+ return OT_ERROR_NONE;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
|
|
|
{
|
|
|
return esp_ieee802154_get_promiscuous();
|
|
|
@@ -295,7 +366,11 @@ bool otPlatRadioGetPromiscuous(otInstance *aInstance)
|
|
|
|
|
|
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
|
|
|
{
|
|
|
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
+ esp_ieee802154_set_pending_mode(ESP_IEEE802154_AUTO_PENDING_ENHANCED);
|
|
|
+#else
|
|
|
esp_ieee802154_set_pending_mode(ESP_IEEE802154_AUTO_PENDING_ENABLE);
|
|
|
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
}
|
|
|
|
|
|
otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
|
|
|
@@ -404,36 +479,212 @@ void otPlatDiagAlarmCallback(otInstance *aInstance)
|
|
|
OT_UNUSED_VARIABLE(aInstance);
|
|
|
}
|
|
|
|
|
|
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
+void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKeyId, const otMacKeyMaterial *aPrevKey,
|
|
|
+ const otMacKeyMaterial *aCurrKey, const otMacKeyMaterial *aNextKey, otRadioKeyType aKeyType)
|
|
|
+{
|
|
|
+ OT_UNUSED_VARIABLE(aInstance);
|
|
|
+ OT_UNUSED_VARIABLE(aKeyIdMode);
|
|
|
+ assert(aKeyType == OT_KEY_TYPE_LITERAL_KEY);
|
|
|
+ assert(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
|
|
|
+
|
|
|
+ s_key_id = aKeyId;
|
|
|
+ s_pervious_key = *aPrevKey;
|
|
|
+ s_current_key = *aCurrKey;
|
|
|
+ s_next_key = *aNextKey;
|
|
|
+}
|
|
|
+
|
|
|
+void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
|
|
|
+{
|
|
|
+ OT_UNUSED_VARIABLE(aInstance);
|
|
|
+
|
|
|
+ s_mac_frame_counter = aMacFrameCounter;
|
|
|
+}
|
|
|
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
+
|
|
|
+uint64_t otPlatRadioGetNow(otInstance *aInstance)
|
|
|
+{
|
|
|
+ OT_UNUSED_VARIABLE(aInstance);
|
|
|
+ return esp_timer_get_time();
|
|
|
+}
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime)
|
|
|
+{
|
|
|
+ OT_UNUSED_VARIABLE(aInstance);
|
|
|
+ s_csl_sample_time = aCslSampleTime;
|
|
|
+}
|
|
|
+
|
|
|
+static IRAM_ATTR uint16_t get_csl_phase()
|
|
|
+{
|
|
|
+ uint32_t cur_time = esp_timer_get_time();
|
|
|
+ uint32_t csl_period_us = s_csl_period * OT_US_PER_TEN_SYMBOLS;
|
|
|
+ uint32_t diff = (csl_period_us - (cur_time % csl_period_us) + (s_csl_sample_time % csl_period_us)) % csl_period_us;
|
|
|
+
|
|
|
+ return (uint16_t)(diff / OT_US_PER_TEN_SYMBOLS + 1);
|
|
|
+}
|
|
|
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+
|
|
|
+uint16_t otPlatTimeGetXtalAccuracy(void)
|
|
|
+{
|
|
|
+ return ESP_OPENTHREAD_XTAL_ACCURACY;
|
|
|
+}
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
|
|
+otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics aLinkMetrics,
|
|
|
+ const otShortAddress aShortAddress, const otExtAddress *aExtAddress)
|
|
|
+{
|
|
|
+ otError error = otLinkMetricsConfigureEnhAckProbing(aShortAddress, aExtAddress, aLinkMetrics);
|
|
|
+ return error;
|
|
|
+}
|
|
|
+#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShortAddress aShortAddr,
|
|
|
+ const otExtAddress *aExtAddr)
|
|
|
+{
|
|
|
+ OT_UNUSED_VARIABLE(aInstance);
|
|
|
+ OT_UNUSED_VARIABLE(aShortAddr);
|
|
|
+ OT_UNUSED_VARIABLE(aExtAddr);
|
|
|
+ s_csl_period = aCslPeriod;
|
|
|
+
|
|
|
+ return OT_ERROR_NONE;
|
|
|
+}
|
|
|
+
|
|
|
+uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
|
|
|
+{
|
|
|
+ return ESP_OPENTHREAD_CSL_ACCURACY;
|
|
|
+}
|
|
|
+
|
|
|
+uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance)
|
|
|
+{
|
|
|
+ return ESP_OPENTHREAD_CSL_UNCERTAIN;
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
// events
|
|
|
void IRAM_ATTR esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack,
|
|
|
- esp_ieee802154_frame_info_t *s_ack_frame_info)
|
|
|
+ esp_ieee802154_frame_info_t *ack_frame_info)
|
|
|
{
|
|
|
ETS_ASSERT(frame == (uint8_t *)&s_transmit_psdu);
|
|
|
|
|
|
if (ack != NULL) {
|
|
|
s_ack_frame.mLength = (uint16_t)(*ack);
|
|
|
s_ack_frame.mPsdu = (uint8_t *)(ack + 1);
|
|
|
+ s_ack_frame.mChannel = ack_frame_info->channel;
|
|
|
+ s_ack_frame.mInfo.mRxInfo.mRssi = ack_frame_info->rssi;
|
|
|
+ s_ack_frame.mInfo.mRxInfo.mTimestamp = ack_frame_info->timestamp;
|
|
|
}
|
|
|
|
|
|
set_event(EVENT_TX_DONE);
|
|
|
}
|
|
|
|
|
|
+static void IRAM_ATTR convert_to_ot_frame(uint8_t *data, esp_ieee802154_frame_info_t *frame_info,
|
|
|
+ otRadioFrame *radio_frame)
|
|
|
+{
|
|
|
+ radio_frame->mPsdu = data + 1;
|
|
|
+ radio_frame->mLength = *data;
|
|
|
+ radio_frame->mChannel = frame_info->channel;
|
|
|
+ radio_frame->mInfo.mRxInfo.mRssi = frame_info->rssi;
|
|
|
+ radio_frame->mInfo.mRxInfo.mAckedWithFramePending = frame_info->pending;
|
|
|
+ radio_frame->mInfo.mRxInfo.mTimestamp = esp_timer_get_time();
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+ radio_frame->mInfo.mRxInfo.mTimestamp = frame_info->timestamp;
|
|
|
+#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+}
|
|
|
+
|
|
|
+static void IRAM_ATTR enh_ack_set_security_addr_and_key(otRadioFrame *ack_frame)
|
|
|
+{
|
|
|
+ struct otMacKeyMaterial *key = NULL;
|
|
|
+ uint8_t key_id;
|
|
|
+
|
|
|
+ ETS_ASSERT(otMacFrameIsSecurityEnabled(ack_frame));
|
|
|
+ key_id = otMacFrameGetKeyId(ack_frame);
|
|
|
+ ETS_ASSERT(otMacFrameIsKeyIdMode1(ack_frame) && key_id != 0);
|
|
|
+
|
|
|
+ if (key_id == s_key_id) {
|
|
|
+ key = &s_current_key;
|
|
|
+ } else if (key_id == s_key_id - 1) {
|
|
|
+ key = &s_pervious_key;
|
|
|
+ } else if (key_id == s_key_id + 1) {
|
|
|
+ key = &s_next_key;
|
|
|
+ } else {
|
|
|
+ ETS_ASSERT(false);
|
|
|
+ }
|
|
|
+ s_ack_frame_counter = s_mac_frame_counter;
|
|
|
+ s_ack_key_id = key_id;
|
|
|
+ s_with_security_enh_ack = true;
|
|
|
+ if (otMacFrameIsKeyIdMode1(ack_frame)) {
|
|
|
+ esp_ieee802154_get_extended_address(s_security_addr);
|
|
|
+ memcpy(s_security_key, (*key).mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE);
|
|
|
+ }
|
|
|
+
|
|
|
+ esp_ieee802154_set_transmit_security(&ack_frame->mPsdu[-1], s_security_key, s_security_addr);
|
|
|
+}
|
|
|
+
|
|
|
+void IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info,
|
|
|
+ uint8_t *enhack_frame)
|
|
|
+{
|
|
|
+ otRadioFrame ack_frame;
|
|
|
+ otRadioFrame ot_frame;
|
|
|
+ uint8_t ack_ie_data[OT_ACK_IE_MAX_SIZE];
|
|
|
+ uint8_t offset = 0;
|
|
|
+#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
|
|
+ uint8_t link_metrics_data_len = 0;
|
|
|
+ uint8_t link_metrics_data[OT_ENH_PROBING_IE_DATA_MAX_SIZE];
|
|
|
+ otMacAddress mac_addr;
|
|
|
+#endif
|
|
|
+ ack_frame.mPsdu = enhack_frame + 1;
|
|
|
+ convert_to_ot_frame(frame, frame_info, &ot_frame);
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+ if (s_csl_period > 0) {
|
|
|
+ offset += otMacFrameGenerateCslIeTemplate(ack_ie_data);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
|
|
+ otMacFrameGetSrcAddr(&ot_frame, &mac_addr);
|
|
|
+ link_metrics_data_len = otLinkMetricsEnhAckGenData(&mac_addr, esp_ieee802154_get_recent_lqi(),
|
|
|
+ esp_ieee802154_get_recent_rssi(), link_metrics_data);
|
|
|
+ if (link_metrics_data_len > 0) {
|
|
|
+ offset += otMacFrameGenerateEnhAckProbingIe(ack_ie_data, link_metrics_data, link_metrics_data_len);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ ETS_ASSERT(otMacFrameGenerateEnhAck(&ot_frame, frame_info->pending, ack_ie_data, offset, &ack_frame) == OT_ERROR_NONE);
|
|
|
+ enhack_frame[0] = ack_frame.mLength;
|
|
|
+
|
|
|
+ s_enhack = enhack_frame;
|
|
|
+
|
|
|
+ if (otMacFrameIsSecurityEnabled(&ack_frame) && !ack_frame.mInfo.mTxInfo.mIsSecurityProcessed) {
|
|
|
+ otMacFrameSetFrameCounter(&ack_frame, s_mac_frame_counter++);
|
|
|
+ enh_ack_set_security_addr_and_key(&ack_frame);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void IRAM_ATTR esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info)
|
|
|
{
|
|
|
+ otRadioFrame ot_frame;
|
|
|
+ ot_frame.mPsdu = data + 1;
|
|
|
+
|
|
|
if (s_recv_queue.used == CONFIG_IEEE802154_RX_BUFFER_SIZE) {
|
|
|
ESP_EARLY_LOGE(OT_PLAT_LOG_TAG, "radio receive buffer full!");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- s_rssi = frame_info->rssi;
|
|
|
-
|
|
|
- s_receive_frame[s_recv_queue.tail].mPsdu = data + 1;
|
|
|
- s_receive_frame[s_recv_queue.tail].mLength = *data;
|
|
|
- s_receive_frame[s_recv_queue.tail].mChannel = frame_info->channel;
|
|
|
- s_receive_frame[s_recv_queue.tail].mInfo.mRxInfo.mRssi = frame_info->rssi;
|
|
|
- s_receive_frame[s_recv_queue.tail].mInfo.mRxInfo.mAckedWithFramePending = frame_info->pending;
|
|
|
- s_receive_frame[s_recv_queue.tail].mInfo.mRxInfo.mTimestamp = esp_timer_get_time();
|
|
|
-
|
|
|
+ convert_to_ot_frame(data, frame_info, &(s_receive_frame[s_recv_queue.tail]));
|
|
|
+#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
+ // Inform if this frame was acknowledged with secured Enh-ACK.
|
|
|
+ if (otMacFrameIsAckRequested(&ot_frame) && otMacFrameIsVersion2015(&ot_frame)) {
|
|
|
+ s_receive_frame[s_recv_queue.tail].mInfo.mRxInfo.mAckedWithSecEnhAck = s_with_security_enh_ack;
|
|
|
+ s_receive_frame[s_recv_queue.tail].mInfo.mRxInfo.mAckFrameCounter = s_ack_frame_counter;
|
|
|
+ s_receive_frame[s_recv_queue.tail].mInfo.mRxInfo.mAckKeyId = s_ack_key_id;
|
|
|
+ }
|
|
|
+ s_with_security_enh_ack = false;
|
|
|
+#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
s_recv_queue.tail = (s_recv_queue.tail + 1) % CONFIG_IEEE802154_RX_BUFFER_SIZE;
|
|
|
s_recv_queue.used++;
|
|
|
set_event(EVENT_RX_DONE);
|
|
|
@@ -454,6 +705,16 @@ void IRAM_ATTR esp_ieee802154_receive_sfd_done(void)
|
|
|
|
|
|
void IRAM_ATTR esp_ieee802154_transmit_sfd_done(uint8_t *frame)
|
|
|
{
|
|
|
+ assert(frame == (uint8_t *)&s_transmit_psdu || frame == s_enhack);
|
|
|
+#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
|
+ otRadioFrame ot_frame;
|
|
|
+ ot_frame.mPsdu = frame + 1;
|
|
|
+ ot_frame.mLength = frame[0];
|
|
|
+
|
|
|
+ if (s_csl_period > 0) {
|
|
|
+ otMacFrameSetCslIe(&ot_frame, s_csl_period, get_csl_phase());
|
|
|
+ }
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
void IRAM_ATTR esp_ieee802154_energy_detect_done(int8_t power)
|