net: openthread: add CSL transmitter API
This commit implements the OpenThread APIs to pass MAC keys and frame counter to the radio layer in order to process the transmission security. This is needed for the correct functioning of a CSL transmitter. Signed-off-by: Eduardo Montoya <eduardo.montoya@nordicsemi.no>
This commit is contained in:
parent
a4d2e062cb
commit
a47677da06
5 changed files with 181 additions and 3 deletions
|
@ -130,6 +130,11 @@ endif # IEEE802154_UPIPE_RANDOM_MAC
|
||||||
|
|
||||||
endif # IEEE802154_UPIPE
|
endif # IEEE802154_UPIPE
|
||||||
|
|
||||||
|
config IEEE802154_2015
|
||||||
|
bool "Enable support for IEEE 802.15.4-2015 frames"
|
||||||
|
help
|
||||||
|
Enable radio driver support for IEEE 802.15.4-2015 frames, including security handling of frames and ACKs.
|
||||||
|
|
||||||
module = IEEE802154_DRIVER
|
module = IEEE802154_DRIVER
|
||||||
module-str = IEEE 802.15.4 driver
|
module-str = IEEE 802.15.4 driver
|
||||||
module-help = Sets log level for IEEE 802.15.4 Device Drivers.
|
module-help = Sets log level for IEEE 802.15.4 Device Drivers.
|
||||||
|
|
|
@ -55,6 +55,7 @@ enum ieee802154_hw_caps {
|
||||||
IEEE802154_HW_ENERGY_SCAN = BIT(7), /* Energy scan supported */
|
IEEE802154_HW_ENERGY_SCAN = BIT(7), /* Energy scan supported */
|
||||||
IEEE802154_HW_TXTIME = BIT(8), /* TX at specified time supported */
|
IEEE802154_HW_TXTIME = BIT(8), /* TX at specified time supported */
|
||||||
IEEE802154_HW_SLEEP_TO_TX = BIT(9), /* TX directly from sleep supported */
|
IEEE802154_HW_SLEEP_TO_TX = BIT(9), /* TX directly from sleep supported */
|
||||||
|
IEEE802154_HW_TX_SEC = BIT(10), /* TX security hadling supported */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ieee802154_filter_type {
|
enum ieee802154_filter_type {
|
||||||
|
@ -150,7 +151,13 @@ enum ieee802154_config_type {
|
||||||
/** Specifies new radio event handler. Specifying NULL as a handler
|
/** Specifies new radio event handler. Specifying NULL as a handler
|
||||||
* will disable radio events notification.
|
* will disable radio events notification.
|
||||||
*/
|
*/
|
||||||
IEEE802154_CONFIG_EVENT_HANDLER
|
IEEE802154_CONFIG_EVENT_HANDLER,
|
||||||
|
|
||||||
|
/** Updates MAC keys and key index for radios supporting transmit security. */
|
||||||
|
IEEE802154_CONFIG_MAC_KEYS,
|
||||||
|
|
||||||
|
/** Sets the current MAC frame counter value for radios supporting transmit security. */
|
||||||
|
IEEE802154_CONFIG_FRAME_COUNTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** IEEE802.15.4 driver configuration data. */
|
/** IEEE802.15.4 driver configuration data. */
|
||||||
|
@ -178,6 +185,18 @@ struct ieee802154_config {
|
||||||
|
|
||||||
/** ``IEEE802154_CONFIG_EVENT_HANDLER`` */
|
/** ``IEEE802154_CONFIG_EVENT_HANDLER`` */
|
||||||
ieee802154_event_cb_t event_handler;
|
ieee802154_event_cb_t event_handler;
|
||||||
|
|
||||||
|
/** ``IEEE802154_CONFIG_MAC_KEYS`` */
|
||||||
|
struct {
|
||||||
|
uint8_t key_id_mode;
|
||||||
|
uint8_t key_id;
|
||||||
|
uint8_t *prev_key;
|
||||||
|
uint8_t *curr_key;
|
||||||
|
uint8_t *next_key;
|
||||||
|
} mac_keys;
|
||||||
|
|
||||||
|
/** ``IEEE802154_CONFIG_FRAME_COUNTER`` */
|
||||||
|
uint32_t frame_counter;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -244,7 +244,14 @@ struct net_pkt {
|
||||||
#if defined(CONFIG_IEEE802154)
|
#if defined(CONFIG_IEEE802154)
|
||||||
uint8_t ieee802154_rssi; /* Received Signal Strength Indication */
|
uint8_t ieee802154_rssi; /* Received Signal Strength Indication */
|
||||||
uint8_t ieee802154_lqi; /* Link Quality Indicator */
|
uint8_t ieee802154_lqi; /* Link Quality Indicator */
|
||||||
|
uint8_t ieee802154_arb : 1; /* ACK Request Bit is set in the frame */
|
||||||
uint8_t ieee802154_ack_fpb : 1; /* Frame Pending Bit was set in the ACK */
|
uint8_t ieee802154_ack_fpb : 1; /* Frame Pending Bit was set in the ACK */
|
||||||
|
#if defined(CONFIG_IEEE802154_2015)
|
||||||
|
uint8_t ieee802154_fv2015 : 1; /* Frame version is IEEE 802.15.4-2015 */
|
||||||
|
uint8_t ieee802154_ack_seb : 1; /* Security Enabled Bit was set in the ACK */
|
||||||
|
uint32_t ieee802154_ack_fc; /* Frame counter set in the ACK */
|
||||||
|
uint8_t ieee802154_ack_keyid; /* Key index set in the ACK */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_NET_L2_CANBUS)
|
#if defined(CONFIG_NET_L2_CANBUS)
|
||||||
union {
|
union {
|
||||||
|
@ -991,6 +998,16 @@ static inline void net_pkt_set_ieee802154_lqi(struct net_pkt *pkt,
|
||||||
pkt->ieee802154_lqi = lqi;
|
pkt->ieee802154_lqi = lqi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool net_pkt_ieee802154_arb(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
return pkt->ieee802154_arb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ieee802154_arb(struct net_pkt *pkt, bool arb)
|
||||||
|
{
|
||||||
|
pkt->ieee802154_arb = arb;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt)
|
static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
return pkt->ieee802154_ack_fpb;
|
return pkt->ieee802154_ack_fpb;
|
||||||
|
@ -1001,7 +1018,51 @@ static inline void net_pkt_set_ieee802154_ack_fpb(struct net_pkt *pkt,
|
||||||
{
|
{
|
||||||
pkt->ieee802154_ack_fpb = fpb;
|
pkt->ieee802154_ack_fpb = fpb;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#if defined(CONFIG_IEEE802154_2015)
|
||||||
|
static inline bool net_pkt_ieee802154_fv2015(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
return pkt->ieee802154_fv2015;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ieee802154_fv2015(struct net_pkt *pkt, bool fv2015)
|
||||||
|
{
|
||||||
|
pkt->ieee802154_fv2015 = fv2015;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool net_pkt_ieee802154_ack_seb(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
return pkt->ieee802154_ack_seb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ieee802154_ack_seb(struct net_pkt *pkt, bool seb)
|
||||||
|
{
|
||||||
|
pkt->ieee802154_ack_seb = seb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t net_pkt_ieee802154_ack_fc(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
return pkt->ieee802154_ack_fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ieee802154_ack_fc(struct net_pkt *pkt,
|
||||||
|
uint32_t fc)
|
||||||
|
{
|
||||||
|
pkt->ieee802154_ack_fc = fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t net_pkt_ieee802154_ack_keyid(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
return pkt->ieee802154_ack_keyid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ieee802154_ack_keyid(struct net_pkt *pkt,
|
||||||
|
uint8_t keyid)
|
||||||
|
{
|
||||||
|
pkt->ieee802154_ack_keyid = keyid;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE802154_2015 */
|
||||||
|
#endif /* CONFIG_IEEE802154 || CONFIG_IEEE802154_RAW_MODE */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV4_AUTO)
|
#if defined(CONFIG_NET_IPV4_AUTO)
|
||||||
static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt)
|
static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt)
|
||||||
|
|
|
@ -91,6 +91,37 @@
|
||||||
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
|
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE
|
||||||
|
*
|
||||||
|
* Define to 1 to enable software transmission target time logic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE
|
||||||
|
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE \
|
||||||
|
(OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
||||||
|
*
|
||||||
|
* Define as 1 to support IEEE 802.15.4-2015 Header IE (Information Element) generation and parsing,
|
||||||
|
* it must be set to support following features:
|
||||||
|
* 1. Time synchronization service feature (i.e., OPENTHREAD_CONFIG_TIME_SYNC_ENABLE is set).
|
||||||
|
* 2. Thread 1.2.
|
||||||
|
*
|
||||||
|
* @note If it's enabled, platform must support interrupt context and concurrent access AES.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
||||||
|
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || \
|
||||||
|
(OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||||
|
#define OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 1
|
||||||
|
#else
|
||||||
|
#define OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
* @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
||||||
*
|
*
|
||||||
|
|
|
@ -39,7 +39,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL);
|
||||||
#define SHORT_ADDRESS_SIZE 2
|
#define SHORT_ADDRESS_SIZE 2
|
||||||
|
|
||||||
#define FCS_SIZE 2
|
#define FCS_SIZE 2
|
||||||
|
#if defined(CONFIG_IEEE802154_2015)
|
||||||
|
#define ACK_PKT_LENGTH 127
|
||||||
|
#else
|
||||||
#define ACK_PKT_LENGTH 3
|
#define ACK_PKT_LENGTH 3
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FRAME_TYPE_MASK 0x07
|
#define FRAME_TYPE_MASK 0x07
|
||||||
#define FRAME_TYPE_ACK 0x02
|
#define FRAME_TYPE_ACK 0x02
|
||||||
|
@ -131,7 +135,7 @@ enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
|
||||||
|
|
||||||
size_t ack_len = net_pkt_get_len(pkt);
|
size_t ack_len = net_pkt_get_len(pkt);
|
||||||
|
|
||||||
if (ack_len != ACK_PKT_LENGTH) {
|
if (ack_len > ACK_PKT_LENGTH) {
|
||||||
return NET_CONTINUE;
|
return NET_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +332,17 @@ static void openthread_handle_received_frame(otInstance *instance,
|
||||||
time->second * USEC_PER_SEC + time->nanosecond / NSEC_PER_USEC;
|
time->second * USEC_PER_SEC + time->nanosecond / NSEC_PER_USEC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_IEEE802154_2015)
|
||||||
|
if (net_pkt_ieee802154_arb(pkt) && net_pkt_ieee802154_fv2015(pkt)) {
|
||||||
|
recv_frame.mInfo.mRxInfo.mAckedWithSecEnhAck =
|
||||||
|
net_pkt_ieee802154_ack_seb(pkt);
|
||||||
|
recv_frame.mInfo.mRxInfo.mAckFrameCounter =
|
||||||
|
net_pkt_ieee802154_ack_fc(pkt);
|
||||||
|
recv_frame.mInfo.mRxInfo.mAckKeyId =
|
||||||
|
net_pkt_ieee802154_ack_keyid(pkt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_OPENTHREAD_DIAG) && otPlatDiagModeGet()) {
|
if (IS_ENABLED(CONFIG_OPENTHREAD_DIAG) && otPlatDiagModeGet()) {
|
||||||
otPlatDiagRadioReceiveDone(instance, &recv_frame, OT_ERROR_NONE);
|
otPlatDiagRadioReceiveDone(instance, &recv_frame, OT_ERROR_NONE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -663,6 +678,18 @@ otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
|
||||||
caps |= OT_RADIO_CAPS_SLEEP_TO_TX;
|
caps |= OT_RADIO_CAPS_SLEEP_TO_TX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_IEEE802154_2015)
|
||||||
|
if (radio_caps & IEEE802154_HW_TX_SEC) {
|
||||||
|
caps |= OT_RADIO_CAPS_TRANSMIT_SEC;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_PKT_TXTIME)
|
||||||
|
if (radio_caps & IEEE802154_HW_TXTIME) {
|
||||||
|
caps |= OT_RADIO_CAPS_TRANSMIT_TIMING;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,9 +915,44 @@ otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
|
||||||
return OT_ERROR_NONE;
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_PKT_TXTIME)
|
||||||
uint64_t otPlatRadioGetNow(otInstance *aInstance)
|
uint64_t otPlatRadioGetNow(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(aInstance);
|
ARG_UNUSED(aInstance);
|
||||||
|
|
||||||
return radio_api->get_time(radio_dev);
|
return radio_api->get_time(radio_dev);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_IEEE802154_2015)
|
||||||
|
void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode,
|
||||||
|
uint8_t aKeyId, const otMacKey *aPrevKey,
|
||||||
|
const otMacKey *aCurrKey, const otMacKey *aNextKey)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(aInstance);
|
||||||
|
__ASSERT_NO_MSG(aPrevKey != NULL && aCurrKey != NULL &&
|
||||||
|
aNextKey != NULL);
|
||||||
|
|
||||||
|
struct ieee802154_config config = {
|
||||||
|
.mac_keys.key_id_mode = aKeyIdMode,
|
||||||
|
.mac_keys.key_id = aKeyId,
|
||||||
|
.mac_keys.prev_key = (uint8_t *)aPrevKey->m8,
|
||||||
|
.mac_keys.curr_key = (uint8_t *)aCurrKey->m8,
|
||||||
|
.mac_keys.next_key = (uint8_t *)aNextKey->m8,
|
||||||
|
};
|
||||||
|
|
||||||
|
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_MAC_KEYS,
|
||||||
|
&config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void otPlatRadioSetMacFrameCounter(otInstance *aInstance,
|
||||||
|
uint32_t aMacFrameCounter)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(aInstance);
|
||||||
|
|
||||||
|
struct ieee802154_config config = { .frame_counter = aMacFrameCounter };
|
||||||
|
|
||||||
|
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_FRAME_COUNTER,
|
||||||
|
&config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue