2020-10-23 12:46:10 +02:00
/*
2021-01-25 15:05:07 +01:00
* Copyright ( c ) 2018 - 2021 , Nordic Semiconductor ASA
2020-01-10 12:01:54 +01:00
* All rights reserved .
*
2021-01-25 15:05:07 +01:00
* SPDX - License - Identifier : BSD - 3 - Clause
*
2020-01-10 12:01:54 +01:00
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
2020-10-23 12:46:10 +02:00
* 1. Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
2020-01-10 12:01:54 +01:00
*
2020-10-23 12:46:10 +02:00
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
2020-01-10 12:01:54 +01:00
*
2021-01-25 15:05:07 +01:00
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
2020-10-23 12:46:10 +02:00
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission .
2020-01-10 12:01:54 +01:00
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
2020-10-23 12:46:10 +02:00
* IMPLIED WARRANTIES OF MERCHANTABILITY , AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE .
2021-01-25 15:05:07 +01:00
*
2020-01-10 12:01:54 +01:00
*/
/**
* @ file
* This file implements procedures to set pending bit and 802.15 .4 - 2015 information
* elements in nRF 802.15 .4 radio driver .
*
*/
# include "nrf_802154_ack_data.h"
# include <assert.h>
# include <string.h>
# include "mac_features/nrf_802154_frame_parser.h"
# include "nrf_802154_config.h"
# include "nrf_802154_const.h"
/// Maximum number of Short Addresses of nodes for which there is ACK data to set.
# define NUM_SHORT_ADDRESSES NRF_802154_PENDING_SHORT_ADDRESSES
/// Maximum number of Extended Addresses of nodes for which there is ACK data to set.
# define NUM_EXTENDED_ADDRESSES NRF_802154_PENDING_EXTENDED_ADDRESSES
/// Structure representing pending bit setting variables.
typedef struct
{
bool enabled ; /// If setting pending bit is enabled.
uint8_t short_addr [ NUM_SHORT_ADDRESSES ] [ SHORT_ADDRESS_SIZE ] ; /// Array of short addresses of nodes for which there is pending data in the buffer.
uint8_t extended_addr [ NUM_EXTENDED_ADDRESSES ] [ EXTENDED_ADDRESS_SIZE ] ; /// Array of extended addresses of nodes for which there is pending data in the buffer.
uint32_t num_of_short_addr ; /// Current number of short addresses of nodes for which there is pending data in the buffer.
uint32_t num_of_ext_addr ; /// Current number of extended addresses of nodes for which there is pending data in the buffer.
} pending_bit_arrays_t ;
// Structure representing a single IE record.
typedef struct
{
uint8_t p_data [ NRF_802154_MAX_ACK_IE_SIZE ] ; /// Pointer to IE data buffer.
uint8_t len ; /// Length of the buffer.
} ie_data_t ;
// Structure representing IE records sent in an ACK message to a given short address.
typedef struct
{
uint8_t addr [ SHORT_ADDRESS_SIZE ] ; /// Short address of peer node.
ie_data_t ie_data ; /// Pointer to IE records.
} ack_short_ie_data_t ;
// Structure representing IE records sent in an ACK message to a given extended address.
typedef struct
{
uint8_t addr [ EXTENDED_ADDRESS_SIZE ] ; /// Extended address of peer node.
ie_data_t ie_data ; /// Pointer to IE records.
} ack_ext_ie_data_t ;
// Structure representing IE data setting variables.
typedef struct
{
ack_short_ie_data_t short_data [ NUM_SHORT_ADDRESSES ] ; /// Array of short addresses and IE records sent to these addresses.
ack_ext_ie_data_t ext_data [ NUM_EXTENDED_ADDRESSES ] ; /// Array of extended addresses and IE records sent to these addresses.
uint32_t num_of_short_data ; /// Current number of short addresses stored in @p short_data.
uint32_t num_of_ext_data ; /// Current number of extended addresses stored in @p ext_data.
} ie_arrays_t ;
// TODO: Combine below arrays to perform binary search only once per Ack generation.
static pending_bit_arrays_t m_pending_bit ;
static ie_arrays_t m_ie ;
static nrf_802154_src_addr_match_t m_src_matching_method ;
/***************************************************************************************************
* @ section Array handling helper functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ brief Compare two extended addresses .
*
* @ param [ in ] p_first_addr Pointer to a first address that should be compared .
* @ param [ in ] p_second_addr Pointer to a second address that should be compared .
*
* @ retval - 1 First address is less than the second address .
* @ retval 0 First address is equal to the second address .
* @ retval 1 First address is greater than the second address .
*/
static int8_t extended_addr_compare ( const uint8_t * p_first_addr , const uint8_t * p_second_addr )
{
uint32_t first_addr ;
uint32_t second_addr ;
// Compare extended address in two steps to prevent unaligned access error.
for ( uint32_t i = 0 ; i < EXTENDED_ADDRESS_SIZE / sizeof ( uint32_t ) ; i + + )
{
first_addr = * ( uint32_t * ) ( p_first_addr + ( i * sizeof ( uint32_t ) ) ) ;
second_addr = * ( uint32_t * ) ( p_second_addr + ( i * sizeof ( uint32_t ) ) ) ;
if ( first_addr < second_addr )
{
return - 1 ;
}
else if ( first_addr > second_addr )
{
return 1 ;
}
}
return 0 ;
}
/**
* @ brief Compare two short addresses .
*
* @ param [ in ] p_first_addr Pointer to a first address that should be compared .
* @ param [ in ] p_second_addr Pointer to a second address that should be compared .
*
* @ retval - 1 First address is less than the second address .
* @ retval 0 First address is equal to the second address .
* @ retval 1 First address is greater than the second address .
*/
static int8_t short_addr_compare ( const uint8_t * p_first_addr , const uint8_t * p_second_addr )
{
uint16_t first_addr = * ( uint16_t * ) ( p_first_addr ) ;
uint16_t second_addr = * ( uint16_t * ) ( p_second_addr ) ;
if ( first_addr < second_addr )
{
return - 1 ;
}
else if ( first_addr > second_addr )
{
return 1 ;
}
else
{
return 0 ;
}
}
/**
* @ brief Compare two addresses .
*
* @ param [ in ] p_first_addr Pointer to a first address that should be compared .
* @ param [ in ] p_second_addr Pointer to a second address that should be compared .
* @ param [ in ] extended Indication if @ p p_first_addr and @ p p_second_addr are extended or short addresses .
*
* @ retval - 1 First address is less than the second address .
* @ retval 0 First address is equal to the second address .
* @ retval 1 First address is greater than the second address .
*/
static int8_t addr_compare ( const uint8_t * p_first_addr ,
const uint8_t * p_second_addr ,
bool extended )
{
if ( extended )
{
return extended_addr_compare ( p_first_addr , p_second_addr ) ;
}
else
{
return short_addr_compare ( p_first_addr , p_second_addr ) ;
}
}
/**
* @ brief Perform a binary search for an address in a list of addresses .
*
* @ param [ in ] p_addr Pointer to an address that is searched for .
* @ param [ in ] p_addr_array Pointer to a list of addresses to be searched .
* @ param [ out ] p_location If the address @ p p_addr appears in the list , this is its index in the address list .
* Otherwise , it is the index which @ p p_addr would have if it was placed in the list
* ( ascending order assumed ) .
* @ param [ in ] extended Indication if @ p p_addr is an extended or a short addresses .
*
* @ retval true Address @ p p_addr is in the list .
* @ retval false Address @ p p_addr is not in the list .
*/
2020-10-23 12:46:10 +02:00
static bool addr_binary_search ( const uint8_t * p_addr ,
const uint8_t * p_addr_array ,
uint32_t * p_location ,
nrf_802154_ack_data_t data_type ,
bool extended )
2020-01-10 12:01:54 +01:00
{
uint32_t addr_array_len = 0 ;
uint8_t entry_size = 0 ;
switch ( data_type )
{
case NRF_802154_ACK_DATA_PENDING_BIT :
entry_size = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE ;
addr_array_len = extended ?
m_pending_bit . num_of_ext_addr : m_pending_bit . num_of_short_addr ;
break ;
case NRF_802154_ACK_DATA_IE :
entry_size = extended ? sizeof ( ack_ext_ie_data_t ) : sizeof ( ack_short_ie_data_t ) ;
addr_array_len = extended ? m_ie . num_of_ext_data : m_ie . num_of_short_data ;
break ;
default :
assert ( false ) ;
break ;
}
// The actual algorithm
int32_t low = 0 ;
uint32_t midpoint = 0 ;
int32_t high = addr_array_len ;
while ( high > = low )
{
midpoint = ( uint32_t ) ( low + ( high - low ) / 2 ) ;
if ( midpoint > = addr_array_len )
{
break ;
}
switch ( addr_compare ( p_addr , p_addr_array + entry_size * midpoint , extended ) )
{
case - 1 :
high = ( int32_t ) ( midpoint - 1 ) ;
break ;
case 0 :
* p_location = midpoint ;
return true ;
case 1 :
low = ( int32_t ) ( midpoint + 1 ) ;
break ;
default :
break ;
}
}
/* If in the last iteration of the loop the last case was utilized, it means that the midpoint
* found by the algorithm is less than the address to be added . The midpoint should be therefore
* shifted to the next position . As a simplified example , a { 1 , 3 , 4 } array can be considered .
* Suppose that a number equal to 2 is about to be added to the array . At the beginning of the
* last iteration , midpoint is equal to 1 and low and high are equal to 0. Midpoint is then set
* to 0 and with last case being utilized , low is set to 1. However , midpoint equal to 0 is
* incorrect , as in the last iteration first element of the array proves to be less than the
* element to be added to the array . With the below code , midpoint is then shifted to 1. */
if ( ( uint32_t ) low = = midpoint + 1 )
{
midpoint + + ;
}
* p_location = midpoint ;
return false ;
}
/**
* @ brief Find an address in a list of addresses .
*
* @ param [ in ] p_addr Pointer to an address that is searched for .
* @ param [ out ] p_location If the address @ p p_addr appears in the list , this is its index in the address list .
* Otherwise , it is the index which @ p p_addr would have if it was placed in the list
* ( ascending order assumed ) .
* @ param [ in ] extended Indication if @ p p_addr is an extended or a short addresses .
*
* @ retval true Address @ p p_addr is in the list .
* @ retval false Address @ p p_addr is not in the list .
*/
2020-10-23 12:46:10 +02:00
static bool addr_index_find ( const uint8_t * p_addr ,
uint32_t * p_location ,
nrf_802154_ack_data_t data_type ,
bool extended )
2020-01-10 12:01:54 +01:00
{
uint8_t * p_addr_array ;
bool valid_data_type = true ;
switch ( data_type )
{
case NRF_802154_ACK_DATA_PENDING_BIT :
p_addr_array = extended ? ( uint8_t * ) m_pending_bit . extended_addr :
( uint8_t * ) m_pending_bit . short_addr ;
break ;
case NRF_802154_ACK_DATA_IE :
p_addr_array = extended ? ( uint8_t * ) m_ie . ext_data : ( uint8_t * ) m_ie . short_data ;
break ;
default :
valid_data_type = false ;
assert ( false ) ;
break ;
}
if ( ! valid_data_type )
{
return false ;
}
return addr_binary_search ( p_addr , p_addr_array , p_location , data_type , extended ) ;
}
/**
* @ brief Thread implementation of the address matching algorithm .
*
* @ param [ in ] p_frame Pointer to the frame for which the ACK frame is being prepared .
*
* @ retval true Pending bit is to be set .
* @ retval false Pending bit is to be cleared .
*/
static bool addr_match_thread ( const uint8_t * p_frame )
{
bool extended ;
uint32_t location ;
const uint8_t * p_src_addr = nrf_802154_frame_parser_src_addr_get ( p_frame , & extended ) ;
// The pending bit is set by default.
if ( ! m_pending_bit . enabled | | ( NULL = = p_src_addr ) )
{
return true ;
}
return addr_index_find ( p_src_addr , & location , NRF_802154_ACK_DATA_PENDING_BIT , extended ) ;
}
/**
* @ brief Zigbee implementation of the address matching algorithm .
*
* @ param [ in ] p_frame Pointer to the frame for which the ACK frame is being prepared .
*
* @ retval true Pending bit is to be set .
* @ retval false Pending bit is to be cleared .
*/
static bool addr_match_zigbee ( const uint8_t * p_frame )
{
uint8_t frame_type ;
nrf_802154_frame_parser_mhr_data_t mhr_fields ;
uint32_t location ;
const uint8_t * p_cmd = p_frame ;
bool ret = false ;
// If ack data generator module is disabled do not perform check, return true by default.
if ( ! m_pending_bit . enabled )
{
return true ;
}
// Check the frame type.
frame_type = ( p_frame [ FRAME_TYPE_OFFSET ] & FRAME_TYPE_MASK ) ;
// Parse the MAC header and retrieve the command type.
if ( nrf_802154_frame_parser_mhr_parse ( p_frame , & mhr_fields ) )
{
// Note: Security header is not included in the offset.
// If security is to be used at any point, additional calculation
// in nrf_802154_frame_parser_mhr_parse needs to be implemented.
p_cmd + = mhr_fields . addressing_end_offset ;
}
else
{
// If invalid source or destination addressing mode is detected, assume unknown device.
// Command type cannot be checked, as addressing_end_offset value will be invalid.
return true ;
}
// Check frame type and command type.
if ( ( frame_type = = FRAME_TYPE_COMMAND ) & & ( * p_cmd = = MAC_CMD_DATA_REQ ) )
{
// Check addressing type - in long case address, pb should always be 1.
if ( mhr_fields . src_addr_size = = SHORT_ADDRESS_SIZE )
{
// Return true if address is not found on the m_pending_bits list.
ret = ! addr_index_find ( mhr_fields . p_src_addr ,
& location ,
NRF_802154_ACK_DATA_PENDING_BIT ,
false ) ;
}
else
{
ret = true ;
}
}
return ret ;
}
/**
* @ brief Standard - compliant implementation of the address matching algorithm .
*
* Function always returns true . It is IEEE 802.15 .4 compliant , as per 6.7 .3 .
* Higher layer should ensure empty data frame with no AR is sent afterwards .
*
* @ param [ in ] p_frame Pointer to the frame for which the ACK frame is being prepared .
*
* @ retval true Pending bit is to be set .
*/
static bool addr_match_standard_compliant ( const uint8_t * p_frame )
{
( void ) p_frame ;
return true ;
}
/**
* @ brief Add an address to the address list in ascending order .
*
* @ param [ in ] p_addr Pointer to the address to be added .
* @ param [ in ] location Index of the location where @ p p_addr should be added .
* @ param [ in ] extended Indication if @ p p_addr is an extended or a short addresses .
*
* @ retval true Address @ p p_addr has been added to the list successfully .
* @ retval false Address @ p p_addr could not be added to the list .
*/
2020-10-23 12:46:10 +02:00
static bool addr_add ( const uint8_t * p_addr ,
uint32_t location ,
nrf_802154_ack_data_t data_type ,
bool extended )
2020-01-10 12:01:54 +01:00
{
uint32_t * p_addr_array_len ;
uint32_t max_addr_array_len ;
uint8_t * p_addr_array ;
uint8_t entry_size ;
bool valid_data_type = true ;
switch ( data_type )
{
case NRF_802154_ACK_DATA_PENDING_BIT :
if ( extended )
{
p_addr_array = ( uint8_t * ) m_pending_bit . extended_addr ;
max_addr_array_len = NUM_EXTENDED_ADDRESSES ;
p_addr_array_len = & m_pending_bit . num_of_ext_addr ;
entry_size = EXTENDED_ADDRESS_SIZE ;
}
else
{
p_addr_array = ( uint8_t * ) m_pending_bit . short_addr ;
max_addr_array_len = NUM_SHORT_ADDRESSES ;
p_addr_array_len = & m_pending_bit . num_of_short_addr ;
entry_size = SHORT_ADDRESS_SIZE ;
}
break ;
case NRF_802154_ACK_DATA_IE :
if ( extended )
{
p_addr_array = ( uint8_t * ) m_ie . ext_data ;
max_addr_array_len = NUM_EXTENDED_ADDRESSES ;
p_addr_array_len = & m_ie . num_of_ext_data ;
entry_size = sizeof ( ack_ext_ie_data_t ) ;
}
else
{
p_addr_array = ( uint8_t * ) m_ie . short_data ;
max_addr_array_len = NUM_SHORT_ADDRESSES ;
p_addr_array_len = & m_ie . num_of_short_data ;
entry_size = sizeof ( ack_short_ie_data_t ) ;
}
break ;
default :
valid_data_type = false ;
assert ( false ) ;
break ;
}
if ( ! valid_data_type | | ( * p_addr_array_len = = max_addr_array_len ) )
{
return false ;
}
memmove ( p_addr_array + entry_size * ( location + 1 ) ,
p_addr_array + entry_size * ( location ) ,
( * p_addr_array_len - location ) * entry_size ) ;
memcpy ( p_addr_array + entry_size * location ,
p_addr ,
extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE ) ;
( * p_addr_array_len ) + + ;
return true ;
}
/**
* @ brief Remove an address from the address list keeping it in ascending order .
*
* @ param [ in ] location Index of the element to be removed from the list .
* @ param [ in ] extended Indication if address to remove is an extended or a short address .
*
* @ retval true Address @ p p_addr has been removed from the list successfully .
* @ retval false Address @ p p_addr could not removed from the list .
*/
2020-10-23 12:46:10 +02:00
static bool addr_remove ( uint32_t location , nrf_802154_ack_data_t data_type , bool extended )
2020-01-10 12:01:54 +01:00
{
uint32_t * p_addr_array_len ;
uint8_t * p_addr_array ;
uint8_t entry_size ;
bool valid_data_type = true ;
switch ( data_type )
{
case NRF_802154_ACK_DATA_PENDING_BIT :
if ( extended )
{
p_addr_array = ( uint8_t * ) m_pending_bit . extended_addr ;
p_addr_array_len = & m_pending_bit . num_of_ext_addr ;
entry_size = EXTENDED_ADDRESS_SIZE ;
}
else
{
p_addr_array = ( uint8_t * ) m_pending_bit . short_addr ;
p_addr_array_len = & m_pending_bit . num_of_short_addr ;
entry_size = SHORT_ADDRESS_SIZE ;
}
break ;
case NRF_802154_ACK_DATA_IE :
if ( extended )
{
p_addr_array = ( uint8_t * ) m_ie . ext_data ;
p_addr_array_len = & m_ie . num_of_ext_data ;
entry_size = sizeof ( ack_ext_ie_data_t ) ;
}
else
{
p_addr_array = ( uint8_t * ) m_ie . short_data ;
p_addr_array_len = & m_ie . num_of_short_data ;
entry_size = sizeof ( ack_short_ie_data_t ) ;
}
break ;
default :
valid_data_type = false ;
assert ( false ) ;
break ;
}
if ( ! valid_data_type | | ( * p_addr_array_len = = 0 ) )
{
return false ;
}
memmove ( p_addr_array + entry_size * location ,
p_addr_array + entry_size * ( location + 1 ) ,
( * p_addr_array_len - location - 1 ) * entry_size ) ;
( * p_addr_array_len ) - - ;
return true ;
}
static void ie_data_add ( uint32_t location , bool extended , const uint8_t * p_data , uint8_t data_len )
{
if ( extended )
{
memcpy ( m_ie . ext_data [ location ] . ie_data . p_data , p_data , data_len ) ;
m_ie . ext_data [ location ] . ie_data . len = data_len ;
}
else
{
memcpy ( m_ie . short_data [ location ] . ie_data . p_data , p_data , data_len ) ;
m_ie . short_data [ location ] . ie_data . len = data_len ;
}
}
/***************************************************************************************************
* @ section Public API
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void nrf_802154_ack_data_init ( void )
{
memset ( & m_pending_bit , 0 , sizeof ( m_pending_bit ) ) ;
memset ( & m_ie , 0 , sizeof ( m_ie ) ) ;
m_pending_bit . enabled = true ;
m_src_matching_method = NRF_802154_SRC_ADDR_MATCH_THREAD ;
}
void nrf_802154_ack_data_enable ( bool enabled )
{
m_pending_bit . enabled = enabled ;
}
2020-10-23 12:46:10 +02:00
bool nrf_802154_ack_data_for_addr_set ( const uint8_t * p_addr ,
bool extended ,
nrf_802154_ack_data_t data_type ,
const void * p_data ,
uint8_t data_len )
2020-01-10 12:01:54 +01:00
{
uint32_t location = 0 ;
if ( addr_index_find ( p_addr , & location , data_type , extended ) | |
addr_add ( p_addr , location , data_type , extended ) )
{
if ( data_type = = NRF_802154_ACK_DATA_IE )
{
ie_data_add ( location , extended , p_data , data_len ) ;
}
return true ;
}
else
{
return false ;
}
}
2020-10-23 12:46:10 +02:00
bool nrf_802154_ack_data_for_addr_clear ( const uint8_t * p_addr ,
bool extended ,
nrf_802154_ack_data_t data_type )
2020-01-10 12:01:54 +01:00
{
uint32_t location = 0 ;
if ( addr_index_find ( p_addr , & location , data_type , extended ) )
{
return addr_remove ( location , data_type , extended ) ;
}
else
{
return false ;
}
}
2020-10-23 12:46:10 +02:00
void nrf_802154_ack_data_reset ( bool extended , nrf_802154_ack_data_t data_type )
2020-01-10 12:01:54 +01:00
{
switch ( data_type )
{
case NRF_802154_ACK_DATA_PENDING_BIT :
if ( extended )
{
m_pending_bit . num_of_ext_addr = 0 ;
}
else
{
m_pending_bit . num_of_short_addr = 0 ;
}
break ;
case NRF_802154_ACK_DATA_IE :
if ( extended )
{
m_ie . num_of_ext_data = 0 ;
}
else
{
m_ie . num_of_short_data = 0 ;
}
break ;
default :
break ;
}
}
void nrf_802154_ack_data_src_addr_matching_method_set ( nrf_802154_src_addr_match_t match_method )
{
switch ( match_method )
{
case NRF_802154_SRC_ADDR_MATCH_THREAD :
case NRF_802154_SRC_ADDR_MATCH_ZIGBEE :
case NRF_802154_SRC_ADDR_MATCH_ALWAYS_1 :
m_src_matching_method = match_method ;
break ;
default :
assert ( false ) ;
}
}
bool nrf_802154_ack_data_pending_bit_should_be_set ( const uint8_t * p_frame )
{
2020-10-23 12:46:10 +02:00
bool ret ;
2020-01-10 12:01:54 +01:00
switch ( m_src_matching_method )
{
case NRF_802154_SRC_ADDR_MATCH_THREAD :
ret = addr_match_thread ( p_frame ) ;
break ;
case NRF_802154_SRC_ADDR_MATCH_ZIGBEE :
ret = addr_match_zigbee ( p_frame ) ;
break ;
case NRF_802154_SRC_ADDR_MATCH_ALWAYS_1 :
ret = addr_match_standard_compliant ( p_frame ) ;
break ;
default :
2020-10-23 12:46:10 +02:00
ret = false ;
2020-01-10 12:01:54 +01:00
assert ( false ) ;
}
return ret ;
}
const uint8_t * nrf_802154_ack_data_ie_get ( const uint8_t * p_src_addr ,
bool src_addr_extended ,
uint8_t * p_ie_length )
{
uint32_t location ;
if ( NULL = = p_src_addr )
{
return NULL ;
}
if ( addr_index_find ( p_src_addr , & location , NRF_802154_ACK_DATA_IE , src_addr_extended ) )
{
if ( src_addr_extended )
{
* p_ie_length = m_ie . ext_data [ location ] . ie_data . len ;
return m_ie . ext_data [ location ] . ie_data . p_data ;
}
else
{
* p_ie_length = m_ie . short_data [ location ] . ie_data . len ;
return m_ie . short_data [ location ] . ie_data . p_data ;
}
}
else
{
* p_ie_length = 0 ;
return NULL ;
}
}