mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '7e1fb3c8420b4d7e43c740c3e779751c9eedb4fb'
* commit '7e1fb3c8420b4d7e43c740c3e779751c9eedb4fb': Squashed 'features/nanostack/sal-stack-nanostack/' changes from 82bbdcc..4a188eapull/7737/head
commit
edfeecdab8
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
#define CCMLIB_H_
|
#define CCMLIB_H_
|
||||||
|
|
||||||
#include "ns_types.h"
|
#include "ns_types.h"
|
||||||
|
#include "platform/arm_hal_aes.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -25,11 +26,11 @@
|
||||||
* \brief CCM Library API.
|
* \brief CCM Library API.
|
||||||
*
|
*
|
||||||
* \section ccm-api CCM Library API:
|
* \section ccm-api CCM Library API:
|
||||||
* - ccm_sec_init(), A function to init CCM library.
|
* - ccm_sec_init(), A function to init CCM context.
|
||||||
* - ccm_process_run(), A function to run configured CCM process.
|
* - ccm_process_run(), A function to run configured CCM process.
|
||||||
*
|
*
|
||||||
* \section ccm-instruction CCM process sequence:
|
* \section ccm-instruction CCM process sequence:
|
||||||
* 1. Init CCM library by, ccm key, ccm_sec_init()
|
* 1. Init CCM context by, ccm key, ccm_sec_init()
|
||||||
* - security level
|
* - security level
|
||||||
* - 128-bit CCM key
|
* - 128-bit CCM key
|
||||||
* - mode: AES_CCM_ENCRYPT or AES_CCM_DECRYPT
|
* - mode: AES_CCM_ENCRYPT or AES_CCM_DECRYPT
|
||||||
|
@ -41,11 +42,6 @@
|
||||||
* -If 0 Process ok
|
* -If 0 Process ok
|
||||||
* -< 0 MIC fail or parameter fail
|
* -< 0 MIC fail or parameter fail
|
||||||
*
|
*
|
||||||
* \section ccm-mutex CCM Mutex for Multi Thread System
|
|
||||||
* If you are running a multi thread system and the CCM library will be used for multiple thread, do the following:
|
|
||||||
* 1. Add compiler flag to library build process CCM_USE_MUTEX.
|
|
||||||
* 2. Define OS-specific mutex at the application.
|
|
||||||
* 3. Implement arm_ccm_mutex_lock() arm_ccm_mutex_unlock() function for using the generated and initialized mutex.
|
|
||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -63,41 +59,39 @@ extern "C" {
|
||||||
#define AES_CCM_DECRYPT 0x01 /**< Decryption mode */
|
#define AES_CCM_DECRYPT 0x01 /**< Decryption mode */
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief A function for locking CCM mutex if the OS is multi thread. If you are using single thread create an empty function.
|
|
||||||
*/
|
|
||||||
extern void arm_ccm_mutex_lock(void);
|
|
||||||
/**
|
|
||||||
* \brief A function for unlocking CCM mutex if the OS is multi thread. If you are using single thread create an empty function
|
|
||||||
*/
|
|
||||||
extern void arm_ccm_mutex_unlock(void);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \struct ccm_globals_t
|
* \struct ccm_globals_t
|
||||||
* \brief CCM global structure.
|
* \brief CCM global structure.
|
||||||
* The structure is used for configuring NONCE, adata and data before calling ccm_process_run().
|
* The structure is used for configuring NONCE, adata and data before calling ccm_process_run().
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t exp_nonce[15]; /**< CCM NONCE buffer Nonce. */
|
uint8_t exp_nonce[15]; /**< CCM NONCE buffer Nonce. */
|
||||||
uint8_t *data_ptr; /**< Pointer to data IN. */
|
uint8_t *data_ptr; /**< Pointer to data IN. */
|
||||||
uint16_t data_len; /**< Length of data IN. */
|
uint16_t data_len; /**< Length of data IN. */
|
||||||
const uint8_t *adata_ptr; /**< Pointer to authentication data. */
|
const uint8_t *adata_ptr; /**< Pointer to authentication data. */
|
||||||
uint16_t adata_len; /**< Length of authentication data. */
|
uint16_t adata_len; /**< Length of authentication data. */
|
||||||
uint8_t mic_len; /**< ccm_sec_init() sets here the length of MIC. */
|
unsigned ccm_encode_mode:1; /**< Encryption modeAES_CCM_ENCRYPT or AES_CCM_DECRYPT. */
|
||||||
uint8_t *mic; /**< Encrypt process writes MIC. Decrypt reads it and compares it with the MIC obtained from data. */
|
unsigned ccm_sec_level:3; /**< Encryption operation security level 0-7. */
|
||||||
|
unsigned ccm_l_param:4; /**< Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12*/
|
||||||
|
uint8_t mic_len; /**< ccm_sec_init() sets here the length of MIC. */
|
||||||
|
uint8_t *mic; /**< Encrypt process writes MIC. Decrypt reads it and compares it with the MIC obtained from data. */
|
||||||
|
const uint8_t *key_ptr; /**< Encyption key pointer to 128-bit key. */
|
||||||
|
arm_aes_context_t *aes_context; /**< Allocated AES context. */
|
||||||
} ccm_globals_t;
|
} ccm_globals_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A function to initialize the CCM library.
|
* \brief A function to initialize the CCM context.
|
||||||
|
* \param ccm_context pointer to initialized XXM context
|
||||||
* \param sec_level Used CCM security level (0-7).
|
* \param sec_level Used CCM security level (0-7).
|
||||||
* \param ccm_key Pointer to 128-key.
|
* \param ccm_key Pointer to 128-key.
|
||||||
* \param mode AES_CCM_ENCRYPT or AES_CCM_DECRYPT.
|
* \param mode AES_CCM_ENCRYPT or AES_CCM_DECRYPT.
|
||||||
* \param ccm_l Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12. (NONCE length = (15-ccm_l))
|
* \param ccm_l Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12. (NONCE length = (15-ccm_l))
|
||||||
*
|
*
|
||||||
* \return Pointer to Global CCM parameter buffer.
|
* \return true when AES context allocation is OK and given parameters.
|
||||||
* \return 0 When parameter fails or CCM is busy.
|
* \return false CCM parameters or AES context allocation fail.
|
||||||
*/
|
*/
|
||||||
extern ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l);
|
extern bool ccm_sec_init(ccm_globals_t *ccm_context, uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A function to run the configured CCM process.
|
* \brief A function to run the configured CCM process.
|
||||||
|
@ -109,6 +103,14 @@ extern ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, ui
|
||||||
* \return -2 Null pointer given to function.
|
* \return -2 Null pointer given to function.
|
||||||
*/
|
*/
|
||||||
extern int8_t ccm_process_run(ccm_globals_t *ccm_params);
|
extern int8_t ccm_process_run(ccm_globals_t *ccm_params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief A function to free aes context. Call only if ccm_process_run() is not called
|
||||||
|
* \param ccm_params CCM parameters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
extern void ccm_free(ccm_globals_t *ccm_params);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -74,17 +74,16 @@ typedef bool fhss_use_broadcast_queue(const fhss_api_t *api, bool is_broadcast_a
|
||||||
* @param is_broadcast_addr Destination address type of packet (true if broadcast address).
|
* @param is_broadcast_addr Destination address type of packet (true if broadcast address).
|
||||||
* @param destination_address Destination MAC address.
|
* @param destination_address Destination MAC address.
|
||||||
* @param frame_type Frame type of packet (Frames types are defined by FHSS api).
|
* @param frame_type Frame type of packet (Frames types are defined by FHSS api).
|
||||||
* @param synch_info Pointer to where FHSS synchronization info is written (if synch frame).
|
|
||||||
* @param frame_length MSDU length of the frame.
|
* @param frame_length MSDU length of the frame.
|
||||||
* @param phy_header_length PHY header length.
|
* @param phy_header_length PHY header length.
|
||||||
* @param phy_tail_length PHY tail length.
|
* @param phy_tail_length PHY tail length.
|
||||||
|
* @param tx_time TX time.
|
||||||
* @return 0 Success.
|
* @return 0 Success.
|
||||||
* @return -1 Transmission of the packet is currently not allowed, try again.
|
* @return -1 Transmission of the packet is currently not allowed, try again.
|
||||||
* @return -2 Invalid api.
|
* @return -2 Invalid api.
|
||||||
* @return -3 Broadcast packet on Unicast channel (not allowed), push packet back to queue.
|
* @return -3 Broadcast packet on Unicast channel (not allowed), push packet back to queue.
|
||||||
* @return -4 Synchronization info missing.
|
|
||||||
*/
|
*/
|
||||||
typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint8_t *synch_info, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length);
|
typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check TX permission.
|
* @brief Check TX permission.
|
||||||
|
@ -152,6 +151,17 @@ typedef uint32_t fhss_read_timestamp(const fhss_api_t *api);
|
||||||
*/
|
*/
|
||||||
typedef uint16_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu);
|
typedef uint16_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write synchronization info to given pointer.
|
||||||
|
* @param api FHSS instance.
|
||||||
|
* @param ptr Pointer to data. Start of written data for Synch frame. Start of IE header for Data frame.
|
||||||
|
* @param length Length of IE header. Ignored when Synch frame.
|
||||||
|
* @param frame_type Frame type of packet (Frames types are defined by FHSS api).
|
||||||
|
* @param tx_time TX time must be referenced to the first symbol following the SFD of the transmitted frame.
|
||||||
|
* @return -1 on fail, write length otherwise.
|
||||||
|
*/
|
||||||
|
typedef int16_t fhss_write_synch_info(const fhss_api_t *api, uint8_t *ptr, uint8_t length, int frame_type, uint32_t tx_time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize MAC functions.
|
* @brief Initialize MAC functions.
|
||||||
* @param api FHSS instance.
|
* @param api FHSS instance.
|
||||||
|
@ -177,6 +187,7 @@ struct fhss_api {
|
||||||
fhss_synch_state_set *synch_state_set; /**< Change synchronization state. */
|
fhss_synch_state_set *synch_state_set; /**< Change synchronization state. */
|
||||||
fhss_read_timestamp *read_timestamp; /**< Read timestamp. */
|
fhss_read_timestamp *read_timestamp; /**< Read timestamp. */
|
||||||
fhss_get_retry_period *get_retry_period; /**< Get retransmission period. */
|
fhss_get_retry_period *get_retry_period; /**< Get retransmission period. */
|
||||||
|
fhss_write_synch_info *write_synch_info; /**< Write synchronization info to TX frame*/
|
||||||
fhss_init_callbacks *init_callbacks; /**< Initialize MAC functions. */
|
fhss_init_callbacks *init_callbacks; /**< Initialize MAC functions. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -256,6 +267,18 @@ typedef int mac_broadcast_notify(const fhss_api_t *fhss_api, uint32_t broadcast_
|
||||||
*/
|
*/
|
||||||
typedef int mac_read_coordinator_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address);
|
typedef int mac_read_coordinator_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read synchronization info for a specific peer.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @param info_ptr Pointer to info data.
|
||||||
|
* @param mac_address MAC address pointer.
|
||||||
|
* @param info_type Type of the read info (UTT-IE, BT-IE, US-IE, BS-IE).
|
||||||
|
* @param rx_timestamp Time of reception of the element.
|
||||||
|
* @return >=0 Length of the info.
|
||||||
|
* @return -1 Fail.
|
||||||
|
*/
|
||||||
|
typedef int mac_read_synch_info(const fhss_api_t *fhss_api, uint8_t *info_ptr, uint8_t *mac_address, int info_type, uint32_t rx_timestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Struct fhss_callback defines functions that software MAC needs to implement.
|
* \brief Struct fhss_callback defines functions that software MAC needs to implement.
|
||||||
* Function pointers are passed to FHSS using fhss_init_callbacks function.
|
* Function pointers are passed to FHSS using fhss_init_callbacks function.
|
||||||
|
@ -270,6 +293,7 @@ struct fhss_callback {
|
||||||
mac_tx_poll *tx_poll; /**< Poll TX queue. */
|
mac_tx_poll *tx_poll; /**< Poll TX queue. */
|
||||||
mac_broadcast_notify *broadcast_notify; /**< Broadcast channel notification from FHSS. */
|
mac_broadcast_notify *broadcast_notify; /**< Broadcast channel notification from FHSS. */
|
||||||
mac_read_coordinator_mac_address *read_coord_mac_address; /**< Read coordinator MAC address. */
|
mac_read_coordinator_mac_address *read_coord_mac_address; /**< Read coordinator MAC address. */
|
||||||
|
mac_read_synch_info *read_synch_info; /**< Read information element for a specific MAC address. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -28,6 +28,23 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "fhss_ws_extension.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief WS channel functions.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/** Fixed channel. */
|
||||||
|
WS_FIXED_CHANNEL,
|
||||||
|
/** TR51 channel function. */
|
||||||
|
WS_TR51CF,
|
||||||
|
/** Direct Hash channel function. */
|
||||||
|
WS_DH1CF,
|
||||||
|
/** Vendor Defined channel function. */
|
||||||
|
WS_VENDOR_DEF_CF
|
||||||
|
} fhss_ws_channel_functions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Struct fhss_tuning_parameter defines FHSS tuning parameters.
|
* \brief Struct fhss_tuning_parameter defines FHSS tuning parameters.
|
||||||
* All delays are given in microseconds.
|
* All delays are given in microseconds.
|
||||||
|
@ -63,20 +80,59 @@ typedef struct fhss_configuration
|
||||||
|
|
||||||
} fhss_configuration_t;
|
} fhss_configuration_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get channel using vendor defined channel function.
|
||||||
|
* @param api FHSS instance.
|
||||||
|
* @param slot Slot number in channel schedule.
|
||||||
|
* @param eui64 EUI-64 address of node for which the (unicast) schedule is calculated. NULL for broadcast schedule.
|
||||||
|
* @param bsi Broadcast schedule identifier used in (broadcast) schedule calculation.
|
||||||
|
* @param number_of_channels Number of channels in schedule.
|
||||||
|
* @return Channel.
|
||||||
|
*/
|
||||||
|
typedef int32_t fhss_vendor_defined_cf(const fhss_api_t *api, uint16_t slot, uint8_t eui64[8], uint16_t bsi, uint16_t number_of_channels);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Struct fhss_ws_configuration defines configuration of WS FHSS.
|
||||||
|
*/
|
||||||
|
typedef struct fhss_ws_configuration
|
||||||
|
{
|
||||||
|
/** WS channel function. */
|
||||||
|
fhss_ws_channel_functions ws_channel_function;
|
||||||
|
|
||||||
|
/** Broadcast schedule identifier. */
|
||||||
|
uint16_t bsi;
|
||||||
|
|
||||||
|
/** Unicast dwell interval. Range: 15-250 milliseconds. */
|
||||||
|
uint8_t fhss_uc_dwell_interval;
|
||||||
|
|
||||||
|
/** Broadcast interval. Duration between broadcast dwell intervals. Range: 0-16777216 milliseconds. */
|
||||||
|
uint32_t fhss_broadcast_interval;
|
||||||
|
|
||||||
|
/** Broadcast dwell interval. Range: 15-250 milliseconds. */
|
||||||
|
uint8_t fhss_bc_dwell_interval;
|
||||||
|
|
||||||
|
/** Channel mask. */
|
||||||
|
uint32_t channel_mask[8];
|
||||||
|
|
||||||
|
/** Vendor defined channel function. */
|
||||||
|
fhss_vendor_defined_cf *vendor_defined_cf;
|
||||||
|
|
||||||
|
} fhss_ws_configuration_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Struct fhss_timer defines interface between FHSS and FHSS platform timer.
|
* \brief Struct fhss_timer defines interface between FHSS and FHSS platform timer.
|
||||||
* Application must implement FHSS timer driver which is then used by FHSS with this interface.
|
* Application must implement FHSS timer driver which is then used by FHSS with this interface.
|
||||||
*/
|
*/
|
||||||
typedef struct fhss_timer
|
typedef struct fhss_timer
|
||||||
{
|
{
|
||||||
/** Start timeout (1us) */
|
/** Start timeout (1us). Timer must support multiple simultaneous timeouts */
|
||||||
int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
|
int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
|
||||||
|
|
||||||
/** Stop timeout */
|
/** Stop timeout */
|
||||||
int (*fhss_timer_stop)(const fhss_api_t *fhss_api);
|
int (*fhss_timer_stop)(void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
|
||||||
|
|
||||||
/** Get remaining time of started timeout*/
|
/** Get remaining time of started timeout*/
|
||||||
uint32_t (*fhss_get_remaining_slots)(const fhss_api_t *fhss_api);
|
uint32_t (*fhss_get_remaining_slots)(void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
|
||||||
|
|
||||||
/** Get timestamp since initialization of driver. Overflow of 32-bit counter is allowed (1us) */
|
/** Get timestamp since initialization of driver. Overflow of 32-bit counter is allowed (1us) */
|
||||||
uint32_t (*fhss_get_timestamp)(const fhss_api_t *fhss_api);
|
uint32_t (*fhss_get_timestamp)(const fhss_api_t *fhss_api);
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file fhss_ws_extension.h
|
||||||
|
* \brief
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FHSS_WS_EXT_H
|
||||||
|
#define FHSS_WS_EXT_H
|
||||||
|
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "fhss_api.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief unicast_timing_info Unicast timing/hopping schedule information structure.
|
||||||
|
*/
|
||||||
|
typedef struct unicast_timing_info {
|
||||||
|
unsigned unicast_channel_function:3; /**< Unicast schedule channel function */
|
||||||
|
uint8_t unicast_dwell_interval; /**< Unicast dwell interval */
|
||||||
|
uint16_t unicast_number_of_channels; /**< Unicast number of channels */
|
||||||
|
uint_fast24_t ufsi; /**< Unicast fractional sequence interval */
|
||||||
|
uint32_t utt_rx_timestamp; /**< UTT-IE reception timestamp */
|
||||||
|
} unicast_timing_info_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief broadcast_timing_info Broadcast timing/hopping schedule information structure.
|
||||||
|
*/
|
||||||
|
typedef struct broadcast_timing_info {
|
||||||
|
unsigned broadcast_channel_function:3; /**< Broadcast schedule channel function */
|
||||||
|
uint8_t broadcast_dwell_interval; /**< Broadcast dwell interval */
|
||||||
|
uint16_t broadcast_slot; /**< Broadcast slot number */
|
||||||
|
uint16_t broadcast_schedule_id; /**< Broadcast schedule identifier */
|
||||||
|
uint_fast24_t broadcast_interval_offset; /**< Broadcast interval offset */
|
||||||
|
uint32_t broadcast_interval; /**< Broadcast interval */
|
||||||
|
uint32_t bt_rx_timestamp; /**< BT-IE reception timestamp */
|
||||||
|
} broadcast_timing_info_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fhss_ws_neighbor_timing_info Neighbor timing/hopping schedule information structure.
|
||||||
|
*/
|
||||||
|
typedef struct fhss_ws_neighbor_timing_info {
|
||||||
|
uint8_t clock_drift; /**< Neighbor clock drift */
|
||||||
|
uint8_t timing_accuracy; /**< Neighbor timing accuracy */
|
||||||
|
unicast_timing_info_t uc_timing_info; /**< Neighbor unicast timing info */
|
||||||
|
broadcast_timing_info_t bc_timing_info; /**< Neighbor broadcast timing info */
|
||||||
|
uint32_t *excluded_channels; /**< Neighbor excluded channels (bit mask) */
|
||||||
|
} fhss_ws_neighbor_timing_info_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get neighbor timing/hopping schedule.
|
||||||
|
* @param api FHSS instance.
|
||||||
|
* @param eui64 EUI-64 address of node for which the info is requested.
|
||||||
|
* @return Neighbor timing/hopping schedule.
|
||||||
|
*/
|
||||||
|
typedef fhss_ws_neighbor_timing_info_t *fhss_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set parent which broadcast channels must be listened by FHSS.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @param eui64 EUI-64 address of parent.
|
||||||
|
* @param bc_timing_info Pointer to parent broadcast timing/hopping schedule info.
|
||||||
|
* @return 0 on success, -1 on fail.
|
||||||
|
*/
|
||||||
|
extern int ns_fhss_ws_set_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove parent which was set by ns_fhss_ws_set_parent function.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @param eui64 EUI-64 address of parent.
|
||||||
|
* @return 0 on success, -1 on fail.
|
||||||
|
*/
|
||||||
|
extern int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set neighbor timing/hopping schedule request function.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @param get_neighbor_info Neighbor info function pointer.
|
||||||
|
* @return 0 on success, -1 on fail.
|
||||||
|
*/
|
||||||
|
extern int ns_fhss_set_neighbor_info_fp(const fhss_api_t *fhss_api, fhss_get_neighbor_info *get_neighbor_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set node hop count. Hop count is used to specify TX/RX slot. When hop count is set to 0xFF, TX/RX slots are ignored.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @param hop_count Hop count to be set.
|
||||||
|
* @return 0 on success, -1 on fail.
|
||||||
|
*/
|
||||||
|
extern int ns_fhss_ws_set_hop_count(const fhss_api_t *fhss_api, const uint8_t hop_count);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // FHSS_WS_EXT_H
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -32,6 +32,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct channel_list_s;
|
||||||
|
|
||||||
typedef struct mac_api_s mac_api_t;
|
typedef struct mac_api_s mac_api_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,6 +122,17 @@ typedef void mlme_request(const mac_api_t* api, mlme_primitive id, const void *d
|
||||||
*/
|
*/
|
||||||
typedef void mcps_data_request(const mac_api_t* api, const mcps_data_req_t *data);
|
typedef void mcps_data_request(const mac_api_t* api, const mcps_data_req_t *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mcps_request MCPS_DATA with IE extions request call
|
||||||
|
* @param api API to handle the request
|
||||||
|
* @param data MCPS-DATA.request specific values
|
||||||
|
* @param ie_ext Information element list to MCPS-DATA.request
|
||||||
|
* @param asynch_channel_list Optional channel list to asynch data request. Give NULL when normal data request.
|
||||||
|
*
|
||||||
|
* Asynch data request is mac standard extension. asynch_channel_list include channel mask which channel message is requested to send.
|
||||||
|
*/
|
||||||
|
typedef void mcps_data_request_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const struct channel_list_s *asynch_channel_list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief mcps_purge_request MCPS_PURGE request call
|
* @brief mcps_purge_request MCPS_PURGE request call
|
||||||
* @param api API to handle the request
|
* @param api API to handle the request
|
||||||
|
@ -136,6 +149,14 @@ typedef void mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data);
|
||||||
*/
|
*/
|
||||||
typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *data);
|
typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mcps_data_confirm_ext MCPS-DATA confirm with Enhanced ACK payload is called as a response to MCPS-DATA request
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param data MCPS-DATA.confirm specific values
|
||||||
|
* @param conf_data Possible Confirmation Data
|
||||||
|
*/
|
||||||
|
typedef void mcps_data_confirm_ext(const mac_api_t* api, const mcps_data_conf_t *data, const mcps_data_conf_payload_t *conf_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data
|
* @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data
|
||||||
* @param api The API which handled the response
|
* @param api The API which handled the response
|
||||||
|
@ -143,6 +164,24 @@ typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *dat
|
||||||
*/
|
*/
|
||||||
typedef void mcps_data_indication(const mac_api_t* api, const mcps_data_ind_t *data);
|
typedef void mcps_data_indication(const mac_api_t* api, const mcps_data_ind_t *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param data MCPS-DATA.indication specific values
|
||||||
|
* @param ie_ext Information element list
|
||||||
|
*/
|
||||||
|
typedef void mcps_data_indication_ext(const mac_api_t* api, const mcps_data_ind_t *data, const mcps_data_ie_list_t *ie_ext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mcps_ack_data_req_ext Callback for request IE elements and payload to enhanced ACK
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param data Pointer where MAC user set Payload and IE element pointers and length
|
||||||
|
* @param rssi Signal strength for received packet
|
||||||
|
* @param lqi Link quality to neighbor
|
||||||
|
*/
|
||||||
|
typedef void mcps_ack_data_req_ext(const mac_api_t* api, mcps_ack_data_payload_t *data, int8_t rssi, uint8_t lqi);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief mcps_purge_confirm MCPS-PURGE confirm is called as a response to MCPS-PURGE request
|
* @brief mcps_purge_confirm MCPS-PURGE confirm is called as a response to MCPS-PURGE request
|
||||||
* @param api The API which handled the request
|
* @param api The API which handled the request
|
||||||
|
@ -201,6 +240,19 @@ typedef int8_t mac_api_initialize(mac_api_t *api, mcps_data_confirm *data_conf_c
|
||||||
mcps_data_indication *data_ind_cb, mcps_purge_confirm *purge_conf_cb, mlme_confirm *mlme_conf_cb,
|
mcps_data_indication *data_ind_cb, mcps_purge_confirm *purge_conf_cb, mlme_confirm *mlme_conf_cb,
|
||||||
mlme_indication *mlme_ind_cb, int8_t parent_id);
|
mlme_indication *mlme_ind_cb, int8_t parent_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mac_api_enable_mcps_ext Initialises MAC 2015 extension for MCPS layer into use, callbacks must be non-NULL.
|
||||||
|
* @param api mac_api_t pointer, which is created by application.
|
||||||
|
* @param data_ind_cb Upper layer function to handle MCPS indications
|
||||||
|
* @param data_cnf_cb Upper layer function to handle MCPS confirmation
|
||||||
|
* @param ack_data_req_cb Upper layer function for set Enhanced ACK payload
|
||||||
|
* @return -1 if error, -2 if OOM, 0 otherwise
|
||||||
|
*/
|
||||||
|
typedef int8_t mac_api_enable_mcps_ext(mac_api_t *api,
|
||||||
|
mcps_data_indication_ext *data_ind_cb,
|
||||||
|
mcps_data_confirm_ext *data_cnf_cb,
|
||||||
|
mcps_ack_data_req_ext *ack_data_req_cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Struct mac_api_s defines functions for two-way communications between external MAC and Upper layer.
|
* \brief Struct mac_api_s defines functions for two-way communications between external MAC and Upper layer.
|
||||||
* Application creates mac_api_t object by calling external MAC's creator function.
|
* Application creates mac_api_t object by calling external MAC's creator function.
|
||||||
|
@ -209,14 +261,19 @@ typedef int8_t mac_api_initialize(mac_api_t *api, mcps_data_confirm *data_conf_c
|
||||||
*/
|
*/
|
||||||
struct mac_api_s {
|
struct mac_api_s {
|
||||||
mac_api_initialize *mac_initialize; /**< MAC initialize function to use */
|
mac_api_initialize *mac_initialize; /**< MAC initialize function to use */
|
||||||
|
mac_api_enable_mcps_ext *mac_mcps_extension_enable; /**< MAC MCPS IE extension enable function, optional feature */
|
||||||
//External MAC callbacks
|
//External MAC callbacks
|
||||||
mlme_request *mlme_req; /**< MAC MLME request function to use */
|
mlme_request *mlme_req; /**< MAC MLME request function to use */
|
||||||
mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */
|
mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */
|
||||||
|
mcps_data_request_ext *mcps_data_req_ext; /**< MAC MCPS data request with Information element extension function to use */
|
||||||
mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */
|
mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */
|
||||||
|
|
||||||
//Upper layer callbacksMLME_ASSOCIATE
|
//Upper layer callbacksMLME_ASSOCIATE
|
||||||
mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */
|
mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */
|
||||||
|
mcps_data_confirm_ext *data_conf_ext_cb; /**< MAC MCPS data confirm with payload callback function */
|
||||||
mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */
|
mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */
|
||||||
|
mcps_data_indication_ext *data_ind_ext_cb; /**< MAC MCPS data indication with IE extension's callback function */
|
||||||
|
mcps_ack_data_req_ext *enhanced_ack_data_req_cb; /**< Enhanced ACK IE element and payload request from MAC user */
|
||||||
mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */
|
mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */
|
||||||
mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */
|
mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */
|
||||||
mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */
|
mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#define MAC_FRAME_VERSION_2003 0 /**< FCF - IEEE 802.15.4-2003 compatible */
|
#define MAC_FRAME_VERSION_2003 0 /**< FCF - IEEE 802.15.4-2003 compatible */
|
||||||
#define MAC_FRAME_VERSION_2006 1 /**< FCF - IEEE 802.15.4-2006 (big payload or new security) */
|
#define MAC_FRAME_VERSION_2006 1 /**< FCF - IEEE 802.15.4-2006 (big payload or new security) */
|
||||||
|
#define MAC_FRAME_VERSION_2015 2 /**< FCF - IEEE 802.15.4-2015 (IE element support) */
|
||||||
|
|
||||||
//See IEEE standard 802.15.4-2006 (table 96) for more details about identifiers
|
//See IEEE standard 802.15.4-2006 (table 96) for more details about identifiers
|
||||||
#define MAC_KEY_ID_MODE_IMPLICIT 0 /**< Key identifier mode implicit */
|
#define MAC_KEY_ID_MODE_IMPLICIT 0 /**< Key identifier mode implicit */
|
||||||
|
@ -66,4 +67,36 @@ typedef struct mlme_security_s {
|
||||||
uint8_t Keysource[8]; /**< Key source */
|
uint8_t Keysource[8]; /**< Key source */
|
||||||
} mlme_security_t;
|
} mlme_security_t;
|
||||||
|
|
||||||
|
#define MAC_HEADER_VENDOR_SPESIFIC_IE_ID 0x00 /**< Vendor specific Header IE element */
|
||||||
|
#define MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID 0x2a /**< External organisation defined Header IE element */
|
||||||
|
#define MAC_HEADER_TERMINATION1_IE_ID 0x7e /**< Header IE element termination when Payload element is following Header IE */
|
||||||
|
#define MAC_HEADER_TERMINATION2_IE_ID 0x7f /**< Header IE element termination when no Payload element is following Header IE but normal payload is */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mac_header_IE_t Mac Header information element structure for parsing or write operation
|
||||||
|
* This structure encapsulates security related variables,
|
||||||
|
*/
|
||||||
|
typedef struct mac_header_IE_s {
|
||||||
|
uint8_t *content_ptr; /**< Content data */
|
||||||
|
unsigned length:7; /**< Element length 0- 127 */
|
||||||
|
uint8_t id; /**< Element ID */
|
||||||
|
} mac_header_IE_t;
|
||||||
|
|
||||||
|
#define MAC_PAYLOAD_IE_ESDU_GROUP_ID 0x00 /**< Encapsulated Service Data Unit (ESDU) Payload IE element's */
|
||||||
|
#define MAC_PAYLOAD_MLME_IE_GROUP_ID 0x01 /**< MLME nested Payload IE element's */
|
||||||
|
#define MAC_PAYLOAD_VENDOR_IE_GROUP_ID 0x02 /**< Vendor specific nested Payload IE element's */
|
||||||
|
#define MAC_PAYLOAD_MPX_IE_GROUP_ID 0x03 /**< MPX Payload IE element, IEEE 802.15.9 defined */
|
||||||
|
#define MAC_PAYLOAD_TERMINATION_IE_GROUP_ID 0x0f /**< Payload IE element terminator. Mandatory when normal payload is coming after IE element part */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mac_header_IE_t Mac Payload information element structure for parsing or write operation
|
||||||
|
* This structure encapsulates security related variables,
|
||||||
|
*/
|
||||||
|
typedef struct mac_payload_IE_s {
|
||||||
|
uint8_t *content_ptr; /**< Content data */
|
||||||
|
unsigned length:11; /**< Element length 0- 2047 */
|
||||||
|
unsigned id:4; /**< Group ID */
|
||||||
|
} mac_payload_IE_t;
|
||||||
|
|
||||||
#endif /* MAC_COMMON_DEFINES_H_ */
|
#endif /* MAC_COMMON_DEFINES_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "mac_common_defines.h"
|
#include "mac_common_defines.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief struct mcps_data_req_t Data request structure
|
* @brief struct mcps_data_req_t Data request structure
|
||||||
*
|
*
|
||||||
|
@ -41,6 +42,8 @@ typedef struct mcps_data_req_s {
|
||||||
bool TxAckReq: 1; /**< Specifies whether ACK is needed or not */
|
bool TxAckReq: 1; /**< Specifies whether ACK is needed or not */
|
||||||
bool InDirectTx:1; /**< Specifies whether indirect or direct transmission is used */
|
bool InDirectTx:1; /**< Specifies whether indirect or direct transmission is used */
|
||||||
bool PendingBit: 1; /**< Specifies whether more fragments are to be sent or not */
|
bool PendingBit: 1; /**< Specifies whether more fragments are to be sent or not */
|
||||||
|
bool SeqNumSuppressed:1; /**< True suppress sequence number from frame. This will be only checked when 2015 extension is enabled */
|
||||||
|
bool PanIdSuppressed:1; /**< True suppress PAN-id is done when possible from frame. This will be only checked when 2015 extension is enabled */
|
||||||
mlme_security_t Key; /**< Security key */
|
mlme_security_t Key; /**< Security key */
|
||||||
} mcps_data_req_t;
|
} mcps_data_req_t;
|
||||||
|
|
||||||
|
@ -58,6 +61,21 @@ typedef struct mcps_data_conf_s {
|
||||||
uint8_t tx_retries; /**< Number of retries done during sending, 0 means no retries */
|
uint8_t tx_retries; /**< Number of retries done during sending, 0 means no retries */
|
||||||
} mcps_data_conf_t;
|
} mcps_data_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mcps_data_conf_payload_t Data confirmatio IE extension list and payload from enhanced ACK
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct mcps_data_conf_payload_s {
|
||||||
|
uint8_t *headerIeList; /**< Header information IE's list without terminator*/
|
||||||
|
uint8_t *payloadIeList; /**< Payload information IE's list without terminator*/
|
||||||
|
uint8_t *payloadPtr; /**< Ack payload pointer */
|
||||||
|
uint16_t headerIeListLength; /**< Header information IE's list length in bytes */
|
||||||
|
uint16_t payloadIeListLength; /**< Payload information IE's list length in bytes */
|
||||||
|
uint16_t payloadLength; /**< Payload length in bytes */
|
||||||
|
} mcps_data_conf_payload_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief struct mcps_data_ind_t Data indication structure
|
* @brief struct mcps_data_ind_t Data indication structure
|
||||||
*
|
*
|
||||||
|
@ -79,6 +97,54 @@ typedef struct mcps_data_ind_s {
|
||||||
uint8_t *msdu_ptr; /**< Data unit */
|
uint8_t *msdu_ptr; /**< Data unit */
|
||||||
} mcps_data_ind_t;
|
} mcps_data_ind_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mcps_data_ie_list_t MCPS data Information element list stucture
|
||||||
|
*
|
||||||
|
* Structure for IEEE 802.15.4-2015 MCPS data extension to Indication
|
||||||
|
*/
|
||||||
|
typedef struct mcps_data_ie_list {
|
||||||
|
uint8_t *headerIeList; /**< Header information IE's list without terminator*/
|
||||||
|
uint8_t *payloadIeList; /**< Payload information IE's list without terminator*/
|
||||||
|
uint16_t headerIeListLength; /**< Header information IE's list length in bytes */
|
||||||
|
uint16_t payloadIeListLength; /**< Payload information IE's list length in bytes */
|
||||||
|
} mcps_data_ie_list_t;
|
||||||
|
|
||||||
|
/** \brief Scatter-gather descriptor for MCPS request IE Element list
|
||||||
|
*
|
||||||
|
* Slightly optimised for small platforms - we assume we won't need any
|
||||||
|
* element bigger than 64K.
|
||||||
|
*/
|
||||||
|
typedef struct ns_ie_iovec {
|
||||||
|
void *ieBase; /**< IE element pointer */
|
||||||
|
uint_fast16_t iovLen; /**< IE element length */
|
||||||
|
} ns_ie_iovec_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mcps_data_req_ie_list MCPS data Information element list stuctrure
|
||||||
|
*
|
||||||
|
* Structure for IEEE 802.15.4-2015 MCPS data extension to Request
|
||||||
|
*
|
||||||
|
* IE element could be divided to multiple vector which MAC just write to message direct.
|
||||||
|
*/
|
||||||
|
typedef struct mcps_data_req_ie_list {
|
||||||
|
ns_ie_iovec_t *headerIeVectorList; /**< Header IE element list */
|
||||||
|
ns_ie_iovec_t *payloadIeVectorList; /**< Payload IE element list */
|
||||||
|
uint16_t headerIovLength; /**< Header IE element list size, set 0 when no elements */
|
||||||
|
uint16_t payloadIovLength; /**< Payload IE element list size, set 0 when no elements */
|
||||||
|
} mcps_data_req_ie_list_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mcps_ack_data_payload_t IE extension list and payload for enhanced ACK
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct mcps_ack_data_payload {
|
||||||
|
struct mcps_data_req_ie_list ie_elements; /**< IE hader and payload's elements */
|
||||||
|
uint8_t *payloadPtr; /**< Ack payload pointer */
|
||||||
|
uint16_t payloadLength; /**< Payload length in bytes */
|
||||||
|
} mcps_ack_data_payload_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief struct mcps_purge_t Purge request structure
|
* @brief struct mcps_purge_t Purge request structure
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -264,6 +264,7 @@ typedef enum {
|
||||||
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
|
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
|
||||||
macDefaultKeySource = 0x7c, /*<Default key source*/
|
macDefaultKeySource = 0x7c, /*<Default key source*/
|
||||||
//NON standard extension
|
//NON standard extension
|
||||||
|
macAcceptByPassUnknowDevice = 0xfc, /*< Accept data trough MAC if packet is data can be authenticated by group key nad MIC. Security enforsment point must be handled carefully these packets */
|
||||||
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
|
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
|
||||||
macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
|
macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
|
||||||
macThreadForceLongAddressForBeacon = 0xff /*<Thread standard force beacon source address for extended 64-bit*/
|
macThreadForceLongAddressForBeacon = 0xff /*<Thread standard force beacon source address for extended 64-bit*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -38,6 +38,15 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics);
|
extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TODO: description.
|
||||||
|
* @param fhss_configuration Basic FHSS configuration.
|
||||||
|
* @param fhss_timer FHSS platform timer interface and configuration.
|
||||||
|
* @param fhss_statistics FHSS statistics storage.
|
||||||
|
* @return New FHSS instance if successful, NULL otherwise.
|
||||||
|
*/
|
||||||
|
extern fhss_api_t *ns_fhss_ws_create(const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set synchronization time configuration for FHSS network. Should be only called from Border router.
|
* @brief Set synchronization time configuration for FHSS network. Should be only called from Border router.
|
||||||
* @param fhss_api FHSS instance.
|
* @param fhss_api FHSS instance.
|
||||||
|
@ -46,6 +55,21 @@ extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration
|
||||||
*/
|
*/
|
||||||
extern int ns_fhss_configuration_set(fhss_api_t *fhss_api, const fhss_synch_configuration_t *fhss_synch_configuration);
|
extern int ns_fhss_configuration_set(fhss_api_t *fhss_api, const fhss_synch_configuration_t *fhss_synch_configuration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get WS configuration.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @return WS configuration.
|
||||||
|
*/
|
||||||
|
extern const fhss_ws_configuration_t *ns_fhss_ws_configuration_get(const fhss_api_t *fhss_api);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set WS configuration.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @param fhss_configuration Basic FHSS configuration.
|
||||||
|
* @return 0 on success, -1 on fail.
|
||||||
|
*/
|
||||||
|
extern int ns_fhss_ws_configuration_set(const fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deletes a FHSS API instance and removes it from software MAC.
|
* @brief Deletes a FHSS API instance and removes it from software MAC.
|
||||||
* @param fhss_api FHSS instance.
|
* @param fhss_api FHSS instance.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -166,6 +166,7 @@ typedef enum {
|
||||||
NET_6LOWPAN_ND_WITHOUT_MLE, /**< **UNSUPPORTED** */
|
NET_6LOWPAN_ND_WITHOUT_MLE, /**< **UNSUPPORTED** */
|
||||||
NET_6LOWPAN_ND_WITH_MLE, /**< 6LoWPAN ND with MLE. */
|
NET_6LOWPAN_ND_WITH_MLE, /**< 6LoWPAN ND with MLE. */
|
||||||
NET_6LOWPAN_THREAD, /**< 6LoWPAN Thread with MLE attached. */
|
NET_6LOWPAN_THREAD, /**< 6LoWPAN Thread with MLE attached. */
|
||||||
|
NET_6LOWPAN_WS , /**< WS. */
|
||||||
NET_6LOWPAN_ZIGBEE_IP /**< **UNSUPPORTED** */
|
NET_6LOWPAN_ZIGBEE_IP /**< **UNSUPPORTED** */
|
||||||
} net_6lowpan_mode_extension_e;
|
} net_6lowpan_mode_extension_e;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -36,19 +36,33 @@
|
||||||
|
|
||||||
#include "ns_types.h"
|
#include "ns_types.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This API must be able to provide this many simultaneous contexts */
|
||||||
|
#if 1 /* config option for 802.15.4-2015? */
|
||||||
|
#define ARM_AES_MBEDTLS_CONTEXT_MIN 2 /**</ event loop and driver rx callback context */
|
||||||
|
#else
|
||||||
|
#define ARM_AES_MBEDTLS_CONTEXT_MIN 1 /**</ event loop use only */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct arm_aes_context arm_aes_context_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set the AES key
|
* \brief Set the AES key
|
||||||
*
|
*
|
||||||
* This function sets the 128-bit AES key that will be used for future
|
* This function sets the 128-bit AES key that will be used for future
|
||||||
* calls to arm_aes_encrypt(). The key must be copied by the function.
|
* calls to arm_aes_encrypt(). The key must be copied by the function.
|
||||||
|
* Function must return unique pointer for every started AES context.
|
||||||
*
|
*
|
||||||
* \param key pointer to 128-bit AES key
|
* \param key pointer to 128-bit AES key
|
||||||
|
*
|
||||||
|
* \return Pointer to aes context
|
||||||
|
* \return NULL if aes context allocation fail
|
||||||
*/
|
*/
|
||||||
void arm_aes_start(const uint8_t key[__static 16]);
|
arm_aes_context_t *arm_aes_start(const uint8_t key[__static 16]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function performs dst=E[preset key,src] (Simple ECB block).
|
* \brief This function performs dst=E[preset key,src] (Simple ECB block).
|
||||||
|
@ -57,10 +71,12 @@ void arm_aes_start(const uint8_t key[__static 16]);
|
||||||
* It is called between arm_aes_start() and arm_aes_finish().
|
* It is called between arm_aes_start() and arm_aes_finish().
|
||||||
* Note that src and dst pointers may be equal.
|
* Note that src and dst pointers may be equal.
|
||||||
*
|
*
|
||||||
|
* \param aes_context Pointer for allocated
|
||||||
* \param src pointer to 128-bit plaintext in
|
* \param src pointer to 128-bit plaintext in
|
||||||
* \param dst pointer for 128-bit ciphertext out
|
* \param dst pointer for 128-bit ciphertext out
|
||||||
*/
|
*/
|
||||||
extern void arm_aes_encrypt(
|
extern void arm_aes_encrypt(
|
||||||
|
arm_aes_context_t *aes_context,
|
||||||
const uint8_t src[__static 16],
|
const uint8_t src[__static 16],
|
||||||
uint8_t dst[__static 16]);
|
uint8_t dst[__static 16]);
|
||||||
|
|
||||||
|
@ -69,9 +85,9 @@ extern void arm_aes_encrypt(
|
||||||
*
|
*
|
||||||
* This function is called to terminate a series of AES operations.
|
* This function is called to terminate a series of AES operations.
|
||||||
* It may be a no-op, or it may disable AES hardware. Use of the preset key is
|
* It may be a no-op, or it may disable AES hardware. Use of the preset key is
|
||||||
* no longer valid after this call.
|
* no longer valid after this call and aes context will be freed.
|
||||||
*/
|
*/
|
||||||
void arm_aes_finish(void);
|
void arm_aes_finish(arm_aes_context_t *aes_context);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -45,6 +45,7 @@ typedef enum {
|
||||||
PHY_LINK_TX_SUCCESS, /**< MAC TX complete. MAC will a make decision to enter wait ACK or TX done state. */
|
PHY_LINK_TX_SUCCESS, /**< MAC TX complete. MAC will a make decision to enter wait ACK or TX done state. */
|
||||||
PHY_LINK_TX_FAIL, /**< Link TX process fail. */
|
PHY_LINK_TX_FAIL, /**< Link TX process fail. */
|
||||||
PHY_LINK_CCA_FAIL, /**< RF link CCA process fail. */
|
PHY_LINK_CCA_FAIL, /**< RF link CCA process fail. */
|
||||||
|
PHY_LINK_CCA_PREPARE, /**< RX Tx timeout prepare operation like channel switch to Tx channel from Receive one If operation fail must return not zero*/
|
||||||
} phy_link_tx_status_e;
|
} phy_link_tx_status_e;
|
||||||
|
|
||||||
/** Extension types */
|
/** Extension types */
|
||||||
|
@ -56,6 +57,13 @@ typedef enum {
|
||||||
PHY_EXTENSION_READ_LINK_STATUS, /**< Net library could read link status. */
|
PHY_EXTENSION_READ_LINK_STATUS, /**< Net library could read link status. */
|
||||||
PHY_EXTENSION_CONVERT_SIGNAL_INFO, /**< Convert signal info. */
|
PHY_EXTENSION_CONVERT_SIGNAL_INFO, /**< Convert signal info. */
|
||||||
PHY_EXTENSION_ACCEPT_ANY_BEACON, /**< Set boolean true or false for accept beacon from other Pan-ID than configured. Default value should be false */
|
PHY_EXTENSION_ACCEPT_ANY_BEACON, /**< Set boolean true or false for accept beacon from other Pan-ID than configured. Default value should be false */
|
||||||
|
PHY_EXTENSION_SET_TX_TIME, /**< Net library sets transmission time based on global time stamp. Max. 65ms from setting to TX. If TX time is set to zero, it should be ignored.*/
|
||||||
|
PHY_EXTENSION_READ_RX_TIME, /**< Read the time of last reception based on global micro seconds time stamp. */
|
||||||
|
PHY_EXTENSION_READ_TX_FINNISH_TIME, /**< Read the time of last finished TX micro seconds based on global time stamp. */
|
||||||
|
PHY_EXTENSION_DYNAMIC_RF_SUPPORTED, /**< Read status for support Radio driver support for set TX time, CCA and Timestamp read. Also PHY_LINK_CCA_PREPARE tx status must be supported also*/
|
||||||
|
PHY_EXTENSION_GET_TIMESTAMP, /**< Read 32-bit constant monotonic time stamp in us */
|
||||||
|
PHY_EXTENSION_SET_CSMA_PARAMETERS, /**< CSMA parameter's are given by phy_csma_params_t structure remember type cast uint8_t pointer to structure type*/
|
||||||
|
PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, /**< Read Symbols per seconds which will help to convert symbol time to real time */
|
||||||
} phy_extension_type_e;
|
} phy_extension_type_e;
|
||||||
|
|
||||||
/** Address types */
|
/** Address types */
|
||||||
|
@ -110,6 +118,12 @@ typedef struct phy_signal_info_s {
|
||||||
uint16_t result; /**< Resulting signal information. */
|
uint16_t result; /**< Resulting signal information. */
|
||||||
} phy_signal_info_s;
|
} phy_signal_info_s;
|
||||||
|
|
||||||
|
/** CSMA-CA parameters */
|
||||||
|
typedef struct phy_csma_params {
|
||||||
|
uint32_t backoff_time; /**< CSMA Backoff us time before start CCA & TX. 0 should disable current backoff*/
|
||||||
|
bool cca_enabled; /**< True will affect CCA check false start TX direct after backoff */
|
||||||
|
} phy_csma_params_t;
|
||||||
|
|
||||||
/** PHY modulation scheme */
|
/** PHY modulation scheme */
|
||||||
typedef enum phy_modulation_e
|
typedef enum phy_modulation_e
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -66,6 +66,13 @@ extern int8_t ns_sw_mac_virtual_client_unregister(struct mac_api_s *api);
|
||||||
*/
|
*/
|
||||||
extern int ns_sw_mac_fhss_register(struct mac_api_s *mac_api, struct fhss_api *fhss_api);
|
extern int ns_sw_mac_fhss_register(struct mac_api_s *mac_api, struct fhss_api *fhss_api);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Request registered FHSS API instance from software MAC instance.
|
||||||
|
* @param mac_api MAC instance.
|
||||||
|
* @return FHSS api.
|
||||||
|
*/
|
||||||
|
extern struct fhss_api *ns_sw_mac_get_fhss_api(struct mac_api_s *mac_api);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start collecting statistics from software MAC.
|
* @brief Start collecting statistics from software MAC.
|
||||||
* @param mac_api MAC instance.
|
* @param mac_api MAC instance.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -75,6 +75,19 @@ int thread_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int thread_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay);
|
int thread_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay);
|
||||||
|
/**
|
||||||
|
* Set prefix to be used as combining multiple thread networks on backbone.
|
||||||
|
*
|
||||||
|
* update prefix value
|
||||||
|
*
|
||||||
|
* \param interface_id interface ID of the Thread network.
|
||||||
|
* \param prefix value must be buffer at the size of 8 bytes
|
||||||
|
*
|
||||||
|
* \return 0 on success
|
||||||
|
* \return <0 in case of errors
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Thread validation interface destination address.
|
* Set the Thread validation interface destination address.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -54,6 +54,7 @@ typedef struct thread_border_router_info_t {
|
||||||
bool P_default_route: 1; /**< This device provides the default route. */
|
bool P_default_route: 1; /**< This device provides the default route. */
|
||||||
bool P_on_mesh: 1; /**< This prefix is considered to be on-mesh */
|
bool P_on_mesh: 1; /**< This prefix is considered to be on-mesh */
|
||||||
bool P_nd_dns: 1; /**< this border router is able to provide DNS information */
|
bool P_nd_dns: 1; /**< this border router is able to provide DNS information */
|
||||||
|
bool P_res1: 1; /**< First reserved bit */
|
||||||
bool stableData: 1; /**< This data is stable and expected to be available at least 48h. */
|
bool stableData: 1; /**< This data is stable and expected to be available at least 48h. */
|
||||||
} thread_border_router_info_t;
|
} thread_border_router_info_t;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -96,7 +96,7 @@ typedef struct link_configuration {
|
||||||
#define SECURITY_POLICY_EXTERNAL_COMMISSIONER_ALLOWED 0x10 /**< This indicates that external Commissioner authentication is allowed using PSKc. */
|
#define SECURITY_POLICY_EXTERNAL_COMMISSIONER_ALLOWED 0x10 /**< This indicates that external Commissioner authentication is allowed using PSKc. */
|
||||||
#define SECURITY_POLICY_BEACON_PAYLOAD_ENABLED 0x08 /**< Thread 1.x Beacons are enabled when this is set. */
|
#define SECURITY_POLICY_BEACON_PAYLOAD_ENABLED 0x08 /**< Thread 1.x Beacons are enabled when this is set. */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Mandatory device information
|
* Mandatory device information
|
||||||
*
|
*
|
||||||
* This information is required if commissioning is enabled for this device.
|
* This information is required if commissioning is enabled for this device.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -69,8 +69,11 @@
|
||||||
#endif
|
#endif
|
||||||
#include "sw_mac.h"
|
#include "sw_mac.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||||
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
||||||
|
#include "Service_Libs/etx/etx.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_GROUP_LOWPAN "6lo"
|
#define TRACE_GROUP_LOWPAN "6lo"
|
||||||
|
@ -164,7 +167,7 @@ void protocol_6lowpan_stack(buffer_t *b)
|
||||||
case B_TO_PHY:
|
case B_TO_PHY:
|
||||||
b = lowpan_adaptation_data_process_tx_preprocess(cur, b);
|
b = lowpan_adaptation_data_process_tx_preprocess(cur, b);
|
||||||
if (lowpan_adaptation_interface_tx(cur, b) != 0) {
|
if (lowpan_adaptation_interface_tx(cur, b) != 0) {
|
||||||
tr_error("Adaptaion Layer Data req fail");
|
tr_error("Adaptation Layer Data req fail");
|
||||||
}
|
}
|
||||||
b = NULL;
|
b = NULL;
|
||||||
break;
|
break;
|
||||||
|
@ -347,7 +350,6 @@ void protocol_6lowpan_host_init(protocol_interface_info_entry_t *cur, bool sleep
|
||||||
}
|
}
|
||||||
//Clear always INTERFACE_NWK_ROUTER_DEVICE, INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE
|
//Clear always INTERFACE_NWK_ROUTER_DEVICE, INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE
|
||||||
cur->lowpan_info &= ~(INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE);
|
cur->lowpan_info &= ~(INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE);
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
|
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
||||||
mac_data_poll_init(cur);
|
mac_data_poll_init(cur);
|
||||||
arm_nwk_6lowpan_borderrouter_data_free(cur);
|
arm_nwk_6lowpan_borderrouter_data_free(cur);
|
||||||
|
@ -358,7 +360,6 @@ void protocol_6lowpan_router_init(protocol_interface_info_entry_t *cur)
|
||||||
cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER;
|
cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER;
|
||||||
cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
|
cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
|
||||||
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
|
|
||||||
mac_data_poll_init(cur);
|
mac_data_poll_init(cur);
|
||||||
arm_nwk_6lowpan_borderrouter_data_free(cur);
|
arm_nwk_6lowpan_borderrouter_data_free(cur);
|
||||||
}
|
}
|
||||||
|
@ -398,6 +399,7 @@ void protocol_6lowpan_register_handlers(protocol_interface_info_entry_t *cur)
|
||||||
* for routers, as RPL doesn't deal with it) */
|
* for routers, as RPL doesn't deal with it) */
|
||||||
cur->ipv6_neighbour_cache.send_addr_reg = true;
|
cur->ipv6_neighbour_cache.send_addr_reg = true;
|
||||||
cur->ipv6_neighbour_cache.recv_na_aro = true;
|
cur->ipv6_neighbour_cache.recv_na_aro = true;
|
||||||
|
cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro = false;
|
||||||
}
|
}
|
||||||
void protocol_6lowpan_release_short_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint16_t shortAddress)
|
void protocol_6lowpan_release_short_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint16_t shortAddress)
|
||||||
{
|
{
|
||||||
|
@ -430,28 +432,27 @@ void protocol_6lowpan_release_long_link_address_from_neighcache(protocol_interfa
|
||||||
}
|
}
|
||||||
#ifdef HAVE_6LOWPAN_ND
|
#ifdef HAVE_6LOWPAN_ND
|
||||||
|
|
||||||
static int8_t mle_set_link_priority(int8_t interface_id, const uint8_t *address, bool priority)
|
static int8_t mle_set_link_priority(protocol_interface_info_entry_t *cur, const uint8_t *address, bool priority)
|
||||||
{
|
{
|
||||||
uint8_t mac64[8];
|
uint8_t mac64[8];
|
||||||
mle_neigh_table_entry_t *mle_entry;
|
mac_neighbor_table_entry_t *entry;
|
||||||
|
|
||||||
if (!memcmp(address, ADDR_SHORT_ADR_SUFFIC, 6)) {
|
if (!memcmp(address, ADDR_SHORT_ADR_SUFFIC, 6)) {
|
||||||
mle_entry = mle_class_get_by_link_address(interface_id, address + 6, ADDR_802_15_4_SHORT);
|
entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address + 6, ADDR_802_15_4_SHORT);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
memcpy(mac64, address, 8);
|
memcpy(mac64, address, 8);
|
||||||
mac64[0] ^= 2;
|
mac64[0] ^= 2;
|
||||||
mle_entry = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG);
|
entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mle_entry) {
|
if (!entry) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority) {
|
if (priority) {
|
||||||
mle_entry->priorityFlag = 1;
|
entry->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
||||||
} else {
|
} else {
|
||||||
mle_entry->priorityFlag = 0;
|
entry->link_role = NORMAL_NEIGHBOUR;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -461,11 +462,11 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t *
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
||||||
#ifndef NO_MLE
|
#ifndef NO_MLE
|
||||||
if (removed_priority) {
|
if (removed_priority) {
|
||||||
mle_set_link_priority(cur->id,removed_priority, false);
|
mle_set_link_priority(cur,removed_priority, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated_priority) {
|
if (updated_priority) {
|
||||||
mle_set_link_priority(cur->id, updated_priority, true);
|
mle_set_link_priority(cur, updated_priority, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -476,30 +477,30 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t *
|
||||||
|
|
||||||
uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr)
|
uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *neigh_table_ptr;
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
|
||||||
if (!addr_ptr) {
|
if (!cur || !addr_ptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type);
|
mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr_ptr + PAN_ID_LEN, addr_type);
|
||||||
|
|
||||||
if (neigh_table_ptr) {
|
if (entry) {
|
||||||
|
etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index);
|
||||||
// If primary parent has changed clears priority from previous parent
|
// If primary parent has changed clears priority from previous parent
|
||||||
if (!neigh_table_ptr->priorityFlag) {
|
if (entry->link_role != PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST);
|
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST);
|
||||||
}
|
}
|
||||||
neigh_table_ptr->priorityFlag = 1;
|
entry->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
||||||
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
if (cur) {
|
uint8_t temp[2];
|
||||||
uint8_t temp[2];
|
common_write_16_bit(entry->mac16, temp);
|
||||||
common_write_16_bit(neigh_table_ptr->short_adr, temp);
|
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, temp);
|
||||||
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, temp);
|
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG, entry->mac64);
|
||||||
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG, neigh_table_ptr->mac64);
|
if (etx_entry) {
|
||||||
|
protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol_stats_update(STATS_ETX_1ST_PARENT, neigh_table_ptr->etx >> 4);
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -508,21 +509,26 @@ uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t
|
||||||
|
|
||||||
uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr)
|
uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *neigh_table_ptr;
|
|
||||||
|
|
||||||
if (!addr_ptr) {
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
|
||||||
|
if (!cur || !addr_ptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type);
|
mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr_ptr + PAN_ID_LEN, addr_type);
|
||||||
|
|
||||||
if (neigh_table_ptr) {
|
if (entry) {
|
||||||
|
etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index);
|
||||||
// If secondary parent has changed clears priority from previous parent
|
// If secondary parent has changed clears priority from previous parent
|
||||||
if (neigh_table_ptr->second_priority_flag == 0) {
|
if (entry->link_role != SECONDARY_PARENT_NEIGHBOUR) {
|
||||||
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND);
|
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND);
|
||||||
}
|
}
|
||||||
neigh_table_ptr->second_priority_flag = 1;
|
entry->link_role = SECONDARY_PARENT_NEIGHBOUR;
|
||||||
protocol_stats_update(STATS_ETX_2ND_PARENT, neigh_table_ptr->etx >> 4);
|
|
||||||
|
if (etx_entry) {
|
||||||
|
protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -531,21 +537,22 @@ uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addr
|
||||||
|
|
||||||
void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority)
|
void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority)
|
||||||
{
|
{
|
||||||
mle_neigh_table_list_t *mle_neigh_table;
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
|
||||||
mle_neigh_table = mle_class_active_list_get(interface_id);
|
if (!cur) {
|
||||||
if (!mle_neigh_table) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_table_list) {
|
||||||
if (priority == PRIORITY_1ST) {
|
if (priority == PRIORITY_1ST && entry->link_role == PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
entry->priorityFlag = 0;
|
entry->link_role = NORMAL_NEIGHBOUR;
|
||||||
} else {
|
} else {
|
||||||
if (entry->second_priority_flag) {
|
if (entry->link_role == SECONDARY_PARENT_NEIGHBOUR) {
|
||||||
protocol_stats_update(STATS_ETX_2ND_PARENT, 0);
|
protocol_stats_update(STATS_ETX_2ND_PARENT, 0);
|
||||||
|
entry->link_role = NORMAL_NEIGHBOUR;
|
||||||
}
|
}
|
||||||
entry->second_priority_flag = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -558,43 +565,33 @@ void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_
|
||||||
int8_t protocol_6lowpan_neighbor_address_state_synch(protocol_interface_info_entry_t *cur, const uint8_t eui64[8], const uint8_t iid[8])
|
int8_t protocol_6lowpan_neighbor_address_state_synch(protocol_interface_info_entry_t *cur, const uint8_t eui64[8], const uint8_t iid[8])
|
||||||
{
|
{
|
||||||
int8_t ret_val = -1;
|
int8_t ret_val = -1;
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
|
||||||
#ifndef NO_MLE
|
mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), eui64, ADDR_802_15_4_LONG);
|
||||||
mle_neigh_table_entry_t *mle_entry = 0;
|
if (entry) {
|
||||||
mle_entry = mle_class_get_by_link_address(cur->id, eui64, ADDR_802_15_4_LONG);
|
if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) {
|
||||||
if (mle_entry && !mle_entry->threadNeighbor) {
|
iid += 6;
|
||||||
if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) {
|
//Set Short Address to MLE
|
||||||
iid += 6;
|
entry->mac16 = common_read_16_bit(iid);
|
||||||
//Set Short Address to MLE
|
}
|
||||||
mle_entry->short_adr = common_read_16_bit(iid);
|
if (!entry->ffd_device) {
|
||||||
}
|
if (entry->connected_device) {
|
||||||
if ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry, entry->link_lifetime);
|
||||||
if (mle_entry->handshakeReady) {
|
}
|
||||||
mle_entry_timeout_refresh(mle_entry);
|
ret_val = 1;
|
||||||
}
|
} else {
|
||||||
ret_val = 1;
|
ret_val = 0;
|
||||||
} else {
|
|
||||||
ret_val = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
ret_val = 0;
|
|
||||||
}
|
}
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t protocol_6lowpan_neighbor_remove(protocol_interface_info_entry_t *cur, uint8_t *address_ptr, addrtype_t type)
|
int8_t protocol_6lowpan_neighbor_remove(protocol_interface_info_entry_t *cur, uint8_t *address_ptr, addrtype_t type)
|
||||||
{
|
{
|
||||||
int8_t ret_val = 0;
|
mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address_ptr, type);
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
if (entry) {
|
||||||
#ifndef NO_MLE
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry);
|
||||||
mle_class_remove_neighbour(cur->id, address_ptr, type);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
//REMOVE Something else
|
|
||||||
}
|
}
|
||||||
return ret_val;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void protocol_6lowpan_allocate_mac16(protocol_interface_info_entry_t *cur)
|
void protocol_6lowpan_allocate_mac16(protocol_interface_info_entry_t *cur)
|
||||||
|
@ -739,7 +736,7 @@ uint8_t protocol_6lowpan_beacon_join_priority_tx(int8_t interface_id)
|
||||||
mle_6lowpan_data_t *mle_6lowpan_data = protocol_6lowpan_mle_data_get();
|
mle_6lowpan_data_t *mle_6lowpan_data = protocol_6lowpan_mle_data_get();
|
||||||
|
|
||||||
if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) {
|
if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) {
|
||||||
uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id);
|
uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur);
|
||||||
|
|
||||||
if (mle_neigh_cnt > mle_6lowpan_data->nbr_of_neigh_lower_threshold) {
|
if (mle_neigh_cnt > mle_6lowpan_data->nbr_of_neigh_lower_threshold) {
|
||||||
uint16_t mle_neigh_limit;
|
uint16_t mle_neigh_limit;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -69,7 +69,9 @@
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "libNET/src/net_load_balance_internal.h"
|
#include "libNET/src/net_load_balance_internal.h"
|
||||||
|
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||||
#include "6LoWPAN/NVM/nwk_nvm.h"
|
#include "6LoWPAN/NVM/nwk_nvm.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
|
|
||||||
/* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315
|
/* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315
|
||||||
|
@ -90,15 +92,16 @@ static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *han
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority);
|
static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority);
|
||||||
static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count);
|
static uint8_t protocol_6lowpan_mle_order_last_entries(int8_t interface_id,mac_neighbor_table_list_t *mac_neigh_table, uint8_t entry_count);
|
||||||
static uint8_t protocol_6lowpan_mle_data_allocate(void);
|
static uint8_t protocol_6lowpan_mle_data_allocate(void);
|
||||||
static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
|
static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
|
||||||
static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status);
|
static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status);
|
||||||
|
|
||||||
static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur);
|
static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *cur);
|
||||||
static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur);
|
static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
|
||||||
static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64);
|
static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
|
||||||
static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64);
|
static bool protocol_6lowpan_router_challenge(protocol_interface_info_entry_t *cur_interface, const uint8_t *mac64);
|
||||||
|
static bool protocol_6lowpan_host_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64);
|
||||||
static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface);
|
static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface);
|
||||||
static void coordinator_black_list(protocol_interface_info_entry_t *cur);
|
static void coordinator_black_list(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
@ -158,9 +161,9 @@ uint8_t *mle_general_write_timeout(uint8_t *ptr, protocol_interface_info_entry_t
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur)
|
static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *cur)
|
||||||
{
|
{
|
||||||
if (!cur->priorityFlag ||
|
if (cur->link_role != PRIORITY_PARENT_NEIGHBOUR ||
|
||||||
!(cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) ||
|
!(cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) ||
|
||||||
cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||||
return;
|
return;
|
||||||
|
@ -176,9 +179,9 @@ static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_en
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Call Priority parent loose
|
//Call Priority parent loose
|
||||||
if (cur->short_adr != 0xffff) {
|
if (cur->mac16 != 0xffff) {
|
||||||
memcpy(mac64, ADDR_SHORT_ADR_SUFFIC, 6);
|
memcpy(mac64, ADDR_SHORT_ADR_SUFFIC, 6);
|
||||||
common_write_16_bit(cur->short_adr, &mac64[6]);
|
common_write_16_bit(cur->mac16, &mac64[6]);
|
||||||
} else {
|
} else {
|
||||||
memcpy(mac64,cur->mac64 , 8);
|
memcpy(mac64,cur->mac64 , 8);
|
||||||
mac64[0] ^= 2;
|
mac64[0] ^= 2;
|
||||||
|
@ -192,64 +195,42 @@ static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_en
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur)
|
static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!cur_interface) {
|
if (!cur_interface) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleepy host
|
|
||||||
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
|
|
||||||
mac_data_poll_protocol_poll_mode_decrement(cur_interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol_6lowpan_priority_neighbor_remove(cur_interface, cur);
|
|
||||||
|
|
||||||
if (cur->mode & MLE_FFD_DEV) {
|
|
||||||
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr);
|
|
||||||
protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64);
|
|
||||||
}
|
|
||||||
mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
|
|
||||||
{
|
|
||||||
uint8_t mac64[8];
|
uint8_t mac64[8];
|
||||||
uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId);
|
uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId);
|
||||||
|
|
||||||
memcpy(mac64, ll64_ptr + 8, 8);
|
memcpy(mac64, ll64_ptr + 8, 8);
|
||||||
mac64[0] ^= 2;
|
mac64[0] ^= 2;
|
||||||
|
|
||||||
mle_neigh_table_entry_t *neig_info = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG);
|
mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), mac64, ADDR_802_15_4_LONG);
|
||||||
|
|
||||||
if (!neig_info) {
|
if (!neig_info) {
|
||||||
return false;//Why entry is removed before timeout??
|
return false;//Why entry is removed before timeout??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (neig_info->ttl > MLE_TABLE_CHALLENGE_TIMER) {
|
if (!neig_info->nud_active) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (usedAllRetries) {
|
if (usedAllRetries) {
|
||||||
//GET entry
|
//GET entry
|
||||||
mle_class_remove_entry(interface_id, neig_info);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), neig_info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64)
|
static bool protocol_6lowpan_host_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
if (!cur) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t bufId;
|
uint16_t bufId;
|
||||||
mle_message_timeout_params_t timeout;
|
mle_message_timeout_params_t timeout;
|
||||||
uint8_t ll64[16];
|
uint8_t ll64[16];
|
||||||
|
@ -261,7 +242,7 @@ static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t
|
||||||
tr_debug("Link REQUEST");
|
tr_debug("Link REQUEST");
|
||||||
bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST);
|
bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST);
|
||||||
if (bufId == 0) {
|
if (bufId == 0) {
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ptr = mle_service_get_data_pointer(bufId);
|
uint8_t *ptr = mle_service_get_data_pointer(bufId);
|
||||||
|
@ -293,16 +274,11 @@ static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t
|
||||||
mle_service_set_msg_timeout_parameters(bufId, &timeout);
|
mle_service_set_msg_timeout_parameters(bufId, &timeout);
|
||||||
|
|
||||||
mle_service_send_message(bufId);
|
mle_service_send_message(bufId);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64)
|
static bool protocol_6lowpan_router_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
if (!cur) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t bufId;
|
uint16_t bufId;
|
||||||
mle_message_timeout_params_t timeout;
|
mle_message_timeout_params_t timeout;
|
||||||
|
@ -315,7 +291,7 @@ static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8
|
||||||
tr_debug("Link REQUEST");
|
tr_debug("Link REQUEST");
|
||||||
bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST);
|
bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST);
|
||||||
if (bufId == 0) {
|
if (bufId == 0) {
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ptr = mle_service_get_data_pointer(bufId);
|
uint8_t *ptr = mle_service_get_data_pointer(bufId);
|
||||||
|
@ -342,16 +318,16 @@ static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8
|
||||||
mle_service_set_msg_timeout_parameters(bufId, &timeout);
|
mle_service_set_msg_timeout_parameters(bufId, &timeout);
|
||||||
|
|
||||||
mle_service_send_message(bufId);
|
mle_service_send_message(bufId);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t mle_advert_neigh_cnt(int8_t interface_id, bool short_adr) {
|
static uint8_t mle_advert_neigh_cnt(protocol_interface_info_entry_t *cur_interface, bool short_adr) {
|
||||||
|
|
||||||
uint8_t advert_neigh_cnt;
|
uint8_t advert_neigh_cnt;
|
||||||
uint8_t neighb_max;
|
uint8_t neighb_max;
|
||||||
|
|
||||||
uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id);
|
uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface);
|
||||||
|
|
||||||
if (short_adr == true) {
|
if (short_adr == true) {
|
||||||
neighb_max = 16;
|
neighb_max = 16;
|
||||||
|
@ -413,88 +389,94 @@ static uint8_t mle_link_quality_tlv_parse(uint8_t *mac64, uint16_t short_address
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *mle_table_set_neighbours(int8_t interface_id, uint8_t *ptr)
|
static bool neighbor_list_short_address_available(mac_neighbor_table_t *table_class)
|
||||||
|
{
|
||||||
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, &table_class->neighbour_list) {
|
||||||
|
if (cur_entry->connected_device && cur_entry->mac16 == 0xffff) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t *mle_table_set_neighbours(protocol_interface_info_entry_t *cur, uint8_t *ptr)
|
||||||
{
|
{
|
||||||
uint8_t *len_ptr = 0;
|
uint8_t *len_ptr = 0;
|
||||||
uint8_t short_temp[2] = {0xff,0xff};
|
|
||||||
uint8_t neigh_count = 0;
|
uint8_t neigh_count = 0;
|
||||||
uint8_t neigh_count_max = 0;
|
uint8_t neigh_count_max = 0;
|
||||||
uint8_t *link_flags_ptr;
|
uint8_t *link_flags_ptr;
|
||||||
mle_neigh_table_entry_t *first_entry_ptr = NULL;
|
mac_neighbor_table_entry_t *first_entry_ptr = NULL;
|
||||||
bool loop_list = false;
|
|
||||||
|
|
||||||
mle_neigh_table_list_t * neigh_list = mle_class_active_list_get(interface_id);
|
mac_neighbor_table_list_t * neigh_list = &cur->mac_parameters->mac_neighbor_table->neighbour_list;
|
||||||
if (!neigh_list) {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ptr++ = MLE_TYPE_LINK_QUALITY;
|
*ptr++ = MLE_TYPE_LINK_QUALITY;
|
||||||
len_ptr = ptr++;
|
len_ptr = ptr++;
|
||||||
*len_ptr = 1;
|
*len_ptr = 1;
|
||||||
// defaults: complete, 2 bytes long link-layer address
|
|
||||||
link_flags_ptr = ptr++;
|
|
||||||
*link_flags_ptr = 0x81;
|
|
||||||
|
|
||||||
if (mle_class_get_by_link_address(interface_id, short_temp,ADDR_802_15_4_SHORT)) {
|
link_flags_ptr = ptr++;
|
||||||
*link_flags_ptr |= 0x07;
|
//*link_flags_ptr = 0x81;
|
||||||
neigh_count_max = mle_advert_neigh_cnt(interface_id, false);
|
bool use_short_address_compression = neighbor_list_short_address_available(mac_neighbor_info(cur));
|
||||||
|
if (use_short_address_compression) {
|
||||||
|
//complete, 2 bytes long link-layer address
|
||||||
|
*link_flags_ptr = 0x81;
|
||||||
} else {
|
} else {
|
||||||
neigh_count_max = mle_advert_neigh_cnt(interface_id, true);
|
//complete, 8 bytes long link-layer address
|
||||||
|
*link_flags_ptr = 0x87;
|
||||||
|
|
||||||
|
}
|
||||||
|
neigh_count_max = mle_advert_neigh_cnt(cur, use_short_address_compression);
|
||||||
|
|
||||||
|
bool clean_entries = false;
|
||||||
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, neigh_list)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((cur_entry->connected_device) && (cur_entry->advertisment == false)) {
|
||||||
|
|
||||||
|
// If looping list, stops adding entries when at first sent entry again
|
||||||
|
if (first_entry_ptr == cur_entry) {
|
||||||
|
break;
|
||||||
|
} else if (first_entry_ptr == NULL) {
|
||||||
|
first_entry_ptr = cur_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limits the number of entries that are sent
|
||||||
|
if (++neigh_count > neigh_count_max) {
|
||||||
|
*link_flags_ptr &= 0x7f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_entry->link_role == PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
|
*ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
|
||||||
|
} else {
|
||||||
|
*ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr++ = etx_local_incoming_idr_read(cur->id, cur_entry->index) >> 3;
|
||||||
|
|
||||||
|
if (use_short_address_compression) {
|
||||||
|
ptr = common_write_16_bit(cur_entry->mac16, ptr);
|
||||||
|
*len_ptr += 4;
|
||||||
|
} else {
|
||||||
|
memcpy(ptr, cur_entry->mac64, 8);
|
||||||
|
ptr += 8;
|
||||||
|
*len_ptr += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If end of the neighbor list, Mark a clean advertisment from the list
|
||||||
|
if (cur_entry->link.next == 0) {
|
||||||
|
clean_entries = true;
|
||||||
|
}
|
||||||
|
cur_entry->advertisment = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
if (clean_entries) {
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list)
|
ns_list_foreach(mac_neighbor_table_entry_t, temp, neigh_list) {
|
||||||
{
|
// Marks entries not sent
|
||||||
|
temp->advertisment = false;
|
||||||
loop_list = false;
|
|
||||||
|
|
||||||
if ((cur->handshakeReady) && (cur->link_q_adv_sent == false)) {
|
|
||||||
|
|
||||||
// If looping list, stops adding entries when at first sent entry again
|
|
||||||
if (first_entry_ptr == cur) {
|
|
||||||
break;
|
|
||||||
} else if (first_entry_ptr == NULL) {
|
|
||||||
first_entry_ptr = cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limits the number of entries that are sent
|
|
||||||
if (++neigh_count > neigh_count_max) {
|
|
||||||
*link_flags_ptr &= 0x7f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur->priorityFlag) {
|
|
||||||
*ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
|
|
||||||
} else {
|
|
||||||
*ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ptr++ = etx_local_incoming_idr_read(interface_id, cur) >> 3;
|
|
||||||
|
|
||||||
if ((*link_flags_ptr & 0x07) == 1) {
|
|
||||||
ptr = common_write_16_bit(cur->short_adr, ptr);
|
|
||||||
*len_ptr += 4;
|
|
||||||
} else {
|
|
||||||
memcpy(ptr, cur->mac64, 8);
|
|
||||||
ptr += 8;
|
|
||||||
*len_ptr += 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If end of the neighbor list, start adding entries from start again
|
|
||||||
if (cur->link.next == 0) {
|
|
||||||
loop_list = true;
|
|
||||||
mle_neigh_table_list_t * neigh_temp = mle_class_active_list_get(interface_id);
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, temp, neigh_temp)
|
|
||||||
{
|
|
||||||
// Marks entries not sent
|
|
||||||
temp->link_q_adv_sent = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cur->link_q_adv_sent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (loop_list);
|
}
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -515,10 +497,10 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_class_get_by_link_address(cur->id, short_temp,ADDR_802_15_4_SHORT)) {
|
if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), short_temp,ADDR_802_15_4_SHORT)) {
|
||||||
neig_cache_size += mle_advert_neigh_cnt(cur->id, false) * 10;
|
neig_cache_size += mle_advert_neigh_cnt(cur, false) * 10;
|
||||||
} else {
|
} else {
|
||||||
neig_cache_size += mle_advert_neigh_cnt(cur->id, true) << 2;
|
neig_cache_size += mle_advert_neigh_cnt(cur, true) << 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bufId = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT);
|
uint16_t bufId = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT);
|
||||||
|
@ -539,7 +521,7 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t
|
||||||
ptr = mle_service_get_data_pointer(bufId);
|
ptr = mle_service_get_data_pointer(bufId);
|
||||||
ptr = mle_general_write_source_address(ptr, cur);
|
ptr = mle_general_write_source_address(ptr, cur);
|
||||||
ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur));
|
ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur));
|
||||||
ptr = mle_table_set_neighbours(cur->id, ptr);
|
ptr = mle_table_set_neighbours(cur, ptr);
|
||||||
|
|
||||||
if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) {
|
if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) {
|
||||||
tr_debug("Buffer overflow at message write");
|
tr_debug("Buffer overflow at message write");
|
||||||
|
@ -549,15 +531,6 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t compute_link_margin(int8_t rssi)
|
|
||||||
{
|
|
||||||
if (rssi < -94) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (rssi + 94);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info)
|
static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -571,8 +544,11 @@ static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length)
|
static void mle_neigh_time_and_mode_update(mac_neighbor_table_entry_t *entry_temp, mle_message_t *mle_msg)
|
||||||
{
|
{
|
||||||
|
uint8_t *tlv_ptr = mle_msg->data_ptr;
|
||||||
|
uint16_t tlv_length = mle_msg->data_length;
|
||||||
|
|
||||||
mle_tlv_info_t mle_tlv_info;
|
mle_tlv_info_t mle_tlv_info;
|
||||||
uint32_t timeout_tlv;
|
uint32_t timeout_tlv;
|
||||||
|
|
||||||
|
@ -580,42 +556,44 @@ static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
|
|
||||||
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) {
|
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) {
|
||||||
uint8_t *t_ptr = mle_tlv_info.dataPtr;
|
uint8_t *t_ptr = mle_tlv_info.dataPtr;
|
||||||
entry_temp->mode = *t_ptr;
|
mle_mode_parse_to_mac_entry(entry_temp, *t_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
|
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
|
||||||
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
|
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
|
||||||
} else {
|
} else {
|
||||||
if (entry_temp->mode & MLE_FFD_DEV) {
|
if (entry_temp->ffd_device) {
|
||||||
timeout_tlv = mle_6lowpan_data->router_lifetime;
|
timeout_tlv = mle_6lowpan_data->router_lifetime;
|
||||||
} else {
|
} else {
|
||||||
timeout_tlv = mle_6lowpan_data->host_lifetime;
|
timeout_tlv = mle_6lowpan_data->host_lifetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mle_entry_timeout_update(entry_temp, timeout_tlv);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout_tlv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address)
|
static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mac_neighbor_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address)
|
||||||
{
|
{
|
||||||
mle_tlv_info_t mle_tlv_info;
|
mle_tlv_info_t mle_tlv_info;
|
||||||
|
|
||||||
if (tlv_length) {
|
if (tlv_length) {
|
||||||
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_SRC_ADDRESS, &mle_tlv_info) > 0) {
|
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_SRC_ADDRESS, &mle_tlv_info) > 0) {
|
||||||
entry_temp->short_adr = common_read_16_bit(mle_tlv_info.dataPtr);
|
entry_temp->mac16 = common_read_16_bit(mle_tlv_info.dataPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) {
|
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) {
|
||||||
uint8_t link_idr;
|
uint8_t link_idr;
|
||||||
uint8_t iop_flags;
|
uint8_t iop_flags;
|
||||||
if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) {
|
if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) {
|
||||||
etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp);
|
etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp->index);
|
||||||
|
|
||||||
if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) {
|
if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) {
|
||||||
entry_temp->priority_child_flag = true;
|
entry_temp->link_role = CHILD_NEIGHBOUR;
|
||||||
} else {
|
} else if (entry_temp->link_role == CHILD_NEIGHBOUR) {
|
||||||
entry_temp->priority_child_flag = false;
|
entry_temp->link_role = NORMAL_NEIGHBOUR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,10 +736,10 @@ static int mle_router_accept_request_build(protocol_interface_info_entry_t *cur,
|
||||||
|
|
||||||
static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64)
|
static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, 0, ll64, false, NULL);
|
mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, false, NULL);
|
||||||
tr_debug("MLE link reject");
|
tr_debug("MLE link reject");
|
||||||
if (entry_temp) {
|
if (mac_entry) {
|
||||||
mle_class_remove_entry(cur->id, entry_temp);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), mac_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,14 +962,16 @@ int protocol_6lowpan_router_synch_to_new_router(protocol_interface_info_entry_t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mle_neigh_table_entry_t *entry_temp)
|
static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mac_neighbor_table_entry_t *entry_temp)
|
||||||
{
|
{
|
||||||
|
if (!entry_temp) {
|
||||||
return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp) >> 3;
|
return etx_lqi_dbm_update(-2, mle_msg->lqi, mle_msg->dbm, 0) >> 3;
|
||||||
|
}
|
||||||
|
return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp->index) >> 3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t *mle_msg, uint8_t only_max_limit_chk)
|
static bool mle_6lowpan_neighbor_limit_check(mle_message_t *mle_msg, uint8_t only_max_limit_chk)
|
||||||
{
|
{
|
||||||
uint16_t mle_neigh_cnt;
|
uint16_t mle_neigh_cnt;
|
||||||
bool link_quality = false;
|
bool link_quality = false;
|
||||||
|
@ -1000,7 +980,7 @@ static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_neigh_cnt = mle_class_active_neigh_counter(interface_id);
|
mle_neigh_cnt = mle_class_active_neigh_counter(mle_msg->interface_ptr);
|
||||||
|
|
||||||
// Neighbor max limit
|
// Neighbor max limit
|
||||||
if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_max) {
|
if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_max) {
|
||||||
|
@ -1048,17 +1028,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
uint8_t mode = 0x0a;
|
uint8_t mode = 0x0a;
|
||||||
mle_tlv_info_t mle_tlv_info;
|
mle_tlv_info_t mle_tlv_info;
|
||||||
mle_tlv_info_t mle_challenge;
|
mle_tlv_info_t mle_challenge;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
uint8_t linkMargin;
|
|
||||||
uint8_t incoming_idr;
|
uint8_t incoming_idr;
|
||||||
uint16_t responseId, own_mac16;
|
uint16_t responseId, own_mac16;
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
if (!cur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Calculate link margin
|
|
||||||
linkMargin = compute_link_margin(mle_msg->dbm);
|
|
||||||
|
|
||||||
own_mac16 = mac_helper_mac16_address_get(cur);
|
own_mac16 = mac_helper_mac16_address_get(cur);
|
||||||
|
|
||||||
|
@ -1081,13 +1055,13 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
mle_6lowpan_data->link_req_token_bucket--;
|
mle_6lowpan_data->link_req_token_bucket--;
|
||||||
} else {
|
} else {
|
||||||
//Update only old information based on link request
|
//Update only old information based on link request
|
||||||
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
if (entry_temp) {
|
if (entry_temp) {
|
||||||
mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length);
|
mle_neigh_time_and_mode_update(entry_temp,mle_msg);
|
||||||
mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
||||||
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
||||||
} else {
|
} else {
|
||||||
if (!mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) {
|
if (!mle_6lowpan_neighbor_limit_check(mle_msg, false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1069,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
|
|
||||||
incoming_idr = mle_calculate_idr(interface_id, mle_msg, entry_temp);
|
incoming_idr = mle_calculate_idr(interface_id, mle_msg, entry_temp);
|
||||||
|
|
||||||
if (entry_temp && entry_temp->handshakeReady) {
|
if (entry_temp && entry_temp->connected_device) {
|
||||||
response_type = MLE_COMMAND_ACCEPT;
|
response_type = MLE_COMMAND_ACCEPT;
|
||||||
} else {
|
} else {
|
||||||
response_type = MLE_COMMAND_ACCEPT_AND_REQUEST;
|
response_type = MLE_COMMAND_ACCEPT_AND_REQUEST;
|
||||||
|
@ -1117,13 +1091,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_debug("Accept & Request");
|
tr_debug("Accept & Request");
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
|
||||||
|
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
// If there is space for neighbors try to allocate new entry
|
// If there is space for neighbors try to allocate new entry
|
||||||
if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, true)) {
|
if (mle_6lowpan_neighbor_limit_check(mle_msg, true)) {
|
||||||
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, true, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,23 +1109,22 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
|
|
||||||
//Response state set now timeout know positive state
|
//Response state set now timeout know positive state
|
||||||
mle_service_set_msg_response_true(responseId);
|
mle_service_set_msg_response_true(responseId);
|
||||||
|
entry_temp->connected_device = 1;
|
||||||
entry_temp->threadNeighbor = false;
|
|
||||||
entry_temp->handshakeReady = 1;
|
|
||||||
|
|
||||||
mac_data_poll_protocol_poll_mode_decrement(cur);
|
mac_data_poll_protocol_poll_mode_decrement(cur);
|
||||||
|
|
||||||
//Read Source address and Challenge
|
//Read Source address and Challenge
|
||||||
mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length);
|
mle_neigh_time_and_mode_update(entry_temp,mle_msg);
|
||||||
if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) {
|
if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) {
|
||||||
// If no global address set priority (bootstrap ongoing)
|
// If no global address set priority (bootstrap ongoing)
|
||||||
if (!cur->global_address_available) {
|
if (!cur->global_address_available) {
|
||||||
entry_temp->priorityFlag = true;
|
entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
||||||
incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp);
|
incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp);
|
||||||
mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, entry_temp->priorityFlag);
|
uint8_t priority = (entry_temp->link_role == PRIORITY_PARENT_NEIGHBOUR);
|
||||||
|
mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, priority);
|
||||||
} else {
|
} else {
|
||||||
mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
||||||
incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp);
|
incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp);
|
||||||
|
@ -1161,7 +1132,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
||||||
// If MLE frame counter was invalid update its value since three way handshake is complete
|
// If MLE frame counter was invalid update its value since three way handshake is complete
|
||||||
if (security_headers->invalid_frame_counter) {
|
if (security_headers->invalid_frame_counter) {
|
||||||
entry_temp->mle_frame_counter = security_headers->frameCounter;
|
mle_service_frame_counter_entry_add(interface_id, entry_temp->index, security_headers->frameCounter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1184,12 +1155,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
t_ptr = mle_tlv_info.dataPtr;
|
t_ptr = mle_tlv_info.dataPtr;
|
||||||
mode = *t_ptr;
|
mode = *t_ptr;
|
||||||
}
|
}
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) {
|
if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) {
|
||||||
// If there is space for neighbors synchronizes to new router
|
// If there is space for neighbors synchronizes to new router
|
||||||
if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) {
|
if (mle_6lowpan_neighbor_limit_check(mle_msg, false)) {
|
||||||
// Checks blacklist
|
// Checks blacklist
|
||||||
if (blacklist_reject(mle_msg->packet_src_address)) {
|
if (blacklist_reject(mle_msg->packet_src_address)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1220,7 +1190,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
//Possible remove
|
//Possible remove
|
||||||
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
|
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
|
||||||
//Remove Entry
|
//Remove Entry
|
||||||
mle_class_remove_entry(cur->id, entry_temp);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
tr_error("MLE adv: Own address not found");
|
tr_error("MLE adv: Own address not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1232,8 +1202,8 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
|
||||||
//UPDATE
|
//UPDATE
|
||||||
mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
|
||||||
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
||||||
if (entry_temp->handshakeReady) {
|
if (entry_temp->connected_device) {
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1250,7 +1220,7 @@ int8_t arm_6lowpan_mle_service_ready_for_security_init(protocol_interface_info_e
|
||||||
//validate MLE service
|
//validate MLE service
|
||||||
if (!mle_service_interface_registeration_validate(cur->id)) {
|
if (!mle_service_interface_registeration_validate(cur->id)) {
|
||||||
//Register
|
//Register
|
||||||
if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) {
|
if (mle_service_interface_register(cur->id,cur, mle_6lowpan_message_handler, cur->mac,8) != 0) {
|
||||||
tr_error("Mle Service init Fail");
|
tr_error("Mle Service init Fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1301,29 +1271,24 @@ mle_6lowpan_data_t *protocol_6lowpan_mle_data_get(void)
|
||||||
|
|
||||||
static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority)
|
static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority)
|
||||||
{
|
{
|
||||||
mle_neigh_table_list_t *mle_neigh_table;
|
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
uint8_t ll64[16];
|
uint8_t ll64[16];
|
||||||
|
|
||||||
if (!cur_interface) {
|
if (!cur_interface) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mac_neighbor_table_list_t *mac_table_list = &cur_interface->mac_parameters->mac_neighbor_table->neighbour_list;
|
||||||
|
|
||||||
mle_neigh_table = mle_class_active_list_get(cur_interface->id);
|
entry_count = protocol_6lowpan_mle_order_last_entries(cur_interface->id, mac_table_list, entry_count);
|
||||||
|
|
||||||
if (!mle_neigh_table) {
|
ns_list_foreach_reverse_safe(mac_neighbor_table_entry_t, entry, mac_table_list) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry_count = protocol_6lowpan_mle_order_last_entries(mle_neigh_table, entry_count);
|
|
||||||
|
|
||||||
ns_list_foreach_reverse_safe(mle_neigh_table_entry_t, entry, mle_neigh_table) {
|
|
||||||
if (++count > entry_count) {
|
if (++count > entry_count) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!force_priority) {
|
if (!force_priority) {
|
||||||
if (entry->priorityFlag || entry->priority_child_flag) {
|
if (entry->link_role == PRIORITY_PARENT_NEIGHBOUR || entry->link_role == CHILD_NEIGHBOUR) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1336,23 +1301,23 @@ static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_
|
||||||
|
|
||||||
// Sends REJECT
|
// Sends REJECT
|
||||||
mle_service_reject_message_build(cur_interface->id, ll64, false);
|
mle_service_reject_message_build(cur_interface->id, ll64, false);
|
||||||
mle_class_remove_entry(cur_interface->id, entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), entry);
|
||||||
|
|
||||||
// Adds purged neighbor to blacklist so that it is not added right away back from advertisement
|
// Adds purged neighbor to blacklist so that it is not added right away back from advertisement
|
||||||
blacklist_update(ll64, false);
|
blacklist_update(ll64, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count)
|
static uint8_t protocol_6lowpan_mle_order_last_entries(int8_t interface_id, mac_neighbor_table_list_t *mac_neigh_table, uint8_t entry_count)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *last;
|
mac_neighbor_table_entry_t *last;
|
||||||
mle_neigh_table_entry_t *first_ordered = NULL;
|
mac_neighbor_table_entry_t *first_ordered = NULL;
|
||||||
|
etx_storage_t * etx_last, *etx_cur;
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
last = NULL;
|
last = NULL;
|
||||||
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_neigh_table) {
|
||||||
|
|
||||||
if (entry == first_ordered) {
|
if (entry == first_ordered) {
|
||||||
break;
|
break;
|
||||||
|
@ -1363,37 +1328,27 @@ static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *m
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primary parent (parent selected for bootstrap or RPL primary parent)
|
if (entry->link_role > last->link_role) { //Bigger link role is allways better
|
||||||
if (entry->priorityFlag && !last->priorityFlag) {
|
|
||||||
continue;
|
continue;
|
||||||
|
} else if (entry->link_role == last->link_role) {
|
||||||
|
// Compare ETX when Link role is same
|
||||||
|
etx_cur = etx_storage_entry_get(interface_id, entry->index);
|
||||||
|
etx_last = etx_storage_entry_get(interface_id, last->index);
|
||||||
|
if (etx_cur && etx_last && etx_cur->etx <= etx_last->etx) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secondary parent (RPL secondary parent)
|
|
||||||
if (entry->second_priority_flag && !last->second_priority_flag) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uses this node as parent
|
|
||||||
if (entry->priority_child_flag && !last->priority_child_flag) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Better ETX
|
|
||||||
if (entry->etx <= last->etx) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
last = entry;
|
last = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets last to end of list
|
// Sets last to end of list
|
||||||
if (last) {
|
if (last) {
|
||||||
ns_list_remove(mle_neigh_table, last);
|
ns_list_remove(mac_neigh_table, last);
|
||||||
|
|
||||||
if (first_ordered) {
|
if (first_ordered) {
|
||||||
ns_list_add_before(mle_neigh_table, first_ordered, last);
|
ns_list_add_before(mac_neigh_table, first_ordered, last);
|
||||||
} else {
|
} else {
|
||||||
ns_list_add_to_end(mle_neigh_table, last);
|
ns_list_add_to_end(mac_neigh_table, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
first_ordered = last;
|
first_ordered = last;
|
||||||
|
@ -1431,10 +1386,11 @@ static int8_t arm_6lowpan_bootstrap_down(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg)
|
static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg)
|
||||||
{
|
{
|
||||||
|
(void) interface_id;
|
||||||
#ifdef PANA
|
#ifdef PANA
|
||||||
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *interface = mle_msg->interface_ptr;
|
||||||
//Accept Only Link Reject
|
//Accept Only Link Reject
|
||||||
if (interface && mle_msg->message_type == MLE_COMMAND_REJECT) {
|
if (mle_msg->message_type == MLE_COMMAND_REJECT) {
|
||||||
|
|
||||||
if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) {
|
if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1508,7 +1464,7 @@ static int8_t arm_6lowpan_bootstrap_up(protocol_interface_info_entry_t *cur)
|
||||||
if (!mle_service_interface_registeration_validate(cur->id)) {
|
if (!mle_service_interface_registeration_validate(cur->id)) {
|
||||||
//Register
|
//Register
|
||||||
|
|
||||||
if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) {
|
if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) {
|
||||||
tr_error("Mle Service init Fail");
|
tr_error("Mle Service init Fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1594,7 +1550,6 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur)
|
||||||
} else {
|
} else {
|
||||||
protocol_6lowpan_register_handlers(cur);
|
protocol_6lowpan_register_handlers(cur);
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
|
|
||||||
mac_helper_default_security_level_set(cur, SEC_NONE);
|
mac_helper_default_security_level_set(cur, SEC_NONE);
|
||||||
|
|
||||||
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) {
|
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) {
|
||||||
|
@ -1621,15 +1576,6 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur)
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lowpan_interface_is_active(int8_t interface_id) {
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params)
|
static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params)
|
||||||
{
|
{
|
||||||
if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) {
|
if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) {
|
||||||
|
@ -1641,6 +1587,66 @@ static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
|
||||||
|
{
|
||||||
|
|
||||||
|
protocol_interface_info_entry_t *cur_interface = user_data;
|
||||||
|
lowpan_adaptation_remove_free_indirect_table(cur_interface, entry_ptr);
|
||||||
|
// Sleepy host
|
||||||
|
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
|
||||||
|
mac_data_poll_protocol_poll_mode_decrement(cur_interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_6lowpan_priority_neighbor_remove(cur_interface, entry_ptr);
|
||||||
|
|
||||||
|
if (entry_ptr->ffd_device) {
|
||||||
|
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, entry_ptr->mac16);
|
||||||
|
protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, entry_ptr->mac64);
|
||||||
|
}
|
||||||
|
mac_helper_devicetable_remove(cur_interface->mac_api, entry_ptr->index);
|
||||||
|
//Removes ETX neighbor
|
||||||
|
etx_neighbor_remove(cur_interface->id, entry_ptr->index);
|
||||||
|
//Remove MLE frame counter info
|
||||||
|
mle_service_frame_counter_entry_delete(cur_interface->id, entry_ptr->index);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Sleepy host
|
||||||
|
protocol_interface_info_entry_t *cur_interface = user_data;
|
||||||
|
|
||||||
|
if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
|
||||||
|
//Trig middle way challenge if Broadcast message have been missed
|
||||||
|
if (!entry_ptr->ffd_device) {
|
||||||
|
return false; //End device must do this
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_ptr->lifetime > (entry_ptr->link_lifetime / 2)) {
|
||||||
|
return false; //Trig only when midway is overed
|
||||||
|
}
|
||||||
|
return protocol_6lowpan_router_challenge(cur_interface, entry_ptr->mac64);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
|
return false; //Do not never challenge than priority parent
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
|
||||||
|
return false; //Sleepy end device should not never challenge
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return protocol_6lowpan_host_challenge(cur_interface, entry_ptr->mac64);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension)
|
int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension)
|
||||||
{
|
{
|
||||||
int8_t ret_val = -1;
|
int8_t ret_val = -1;
|
||||||
|
@ -1665,20 +1671,29 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode
|
||||||
cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb;
|
cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb;
|
||||||
//Allocate MLE class here
|
//Allocate MLE class here
|
||||||
//Deallocate old here
|
//Deallocate old here
|
||||||
|
mac_neighbor_table_delete(mac_neighbor_info(cur));
|
||||||
|
mac_description_storage_size_t buffer;
|
||||||
|
//Read MAC device table sizes
|
||||||
|
if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
mle_class_deallocate(interface_id);
|
mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size, lowpan_neighbor_entry_remove_notify
|
||||||
|
, lowpan_neighbor_entry_nud_notify, cur);
|
||||||
|
if (!mac_neighbor_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (enable_mle_protocol) {
|
if (enable_mle_protocol) {
|
||||||
|
if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
mac_description_storage_size_t buffer;
|
if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size)) {
|
||||||
//Read MAC device table sizes
|
|
||||||
if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (mle_class_init(interface_id, buffer.device_decription_table_size, &protocol_6lowpan_neighbor_information_remove, &protocol_6lowpan_host_challenge, &lowpan_interface_is_active) != 0) {
|
|
||||||
return -1;
|
lowpan_adaptation_interface_etx_update_enable(cur->id);
|
||||||
}
|
|
||||||
mle_class_router_challenge(interface_id, protocol_6lowpan_router_challenge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_service_interface_unregister(cur->id);
|
mle_service_interface_unregister(cur->id);
|
||||||
|
@ -1704,7 +1719,7 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode
|
||||||
return -2;
|
return -2;
|
||||||
#else
|
#else
|
||||||
cur->comm_status_ind_cb = lowpan_comm_status_indication_cb;
|
cur->comm_status_ind_cb = lowpan_comm_status_indication_cb;
|
||||||
if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) {
|
if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) {
|
||||||
tr_error("Mle Service init Fail");
|
tr_error("Mle Service init Fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1906,7 +1921,7 @@ void protocol_6lowpan_link_advertise_handle(nd_router_t *cur, protocol_interface
|
||||||
cur->mle_purge_timer -= 1;
|
cur->mle_purge_timer -= 1;
|
||||||
} else {
|
} else {
|
||||||
if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) {
|
if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) {
|
||||||
uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface->id);
|
uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface);
|
||||||
if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) {
|
if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) {
|
||||||
protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true);
|
protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true);
|
||||||
}
|
}
|
||||||
|
@ -1946,15 +1961,15 @@ static void protocol_6lowpan_nd_ready(protocol_interface_info_entry_t *cur)
|
||||||
if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) {
|
if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) {
|
||||||
//TRIG Only Normal Host
|
//TRIG Only Normal Host
|
||||||
#ifndef NO_MLE
|
#ifndef NO_MLE
|
||||||
//GET Cordinaotor MLE Entry
|
//GET Cordinator MLE Entry
|
||||||
addrtype_t addrType;
|
addrtype_t addrType;
|
||||||
uint8_t tempAddr[8];
|
uint8_t tempAddr[8];
|
||||||
addrType = mac_helper_coordinator_address_get(cur, tempAddr);
|
addrType = mac_helper_coordinator_address_get(cur, tempAddr);
|
||||||
|
mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tempAddr, addrType);
|
||||||
|
|
||||||
mle_neigh_table_entry_t *entry_t = mle_class_get_by_link_address(cur->id, tempAddr, addrType);
|
if (neig_info) {
|
||||||
if (entry_t) {
|
if (neig_info->lifetime > MLE_TABLE_CHALLENGE_TIMER) {
|
||||||
if (entry_t->ttl > MLE_TABLE_CHALLENGE_TIMER) {
|
neig_info->lifetime = (MLE_TABLE_CHALLENGE_TIMER + 1);
|
||||||
entry_t->ttl = (MLE_TABLE_CHALLENGE_TIMER + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2175,7 +2190,6 @@ void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t *
|
||||||
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) {
|
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) {
|
||||||
cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
||||||
tr_debug("Enable Poll state");
|
tr_debug("Enable Poll state");
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
|
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
|
||||||
mac_data_poll_init(cur);
|
mac_data_poll_init(cur);
|
||||||
mac_data_poll_init_protocol_poll(cur);
|
mac_data_poll_init_protocol_poll(cur);
|
||||||
|
@ -2753,12 +2767,13 @@ static void protocol_6lowpan_generate_link_reject(protocol_interface_info_entry_
|
||||||
|
|
||||||
static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status)
|
static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status)
|
||||||
{
|
{
|
||||||
#ifndef NO_MLE
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac_neighbor_table_entry_t * entry_ptr;
|
||||||
|
|
||||||
switch (status->status) {
|
switch (status->status) {
|
||||||
case MLME_UNSUPPORTED_SECURITY:
|
case MLME_UNSUPPORTED_SECURITY:
|
||||||
case MLME_UNAVAILABLE_KEY:
|
case MLME_UNAVAILABLE_KEY:
|
||||||
|
@ -2775,29 +2790,33 @@ static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_statu
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MLME_DATA_POLL_NOTIFICATION:
|
case MLME_DATA_POLL_NOTIFICATION:
|
||||||
mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false);
|
entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), status->SrcAddr, status->SrcAddrMode);
|
||||||
|
if (entry_ptr) {
|
||||||
|
// Refresh Timeout
|
||||||
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_ptr, entry_ptr->link_lifetime);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address)
|
bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool return_value = false;
|
bool return_value = false;
|
||||||
#ifndef NO_MLE
|
mac_neighbor_table_entry_t *neigh_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), link_local_address, false, NULL);
|
||||||
mle_neigh_table_entry_t * neigh_entry = mle_class_get_entry_by_ll64(interface_id, 0, link_local_address, false, NULL);
|
|
||||||
if (neigh_entry) {
|
if (neigh_entry) {
|
||||||
//Remove entry
|
//Remove entry
|
||||||
if (neigh_entry->priorityFlag) {
|
if (neigh_entry->link_role == PRIORITY_PARENT_NEIGHBOUR || neigh_entry->link_role == SECONDARY_PARENT_NEIGHBOUR) {
|
||||||
return_value = true;
|
|
||||||
} else if (neigh_entry->second_priority_flag) {
|
|
||||||
return_value = true;
|
return_value = true;
|
||||||
}
|
}
|
||||||
mle_class_remove_entry(interface_id, neigh_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neigh_entry);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h"
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h"
|
||||||
#include "Service_Libs/blacklist/blacklist.h"
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
|
|
||||||
#ifdef HAVE_RPL
|
#ifdef HAVE_RPL
|
||||||
|
@ -66,6 +67,7 @@
|
||||||
#include "platform/arm_hal_interrupt.h"
|
#include "platform/arm_hal_interrupt.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||||
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
||||||
#include "libNET/src/net_load_balance_internal.h"
|
#include "libNET/src/net_load_balance_internal.h"
|
||||||
|
@ -80,12 +82,14 @@ static int8_t set_6lowpan_nwk_down(protocol_interface_info_entry_t *cur)
|
||||||
/* Change Active -> Idle */
|
/* Change Active -> Idle */
|
||||||
/* Disable Protocols Timers */
|
/* Disable Protocols Timers */
|
||||||
if (!thread_info(cur)) {
|
if (!thread_info(cur)) {
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
|
||||||
#ifndef NO_MLE
|
#ifndef NO_MLE
|
||||||
mle_class_list_clean(cur->id);
|
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
||||||
|
|
||||||
blacklist_clear();
|
blacklist_clear();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) {
|
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) {
|
||||||
pana_reset_values(cur->mac_parameters->pan_id);
|
pana_reset_values(cur->mac_parameters->pan_id);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -35,13 +35,11 @@ extern struct rpl_domain *protocol_6lowpan_rpl_domain;
|
||||||
extern struct rpl_dodag *protocol_6lowpan_rpl_root_dodag;
|
extern struct rpl_dodag *protocol_6lowpan_rpl_root_dodag;
|
||||||
|
|
||||||
#ifdef HAVE_RPL
|
#ifdef HAVE_RPL
|
||||||
#ifndef NO_MLE
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PRIORITY_1ST,
|
PRIORITY_1ST,
|
||||||
PRIORITY_2ND,
|
PRIORITY_2ND,
|
||||||
} neighbor_priority;
|
} neighbor_priority;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
void protocol_6lowpan_interface_common_init(struct protocol_interface_info_entry *cur);
|
void protocol_6lowpan_interface_common_init(struct protocol_interface_info_entry *cur);
|
||||||
void protocol_6lowpan_host_init(struct protocol_interface_info_entry *cur, bool sleepy_host);
|
void protocol_6lowpan_host_init(struct protocol_interface_info_entry *cur, bool sleepy_host);
|
||||||
|
@ -53,12 +51,10 @@ int protocol_6lowpan_child_update(struct protocol_interface_info_entry *cur);
|
||||||
void protocol_6lowpan_neighbor_priority_update(struct protocol_interface_info_entry *cur, uint8_t *removed_priority, uint8_t *updated_priority);
|
void protocol_6lowpan_neighbor_priority_update(struct protocol_interface_info_entry *cur, uint8_t *removed_priority, uint8_t *updated_priority);
|
||||||
|
|
||||||
#ifdef HAVE_RPL
|
#ifdef HAVE_RPL
|
||||||
#ifndef NO_MLE
|
|
||||||
uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr);
|
uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr);
|
||||||
uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr);
|
uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr);
|
||||||
void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority);
|
void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define protocol_6lowpan_child_update(cur) (-1)
|
#define protocol_6lowpan_child_update(cur) (-1)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
struct protocol_interface_info_entry;
|
struct protocol_interface_info_entry;
|
||||||
struct nd_router;
|
struct nd_router;
|
||||||
struct mle_neigh_table_entry_t;
|
|
||||||
|
|
||||||
#define MLE_NEIGHBOR_PURGE_NBR 3
|
#define MLE_NEIGHBOR_PURGE_NBR 3
|
||||||
#define MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT 4 // Times advertisement timeout
|
#define MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT 4 // Times advertisement timeout
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -77,12 +77,7 @@ buffer_t *lowpan_down(buffer_t *buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (thread_info(cur)) {
|
if (thread_info(cur)) {
|
||||||
mle_neigh_table_entry_t *mle_entry;
|
stable_only = thread_stable_context_check(cur, buf);
|
||||||
mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
|
||||||
if (mle_entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), mle_entry->short_adr)) {
|
|
||||||
/* Check if the child can handle only stable network data (e.g. sleepy device) */
|
|
||||||
stable_only = !(mle_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +164,7 @@ buffer_t *lowpan_down(buffer_t *buf)
|
||||||
/* RFC 6282+4944 require that we limit compression to the first fragment.
|
/* RFC 6282+4944 require that we limit compression to the first fragment.
|
||||||
* This check is slightly conservative - always allow 4 for first-fragment header
|
* This check is slightly conservative - always allow 4 for first-fragment header
|
||||||
*/
|
*/
|
||||||
uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf);
|
uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf);
|
||||||
uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4;
|
uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4;
|
||||||
|
|
||||||
buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only);
|
buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "mPol"
|
#define TRACE_GROUP "mPol"
|
||||||
|
|
||||||
|
@ -281,6 +282,23 @@ void mac_poll_timer_trig(uint32_t poll_time, protocol_interface_info_entry_t *cu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, uint8_t *address, addrtype_t type)
|
||||||
|
{
|
||||||
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type);
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry->connected_device) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry->nud_active) {
|
||||||
|
entry->lifetime = entry->link_lifetime;
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm)
|
void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm)
|
||||||
{
|
{
|
||||||
|
@ -295,20 +313,21 @@ void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_ptr->pollActive = false;
|
rf_ptr->pollActive = false;
|
||||||
|
mac_neighbor_table_entry_t *entry = NULL;
|
||||||
|
|
||||||
switch (confirm->status) {
|
switch (confirm->status) {
|
||||||
case MLME_SUCCESS:
|
case MLME_SUCCESS:
|
||||||
//tr_debug("Poll Confirm: Data with Data");
|
//tr_debug("Poll Confirm: Data with Data");
|
||||||
rf_ptr->nwk_parent_poll_fail = 0;
|
rf_ptr->nwk_parent_poll_fail = 0;
|
||||||
//Trig new Data Poll immediately
|
//Trig new Data Poll immediately
|
||||||
mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true);
|
entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode);
|
||||||
poll_time = 1;
|
poll_time = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MLME_NO_DATA:
|
case MLME_NO_DATA:
|
||||||
//Start next case timer
|
//Start next case timer
|
||||||
rf_ptr->nwk_parent_poll_fail = 0;
|
rf_ptr->nwk_parent_poll_fail = 0;
|
||||||
mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true);
|
entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode);
|
||||||
//tr_debug("Poll Confirm: No Data");
|
//tr_debug("Poll Confirm: No Data");
|
||||||
|
|
||||||
if (rf_ptr->protocol_poll == 0) {
|
if (rf_ptr->protocol_poll == 0) {
|
||||||
|
@ -333,6 +352,9 @@ void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (thread_info(cur) && entry) {
|
||||||
|
thread_neighbor_communication_update(cur, entry->index);
|
||||||
|
}
|
||||||
|
|
||||||
mac_poll_timer_trig(poll_time, cur);
|
mac_poll_timer_trig(poll_time, cur);
|
||||||
|
|
||||||
|
@ -423,7 +445,6 @@ int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, ne
|
||||||
new_poll_time = (poll_time * 1000);
|
new_poll_time = (poll_time * 1000);
|
||||||
if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) {
|
if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) {
|
||||||
tr_debug("Init Poll timer and period");
|
tr_debug("Init Poll timer and period");
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_ptr->nwk_app_poll_time = new_poll_time;
|
rf_ptr->nwk_app_poll_time = new_poll_time;
|
||||||
|
@ -449,7 +470,6 @@ int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, ne
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr_debug("Enable Poll By APP");
|
tr_debug("Enable Poll By APP");
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
|
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
|
||||||
mac_poll_timer_trig(1, cur);
|
mac_poll_timer_trig(1, cur);
|
||||||
rf_ptr->nwk_app_poll_time = 300;
|
rf_ptr->nwk_app_poll_time = 300;
|
||||||
|
@ -525,14 +545,12 @@ void mac_data_poll_init(struct protocol_interface_info_entry *cur)
|
||||||
if (cur->mac_parameters->RxOnWhenIdle) {
|
if (cur->mac_parameters->RxOnWhenIdle) {
|
||||||
tr_debug("Set Non-Sleepy HOST");
|
tr_debug("Set Non-Sleepy HOST");
|
||||||
rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE;
|
rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE;
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
rfd_ptr->protocol_poll = 1;
|
rfd_ptr->protocol_poll = 1;
|
||||||
mac_poll_timer_trig(200, cur);
|
mac_poll_timer_trig(200, cur);
|
||||||
tr_debug("Set Sleepy HOST configure");
|
tr_debug("Set Sleepy HOST configure");
|
||||||
rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE;
|
rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE;
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
|
|
||||||
rfd_ptr->slow_poll_rate_seconds = 3;
|
rfd_ptr->slow_poll_rate_seconds = 3;
|
||||||
rfd_ptr->timeOutInSeconds = 32;
|
rfd_ptr->timeOutInSeconds = 32;
|
||||||
rfd_ptr->nwk_app_poll_time = 300;
|
rfd_ptr->nwk_app_poll_time = 300;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -25,7 +25,6 @@
|
||||||
#include "net_nwk_scan.h"
|
#include "net_nwk_scan.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "MLE/mle_tlv.h"
|
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "MACh"
|
#define TRACE_GROUP "MACh"
|
||||||
|
@ -685,7 +684,7 @@ int8_t mac_helper_mac64_set(protocol_interface_info_entry_t *interface, const ui
|
||||||
* Given a buffer, with address and security flags set, compute the maximum
|
* Given a buffer, with address and security flags set, compute the maximum
|
||||||
* MAC payload that could be put in that buffer.
|
* MAC payload that could be put in that buffer.
|
||||||
*/
|
*/
|
||||||
uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast8_t frame_overhead)
|
uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast16_t frame_overhead)
|
||||||
{
|
{
|
||||||
uint16_t max;
|
uint16_t max;
|
||||||
|
|
||||||
|
@ -833,7 +832,17 @@ void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index)
|
||||||
mac_api->mlme_req(mac_api,MLME_SET , &set_req);
|
mac_api->mlme_req(mac_api,MLME_SET , &set_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID, bool force_set)
|
void mac_helper_device_description_write(protocol_interface_info_entry_t *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt)
|
||||||
|
{
|
||||||
|
memcpy(device_desc->ExtAddress, mac64, 8);
|
||||||
|
device_desc->ShortAddress = mac16;
|
||||||
|
device_desc->PANId = mac_helper_panid_get(cur);
|
||||||
|
device_desc->Exempt = exempt;
|
||||||
|
device_desc->FrameCounter = frame_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_desc, protocol_interface_info_entry_t *cur, uint8_t attribute_index, uint8_t keyID, bool force_set)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!cur->mac_api) {
|
if (!cur->mac_api) {
|
||||||
return;
|
return;
|
||||||
|
@ -844,18 +853,10 @@ void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_in
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlme_device_descriptor_t device_desc;
|
|
||||||
mlme_set_t set_req;
|
mlme_set_t set_req;
|
||||||
device_desc.FrameCounter = frame_counter;
|
|
||||||
device_desc.Exempt = false;
|
|
||||||
device_desc.ShortAddress = entry_temp->short_adr;
|
|
||||||
memcpy(device_desc.ExtAddress, entry_temp->mac64, 8);
|
|
||||||
device_desc.PANId = mac_helper_panid_get(cur);
|
|
||||||
|
|
||||||
|
|
||||||
set_req.attr = macDeviceTable;
|
set_req.attr = macDeviceTable;
|
||||||
set_req.attr_index = entry_temp->attribute_index;
|
set_req.attr_index = attribute_index;
|
||||||
set_req.value_pointer = (void*)&device_desc;
|
set_req.value_pointer = (void*)device_desc;
|
||||||
set_req.value_size = sizeof(mlme_device_descriptor_t);
|
set_req.value_size = sizeof(mlme_device_descriptor_t);
|
||||||
tr_debug("Register Device");
|
tr_debug("Register Device");
|
||||||
cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req);
|
cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -29,7 +29,6 @@ struct protocol_interface_info_entry;
|
||||||
struct ns_sockaddr;
|
struct ns_sockaddr;
|
||||||
struct buffer;
|
struct buffer;
|
||||||
struct mac_api_s;
|
struct mac_api_s;
|
||||||
struct mle_neigh_table_entry_t;
|
|
||||||
|
|
||||||
|
|
||||||
void mac_create_scan_request(mac_scan_type_t type, struct channel_list_s *chanlist, uint8_t scan_duration, struct mlme_scan_s *request);
|
void mac_create_scan_request(mac_scan_type_t type, struct channel_list_s *chanlist, uint8_t scan_duration, struct mlme_scan_s *request);
|
||||||
|
@ -100,7 +99,7 @@ bool mac_helper_write_our_addr(struct protocol_interface_info_entry *interface,
|
||||||
|
|
||||||
int8_t mac_helper_mac64_set(struct protocol_interface_info_entry *interface, const uint8_t *mac64);
|
int8_t mac_helper_mac64_set(struct protocol_interface_info_entry *interface, const uint8_t *mac64);
|
||||||
|
|
||||||
uint_fast16_t mac_helper_max_payload_size(struct protocol_interface_info_entry *cur, uint_fast8_t frame_overhead);
|
uint_fast16_t mac_helper_max_payload_size(struct protocol_interface_info_entry *cur, uint_fast16_t frame_overhead);
|
||||||
|
|
||||||
uint_fast8_t mac_helper_frame_overhead(struct protocol_interface_info_entry *cur, const struct buffer *buf);
|
uint_fast8_t mac_helper_frame_overhead(struct protocol_interface_info_entry *cur, const struct buffer *buf);
|
||||||
|
|
||||||
|
@ -110,8 +109,9 @@ int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr);
|
||||||
|
|
||||||
void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_index);
|
void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_index);
|
||||||
|
|
||||||
void mac_helper_devicetable_set(struct mle_neigh_table_entry_t *entry_temp, struct protocol_interface_info_entry *cur, uint32_t frame_counter, uint8_t keyID, bool force_set);
|
void mac_helper_device_description_write(struct protocol_interface_info_entry *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt);
|
||||||
|
|
||||||
|
void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_dec, struct protocol_interface_info_entry *cur, uint8_t attribute_index, uint8_t keyID, bool force_set);
|
||||||
int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set);
|
int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set);
|
||||||
|
|
||||||
#endif // MAC_HELPER_H
|
#endif // MAC_HELPER_H
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "common_functions.h"
|
||||||
|
#include "mac_common_defines.h"
|
||||||
|
#include "mac_ie_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAC_IE_HEADER_LENGTH_MASK 0x007f
|
||||||
|
#define MAC_IE_HEADER_ID_MASK 0x7f80
|
||||||
|
#define MAC_IE_PAYLOAD_LENGTH_MASK 0x07ff
|
||||||
|
#define MAC_IE_PAYLOAD_ID_MASK 0x7800
|
||||||
|
#define MAC_IE_TYPE_PAYLOAD_MASK 0x8000
|
||||||
|
|
||||||
|
#define MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK 0x07ff
|
||||||
|
#define MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK 0x7800
|
||||||
|
#define MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK 0x00ff
|
||||||
|
#define MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK 0x7f00
|
||||||
|
#define MAC_NESTED_IE_TYPE_LONG_MASK 0x8000
|
||||||
|
|
||||||
|
static void mac_ie_header_parse(mac_header_IE_t *header_element, uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint16_t ie_dummy = common_read_16_bit_inverse(ptr);
|
||||||
|
header_element->length = (ie_dummy & MAC_IE_HEADER_LENGTH_MASK);
|
||||||
|
header_element->id = ((ie_dummy & MAC_IE_HEADER_ID_MASK ) >> 7 );
|
||||||
|
header_element->content_ptr = ptr + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mac_ie_payload_parse(mac_payload_IE_t *payload_element, uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint16_t ie_dummy = common_read_16_bit_inverse(ptr);
|
||||||
|
payload_element->length = (ie_dummy & MAC_IE_PAYLOAD_LENGTH_MASK);
|
||||||
|
payload_element->id = ((ie_dummy & MAC_IE_PAYLOAD_ID_MASK ) >> 11);
|
||||||
|
payload_element->content_ptr = ptr + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mac_ie_nested_id_parse(mac_nested_payload_IE_t *element, uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint16_t ie_dummy = common_read_16_bit_inverse(ptr);
|
||||||
|
|
||||||
|
if (ie_dummy & MAC_NESTED_IE_TYPE_LONG_MASK) {
|
||||||
|
element->type_long = true;
|
||||||
|
element->length = (ie_dummy & MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK);
|
||||||
|
element->id = ((ie_dummy & MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK ) >> 11);
|
||||||
|
} else {
|
||||||
|
element->type_long = false;
|
||||||
|
element->length = (ie_dummy & MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK);
|
||||||
|
element->id = ((ie_dummy & MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK ) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
element->content_ptr = ptr + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *mac_ie_header_base_write(uint8_t *ptr, uint8_t type, uint16_t length)
|
||||||
|
{
|
||||||
|
uint16_t ie_dummy = 0; //Header Type
|
||||||
|
ie_dummy |= (length & MAC_IE_HEADER_LENGTH_MASK);
|
||||||
|
ie_dummy |= ((type << 7 ) & MAC_IE_HEADER_ID_MASK);
|
||||||
|
return common_write_16_bit_inverse(ie_dummy, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *mac_ie_payload_base_write(uint8_t *ptr, uint8_t type, uint16_t length)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t ie_dummy = MAC_IE_TYPE_PAYLOAD_MASK; //Payload type
|
||||||
|
ie_dummy |= (length & MAC_IE_PAYLOAD_LENGTH_MASK);
|
||||||
|
ie_dummy |= ((type << 11 ) & MAC_IE_PAYLOAD_ID_MASK);
|
||||||
|
return common_write_16_bit_inverse(ie_dummy, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *mac_ie_nested_ie_long_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length)
|
||||||
|
{
|
||||||
|
uint16_t ie_dummy = MAC_NESTED_IE_TYPE_LONG_MASK;
|
||||||
|
ie_dummy |= (length & MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK);
|
||||||
|
ie_dummy |= ((sub_id << 11 ) & MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK);
|
||||||
|
|
||||||
|
return common_write_16_bit_inverse(ie_dummy, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *mac_ie_nested_ie_short_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length)
|
||||||
|
{
|
||||||
|
uint16_t ie_dummy = 0;
|
||||||
|
ie_dummy |= (length & MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK);
|
||||||
|
ie_dummy |= ((sub_id << 8 ) & MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK);
|
||||||
|
|
||||||
|
return common_write_16_bit_inverse(ie_dummy, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, mac_payload_IE_t * payload_ie)
|
||||||
|
{
|
||||||
|
mac_payload_IE_t ie_element;
|
||||||
|
while (length >= 2) {
|
||||||
|
mac_ie_payload_parse(&ie_element, payload_ptr);
|
||||||
|
if (payload_ie->id == ie_element.id) {
|
||||||
|
payload_ie->content_ptr = ie_element.content_ptr;
|
||||||
|
payload_ie->length = ie_element.length;
|
||||||
|
return ie_element.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= ie_element.length + 2;
|
||||||
|
|
||||||
|
payload_ptr += ie_element.length + 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t * nested_ie)
|
||||||
|
{
|
||||||
|
mac_nested_payload_IE_t ie_element;
|
||||||
|
while (length >= 2) {
|
||||||
|
mac_ie_nested_id_parse(&ie_element, payload_ptr);
|
||||||
|
|
||||||
|
if (length < ie_element.length + 2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nested_ie->id == ie_element.id && nested_ie->type_long == ie_element.type_long) {
|
||||||
|
nested_ie->content_ptr = ie_element.content_ptr;
|
||||||
|
nested_ie->length = ie_element.length;
|
||||||
|
return ie_element.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= ie_element.length + 2;
|
||||||
|
|
||||||
|
payload_ptr += ie_element.length + 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie)
|
||||||
|
{
|
||||||
|
mac_header_IE_t ie_element;
|
||||||
|
while (length >= 2) {
|
||||||
|
mac_ie_header_parse(&ie_element, header_ptr);
|
||||||
|
if (header_ie->id == ie_element.id) {
|
||||||
|
header_ie->content_ptr = ie_element.content_ptr;
|
||||||
|
header_ie->length = ie_element.length;
|
||||||
|
return ie_element.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= ie_element.length + 2;
|
||||||
|
|
||||||
|
header_ptr += ie_element.length + 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t mac_ie_header_sub_id_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie, uint8_t sub_id)
|
||||||
|
{
|
||||||
|
mac_header_IE_t ie_element;
|
||||||
|
uint8_t *sub_id_ptr;
|
||||||
|
while (length > 2) {
|
||||||
|
mac_ie_header_parse(&ie_element, header_ptr);
|
||||||
|
sub_id_ptr = ie_element.content_ptr;
|
||||||
|
if (ie_element.length && header_ie->id == ie_element.id && *sub_id_ptr == sub_id) {
|
||||||
|
sub_id_ptr++;
|
||||||
|
ie_element.length--;
|
||||||
|
header_ie->content_ptr = sub_id_ptr;
|
||||||
|
header_ie->length = ie_element.length;
|
||||||
|
return ie_element.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= ie_element.length + 2;
|
||||||
|
|
||||||
|
header_ptr += ie_element.length + 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MAC_IE_LIB_H_
|
||||||
|
#define MAC_IE_LIB_H_
|
||||||
|
|
||||||
|
struct mac_payload_IE_s;
|
||||||
|
struct mac_payload_IE_s;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct mac_nested_payload_IE_t Mac Nested IE Payload information element structure for parsing or write operation
|
||||||
|
*/
|
||||||
|
typedef struct mac_nested_payload_IE_s {
|
||||||
|
uint8_t *content_ptr; /**< Content data */
|
||||||
|
uint16_t length; /**< Element length 0- 2047 when type_long true and for short 0- 255*/
|
||||||
|
unsigned id:7; /**< Group ID 4-bit for long and 7 bit for short type */
|
||||||
|
bool type_long:1; /**< True when Nested IE long format and false for short */
|
||||||
|
} mac_nested_payload_IE_t;
|
||||||
|
|
||||||
|
/** IE header element generic header write */
|
||||||
|
uint8_t *mac_ie_header_base_write(uint8_t *ptr, uint8_t type, uint16_t length);
|
||||||
|
|
||||||
|
/** IE payload element generic header write */
|
||||||
|
uint8_t *mac_ie_payload_base_write(uint8_t *ptr, uint8_t type, uint16_t length);
|
||||||
|
|
||||||
|
/** Nested IE long header write */
|
||||||
|
uint8_t *mac_ie_nested_ie_long_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length);
|
||||||
|
|
||||||
|
/** Nested IE short header write */
|
||||||
|
uint8_t *mac_ie_nested_ie_short_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length);
|
||||||
|
|
||||||
|
/** Payload IE discover for spesific group ID */
|
||||||
|
uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, struct mac_payload_IE_s * payload_ie);
|
||||||
|
|
||||||
|
/** Nested IE element discover inside parsed payload element */
|
||||||
|
uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t * nested_ie);
|
||||||
|
|
||||||
|
/** Header IE elemnt discover */
|
||||||
|
uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, struct mac_header_IE_s * header_ie);
|
||||||
|
|
||||||
|
/** Header IE elemnt discover with sub id */
|
||||||
|
uint8_t mac_ie_header_sub_id_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie, uint8_t sub_id);
|
||||||
|
|
||||||
|
#endif /* MAC_IE_LIB_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "mPKe"
|
#define TRACE_GROUP "mPKe"
|
||||||
|
|
||||||
|
@ -171,12 +172,12 @@ static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class(uint8_t key_l
|
||||||
|
|
||||||
static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) {
|
static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) {
|
||||||
//Delete mle entries & Keys
|
//Delete mle entries & Keys
|
||||||
mle_neigh_table_entry_t *cur_entry;
|
mac_neighbor_table_entry_t *cur_entry;
|
||||||
mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table;
|
mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table;
|
||||||
for (uint8_t i = 0; i< main_list->key_table_size; i++) {
|
for (uint8_t i = 0; i< main_list->key_table_size; i++) {
|
||||||
cur_entry = mle_class_get_by_device_attribute_id(interface->id, cur->device_descriptor_attribute);
|
cur_entry = mac_neighbor_table_attribute_discover(mac_neighbor_info(interface), cur->device_descriptor_attribute);
|
||||||
if (cur_entry) {
|
if (cur_entry) {
|
||||||
mle_class_remove_entry(interface->id, cur_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), cur_entry);
|
||||||
}
|
}
|
||||||
mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute);
|
mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute);
|
||||||
}
|
}
|
||||||
|
@ -266,30 +267,31 @@ int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const ui
|
||||||
}
|
}
|
||||||
|
|
||||||
//Allocate mle entry
|
//Allocate mle entry
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, &new_entry_created);
|
mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, &new_entry_created);
|
||||||
if (!mle_entry) {
|
if (!mac_entry) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mle_entry->thread_commission = true;
|
|
||||||
mle_entry->short_adr = 0xffff;
|
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), mac_entry, true);
|
||||||
mle_entry->ttl = 20;
|
mac_entry->mac16 = 0xffff;
|
||||||
|
|
||||||
//Allocate key description
|
//Allocate key description
|
||||||
|
|
||||||
mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mle_entry->attribute_index);
|
mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mac_entry->index);
|
||||||
|
|
||||||
if (!key_desc) {
|
if (!key_desc) {
|
||||||
mle_class_remove_entry(interface_id, mle_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set device descriptor
|
mlme_device_descriptor_t device_desc;
|
||||||
mac_helper_devicetable_set(mle_entry, interface, 0, interface->mac_parameters->mac_default_key_index, new_entry_created);
|
mac_helper_device_description_write(interface, &device_desc, mac_entry->mac64, mac_entry->mac16,0, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, interface,mac_entry->index, interface->mac_parameters->mac_default_key_index, new_entry_created);
|
||||||
|
|
||||||
//set key descriptor
|
//set key descriptor
|
||||||
if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) {
|
if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) {
|
||||||
main_list->key_table_size--;
|
main_list->key_table_size--;
|
||||||
mle_class_remove_entry(interface_id, mle_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,23 +311,23 @@ int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8])
|
||||||
if (!main_list) {
|
if (!main_list) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//Get from mle
|
//Get from mac
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, NULL);
|
mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, NULL);
|
||||||
if (!mle_entry) {
|
if (!mac_entry) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//discover by mle entry attribute
|
//discover by mle entry attribute
|
||||||
uint8_t key_attribute;
|
uint8_t key_attribute;
|
||||||
|
|
||||||
if (!mac_pairwise_key_info_delete(main_list, mle_entry->attribute_index, &key_attribute)) {
|
if (!mac_pairwise_key_info_delete(main_list, mac_entry->index, &key_attribute)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//kill Entry & overwrite key
|
//kill Entry & overwrite key
|
||||||
mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute);
|
mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute);
|
||||||
|
|
||||||
mle_class_remove_entry(interface_id, mle_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -31,9 +31,9 @@
|
||||||
#include "mac_mcps.h"
|
#include "mac_mcps.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "6LoWPAN/MAC/mac_response_handler.h"
|
#include "6LoWPAN/MAC/mac_response_handler.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
static bool mac_data_is_broadcast_addr(const sockaddr_t *addr);
|
|
||||||
|
|
||||||
#define TRACE_GROUP "MRsH"
|
#define TRACE_GROUP "MRsH"
|
||||||
|
|
||||||
|
@ -49,15 +49,16 @@ static void mac_mlme_device_table_confirmation_handle(protocol_interface_info_en
|
||||||
|
|
||||||
if (confirmation->status == MLME_SUCCESS) {
|
if (confirmation->status == MLME_SUCCESS) {
|
||||||
//GET ME table by extended mac64 address
|
//GET ME table by extended mac64 address
|
||||||
mle_neigh_table_entry_t * entry = mle_class_get_by_link_address(info_entry->id, descpription->ExtAddress, ADDR_802_15_4_LONG);
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(info_entry), descpription->ExtAddress, ADDR_802_15_4_LONG);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->short_adr != descpription->ShortAddress) {
|
if (entry->mac16 != descpription->ShortAddress) {
|
||||||
//Refresh Short ADDRESS
|
//Refresh Short ADDRESS
|
||||||
mlme_set_t set_request;
|
mlme_set_t set_request;
|
||||||
descpription->ShortAddress = entry->short_adr;
|
descpription->ShortAddress = entry->mac16;
|
||||||
|
|
||||||
//CALL MLME-SET
|
//CALL MLME-SET
|
||||||
set_request.attr = macDeviceTable;
|
set_request.attr = macDeviceTable;
|
||||||
|
@ -107,62 +108,10 @@ void mcps_data_confirm_handler( const mac_api_t* api, const mcps_data_conf_t *da
|
||||||
lowpan_adaptation_interface_tx_confirm(info_entry, data);
|
lowpan_adaptation_interface_tx_confirm(info_entry, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mcps_data_indication_neighbor_validate(int8_t interface_id, const sockaddr_t *addr)
|
|
||||||
{
|
|
||||||
/* If MLE is enabled, we will talk if we have an MLE association */
|
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(interface_id, addr->address + 2, addr->addr_type);
|
|
||||||
if (mle_entry && (mle_entry->handshakeReady || mle_entry->thread_commission)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, we don't know them */
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void mcps_data_indication_handler( const mac_api_t* api, const mcps_data_ind_t *data_ind )
|
void mcps_data_indication_handler( const mac_api_t* api, const mcps_data_ind_t *data_ind )
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *info_entry = protocol_stack_interface_info_get_by_id(api->parent_id);
|
protocol_interface_info_entry_t *info_entry = protocol_stack_interface_info_get_by_id(api->parent_id);
|
||||||
buffer_t *buf = buffer_get(data_ind->msduLength);
|
lowpan_adaptation_interface_data_ind(info_entry, data_ind);
|
||||||
if (!buf || !info_entry) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint8_t *ptr;
|
|
||||||
buffer_data_add(buf, data_ind->msdu_ptr, data_ind->msduLength);
|
|
||||||
//tr_debug("MAC Paylod size %u %s",data_ind->msduLength, trace_array(data_ind->msdu_ptr, 8));
|
|
||||||
buf->options.lqi = data_ind->mpduLinkQuality;
|
|
||||||
buf->options.dbm = data_ind->signal_dbm;
|
|
||||||
buf->src_sa.addr_type = (addrtype_t)data_ind->SrcAddrMode;
|
|
||||||
ptr = common_write_16_bit(data_ind->SrcPANId, buf->src_sa.address);
|
|
||||||
memcpy(ptr, data_ind->SrcAddr, 8);
|
|
||||||
buf->dst_sa.addr_type = (addrtype_t)data_ind->DstAddrMode;
|
|
||||||
ptr = common_write_16_bit(data_ind->DstPANId, buf->dst_sa.address);
|
|
||||||
memcpy(ptr, data_ind->DstAddr, 8);
|
|
||||||
//Set Link spesific stuff to seperately
|
|
||||||
buf->link_specific.ieee802_15_4.srcPanId = data_ind->SrcPANId;
|
|
||||||
buf->link_specific.ieee802_15_4.dstPanId = data_ind->DstPANId;
|
|
||||||
|
|
||||||
if (mac_data_is_broadcast_addr(&buf->dst_sa)) {
|
|
||||||
buf->options.ll_broadcast_rx = true;
|
|
||||||
}
|
|
||||||
buf->interface = info_entry;
|
|
||||||
if (data_ind->Key.SecurityLevel) {
|
|
||||||
buf->link_specific.ieee802_15_4.fc_security = true;
|
|
||||||
|
|
||||||
if (info_entry->mac_security_key_usage_update_cb) {
|
|
||||||
info_entry->mac_security_key_usage_update_cb(info_entry, &data_ind->Key);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buf->link_specific.ieee802_15_4.fc_security = false;
|
|
||||||
if (mac_helper_default_security_level_get(info_entry) ||
|
|
||||||
!mcps_data_indication_neighbor_validate(info_entry->id, &buf->src_sa)) {
|
|
||||||
//SET By Pass
|
|
||||||
buf->options.ll_security_bypass_rx = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf->info = (buffer_info_t)(B_TO_IPV6_TXRX | B_FROM_MAC | B_DIR_UP);
|
|
||||||
protocol_push(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcps_purge_confirm_handler( const mac_api_t* api, mcps_purge_conf_t *data )
|
void mcps_purge_confirm_handler( const mac_api_t* api, mcps_purge_conf_t *data )
|
||||||
|
@ -306,9 +255,3 @@ void mlme_indication_handler( const mac_api_t* api, mlme_primitive id, const voi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mac_data_is_broadcast_addr(const sockaddr_t *addr)
|
|
||||||
{
|
|
||||||
return (addr->addr_type == ADDR_802_15_4_SHORT) &&
|
|
||||||
(addr->address[2] == 0xFF && addr->address[3] == 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MPX_API_H_
|
||||||
|
#define MPX_API_H_
|
||||||
|
|
||||||
|
struct mcps_data_req_s;
|
||||||
|
struct mcps_data_conf_s;
|
||||||
|
struct mcps_data_ind_s;
|
||||||
|
struct mcps_purge_s;
|
||||||
|
|
||||||
|
typedef struct mpx_api_s mpx_api_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mpx_data_request MPX_DATA request with user ID
|
||||||
|
* @param api API to handle the request
|
||||||
|
* @param data MCPS-DATA.request specific values
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void mpx_data_request(const mpx_api_t *api, const struct mcps_data_req_s *data, uint16_t user_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mpx_data_queue_clean clean MPX user data
|
||||||
|
* @param api API to handle the request
|
||||||
|
* @param purge MCPS-purge request
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mpx_data_confirm MPX-DATA confirm is called as a response to MPX-DATA request
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param data MCPS-DATA.confirm specific values
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*/
|
||||||
|
typedef void mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mpx_data_indication MPX-DATA confirm is called as a response to MPX-DATA request
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param data MCPS-DATA.indication specific values
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*/
|
||||||
|
typedef void mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mpx_header_size_get Function for request MPX user head room size
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*
|
||||||
|
* @return >0 Head room size in bytes
|
||||||
|
* @return 0 When Unknown User Id
|
||||||
|
*/
|
||||||
|
typedef uint16_t mpx_header_size_get(const mpx_api_t * api, uint16_t user_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief mpx_data_cb_register MPX-DATA confirm cb register by user
|
||||||
|
* @param api The API which handled the response
|
||||||
|
* @param confirm_cb MPX Data Confirm call back
|
||||||
|
* @param indication_cb MPX Data indication
|
||||||
|
* @param user_id MPX user ID
|
||||||
|
*
|
||||||
|
* @return 0 register OK
|
||||||
|
* @return -1 Unknown User ID
|
||||||
|
*/
|
||||||
|
typedef int8_t mpx_data_cb_register(const mpx_api_t* api, mpx_data_confirm *confirm_cb, mpx_data_indication *indication_cb, uint16_t user_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Struct mpx_api_s defines functions for MPX user for register call backs and send data.
|
||||||
|
*/
|
||||||
|
struct mpx_api_s {
|
||||||
|
mpx_data_request * mpx_data_request; /**< MPX data request. */
|
||||||
|
mpx_data_purge_request *mpx_data_purge; /**< MPX data Purge. */
|
||||||
|
mpx_header_size_get * mpx_headroom_size_get; /**< MPX headroom size get in bytes. */
|
||||||
|
mpx_data_cb_register * mpx_user_registration; /**< MPX User cb registration must be call before enable to send or RX data*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MPX_API_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -41,6 +41,8 @@
|
||||||
#include "BorderRouter/border_router.h"
|
#include "BorderRouter/border_router.h"
|
||||||
#include "Service_Libs/pan_blacklist/pan_blacklist_api.h"
|
#include "Service_Libs/pan_blacklist/pan_blacklist_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "loND"
|
#define TRACE_GROUP "loND"
|
||||||
|
|
||||||
|
@ -845,17 +847,18 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac
|
||||||
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
||||||
/* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */
|
/* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */
|
||||||
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, neigh->lifetime - 2, 0);
|
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, neigh->lifetime - 2, 0);
|
||||||
#ifndef NO_MLE
|
|
||||||
/* We need to know peer is a host before publishing - this needs MLE. Not yet established
|
/* We need to know peer is a host before publishing - this needs MLE. Not yet established
|
||||||
* what to do without MLE - might need special external/non-external prioritisation at root.
|
* what to do without MLE - might need special external/non-external prioritisation at root.
|
||||||
* This "publish for RFD" rule comes from ZigBee IP.
|
* This "publish for RFD" rule comes from ZigBee IP.
|
||||||
*/
|
*/
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur_interface->id, ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG);
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG);
|
||||||
if (mle_entry && ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV)) {
|
|
||||||
|
if (entry && !entry->ffd_device) {
|
||||||
rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime);
|
rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime);
|
||||||
}
|
}
|
||||||
protocol_6lowpan_neighbor_address_state_synch(cur_interface, aro->eui64, neigh->ip_address + 8);
|
protocol_6lowpan_neighbor_address_state_synch(cur_interface, aro->eui64, neigh->ip_address + 8);
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
/* Um, no - can't transmit response if we remove NCE now! */
|
/* Um, no - can't transmit response if we remove NCE now! */
|
||||||
//ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache, neigh);
|
//ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache, neigh);
|
||||||
|
@ -863,9 +866,7 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac
|
||||||
neigh->lifetime = 2;
|
neigh->lifetime = 2;
|
||||||
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
||||||
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, 4, 0);
|
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, 4, 0);
|
||||||
#ifndef NO_MLE
|
|
||||||
rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address);
|
rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,7 +968,13 @@ bool nd_ns_aro_handler(protocol_interface_info_entry_t *cur_interface, const uin
|
||||||
/* Set the LL address, ensure it's marked STALE */
|
/* Set the LL address, ensure it's marked STALE */
|
||||||
ipv6_neighbour_entry_update_unsolicited(&cur_interface->ipv6_neighbour_cache, neigh, ll_addr.addr_type, ll_addr.address);
|
ipv6_neighbour_entry_update_unsolicited(&cur_interface->ipv6_neighbour_cache, neigh, ll_addr.addr_type, ll_addr.address);
|
||||||
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
||||||
|
if (ws_info(cur_interface)) {
|
||||||
|
aro_out->status = ARO_SUCCESS;
|
||||||
|
aro_out->present = true;
|
||||||
|
// Todo: this might not be needed...
|
||||||
|
nd_update_registration(cur_interface, neigh, aro_out);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || nd_params.multihop_dad == false) {
|
if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || nd_params.multihop_dad == false) {
|
||||||
if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||||
whiteboard_entry_t *wb;
|
whiteboard_entry_t *wb;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -30,10 +30,23 @@
|
||||||
#ifndef THREAD_ADDRESS_REGISTRATION_CLIENT_H_
|
#ifndef THREAD_ADDRESS_REGISTRATION_CLIENT_H_
|
||||||
#define THREAD_ADDRESS_REGISTRATION_CLIENT_H_
|
#define THREAD_ADDRESS_REGISTRATION_CLIENT_H_
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_THREAD_V2
|
||||||
|
|
||||||
|
void thread_address_registration_init(void);
|
||||||
|
void thread_address_registration_deinit(void);
|
||||||
|
|
||||||
|
void thread_address_registration_timer_set(protocol_interface_info_entry_t *interface, uint16_t dua_delay_seconds, uint16_t mlr_refresh_seconds);
|
||||||
|
void thread_address_registration_timer(protocol_interface_info_entry_t *interface, uint16_t seconds);
|
||||||
|
#else
|
||||||
|
|
||||||
#define thread_address_registration_init(void)
|
#define thread_address_registration_init(void)
|
||||||
#define thread_address_registration_deinit(void)
|
#define thread_address_registration_deinit(void)
|
||||||
|
|
||||||
#define thread_address_registration_timer_set(interface, seconds);
|
#define thread_address_registration_timer_set(interface, dua_delay_seconds, mlr_refresh_seconds);
|
||||||
#define thread_address_registration_timer(interface, seconds);
|
#define thread_address_registration_timer(interface, seconds);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* THREAD_ADDRESS_REGISTRATION_CLIENT_H_ */
|
#endif /* THREAD_ADDRESS_REGISTRATION_CLIENT_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -943,7 +943,7 @@ void thread_bbr_seconds_timer(int8_t interface_id, uint32_t seconds)
|
||||||
#endif // HAVE_THREAD_ROUTER
|
#endif // HAVE_THREAD_ROUTER
|
||||||
|
|
||||||
#ifdef HAVE_THREAD_BORDER_ROUTER
|
#ifdef HAVE_THREAD_BORDER_ROUTER
|
||||||
static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16])
|
int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16])
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
|
@ -955,18 +955,18 @@ static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 1
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr) {
|
|
||||||
(void) mleid_ptr;
|
int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info)
|
||||||
|
{
|
||||||
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
|
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
|
||||||
if (!this || this->backbone_interface_id < 0) {
|
if (!this || this->backbone_interface_id < 0) {
|
||||||
tr_err("bbr not ready");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_HOST, info, 0, lifetime, 0);
|
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_HOST, info, 0, lifetime, 0);
|
||||||
// We are using route info field to store sequence number
|
// We are using route info field to store sequence number
|
||||||
if (!route) {
|
if (!route) {
|
||||||
// Direct route to host allows ND proxying to work
|
// Direct route to host allows ND proxying to work
|
||||||
tr_err("out of resources");
|
tr_err("bbr out of resources");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
// send NA
|
// send NA
|
||||||
|
@ -975,14 +975,44 @@ int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) {
|
int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr)
|
||||||
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL);
|
{
|
||||||
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST ) {
|
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
|
||||||
//Not found
|
if (!this || this->backbone_interface_id < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//TODO get information to route to parameters eq mleid, timeout
|
thread_pbbr_dua_info_t *map = ns_dyn_mem_alloc(sizeof(thread_pbbr_dua_info_t));
|
||||||
|
if (!map) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memcpy(map->mleid_ptr, mleid_ptr, 8);
|
||||||
|
map->last_contact_time = protocol_core_monotonic_time;
|
||||||
|
|
||||||
|
// We are using route info field to store BBR MLEID map
|
||||||
|
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_DUA_HOST, map, 0, lifetime, 0);
|
||||||
|
if (!route) {
|
||||||
|
// Direct route to host allows ND proxying to work
|
||||||
|
ns_dyn_mem_free(map);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
// Route info autofreed
|
||||||
|
route->info_autofree = true;
|
||||||
|
// send NA
|
||||||
|
thread_bbr_na_send(this->backbone_interface_id, addr_data_ptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
error:
|
||||||
|
tr_err("out of resources");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) {
|
||||||
|
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL);
|
||||||
|
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_DUA_HOST ) {
|
||||||
|
//Not found
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_bbr_proxy_state_update(int8_t caller_interface_id , int8_t handler_interface_id, bool status)
|
int thread_bbr_proxy_state_update(int8_t caller_interface_id , int8_t handler_interface_id, bool status)
|
||||||
|
@ -1090,6 +1120,17 @@ return 0;
|
||||||
#endif // HAVE_THREAD_BORDER_ROUTER
|
#endif // HAVE_THREAD_BORDER_ROUTER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) prefix;
|
||||||
|
#ifdef HAVE_THREAD_BORDER_ROUTER
|
||||||
|
return thread_extension_bbr_prefix_set(interface_id, prefix);
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif // HAVE_THREAD_BORDER_ROUTER
|
||||||
|
}
|
||||||
|
|
||||||
int thread_bbr_validation_interface_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port)
|
int thread_bbr_validation_interface_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port)
|
||||||
{
|
{
|
||||||
(void) interface_id;
|
(void) interface_id;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -36,6 +36,8 @@
|
||||||
|
|
||||||
#include "net_interface.h"
|
#include "net_interface.h"
|
||||||
#ifdef HAVE_THREAD_ROUTER
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
|
struct ipv6_route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize Thread Commissioner relay for BBR and Routers
|
* \brief Initialize Thread Commissioner relay for BBR and Routers
|
||||||
*
|
*
|
||||||
|
@ -98,23 +100,39 @@ void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur)
|
||||||
/**
|
/**
|
||||||
* \brief Add new nd entry to bbr
|
* \brief Add new nd entry to bbr
|
||||||
*
|
*
|
||||||
* \param interface_id addr_data_ptr lifetime info mleid_ptr
|
* \param interface_id addr_data_ptr lifetime info
|
||||||
*/
|
*/
|
||||||
int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr);
|
int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Find if bbr has nd entry
|
* \brief Add new dua entry to bbr
|
||||||
|
*
|
||||||
|
* \param interface_id addr_data_ptr lifetime info mleid_ptr
|
||||||
|
*/
|
||||||
|
int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send na
|
||||||
|
*
|
||||||
|
* \param interface_id addr_data_ptr lifetime info mleid_ptr
|
||||||
|
*/
|
||||||
|
int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Find if bbr has dua entry
|
||||||
*
|
*
|
||||||
* \param interface_id addr_data_ptr
|
* \param interface_id addr_data_ptr
|
||||||
*/
|
*/
|
||||||
int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr);
|
struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define thread_bbr_proxy_state_update(caller_interface_id , handler_interface_id, status) (NULL)
|
#define thread_bbr_proxy_state_update(caller_interface_id , handler_interface_id, status) (NULL)
|
||||||
#define thread_bbr_routing_enabled(cur) false
|
#define thread_bbr_routing_enabled(cur) false
|
||||||
#define thread_bbr_network_data_update_notify(cur)
|
#define thread_bbr_network_data_update_notify(cur)
|
||||||
#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info, mleid_ptr) (0)
|
#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info) (0)
|
||||||
#define thread_bbr_nd_entry_find(interface_id, addr_data_ptr) (0)
|
#define thread_bbr_dua_entry_add(interface_id, addr_data_ptr, lifetime, mleid_ptr) (0)
|
||||||
|
#define thread_bbr_dua_entry_find(interface_id, addr_data_ptr) (NULL)
|
||||||
|
#define thread_bbr_na_send(interface_id, target) (0)
|
||||||
#endif //HAVE_THREAD_BORDER_ROUTER
|
#endif //HAVE_THREAD_BORDER_ROUTER
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -59,6 +59,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_server.h"
|
#include "6LoWPAN/Thread/thread_management_server.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_synch.h"
|
#include "6LoWPAN/Thread/thread_network_synch.h"
|
||||||
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
||||||
|
@ -90,9 +91,14 @@
|
||||||
#include "thread_meshcop_lib.h"
|
#include "thread_meshcop_lib.h"
|
||||||
#include "multicast_api.h"
|
#include "multicast_api.h"
|
||||||
#include "mlme.h"
|
#include "mlme.h"
|
||||||
|
#include "Service_Libs/etx/etx.h"
|
||||||
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
||||||
#include "Service_Libs/blacklist/blacklist.h"
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
|
#include "Service_Libs/mle_service/mle_service_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
#include "platform/topo_trace.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "thbs"
|
#define TRACE_GROUP "thbs"
|
||||||
|
|
||||||
|
@ -111,27 +117,46 @@ static void thread_bootstrap_generate_leader_and_link(protocol_interface_info_en
|
||||||
static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_state_type_e state);
|
static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_state_type_e state);
|
||||||
static void thread_bootsrap_network_discovery_failure(int8_t interface_id);
|
static void thread_bootsrap_network_discovery_failure(int8_t interface_id);
|
||||||
|
|
||||||
static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur);
|
static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
|
||||||
static void thread_bootsrap_network_join_start(struct protocol_interface_info_entry *cur_interface, discovery_response_list_t *nwk_info);
|
static void thread_bootsrap_network_join_start(struct protocol_interface_info_entry *cur_interface, discovery_response_list_t *nwk_info);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool thread_interface_is_active(int8_t interface_id) {
|
static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
{
|
||||||
if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
|
protocol_interface_info_entry_t *cur = user_data;
|
||||||
|
lowpan_adaptation_remove_free_indirect_table(cur, entry_ptr);
|
||||||
|
|
||||||
|
thread_reset_neighbour_info(cur, entry_ptr);
|
||||||
|
//Removes ETX neighbor
|
||||||
|
etx_neighbor_remove(cur->id, entry_ptr->index);
|
||||||
|
//Remove MLE frame counter info
|
||||||
|
mle_service_frame_counter_entry_delete(cur->id, entry_ptr->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool thread_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Sleepy host
|
||||||
|
protocol_interface_info_entry_t *cur_interface = user_data;
|
||||||
|
|
||||||
|
if (thread_am_router(cur_interface)) {
|
||||||
|
return false; //Never do Keep alive with any one
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
|
return false; //Do not never challenge than priority parent
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
|
||||||
|
return false; //Sleepy end device should not never challenge
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return thread_host_bootstrap_child_update(cur_interface, entry_ptr->mac64);
|
||||||
}
|
|
||||||
|
|
||||||
static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur)
|
|
||||||
{
|
|
||||||
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
if (!cur_interface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
thread_reset_neighbour_info(cur_interface, cur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t thread_mle_class_init(int8_t interface_id)
|
int8_t thread_mle_class_init(int8_t interface_id)
|
||||||
|
@ -151,11 +176,29 @@ int8_t thread_mle_class_init(int8_t interface_id)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_class_init(interface_id, buffer.device_decription_table_size - 1, &thread_neighbor_remove, &thread_host_bootstrap_child_update, &thread_interface_is_active) != 0) {
|
thread_neighbor_class_delete(&cur->thread_info->neighbor_class);
|
||||||
|
|
||||||
|
if (!thread_neighbor_class_create(&cur->thread_info->neighbor_class, buffer.device_decription_table_size - 1)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_class_router_challenge(interface_id, NULL);
|
if (!mac_neighbor_info(cur) ) {
|
||||||
|
mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size - 1, thread_neighbor_remove
|
||||||
|
, thread_neighbor_entry_nud_notify, cur);
|
||||||
|
if (!mac_neighbor_info(cur)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size - 1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size - 1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lowpan_adaptation_interface_etx_update_enable(cur->id);
|
||||||
|
|
||||||
//Defined well know neighbour for discovery
|
//Defined well know neighbour for discovery
|
||||||
|
|
||||||
|
@ -232,7 +275,7 @@ uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParen
|
||||||
return newLqi;
|
return newLqi;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp)
|
bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_temp)
|
||||||
{
|
{
|
||||||
if (entry_temp && thread_info(cur)->thread_endnode_parent) {
|
if (entry_temp && thread_info(cur)->thread_endnode_parent) {
|
||||||
if(memcmp(entry_temp->mac64, thread_info(cur)->thread_endnode_parent->mac64, 8) == 0) {
|
if(memcmp(entry_temp->mac64, thread_info(cur)->thread_endnode_parent->mac64, 8) == 0) {
|
||||||
|
@ -245,45 +288,31 @@ bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mle_ne
|
||||||
bool thread_bootstrap_request_network_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, uint16_t short_address)
|
bool thread_bootstrap_request_network_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, uint16_t short_address)
|
||||||
{
|
{
|
||||||
bool requestNetworkdata = false;
|
bool requestNetworkdata = false;
|
||||||
thread_leader_data_t *leadeInfo = thread_info(cur)->thread_leader_data;
|
thread_leader_data_t *leaderInfo = thread_info(cur)->thread_leader_data;
|
||||||
|
|
||||||
if (thread_info(cur)->thread_endnode_parent->shortAddress != short_address) {
|
if (thread_info(cur)->thread_endnode_parent->shortAddress != short_address) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) {
|
if (!thread_partition_match(cur, leaderData)) {
|
||||||
tr_debug("Learn new Network Data");
|
tr_debug("Learn new Network Data");
|
||||||
requestNetworkdata = true;
|
requestNetworkdata = true;
|
||||||
thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1;
|
thread_partition_info_update(cur, leaderData);
|
||||||
thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1;
|
|
||||||
}
|
}
|
||||||
else if (common_serial_number_greater_8(leaderData->dataVersion, leadeInfo->dataVersion)) {
|
else if (common_serial_number_greater_8(leaderData->dataVersion, leaderInfo->dataVersion)) {
|
||||||
requestNetworkdata = true;
|
requestNetworkdata = true;
|
||||||
|
|
||||||
} else if (common_serial_number_greater_8(leaderData->stableDataVersion, leadeInfo->stableDataVersion)) {
|
} else if (common_serial_number_greater_8(leaderData->stableDataVersion, leaderInfo->stableDataVersion)) {
|
||||||
requestNetworkdata = true;
|
requestNetworkdata = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version number is updated when new network data is learned to avoid synchronization problems
|
|
||||||
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId;
|
|
||||||
thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId;
|
|
||||||
if (requestNetworkdata) {
|
if (requestNetworkdata) {
|
||||||
thread_bootstrap_parent_network_data_request(cur, true);
|
thread_bootstrap_parent_network_data_request(cur, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thread_instance_id_matches(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
|
|
||||||
{
|
|
||||||
if (thread_info(cur)->thread_leader_data) {
|
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int thread_router_check_previous_partition_info(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv)
|
static int thread_router_check_previous_partition_info(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv)
|
||||||
{
|
{
|
||||||
if (!routeTlv || !routeTlv->dataPtr || !routeTlv->tlvLen || !leaderData) {
|
if (!routeTlv || !routeTlv->dataPtr || !routeTlv->tlvLen || !leaderData) {
|
||||||
|
@ -386,8 +415,7 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l
|
||||||
if (!thread_info(cur)->thread_leader_data) {
|
if (!thread_info(cur)->thread_leader_data) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) ||
|
if (!thread_partition_match(cur, leaderData)) {
|
||||||
(thread_info(cur)->thread_leader_data->weighting != leaderData->weighting)) {
|
|
||||||
uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv);
|
uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv);
|
||||||
//partition checks
|
//partition checks
|
||||||
return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv);
|
return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv);
|
||||||
|
@ -472,11 +500,9 @@ void thread_end_device_mode_set(protocol_interface_info_entry_t *cur, bool sleep
|
||||||
{
|
{
|
||||||
if (sleepy) {
|
if (sleepy) {
|
||||||
cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
|
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
|
||||||
} else {
|
} else {
|
||||||
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
|
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,9 +563,6 @@ void thread_set_link_local_address(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
static int thread_configuration_security_activate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration)
|
static int thread_configuration_security_activate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration)
|
||||||
{
|
{
|
||||||
uint8_t key_material[32];
|
|
||||||
uint8_t key_index;
|
|
||||||
|
|
||||||
tr_debug("MAC SET Security Mode");
|
tr_debug("MAC SET Security Mode");
|
||||||
|
|
||||||
if (!(cur->lowpan_info & INTERFACE_NWK_ACTIVE) || !(cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED)) {
|
if (!(cur->lowpan_info & INTERFACE_NWK_ACTIVE) || !(cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED)) {
|
||||||
|
@ -554,16 +577,11 @@ static int thread_configuration_security_activate(protocol_interface_info_entry_
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyValid = false;
|
cur->thread_info->masterSecretMaterial.historyKeyValid = false;
|
||||||
cur->thread_info->masterSecretMaterial.valid_Info = true;
|
cur->thread_info->masterSecretMaterial.valid_Info = true;
|
||||||
// Update the guard timer value
|
// Update the guard timer value
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, true);
|
thread_key_guard_timer_calculate(cur, linkConfiguration, true);
|
||||||
//Define KEY's
|
//Define KEY's
|
||||||
thread_key_get(linkConfiguration->master_key, key_material, linkConfiguration->key_sequence);
|
thread_security_prev_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
||||||
key_index = THREAD_KEY_INDEX(linkConfiguration->key_sequence);
|
thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
||||||
//Set Keys
|
thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
||||||
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
|
|
||||||
//Add Security to MLE service
|
|
||||||
mle_service_security_set_security_key(cur->id, key_material, key_index, true);
|
|
||||||
//Gen also Next Key
|
|
||||||
thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,9 +729,9 @@ int thread_configuration_mle_disable(protocol_interface_info_entry_t *cur)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_mle_service_register(int8_t interface_id, uint8_t *mac64 )
|
static int thread_mle_service_register(protocol_interface_info_entry_t *cur, uint8_t *mac64 )
|
||||||
{
|
{
|
||||||
if (mle_service_interface_register(interface_id,thread_mle_parent_discover_receive_cb, mac64,8) != 0) {
|
if (mle_service_interface_register(cur->id, cur, thread_mle_parent_discover_receive_cb, mac64,8) != 0) {
|
||||||
tr_error("Mle Service init Fail");
|
tr_error("Mle Service init Fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1052,7 +1070,7 @@ void thread_tasklet(arm_event_s *event)
|
||||||
case THREAD_CHILD_UPDATE:
|
case THREAD_CHILD_UPDATE:
|
||||||
tr_debug_extra("Thread SM THREAD_CHILD_UPDATE");
|
tr_debug_extra("Thread SM THREAD_CHILD_UPDATE");
|
||||||
if (thread_info(cur)->thread_endnode_parent) {
|
if (thread_info(cur)->thread_endnode_parent) {
|
||||||
thread_host_bootstrap_child_update(cur->id, cur->thread_info->thread_endnode_parent->mac64);
|
thread_host_bootstrap_child_update(cur, cur->thread_info->thread_endnode_parent->mac64);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case THREAD_ANNOUNCE_ACTIVE: {
|
case THREAD_ANNOUNCE_ACTIVE: {
|
||||||
|
@ -1166,12 +1184,12 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur)
|
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur)
|
||||||
{
|
{
|
||||||
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
|
|
||||||
ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) {
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) {
|
if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->mac16)) {
|
||||||
tr_debug("Free ID %x", cur_entry->short_adr);
|
tr_debug("Free ID %x", cur_entry->mac16);
|
||||||
mle_class_remove_entry(cur->id, cur_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), cur_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1454,9 +1472,7 @@ int thread_bootstrap_reset(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
neighbor_cache_flush(&cur->neigh_cache);
|
neighbor_cache_flush(&cur->neigh_cache);
|
||||||
thread_bootstrap_stop(cur);
|
thread_bootstrap_stop(cur);
|
||||||
#ifndef NO_MLE
|
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
|
||||||
mle_class_list_clean(cur->id);
|
|
||||||
#endif
|
|
||||||
cur->bootsrap_state_machine_cnt = 0;
|
cur->bootsrap_state_machine_cnt = 0;
|
||||||
mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params);
|
mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params);
|
||||||
//tr_debug( "--> idle");
|
//tr_debug( "--> idle");
|
||||||
|
@ -1600,6 +1616,7 @@ void thread_bootstrap_routing_activate(protocol_interface_info_entry_t *cur)
|
||||||
// FEDs and routers (REEDs) perform their own address resolution
|
// FEDs and routers (REEDs) perform their own address resolution
|
||||||
thread_nd_service_activate(cur->id);
|
thread_nd_service_activate(cur->id);
|
||||||
} else {
|
} else {
|
||||||
|
thread_nd_client_service_activate(cur->id);
|
||||||
thread_child_set_default_route(cur);
|
thread_child_set_default_route(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2177,7 +2194,7 @@ void thread_bootstrap_start_network_discovery(protocol_interface_info_entry_t *c
|
||||||
scan_request.channel_mask = cur->mac_parameters->nwk_scan_params.stack_chan_list.channel_mask[0];
|
scan_request.channel_mask = cur->mac_parameters->nwk_scan_params.stack_chan_list.channel_mask[0];
|
||||||
scan_request.filter_tlv_data = NULL;
|
scan_request.filter_tlv_data = NULL;
|
||||||
scan_request.filter_tlv_length = 0;
|
scan_request.filter_tlv_length = 0;
|
||||||
if (thread_discovery_network_scan(cur->id, &scan_request, discover_ready) != 0 ) {
|
if (thread_discovery_network_scan(cur, &scan_request, discover_ready) != 0 ) {
|
||||||
tr_error("Discovery scan start fail");
|
tr_error("Discovery scan start fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2198,7 +2215,7 @@ void thread_bootstrap_state_machine(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
//SET Link by Static configuration
|
//SET Link by Static configuration
|
||||||
tr_info("thread network attach start");
|
tr_info("thread network attach start");
|
||||||
if (thread_mle_service_register(cur->id,thread_joiner_application_random_mac_get(cur->id)) != 0 ||
|
if (thread_mle_service_register(cur,thread_joiner_application_random_mac_get(cur->id)) != 0 ||
|
||||||
thread_link_configuration_activate(cur, linkConfiguration) != 0) {
|
thread_link_configuration_activate(cur, linkConfiguration) != 0) {
|
||||||
tr_error("Network Bootsrap Start Fail");
|
tr_error("Network Bootsrap Start Fail");
|
||||||
bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, cur);
|
bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, cur);
|
||||||
|
@ -2257,6 +2274,7 @@ void thread_bootstrap_stop(protocol_interface_info_entry_t *cur)
|
||||||
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL);
|
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL);
|
||||||
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL);
|
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL);
|
||||||
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
|
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
|
||||||
|
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
|
||||||
thread_leader_service_leader_data_free(cur->thread_info);
|
thread_leader_service_leader_data_free(cur->thread_info);
|
||||||
thread_bootstrap_all_nodes_multicast_unregister(cur);
|
thread_bootstrap_all_nodes_multicast_unregister(cur);
|
||||||
thread_data_base_init(cur->thread_info, cur->id);
|
thread_data_base_init(cur->thread_info, cur->id);
|
||||||
|
@ -2672,7 +2690,7 @@ int thread_bootstrap_network_data_activate(protocol_interface_info_entry_t *cur)
|
||||||
thread_router_bootstrap_anycast_address_register(cur);
|
thread_router_bootstrap_anycast_address_register(cur);
|
||||||
// Update joiner router status
|
// Update joiner router status
|
||||||
thread_management_server_joiner_router_init(cur->id);
|
thread_management_server_joiner_router_init(cur->id);
|
||||||
thread_extension_joiner_router_init(cur->id);
|
thread_extension_service_init(cur);
|
||||||
|
|
||||||
// Update border router relay
|
// Update border router relay
|
||||||
thread_bbr_commissioner_proxy_service_update(cur->id);
|
thread_bbr_commissioner_proxy_service_update(cur->id);
|
||||||
|
@ -2870,8 +2888,7 @@ void thread_bootstrap_clear_neighbor_entries(protocol_interface_info_entry_t *cu
|
||||||
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour);
|
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
|
||||||
mle_class_list_clean(cur->id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t *cur)
|
void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t *cur)
|
||||||
|
@ -2883,10 +2900,10 @@ void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t
|
||||||
|
|
||||||
if (thread_i_am_router(cur)) {
|
if (thread_i_am_router(cur)) {
|
||||||
/* Store information of our children to the dynamic storage */
|
/* Store information of our children to the dynamic storage */
|
||||||
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
ns_list_foreach_safe(mle_neigh_table_entry_t, entry, neig_list) {
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, entry, mac_table_list) {
|
||||||
if (thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->short_adr)) {
|
if (thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16)) {
|
||||||
thread_dynamic_storage_child_info_store(cur->id, entry);
|
thread_dynamic_storage_child_info_store(cur, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2910,7 +2927,7 @@ bool thread_bootstrap_link_create_check(protocol_interface_info_entry_t *interfa
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mle_class_free_entry_count_get(interface->id) < 1) {
|
if(mle_class_free_entry_count_get(interface) < 1) {
|
||||||
// We dont have room for any new links
|
// We dont have room for any new links
|
||||||
tr_warn("Link ignore no room for addr:%x", short_address);
|
tr_warn("Link ignore no room for addr:%x", short_address);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2928,7 +2945,7 @@ bool thread_bootstrap_link_create_check(protocol_interface_info_entry_t *interfa
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_class_active_neigh_counter(interface->id) < THREAD_REED_AND_END_DEVICE_NEIGHBOR_LINKS + 1) {
|
if (mle_class_active_neigh_counter(interface) < THREAD_REED_AND_END_DEVICE_NEIGHBOR_LINKS + 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -52,7 +52,7 @@ struct thread_info_s;
|
||||||
struct protocol_interface_info_entry;
|
struct protocol_interface_info_entry;
|
||||||
struct thread_leader_data_s;
|
struct thread_leader_data_s;
|
||||||
struct link_configuration;
|
struct link_configuration;
|
||||||
struct mle_neigh_table_entry_t;
|
struct mac_neighbor_table_entry;
|
||||||
struct mle_tlv_info_s;
|
struct mle_tlv_info_s;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -103,12 +103,11 @@ uint8_t thread_mode_get_by_interface_ptr(struct protocol_interface_info_entry *c
|
||||||
void thread_bootstrap_device_synch_finish(protocol_interface_info_entry_t *cur);
|
void thread_bootstrap_device_synch_finish(protocol_interface_info_entry_t *cur);
|
||||||
int8_t thread_mle_class_init(int8_t interface_id);
|
int8_t thread_mle_class_init(int8_t interface_id);
|
||||||
void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers);
|
void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers);
|
||||||
int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child);
|
|
||||||
void thread_bootstrap_ready(struct protocol_interface_info_entry *cur);
|
void thread_bootstrap_ready(struct protocol_interface_info_entry *cur);
|
||||||
int thread_bootstrap_reset(struct protocol_interface_info_entry *cur);
|
int thread_bootstrap_reset(struct protocol_interface_info_entry *cur);
|
||||||
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur);
|
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur);
|
||||||
bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address);
|
bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address);
|
||||||
bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp);
|
bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mac_neighbor_table_entry *entry_temp);
|
||||||
void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur);
|
void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur);
|
||||||
int8_t thread_bootsrap_event_trig(thread_bootsrap_event_type_e event_type, int8_t Id, arm_library_event_priority_e priority);
|
int8_t thread_bootsrap_event_trig(thread_bootsrap_event_type_e event_type, int8_t Id, arm_library_event_priority_e priority);
|
||||||
void thread_interface_init(struct protocol_interface_info_entry *cur);
|
void thread_interface_init(struct protocol_interface_info_entry *cur);
|
||||||
|
@ -126,7 +125,6 @@ int thread_parent_discover_start(int8_t interface_id, uint8_t *mac64 );
|
||||||
|
|
||||||
bool thread_device_synch_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
|
bool thread_device_synch_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
|
||||||
bool thread_link_request_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
|
bool thread_link_request_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
|
||||||
bool thread_instance_id_matches(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData);
|
|
||||||
int thread_leader_data_validation(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, struct mle_tlv_info_s *routeTlv);
|
int thread_leader_data_validation(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, struct mle_tlv_info_s *routeTlv);
|
||||||
uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParent);
|
uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParent);
|
||||||
uint8_t thread_compute_link_margin(int8_t rssi);
|
uint8_t thread_compute_link_margin(int8_t rssi);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -297,19 +297,19 @@ static bool thread_border_router_local_network_data_prefix_match(thread_network_
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_border_router_child_network_data_clean(uint8_t interface_id, uint16_t child_id)
|
static void thread_border_router_child_network_data_clean(protocol_interface_info_entry_t *cur, uint16_t child_id)
|
||||||
{
|
{
|
||||||
uint8_t addr16_buf[2];
|
uint8_t addr16_buf[2];
|
||||||
|
|
||||||
common_write_16_bit(child_id, addr16_buf);
|
common_write_16_bit(child_id, addr16_buf);
|
||||||
if (mle_class_get_by_link_address(interface_id, addr16_buf, ADDR_802_15_4_SHORT)) {
|
if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr16_buf, ADDR_802_15_4_SHORT)) {
|
||||||
/* Child is available in mle, do nothing */
|
/* Child is available in mle, do nothing */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child is not our child => network data contains data from lost children, remove it
|
// Child is not our child => network data contains data from lost children, remove it
|
||||||
tr_debug("Remove nwk data from lost child: %04x", child_id);
|
tr_debug("Remove nwk data from lost child: %04x", child_id);
|
||||||
thread_management_client_network_data_unregister(interface_id, child_id);
|
thread_management_client_network_data_unregister(cur->id, child_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr)
|
static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr)
|
||||||
|
@ -326,7 +326,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf
|
||||||
ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) {
|
ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) {
|
||||||
if (thread_addr_is_child(router_short_addr, curRoute->routerID)) {
|
if (thread_addr_is_child(router_short_addr, curRoute->routerID)) {
|
||||||
// Router children found
|
// Router children found
|
||||||
thread_border_router_child_network_data_clean(cur->id, curRoute->routerID);
|
thread_border_router_child_network_data_clean(cur, curRoute->routerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf
|
||||||
ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) {
|
ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) {
|
||||||
if (thread_addr_is_child(router_short_addr, curBR->routerID)) {
|
if (thread_addr_is_child(router_short_addr, curBR->routerID)) {
|
||||||
// Router children found
|
// Router children found
|
||||||
thread_border_router_child_network_data_clean(cur->id, curBR->routerID);
|
thread_border_router_child_network_data_clean(cur, curBR->routerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf
|
||||||
ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) {
|
ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) {
|
||||||
if (thread_addr_is_child(router_short_addr, server->router_id)) {
|
if (thread_addr_is_child(router_short_addr, server->router_id)) {
|
||||||
// Router children found
|
// Router children found
|
||||||
thread_border_router_child_network_data_clean(cur->id, server->router_id);
|
thread_border_router_child_network_data_clean(cur, server->router_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,6 +626,7 @@ int thread_border_router_prefix_add(int8_t interface_id, uint8_t *prefix_ptr, ui
|
||||||
service.stableData = prefix_info_ptr->stableData;
|
service.stableData = prefix_info_ptr->stableData;
|
||||||
service.P_on_mesh = prefix_info_ptr->P_on_mesh;
|
service.P_on_mesh = prefix_info_ptr->P_on_mesh;
|
||||||
service.P_nd_dns = prefix_info_ptr->P_nd_dns;
|
service.P_nd_dns = prefix_info_ptr->P_nd_dns;
|
||||||
|
service.P_res1 = prefix_info_ptr->P_res1;
|
||||||
|
|
||||||
return thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service);
|
return thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2015, 2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2015, 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -64,6 +64,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_address_registration_client.h"
|
#include "6LoWPAN/Thread/thread_address_registration_client.h"
|
||||||
#include "6LoWPAN/Thread/thread_resolution_client.h"
|
#include "6LoWPAN/Thread/thread_resolution_client.h"
|
||||||
#include <6LoWPAN/Thread/thread_extension_bootstrap.h>
|
#include <6LoWPAN/Thread/thread_extension_bootstrap.h>
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "Service_Libs/mle_service/mle_service_security.h"
|
#include "Service_Libs/mle_service/mle_service_security.h"
|
||||||
#include "Service_Libs/blacklist/blacklist.h"
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
|
@ -79,6 +80,7 @@
|
||||||
#include "MLE/mle_tlv.h"
|
#include "MLE/mle_tlv.h"
|
||||||
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
#include "Service_Libs/nd_proxy/nd_proxy.h"
|
||||||
#include "Service_Libs/mle_service/mle_service_api.h"
|
#include "Service_Libs/mle_service/mle_service_api.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
@ -104,7 +106,7 @@ thread_leader_data_t *thread_leader_data_generate(void);
|
||||||
thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info);
|
thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info);
|
||||||
static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr);
|
static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr);
|
||||||
static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr);
|
static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr);
|
||||||
static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, mle_neigh_table_entry_t *neighbor);
|
static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index);
|
||||||
static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason);
|
static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason);
|
||||||
|
|
||||||
/* Helper functions*/
|
/* Helper functions*/
|
||||||
|
@ -152,33 +154,37 @@ uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
//tr_debug("MLE key request by sequence id %"PRIu8" seq %"PRIu32, keyId, keySequnce);
|
||||||
|
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (cur && cur->thread_info) {
|
if (!cur || !cur->thread_info) {
|
||||||
if (cur->thread_info->masterSecretMaterial.valid_Info) {
|
return NULL;
|
||||||
if (keySequnce == linkConfiguration->key_sequence) {
|
}
|
||||||
if (mle_service_security_default_key_id_get(interface_id) == keyId) {
|
if (!cur->thread_info->masterSecretMaterial.valid_Info) {
|
||||||
keyPtr = mle_service_security_default_key_get(interface_id);
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (keySequnce == (linkConfiguration->key_sequence + 1)) {
|
if (keySequnce == linkConfiguration->key_sequence) {
|
||||||
if (mle_service_security_next_key_id_get(interface_id) == keyId) {
|
if (mle_service_security_default_key_id_get(interface_id) == keyId) {
|
||||||
keyPtr = mle_service_security_next_key_get(interface_id);
|
keyPtr = mle_service_security_default_key_get(interface_id);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!keyPtr) {
|
|
||||||
tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce);
|
|
||||||
thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce);
|
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyId = keyId;
|
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyValid = false;
|
|
||||||
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (keySequnce == (linkConfiguration->key_sequence + 1)) {
|
||||||
|
if (mle_service_security_next_key_id_get(interface_id) == keyId) {
|
||||||
|
keyPtr = mle_service_security_next_key_get(interface_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!keyPtr) {
|
||||||
|
tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce);
|
||||||
|
thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce);
|
||||||
|
cur->thread_info->masterSecretMaterial.historyKeyId = keyId;
|
||||||
|
cur->thread_info->masterSecretMaterial.historyKeyValid = false;
|
||||||
|
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
|
||||||
}
|
}
|
||||||
return keyPtr;
|
return keyPtr;
|
||||||
}
|
}
|
||||||
uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId)
|
uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId)
|
||||||
{
|
{
|
||||||
|
(void)keyId;
|
||||||
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!interface) {
|
if (!interface) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -197,7 +203,7 @@ uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_securit
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MLE_SEC_UNKNOWN_KEY:
|
case MLE_SEC_UNKNOWN_KEY:
|
||||||
return thread_management_key_request(interface_id,keyId);
|
return NULL;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -360,23 +366,31 @@ bool thread_connectivity_tlv_parse(uint8_t *ptr, uint16_t dataLength, thread_con
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init)
|
void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init)
|
||||||
{
|
{
|
||||||
uint32_t key_rotation = linkConfiguration ? linkConfiguration->key_rotation : 0;
|
uint32_t key_rotation = linkConfiguration ? linkConfiguration->key_rotation : 0;
|
||||||
|
|
||||||
if (is_init && key_rotation < 3600) {
|
if (is_init && key_rotation < 1) {
|
||||||
tr_warn("Attempted to set key rotation time smaller than 1 hour.");
|
tr_warn("Attempted to set key rotation time smaller than 1 hour.");
|
||||||
key_rotation = 3600;
|
key_rotation = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->thread_info->masterSecretMaterial.keyRotation = key_rotation;
|
cur->thread_info->masterSecretMaterial.keyRotation = key_rotation * 3600; // setting value is hours converting to seconds
|
||||||
cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 0.93);
|
cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 3600 * 0.93);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_leader_data_t *thread_leader_data_generate(void)
|
thread_leader_data_t *thread_leader_data_generate(void)
|
||||||
{
|
{
|
||||||
thread_leader_data_t *leader_data;
|
thread_leader_data_t *leader_data;
|
||||||
leader_data = ns_dyn_mem_alloc(sizeof(thread_leader_data_t));
|
leader_data = ns_dyn_mem_alloc(sizeof(thread_leader_data_t));
|
||||||
|
if (leader_data) {
|
||||||
|
memset(leader_data,0,sizeof(thread_leader_data_t));
|
||||||
|
}
|
||||||
return leader_data;
|
return leader_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,16 +677,27 @@ thread_mcast_child_t *thread_child_mcast_entry_find(thread_mcast_children_list_t
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
||||||
|
{
|
||||||
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur),buf->dst_sa.address + 2 , buf->dst_sa.addr_type);
|
||||||
|
if (entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16)) {
|
||||||
|
|
||||||
|
/* Check if the child can handle only stable network data (e.g. sleepy device) */
|
||||||
|
return !(thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, entry->index));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
thread_mcast_child_t *thread_child_mcast_entry_get(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr, const uint8_t *mac64)
|
thread_mcast_child_t *thread_child_mcast_entry_get(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr, const uint8_t *mac64)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, mac64, ADDR_802_15_4_LONG);
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG);
|
||||||
|
|
||||||
if (!mle_entry) {
|
if (!entry) {
|
||||||
tr_error("No MLE entry.");
|
tr_error("No MLE entry.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_entry->mode & MLE_RX_ON_IDLE) {
|
if (entry->rx_on_idle) {
|
||||||
/* Not a sleepy child */
|
/* Not a sleepy child */
|
||||||
tr_debug("Not a sleepy child");
|
tr_debug("Not a sleepy child");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -791,8 +816,6 @@ int thread_init(protocol_interface_info_entry_t *cur)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_class_router_challenge(cur->id, NULL);
|
|
||||||
|
|
||||||
if (etx_accum_failures_callback_register(cur->nwk_id, cur->id, 1, thread_tx_failure_handler) != 1) {
|
if (etx_accum_failures_callback_register(cur->nwk_id, cur->id, 1, thread_tx_failure_handler) != 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -803,7 +826,6 @@ int thread_init(protocol_interface_info_entry_t *cur)
|
||||||
thread_data_base_init(cur->thread_info, cur->id);
|
thread_data_base_init(cur->thread_info, cur->id);
|
||||||
mac_helper_pib_boolean_set(cur,macThreadForceLongAddressForBeacon , true);
|
mac_helper_pib_boolean_set(cur,macThreadForceLongAddressForBeacon , true);
|
||||||
mac_helper_mac16_address_set(cur, 0xffff);
|
mac_helper_mac16_address_set(cur, 0xffff);
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,7 +839,7 @@ int thread_attach_ready(protocol_interface_info_entry_t *cur)
|
||||||
case THREAD_STATE_CONNECTED:
|
case THREAD_STATE_CONNECTED:
|
||||||
case THREAD_STATE_CONNECTED_ROUTER:
|
case THREAD_STATE_CONNECTED_ROUTER:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
/* break; */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -919,7 +941,7 @@ static void thread_key_switch_timer(protocol_interface_info_entry_t *cur, uint16
|
||||||
|
|
||||||
tr_debug("thrKeyRotation == 0: sync key material by %"PRIu32, linkConfiguration->key_sequence + 1);
|
tr_debug("thrKeyRotation == 0: sync key material by %"PRIu32, linkConfiguration->key_sequence + 1);
|
||||||
thread_management_key_sets_calc(cur, linkConfiguration, linkConfiguration->key_sequence + 1);
|
thread_management_key_sets_calc(cur, linkConfiguration, linkConfiguration->key_sequence + 1);
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, false);
|
thread_key_guard_timer_calculate(cur, linkConfiguration, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,14 +1041,15 @@ void thread_timer(protocol_interface_info_entry_t *cur, uint8_t ticks)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_i_am_router(cur)) {
|
if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) {
|
||||||
|
/* Own attach is ongoing, do not send advertisements */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread_i_am_router(cur)) {
|
||||||
if (thread_routing_timer(thread_info, ticks)) {
|
if (thread_routing_timer(thread_info, ticks)) {
|
||||||
thread_router_bootstrap_mle_advertise(cur);
|
thread_router_bootstrap_mle_advertise(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,14 +1144,20 @@ uint8_t thread_beacon_indication(uint8_t *ptr, uint8_t len, protocol_interface_i
|
||||||
|
|
||||||
static uint8_t *thread_linkquality_write(int8_t interface_id, uint8_t *buffer)
|
static uint8_t *thread_linkquality_write(int8_t interface_id, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
|
protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!interface_ptr && !interface_ptr->thread_info) {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t lqi1 = 0, lqi2 = 0, lqi3 = 0;
|
uint8_t lqi1 = 0, lqi2 = 0, lqi3 = 0;
|
||||||
thread_link_quality_e thread_link_quality;
|
thread_link_quality_e thread_link_quality;
|
||||||
mle_neigh_table_list_t *neigh_list = mle_class_active_list_get(interface_id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(interface_ptr)->neighbour_list;
|
||||||
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list) {
|
ns_list_foreach(mac_neighbor_table_entry_t, cur, mac_table_list) {
|
||||||
if (thread_is_router_addr(cur->short_adr)) {
|
if (thread_is_router_addr(cur->mac16)) {
|
||||||
// Only count routers to link quality
|
// Only count routers to link quality
|
||||||
thread_link_quality = thread_link_margin_to_quality(cur->link_margin);
|
uint16_t link_margin = thread_neighbor_entry_linkmargin_get(&interface_ptr->thread_info->neighbor_class, cur->index);
|
||||||
|
thread_link_quality = thread_link_margin_to_quality(link_margin);
|
||||||
switch (thread_link_quality) {
|
switch (thread_link_quality) {
|
||||||
case QUALITY_20dB:
|
case QUALITY_20dB:
|
||||||
lqi3++;
|
lqi3++;
|
||||||
|
@ -1193,14 +1222,14 @@ uint8_t *thread_connectivity_tlv_write(uint8_t *ptr, protocol_interface_info_ent
|
||||||
*ptr++ = 10;
|
*ptr++ = 10;
|
||||||
|
|
||||||
// determine parent priority
|
// determine parent priority
|
||||||
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur->id) > 2*THREAD_MAX_MTD_CHILDREN)) {
|
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur) > 2*THREAD_MAX_MTD_CHILDREN)) {
|
||||||
*ptr++ = CONNECTIVITY_PP_LOW;
|
*ptr++ = CONNECTIVITY_PP_LOW;
|
||||||
} else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur->id) > 2*THREAD_MAX_SED_CHILDREN)) {
|
} else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur) > 2*THREAD_MAX_SED_CHILDREN)) {
|
||||||
*ptr++ = CONNECTIVITY_PP_LOW;
|
*ptr++ = CONNECTIVITY_PP_LOW;
|
||||||
} else if (3*thread_router_bootstrap_child_count_get(cur) > 2*thread->maxChildCount) {
|
} else if (3*thread_router_bootstrap_child_count_get(cur) > 2*thread->maxChildCount) {
|
||||||
// 1/3 of the child capacity remaining, PP=low
|
// 1/3 of the child capacity remaining, PP=low
|
||||||
*ptr++ = CONNECTIVITY_PP_LOW;
|
*ptr++ = CONNECTIVITY_PP_LOW;
|
||||||
} else if (mle_class_free_entry_count_get(cur->id) < THREAD_FREE_MLE_ENTRY_THRESHOLD) {
|
} else if (mle_class_free_entry_count_get(cur) < THREAD_FREE_MLE_ENTRY_THRESHOLD) {
|
||||||
// If only few entries available in the MLE table, change priority to low
|
// If only few entries available in the MLE table, change priority to low
|
||||||
*ptr++ = CONNECTIVITY_PP_LOW;
|
*ptr++ = CONNECTIVITY_PP_LOW;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1829,7 +1858,7 @@ static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr)
|
||||||
return common_write_16_bit(port, ptr);
|
return common_write_16_bit(port, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, mle_neigh_table_entry_t *neighbor)
|
static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id);
|
||||||
|
|
||||||
|
@ -1839,27 +1868,33 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_attribute_discover(mac_neighbor_info(cur), attribute_index);
|
||||||
|
if (!neighbor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
|
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
|
||||||
mle_class_remove_entry(cur->id, neighbor);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when MLE link to neighbour lost, or ETX callback says link is bad */
|
/* Called when MLE link to neighbour lost, or ETX callback says link is bad */
|
||||||
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour)
|
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbour)
|
||||||
{
|
{
|
||||||
thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent;
|
thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent;
|
||||||
|
|
||||||
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) {
|
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->mac16) {
|
||||||
if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
|
if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
|
||||||
tr_warn("End device lost parent, reset!\n");
|
tr_warn("End device lost parent, reset!\n");
|
||||||
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_routing_remove_link(cur, neighbour->short_adr);
|
thread_routing_remove_link(cur, neighbour->mac16);
|
||||||
thread_router_bootstrap_reset_child_info(cur, neighbour);
|
thread_router_bootstrap_reset_child_info(cur, neighbour);
|
||||||
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64);
|
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64);
|
||||||
mac_helper_devicetable_remove(cur->mac_api, neighbour->attribute_index);
|
mac_helper_devicetable_remove(cur->mac_api, neighbour->index);
|
||||||
|
thread_neighbor_class_entry_remove(&cur->thread_info->neighbor_class, neighbour->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv)
|
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv)
|
||||||
|
@ -1894,7 +1929,7 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry
|
||||||
} else {
|
} else {
|
||||||
if (reason == ADDR_CALLBACK_DAD_COMPLETE) {
|
if (reason == ADDR_CALLBACK_DAD_COMPLETE) {
|
||||||
/* Send address notification (our parent doesn't do that for us) */
|
/* Send address notification (our parent doesn't do that for us) */
|
||||||
thread_extension_address_registration(interface, addr->address, NULL);
|
thread_extension_address_registration(interface, addr->address, NULL, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1902,9 +1937,6 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry
|
||||||
|
|
||||||
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, if_group_entry_t *group, bool addr_added)
|
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, if_group_entry_t *group, bool addr_added)
|
||||||
{
|
{
|
||||||
(void) addr_added;
|
|
||||||
|
|
||||||
group->mld_timer = 0;
|
|
||||||
|
|
||||||
if (thread_attach_ready(interface) != 0) {
|
if (thread_attach_ready(interface) != 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -1918,11 +1950,13 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface,
|
||||||
interface->thread_info->childUpdateReqTimer = 1;
|
interface->thread_info->childUpdateReqTimer = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
thread_extension_mcast_subscrition_change(interface, group, addr_added);
|
if (addr_added) {
|
||||||
|
thread_address_registration_timer_set(interface, 0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur)
|
void thread_partition_data_purge(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
/* Partition has been changed. Wipe out data related to old partition */
|
/* Partition has been changed. Wipe out data related to old partition */
|
||||||
thread_management_client_pending_coap_request_kill(cur->id);
|
thread_management_client_pending_coap_request_kill(cur->id);
|
||||||
|
@ -1935,5 +1969,33 @@ void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
|
||||||
|
{
|
||||||
|
if (thread_info(cur)->thread_leader_data) {
|
||||||
|
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) &&
|
||||||
|
(thread_info(cur)->thread_leader_data->weighting == leaderData->weighting)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
|
||||||
|
{
|
||||||
|
/* Force network data update later when processing network data TLV */
|
||||||
|
thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1;
|
||||||
|
thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1;
|
||||||
|
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId;
|
||||||
|
thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId;
|
||||||
|
thread_info(cur)->thread_leader_data->weighting = leaderData->weighting;
|
||||||
|
/* New network data learned, get rid of old partition data */
|
||||||
|
thread_partition_data_purge(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index)
|
||||||
|
{
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -40,6 +40,8 @@
|
||||||
#include "eventOS_event_timer.h"
|
#include "eventOS_event_timer.h"
|
||||||
#include "MLE/mle_tlv.h"
|
#include "MLE/mle_tlv.h"
|
||||||
|
|
||||||
|
struct mac_neighbor_table_entry;
|
||||||
|
|
||||||
#define MAX_MLE_CHALLENGE_LENGTH 32
|
#define MAX_MLE_CHALLENGE_LENGTH 32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,8 +57,8 @@
|
||||||
#define NETWORK_ID_TIMEOUT 120 //seconds
|
#define NETWORK_ID_TIMEOUT 120 //seconds
|
||||||
|
|
||||||
// Values when adverticements are made faster when leader connection is restored
|
// Values when adverticements are made faster when leader connection is restored
|
||||||
#define NETWORK_ID_SPEEDUP 60 //seconds
|
#define NETWORK_ID_SPEEDUP 55 //seconds
|
||||||
#define NETWORK_ID_SPEEDUP_MAX 100 //seconds
|
#define NETWORK_ID_SPEEDUP_MAX 80 //seconds
|
||||||
|
|
||||||
#define DHCPV6_ENTERPRISE_THREAD 0x0000AFAA
|
#define DHCPV6_ENTERPRISE_THREAD 0x0000AFAA
|
||||||
#define DHCPV6_OPTION_VENDOR_SPESIFIC_INFO_LEN 0x0011
|
#define DHCPV6_OPTION_VENDOR_SPESIFIC_INFO_LEN 0x0011
|
||||||
|
@ -92,6 +94,22 @@ typedef enum {
|
||||||
THREAD_COMMISSIONER_REGISTERED
|
THREAD_COMMISSIONER_REGISTERED
|
||||||
} thread_commissioner_register_status_e;
|
} thread_commissioner_register_status_e;
|
||||||
|
|
||||||
|
typedef struct thread_neigh_table_entry_s {
|
||||||
|
uint8_t mlEid[8];
|
||||||
|
uint32_t last_contact_time; /*!< monotonic time - hard to define "contact"; used for Thread Leasequery replies */
|
||||||
|
uint16_t link_margin;
|
||||||
|
bool secured_data_request:1;
|
||||||
|
bool request_full_data_set:1;
|
||||||
|
} thread_neigh_table_entry_t ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Neighbor info data base
|
||||||
|
*/
|
||||||
|
typedef struct thread_neighbor_class_s {
|
||||||
|
thread_neigh_table_entry_t *neigh_info_list; /*!< Allocated Neighbour info array*/
|
||||||
|
uint8_t list_size; /*!< List size*/
|
||||||
|
} thread_neighbor_class_t;
|
||||||
|
|
||||||
typedef struct thread_mcast_child {
|
typedef struct thread_mcast_child {
|
||||||
uint8_t mac64[8];
|
uint8_t mac64[8];
|
||||||
ns_list_link_t link;
|
ns_list_link_t link;
|
||||||
|
@ -261,6 +279,7 @@ typedef struct thread_previous_partition_info_s {
|
||||||
|
|
||||||
typedef struct thread_info_s {
|
typedef struct thread_info_s {
|
||||||
thread_routing_info_t routing;
|
thread_routing_info_t routing;
|
||||||
|
thread_neighbor_class_t neighbor_class;
|
||||||
thread_master_secret_material_t masterSecretMaterial;
|
thread_master_secret_material_t masterSecretMaterial;
|
||||||
thread_network_data_cache_entry_t networkDataStorage;
|
thread_network_data_cache_entry_t networkDataStorage;
|
||||||
thread_network_local_data_cache_entry_t localServerDataBase;
|
thread_network_local_data_cache_entry_t localServerDataBase;
|
||||||
|
@ -363,7 +382,7 @@ uint16_t thread_network_data_generate_stable_set(protocol_interface_info_entry_t
|
||||||
|
|
||||||
void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId);
|
void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId);
|
||||||
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv);
|
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv);
|
||||||
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour);
|
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *neighbour);
|
||||||
|
|
||||||
void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur);
|
void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur);
|
||||||
thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64);
|
thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64);
|
||||||
|
@ -413,15 +432,19 @@ uint8_t *thread_pending_operational_dataset_write(protocol_interface_info_entry_
|
||||||
bool thread_pending_operational_dataset_process(protocol_interface_info_entry_t *cur, uint64_t mle_pending_timestamp, uint8_t *ptr, uint16_t len);
|
bool thread_pending_operational_dataset_process(protocol_interface_info_entry_t *cur, uint64_t mle_pending_timestamp, uint8_t *ptr, uint16_t len);
|
||||||
/*Write optional thread leader data TLV if leader data is known*/
|
/*Write optional thread leader data TLV if leader data is known*/
|
||||||
uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur);
|
uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur);
|
||||||
void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init);
|
void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init);
|
||||||
|
void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur);
|
||||||
void thread_set_link_local_address(protocol_interface_info_entry_t *cur);
|
void thread_set_link_local_address(protocol_interface_info_entry_t *cur);
|
||||||
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added);
|
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added);
|
||||||
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur);
|
void thread_partition_data_purge(protocol_interface_info_entry_t *cur);
|
||||||
|
bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
|
||||||
|
void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
|
||||||
|
void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index);
|
||||||
|
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
||||||
#else // HAVE_THREAD
|
#else // HAVE_THREAD
|
||||||
|
|
||||||
NS_DUMMY_DEFINITIONS_OK
|
NS_DUMMY_DEFINITIONS_OK
|
||||||
|
#define thread_stable_context_check(cur, buf) (false)
|
||||||
#define thread_info(cur) ((thread_info_t *) NULL)
|
#define thread_info(cur) ((thread_info_t *) NULL)
|
||||||
#define thread_am_router(cur) (false)
|
#define thread_am_router(cur) (false)
|
||||||
#define thread_am_host(cur) (false)
|
#define thread_am_host(cur) (false)
|
||||||
|
@ -438,6 +461,7 @@ NS_DUMMY_DEFINITIONS_OK
|
||||||
#define thread_link_reject_send(interface, ll64) 0
|
#define thread_link_reject_send(interface, ll64) 0
|
||||||
#define thread_addr_is_mesh_local_16(addr, cur) false
|
#define thread_addr_is_mesh_local_16(addr, cur) false
|
||||||
#define thread_mcast_group_change(interface, group, group_added) ((void)0)
|
#define thread_mcast_group_change(interface, group, group_added) ((void)0)
|
||||||
|
#define thread_neighbor_communication_update(cur, neighbor_attribute_index) ((void)0)
|
||||||
#endif // HAVE_THREAD
|
#endif // HAVE_THREAD
|
||||||
|
|
||||||
#endif /* LOWPAN_THREAD_H_ */
|
#endif /* LOWPAN_THREAD_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
#include "thread_joiner_application.h"
|
#include "thread_joiner_application.h"
|
||||||
#include "thread_leader_service.h"
|
#include "thread_leader_service.h"
|
||||||
#include "thread_router_bootstrap.h"
|
#include "thread_router_bootstrap.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
||||||
#include "thread_config.h"
|
#include "thread_config.h"
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
#include "thread_diagcop_lib.h"
|
#include "thread_diagcop_lib.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,31 +95,31 @@ static uint8_t *thread_diagnostic_child_table_tlv_build(uint8_t *data_ptr, proto
|
||||||
uint8_t child_count = 0;
|
uint8_t child_count = 0;
|
||||||
uint8_t calculated_timeout;
|
uint8_t calculated_timeout;
|
||||||
|
|
||||||
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!mle_table) {
|
|
||||||
return data_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
child_count = thread_router_bootstrap_child_count_get(cur);
|
child_count = thread_router_bootstrap_child_count_get(cur);
|
||||||
|
|
||||||
*data_ptr++ = DIAGCOP_TLV_CHILD_TABLE; // Type
|
*data_ptr++ = DIAGCOP_TLV_CHILD_TABLE; // Type
|
||||||
*data_ptr++ = (3 * child_count); // Length
|
*data_ptr++ = (3 * child_count); // Length
|
||||||
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == mac_helper_mac16_address_get(cur)){
|
if (thread_router_addr_from_addr(cur_entry->mac16) == mac_helper_mac16_address_get(cur)){
|
||||||
/* |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3| */
|
/* |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3| */
|
||||||
/* |Timeout |Rsv| Child ID | Mode | */
|
/* |Timeout |Rsv| Child ID | Mode | */
|
||||||
calculated_timeout = thread_log2_aprx((cur_entry->timeout_rx-1)*MLE_TIMER_TICKS_SECONDS) + 4;
|
calculated_timeout = thread_log2_aprx(cur_entry->link_lifetime - 1) + 4;
|
||||||
tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->short_adr, cur_entry->mode);
|
uint8_t mode = 0;
|
||||||
|
mode |= mle_mode_write_from_mac_entry(cur_entry);
|
||||||
|
mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, cur_entry->index);
|
||||||
|
tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->mac16, mode);
|
||||||
*data_ptr = 0x00; //reserved bytes to zero
|
*data_ptr = 0x00; //reserved bytes to zero
|
||||||
*data_ptr = calculated_timeout << 3;
|
*data_ptr = calculated_timeout << 3;
|
||||||
|
|
||||||
if(cur_entry->short_adr & 0x0100){
|
if(cur_entry->mac16 & 0x0100){
|
||||||
*data_ptr = *data_ptr | 0x01;
|
*data_ptr = *data_ptr | 0x01;
|
||||||
}
|
}
|
||||||
data_ptr++;
|
data_ptr++;
|
||||||
*data_ptr++ = (uint8_t)(cur_entry->short_adr & 0x00ff);
|
*data_ptr++ = (uint8_t)(cur_entry->mac16 & 0x00ff);
|
||||||
*data_ptr++ = cur_entry->mode;
|
*data_ptr++ = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -818,7 +818,7 @@ static void thread_discovery_request_msg_handler(thread_discovery_class_t * disc
|
||||||
tr_debug("Thread discovery request message RX");
|
tr_debug("Thread discovery request message RX");
|
||||||
|
|
||||||
// Check if we have room for new neighbor
|
// Check if we have room for new neighbor
|
||||||
if (mle_class_free_entry_count_get(discovery_class->interface_id) < 1) {
|
if (mle_class_free_entry_count_get(discovery_class->interface) < 1) {
|
||||||
tr_debug("MLE table full, skip request");
|
tr_debug("MLE table full, skip request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1281,10 +1281,10 @@ static void thread_discovery_normal_receive_cb(int8_t interface_id, mle_message_
|
||||||
/**
|
/**
|
||||||
* Start Thread network discovery
|
* Start Thread network discovery
|
||||||
*/
|
*/
|
||||||
int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb)
|
int thread_discovery_network_scan(struct protocol_interface_info_entry *cur_interface, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb)
|
||||||
{
|
{
|
||||||
|
|
||||||
thread_discovery_class_t * discovery_class = thread_discovery_class_get(interface_id);
|
thread_discovery_class_t * discovery_class = thread_discovery_class_get(cur_interface->id);
|
||||||
if (!discovery_class || !ready_cb || !scan_request) {
|
if (!discovery_class || !ready_cb || !scan_request) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1304,12 +1304,12 @@ int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_service_interface_register(interface_id, thread_discovery_normal_receive_cb, discovery_class->discovery_request->temporary_mac64,8) != 0) {
|
if (mle_service_interface_register(cur_interface->id, cur_interface, thread_discovery_normal_receive_cb, discovery_class->discovery_request->temporary_mac64,8) != 0) {
|
||||||
thread_discovery_request_free(discovery_class);
|
thread_discovery_request_free(discovery_class);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_service_interface_receiver_bypass_handler_update(interface_id, thread_discovery_message_receiver_cb) != 0) {
|
if (mle_service_interface_receiver_bypass_handler_update(cur_interface->id, thread_discovery_message_receiver_cb) != 0) {
|
||||||
thread_discovery_request_free(discovery_class);
|
thread_discovery_request_free(discovery_class);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -122,7 +122,7 @@ int thread_discovery_responser_enable(int8_t interface_id, bool enable_service);
|
||||||
/**
|
/**
|
||||||
* Start Thread network discovery
|
* Start Thread network discovery
|
||||||
*/
|
*/
|
||||||
int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb);
|
int thread_discovery_network_scan(struct protocol_interface_info_entry *cur_interface, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start device orphan scan
|
* Start device orphan scan
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -40,27 +40,66 @@ extern "C" {
|
||||||
|
|
||||||
struct discovery_response_list;
|
struct discovery_response_list;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREAD_V2
|
||||||
|
|
||||||
|
void thread_extension_allocate(protocol_interface_info_entry_t *cur);
|
||||||
|
void thread_extension_free(protocol_interface_info_entry_t *cur);
|
||||||
|
void thread_extension_init(int8_t interface_id, int8_t coap_service_id);
|
||||||
|
void thread_extension_mtd_service_register(protocol_interface_info_entry_t *cur);
|
||||||
|
int thread_extension_network_prefix_get(int8_t interface_id, uint8_t *options_ptr, uint8_t *prefix_ptr, uint8_t *prefix_len);
|
||||||
|
void thread_extension_network_data_process(struct protocol_interface_info_entry *cur);
|
||||||
|
int thread_extension_primary_bbr_get(struct protocol_interface_info_entry *cur, uint8_t *addr_ptr, uint8_t *seq_ptr, uint32_t *timer1_ptr, uint32_t *timer2_ptr);
|
||||||
|
void thread_extension_address_registration(struct protocol_interface_info_entry *interface, const uint8_t *addr, const uint8_t *child_mac64, bool refresh_child_entry, bool duplicate_child_detected);
|
||||||
|
void thread_extension_address_generate(protocol_interface_info_entry_t *cur);
|
||||||
|
void thread_extension_aloc_generate(struct protocol_interface_info_entry *cur);
|
||||||
|
bool thread_extension_aloc_map(protocol_interface_info_entry_t *cur, uint16_t *addr16);
|
||||||
|
void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t *interface);
|
||||||
|
void thread_extension_address_registration_trigger(protocol_interface_info_entry_t *interface);
|
||||||
|
void thread_extension_route_set(protocol_interface_info_entry_t *cur);
|
||||||
|
void thread_extension_activate(protocol_interface_info_entry_t *cur);
|
||||||
|
bool thread_extension_enabled(protocol_interface_info_entry_t *cur);
|
||||||
|
bool thread_extension_context_can_delete(int8_t id, uint8_t servicesPrefix[16], uint8_t context_prefix_length);
|
||||||
|
bool thread_extension_version_check(uint8_t version);
|
||||||
|
void thread_extension_discover_response_read(struct discovery_response_list *nwk_info, uint16_t discover_response_tlv, uint8_t *data_ptr, uint16_t data_len);
|
||||||
|
void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy);
|
||||||
|
int thread_extension_service_init(protocol_interface_info_entry_t *cur);
|
||||||
|
void thread_extension_addr_ntf_send(struct protocol_interface_info_entry *cur, uint8_t *destination_address, const uint8_t *addr_data_ptr, uint8_t bbr_status);
|
||||||
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
|
bool thread_extension_joining_enabled(int8_t interface_id);
|
||||||
|
uint8_t thread_extension_discover_response_len(protocol_interface_info_entry_t *cur);
|
||||||
|
uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_t *cur, uint8_t *ptr);
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define thread_extension_joining_enabled(interface_id) false
|
||||||
|
#define thread_extension_discover_response_len(cur) 0
|
||||||
|
#define thread_extension_discover_response_write(cur, ptr) (ptr)
|
||||||
|
#endif //HAVE_THREAD_ROUTER
|
||||||
|
#else
|
||||||
|
|
||||||
#define thread_extension_allocate(cur)
|
#define thread_extension_allocate(cur)
|
||||||
#define thread_extension_free(cur)
|
#define thread_extension_free(cur)
|
||||||
#define thread_extension_init(interface_id,coap_service_id)
|
#define thread_extension_init(interface_id,coap_service_id)
|
||||||
#define thread_extension_network_prefix_get(interface_id,options_ptr,prefix_ptr,prefix_len) (-1)
|
#define thread_extension_network_prefix_get(interface_id,options_ptr,prefix_ptr,prefix_len) (-1)
|
||||||
#define thread_extension_network_data_process(cur)
|
#define thread_extension_network_data_process(cur)
|
||||||
#define thread_extension_primary_bbr_get(cur,addr_ptr,seq_ptr,timer1_ptr, timer2_ptr) (-1)
|
#define thread_extension_primary_bbr_get(cur,addr_ptr,seq_ptr,timer1_ptr, timer2_ptr) (-1)
|
||||||
#define thread_extension_address_registration(interface,addr,child_mac64)
|
#define thread_extension_address_registration(interface,addr,child_mac64,refresh_child_entry,duplicate_child_detected)
|
||||||
#define thread_extension_address_generate(cur)
|
#define thread_extension_address_generate(cur)
|
||||||
#define thread_extension_aloc_generate(cur)
|
#define thread_extension_aloc_generate(cur)
|
||||||
#define thread_extension_aloc_map(cur, addr16) false
|
#define thread_extension_aloc_map(cur, addr16) false
|
||||||
#define thread_extension_mcast_subscrition_change(interface, group, added)
|
#define thread_extension_mcast_subscrition_change(interface)
|
||||||
#define thread_extension_route_set(cur)
|
#define thread_extension_route_set(cur)
|
||||||
#define thread_extension_activate(cur)
|
#define thread_extension_activate(cur)
|
||||||
#define thread_extension_enabled(cur) (false)
|
#define thread_extension_enabled(cur) (false)
|
||||||
#define thread_extension_version_check(version) (false)
|
#define thread_extension_version_check(version) (false)
|
||||||
#define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len)
|
#define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len)
|
||||||
#define thread_extension_discover_response_tlv_write(data, version, extension_bit) (data)
|
#define thread_extension_discover_response_tlv_write(data, version, extension_bit) (data)
|
||||||
#define thread_extension_joiner_router_init(interface_id)
|
#define thread_extension_service_init(cur) 0
|
||||||
#define thread_extension_joining_enabled(interface_id) false
|
#define thread_extension_joining_enabled(interface_id) false
|
||||||
#define thread_extension_discover_response_len(cur) 0
|
#define thread_extension_discover_response_len(cur) 0
|
||||||
#define thread_extension_discover_response_write(cur, ptr) (ptr)
|
#define thread_extension_discover_response_write(cur, ptr) (ptr)
|
||||||
|
#define thread_extension_addr_ntf_send(cur,destination_address,addr_data_ptr,bbr_status)
|
||||||
|
#define thread_extension_context_can_delete(id, servicesPrefix, context_prefix_length) false
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -38,6 +38,14 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thread PBBR ML-EID map structure
|
||||||
|
*/
|
||||||
|
typedef struct thread_pbbr_dua_info {
|
||||||
|
uint8_t mleid_ptr[8];
|
||||||
|
uint32_t last_contact_time;
|
||||||
|
} thread_pbbr_dua_info_t;
|
||||||
|
|
||||||
#if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER)
|
#if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER)
|
||||||
|
|
||||||
int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id);
|
int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id);
|
||||||
|
@ -47,6 +55,7 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds);
|
||||||
int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay);
|
int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay);
|
||||||
int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port);
|
int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port);
|
||||||
void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur);
|
void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur);
|
||||||
|
int thread_extension_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -58,6 +67,7 @@ void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur);
|
||||||
#define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay)
|
#define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay)
|
||||||
#define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1)
|
#define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1)
|
||||||
#define thread_extension_bbr_route_update(cur)
|
#define thread_extension_bbr_route_update(cur)
|
||||||
|
#define thread_extension_bbr_prefix_set(interface_id, prefix) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -63,6 +63,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_management_client.h"
|
#include "6LoWPAN/Thread/thread_management_client.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
#include "Common_Protocols/ipv6.h"
|
#include "Common_Protocols/ipv6.h"
|
||||||
#include "MPL/mpl.h"
|
#include "MPL/mpl.h"
|
||||||
|
@ -73,6 +74,7 @@
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/address.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "tebs"
|
#define TRACE_GROUP "tebs"
|
||||||
|
|
||||||
|
@ -122,7 +124,8 @@ static void thread_merge_prepare(protocol_interface_info_entry_t *cur)
|
||||||
thread_clean_old_16_bit_address_based_addresses(cur);
|
thread_clean_old_16_bit_address_based_addresses(cur);
|
||||||
mpl_clear_realm_scope_seeds(cur);
|
mpl_clear_realm_scope_seeds(cur);
|
||||||
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
|
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
|
||||||
thread_old_partition_data_purge(cur);
|
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
|
||||||
|
thread_partition_data_purge(cur);
|
||||||
thread_network_data_clean(cur);
|
thread_network_data_clean(cur);
|
||||||
cur->nwk_mode = ARM_NWK_GP_IP_MODE;
|
cur->nwk_mode = ARM_NWK_GP_IP_MODE;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +148,7 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI
|
||||||
uint8_t ll64[16];
|
uint8_t ll64[16];
|
||||||
thread_scanned_parent_t *parent = cur->thread_info->thread_attach_scanned_parent;
|
thread_scanned_parent_t *parent = cur->thread_info->thread_attach_scanned_parent;
|
||||||
link_configuration_s *linkConfiguration;
|
link_configuration_s *linkConfiguration;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
|
|
||||||
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
|
@ -156,22 +159,25 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI
|
||||||
memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8);
|
memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8);
|
||||||
memcpy(&ll64[8], parent->mac64 , 8);
|
memcpy(&ll64[8], parent->mac64 , 8);
|
||||||
ll64[8] ^= 2;
|
ll64[8] ^= 2;
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, true, &new_entry_created);
|
||||||
entry_temp = mle_class_get_entry_by_ll64(interface_id, parent->linkMarginToParent,ll64, true, &new_entry_created);
|
|
||||||
if (entry_temp == NULL) {
|
if (entry_temp == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
entry_temp->threadNeighbor = true;
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, parent->linkMarginToParent, new_entry_created);
|
||||||
entry_temp->short_adr = parent->shortAddress;
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
entry_temp->priorityFlag = true;
|
|
||||||
entry_temp->holdTime = 90;
|
entry_temp->mac16 = parent->shortAddress;
|
||||||
entry_temp->mle_frame_counter = parent->mleFrameCounter;
|
entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
||||||
|
|
||||||
|
mle_service_frame_counter_entry_add(interface_id, entry_temp->index, parent->mleFrameCounter);
|
||||||
|
|
||||||
thread_management_key_sets_calc(cur, linkConfiguration, cur->thread_info->thread_attach_scanned_parent->keySequence);
|
thread_management_key_sets_calc(cur, linkConfiguration, cur->thread_info->thread_attach_scanned_parent->keySequence);
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, true);
|
thread_key_guard_timer_calculate(cur, linkConfiguration, true);
|
||||||
|
|
||||||
mac_helper_devicetable_set(entry_temp, cur, parent->linLayerFrameCounter, mac_helper_default_key_index_get(cur), new_entry_created);
|
mlme_device_descriptor_t device_desc;
|
||||||
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME);
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,parent->linLayerFrameCounter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur,entry_temp->index, mac_helper_default_key_index_get(cur), new_entry_created);
|
||||||
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, THREAD_DEFAULT_LINK_LIFETIME);
|
||||||
|
|
||||||
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
|
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
|
||||||
nwk_thread_host_control(cur, NET_HOST_FAST_POLL_MODE, 50);
|
nwk_thread_host_control(cur, NET_HOST_FAST_POLL_MODE, 50);
|
||||||
|
@ -284,6 +290,8 @@ void thread_network_attach_start(protocol_interface_info_entry_t *cur)
|
||||||
tr_debug("MLE Parent request");
|
tr_debug("MLE Parent request");
|
||||||
cur->nwk_bootstrap_state = ER_MLE_SCAN;
|
cur->nwk_bootstrap_state = ER_MLE_SCAN;
|
||||||
cur->bootsrap_state_machine_cnt = 0;
|
cur->bootsrap_state_machine_cnt = 0;
|
||||||
|
/* advance trickle timer by 6 (in 100ms ticks) seconds if needed */
|
||||||
|
thread_routing_trickle_advance(&cur->thread_info->routing, 6*10);
|
||||||
} else {
|
} else {
|
||||||
cur->bootsrap_state_machine_cnt = 5;
|
cur->bootsrap_state_machine_cnt = 5;
|
||||||
}
|
}
|
||||||
|
@ -297,7 +305,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
|
||||||
uint16_t address16;
|
uint16_t address16;
|
||||||
uint32_t llFrameCounter;
|
uint32_t llFrameCounter;
|
||||||
thread_leader_data_t leaderData;
|
thread_leader_data_t leaderData;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool new_entry_created;
|
bool new_entry_created;
|
||||||
|
|
||||||
tr_debug("Validate Link Synch Response");
|
tr_debug("Validate Link Synch Response");
|
||||||
|
@ -323,31 +331,36 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
|
||||||
|
|
||||||
if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
||||||
thread_management_key_synch_req(cur->id, common_read_32_bit(securityHeader->Keysource));
|
thread_management_key_synch_req(cur->id, common_read_32_bit(securityHeader->Keysource));
|
||||||
|
// if learning key sequence from link sync actual guard timer value is not known
|
||||||
|
thread_key_guard_timer_reset(cur);
|
||||||
} else {
|
} else {
|
||||||
tr_debug("Key ID Mode 2 not used; dropped.");
|
tr_debug("Key ID Mode 2 not used; dropped.");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Update parent link information
|
//Update parent link information
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, src_address, true, &new_entry_created);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), src_address, true, &new_entry_created);
|
||||||
|
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
tr_debug("Neighbor allocate fail");
|
tr_debug("Neighbor allocate fail");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_entry_created);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
/*
|
/*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
entry_temp->threadNeighbor = true;
|
entry_temp->mac16 = srcAddress;
|
||||||
entry_temp->short_adr = srcAddress;
|
entry_temp->connected_device = 1;
|
||||||
entry_temp->handshakeReady = 1;
|
entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR; // Make this our parent
|
||||||
entry_temp->holdTime = 90;
|
common_write_16_bit(entry_temp->mac16, shortAddress);
|
||||||
entry_temp->priorityFlag = true; // Make this our parent
|
|
||||||
common_write_16_bit(entry_temp->short_adr, shortAddress);
|
|
||||||
|
|
||||||
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
|
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
|
||||||
mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, thread_info(cur)->host_link_timeout);
|
||||||
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, securityHeader->KeyIndex, new_entry_created);
|
|
||||||
|
mlme_device_descriptor_t device_desc;
|
||||||
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, securityHeader->KeyIndex, new_entry_created);
|
||||||
|
|
||||||
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
|
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
|
||||||
thread_bootstrap_update_ml16_address(cur, address16);
|
thread_bootstrap_update_ml16_address(cur, address16);
|
||||||
|
@ -377,12 +390,10 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
|
||||||
|
|
||||||
static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
||||||
{
|
{
|
||||||
|
(void) interface_id;
|
||||||
tr_debug("Thread MLE message child_synch handler");
|
tr_debug("Thread MLE message child_synch handler");
|
||||||
//State machine What packet shuold accept in this case
|
//State machine What packet shuold accept in this case
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
if (!cur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that message is from link-local scope */
|
/* Check that message is from link-local scope */
|
||||||
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
||||||
|
@ -466,10 +477,8 @@ static bool thread_host_prefer_parent_response(protocol_interface_info_entry_t *
|
||||||
*/
|
*/
|
||||||
void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
(void) interface_id;
|
||||||
if (!cur) {
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that message is from link-local scope */
|
/* Check that message is from link-local scope */
|
||||||
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
||||||
|
@ -538,8 +547,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
|
||||||
if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) {
|
if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) {
|
||||||
tr_debug("Reattach");
|
tr_debug("Reattach");
|
||||||
if (thread_info(cur)->thread_leader_data) {
|
if (thread_info(cur)->thread_leader_data) {
|
||||||
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) ||
|
if (!thread_partition_match(cur, &leaderData)) {
|
||||||
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
|
|
||||||
//accept only same ID at reattach phase
|
//accept only same ID at reattach phase
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -557,8 +565,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
|
||||||
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED ||
|
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED ||
|
||||||
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) {
|
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) {
|
||||||
if (thread_info(cur)->thread_leader_data) {
|
if (thread_info(cur)->thread_leader_data) {
|
||||||
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) &&
|
if (thread_partition_match(cur, &leaderData)) {
|
||||||
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
|
|
||||||
//accept only different ID at anyattach phase
|
//accept only different ID at anyattach phase
|
||||||
tr_debug("Drop old partition");
|
tr_debug("Drop old partition");
|
||||||
return;
|
return;
|
||||||
|
@ -736,12 +743,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
|
||||||
static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
||||||
{
|
{
|
||||||
thread_leader_data_t leaderData;
|
thread_leader_data_t leaderData;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
link_configuration_s *link_configuration;
|
link_configuration_s *link_configuration;
|
||||||
if (!cur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
link_configuration = thread_joiner_application_get_config(cur->id);
|
link_configuration = thread_joiner_application_get_config(cur->id);
|
||||||
if (!link_configuration) {
|
if (!link_configuration) {
|
||||||
return;
|
return;
|
||||||
|
@ -790,17 +794,19 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
|
||||||
thread_merge_prepare(cur);
|
thread_merge_prepare(cur);
|
||||||
|
|
||||||
// Create entry for new parent
|
// Create entry for new parent
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, thread_compute_link_margin(mle_msg->dbm), mle_msg->packet_src_address, true, &new_entry_created);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, &new_entry_created);
|
||||||
if (entry_temp == NULL) {
|
if (entry_temp == NULL) {
|
||||||
// todo: what to do here?
|
// todo: what to do here?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, thread_compute_link_margin(mle_msg->dbm), new_entry_created);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
|
||||||
//Parse mandatory TLV's
|
//Parse mandatory TLV's
|
||||||
if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) {
|
if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &entry_temp->short_adr)) {
|
if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &entry_temp->mac16)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,25 +842,24 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
common_write_16_bit(entry_temp->short_adr, shortAddress);
|
common_write_16_bit(entry_temp->mac16, shortAddress);
|
||||||
//Update possible reed address by real router address
|
//Update possible reed address by real router address
|
||||||
scan_result->shortAddress = entry_temp->short_adr;
|
scan_result->shortAddress = entry_temp->mac16;
|
||||||
|
|
||||||
entry_temp->holdTime = 90;
|
entry_temp->connected_device = 1;
|
||||||
entry_temp->handshakeReady = 1;
|
entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
||||||
entry_temp->priorityFlag = true;
|
|
||||||
entry_temp->threadNeighbor = true;
|
|
||||||
|
|
||||||
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
|
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
|
||||||
mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, thread_info(cur)->host_link_timeout);
|
||||||
|
|
||||||
if (scan_result->security_key_index != security_headers->KeyIndex) {
|
if (scan_result->security_key_index != security_headers->KeyIndex) {
|
||||||
// KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter
|
// KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter
|
||||||
scan_result->linLayerFrameCounter = 0;
|
scan_result->linLayerFrameCounter = 0;
|
||||||
scan_result->security_key_index = security_headers->KeyIndex;
|
scan_result->security_key_index = security_headers->KeyIndex;
|
||||||
}
|
}
|
||||||
|
mlme_device_descriptor_t device_desc;
|
||||||
mac_helper_devicetable_set(entry_temp, cur, scan_result->linLayerFrameCounter, security_headers->KeyIndex, new_entry_created);
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,scan_result->linLayerFrameCounter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry_created);
|
||||||
|
|
||||||
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
|
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
|
||||||
|
|
||||||
|
@ -948,23 +953,26 @@ static int8_t thread_end_device_synch_start(protocol_interface_info_entry_t *cur
|
||||||
void thread_endevice_synch_start(protocol_interface_info_entry_t *cur)
|
void thread_endevice_synch_start(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
if (cur->thread_info->thread_endnode_parent) {
|
if (cur->thread_info->thread_endnode_parent) {
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
|
||||||
bool new_entry_created;
|
bool new_entry_created;
|
||||||
|
|
||||||
// Add the parent to the MLE neighbor table
|
// Add the parent to the MLE neighbor table
|
||||||
entry_temp = mle_class_get_entry_by_mac64(cur->id, 64, cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created);
|
mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created);
|
||||||
|
if (mac_entry) {
|
||||||
|
//Add link margin 64
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index,64, new_entry_created);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index);
|
||||||
|
|
||||||
if (entry_temp) {
|
mac_entry->mac16 = cur->thread_info->thread_endnode_parent->shortAddress;
|
||||||
entry_temp->short_adr = cur->thread_info->thread_endnode_parent->shortAddress;
|
mac_entry->connected_device = 1;
|
||||||
entry_temp->handshakeReady = 1;
|
|
||||||
entry_temp->threadNeighbor = true;
|
|
||||||
|
|
||||||
// In case we don't get response to sync; use temporary timeout here,
|
// In case we don't get response to sync; use temporary timeout here,
|
||||||
// Child ID Response handler will set correct value later
|
// Child ID Response handler will set correct value later
|
||||||
mle_entry_timeout_update(entry_temp, 20);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_entry, mac_entry->link_lifetime);
|
||||||
|
|
||||||
// Add the parent to the MAC table (for e.g. secured/fragmented Child Update Response)
|
// Add the parent to the MAC table (for e.g. secured/fragmented Child Update Response)
|
||||||
mac_helper_devicetable_set(entry_temp, cur, 0, cur->mac_parameters->mac_default_key_index, new_entry_created);
|
mlme_device_descriptor_t device_desc;
|
||||||
|
mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64, mac_entry->mac16,0, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, mac_entry->index, cur->mac_parameters->mac_default_key_index, new_entry_created);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,10 +986,9 @@ void thread_endevice_synch_start(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
|
static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
thread_scanned_parent_t *scanned_parent;
|
thread_scanned_parent_t *scanned_parent;
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
uint8_t ll64[16];
|
|
||||||
|
|
||||||
(void)msgId;
|
(void)msgId;
|
||||||
|
|
||||||
|
@ -1017,15 +1024,17 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo
|
||||||
tr_debug("Back to old partition");
|
tr_debug("Back to old partition");
|
||||||
|
|
||||||
/* If scanned parent is from other partition, delete from MLE table */
|
/* If scanned parent is from other partition, delete from MLE table */
|
||||||
if (scanned_parent->leader_data.partitionId != thread_info(cur)->thread_leader_data->partitionId) {
|
if ((scanned_parent->leader_data.partitionId != thread_info(cur)->thread_leader_data->partitionId) ||
|
||||||
memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8);
|
(scanned_parent->leader_data.weighting != thread_info(cur)->thread_leader_data->weighting)) {
|
||||||
memcpy(&ll64[8], scanned_parent->mac64 , 8);
|
entry_temp = mac_neighbor_table_address_discover(mac_neighbor_info(cur), scanned_parent->mac64, ADDR_802_15_4_LONG);
|
||||||
ll64[8] ^= 2;
|
if (entry_temp) {
|
||||||
|
bool my_parent = thread_check_is_this_my_parent(cur, entry_temp);
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, scanned_parent->linkMarginToParent, ll64, false, NULL);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
if (entry_temp && !thread_check_is_this_my_parent(cur, entry_temp)) {
|
if (my_parent) {
|
||||||
// remove scanned_parent entry only if it is not my parent
|
tr_debug("No parent resp - any-attach");
|
||||||
mle_class_remove_entry(cur->id, entry_temp);
|
thread_bootstrap_connection_error(interface_id, CON_ERROR_NETWORK_ATTACH_FAIL, NULL);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,22 +1168,22 @@ static bool thread_child_update_timeout_cb(int8_t interface_id, uint16_t msgId,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64)
|
bool thread_host_bootstrap_child_update(protocol_interface_info_entry_t *cur, const uint8_t *mac64)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
mle_message_timeout_params_t timeout;
|
mle_message_timeout_params_t timeout;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
uint32_t keySequence;
|
uint32_t keySequence;
|
||||||
|
|
||||||
|
|
||||||
if (!cur->thread_info->thread_endnode_parent) {
|
if (!cur->thread_info->thread_endnode_parent) {
|
||||||
return -1;
|
tr_debug("Not end device parent info for NUD");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) {
|
if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) {
|
||||||
//Set Pending if earlier process is already started
|
//Set Pending if earlier process is already started
|
||||||
cur->thread_info->thread_endnode_parent->childUpdatePending = true;
|
cur->thread_info->thread_endnode_parent->childUpdatePending = true;
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
//Trig event
|
//Trig event
|
||||||
cur->thread_info->thread_endnode_parent->childUpdatePending = false;
|
cur->thread_info->thread_endnode_parent->childUpdatePending = false;
|
||||||
|
@ -1189,7 +1198,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma
|
||||||
|
|
||||||
uint16_t bufId = mle_service_msg_allocate(cur->id, 150 + 3 + 6 + 10, false, MLE_COMMAND_CHILD_UPDATE_REQUEST);
|
uint16_t bufId = mle_service_msg_allocate(cur->id, 150 + 3 + 6 + 10, false, MLE_COMMAND_CHILD_UPDATE_REQUEST);
|
||||||
if (bufId == 0) {
|
if (bufId == 0) {
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_management_get_current_keysequence(cur->id, &keySequence);
|
thread_management_get_current_keysequence(cur->id, &keySequence);
|
||||||
|
@ -1228,7 +1237,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma
|
||||||
mle_service_set_msg_timeout_parameters(bufId, &timeout);
|
mle_service_set_msg_timeout_parameters(bufId, &timeout);
|
||||||
mle_service_send_message(bufId);
|
mle_service_send_message(bufId);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge)
|
int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -42,7 +42,7 @@ struct protocol_interface_info_entry;
|
||||||
struct mle_security_header;
|
struct mle_security_header;
|
||||||
|
|
||||||
void thread_network_attach_start(struct protocol_interface_info_entry *cur);
|
void thread_network_attach_start(struct protocol_interface_info_entry *cur);
|
||||||
int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64);
|
bool thread_host_bootstrap_child_update(struct protocol_interface_info_entry *cur, const uint8_t *mac64);
|
||||||
int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge);
|
int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge);
|
||||||
void thread_child_set_default_route(struct protocol_interface_info_entry *cur);
|
void thread_child_set_default_route(struct protocol_interface_info_entry *cur);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -778,8 +778,8 @@ static bool thread_joiner_application_validate_settings(thread_joiner_t *this)
|
||||||
new_value_generated = 1;
|
new_value_generated = 1;
|
||||||
tr_info("Generating Random ML-EID");
|
tr_info("Generating Random ML-EID");
|
||||||
}
|
}
|
||||||
if (this->configuration_ptr->key_rotation < 3600) {
|
if (this->configuration_ptr->key_rotation < 1) {
|
||||||
this->configuration_ptr->key_rotation = 3600;
|
this->configuration_ptr->key_rotation = 1;
|
||||||
}
|
}
|
||||||
return new_value_generated;
|
return new_value_generated;
|
||||||
}
|
}
|
||||||
|
@ -967,17 +967,12 @@ static int thread_joiner_application_nvm_link_config_read(thread_joiner_t *this)
|
||||||
this->configuration_valid = true;
|
this->configuration_valid = true;
|
||||||
link_configuration_trace(this->configuration_ptr);
|
link_configuration_trace(this->configuration_ptr);
|
||||||
|
|
||||||
//Add Security to MLE service
|
|
||||||
uint8_t key_material[32];
|
|
||||||
uint8_t key_index;
|
|
||||||
//Define KEY's
|
|
||||||
|
|
||||||
thread_key_get(this->configuration_ptr->master_key, key_material, this->configuration_ptr->key_sequence);
|
|
||||||
key_index = THREAD_KEY_INDEX(this->configuration_ptr->key_sequence);
|
|
||||||
//Set Keys
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
|
||||||
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
|
//Add Security to MLE service
|
||||||
mle_service_security_set_security_key(this->interface_id, key_material, key_index, true);
|
thread_security_prev_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence);
|
||||||
|
thread_security_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence);
|
||||||
|
thread_security_next_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence);
|
||||||
|
|
||||||
// update counters
|
// update counters
|
||||||
mle_service_security_set_frame_counter(this->interface_id, fast_data.mle_frame_counter);
|
mle_service_security_set_frame_counter(this->interface_id, fast_data.mle_frame_counter);
|
||||||
mac_helper_link_frame_counter_set(this->interface_id, fast_data.mac_frame_counter);
|
mac_helper_link_frame_counter_set(this->interface_id, fast_data.mac_frame_counter);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -414,7 +414,7 @@ static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) {
|
if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) {
|
||||||
if (common_read_16_bit(ptr) < 3600) {
|
if (common_read_16_bit(ptr) < 1) {
|
||||||
tr_warn("invalid security policy");
|
tr_warn("invalid security policy");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto send_response;
|
goto send_response;
|
||||||
|
@ -1090,7 +1090,7 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
|
||||||
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff);
|
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr, session_id, ret);
|
tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret);
|
||||||
|
|
||||||
send_error_response:
|
send_error_response:
|
||||||
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
|
||||||
|
@ -1346,7 +1346,7 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in
|
||||||
thread_leader_service_private_routemask_init(private);
|
thread_leader_service_private_routemask_init(private);
|
||||||
//SET Router ID
|
//SET Router ID
|
||||||
thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
|
thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
|
||||||
thread_old_partition_data_purge(cur);
|
thread_partition_data_purge(cur);
|
||||||
// remove any existing rloc mapping in nvm
|
// remove any existing rloc mapping in nvm
|
||||||
thread_nvm_store_mleid_rloc_map_remove();
|
thread_nvm_store_mleid_rloc_map_remove();
|
||||||
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
|
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
|
||||||
|
@ -1526,7 +1526,7 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t
|
||||||
cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
|
cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
|
||||||
|
|
||||||
thread_leader_service_update_id_set(cur);
|
thread_leader_service_update_id_set(cur);
|
||||||
thread_network_data_context_re_use_timer_update(&cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts);
|
thread_network_data_context_re_use_timer_update(cur->id, &cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts);
|
||||||
// Send update to network data if needed
|
// Send update to network data if needed
|
||||||
thread_leader_service_network_data_changed(cur, false, false);
|
thread_leader_service_network_data_changed(cur, false, false);
|
||||||
}
|
}
|
||||||
|
@ -1621,7 +1621,6 @@ void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool
|
||||||
//memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8);
|
//memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8);
|
||||||
//SET SHort Address & PAN-ID
|
//SET SHort Address & PAN-ID
|
||||||
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
|
|
||||||
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
|
||||||
cur->interface_mode = INTERFACE_UP;
|
cur->interface_mode = INTERFACE_UP;
|
||||||
cur->nwk_mode = ARM_NWK_GP_IP_MODE;
|
cur->nwk_mode = ARM_NWK_GP_IP_MODE;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -146,6 +146,8 @@ void thread_management_client_init(int8_t interface_id)
|
||||||
|
|
||||||
if (this) {
|
if (this) {
|
||||||
this->network_data_set_cb_ptr = NULL;
|
this->network_data_set_cb_ptr = NULL;
|
||||||
|
this->router_id_release_cb_ptr = NULL;
|
||||||
|
this->neighbor_discovery_cb_ptr = NULL;
|
||||||
this->router_id_cb_ptr = NULL;
|
this->router_id_cb_ptr = NULL;
|
||||||
this->interface_id = interface_id;
|
this->interface_id = interface_id;
|
||||||
this->coap_asd_msg_id = 0;
|
this->coap_asd_msg_id = 0;
|
||||||
|
@ -333,6 +335,15 @@ static int thread_management_client_neighbor_discovery_data_cb(int8_t service_id
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_management_client_get_interface_id_by_service_id(int8_t service_id)
|
||||||
|
{
|
||||||
|
thread_management_t *this = thread_management_find_by_service(service_id);
|
||||||
|
if (!this) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return this->interface_id;
|
||||||
|
}
|
||||||
|
|
||||||
int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb)
|
int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb)
|
||||||
{
|
{
|
||||||
thread_management_t *this = thread_management_find(interface_id);
|
thread_management_t *this = thread_management_find(interface_id);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -148,6 +148,15 @@ int thread_management_client_network_data_unregister(int8_t interface_id, uint16
|
||||||
*/
|
*/
|
||||||
int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb);
|
int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb);
|
||||||
|
|
||||||
|
/** Get interface_id of based on coap service_id
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* /param service_id coap service id.
|
||||||
|
*
|
||||||
|
*return interface_id of thread instance if successful and -1 for failure
|
||||||
|
*/
|
||||||
|
int thread_management_client_get_interface_id_by_service_id(int8_t service_id);
|
||||||
|
|
||||||
/** send active configuration dataset get for parent
|
/** send active configuration dataset get for parent
|
||||||
*
|
*
|
||||||
* /param interface_id interface id of this thread instance.
|
* /param interface_id interface id of this thread instance.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -62,6 +62,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_constants.h"
|
#include "6LoWPAN/Thread/thread_constants.h"
|
||||||
#include "6LoWPAN/Thread/thread_extension_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_extension_bootstrap.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_extension.h"
|
||||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||||
#include "RPL/rpl_control.h" // insanity - bootstraps shouldn't be doing each others' clean-up
|
#include "RPL/rpl_control.h" // insanity - bootstraps shouldn't be doing each others' clean-up
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
|
@ -77,7 +78,9 @@
|
||||||
#include "Service_Libs/blacklist/blacklist.h"
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
#include "6LoWPAN/MAC/mac_pairwise_key.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
#include "6LoWPAN/lowpan_adaptation_interface.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "mac_common_defines.h"
|
#include "mac_common_defines.h"
|
||||||
#include "mlme.h"
|
#include "mlme.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
|
@ -307,68 +310,6 @@ void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_seque
|
||||||
SHALIB_finish_HMAC(key_material_buf, 8);
|
SHALIB_finish_HMAC(key_material_buf, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Increment Thread key sequence counter
|
|
||||||
*
|
|
||||||
* \param interface_id Network Interface
|
|
||||||
*
|
|
||||||
* return 0, ADD OK
|
|
||||||
* return <0 Add Not OK
|
|
||||||
*/
|
|
||||||
uint8_t *thread_management_key_request(int8_t interface_id, uint8_t keyId)
|
|
||||||
{
|
|
||||||
protocol_interface_info_entry_t *cur;
|
|
||||||
uint8_t *keyPtr = NULL;
|
|
||||||
link_configuration_s *linkConfiguration;
|
|
||||||
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
|
||||||
if (!linkConfiguration) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
if (cur && cur->thread_info) {
|
|
||||||
if (cur->thread_info->masterSecretMaterial.valid_Info) {
|
|
||||||
|
|
||||||
if (cur->thread_info->masterSecretMaterial.historyKeyValid && (cur->thread_info->masterSecretMaterial.historyKeyId == keyId)) {
|
|
||||||
|
|
||||||
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
uint32_t thrSequenceCounter;
|
|
||||||
uint8_t compId = 0xff, keyIdDiff;
|
|
||||||
thrSequenceCounter = linkConfiguration->key_sequence + 1;
|
|
||||||
//Calculate Current Next key ID
|
|
||||||
compId = THREAD_KEY_INDEX(thrSequenceCounter);
|
|
||||||
|
|
||||||
if (keyId > compId) {
|
|
||||||
keyIdDiff = (keyId - compId);
|
|
||||||
} else {
|
|
||||||
keyIdDiff = (128 - (compId - keyId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyIdDiff > 64) {
|
|
||||||
//Calc Temp Key
|
|
||||||
thrSequenceCounter -= (128 - keyIdDiff);
|
|
||||||
tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, thrSequenceCounter);
|
|
||||||
thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, thrSequenceCounter);
|
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyId = keyId;
|
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyValid = true;
|
|
||||||
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
|
|
||||||
} else {
|
|
||||||
tr_debug("Gen new key id %"PRIu8" %"PRIu8" diff", keyId, keyIdDiff);
|
|
||||||
thrSequenceCounter += keyIdDiff;
|
|
||||||
//Generate
|
|
||||||
tr_debug("Missed n key Update...generated missed key %"PRIu8" update by seq %"PRIu32, keyIdDiff, thrSequenceCounter);
|
|
||||||
thread_management_key_sets_calc(cur, linkConfiguration, thrSequenceCounter);
|
|
||||||
//Get Default key
|
|
||||||
keyPtr = mle_service_security_default_key_get(interface_id);
|
|
||||||
}
|
|
||||||
thread_nvm_store_seq_counter_write(linkConfiguration->key_sequence);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keyPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread key sequence & key synch
|
* Thread key sequence & key synch
|
||||||
*
|
*
|
||||||
|
@ -381,22 +322,32 @@ void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce)
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (cur && cur->thread_info) {
|
if (!cur || !cur->thread_info) {
|
||||||
if (cur->thread_info->masterSecretMaterial.valid_Info) {
|
return;
|
||||||
if (keySequnce != linkConfiguration->key_sequence) {
|
|
||||||
if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer == 0 && keySequnce > linkConfiguration->key_sequence)) {
|
|
||||||
tr_debug("Sync key material by %"PRIu32, keySequnce);
|
|
||||||
thread_management_key_sets_calc(cur, linkConfiguration, keySequnce);
|
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!cur->thread_info->masterSecretMaterial.valid_Info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//tr_debug("Sync key material by %"PRIu32, keySequnce);
|
||||||
|
|
||||||
|
if (keySequnce <= linkConfiguration->key_sequence) {
|
||||||
|
// Smaller or equal request ignored
|
||||||
|
//tr_debug("Sync key material no change");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > 0)) {
|
||||||
|
// Guard time prevent the change
|
||||||
|
//tr_debug("Sync key material guard blocked");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Calculate new keys
|
||||||
|
tr_debug("Sync key material by %"PRIu32, keySequnce);
|
||||||
|
thread_management_key_sets_calc(cur, linkConfiguration, keySequnce);
|
||||||
|
thread_key_guard_timer_calculate(cur, linkConfiguration, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId)
|
static void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId)
|
||||||
{
|
{
|
||||||
thread_info->masterSecretMaterial.historyKeyValid = true;
|
thread_info->masterSecretMaterial.historyKeyValid = true;
|
||||||
thread_info->masterSecretMaterial.historyKeyId = keyId;
|
thread_info->masterSecretMaterial.historyKeyId = keyId;
|
||||||
|
@ -424,7 +375,7 @@ void thread_security_update_from_mac(protocol_interface_info_entry_t *cur)
|
||||||
linkConfiguration->key_sequence++;
|
linkConfiguration->key_sequence++;
|
||||||
mac_helper_link_frame_counter_set(cur->id, 0);
|
mac_helper_link_frame_counter_set(cur->id, 0);
|
||||||
thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence);
|
thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence);
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, false);
|
thread_key_guard_timer_calculate(cur, linkConfiguration, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
|
void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
|
||||||
|
@ -437,11 +388,33 @@ void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t
|
||||||
thread_key_get(masterKey, key_material, thrKeySequenceCounter);
|
thread_key_get(masterKey, key_material, thrKeySequenceCounter);
|
||||||
/* Update keys as primary keys */
|
/* Update keys as primary keys */
|
||||||
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
|
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
|
||||||
tr_debug("Set key Id: %u", key_index);
|
tr_debug("Set current key Id: %u", key_index);
|
||||||
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
|
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
|
||||||
mle_service_security_set_security_key(cur->id, key_material, key_index, true);
|
mle_service_security_set_security_key(cur->id, key_material, key_index, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void thread_security_prev_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
|
||||||
|
{
|
||||||
|
uint8_t key_material[32];
|
||||||
|
uint8_t key_index;
|
||||||
|
uint32_t thrKeySequenceCounter;
|
||||||
|
if (keySequence == 0) {
|
||||||
|
// in initial value there is no prev available
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thrKeySequenceCounter = keySequence - 1;
|
||||||
|
/* Produced keys from Thread security material: MAC key | MLE key */
|
||||||
|
thread_key_get(masterKey, key_material, thrKeySequenceCounter);
|
||||||
|
/* Update keys as primary keys */
|
||||||
|
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
|
||||||
|
tr_debug("Set previous key Id: %u", key_index);
|
||||||
|
mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
|
||||||
|
mle_service_security_set_security_key(cur->id, key_material, key_index, false);
|
||||||
|
//copy master secret material to history
|
||||||
|
thread_history_key_material_push(cur->thread_info, key_material, key_index);
|
||||||
|
}
|
||||||
|
|
||||||
void thread_security_next_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
|
void thread_security_next_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
|
||||||
{
|
{
|
||||||
uint8_t key_material[32];
|
uint8_t key_material[32];
|
||||||
|
@ -471,31 +444,17 @@ int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_c
|
||||||
ret_val = 0;
|
ret_val = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Generate new key set */
|
/* Generate new key set */
|
||||||
uint8_t key_material[32];
|
|
||||||
uint8_t key_index;
|
|
||||||
thread_nvm_fast_data_t fast_data;
|
|
||||||
//SET History key, Current Key & Next Key
|
|
||||||
//Generate History Key
|
|
||||||
//Clean All Keys
|
//Clean All Keys
|
||||||
mac_helper_security_key_clean(cur);
|
mac_helper_security_key_clean(cur);
|
||||||
thrKeySequenceCounter--;
|
|
||||||
/* Update keys as non-primary keys */
|
|
||||||
thread_key_get(linkConfiguration->master_key, key_material, thrKeySequenceCounter);
|
|
||||||
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
|
|
||||||
//copy master secret material to history
|
|
||||||
memcpy(cur->thread_info->masterSecretMaterial.historyKey, key_material, 32);
|
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyId = key_index;
|
|
||||||
cur->thread_info->masterSecretMaterial.historyKeyValid = true;
|
|
||||||
|
|
||||||
mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
|
// Update key sequence
|
||||||
//Set New Active Key
|
|
||||||
thrKeySequenceCounter++;
|
|
||||||
linkConfiguration->key_sequence = thrKeySequenceCounter;
|
linkConfiguration->key_sequence = thrKeySequenceCounter;
|
||||||
fast_data.seq_counter = thrKeySequenceCounter;
|
// Zero all frame counters. MLE does it automatically
|
||||||
fast_data.mac_frame_counter = 0;
|
|
||||||
fast_data.mle_frame_counter = mle_service_security_get_frame_counter(cur->interface_mode);
|
|
||||||
thread_nvm_store_fast_data_write(&fast_data);
|
|
||||||
mac_helper_link_frame_counter_set(cur->id, 0);
|
mac_helper_link_frame_counter_set(cur->id, 0);
|
||||||
|
// Store all frame counters as zero and update the sequence counter
|
||||||
|
thread_nvm_store_fast_data_write_all(0, 0, thrKeySequenceCounter);
|
||||||
|
|
||||||
|
thread_security_prev_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
||||||
thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
||||||
thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
|
||||||
ret_val = 0;
|
ret_val = 0;
|
||||||
|
@ -790,12 +749,23 @@ int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_THREAD
|
#ifdef HAVE_THREAD
|
||||||
|
static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, const uint8_t *address, addrtype_t type)
|
||||||
|
{
|
||||||
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type);
|
||||||
|
if (!entry || !entry->connected_device) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->lifetime = entry->link_lifetime;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status)
|
void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mac_neighbor_table_entry_t *entry;
|
||||||
|
|
||||||
switch (status->status) {
|
switch (status->status) {
|
||||||
|
|
||||||
|
@ -808,7 +778,10 @@ void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* st
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MLME_DATA_POLL_NOTIFICATION:
|
case MLME_DATA_POLL_NOTIFICATION:
|
||||||
mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false);
|
entry = neighbor_data_poll_referesh(cur, status->SrcAddr, (addrtype_t)status->SrcAddrMode);
|
||||||
|
if (entry) {
|
||||||
|
thread_neighbor_communication_update(cur, entry->index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -908,7 +881,7 @@ int thread_management_node_init(
|
||||||
scan_params->scan_duration = 5;
|
scan_params->scan_duration = 5;
|
||||||
|
|
||||||
cur->thread_info->masterSecretMaterial.valid_Info = false;
|
cur->thread_info->masterSecretMaterial.valid_Info = false;
|
||||||
thread_calculate_key_guard_timer(cur, static_configuration, true);
|
thread_key_guard_timer_calculate(cur, static_configuration, true);
|
||||||
|
|
||||||
cur->thread_info->maxChildCount = THREAD_MAX_CHILD_COUNT;
|
cur->thread_info->maxChildCount = THREAD_MAX_CHILD_COUNT;
|
||||||
cur->thread_info->rfc6775 = false;
|
cur->thread_info->rfc6775 = false;
|
||||||
|
@ -1439,10 +1412,21 @@ int thread_management_partition_weighting_set(int8_t interface_id, uint8_t parti
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool trig_network_scan = false;
|
||||||
|
if (cur->thread_info->thread_leader_data) {
|
||||||
|
if (cur->thread_info->thread_leader_data->weighting < partition_weighting) {
|
||||||
|
trig_network_scan = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cur->thread_info->partition_weighting = partition_weighting;
|
cur->thread_info->partition_weighting = partition_weighting;
|
||||||
|
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||||
// bootstrap active and weighting has changed
|
if (trig_network_scan && thread_extension_enabled(cur)) {
|
||||||
thread_bootstrap_reset_restart(interface_id);
|
thread_nvm_store_link_info_clear();
|
||||||
|
// bootstrap active and weighting has changed
|
||||||
|
thread_bootstrap_reset_restart(interface_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -77,15 +77,13 @@ int thread_management_increment_key_sequence_counter(int8_t interface_id);
|
||||||
|
|
||||||
int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, uint32_t thrKeySequenceCounter);
|
int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, uint32_t thrKeySequenceCounter);
|
||||||
|
|
||||||
uint8_t *thread_management_key_request(int8_t interface_id, uint8_t keyId);
|
|
||||||
|
|
||||||
void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce);
|
void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce);
|
||||||
uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_t keyId, uint32_t keySequnce);
|
uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_t keyId, uint32_t keySequnce);
|
||||||
|
|
||||||
void thread_security_update_from_mac(struct protocol_interface_info_entry *cur);
|
void thread_security_update_from_mac(struct protocol_interface_info_entry *cur);
|
||||||
|
|
||||||
void thread_history_key_material_push(struct thread_info_s *thread_info, uint8_t *mleKeyPtr, uint8_t keyId);
|
void thread_security_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
|
||||||
|
void thread_security_prev_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
|
||||||
void thread_security_next_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
|
void thread_security_next_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
|
||||||
|
|
||||||
void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_sequence_counter);
|
void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_sequence_counter);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -1159,7 +1159,6 @@ int thread_management_server_init(int8_t interface_id)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
thread_extension_init(interface_id, this->coap_service_id);
|
thread_extension_init(interface_id, this->coap_service_id);
|
||||||
|
|
||||||
// All thread devices
|
// All thread devices
|
||||||
coap_service_register_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_management_server_get_command_cb);
|
coap_service_register_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_management_server_get_command_cb);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -38,6 +38,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_config.h"
|
#include "6LoWPAN/Thread/thread_config.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
#include "6LoWPAN/Thread/thread_lowpower_private_api.h"
|
#include "6LoWPAN/Thread/thread_lowpower_private_api.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "6LoWPAN/Thread/thread_mle_message_handler.h"
|
#include "6LoWPAN/Thread/thread_mle_message_handler.h"
|
||||||
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||||
|
@ -48,13 +49,15 @@
|
||||||
#include "6LoWPAN/Thread/thread_extension.h"
|
#include "6LoWPAN/Thread/thread_extension.h"
|
||||||
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_synch.h"
|
#include "6LoWPAN/Thread/thread_network_synch.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#define TRACE_GROUP "thmh"
|
#define TRACE_GROUP "thmh"
|
||||||
static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, uint8_t *router_ll64);
|
static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, uint8_t *router_ll64);
|
||||||
static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mle_neigh_table_entry_t *neighbor);
|
static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mac_neighbor_table_entry_t *neighbor);
|
||||||
static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin);
|
static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin);
|
||||||
static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
|
static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
|
||||||
static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin);
|
static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin);
|
||||||
|
@ -72,11 +75,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg,
|
||||||
* and MUST be discarded.
|
* and MUST be discarded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
|
|
||||||
if (!cur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that message is from link-local scope */
|
/* Check that message is from link-local scope */
|
||||||
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
||||||
|
@ -100,11 +99,11 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
case MLE_COMMAND_REJECT: {
|
case MLE_COMMAND_REJECT: {
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
tr_warn("Reject Link");
|
tr_warn("Reject Link");
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
if (entry_temp) {
|
if (entry_temp) {
|
||||||
mle_class_remove_entry(cur->id, entry_temp);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -159,16 +158,11 @@ static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread
|
||||||
requestNetworkdata = true;
|
requestNetworkdata = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) {
|
if (!thread_partition_match(cur, leaderData)) {
|
||||||
requestNetworkdata = true;
|
requestNetworkdata = true;
|
||||||
thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1;
|
thread_partition_info_update(cur, leaderData);
|
||||||
thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId;
|
|
||||||
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId;
|
|
||||||
thread_info(cur)->thread_leader_data->weighting = leaderData->weighting;
|
|
||||||
|
|
||||||
if (requestNetworkdata) {
|
if (requestNetworkdata) {
|
||||||
thread_bootstrap_parent_network_data_request(cur, false);
|
thread_bootstrap_parent_network_data_request(cur, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,12 +209,12 @@ static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, ui
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mle_neigh_table_entry_t *neighbor)
|
static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mac_neighbor_table_entry_t *neighbor)
|
||||||
{
|
{
|
||||||
int leaderDataUpdate = thread_leader_data_validation(cur, leaderData, routeTlv);
|
int leaderDataUpdate = thread_leader_data_validation(cur, leaderData, routeTlv);
|
||||||
|
|
||||||
if (leaderDataUpdate == 1) {
|
if (leaderDataUpdate == 1) {
|
||||||
if (neighbor && neighbor->handshakeReady == 1) {
|
if (neighbor && neighbor->connected_device == 1) {
|
||||||
// Request network data if we have a 2-way link
|
// Request network data if we have a 2-way link
|
||||||
tr_debug("Request New Network Data from %s", trace_ipv6(src_address));
|
tr_debug("Request New Network Data from %s", trace_ipv6(src_address));
|
||||||
thread_network_data_request_send(cur, src_address, true);
|
thread_network_data_request_send(cur, src_address, true);
|
||||||
|
@ -272,30 +266,32 @@ static bool thread_router_advertiment_tlv_analyze(uint8_t *ptr, uint16_t data_le
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, mle_neigh_table_entry_t *entry_temp, uint16_t short_address)
|
static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, mac_neighbor_table_entry_t *entry_temp, uint16_t short_address)
|
||||||
{
|
{
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t linkMargin = thread_compute_link_margin(mle_msg->dbm);
|
||||||
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
|
||||||
|
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
|
||||||
if (!thread_attach_active_router(cur) && !thread_check_is_this_my_parent(cur, entry_temp)) {
|
if (!thread_attach_active_router(cur) && !thread_check_is_this_my_parent(cur, entry_temp)) {
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
|
||||||
} else {
|
|
||||||
entry_temp->last_contact_time = protocol_core_monotonic_time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (short_address != entry_temp->short_adr) {
|
if (short_address != entry_temp->mac16) {
|
||||||
if (thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) {
|
if (thread_router_addr_from_addr(entry_temp->mac16) == cur->thread_info->routerShortAddress) {
|
||||||
thread_dynamic_storage_child_info_clear(cur->id, entry_temp);
|
thread_dynamic_storage_child_info_clear(cur->id, entry_temp);
|
||||||
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr);
|
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16);
|
||||||
}
|
}
|
||||||
entry_temp->short_adr = short_address;
|
entry_temp->mac16 = short_address;
|
||||||
/* throw MLME_GET request, short address is changed automatically in get request callback */
|
/* throw MLME_GET request, short address is changed automatically in get request callback */
|
||||||
mlme_get_t get_req;
|
mlme_get_t get_req;
|
||||||
get_req.attr = macDeviceTable;
|
get_req.attr = macDeviceTable;
|
||||||
get_req.attr_index = entry_temp->attribute_index;
|
get_req.attr_index = entry_temp->index;
|
||||||
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,11 +300,6 @@ static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_me
|
||||||
|
|
||||||
static bool thread_parse_advertisement_from_parent(protocol_interface_info_entry_t *cur, thread_leader_data_t *leader_data, uint16_t short_address)
|
static bool thread_parse_advertisement_from_parent(protocol_interface_info_entry_t *cur, thread_leader_data_t *leader_data, uint16_t short_address)
|
||||||
{
|
{
|
||||||
if ((thread_info(cur)->thread_leader_data->partitionId != leader_data->partitionId) ||
|
|
||||||
(thread_info(cur)->thread_leader_data->weighting != leader_data->weighting)) {
|
|
||||||
//parent changed partition/weight - reset own routing information
|
|
||||||
thread_old_partition_data_purge(cur);
|
|
||||||
}
|
|
||||||
//check if network data needs to be requested
|
//check if network data needs to be requested
|
||||||
if (!thread_bootstrap_request_network_data(cur, leader_data, short_address)) {
|
if (!thread_bootstrap_request_network_data(cur, leader_data, short_address)) {
|
||||||
tr_debug("Parent short address changed - re-attach");
|
tr_debug("Parent short address changed - re-attach");
|
||||||
|
@ -323,7 +314,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
|
||||||
{
|
{
|
||||||
mle_tlv_info_t routeTlv;
|
mle_tlv_info_t routeTlv;
|
||||||
thread_leader_data_t leaderData;
|
thread_leader_data_t leaderData;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
uint16_t shortAddress;
|
uint16_t shortAddress;
|
||||||
bool adv_from_my_partition;
|
bool adv_from_my_partition;
|
||||||
bool my_parent;
|
bool my_parent;
|
||||||
|
@ -342,12 +333,16 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get MLE entry
|
// Get MLE entry
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
if (entry_temp) {
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if this is from my parent
|
// Check if this is from my parent
|
||||||
my_parent = thread_check_is_this_my_parent(cur, entry_temp);
|
my_parent = thread_check_is_this_my_parent(cur, entry_temp);
|
||||||
|
|
||||||
adv_from_my_partition = thread_instance_id_matches(cur, &leaderData);
|
adv_from_my_partition = thread_partition_match(cur, &leaderData);
|
||||||
|
|
||||||
if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) {
|
if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) {
|
||||||
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
||||||
|
@ -355,13 +350,14 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
|
||||||
|
|
||||||
if (entry_temp && !adv_from_my_partition && !my_parent ) {
|
if (entry_temp && !adv_from_my_partition && !my_parent ) {
|
||||||
// Remove MLE entry that are located in other partition and is not my parent
|
// Remove MLE entry that are located in other partition and is not my parent
|
||||||
mle_class_remove_entry(cur->id, entry_temp);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
entry_temp = NULL;
|
entry_temp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check parent status */
|
/* Check parent status */
|
||||||
if (!thread_attach_active_router(cur) && my_parent) {
|
if (!thread_attach_active_router(cur) && my_parent) {
|
||||||
if (!thread_parse_advertisement_from_parent(cur, &leaderData, shortAddress)) {
|
if (!thread_parse_advertisement_from_parent(cur, &leaderData, shortAddress)) {
|
||||||
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,7 +370,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
|
||||||
/* REED and FED */
|
/* REED and FED */
|
||||||
if (!thread_attach_active_router(cur)) {
|
if (!thread_attach_active_router(cur)) {
|
||||||
/* Check if advertisement is from same partition */
|
/* Check if advertisement is from same partition */
|
||||||
if (thread_info(cur)->thread_leader_data->weighting == leaderData.weighting && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId ) {
|
if (thread_partition_match(cur, &leaderData)) {
|
||||||
if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) {
|
if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) {
|
||||||
// Create link to new neighbor no other processing allowed
|
// Create link to new neighbor no other processing allowed
|
||||||
thread_link_request_start(cur, mle_msg->packet_src_address);
|
thread_link_request_start(cur, mle_msg->packet_src_address);
|
||||||
|
@ -404,9 +400,8 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process route TLV
|
// Process route TLV
|
||||||
if ((entry_temp && routeTlv.dataPtr && routeTlv.tlvLen) &&
|
if ((entry_temp && routeTlv.dataPtr && routeTlv.tlvLen) && thread_partition_match(cur, &leaderData)){
|
||||||
(thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId)){
|
tr_debug("Update Route TLV %x", entry_temp->mac16);
|
||||||
tr_debug("Update Route TLV %x", entry_temp->short_adr);
|
|
||||||
thread_router_bootstrap_route_tlv_push(cur, routeTlv.dataPtr, routeTlv.tlvLen , linkMargin, entry_temp);
|
thread_router_bootstrap_route_tlv_push(cur, routeTlv.dataPtr, routeTlv.tlvLen , linkMargin, entry_temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,7 +412,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag
|
||||||
uint16_t version, shortAddress;
|
uint16_t version, shortAddress;
|
||||||
uint16_t messageId;
|
uint16_t messageId;
|
||||||
uint8_t linkMarginfronNeigh;
|
uint8_t linkMarginfronNeigh;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool createNew, new_entry_created;
|
bool createNew, new_entry_created;
|
||||||
|
|
||||||
tr_info("MLE LINK ACCEPT");
|
tr_info("MLE LINK ACCEPT");
|
||||||
|
@ -444,12 +439,14 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag
|
||||||
/* Call to determine whether or not we should create a new link */
|
/* Call to determine whether or not we should create a new link */
|
||||||
createNew = thread_bootstrap_link_create_check(cur, shortAddress);
|
createNew = thread_bootstrap_link_create_check(cur, shortAddress);
|
||||||
|
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry_created);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, createNew, &new_entry_created);
|
||||||
|
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
thread_link_reject_send(cur, mle_msg->packet_src_address);
|
thread_link_reject_send(cur, mle_msg->packet_src_address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_entry_created);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
|
||||||
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
||||||
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
||||||
|
@ -460,32 +457,35 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag
|
||||||
mleFrameCounter = llFrameCounter;
|
mleFrameCounter = llFrameCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_temp->threadNeighbor = true;
|
entry_temp->mac16 = shortAddress;
|
||||||
entry_temp->short_adr = shortAddress;
|
mle_service_frame_counter_entry_add(cur->id, entry_temp->index, mleFrameCounter);
|
||||||
entry_temp->mle_frame_counter = mleFrameCounter;
|
|
||||||
// Set full data as REED needs full data and SED will not make links
|
// Set full data as REED needs full data and SED will not make links
|
||||||
entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET;
|
thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
|
||||||
|
mlme_device_descriptor_t device_desc;
|
||||||
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry_created);
|
||||||
|
uint32_t timeout;
|
||||||
|
|
||||||
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry_created);
|
if (new_entry_created) {
|
||||||
|
timeout = THREAD_DEFAULT_LINK_LIFETIME;
|
||||||
if (entry_temp->timeout_rx) {
|
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
|
||||||
} else {
|
} else {
|
||||||
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME);
|
timeout = entry_temp->link_lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_i_am_router(cur) && thread_is_router_addr(entry_temp->short_adr)) {
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
|
||||||
|
|
||||||
|
if (thread_i_am_router(cur) && thread_is_router_addr(entry_temp->mac16)) {
|
||||||
// If we both are routers, mark the link as 2-way
|
// If we both are routers, mark the link as 2-way
|
||||||
entry_temp->handshakeReady = 1;
|
entry_temp->connected_device = 1;
|
||||||
tr_debug("Marked link as 2-way, handshakeReady=%d", entry_temp->handshakeReady);
|
tr_debug("Marked link as 2-way, handshakeReady=%d", entry_temp->connected_device);
|
||||||
} else {
|
} else {
|
||||||
tr_debug("Marked link as 1-way, handshakeReady=%d", entry_temp->handshakeReady);
|
tr_debug("Marked link as 1-way, handshakeReady=%d", entry_temp->connected_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
blacklist_update(mle_msg->packet_src_address, true);
|
blacklist_update(mle_msg->packet_src_address, true);
|
||||||
|
|
||||||
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) {
|
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) {
|
||||||
thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh);
|
thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void thread_parse_annoucement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg)
|
static void thread_parse_annoucement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg)
|
||||||
|
@ -544,7 +544,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
|
||||||
mle_tlv_info_t ConfigurationTlv;
|
mle_tlv_info_t ConfigurationTlv;
|
||||||
uint64_t active_timestamp = 0;
|
uint64_t active_timestamp = 0;
|
||||||
uint64_t pending_timestamp = 0;// means no pending timestamp
|
uint64_t pending_timestamp = 0;// means no pending timestamp
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool accept_new_data = false;
|
bool accept_new_data = false;
|
||||||
bool leaderDataReceived;
|
bool leaderDataReceived;
|
||||||
|
|
||||||
|
@ -560,7 +560,12 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
|
||||||
|
if (entry_temp) {
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
}
|
||||||
|
|
||||||
if(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER ||
|
if(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER ||
|
||||||
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) {
|
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) {
|
||||||
|
@ -570,7 +575,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
|
if (!thread_partition_match(cur, &leaderData)) {
|
||||||
// if receiving data response from different partition it is dropped
|
// if receiving data response from different partition it is dropped
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -583,10 +588,8 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
|
if (!thread_partition_match(cur, &leaderData)) {
|
||||||
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId;
|
thread_partition_info_update(cur, &leaderData);
|
||||||
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
|
|
||||||
thread_old_partition_data_purge(cur);
|
|
||||||
accept_new_data = true;
|
accept_new_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,11 +708,11 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
|
||||||
mle_tlv_info_t tlv_req;
|
mle_tlv_info_t tlv_req;
|
||||||
uint64_t active_timestamp = 0;
|
uint64_t active_timestamp = 0;
|
||||||
uint64_t pending_timestamp = 0;// means no pending timestamp
|
uint64_t pending_timestamp = 0;// means no pending timestamp
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool data_request_needed = false;
|
bool data_request_needed = false;
|
||||||
|
|
||||||
tr_debug("Child update request");
|
tr_debug("Child update request");
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
|
||||||
if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData) ||
|
if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData) ||
|
||||||
!entry_temp ||
|
!entry_temp ||
|
||||||
|
@ -718,14 +721,16 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
|
||||||
tr_warn("invalid message");
|
tr_warn("invalid message");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
|
||||||
mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv);
|
mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv);
|
||||||
mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req);
|
mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req);
|
||||||
|
|
||||||
// Check if partition changed
|
// Check if partition changed
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
|
if (!thread_partition_match(cur, &leaderData)) {
|
||||||
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId;
|
thread_partition_info_update(cur, &leaderData);
|
||||||
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
|
|
||||||
thread_old_partition_data_purge(cur);
|
|
||||||
}
|
}
|
||||||
//Check Network Data TLV
|
//Check Network Data TLV
|
||||||
if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) {
|
if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) {
|
||||||
|
@ -767,7 +772,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
{
|
{
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
thread_leader_data_t leaderData = {0};
|
thread_leader_data_t leaderData = {0};
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
bool leader_data_received;
|
bool leader_data_received;
|
||||||
|
@ -780,11 +785,12 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
|
|
||||||
//mle_service_buffer_find
|
//mle_service_buffer_find
|
||||||
leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData);
|
leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData);
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
|
||||||
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status) &&
|
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status) &&
|
||||||
status == 1 && thread_check_is_this_my_parent(cur, entry_temp)) {
|
status == 1 && thread_check_is_this_my_parent(cur, entry_temp)) {
|
||||||
tr_debug("parent has connection error");
|
tr_debug("parent has connection error");
|
||||||
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -798,6 +804,8 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
||||||
} else {
|
} else {
|
||||||
tr_debug("Key ID Mode 2 not used; dropped.");
|
tr_debug("Key ID Mode 2 not used; dropped.");
|
||||||
|
@ -811,13 +819,11 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
|
|
||||||
timeout = cur->thread_info->host_link_timeout;
|
timeout = cur->thread_info->host_link_timeout;
|
||||||
if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) {
|
if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) {
|
||||||
entry_temp->holdTime = 90;
|
|
||||||
tr_debug("Setting child timeout, value=%"PRIu32, timeout);
|
tr_debug("Setting child timeout, value=%"PRIu32, timeout);
|
||||||
mle_entry_timeout_update(entry_temp, timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_debug("Keep-Alive -->Respond from Parent");
|
tr_debug("Keep-Alive -->Respond from Parent");
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
|
||||||
|
|
||||||
//Save possible new Leader Data
|
//Save possible new Leader Data
|
||||||
if (leader_data_received) {
|
if (leader_data_received) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -50,6 +50,7 @@
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
#include "6LoWPAN/Thread/thread_routing.h"
|
#include "6LoWPAN/Thread/thread_routing.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "6LoWPAN/Thread/thread_nd.h"
|
#include "6LoWPAN/Thread/thread_nd.h"
|
||||||
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
||||||
#include "6LoWPAN/Thread/thread_extension.h"
|
#include "6LoWPAN/Thread/thread_extension.h"
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_resolution_server.h"
|
#include "6LoWPAN/Thread/thread_resolution_server.h"
|
||||||
#include "6LoWPAN/Thread/thread_bbr_api_internal.h"
|
#include "6LoWPAN/Thread/thread_bbr_api_internal.h"
|
||||||
#include "6LoWPAN/Thread/thread_extension_bbr.h"
|
#include "6LoWPAN/Thread/thread_extension_bbr.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
|
@ -196,14 +198,14 @@ bool thread_nd_ns_transmit(protocol_interface_info_entry_t *cur, ipv6_neighbour_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mle_neigh_table_entry_t *thread_nd_child_mleid_get(int8_t interface_id, uint8_t *childAddress, uint8_t *mlmeid_ptr)
|
static mac_neighbor_table_entry_t *thread_nd_child_mleid_get(protocol_interface_info_entry_t *cur, uint8_t *childAddress, uint8_t *mlmeid_ptr)
|
||||||
{
|
{
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), childAddress, ADDR_802_15_4_SHORT);
|
||||||
entry_temp = mle_class_get_by_link_address(interface_id, childAddress, ADDR_802_15_4_SHORT);
|
if (entry && !entry->ffd_device) {
|
||||||
if (entry_temp) {
|
uint8_t *ptr = thread_neighbor_class_get_mleid(&cur->thread_info->neighbor_class, entry->index);
|
||||||
if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
|
if (ptr) {
|
||||||
memcpy(mlmeid_ptr,entry_temp->mlEid,8);
|
memcpy(mlmeid_ptr, ptr, 8);
|
||||||
return entry_temp;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -228,12 +230,13 @@ static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t tar
|
||||||
/* Scan IPv6 neighbour cache for registered entries of children */
|
/* Scan IPv6 neighbour cache for registered entries of children */
|
||||||
ns_list_foreach(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) {
|
ns_list_foreach(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) {
|
||||||
if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, target_addr)) {
|
if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, target_addr)) {
|
||||||
mle_neigh_table_entry_t *mle_entry;
|
mac_neighbor_table_entry_t *mle_entry;
|
||||||
*addr_out = mac16;
|
*addr_out = mac16;
|
||||||
mle_entry = thread_nd_child_mleid_get(interface_id, &n->ll_address[2], mleid_ptr);
|
mle_entry = thread_nd_child_mleid_get(cur, &n->ll_address[2], mleid_ptr);
|
||||||
if (mle_entry) {
|
if (mle_entry) {
|
||||||
//Get MLEID from Child
|
//Get MLEID from Child
|
||||||
*last_transaction_time = (protocol_core_monotonic_time - mle_entry->last_contact_time) / 10; /* Both variables are count of 100ms ticks. */
|
uint32_t last_contact = thread_neighbor_last_communication_time_get(&cur->thread_info->neighbor_class, mle_entry->index);
|
||||||
|
*last_transaction_time = (protocol_core_monotonic_time - last_contact) / 10; /* Both variables are count of 100ms ticks. */
|
||||||
*proxy = true;
|
*proxy = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -291,17 +294,18 @@ static void thread_nd_address_error(int8_t interface_id, const uint8_t ip_addr[1
|
||||||
if_address_entry_t *addr_entry = addr_get_entry(cur, ip_addr);
|
if_address_entry_t *addr_entry = addr_get_entry(cur, ip_addr);
|
||||||
if (addr_entry && memcmp(ml_eid, cur->iid_slaac, 8)) {
|
if (addr_entry && memcmp(ml_eid, cur->iid_slaac, 8)) {
|
||||||
addr_duplicate_detected(cur, ip_addr);
|
addr_duplicate_detected(cur, ip_addr);
|
||||||
|
thread_extension_address_generate(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan IPv6 neighbour cache for registered entries of children */
|
/* Scan IPv6 neighbour cache for registered entries of children */
|
||||||
ns_list_foreach_safe(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) {
|
ns_list_foreach_safe(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) {
|
||||||
if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, ip_addr)) {
|
if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, ip_addr)) {
|
||||||
uint8_t child_mleid[8];
|
uint8_t child_mleid[8];
|
||||||
mle_neigh_table_entry_t *child = thread_nd_child_mleid_get(interface_id, &n->ll_address[2], child_mleid);
|
mac_neighbor_table_entry_t *child = thread_nd_child_mleid_get(cur, &n->ll_address[2], child_mleid);
|
||||||
/* If this address belongs to an RFD child, with a different ML-EID, we must send it a duplicate message, and remove the EID */
|
/* If this address belongs to an RFD child, with a different ML-EID, we must send it a duplicate message, and remove the EID */
|
||||||
if (child && memcmp(child_mleid, ml_eid, 8)) {
|
if (child && memcmp(child_mleid, ml_eid, 8)) {
|
||||||
uint8_t child_ml_addr[16];
|
uint8_t child_ml_addr[16];
|
||||||
thread_addr_write_mesh_local_16(child_ml_addr, child->short_adr, cur->thread_info);
|
thread_addr_write_mesh_local_16(child_ml_addr, child->mac16, cur->thread_info);
|
||||||
tr_warn("Forwarding address error to child %04x", common_read_16_bit(&n->ll_address[2]));
|
tr_warn("Forwarding address error to child %04x", common_read_16_bit(&n->ll_address[2]));
|
||||||
thread_resolution_client_address_error(interface_id, child_ml_addr, ip_addr, ml_eid);
|
thread_resolution_client_address_error(interface_id, child_ml_addr, ip_addr, ml_eid);
|
||||||
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, n);
|
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, n);
|
||||||
|
@ -367,7 +371,7 @@ buffer_t *thread_nd_snoop(protocol_interface_info_entry_t *cur, buffer_t *buf, c
|
||||||
return buffer_free(buf);
|
return buffer_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mle_class_get_by_link_address(cur->id, &ll_dst->address[2], ADDR_802_15_4_SHORT)) {
|
if (!mac_neighbor_table_address_discover(mac_neighbor_info(cur), &ll_dst->address[2], ADDR_802_15_4_SHORT)) {
|
||||||
/* We now know this was a packet for a non-existent child */
|
/* We now know this was a packet for a non-existent child */
|
||||||
goto bounce;
|
goto bounce;
|
||||||
}
|
}
|
||||||
|
@ -433,7 +437,7 @@ buffer_t *thread_nd_special_forwarding(protocol_interface_info_entry_t *cur, buf
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_neigh_table_entry_t *entry = mle_class_get_by_link_address(cur->id, &ll_src->address[2], ADDR_802_15_4_SHORT);
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), &ll_src->address[2], ADDR_802_15_4_SHORT);
|
||||||
|
|
||||||
/* Due to note 1 and 1b above, full-function children / neighbor routers
|
/* Due to note 1 and 1b above, full-function children / neighbor routers
|
||||||
* who did resolve to an RLOC16 may have optimised out the mesh header.
|
* who did resolve to an RLOC16 may have optimised out the mesh header.
|
||||||
|
@ -446,7 +450,7 @@ buffer_t *thread_nd_special_forwarding(protocol_interface_info_entry_t *cur, buf
|
||||||
* is not in our neighbour cache, we need to send the child an error
|
* is not in our neighbour cache, we need to send the child an error
|
||||||
* to clear its cache.)
|
* to clear its cache.)
|
||||||
*/
|
*/
|
||||||
if (!(buf->options.lowpan_mesh_rx || (entry && (entry->mode & MLE_DEV_MASK) == MLE_FFD_DEV))) {
|
if (!(buf->options.lowpan_mesh_rx || (entry && entry->ffd_device))) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,10 +534,11 @@ buffer_t *thread_nd_icmp_handler(protocol_interface_info_entry_t *cur, buffer_t
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64)
|
int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64, bool *new_neighbour_created)
|
||||||
{
|
{
|
||||||
ipv6_neighbour_t *neigh;
|
ipv6_neighbour_t *neigh;
|
||||||
uint8_t ll_address[4];
|
uint8_t ll_address[4];
|
||||||
|
bool neighbor_created = false;
|
||||||
common_write_16_bit(panId, ll_address + 0);
|
common_write_16_bit(panId, ll_address + 0);
|
||||||
common_write_16_bit(mac16, ll_address + 2);
|
common_write_16_bit(mac16, ll_address + 2);
|
||||||
neigh = ipv6_neighbour_lookup_or_create(&cur->ipv6_neighbour_cache, ipv6Address);
|
neigh = ipv6_neighbour_lookup_or_create(&cur->ipv6_neighbour_cache, ipv6Address);
|
||||||
|
@ -542,21 +547,24 @@ int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const u
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *nce_eui64 = ipv6_neighbour_eui64(&cur->ipv6_neighbour_cache, neigh);
|
uint8_t *nce_eui64 = ipv6_neighbour_eui64(&cur->ipv6_neighbour_cache, neigh);
|
||||||
/*if (neigh->state != IP_NEIGHBOUR_NEW)
|
if (neigh->state != IP_NEIGHBOUR_NEW && memcmp(nce_eui64, mac64, 8) != 0)
|
||||||
{
|
|
||||||
// Worry about this later
|
|
||||||
// Compare mac64 to nce_eui64 to spot duplicates
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
{
|
||||||
/* New entry */
|
return -2;
|
||||||
memcpy(nce_eui64, mac64, 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* New entry */
|
||||||
|
if (neigh->state == IP_NEIGHBOUR_NEW) {
|
||||||
|
neighbor_created = true;
|
||||||
|
}
|
||||||
|
memcpy(nce_eui64, mac64, 8);
|
||||||
/* Set the LL address, ensure it's marked STALE */
|
/* Set the LL address, ensure it's marked STALE */
|
||||||
ipv6_neighbour_entry_update_unsolicited(&cur->ipv6_neighbour_cache, neigh, ADDR_802_15_4_SHORT, ll_address);
|
ipv6_neighbour_entry_update_unsolicited(&cur->ipv6_neighbour_cache, neigh, ADDR_802_15_4_SHORT, ll_address);
|
||||||
neigh->type = IP_NEIGHBOUR_REGISTERED;
|
neigh->type = IP_NEIGHBOUR_REGISTERED;
|
||||||
neigh->lifetime = 0xffffffff; //Set Infinite
|
neigh->lifetime = 0xffffffff; //Set Infinite
|
||||||
ipv6_neighbour_set_state(&cur->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
ipv6_neighbour_set_state(&cur->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
|
||||||
|
if (new_neighbour_created) {
|
||||||
|
*new_neighbour_created = neighbor_created;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -55,7 +55,7 @@ int thread_nd_map_anycast_address(protocol_interface_info_entry_t *cur, uint16_t
|
||||||
void thread_nd_address_remove(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address);
|
void thread_nd_address_remove(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address);
|
||||||
void thread_nd_flush_neighbour_cache_for_short_addr(struct protocol_interface_info_entry *cur, uint16_t flushee, bool children);
|
void thread_nd_flush_neighbour_cache_for_short_addr(struct protocol_interface_info_entry *cur, uint16_t flushee, bool children);
|
||||||
|
|
||||||
int thread_nd_address_registration(struct protocol_interface_info_entry *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64);
|
int thread_nd_address_registration(struct protocol_interface_info_entry *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64, bool *new_neighbour_created);
|
||||||
|
|
||||||
#else //HAVE_THREAD_NEIGHBOR_DISCOVERY
|
#else //HAVE_THREAD_NEIGHBOR_DISCOVERY
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 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.
|
||||||
|
* 3. Neither the name of the copyright holder nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "common_functions.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_routing.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
|
|
||||||
|
|
||||||
|
static thread_neigh_table_entry_t * thread_neighbor_class_table_entry_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
if (!class_ptr->neigh_info_list || attribute_index >= class_ptr->list_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_neigh_table_entry_t *entry = class_ptr->neigh_info_list + attribute_index;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thread_neighbor_class_create(thread_neighbor_class_t *class_ptr, uint8_t neigh_table_size)
|
||||||
|
{
|
||||||
|
class_ptr->neigh_info_list = ns_dyn_mem_alloc(sizeof(thread_neigh_table_entry_t) * neigh_table_size);
|
||||||
|
if (!class_ptr->neigh_info_list) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class_ptr->list_size = neigh_table_size;
|
||||||
|
thread_neigh_table_entry_t * list_ptr = class_ptr->neigh_info_list;
|
||||||
|
for (uint8_t i = 0; i< neigh_table_size; i++) {
|
||||||
|
memset(list_ptr, 0, sizeof(thread_neigh_table_entry_t));
|
||||||
|
list_ptr++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_class_delete(thread_neighbor_class_t *class_ptr)
|
||||||
|
{
|
||||||
|
ns_dyn_mem_free(class_ptr->neigh_info_list);
|
||||||
|
class_ptr->neigh_info_list = NULL;
|
||||||
|
class_ptr->list_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_class_add_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(entry->mlEid, mleid, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * thread_neighbor_class_get_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return entry->mlEid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_last_communication_time_update(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entry->last_contact_time = protocol_core_monotonic_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_class_update_link(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, uint8_t linkmargin, bool new_link)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_link) {
|
||||||
|
entry->link_margin = entry->link_margin + linkmargin - (entry->link_margin >> THREAD_LINK_MARGIN_SCALING);
|
||||||
|
} else {
|
||||||
|
entry->link_margin = linkmargin << THREAD_LINK_MARGIN_SCALING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t thread_neighbor_entry_linkmargin_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return entry->link_margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t thread_neighbor_last_communication_time_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return entry->last_contact_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thread_neighbor_class_mleid_compare(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, const uint8_t *mleid)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry || memcmp(entry->mlEid, mleid, 8)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thread_neighbor_class_request_full_data_setup(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return entry->request_full_data_set;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thread_neighbor_class_secured_data_request(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (!entry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return entry->secured_data_request;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_class_request_full_data_setup_set(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, bool value)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (entry) {
|
||||||
|
entry->request_full_data_set = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_class_secured_data_request_set(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, bool value)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (entry) {
|
||||||
|
entry->secured_data_request = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_neighbor_class_mode_parse_to_entry(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, uint8_t mode)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (entry) {
|
||||||
|
entry->request_full_data_set = mode & MLE_THREAD_REQ_FULL_DATA_SET;
|
||||||
|
entry->secured_data_request = mode & MLE_THREAD_SECURED_DATA_REQUEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t thread_neighbor_class_mode_write_from_entry(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
uint8_t mode = 0;
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (entry) {
|
||||||
|
if (entry->request_full_data_set) {
|
||||||
|
mode |= MLE_THREAD_REQ_FULL_DATA_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->secured_data_request) {
|
||||||
|
mode |= MLE_THREAD_SECURED_DATA_REQUEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void thread_neighbor_class_entry_remove(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
|
||||||
|
{
|
||||||
|
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
|
||||||
|
if (entry) {
|
||||||
|
memset(entry, 0, sizeof(thread_neigh_table_entry_t));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 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.
|
||||||
|
* 3. Neither the name of the copyright holder nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef THREAD_NEIGHBOR_CLASS_H_
|
||||||
|
#define THREAD_NEIGHBOR_CLASS_H_
|
||||||
|
|
||||||
|
struct thread_neighbor_class_s;
|
||||||
|
|
||||||
|
/** Thead Spesific ModeFlags */
|
||||||
|
#define MLE_THREAD_SECURED_DATA_REQUEST 0x04
|
||||||
|
#define MLE_THREAD_REQ_FULL_DATA_SET 0x01
|
||||||
|
|
||||||
|
bool thread_neighbor_class_create(struct thread_neighbor_class_s *class_ptr, uint8_t neigh_table_size);
|
||||||
|
|
||||||
|
void thread_neighbor_class_delete(struct thread_neighbor_class_s *class_ptr);
|
||||||
|
|
||||||
|
void thread_neighbor_class_add_link(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t linkmargin);
|
||||||
|
|
||||||
|
void thread_neighbor_class_add_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid);
|
||||||
|
|
||||||
|
uint8_t * thread_neighbor_class_get_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
void thread_neighbor_class_update_link(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t linkmargin, bool new_link);
|
||||||
|
|
||||||
|
void thread_neighbor_last_communication_time_update(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
uint16_t thread_neighbor_entry_linkmargin_get(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
uint32_t thread_neighbor_last_communication_time_get(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
bool thread_neighbor_class_mleid_compare(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid);
|
||||||
|
|
||||||
|
bool thread_neighbor_class_request_full_data_setup(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
bool thread_neighbor_class_secured_data_request(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
void thread_neighbor_class_mode_parse_to_entry(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t mode);
|
||||||
|
|
||||||
|
uint8_t thread_neighbor_class_mode_write_from_entry(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
void thread_neighbor_class_request_full_data_setup_set(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, bool value);
|
||||||
|
|
||||||
|
void thread_neighbor_class_secured_data_request_set(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, bool value);
|
||||||
|
|
||||||
|
void thread_neighbor_class_entry_remove(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
|
||||||
|
|
||||||
|
#endif /* THREAD_NEIGHBOR_CLASS_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -60,6 +60,7 @@
|
||||||
#define THREAD_P_DEF_ROUTE_BIT_MOVE 9 /* R-bit */
|
#define THREAD_P_DEF_ROUTE_BIT_MOVE 9 /* R-bit */
|
||||||
#define THREAD_P_ON_MESH_BIT_MOVE 8 /* O-bit */
|
#define THREAD_P_ON_MESH_BIT_MOVE 8 /* O-bit */
|
||||||
#define THREAD_P_ND_DNS_BIT_MOVE 7 /* N-bit */
|
#define THREAD_P_ND_DNS_BIT_MOVE 7 /* N-bit */
|
||||||
|
#define THREAD_P_ND_RES_BIT_MOVE 6 /* First reserved bit */
|
||||||
|
|
||||||
/* Bit shift for HasRouteTLV preference bit */
|
/* Bit shift for HasRouteTLV preference bit */
|
||||||
#define THREAD_HAS_ROUTE_PRF_BIT_MOVE 6 /* Prf-bits */
|
#define THREAD_HAS_ROUTE_PRF_BIT_MOVE 6 /* Prf-bits */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -328,9 +328,8 @@ thread_network_local_data_entry_t *thread_local_service_list_allocate(thread_pre
|
||||||
newEntry->servicesPrefixLen = prefixTlv->PrefixLen;
|
newEntry->servicesPrefixLen = prefixTlv->PrefixLen;
|
||||||
newEntry->domainId = prefixTlv->domainId;
|
newEntry->domainId = prefixTlv->domainId;
|
||||||
newEntry->dhcpv6ServerActive = false;
|
newEntry->dhcpv6ServerActive = false;
|
||||||
newEntry->dhcpv6ServerDataStable = false;
|
newEntry->brDataStable = false;
|
||||||
newEntry->slaacServerActive = false;
|
newEntry->slaacServerActive = false;
|
||||||
newEntry->slaacServerDataStable = false;
|
|
||||||
newEntry->slaacPreferred = false;
|
newEntry->slaacPreferred = false;
|
||||||
newEntry->routeActive = false;
|
newEntry->routeActive = false;
|
||||||
newEntry->routeDataStable = false;
|
newEntry->routeDataStable = false;
|
||||||
|
@ -339,6 +338,8 @@ thread_network_local_data_entry_t *thread_local_service_list_allocate(thread_pre
|
||||||
newEntry->defaultRoute = false;
|
newEntry->defaultRoute = false;
|
||||||
newEntry->onMesh = false;
|
newEntry->onMesh = false;
|
||||||
newEntry->ndDns = false;
|
newEntry->ndDns = false;
|
||||||
|
newEntry->brActive = false;
|
||||||
|
newEntry->res1 = false;
|
||||||
}
|
}
|
||||||
return newEntry;
|
return newEntry;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +374,7 @@ thread_network_server_data_entry_t *thread_server_entry_allocate(thread_border_r
|
||||||
newEntry->Prf = service->Prf;
|
newEntry->Prf = service->Prf;
|
||||||
newEntry->P_on_mesh = service->P_on_mesh;
|
newEntry->P_on_mesh = service->P_on_mesh;
|
||||||
newEntry->P_nd_dns = service->P_nd_dns;
|
newEntry->P_nd_dns = service->P_nd_dns;
|
||||||
|
newEntry->P_res1 = service->P_res1;
|
||||||
newEntry->canDelete = false;
|
newEntry->canDelete = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -868,7 +870,7 @@ static int thread_service_data_delete_mark_by_router_id(thread_network_data_serv
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int thread_server_context_clean(thread_network_data_cache_entry_t *cachePtr, thread_data_context_list_t *listPtr, thread_network_data_prefix_cache_entry_t *prefixEntry, lowpan_context_list_t *context_list)
|
static int thread_server_context_clean(int8_t id, thread_network_data_cache_entry_t *cachePtr, thread_data_context_list_t *listPtr, thread_network_data_prefix_cache_entry_t *prefixEntry, lowpan_context_list_t *context_list)
|
||||||
{
|
{
|
||||||
int retVal = -1;
|
int retVal = -1;
|
||||||
(void) prefixEntry;
|
(void) prefixEntry;
|
||||||
|
@ -879,7 +881,9 @@ static int thread_server_context_clean(thread_network_data_cache_entry_t *cacheP
|
||||||
cachePtr->stableUpdatePushed = true;
|
cachePtr->stableUpdatePushed = true;
|
||||||
}
|
}
|
||||||
// Set context lifetime to 0 to delete
|
// Set context lifetime to 0 to delete
|
||||||
lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true);
|
if (thread_extension_context_can_delete(id, prefixEntry->servicesPrefix, cur->contextPrefixLength)) {
|
||||||
|
lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true);
|
||||||
|
}
|
||||||
ns_list_remove(listPtr, cur);
|
ns_list_remove(listPtr, cur);
|
||||||
ns_dyn_mem_free(cur);
|
ns_dyn_mem_free(cur);
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
|
@ -1019,7 +1023,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
|
||||||
}
|
}
|
||||||
thread_server_data_clean_by_router_id(cachePtr, &cur->routeList, cur, true, curInterface);
|
thread_server_data_clean_by_router_id(cachePtr, &cur->routeList, cur, true, curInterface);
|
||||||
if (!is_leader) {
|
if (!is_leader) {
|
||||||
thread_server_context_clean(cachePtr, &cur->contextList, cur, &curInterface->lowpan_contexts);
|
thread_server_context_clean(curInterface->id, cachePtr, &cur->contextList, cur, &curInterface->lowpan_contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ns_list_is_empty(&cur->borderRouterList)) {
|
if (ns_list_is_empty(&cur->borderRouterList)) {
|
||||||
|
@ -1071,7 +1075,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
|
||||||
return address_removed;
|
return address_removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_network_data_context_re_use_timer_update(thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list)
|
void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list)
|
||||||
{
|
{
|
||||||
ns_list_foreach_safe(thread_network_data_prefix_cache_entry_t, cur, &cachePtr->localPrefixList) {
|
ns_list_foreach_safe(thread_network_data_prefix_cache_entry_t, cur, &cachePtr->localPrefixList) {
|
||||||
ns_list_foreach_safe(thread_network_data_context_entry_t, curContext, &cur->contextList) {
|
ns_list_foreach_safe(thread_network_data_context_entry_t, curContext, &cur->contextList) {
|
||||||
|
@ -1086,7 +1090,9 @@ void thread_network_data_context_re_use_timer_update(thread_network_data_cache_e
|
||||||
cachePtr->temporaryUpdatePushed = true;
|
cachePtr->temporaryUpdatePushed = true;
|
||||||
}
|
}
|
||||||
// Set context lifetime to 0 to delete
|
// Set context lifetime to 0 to delete
|
||||||
lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true);
|
if (thread_extension_context_can_delete(id, cur->servicesPrefix,curContext->contextPrefixLength)) {
|
||||||
|
lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true);
|
||||||
|
}
|
||||||
ns_dyn_mem_free(curContext);
|
ns_dyn_mem_free(curContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1708,21 +1714,21 @@ int thread_local_server_list_add_on_mesh_server(thread_network_local_data_cache_
|
||||||
if (networkDataList) {
|
if (networkDataList) {
|
||||||
thread_network_local_data_entry_t *prefix_entry = thread_local_prefix_entry_get(&networkDataList->prefix_list, prefixTlv);
|
thread_network_local_data_entry_t *prefix_entry = thread_local_prefix_entry_get(&networkDataList->prefix_list, prefixTlv);
|
||||||
if (prefix_entry) {
|
if (prefix_entry) {
|
||||||
|
prefix_entry->brDataStable = service->stableData;
|
||||||
prefix_entry->preference = service->Prf;
|
prefix_entry->preference = service->Prf;
|
||||||
prefix_entry->configure = service->P_configure;
|
prefix_entry->configure = service->P_configure;
|
||||||
prefix_entry->defaultRoute = service->P_default_route;
|
prefix_entry->defaultRoute = service->P_default_route;
|
||||||
prefix_entry->onMesh = service->P_on_mesh;
|
prefix_entry->onMesh = service->P_on_mesh;
|
||||||
prefix_entry->ndDns = service->P_nd_dns;
|
prefix_entry->ndDns = service->P_nd_dns;
|
||||||
|
prefix_entry->res1 = service->P_res1;
|
||||||
|
prefix_entry->dhcpv6ServerActive = service->P_dhcp;
|
||||||
|
prefix_entry->slaacServerActive = service->P_slaac;
|
||||||
|
prefix_entry->slaacPreferred = service->P_preferred;
|
||||||
|
|
||||||
if (service->P_dhcp) {
|
if (service->P_dhcp ||
|
||||||
prefix_entry->dhcpv6ServerActive = true;
|
service->P_slaac ||
|
||||||
prefix_entry->dhcpv6ServerDataStable = service->stableData;
|
service->P_res1) {
|
||||||
}
|
prefix_entry->brActive = true;
|
||||||
|
|
||||||
if (service->P_slaac) {
|
|
||||||
prefix_entry->slaacServerActive = true;
|
|
||||||
prefix_entry->slaacServerDataStable = service->stableData;
|
|
||||||
prefix_entry->slaacPreferred = service->P_preferred;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefixTlv->PrefixLen == 0) {
|
if (prefixTlv->PrefixLen == 0) {
|
||||||
|
@ -1891,9 +1897,7 @@ int thread_local_server_del_route(thread_network_local_data_cache_entry_t *netwo
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix_entry->routeActive = false;
|
prefix_entry->routeActive = false;
|
||||||
if (prefix_entry->dhcpv6ServerActive) {
|
if (prefix_entry->brActive) {
|
||||||
return 0;
|
|
||||||
} else if (prefix_entry->slaacServerActive) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2023,17 +2027,13 @@ uint8_t thread_server_prefix_length(thread_network_local_data_entry_t *cur)
|
||||||
|
|
||||||
|
|
||||||
if (cur->routeActive) {
|
if (cur->routeActive) {
|
||||||
if (!((cur->slaacServerActive || cur->dhcpv6ServerActive) && cur->defaultRoute)) {
|
if (!(cur->brActive && cur->defaultRoute)) {
|
||||||
// HasRoute is added if BorderRouter TLV does not have default route bit
|
// HasRoute is added if BorderRouter TLV does not have default route bit
|
||||||
tempLength += 5;
|
tempLength += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->dhcpv6ServerActive) {
|
if (cur->brActive) {
|
||||||
tempLength += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur->slaacServerActive) {
|
|
||||||
tempLength += 6;
|
tempLength += 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2091,14 +2091,9 @@ uint16_t thread_nd_own_service_list_data_size(thread_network_local_data_cache_en
|
||||||
|
|
||||||
static bool thread_check_local_data_prefix_stable_boolean(thread_network_local_data_entry_t *dataList)
|
static bool thread_check_local_data_prefix_stable_boolean(thread_network_local_data_entry_t *dataList)
|
||||||
{
|
{
|
||||||
if (dataList->dhcpv6ServerActive && dataList->dhcpv6ServerDataStable) {
|
if (dataList->brActive && dataList->brDataStable) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataList->slaacServerActive && dataList->slaacServerDataStable) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2269,7 +2264,7 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_
|
||||||
if (servicesLen) {
|
if (servicesLen) {
|
||||||
ptr = thread_nd_hosted_prefix_header_write(ptr,servicesLen, cur);
|
ptr = thread_nd_hosted_prefix_header_write(ptr,servicesLen, cur);
|
||||||
if (cur->routeActive) {
|
if (cur->routeActive) {
|
||||||
if (!((cur->slaacServerActive || cur->dhcpv6ServerActive) && cur->defaultRoute)) {
|
if (!(cur->brActive && cur->defaultRoute)) {
|
||||||
// HasRoute is added if BorderRouter TLV does not have default route bit
|
// HasRoute is added if BorderRouter TLV does not have default route bit
|
||||||
uint8_t preference = 0;
|
uint8_t preference = 0;
|
||||||
tlvType = THREAD_NWK_DATA_TYPE_ROUTE;
|
tlvType = THREAD_NWK_DATA_TYPE_ROUTE;
|
||||||
|
@ -2283,10 +2278,10 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->slaacServerActive || cur->dhcpv6ServerActive) {
|
if (cur->brActive) {
|
||||||
uint16_t flags = 0;
|
uint16_t flags = 0;
|
||||||
tlvType = THREAD_NWK_DATA_TYPE_BORDER_ROUTER;
|
tlvType = THREAD_NWK_DATA_TYPE_BORDER_ROUTER;
|
||||||
if (cur->slaacServerDataStable || cur->dhcpv6ServerDataStable) {
|
if (cur->brDataStable) {
|
||||||
tlvType |= THREAD_NWK_STABLE_DATA;
|
tlvType |= THREAD_NWK_STABLE_DATA;
|
||||||
}
|
}
|
||||||
if (cur->slaacServerActive) {
|
if (cur->slaacServerActive) {
|
||||||
|
@ -2313,6 +2308,9 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_
|
||||||
if (cur->ndDns) {
|
if (cur->ndDns) {
|
||||||
flags |= 1 << THREAD_P_ND_DNS_BIT_MOVE;
|
flags |= 1 << THREAD_P_ND_DNS_BIT_MOVE;
|
||||||
}
|
}
|
||||||
|
if (cur->res1) {
|
||||||
|
flags |= 1 << THREAD_P_ND_RES_BIT_MOVE;
|
||||||
|
}
|
||||||
ptr = thread_service_border_router_tlv_write(ptr, tlvType, routerID, flags);
|
ptr = thread_service_border_router_tlv_write(ptr, tlvType, routerID, flags);
|
||||||
} // slaac or dhcp
|
} // slaac or dhcp
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -72,6 +72,7 @@ typedef struct thread_network_data_temporary_route_or_dhcpv6_server_entry_s {
|
||||||
bool stableData: 1;
|
bool stableData: 1;
|
||||||
bool P_on_mesh: 1;
|
bool P_on_mesh: 1;
|
||||||
bool P_nd_dns: 1;
|
bool P_nd_dns: 1;
|
||||||
|
bool P_res1: 1;
|
||||||
bool canDelete: 1;
|
bool canDelete: 1;
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
} thread_network_server_data_entry_t;
|
} thread_network_server_data_entry_t;
|
||||||
|
@ -87,6 +88,7 @@ typedef struct thread_border_router_tlv_entry_t {
|
||||||
bool stableData: 1; /* P_stable */
|
bool stableData: 1; /* P_stable */
|
||||||
bool P_on_mesh: 1; /* P_on_mesh */
|
bool P_on_mesh: 1; /* P_on_mesh */
|
||||||
bool P_nd_dns: 1; /* P_nd_dns */
|
bool P_nd_dns: 1; /* P_nd_dns */
|
||||||
|
bool P_res1: 1; /* P_res1 */
|
||||||
} thread_border_router_tlv_entry_t;
|
} thread_border_router_tlv_entry_t;
|
||||||
|
|
||||||
typedef struct thread_prefix_tlv {
|
typedef struct thread_prefix_tlv {
|
||||||
|
@ -136,16 +138,17 @@ typedef struct thread_network_local_data_entry_s {
|
||||||
uint8_t servicesPrefixLen; /*!< Prefix length in bits This Can Be 1-128 */
|
uint8_t servicesPrefixLen; /*!< Prefix length in bits This Can Be 1-128 */
|
||||||
bool routeActive: 1;
|
bool routeActive: 1;
|
||||||
bool routeDataStable: 1;
|
bool routeDataStable: 1;
|
||||||
|
bool brActive: 1;
|
||||||
bool dhcpv6ServerActive: 1;
|
bool dhcpv6ServerActive: 1;
|
||||||
bool dhcpv6ServerDataStable: 1;
|
bool brDataStable: 1;
|
||||||
bool slaacServerActive: 1;
|
bool slaacServerActive: 1;
|
||||||
bool slaacServerDataStable: 1;
|
|
||||||
bool slaacPreferred: 1;
|
bool slaacPreferred: 1;
|
||||||
unsigned preference: 2;
|
unsigned preference: 2;
|
||||||
bool configure: 1;
|
bool configure: 1;
|
||||||
bool defaultRoute: 1;
|
bool defaultRoute: 1;
|
||||||
bool onMesh: 1;
|
bool onMesh: 1;
|
||||||
bool ndDns: 1;
|
bool ndDns: 1;
|
||||||
|
bool res1:1;
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
} thread_network_local_data_entry_t;
|
} thread_network_local_data_entry_t;
|
||||||
|
|
||||||
|
@ -207,7 +210,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
|
||||||
|
|
||||||
void thread_network_local_data_free_and_clean(thread_network_local_data_cache_entry_t *cachePtr, int8_t interface_id);
|
void thread_network_local_data_free_and_clean(thread_network_local_data_cache_entry_t *cachePtr, int8_t interface_id);
|
||||||
|
|
||||||
void thread_network_data_context_re_use_timer_update(thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list);
|
void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new route information to route List
|
* Add new route information to route List
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -56,12 +56,14 @@
|
||||||
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_client.h"
|
#include "6LoWPAN/Thread/thread_management_client.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_synch.h"
|
#include "6LoWPAN/Thread/thread_network_synch.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
#include "thread_config.h"
|
#include "thread_config.h"
|
||||||
#include "Common_Protocols/ipv6.h"
|
#include "Common_Protocols/ipv6.h"
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#include "Common_Protocols/icmpv6_radv.h"
|
#include "Common_Protocols/icmpv6_radv.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "tsyn"
|
#define TRACE_GROUP "tsyn"
|
||||||
|
@ -90,7 +92,7 @@ typedef struct thread_network_dynamic_data_entry {
|
||||||
} thread_network_dynamic_data_entry_t;
|
} thread_network_dynamic_data_entry_t;
|
||||||
|
|
||||||
static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id);
|
static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id);
|
||||||
static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child);
|
static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child);
|
||||||
static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link);
|
static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link);
|
||||||
|
|
||||||
thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId)
|
thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId)
|
||||||
|
@ -155,54 +157,53 @@ int thread_network_synch_data_free(int8_t interface_id)
|
||||||
* Dynamic network data storage.
|
* Dynamic network data storage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child)
|
void thread_dynamic_storage_child_info_store(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *child)
|
||||||
{
|
{
|
||||||
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
|
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(cur_interface->id);
|
||||||
|
|
||||||
if (!storeEntry) {
|
if (!storeEntry) {
|
||||||
storeEntry = thread_network_synch_create(interface_id);
|
storeEntry = thread_network_synch_create(cur_interface->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!storeEntry) {
|
if (!storeEntry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child);
|
uint32_t mle_frame_counter = mle_service_neighbor_frame_counter_get(cur_interface->id, child->index);
|
||||||
|
|
||||||
|
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(cur_interface->id, child);
|
||||||
|
if (!child_info) {
|
||||||
|
child_info = thread_dynamic_storage_free_child_find(cur_interface->id);
|
||||||
|
}
|
||||||
|
|
||||||
if (child_info) {
|
if (child_info) {
|
||||||
child_info->mode = child->mode;
|
uint8_t mode = mle_mode_write_from_mac_entry(child);
|
||||||
child_info->short_addr = child->short_adr;
|
mode |= thread_neighbor_class_mode_write_from_entry(&cur_interface->thread_info->neighbor_class, child->index);
|
||||||
child_info->mle_frame_counter = child->mle_frame_counter;
|
|
||||||
|
child_info->mode = mode;
|
||||||
|
child_info->short_addr = child->mac16;
|
||||||
|
child_info->mle_frame_counter = mle_frame_counter;
|
||||||
child_info->mac_frame_counter = 0;
|
child_info->mac_frame_counter = 0;
|
||||||
memcpy(child_info->long_addr, child->mac64, 8);
|
memcpy(child_info->long_addr, child->mac64, 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_info = thread_dynamic_storage_free_child_find(interface_id);
|
|
||||||
|
|
||||||
if (child_info) {
|
|
||||||
child_info->mode = child->mode;
|
|
||||||
child_info->short_addr = child->short_adr;
|
|
||||||
child_info->mle_frame_counter = child->mle_frame_counter;
|
|
||||||
child_info->mac_frame_counter = 0;
|
|
||||||
memcpy(child_info->long_addr, child->mac64, 8);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child)
|
void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child)
|
||||||
{
|
{
|
||||||
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child);
|
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child);
|
||||||
|
|
||||||
if (child_info){
|
if (child_info){
|
||||||
// Clear child information
|
// Clear child information
|
||||||
memset (child_info,0,sizeof(thread_sync_child_info_t));
|
memset (child_info,0,sizeof(thread_sync_child_info_t));
|
||||||
tr_debug("Dynamic storage: cleared child; mac16=%04x", child->short_adr);
|
tr_debug("Dynamic storage: cleared child; mac16=%04x", child->mac16);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child)
|
static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child)
|
||||||
{
|
{
|
||||||
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
|
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
|
||||||
|
|
||||||
|
@ -236,6 +237,10 @@ static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t i
|
||||||
void thread_dynamic_storage_build_mle_table(int8_t interface_id)
|
void thread_dynamic_storage_build_mle_table(int8_t interface_id)
|
||||||
{
|
{
|
||||||
tr_debug("Dynamic storage: building MLE table.");
|
tr_debug("Dynamic storage: building MLE table.");
|
||||||
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur || !cur->mac_parameters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
|
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
|
||||||
bool new_entry_created;
|
bool new_entry_created;
|
||||||
|
@ -248,9 +253,9 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
|
|
||||||
if (!neig_list) {
|
if (!mac_table_list) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,19 +267,21 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id)
|
||||||
}
|
}
|
||||||
uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr;
|
uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr;
|
||||||
tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8));
|
tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8));
|
||||||
mle_neigh_table_entry_t *entry = mle_class_get_entry_by_mac64(interface_id, 64, mac64, true, &new_entry_created);
|
|
||||||
if (entry) {
|
|
||||||
entry->short_adr = storeEntry->networ_dynamic_data_parameters.children[i].short_addr;
|
|
||||||
entry->mle_frame_counter = storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter;
|
|
||||||
entry->mode = storeEntry->networ_dynamic_data_parameters.children[i].mode;
|
|
||||||
entry->threadNeighbor = true;
|
|
||||||
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), mac64, true, &new_entry_created);
|
||||||
|
if (mac_entry) {
|
||||||
|
|
||||||
if (cur && cur->mac_parameters) {
|
mac_entry->mac16 = storeEntry->networ_dynamic_data_parameters.children[i].short_addr;
|
||||||
// Set MAC layer frame counter for the child
|
mle_service_frame_counter_entry_add(interface_id, mac_entry->index, storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter);
|
||||||
mac_helper_devicetable_set(entry, cur, storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, cur->mac_parameters->mac_default_key_index, new_entry_created);
|
mle_mode_parse_to_mac_entry(mac_entry, storeEntry->networ_dynamic_data_parameters.children[i].mode);
|
||||||
}
|
|
||||||
|
// Set MAC layer frame counter for the child
|
||||||
|
mlme_device_descriptor_t device_desc;
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index,64, new_entry_created);
|
||||||
|
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, mac_entry->index,storeEntry->networ_dynamic_data_parameters.children[i].mode);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index);
|
||||||
|
mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64, mac_entry->mac16,storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, mac_entry->index, cur->mac_parameters->mac_default_key_index, new_entry_created);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -35,6 +35,9 @@
|
||||||
#ifndef THREAD_NETWORK_SYNCH_H_
|
#ifndef THREAD_NETWORK_SYNCH_H_
|
||||||
#define THREAD_NETWORK_SYNCH_H_
|
#define THREAD_NETWORK_SYNCH_H_
|
||||||
|
|
||||||
|
struct protocol_interface_info_entry;
|
||||||
|
struct mac_neighbor_table_entry;
|
||||||
|
|
||||||
//Call This when clean synched networkdata
|
//Call This when clean synched networkdata
|
||||||
int thread_network_synch_data_free(int8_t interface_id);
|
int thread_network_synch_data_free(int8_t interface_id);
|
||||||
//Call This when want synch last network setup
|
//Call This when want synch last network setup
|
||||||
|
@ -46,8 +49,8 @@ bool thread_dynamic_storage_pending_configuration_exists(int8_t interface_id);
|
||||||
void thread_dynamic_storage_pending_configuration_read(int8_t interface_id, void *data, uint16_t size);
|
void thread_dynamic_storage_pending_configuration_read(int8_t interface_id, void *data, uint16_t size);
|
||||||
void thread_dynamic_storage_pending_configuration_store(int8_t interface_id, void *data, uint16_t size);
|
void thread_dynamic_storage_pending_configuration_store(int8_t interface_id, void *data, uint16_t size);
|
||||||
|
|
||||||
void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child);
|
void thread_dynamic_storage_child_info_store(struct protocol_interface_info_entry *cur_interface, struct mac_neighbor_table_entry *child);
|
||||||
void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child);
|
void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child);
|
||||||
void thread_dynamic_storage_build_mle_table(int8_t interface_id);
|
void thread_dynamic_storage_build_mle_table(int8_t interface_id);
|
||||||
void thread_dynamic_storage_frame_counter_store(int8_t interface_id, uint32_t mle_frame_counter, uint32_t mac_frame_counter);
|
void thread_dynamic_storage_frame_counter_store(int8_t interface_id, uint32_t mle_frame_counter, uint32_t mac_frame_counter);
|
||||||
uint32_t thread_dynamic_storage_mle_frame_counter_get(int8_t interfaceId);
|
uint32_t thread_dynamic_storage_mle_frame_counter_get(int8_t interfaceId);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -84,7 +84,7 @@ static int thread_nvm_store_fast_data_save(thread_nvm_fast_data_t* fast_data_to_
|
||||||
static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t seq_counter);
|
static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t seq_counter);
|
||||||
static void thread_nvm_store_link_info_delayed_write(uint32_t seconds);
|
static void thread_nvm_store_link_info_delayed_write(uint32_t seconds);
|
||||||
|
|
||||||
#define MAX_ROOT_PATH_LEN 150
|
#define MAX_ROOT_PATH_LEN 200
|
||||||
|
|
||||||
#define FAST_DATA_STRING_LEN (strlen(FAST_DATA_FILE)+strlen(thread_nvm_store_get_root_path())+1)
|
#define FAST_DATA_STRING_LEN (strlen(FAST_DATA_FILE)+strlen(thread_nvm_store_get_root_path())+1)
|
||||||
#define ACTIVE_CONF_STRING_LEN (strlen(THREAD_NVM_ACTIVE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1)
|
#define ACTIVE_CONF_STRING_LEN (strlen(THREAD_NVM_ACTIVE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1)
|
||||||
|
@ -330,6 +330,15 @@ int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint3
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_nvm_store_fast_data_write_all(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = thread_nvm_store_all_counters_store(mac_frame_counter, mle_frame_counter, network_seq_counter);
|
||||||
|
cached_fast_data.mac_frame_counter = mac_frame_counter;
|
||||||
|
cached_fast_data.mle_frame_counter = mle_frame_counter;
|
||||||
|
cached_fast_data.seq_counter=network_seq_counter;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter)
|
int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
* Copyright (c) 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -84,6 +84,9 @@ int thread_nvm_store_fast_data_write(thread_nvm_fast_data_t* fast_data);
|
||||||
int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter);
|
int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter);
|
||||||
/* stores the frame counter and seq counter to nvm only if any threshold is passed*/
|
/* stores the frame counter and seq counter to nvm only if any threshold is passed*/
|
||||||
int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter);
|
int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter);
|
||||||
|
/*Store all fast data values unconditionally*/
|
||||||
|
int thread_nvm_store_fast_data_write_all(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter);
|
||||||
|
|
||||||
/* stores the value to nvm only if it has changed */
|
/* stores the value to nvm only if it has changed */
|
||||||
|
|
||||||
int thread_nvm_store_seq_counter_write(uint32_t network_seq_counter);
|
int thread_nvm_store_seq_counter_write(uint32_t network_seq_counter);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -66,6 +66,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_lowpower_private_api.h"
|
#include "6LoWPAN/Thread/thread_lowpower_private_api.h"
|
||||||
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_nvm_store.h"
|
#include "6LoWPAN/Thread/thread_nvm_store.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
#include "Common_Protocols/ipv6.h"
|
#include "Common_Protocols/ipv6.h"
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
|
@ -83,12 +84,12 @@
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
#include "thread_border_router_api.h"
|
#include "thread_border_router_api.h"
|
||||||
#include "Core/include/address.h"
|
#include "Core/include/address.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#ifdef HAVE_THREAD_ROUTER
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
|
|
||||||
#define TRACE_GROUP "trbs"
|
#define TRACE_GROUP "trbs"
|
||||||
|
|
||||||
static bool thread_rfd_device(uint8_t mode);
|
|
||||||
static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode);
|
static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode);
|
||||||
|
|
||||||
static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
||||||
|
@ -103,18 +104,10 @@ static int thread_router_accept_request_build(protocol_interface_info_entry_t *c
|
||||||
static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv, uint64_t active_timestamp, uint64_t pending_timestamp);
|
static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv, uint64_t active_timestamp, uint64_t pending_timestamp);
|
||||||
static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode);
|
static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode);
|
||||||
static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode);
|
static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode);
|
||||||
static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info);
|
static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req, struct mac_neighbor_table_entry *neigh_info);
|
||||||
|
|
||||||
static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur);
|
static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur);
|
||||||
static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp);
|
static bool thread_child_id_request(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *entry_temp);
|
||||||
|
|
||||||
static bool thread_rfd_device(uint8_t mode)
|
|
||||||
{
|
|
||||||
if ((mode & MLE_DEV_MASK) != MLE_RFD_DEV) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool thread_router_parent_address_check(protocol_interface_info_entry_t *cur, uint8_t *source_addr)
|
static bool thread_router_parent_address_check(protocol_interface_info_entry_t *cur, uint8_t *source_addr)
|
||||||
{
|
{
|
||||||
|
@ -209,7 +202,7 @@ int thread_router_bootstrap_mle_advertise(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *mle_entry, buffer_t *buf)
|
static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry, buffer_t *buf)
|
||||||
{
|
{
|
||||||
link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id);
|
link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id);
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
|
@ -224,7 +217,7 @@ static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle
|
||||||
new_buf->info = (buffer_info_t) (B_DIR_DOWN | B_TO_IPV6_TXRX | B_FROM_IPV6_FWD);
|
new_buf->info = (buffer_info_t) (B_DIR_DOWN | B_TO_IPV6_TXRX | B_FROM_IPV6_FWD);
|
||||||
uint8_t next_hop[16];
|
uint8_t next_hop[16];
|
||||||
memcpy(next_hop, ADDR_LINK_LOCAL_PREFIX, 8);
|
memcpy(next_hop, ADDR_LINK_LOCAL_PREFIX, 8);
|
||||||
memcpy(&next_hop[8], mle_entry->mac64, 8);
|
memcpy(&next_hop[8], entry->mac64, 8);
|
||||||
next_hop[8] ^= 2;
|
next_hop[8] ^= 2;
|
||||||
|
|
||||||
ipv6_buffer_route_to(new_buf, next_hop, cur);
|
ipv6_buffer_route_to(new_buf, next_hop, cur);
|
||||||
|
@ -234,15 +227,11 @@ static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle
|
||||||
|
|
||||||
static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
||||||
{
|
{
|
||||||
mle_neigh_table_list_t *mle_neigh_list = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!mle_neigh_list) {
|
|
||||||
return;
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
}
|
if (!cur_entry->rx_on_idle) {
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_neigh_list) {
|
clone_multicast_to_unicast(cur, cur_entry, buf);
|
||||||
if (cur_entry->threadNeighbor) {
|
|
||||||
if (!(cur_entry->mode & MLE_RX_ON_IDLE)) {
|
|
||||||
clone_multicast_to_unicast(cur, cur_entry, buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,9 +249,9 @@ static void thread_registered_mcast_forward_to_child(protocol_interface_info_ent
|
||||||
tr_debug("Forwarding to registered multicast address: %s", trace_ipv6(addr->address));
|
tr_debug("Forwarding to registered multicast address: %s", trace_ipv6(addr->address));
|
||||||
|
|
||||||
ns_list_foreach(thread_mcast_child_t, child, &addr->children) {
|
ns_list_foreach(thread_mcast_child_t, child, &addr->children) {
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, child->mac64, ADDR_802_15_4_LONG);
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), child->mac64, ADDR_802_15_4_LONG);
|
||||||
if (mle_entry && mle_entry->threadNeighbor && !(mle_entry->mode & MLE_RX_ON_IDLE)) {
|
if (entry && !entry->rx_on_idle) {
|
||||||
clone_multicast_to_unicast(cur, mle_entry, buffer);
|
clone_multicast_to_unicast(cur, entry, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,13 +293,10 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m
|
||||||
uint16_t version, shortAddress, address16;
|
uint16_t version, shortAddress, address16;
|
||||||
uint32_t llFrameCounter;
|
uint32_t llFrameCounter;
|
||||||
mle_tlv_info_t routing;
|
mle_tlv_info_t routing;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
tr_debug("Thread MLE message router sync");
|
tr_debug("Thread MLE message router sync");
|
||||||
//State machine What packet shuold accept in this case
|
//State machine What packet shuold accept in this case
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
if (!cur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that message is from link-local scope */
|
/* Check that message is from link-local scope */
|
||||||
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
|
||||||
|
@ -353,42 +339,56 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Allocate neighbor entry
|
//Allocate neighbor entry
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, &new_neigbour);
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, true, &new_neigbour);
|
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
||||||
|
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
||||||
|
thread_key_guard_timer_reset(cur);
|
||||||
|
} else {
|
||||||
|
tr_error("Key ID Mode 2 not used; dropped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_neigbour);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
|
||||||
//Free Response
|
//Free Response
|
||||||
mle_service_msg_free(messageId);
|
mle_service_msg_free(messageId);
|
||||||
entry_temp->threadNeighbor = true;
|
entry_temp->mac16 = shortAddress;
|
||||||
entry_temp->short_adr = shortAddress;
|
|
||||||
//when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour
|
//when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour
|
||||||
entry_temp->mle_frame_counter = mleFrameCounter;
|
mle_service_frame_counter_entry_add(cur->id, entry_temp->index, mleFrameCounter);
|
||||||
if (entry_temp->timeout_rx) {
|
uint32_t timeout_tlv;
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
|
||||||
|
mle_tlv_info_t mle_tlv_info;
|
||||||
|
|
||||||
|
if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
|
||||||
|
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
|
||||||
} else {
|
} else {
|
||||||
mle_tlv_info_t mle_tlv_info;
|
if (new_neigbour) {
|
||||||
uint32_t timeout_tlv;
|
timeout_tlv = THREAD_DEFAULT_LINK_LIFETIME;
|
||||||
if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
|
|
||||||
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
|
|
||||||
mle_entry_timeout_update(entry_temp, timeout_tlv);
|
|
||||||
} else {
|
} else {
|
||||||
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME);
|
timeout_tlv = entry_temp->link_lifetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_is_router_addr(shortAddress)) {
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout_tlv);
|
||||||
entry_temp->handshakeReady = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET;
|
if (thread_is_router_addr(shortAddress)) {
|
||||||
|
entry_temp->connected_device = 1;
|
||||||
|
}
|
||||||
|
thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
|
||||||
|
|
||||||
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) {
|
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) {
|
||||||
thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh);
|
thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh);
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_neigbour);
|
mlme_device_descriptor_t device_desc;
|
||||||
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_neigbour);
|
||||||
|
|
||||||
//Copy Leader Data
|
//Copy Leader Data
|
||||||
*cur->thread_info->thread_leader_data = leaderData;
|
*cur->thread_info->thread_leader_data = leaderData;
|
||||||
|
@ -949,17 +949,17 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child)
|
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *child)
|
||||||
{
|
{
|
||||||
/* Cleanup occurs for /any/ link we lose to something that looks like a child address,
|
/* Cleanup occurs for /any/ link we lose to something that looks like a child address,
|
||||||
* not just links that are /now/ our children.
|
* not just links that are /now/ our children.
|
||||||
* Due to REED/partition transitions the address may not look like a current child address;
|
* Due to REED/partition transitions the address may not look like a current child address;
|
||||||
* we could be holding a child entry for future repromotion to router with same ID.
|
* we could be holding a child entry for future repromotion to router with same ID.
|
||||||
*/
|
*/
|
||||||
if (thread_is_router_addr(child->short_adr) || child->short_adr >= 0xfffe) {
|
if (thread_is_router_addr(child->mac16) || child->mac16 >= 0xfffe) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tr_debug("Child free %x", child->short_adr);
|
tr_debug("Child free %x", child->mac16);
|
||||||
thread_dynamic_storage_child_info_clear(cur->id, child);
|
thread_dynamic_storage_child_info_clear(cur->id, child);
|
||||||
|
|
||||||
/* As we are losing a link to a child address, we can assume that if we have an IP neighbour cache
|
/* As we are losing a link to a child address, we can assume that if we have an IP neighbour cache
|
||||||
|
@ -967,12 +967,12 @@ int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cu
|
||||||
* finding a new parent, and hence a new 16-bit address. (Losing a link to a router address would not
|
* finding a new parent, and hence a new 16-bit address. (Losing a link to a router address would not
|
||||||
* invalidate our IP->16-bit mapping.)
|
* invalidate our IP->16-bit mapping.)
|
||||||
*/
|
*/
|
||||||
protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->short_adr);
|
protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->mac16);
|
||||||
|
|
||||||
// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
|
// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
|
||||||
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) {
|
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->mac16)) {
|
||||||
tr_debug("Remove references to Child's RLOC16 from the Network Data");
|
tr_debug("Remove references to Child's RLOC16 from the Network Data");
|
||||||
thread_management_client_network_data_unregister(cur->id, child->short_adr);
|
thread_management_client_network_data_unregister(cur->id, child->mac16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all (sleepy) child registrations to multicast groups
|
// Clear all (sleepy) child registrations to multicast groups
|
||||||
|
@ -991,13 +991,11 @@ void thread_router_bootstrap_child_information_clear(protocol_interface_info_ent
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove mle neighbour entries for children in previous partition
|
// Remove mle neighbour entries for children in previous partition
|
||||||
mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!entry_list) {
|
|
||||||
return;
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, table_entry, mac_table_list) {
|
||||||
}
|
if (table_entry->mac16 < 0xfffe && !thread_is_router_addr(table_entry->mac16)) {
|
||||||
ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) {
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), table_entry);
|
||||||
if (table_entry->short_adr < 0xfffe && !thread_is_router_addr(table_entry->short_adr)) {
|
|
||||||
mle_class_remove_entry(cur->id, table_entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1006,17 +1004,14 @@ static void thread_router_bootstrap_invalid_child_information_clear(protocol_int
|
||||||
|
|
||||||
tr_debug("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc);
|
tr_debug("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc);
|
||||||
|
|
||||||
mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!entry_list) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// scrub neighbours with child addresses that are not ours
|
// scrub neighbours with child addresses that are not ours
|
||||||
ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) {
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, table_entry, mac_table_list) {
|
||||||
if (table_entry->short_adr < 0xfffe &&
|
if (table_entry->mac16 < 0xfffe &&
|
||||||
!thread_is_router_addr(table_entry->short_adr) &&
|
!thread_is_router_addr(table_entry->mac16) &&
|
||||||
thread_router_addr_from_addr(table_entry->short_adr) != router_rloc) {
|
thread_router_addr_from_addr(table_entry->mac16) != router_rloc) {
|
||||||
mle_class_remove_entry(cur->id, table_entry);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), table_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1105,7 +1100,7 @@ void thread_router_bootstrap_router_id_request(protocol_interface_info_entry_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info)
|
static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req, struct mac_neighbor_table_entry *neigh_info)
|
||||||
{
|
{
|
||||||
uint16_t len = 12 + 4; //Leader data and short address
|
uint16_t len = 12 + 4; //Leader data and short address
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
@ -1117,7 +1112,7 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neigh_info->mode & MLE_THREAD_REQ_FULL_DATA_SET) {
|
if (thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, neigh_info->index)) {
|
||||||
fullList = true;
|
fullList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,7 +1158,7 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c
|
||||||
ptr = mle_general_write_source_address(ptr, cur);
|
ptr = mle_general_write_source_address(ptr, cur);
|
||||||
|
|
||||||
if (child_req->shortAddressReq) {
|
if (child_req->shortAddressReq) {
|
||||||
ptr = mle_tlv_write_short_address(ptr, neigh_info->short_adr);
|
ptr = mle_tlv_write_short_address(ptr, neigh_info->mac16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child_req->routeReq) {
|
if (child_req->routeReq) {
|
||||||
|
@ -1214,12 +1209,10 @@ uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t
|
||||||
if (router_address >= 0xfffe) {
|
if (router_address >= 0xfffe) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!mle_table) {
|
|
||||||
return -1;
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
}
|
if (thread_router_addr_from_addr(cur_entry->mac16) == router_address) {
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
|
|
||||||
if (thread_router_addr_from_addr(cur_entry->short_adr) == router_address) {
|
|
||||||
child_count++;
|
child_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1228,22 +1221,19 @@ uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t
|
||||||
|
|
||||||
static uint16_t thread_router_bootstrap_child_address_generate(protocol_interface_info_entry_t *cur)
|
static uint16_t thread_router_bootstrap_child_address_generate(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!mle_table) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) {
|
if (thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) {
|
||||||
tr_info("Maximum count %d reached", cur->thread_info->maxChildCount);
|
tr_info("Maximum count %d reached", cur->thread_info->maxChildCount);
|
||||||
return 0xffff;
|
return 0xfffe;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool address_allocated = false;
|
bool address_allocated = false;
|
||||||
for (uint16_t i = 0; i < cur->thread_info->maxChildCount; i++) {
|
for (uint16_t i = 0; i < cur->thread_info->maxChildCount; i++) {
|
||||||
address_allocated = false;
|
address_allocated = false;
|
||||||
cur->thread_info->lastAllocatedChildAddress = (cur->thread_info->lastAllocatedChildAddress % THREAD_MAX_CHILD_ID_COUNT) + 1;
|
cur->thread_info->lastAllocatedChildAddress = (cur->thread_info->lastAllocatedChildAddress % THREAD_MAX_CHILD_ID_COUNT) + 1;
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
if ( (cur_entry->short_adr & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) {
|
if ( (cur_entry->mac16 & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) {
|
||||||
address_allocated = true;
|
address_allocated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1254,29 +1244,29 @@ static uint16_t thread_router_bootstrap_child_address_generate(protocol_interfac
|
||||||
}
|
}
|
||||||
if (address_allocated){
|
if (address_allocated){
|
||||||
// all possible addresses already allocated
|
// all possible addresses already allocated
|
||||||
return 0xffff;
|
return 0xfffe;
|
||||||
}
|
}
|
||||||
return ((mac_helper_mac16_address_get(cur) & THREAD_ROUTER_MASK) | cur->thread_info->lastAllocatedChildAddress);
|
return ((mac_helper_mac16_address_get(cur) & THREAD_ROUTER_MASK) | cur->thread_info->lastAllocatedChildAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp)
|
static bool thread_child_id_request(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *entry_temp)
|
||||||
{
|
{
|
||||||
//Remove All Short address links from router
|
//Remove All Short address links from router
|
||||||
if (entry_temp->short_adr != 0xffff) {
|
if (entry_temp->mac16 < 0xfffe) {
|
||||||
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr);
|
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16);
|
||||||
}
|
}
|
||||||
|
|
||||||
//allocate child address if current is router, 0xffff or not our child
|
//allocate child address if current is router, 0xffff or not our child
|
||||||
if (!thread_addr_is_child(mac_helper_mac16_address_get(cur), entry_temp->short_adr)) {
|
if (!thread_addr_is_child(mac_helper_mac16_address_get(cur), entry_temp->mac16)) {
|
||||||
entry_temp->short_adr = thread_router_bootstrap_child_address_generate(cur);
|
entry_temp->mac16 = thread_router_bootstrap_child_address_generate(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry_temp->short_adr == 0xffff) {
|
if (entry_temp->mac16 >= 0xfffe) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store this child info to the NVM
|
// Store this child info to the NVM
|
||||||
thread_dynamic_storage_child_info_store(cur->id, entry_temp);
|
thread_dynamic_storage_child_info_store(cur, entry_temp);
|
||||||
//}
|
//}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1301,7 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c
|
||||||
memcpy(&ll64[8], req->euid64 , 8);
|
memcpy(&ll64[8], req->euid64 , 8);
|
||||||
ll64[8] ^= 2;
|
ll64[8] ^= 2;
|
||||||
//Allocate entry
|
//Allocate entry
|
||||||
mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, true, &new_neigbour);
|
mac_neighbor_table_entry_t *entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, true, &new_neigbour);
|
||||||
|
|
||||||
if (!entry_temp) {
|
if (!entry_temp) {
|
||||||
//Send link reject
|
//Send link reject
|
||||||
|
@ -1319,44 +1309,48 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c
|
||||||
goto free_request;
|
goto free_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, req->linkMargin, new_neigbour);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
|
||||||
// If mac frame couter is less than previous we need to leave the old one
|
// If mac frame couter is less than previous we need to leave the old one
|
||||||
|
|
||||||
//Update or set neigh info
|
//Update or set neigh info
|
||||||
entry_temp->holdTime = 90;
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, req->timeout);
|
||||||
|
mle_mode_parse_to_mac_entry(entry_temp, req->mode);
|
||||||
mle_entry_timeout_update(entry_temp, req->timeout);
|
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, req->mode);
|
||||||
entry_temp->mode = req->mode;
|
entry_temp->connected_device = 1;
|
||||||
entry_temp->threadNeighbor = true;
|
mle_service_frame_counter_entry_add(cur->id, entry_temp->index, req->mleFrameCounter);
|
||||||
entry_temp->handshakeReady = 1;
|
|
||||||
entry_temp->mle_frame_counter = req->mleFrameCounter;
|
|
||||||
|
|
||||||
if (req->shortAddressReq) {
|
if (req->shortAddressReq) {
|
||||||
if (!thread_child_id_request(cur, entry_temp)) {
|
if (!thread_child_id_request(cur, entry_temp)) {
|
||||||
mle_class_remove_entry(cur->id, entry_temp);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
thread_link_reject_send(cur, ll64);
|
thread_link_reject_send(cur, ll64);
|
||||||
goto free_request;
|
goto free_request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (new_neigbour) {
|
if (new_neigbour) {
|
||||||
mac_helper_devicetable_set(entry_temp, cur, req->frameCounter, req->keyId, new_neigbour);
|
mlme_device_descriptor_t device_desc;
|
||||||
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,req->frameCounter, false);
|
||||||
|
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, req->keyId, new_neigbour);
|
||||||
} else {
|
} else {
|
||||||
// in get response handler this will update the short address from MLE table
|
// in get response handler this will update the short address from MLE table
|
||||||
mlme_get_t get_req;
|
mlme_get_t get_req;
|
||||||
get_req.attr = macDeviceTable;
|
get_req.attr = macDeviceTable;
|
||||||
get_req.attr_index = entry_temp->attribute_index;
|
get_req.attr_index = entry_temp->index;
|
||||||
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Register MLEID if RRFD device
|
//Register MLEID if RRFD device
|
||||||
if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
|
if (!entry_temp->ffd_device) {
|
||||||
uint8_t tempIPv6Address[16];
|
uint8_t tempIPv6Address[16];
|
||||||
memcpy(tempIPv6Address, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8);
|
memcpy(tempIPv6Address, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8);
|
||||||
memcpy(&tempIPv6Address[8], req->eiid, 8);
|
memcpy(&tempIPv6Address[8], req->eiid, 8);
|
||||||
memcpy(&entry_temp->mlEid, req->eiid, 8);
|
|
||||||
|
thread_neighbor_class_add_mleid(&cur->thread_info->neighbor_class, entry_temp->index, req->eiid);
|
||||||
|
|
||||||
tr_debug("Register %s", trace_ipv6(tempIPv6Address));
|
tr_debug("Register %s", trace_ipv6(tempIPv6Address));
|
||||||
//Register GP --> 16
|
//Register GP --> 16
|
||||||
thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64);
|
thread_nd_address_registration(cur, tempIPv6Address, entry_temp->mac16, cur->mac_parameters->pan_id, entry_temp->mac64, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_attach_child_id_response_build(cur,ll64,req, entry_temp);
|
mle_attach_child_id_response_build(cur,ll64,req, entry_temp);
|
||||||
|
@ -1371,6 +1365,7 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
lowpan_context_t *ctx;
|
lowpan_context_t *ctx;
|
||||||
uint8_t tempIPv6Address[16];
|
uint8_t tempIPv6Address[16];
|
||||||
uint8_t ctxId;
|
uint8_t ctxId;
|
||||||
|
bool new_neighbour_created;
|
||||||
|
|
||||||
while (data_length) {
|
while (data_length) {
|
||||||
//Read
|
//Read
|
||||||
|
@ -1383,8 +1378,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
memcpy(&tempIPv6Address[8], ptr, 8);
|
memcpy(&tempIPv6Address[8], ptr, 8);
|
||||||
tr_debug("Register %s", trace_ipv6(tempIPv6Address));
|
tr_debug("Register %s", trace_ipv6(tempIPv6Address));
|
||||||
//Register GP --> 16
|
//Register GP --> 16
|
||||||
thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64);
|
int retVal = thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
|
||||||
thread_extension_address_registration(cur, tempIPv6Address, mac64);
|
thread_extension_address_registration(cur, tempIPv6Address, mac64, new_neighbour_created, retVal == -2);
|
||||||
} else {
|
} else {
|
||||||
tr_debug("No Context %u", ctxId);
|
tr_debug("No Context %u", ctxId);
|
||||||
}
|
}
|
||||||
|
@ -1403,8 +1398,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Register GP --> 16
|
//Register GP --> 16
|
||||||
thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64);
|
int retVal = thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
|
||||||
thread_extension_address_registration(cur, ptr, mac64);
|
thread_extension_address_registration(cur, ptr, mac64, new_neighbour_created, retVal == -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += 16;
|
ptr += 16;
|
||||||
|
@ -1415,14 +1410,12 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
|
|
||||||
void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
|
||||||
{
|
{
|
||||||
|
(void) interface_id;
|
||||||
thread_leader_data_t leaderData;
|
thread_leader_data_t leaderData;
|
||||||
mle_neigh_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool rssiTLV;
|
bool rssiTLV;
|
||||||
bool leaderDataReceived;
|
bool leaderDataReceived;
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
|
||||||
if (!cur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TLV REQUSTED
|
//TLV REQUSTED
|
||||||
if (mle_tlv_type_requested(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length)) {
|
if (mle_tlv_type_requested(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length)) {
|
||||||
|
@ -1471,9 +1464,13 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
// parent request received
|
// parent request received
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
if (entry_temp) {
|
if (entry_temp) {
|
||||||
entry_temp->mode = (MLE_FFD_DEV | MLE_RX_ON_IDLE | MLE_THREAD_REQ_FULL_DATA_SET);
|
//Set MAC modes
|
||||||
|
mle_mode_parse_to_mac_entry(entry_temp, (MLE_FFD_DEV | MLE_RX_ON_IDLE));
|
||||||
|
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, MLE_THREAD_REQ_FULL_DATA_SET);
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
}
|
}
|
||||||
if(!entry_temp) {
|
if(!entry_temp) {
|
||||||
if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) {
|
if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) {
|
||||||
|
@ -1487,17 +1484,17 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_class_free_entry_count_get(cur->id) < 1) {
|
if (mle_class_free_entry_count_get(cur) < 1) {
|
||||||
tr_info("Drop MLE message: no space left in the MLE table");
|
tr_info("Drop MLE message: no space left in the MLE table");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur->id) >= THREAD_MAX_MTD_CHILDREN) {
|
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur) >= THREAD_MAX_MTD_CHILDREN) {
|
||||||
tr_info("Drop MLE message: maximum MTD child count reached.");
|
tr_info("Drop MLE message: maximum MTD child count reached.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur->id) >= THREAD_MAX_SED_CHILDREN) {
|
if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur) >= THREAD_MAX_SED_CHILDREN) {
|
||||||
tr_info("Drop MLE message: maximum SED child count reached.");
|
tr_info("Drop MLE message: maximum SED child count reached.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1571,10 +1568,14 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are in REED mode and receive child IR request from our parent, call connection error.
|
// If we are in REED mode and receive child ID request from our parent, call connection error.
|
||||||
if (thread_am_reed(cur)) {
|
if (thread_am_reed(cur)) {
|
||||||
if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) {
|
if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) {
|
||||||
tr_debug("Child ID req from own parent -> connection error");
|
tr_debug("Child ID req from own parent -> connection error");
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
if (entry_temp) {
|
||||||
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
|
}
|
||||||
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1714,7 +1715,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
if (mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) {
|
if (mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) {
|
||||||
//Correct TLV's lets response
|
//Correct TLV's lets response
|
||||||
if (!thread_is_router_addr(shortAddress)) {
|
if (!thread_is_router_addr(shortAddress)) {
|
||||||
if (leaderDataReceived && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) {
|
if (leaderDataReceived && thread_partition_match(cur, &leaderData)) {
|
||||||
//REED or end device send response
|
//REED or end device send response
|
||||||
thread_router_accept_to_endevice(cur, mle_msg, challengeTlv.dataPtr, challengeTlv.tlvLen);
|
thread_router_accept_to_endevice(cur, mle_msg, challengeTlv.dataPtr, challengeTlv.tlvLen);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1726,7 +1727,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
|
||||||
if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) {
|
if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) {
|
||||||
|
|
||||||
|
@ -1738,9 +1739,11 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (entry_temp && entry_temp->handshakeReady) {
|
if (entry_temp && entry_temp->connected_device) {
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
|
||||||
thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen);
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->mac16, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool update_mac_mib = false;
|
bool update_mac_mib = false;
|
||||||
|
@ -1759,7 +1762,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
//validate partition id
|
//validate partition id
|
||||||
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) {
|
if (!thread_partition_match(cur, &leaderData)) {
|
||||||
tr_debug("Drop link request from wrong partition");
|
tr_debug("Drop link request from wrong partition");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1767,26 +1770,28 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
if (entry_temp) {
|
if (entry_temp) {
|
||||||
/*remove from child list when becoming router*/
|
/*remove from child list when becoming router*/
|
||||||
// Was this previously our child? If yes, update.
|
// Was this previously our child? If yes, update.
|
||||||
if ((entry_temp->short_adr & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) {
|
if ((entry_temp->mac16 & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->mac16) == cur->thread_info->routerShortAddress) {
|
||||||
thread_dynamic_storage_child_info_clear(cur->id, entry_temp);
|
thread_dynamic_storage_child_info_clear(cur->id, entry_temp);
|
||||||
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr);
|
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16);
|
||||||
}
|
}
|
||||||
update_mac_mib = true;
|
update_mac_mib = true;
|
||||||
entry_temp->short_adr = shortAddress; // short address refreshed
|
entry_temp->mac16 = shortAddress; // short address refreshed
|
||||||
|
|
||||||
if (entry_temp->handshakeReady) {
|
if (entry_temp->connected_device) {
|
||||||
if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) {
|
if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) {
|
||||||
if (thread_rfd_device(entry_temp->mode)) {
|
if (!entry_temp->ffd_device) {
|
||||||
thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64);
|
thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->mac16, entry_temp->mac64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
if (!mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex) && update_mac_mib) {
|
if (!mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex) && update_mac_mib) {
|
||||||
//GET
|
//GET
|
||||||
mlme_get_t get_req;
|
mlme_get_t get_req;
|
||||||
get_req.attr = macDeviceTable;
|
get_req.attr = macDeviceTable;
|
||||||
get_req.attr_index = entry_temp->attribute_index;
|
get_req.attr_index = entry_temp->index;
|
||||||
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
||||||
}
|
}
|
||||||
response_type = MLE_COMMAND_ACCEPT;
|
response_type = MLE_COMMAND_ACCEPT;
|
||||||
|
@ -1853,32 +1858,41 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
createNew = thread_bootstrap_link_create_check(cur, shortAddress);
|
createNew = thread_bootstrap_link_create_check(cur, shortAddress);
|
||||||
|
|
||||||
//Send Response
|
//Send Response
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry);
|
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, createNew, &new_entry);
|
||||||
if (entry_temp) {
|
if (entry_temp) {
|
||||||
|
|
||||||
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, new_entry);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
|
||||||
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_temp->threadNeighbor = true;
|
entry_temp->mac16 = shortAddress;
|
||||||
entry_temp->short_adr = shortAddress;
|
mlme_device_descriptor_t device_desc;
|
||||||
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry);
|
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
|
||||||
if (entry_temp->timeout_rx) {
|
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry);
|
||||||
mle_entry_timeout_refresh(entry_temp);
|
|
||||||
|
uint32_t link_lifetime;
|
||||||
|
if (new_entry) {
|
||||||
|
link_lifetime = THREAD_DEFAULT_LINK_LIFETIME;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME);
|
link_lifetime = entry_temp->link_lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, link_lifetime);
|
||||||
|
|
||||||
if (thread_is_router_addr(shortAddress)) {
|
if (thread_is_router_addr(shortAddress)) {
|
||||||
entry_temp->handshakeReady = 1;
|
entry_temp->connected_device = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET;
|
thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
|
||||||
|
|
||||||
thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh);
|
thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh);
|
||||||
//Read Source address and Challenge
|
//Read Source address and Challenge
|
||||||
mac_data_poll_protocol_poll_mode_decrement(cur);
|
mac_data_poll_protocol_poll_mode_decrement(cur);
|
||||||
thread_router_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin);
|
thread_router_accept_request_build(cur, mle_msg, entry_temp->mac16, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin);
|
||||||
|
|
||||||
blacklist_update(mle_msg->packet_src_address, true);
|
blacklist_update(mle_msg->packet_src_address, true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1899,11 +1913,12 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
mle_tlv_info_t addressRegisterTlv = {0};
|
mle_tlv_info_t addressRegisterTlv = {0};
|
||||||
mle_tlv_info_t challengeTlv = {0};
|
mle_tlv_info_t challengeTlv = {0};
|
||||||
mle_tlv_info_t tlv_req = {0};
|
mle_tlv_info_t tlv_req = {0};
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
|
|
||||||
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) {
|
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) {
|
||||||
if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) {
|
if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) {
|
||||||
tr_debug("parent has removed REED");
|
tr_debug("Parent has removed REED");
|
||||||
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
|
||||||
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -1923,9 +1938,10 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
//Keep alive updated
|
//Keep alive updated
|
||||||
entry_temp->ttl = entry_temp->timeout_rx;
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
|
||||||
entry_temp->last_contact_time = protocol_core_monotonic_time;
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
entry_temp->mode = mode;
|
mle_mode_parse_to_mac_entry(entry_temp, mode);
|
||||||
|
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, mode);
|
||||||
|
|
||||||
addressRegisterTlv.tlvType = MLE_TYPE_UNASSIGNED;
|
addressRegisterTlv.tlvType = MLE_TYPE_UNASSIGNED;
|
||||||
mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisterTlv);
|
mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisterTlv);
|
||||||
|
@ -1935,25 +1951,26 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req);
|
mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req);
|
||||||
|
|
||||||
if (addressRegisterTlv.tlvType == MLE_TYPE_ADDRESS_REGISTRATION &&
|
if (addressRegisterTlv.tlvType == MLE_TYPE_ADDRESS_REGISTRATION &&
|
||||||
thread_rfd_device(entry_temp->mode)) {
|
!entry_temp->ffd_device) {
|
||||||
|
|
||||||
tr_debug("Register child address");
|
tr_debug("Register child address");
|
||||||
thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64);
|
thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->mac16, entry_temp->mac64);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) {
|
if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) {
|
||||||
|
|
||||||
tr_debug("Setting child timeout, value=%"PRIu32, timeout);
|
tr_debug("Setting child timeout, value=%"PRIu32, timeout);
|
||||||
entry_temp->holdTime = 90;
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
|
||||||
mle_entry_timeout_update(entry_temp, timeout);
|
} else {
|
||||||
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!leaderDataReceived) {
|
if (!leaderDataReceived) {
|
||||||
tr_debug("Child synch req");
|
tr_debug("Child synch req");
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_debug("Keep-Alive -->Respond Child");
|
tr_debug("Keep-Alive -->Respond Child");
|
||||||
//Response
|
//Response
|
||||||
thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->short_adr, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv, active_timestamp, pending_timestamp);
|
thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->mac16, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv, active_timestamp, pending_timestamp);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1969,11 +1986,16 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
case MLE_COMMAND_DATA_REQUEST: {
|
case MLE_COMMAND_DATA_REQUEST: {
|
||||||
mle_tlv_info_t requestTlv;
|
mle_tlv_info_t requestTlv;
|
||||||
tr_info("Recv Router Data Request");
|
tr_info("Recv Router Data Request");
|
||||||
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
|
|
||||||
|
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
|
||||||
if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) {
|
if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, entry_temp->mode);
|
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
|
||||||
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
uint8_t mode = mle_mode_write_from_mac_entry(entry_temp);
|
||||||
|
mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, mode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2184,7 +2206,10 @@ void thread_router_bootstrap_child_id_reject(protocol_interface_info_entry_t *cu
|
||||||
while (req) {
|
while (req) {
|
||||||
tr_debug("Remove entry from list");
|
tr_debug("Remove entry from list");
|
||||||
//Remove entry from list
|
//Remove entry from list
|
||||||
mle_class_remove_neighbour(cur->id, req->euid64, ADDR_802_15_4_LONG);
|
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), req->euid64, ADDR_802_15_4_LONG);
|
||||||
|
if (neighbor) {
|
||||||
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor);
|
||||||
|
}
|
||||||
|
|
||||||
ns_dyn_mem_free(req);
|
ns_dyn_mem_free(req);
|
||||||
req = thread_child_id_request_entry_get_from_the_list(cur);
|
req = thread_child_id_request_entry_get_from_the_list(cur);
|
||||||
|
@ -2206,7 +2231,6 @@ void thread_router_bootstrap_active_router_attach(protocol_interface_info_entry_
|
||||||
cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
|
cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
|
||||||
thread_routing_activate(&cur->thread_info->routing);
|
thread_routing_activate(&cur->thread_info->routing);
|
||||||
thread_router_synch_new_router(cur, ADDR_LINK_LOCAL_ALL_ROUTERS);
|
thread_router_synch_new_router(cur, ADDR_LINK_LOCAL_ALL_ROUTERS);
|
||||||
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
|
|
||||||
thread_bootstrap_ready(cur);
|
thread_bootstrap_ready(cur);
|
||||||
thread_bootstrap_network_prefixes_process(cur);
|
thread_bootstrap_network_prefixes_process(cur);
|
||||||
thread_nd_service_activate(cur->id);
|
thread_nd_service_activate(cur->id);
|
||||||
|
@ -2226,7 +2250,7 @@ static int thread_validate_own_routeid_from_new_mask(const uint8_t *master_route
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry)
|
int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, struct mac_neighbor_table_entry *entry)
|
||||||
{
|
{
|
||||||
(void) route_len;
|
(void) route_len;
|
||||||
|
|
||||||
|
@ -2239,9 +2263,9 @@ int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur,
|
||||||
route_data = route_tlv;
|
route_data = route_tlv;
|
||||||
uint16_t mac16 = mac_helper_mac16_address_get(cur);
|
uint16_t mac16 = mac_helper_mac16_address_get(cur);
|
||||||
|
|
||||||
if (!thread_is_router_addr(entry->short_adr)) {
|
if (!thread_is_router_addr(entry->mac16)) {
|
||||||
// Received route tlv from non router ignore
|
// Received route tlv from non router ignore
|
||||||
tr_info("drop route Processing from end device %x", entry->short_adr);
|
tr_info("drop route Processing from end device %x", entry->mac16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2251,21 +2275,20 @@ int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur,
|
||||||
thread_routing_leader_connection_validate(cur->thread_info,routing->networkFragmentationTimer);
|
thread_routing_leader_connection_validate(cur->thread_info,routing->networkFragmentationTimer);
|
||||||
routing->networkFragmentationTimer = 0;
|
routing->networkFragmentationTimer = 0;
|
||||||
if (thread_validate_own_routeid_from_new_mask(router_id_mask, thread_router_id_from_addr(mac16)) != 0) {
|
if (thread_validate_own_routeid_from_new_mask(router_id_mask, thread_router_id_from_addr(mac16)) != 0) {
|
||||||
|
|
||||||
tr_debug("RouterID not valid any More");
|
tr_debug("RouterID not valid any More");
|
||||||
thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_KICK, NULL);
|
thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_KICK, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!thread_info(cur)->thread_endnode_parent ||
|
} else if (!thread_info(cur)->thread_endnode_parent ||
|
||||||
thread_info(cur)->thread_endnode_parent->shortAddress != entry->short_adr ) {
|
thread_info(cur)->thread_endnode_parent->shortAddress != entry->mac16 ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */
|
/* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */
|
||||||
/* Don't add routing link if MLE link is NOT bi-directional (i.e. we can only hear) */
|
/* Don't add routing link if MLE link is NOT bi-directional (i.e. we can only hear) */
|
||||||
if (entry->handshakeReady) {
|
if (entry->connected_device) {
|
||||||
thread_routing_add_link(cur, entry->short_adr, linkMargin, route_id_seq, router_id_mask, route_data, false);
|
thread_routing_add_link(cur, entry->mac16, linkMargin, route_id_seq, router_id_mask, route_data, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2342,6 +2365,13 @@ static void thread_reed_advertisements_cb(void* arg)
|
||||||
protocol_interface_info_entry_t *cur = arg;
|
protocol_interface_info_entry_t *cur = arg;
|
||||||
|
|
||||||
cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL;
|
cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL;
|
||||||
|
|
||||||
|
if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) {
|
||||||
|
/* Own attach is ongoing, try to send advertisement after few seconds */
|
||||||
|
cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb, 2 * 1000, cur);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED &&
|
if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED &&
|
||||||
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){
|
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){
|
||||||
thread_reed_advertise(cur);
|
thread_reed_advertise(cur);
|
||||||
|
@ -2461,23 +2491,22 @@ void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress)
|
void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, struct mac_neighbor_table_entry *entry_temp, uint16_t shortAddress)
|
||||||
{
|
{
|
||||||
if (entry_temp) {
|
if (entry_temp) {
|
||||||
entry_temp->threadNeighbor = true;
|
|
||||||
|
|
||||||
if (entry_temp->timeout_rx == 0 || thread_is_router_addr(shortAddress)) {
|
if (thread_is_router_addr(shortAddress)) {
|
||||||
entry_temp->timeout_rx = THREAD_DEFAULT_LINK_LIFETIME / MLE_TIMER_TICKS_SECONDS;
|
entry_temp->link_lifetime = THREAD_DEFAULT_LINK_LIFETIME;
|
||||||
entry_temp->timeout_rx++;
|
entry_temp->link_lifetime++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_is_router_addr(shortAddress)) {
|
if (thread_is_router_addr(shortAddress)) {
|
||||||
//Update MAC Security PIB table by get & set Operation
|
//Update MAC Security PIB table by get & set Operation
|
||||||
mlme_get_t get_req;
|
mlme_get_t get_req;
|
||||||
get_req.attr = macDeviceTable;
|
get_req.attr = macDeviceTable;
|
||||||
get_req.attr_index = entry_temp->attribute_index;
|
get_req.attr_index = entry_temp->index;
|
||||||
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
||||||
entry_temp->ttl = entry_temp->timeout_rx;
|
entry_temp->lifetime = entry_temp->link_lifetime;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
|
@ -2661,19 +2690,18 @@ static int thread_router_bootstrap_network_data_propagation(protocol_interface_i
|
||||||
static void thread_router_bootstrap_network_data_push_to_sleep_child(protocol_interface_info_entry_t *cur, bool stableDataUpdate)
|
static void thread_router_bootstrap_network_data_push_to_sleep_child(protocol_interface_info_entry_t *cur, bool stableDataUpdate)
|
||||||
{
|
{
|
||||||
uint8_t childLinkLocalAddress[16];
|
uint8_t childLinkLocalAddress[16];
|
||||||
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
|
|
||||||
memcpy(childLinkLocalAddress, ADDR_LINK_LOCAL_PREFIX, 8);
|
memcpy(childLinkLocalAddress, ADDR_LINK_LOCAL_PREFIX, 8);
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
if (cur_entry->threadNeighbor) {
|
if (!cur_entry->rx_on_idle) {
|
||||||
if (!(cur_entry->mode & MLE_RX_ON_IDLE)) {
|
memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8);
|
||||||
memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8);
|
childLinkLocalAddress[8] ^= 2;
|
||||||
childLinkLocalAddress[8] ^= 2;
|
if (thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, cur_entry->index)) {
|
||||||
if (cur_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET) {
|
thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true);
|
||||||
thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true);
|
} else {
|
||||||
} else {
|
if (stableDataUpdate) {
|
||||||
if (stableDataUpdate) {
|
thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false);
|
||||||
thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -43,13 +43,14 @@ struct protocol_interface_info_entry;
|
||||||
struct thread_info_s;
|
struct thread_info_s;
|
||||||
struct mle_security_header;
|
struct mle_security_header;
|
||||||
struct buffer;
|
struct buffer;
|
||||||
|
struct mac_neighbor_table_entry;
|
||||||
|
|
||||||
void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur);
|
void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur);
|
||||||
void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur);
|
void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur);
|
||||||
int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur);
|
int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur);
|
||||||
|
|
||||||
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur);
|
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur);
|
||||||
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child);
|
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *child);
|
||||||
uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur);
|
uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur);
|
||||||
void thread_router_bootstrap_child_id_handler(struct protocol_interface_info_entry *cur);
|
void thread_router_bootstrap_child_id_handler(struct protocol_interface_info_entry *cur);
|
||||||
void thread_router_bootstrap_child_id_reject(struct protocol_interface_info_entry *cur);
|
void thread_router_bootstrap_child_id_reject(struct protocol_interface_info_entry *cur);
|
||||||
|
@ -61,11 +62,11 @@ int thread_router_bootstrap_link_synch_start(struct protocol_interface_info_entr
|
||||||
bool thread_router_bootstrap_router_downgrade(struct protocol_interface_info_entry *cur);
|
bool thread_router_bootstrap_router_downgrade(struct protocol_interface_info_entry *cur);
|
||||||
bool thread_router_bootstrap_reed_upgrade(struct protocol_interface_info_entry *cur);
|
bool thread_router_bootstrap_reed_upgrade(struct protocol_interface_info_entry *cur);
|
||||||
void thread_router_bootstrap_active_router_attach(struct protocol_interface_info_entry *cur);
|
void thread_router_bootstrap_active_router_attach(struct protocol_interface_info_entry *cur);
|
||||||
int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry);
|
int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, struct mac_neighbor_table_entry *entry);
|
||||||
void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, struct mle_security_header *security_headers);
|
void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, struct mle_security_header *security_headers);
|
||||||
void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_t ticks);
|
void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_t ticks);
|
||||||
uint32_t thread_router_bootstrap_random_upgrade_jitter();
|
uint32_t thread_router_bootstrap_random_upgrade_jitter(void);
|
||||||
void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress);
|
void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, struct mac_neighbor_table_entry *entry_temp, uint16_t shortAddress);
|
||||||
|
|
||||||
void thread_router_bootstrap_multicast_forwarder_enable(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
void thread_router_bootstrap_multicast_forwarder_enable(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
||||||
void thread_router_bootstrap_anycast_address_register(protocol_interface_info_entry_t *cur);
|
void thread_router_bootstrap_anycast_address_register(protocol_interface_info_entry_t *cur);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -52,6 +52,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_routing.h"
|
#include "6LoWPAN/Thread/thread_routing.h"
|
||||||
#include "6LoWPAN/Thread/thread_leader_service.h"
|
#include "6LoWPAN/Thread/thread_leader_service.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "trou"
|
#define TRACE_GROUP "trou"
|
||||||
|
|
||||||
|
@ -183,7 +184,7 @@ static inline thread_link_quality_e thread_quality_combine(thread_link_quality_e
|
||||||
/* Return the quality (worse of incoming and outgoing quality) for a neighbour router */
|
/* Return the quality (worse of incoming and outgoing quality) for a neighbour router */
|
||||||
static inline thread_link_quality_e thread_neighbour_router_quality(const thread_router_link_t *neighbour)
|
static inline thread_link_quality_e thread_neighbour_router_quality(const thread_router_link_t *neighbour)
|
||||||
{
|
{
|
||||||
return thread_quality_combine(neighbour->incoming_quality, neighbour->outgoing_quality);
|
return thread_quality_combine((thread_link_quality_e) neighbour->incoming_quality, (thread_link_quality_e) neighbour->outgoing_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,8 +266,8 @@ static int_fast8_t thread_route_fn(
|
||||||
uint16_t dest_router_addr = thread_router_addr_from_addr(dest);
|
uint16_t dest_router_addr = thread_router_addr_from_addr(dest);
|
||||||
if (dest_router_addr == mac16) {
|
if (dest_router_addr == mac16) {
|
||||||
/* We're this device's parent - transmit direct to it */
|
/* We're this device's parent - transmit direct to it */
|
||||||
mle_neigh_table_entry_t *entry = mle_class_get_by_link_address(cur->id, dest_addr, ADDR_802_15_4_SHORT);
|
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), dest_addr, ADDR_802_15_4_SHORT);
|
||||||
if (!entry || (entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
|
if (!entry || !entry->ffd_device) {
|
||||||
/* To cover some of draft-kelsey-thread-network-data-00, we send the
|
/* To cover some of draft-kelsey-thread-network-data-00, we send the
|
||||||
* packet up to our own IP layer in the case where it's addressed to
|
* packet up to our own IP layer in the case where it's addressed to
|
||||||
* an unrecognised child. The special IP forwarding rules can then
|
* an unrecognised child. The special IP forwarding rules can then
|
||||||
|
@ -690,8 +691,8 @@ int_fast8_t thread_routing_add_link(protocol_interface_info_entry_t *cur,
|
||||||
if (our_quality_to_other_neighbour < QUALITY_10dB) {
|
if (our_quality_to_other_neighbour < QUALITY_10dB) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
thread_link_quality_e neighbours_incoming_quality_to_other_neighbour = (byte & ROUTE_DATA_IN_MASK) >> ROUTE_DATA_IN_SHIFT;
|
thread_link_quality_e neighbours_incoming_quality_to_other_neighbour = (thread_link_quality_e) ((byte & ROUTE_DATA_IN_MASK) >> ROUTE_DATA_IN_SHIFT);
|
||||||
thread_link_quality_e neighbours_outgoing_quality_to_other_neighbour = (byte & ROUTE_DATA_OUT_MASK) >> ROUTE_DATA_OUT_SHIFT;
|
thread_link_quality_e neighbours_outgoing_quality_to_other_neighbour = (thread_link_quality_e) ((byte & ROUTE_DATA_OUT_MASK) >> ROUTE_DATA_OUT_SHIFT);
|
||||||
thread_link_quality_e neighbours_quality_to_other_neighbour = thread_quality_combine(neighbours_incoming_quality_to_other_neighbour,
|
thread_link_quality_e neighbours_quality_to_other_neighbour = thread_quality_combine(neighbours_incoming_quality_to_other_neighbour,
|
||||||
neighbours_outgoing_quality_to_other_neighbour);
|
neighbours_outgoing_quality_to_other_neighbour);
|
||||||
if (neighbours_quality_to_other_neighbour < our_quality_to_other_neighbour) {
|
if (neighbours_quality_to_other_neighbour < our_quality_to_other_neighbour) {
|
||||||
|
@ -975,6 +976,21 @@ static void thread_trickle_accelerate(trickle_t *t, const trickle_params_t *para
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread_routing_trickle_advance(thread_routing_info_t *routing, uint16_t ticks)
|
||||||
|
{
|
||||||
|
trickle_t *t =&routing->mle_advert_timer;
|
||||||
|
|
||||||
|
if (!trickle_running(t, &thread_mle_advert_trickle_params)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((t->t > t->now) && (t->t - t->now < ticks)) {
|
||||||
|
/* advance trickle elapsing time by number of ticks */
|
||||||
|
t->t = t->t + ticks - (t->t - t->now);
|
||||||
|
tr_debug("trickle advanced to %d, now %d ", t->t, t->now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This functions speeds up next advertisement depending on the disconnect period to leader
|
// This functions speeds up next advertisement depending on the disconnect period to leader
|
||||||
void thread_routing_leader_connection_validate(thread_info_t *thread, uint16_t disconnect_period)
|
void thread_routing_leader_connection_validate(thread_info_t *thread, uint16_t disconnect_period)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -187,6 +187,7 @@ void thread_routing_free(thread_routing_info_t *routing);
|
||||||
void thread_routing_activate(thread_routing_info_t *routing);
|
void thread_routing_activate(thread_routing_info_t *routing);
|
||||||
void thread_routing_deactivate(thread_routing_info_t *routing);
|
void thread_routing_deactivate(thread_routing_info_t *routing);
|
||||||
bool thread_routing_timer(struct thread_info_s *thread, uint8_t ticks);
|
bool thread_routing_timer(struct thread_info_s *thread, uint8_t ticks);
|
||||||
|
void thread_routing_trickle_advance(thread_routing_info_t *routing, uint16_t ticks);
|
||||||
void thread_routing_leader_connection_validate(struct thread_info_s *thread, uint16_t disconnect_period);
|
void thread_routing_leader_connection_validate(struct thread_info_s *thread, uint16_t disconnect_period);
|
||||||
void thread_routing_set_mesh_callbacks(protocol_interface_info_entry_t *cur);
|
void thread_routing_set_mesh_callbacks(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
@ -233,6 +234,7 @@ int_fast8_t thread_routing_get_route_data(protocol_interface_info_entry_t *cur,
|
||||||
#define thread_routing_activate(routing)
|
#define thread_routing_activate(routing)
|
||||||
#define thread_routing_deactivate(routing)
|
#define thread_routing_deactivate(routing)
|
||||||
#define thread_routing_timer(thread, ticks) false
|
#define thread_routing_timer(thread, ticks) false
|
||||||
|
#define thread_routing_trickle_advance(routing, ticks)
|
||||||
#define thread_routing_leader_connection_validate(thread, disconnect_period)
|
#define thread_routing_leader_connection_validate(thread, disconnect_period)
|
||||||
#define thread_routing_set_mesh_callbacks(cur)
|
#define thread_routing_set_mesh_callbacks(cur)
|
||||||
#define thread_routing_cost_get_by_router_id(routing, routerId) (0)
|
#define thread_routing_cost_get_by_router_id(routing, routerId) (0)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -49,11 +49,13 @@
|
||||||
#include "6LoWPAN/Thread/thread_discovery.h"
|
#include "6LoWPAN/Thread/thread_discovery.h"
|
||||||
#include "6LoWPAN/Thread/thread_nvm_store.h"
|
#include "6LoWPAN/Thread/thread_nvm_store.h"
|
||||||
#include "6LoWPAN/Thread/thread_extension_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_extension_bootstrap.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_neighbor_class.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "thread_meshcop_lib.h"
|
#include "thread_meshcop_lib.h"
|
||||||
#include "thread_diagcop_lib.h"
|
#include "thread_diagcop_lib.h"
|
||||||
#include "coap_service_api.h"
|
#include "coap_service_api.h"
|
||||||
#include "Service_Libs/mle_service/mle_service_api.h"
|
#include "Service_Libs/mle_service/mle_service_api.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "tapi"
|
#define TRACE_GROUP "tapi"
|
||||||
|
@ -452,7 +454,7 @@ int thread_test_key_rotation_update(int8_t interface_id, uint32_t thrKeyRotation
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
|
||||||
if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) {
|
if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) {
|
||||||
linkConfiguration->key_rotation = thrKeyRotation;
|
linkConfiguration->key_rotation = thrKeyRotation;
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, false);
|
thread_key_guard_timer_calculate(cur, linkConfiguration, false);
|
||||||
ret_val = 0;
|
ret_val = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -593,7 +595,7 @@ int thread_test_security_material_set(int8_t interface_id, bool enableSecurity,
|
||||||
mle_service_security_set_security_key(cur->id, key_material, key_index, true);
|
mle_service_security_set_security_key(cur->id, key_material, key_index, true);
|
||||||
//Gen also Next Key
|
//Gen also Next Key
|
||||||
thread_security_next_key_generate(cur, linkConfiguration->master_key, thrKeySequenceCounter);
|
thread_security_next_key_generate(cur, linkConfiguration->master_key, thrKeySequenceCounter);
|
||||||
thread_calculate_key_guard_timer(cur, linkConfiguration, false);
|
thread_key_guard_timer_calculate(cur, linkConfiguration, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret_val = 0;
|
ret_val = 0;
|
||||||
|
@ -625,7 +627,8 @@ int thread_test_version_set(int8_t interface_id, uint8_t version)
|
||||||
thread_version = version;
|
thread_version = version;
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
return -1;
|
/*We already stored the new Thread version above, so even if cur is NULL the version is updated.*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
cur->thread_info->version = version;
|
cur->thread_info->version = version;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1114,22 +1117,22 @@ int8_t thread_test_child_info_get(int8_t interface_id, uint8_t index, uint16_t *
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
uint8_t n= 0;
|
uint8_t n= 0;
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
if (!cur || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) {
|
if (!cur || !cur->mac_parameters || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint16_t mac16 = mac_helper_mac16_address_get(cur);
|
uint16_t mac16 = mac_helper_mac16_address_get(cur);
|
||||||
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!mle_table) {
|
if (!mac_table_list) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == thread_router_addr_from_addr(mac16)) {
|
if (thread_router_addr_from_addr(cur_entry->mac16) == thread_router_addr_from_addr(mac16)) {
|
||||||
if (n == index) {
|
if (n == index) {
|
||||||
*short_addr = cur_entry->short_adr;
|
*short_addr = cur_entry->mac16;
|
||||||
memcpy(mac64,cur_entry->mac64, 8);
|
memcpy(mac64,cur_entry->mac64, 8);
|
||||||
*sleepy = (cur_entry->mode & MLE_RX_ON_IDLE) != MLE_RX_ON_IDLE;
|
*sleepy = cur_entry->rx_on_idle != true;
|
||||||
*margin = cur_entry->link_margin;
|
*margin = thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, cur_entry->index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
|
@ -1156,17 +1159,17 @@ int8_t thread_test_neighbour_info_get(int8_t interface_id, uint8_t index, uint16
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint16_t mac16 = mac_helper_mac16_address_get(cur);
|
uint16_t mac16 = mac_helper_mac16_address_get(cur);
|
||||||
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id);
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
if (!mle_table) {
|
if (!mac_table_list) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) != thread_router_addr_from_addr(mac16)) {
|
if (thread_router_addr_from_addr(cur_entry->mac16) != thread_router_addr_from_addr(mac16)) {
|
||||||
if (n == index) {
|
if (n == index) {
|
||||||
*short_addr = cur_entry->short_adr;
|
*short_addr = cur_entry->mac16;
|
||||||
memcpy(mac64,cur_entry->mac64, 8);
|
memcpy(mac64,cur_entry->mac64, 8);
|
||||||
*margin = cur_entry->link_margin;
|
*margin = thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, cur_entry->index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
#include "NWK_INTERFACE/Include/protocol_timer.h"
|
#include "NWK_INTERFACE/Include/protocol_timer.h"
|
||||||
#include "Service_Libs/etx/etx.h"
|
#include "Service_Libs/etx/etx.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
#include "6LoWPAN/Mesh/mesh.h"
|
#include "6LoWPAN/Mesh/mesh.h"
|
||||||
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
|
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
|
||||||
#include "lowpan_adaptation_interface.h"
|
#include "lowpan_adaptation_interface.h"
|
||||||
|
@ -42,9 +43,15 @@
|
||||||
#ifdef HAVE_RPL
|
#ifdef HAVE_RPL
|
||||||
#include "RPL/rpl_data.h"
|
#include "RPL/rpl_data.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "6lAd"
|
#define TRACE_GROUP "6lAd"
|
||||||
|
|
||||||
|
typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm);
|
||||||
|
|
||||||
// #define EXTRA_DEBUG_EXTRA
|
// #define EXTRA_DEBUG_EXTRA
|
||||||
#ifdef EXTRA_DEBUG_EXTRA
|
#ifdef EXTRA_DEBUG_EXTRA
|
||||||
#define tr_debug_extra(...) tr_debug(__VA_ARGS__)
|
#define tr_debug_extra(...) tr_debug(__VA_ARGS__)
|
||||||
|
@ -88,6 +95,9 @@ typedef struct {
|
||||||
uint16_t max_indirect_big_packets_total;
|
uint16_t max_indirect_big_packets_total;
|
||||||
uint16_t max_indirect_small_packets_per_child;
|
uint16_t max_indirect_small_packets_per_child;
|
||||||
bool fragmenter_active; /*!< Fragmenter state */
|
bool fragmenter_active; /*!< Fragmenter state */
|
||||||
|
adaptation_etx_update_cb *etx_update_cb;
|
||||||
|
mpx_api_t *mpx_api;
|
||||||
|
uint16_t mpx_user_id;
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
} fragmenter_interface_t;
|
} fragmenter_interface_t;
|
||||||
|
|
||||||
|
@ -101,8 +111,8 @@ static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_p
|
||||||
static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interface_ptr, protocol_interface_info_entry_t *cur);
|
static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interface_ptr, protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
/* Data direction and message length validation */
|
/* Data direction and message length validation */
|
||||||
static bool lowpan_adaptation_indirect_data_request(mle_neigh_table_entry_t *mle_entry);
|
static bool lowpan_adaptation_indirect_data_request(mac_neighbor_table_entry_t *mle_entry);
|
||||||
static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_interface_t *interface_ptr);
|
||||||
|
|
||||||
/* Common data tx request process functions */
|
/* Common data tx request process functions */
|
||||||
static void lowpan_active_buffer_state_reset(fragmenter_tx_entry_t *tx_buffer);
|
static void lowpan_active_buffer_state_reset(fragmenter_tx_entry_t *tx_buffer);
|
||||||
|
@ -110,7 +120,7 @@ static uint8_t lowpan_data_request_unique_handle_get(fragmenter_interface_t *int
|
||||||
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size);
|
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size);
|
||||||
static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_interface_t *interface_ptr, bool indirect, bool fragmented, bool is_unicast);
|
static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_interface_t *interface_ptr, bool indirect, bool fragmented, bool is_unicast);
|
||||||
static void lowpan_adaptation_data_request_primitiv_set(const buffer_t *buf, mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur);
|
static void lowpan_adaptation_data_request_primitiv_set(const buffer_t *buf, mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur);
|
||||||
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr);
|
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr);
|
||||||
|
|
||||||
/* Tx confirmation local functions */
|
/* Tx confirmation local functions */
|
||||||
static bool lowpan_active_tx_handle_verify(uint8_t handle, buffer_t *buf);
|
static bool lowpan_active_tx_handle_verify(uint8_t handle, buffer_t *buf);
|
||||||
|
@ -120,12 +130,49 @@ static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status);
|
||||||
static bool lowpan_adaptation_tx_process_ready(fragmenter_tx_entry_t *tx_ptr);
|
static bool lowpan_adaptation_tx_process_ready(fragmenter_tx_entry_t *tx_ptr);
|
||||||
|
|
||||||
/* Fragmentation local functions */
|
/* Fragmentation local functions */
|
||||||
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur);
|
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr);
|
||||||
static bool lowpan_message_fragmentation_message_write(const fragmenter_tx_entry_t *frag_entry, mcps_data_req_t *dataReq);
|
static bool lowpan_message_fragmentation_message_write(const fragmenter_tx_entry_t *frag_entry, mcps_data_req_t *dataReq);
|
||||||
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
|
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
|
||||||
|
|
||||||
static fragmenter_tx_entry_t* lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
|
static fragmenter_tx_entry_t* lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
|
||||||
|
|
||||||
|
static void lowpan_adaptation_etx_update_cb(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm)
|
||||||
|
{
|
||||||
|
switch (confirm->status) {
|
||||||
|
case MLME_TX_NO_ACK:
|
||||||
|
case MLME_NO_DATA:
|
||||||
|
case MLME_SUCCESS:
|
||||||
|
if (buf->link_specific.ieee802_15_4.requestAck) {
|
||||||
|
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
|
||||||
|
bool success = false;
|
||||||
|
if (confirm->status == MLME_SUCCESS) {
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
// Gets table entry
|
||||||
|
mac_neighbor_table_entry_t *neigh_table_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type);
|
||||||
|
if (neigh_table_ptr) {
|
||||||
|
etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries , success, neigh_table_ptr->index);
|
||||||
|
// Updates ETX statistics
|
||||||
|
etx_storage_t * etx_entry = etx_storage_entry_get(cur->id, neigh_table_ptr->index);
|
||||||
|
if (etx_entry) {
|
||||||
|
if (neigh_table_ptr->link_role == PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
|
protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4);
|
||||||
|
} else if (neigh_table_ptr->link_role == SECONDARY_PARENT_NEIGHBOUR) {
|
||||||
|
protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Discover
|
//Discover
|
||||||
static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t interfaceId)
|
static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t interfaceId)
|
||||||
{
|
{
|
||||||
|
@ -139,6 +186,18 @@ static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t inter
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct protocol_interface_info_entry *lowpan_adaptation_network_interface_discover(const mpx_api_t* api)
|
||||||
|
{
|
||||||
|
|
||||||
|
ns_list_foreach(fragmenter_interface_t, interface_ptr, &fragmenter_interface_list) {
|
||||||
|
if (api == interface_ptr->mpx_api) {
|
||||||
|
return protocol_stack_interface_info_get_by_id(interface_ptr->interface_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr , buffer_t *buf)
|
static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr , buffer_t *buf)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +223,7 @@ static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interf
|
||||||
* Data confirm has freed the corresponding "active buffer" and this function will look for new buffer to be set as active buffer.
|
* Data confirm has freed the corresponding "active buffer" and this function will look for new buffer to be set as active buffer.
|
||||||
*/
|
*/
|
||||||
ns_list_foreach_safe(buffer_t, buf, &interface_ptr->directTxQueue) {
|
ns_list_foreach_safe(buffer_t, buf, &interface_ptr->directTxQueue) {
|
||||||
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf);
|
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
|
||||||
//Check that we not trig second active fragmentation process
|
//Check that we not trig second active fragmentation process
|
||||||
if (fragmented_needed && interface_ptr->fragmenter_active) {
|
if (fragmented_needed && interface_ptr->fragmenter_active) {
|
||||||
tr_debug("Do not trig Second active fragmentation");
|
tr_debug("Do not trig Second active fragmentation");
|
||||||
|
@ -179,9 +238,13 @@ static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interf
|
||||||
|
|
||||||
//fragmentation needed
|
//fragmentation needed
|
||||||
|
|
||||||
static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_interface_t *interface_ptr)
|
||||||
{
|
{
|
||||||
uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf);
|
uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf);
|
||||||
|
|
||||||
|
if (interface_ptr->mpx_api) {
|
||||||
|
overhead += interface_ptr->mpx_api->mpx_headroom_size_get(interface_ptr->mpx_api, interface_ptr->mpx_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (buffer_data_length(buf) > (int16_t)mac_helper_max_payload_size(cur, overhead)) {
|
if (buffer_data_length(buf) > (int16_t)mac_helper_max_payload_size(cur, overhead)) {
|
||||||
|
@ -191,9 +254,9 @@ static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_en
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lowpan_adaptation_indirect_data_request(mle_neigh_table_entry_t *mle_entry)
|
static bool lowpan_adaptation_indirect_data_request(mac_neighbor_table_entry_t *entry_ptr)
|
||||||
{
|
{
|
||||||
if (mle_entry && !(mle_entry->mode & MLE_RX_ON_IDLE)) {
|
if (entry_ptr && !(entry_ptr->rx_on_idle)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -302,6 +365,14 @@ int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_si
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lowpan_adaptation_interface_etx_update_enable(int8_t interface_id)
|
||||||
|
{
|
||||||
|
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id);
|
||||||
|
if (interface_ptr) {
|
||||||
|
interface_ptr->etx_update_cb = lowpan_adaptation_etx_update_cb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_free(int8_t interface_id)
|
int8_t lowpan_adaptation_interface_free(int8_t interface_id)
|
||||||
{
|
{
|
||||||
//Discover
|
//Discover
|
||||||
|
@ -350,6 +421,44 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lowpan_adaptation_mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t * interface = lowpan_adaptation_network_interface_discover(api);
|
||||||
|
|
||||||
|
lowpan_adaptation_interface_tx_confirm(interface, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lowpan_adaptation_mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t * interface = lowpan_adaptation_network_interface_discover(api);
|
||||||
|
lowpan_adaptation_interface_data_ind(interface, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id)
|
||||||
|
{
|
||||||
|
//Discover
|
||||||
|
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id);
|
||||||
|
if (!interface_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!mpx_api && interface_ptr->mpx_api) {
|
||||||
|
//Disable Data Callbacks from MPX Class
|
||||||
|
interface_ptr->mpx_api->mpx_user_registration(interface_ptr->mpx_api, NULL, NULL, interface_ptr->mpx_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface_ptr->mpx_api = mpx_api;
|
||||||
|
interface_ptr->mpx_user_id = mpx_user_id;
|
||||||
|
|
||||||
|
if (interface_ptr->mpx_api) {
|
||||||
|
//Register MPX callbacks: confirmation and indication
|
||||||
|
interface_ptr->mpx_api->mpx_user_registration(interface_ptr->mpx_api, lowpan_adaptation_mpx_data_confirm, lowpan_adaptation_mpx_data_indication, interface_ptr->mpx_user_id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size)
|
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +486,7 @@ static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_b
|
||||||
return indirec_entry;
|
return indirec_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur)
|
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr)
|
||||||
{
|
{
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
uint16_t uncompressed_size;
|
uint16_t uncompressed_size;
|
||||||
|
@ -405,7 +514,11 @@ static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_ent
|
||||||
frag_entry->orig_size = frag_entry->size;
|
frag_entry->orig_size = frag_entry->size;
|
||||||
frag_entry->size += (uncompressed_size - frag_entry->pattern);
|
frag_entry->size += (uncompressed_size - frag_entry->pattern);
|
||||||
|
|
||||||
uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf);
|
uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf);
|
||||||
|
if (interface_ptr->mpx_api) {
|
||||||
|
overhead += interface_ptr->mpx_api->mpx_headroom_size_get(interface_ptr->mpx_api, interface_ptr->mpx_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
frag_entry->frag_max = mac_helper_max_payload_size(cur, overhead);
|
frag_entry->frag_max = mac_helper_max_payload_size(cur, overhead);
|
||||||
|
|
||||||
|
|
||||||
|
@ -498,24 +611,25 @@ static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_inte
|
||||||
|
|
||||||
buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
||||||
{
|
{
|
||||||
|
mac_neighbor_table_entry_t *neigh_entry_ptr = NULL;
|
||||||
|
|
||||||
//Validate is link known and set indirect, datareq and security key id mode
|
//Validate is link known and set indirect, datareq and security key id mode
|
||||||
if (buf->dst_sa.addr_type == ADDR_NONE) {
|
if (buf->dst_sa.addr_type == ADDR_NONE) {
|
||||||
goto tx_error_handler;
|
goto tx_error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
mle_neigh_table_entry_t *mle_entry = NULL;
|
|
||||||
/* If MLE is enabled, we will talk if we have an MLE association */
|
/* If MLE is enabled, we will talk if we have an MLE association */
|
||||||
if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG ) {
|
if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG ) {
|
||||||
mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
||||||
|
|
||||||
} else if(buf->dst_sa.addr_type == ADDR_802_15_4_SHORT && (common_read_16_bit(buf->dst_sa.address + 2)) != 0xffff) {
|
} else if(buf->dst_sa.addr_type == ADDR_802_15_4_SHORT && (common_read_16_bit(buf->dst_sa.address + 2)) != 0xffff) {
|
||||||
mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validate neighbour
|
//Validate neighbour
|
||||||
if (!buf->options.ll_security_bypass_tx && mle_entry) {
|
if (!buf->options.ll_security_bypass_tx && neigh_entry_ptr) {
|
||||||
|
|
||||||
if (mle_entry->handshakeReady || mle_entry->thread_commission) {
|
if (neigh_entry_ptr->connected_device || neigh_entry_ptr->trusted_device) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true));
|
//tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true));
|
||||||
|
@ -534,14 +648,14 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_
|
||||||
buf->link_specific.ieee802_15_4.requestAck = false;
|
buf->link_specific.ieee802_15_4.requestAck = false;
|
||||||
} else {
|
} else {
|
||||||
buf->link_specific.ieee802_15_4.requestAck = true;
|
buf->link_specific.ieee802_15_4.requestAck = true;
|
||||||
buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(mle_entry);
|
buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(neigh_entry_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->link_specific.ieee802_15_4.key_id_mode != B_SECURITY_KEY_ID_2) {
|
if (buf->link_specific.ieee802_15_4.key_id_mode != B_SECURITY_KEY_ID_2) {
|
||||||
|
|
||||||
if (!buf->link_specific.ieee802_15_4.requestAck ) {
|
if (!buf->link_specific.ieee802_15_4.requestAck ) {
|
||||||
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
|
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
|
||||||
} else if (mle_entry && !mle_entry->thread_commission) {
|
} else if (ws_info(cur) || (neigh_entry_ptr && !neigh_entry_ptr->trusted_device)) {
|
||||||
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
|
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
|
||||||
} else {
|
} else {
|
||||||
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_IMPLICIT;
|
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_IMPLICIT;
|
||||||
|
@ -551,6 +665,11 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
tx_error_handler:
|
tx_error_handler:
|
||||||
|
if (neigh_entry_ptr && neigh_entry_ptr->nud_active) {
|
||||||
|
mac_neighbor_info(cur)->active_nud_process--;
|
||||||
|
neigh_entry_ptr->nud_active = false;
|
||||||
|
|
||||||
|
}
|
||||||
socket_tx_buffer_event_and_free(buf, SOCKET_TX_FAIL);
|
socket_tx_buffer_event_and_free(buf, SOCKET_TX_FAIL);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -616,7 +735,7 @@ static bool lowpan_adaptation_indirect_cache_sanity_check(protocol_interface_inf
|
||||||
// entry is in cache and is not sent to mac => trigger this
|
// entry is in cache and is not sent to mac => trigger this
|
||||||
tr_debug_extra("sanity check, push seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
|
tr_debug_extra("sanity check, push seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
|
||||||
fragmenter_tx_entry->indirect_data_cached = false;
|
fragmenter_tx_entry->indirect_data_cached = false;
|
||||||
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry);
|
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,7 +757,7 @@ static bool lowpan_adaptation_indirect_cache_trigger(protocol_interface_info_ent
|
||||||
if (addr_ipv6_equal(tx_ptr->buf->dst_sa.address, fragmenter_tx_entry->buf->dst_sa.address)) {
|
if (addr_ipv6_equal(tx_ptr->buf->dst_sa.address, fragmenter_tx_entry->buf->dst_sa.address)) {
|
||||||
tr_debug_extra("pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
|
tr_debug_extra("pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
|
||||||
fragmenter_tx_entry->indirect_data_cached = false;
|
fragmenter_tx_entry->indirect_data_cached = false;
|
||||||
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry);
|
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,7 +793,7 @@ static fragmenter_tx_entry_t* lowpan_adaptation_indirect_first_cached_request_ge
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mle_neigh_table_entry_t *neighbour_to_count)
|
static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count)
|
||||||
{
|
{
|
||||||
if (interface_ptr->max_indirect_small_packets_per_child == 0) {
|
if (interface_ptr->max_indirect_small_packets_per_child == 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -683,7 +802,7 @@ static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info
|
||||||
uint_fast16_t count = 0;
|
uint_fast16_t count = 0;
|
||||||
|
|
||||||
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
|
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
|
||||||
mle_neigh_table_entry_t *tx_neighbour = mle_class_get_by_link_address(cur->id, tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type);
|
mac_neighbor_table_entry_t *tx_neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type);
|
||||||
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
|
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
|
||||||
if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
|
if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
|
||||||
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry);
|
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry);
|
||||||
|
@ -710,7 +829,7 @@ static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr)
|
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr)
|
||||||
{
|
{
|
||||||
mcps_data_req_t dataReq;
|
mcps_data_req_t dataReq;
|
||||||
|
|
||||||
|
@ -737,7 +856,11 @@ static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->mac_api->mcps_data_req(cur->mac_api, &dataReq);
|
if (interface_ptr->mpx_api) {
|
||||||
|
interface_ptr->mpx_api->mpx_data_request(interface_ptr->mpx_api, &dataReq, interface_ptr->mpx_user_id);
|
||||||
|
} else {
|
||||||
|
cur->mac_api->mcps_data_req(cur->mac_api, &dataReq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
|
||||||
|
@ -756,7 +879,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check packet size
|
//Check packet size
|
||||||
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf);
|
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
|
||||||
bool is_unicast = buf->link_specific.ieee802_15_4.requestAck;
|
bool is_unicast = buf->link_specific.ieee802_15_4.requestAck;
|
||||||
bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess;
|
bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess;
|
||||||
if (!indirect) {
|
if (!indirect) {
|
||||||
|
@ -783,7 +906,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
|
|
||||||
if (fragmented_needed) {
|
if (fragmented_needed) {
|
||||||
//Fragmentation init
|
//Fragmentation init
|
||||||
if (lowpan_message_fragmentation_init(buf, tx_ptr, cur) ) {
|
if (lowpan_message_fragmentation_init(buf, tx_ptr, cur, interface_ptr) ) {
|
||||||
tr_error("Fragment init fail");
|
tr_error("Fragment init fail");
|
||||||
if (indirect) {
|
if (indirect) {
|
||||||
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
|
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
|
||||||
|
@ -801,9 +924,9 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
if (indirect) {
|
if (indirect) {
|
||||||
//Add to indirectQUue
|
//Add to indirectQUue
|
||||||
fragmenter_tx_entry_t *tx_ptr_cached;
|
fragmenter_tx_entry_t *tx_ptr_cached;
|
||||||
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
mac_neighbor_table_entry_t *neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type);
|
||||||
if (mle_entry) {
|
if (neigh_entry_ptr) {
|
||||||
buf->link_specific.ieee802_15_4.indirectTTL = (uint32_t) mle_entry->timeout_rx * MLE_TIMER_TICKS_MS;
|
buf->link_specific.ieee802_15_4.indirectTTL = (uint32_t) neigh_entry_ptr->link_lifetime * 1000;
|
||||||
} else {
|
} else {
|
||||||
buf->link_specific.ieee802_15_4.indirectTTL = cur->mac_parameters->mac_in_direct_entry_timeout;
|
buf->link_specific.ieee802_15_4.indirectTTL = cur->mac_parameters->mac_in_direct_entry_timeout;
|
||||||
}
|
}
|
||||||
|
@ -812,7 +935,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
|
|
||||||
// Make room for new message if needed */
|
// Make room for new message if needed */
|
||||||
if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) {
|
if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) {
|
||||||
lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, mle_entry);
|
lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr);
|
||||||
} else {
|
} else {
|
||||||
lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr);
|
lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr);
|
||||||
}
|
}
|
||||||
|
@ -841,7 +964,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lowpan_data_request_to_mac(cur, buf, tx_ptr);
|
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
@ -952,28 +1075,15 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
{
|
{
|
||||||
buf->link_specific.ieee802_15_4.indirectTTL -= 7000;
|
buf->link_specific.ieee802_15_4.indirectTTL -= 7000;
|
||||||
//Push Back to MAC
|
//Push Back to MAC
|
||||||
lowpan_data_request_to_mac(cur, buf, tx_ptr);
|
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (confirm->status) {
|
if (interface_ptr->etx_update_cb) {
|
||||||
case MLME_TX_NO_ACK:
|
interface_ptr->etx_update_cb(cur, buf, confirm);
|
||||||
case MLME_NO_DATA:
|
|
||||||
case MLME_SUCCESS:
|
|
||||||
if (buf->link_specific.ieee802_15_4.requestAck) {
|
|
||||||
bool success = false;
|
|
||||||
if (confirm->status == MLME_SUCCESS) {
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries , success, buf->dst_sa.addr_type, buf->dst_sa.address);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Switch original channel back
|
//Switch original channel back
|
||||||
if (buf->link_specific.ieee802_15_4.rf_channel_switch) {
|
if (buf->link_specific.ieee802_15_4.rf_channel_switch) {
|
||||||
mac_helper_mac_channel_set(cur, buf->link_specific.ieee802_15_4.selected_channel);
|
mac_helper_mac_channel_set(cur, buf->link_specific.ieee802_15_4.selected_channel);
|
||||||
|
@ -983,7 +1093,7 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
switch (confirm->status) {
|
switch (confirm->status) {
|
||||||
|
|
||||||
case MLME_BUSY_CHAN:
|
case MLME_BUSY_CHAN:
|
||||||
lowpan_data_request_to_mac(cur, buf, tx_ptr);
|
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
||||||
break;
|
break;
|
||||||
case MLME_SUCCESS:
|
case MLME_SUCCESS:
|
||||||
|
|
||||||
|
@ -1005,7 +1115,7 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lowpan_data_request_to_mac(cur, buf, tx_ptr);
|
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1049,6 +1159,73 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mac_data_is_broadcast_addr(const sockaddr_t *addr)
|
||||||
|
{
|
||||||
|
return (addr->addr_type == ADDR_802_15_4_SHORT) &&
|
||||||
|
(addr->address[2] == 0xFF && addr->address[3] == 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mcps_data_indication_neighbor_validate(protocol_interface_info_entry_t *cur, const sockaddr_t *addr)
|
||||||
|
{
|
||||||
|
if (thread_info(cur) || ws_info(cur) || (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE)) {
|
||||||
|
mac_neighbor_table_entry_t * neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr->address + 2, addr->addr_type);
|
||||||
|
if (neighbor && (neighbor->connected_device || neighbor->trusted_device)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we don't know them */
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
//6lowpan without MLE don't can't do validation
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void lowpan_adaptation_interface_data_ind(protocol_interface_info_entry_t *cur, const mcps_data_ind_t *data_ind)
|
||||||
|
{
|
||||||
|
buffer_t *buf = buffer_get(data_ind->msduLength);
|
||||||
|
if (!buf || !cur) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t *ptr;
|
||||||
|
buffer_data_add(buf, data_ind->msdu_ptr, data_ind->msduLength);
|
||||||
|
//tr_debug("MAC Paylod size %u %s",data_ind->msduLength, trace_array(data_ind->msdu_ptr, 8));
|
||||||
|
buf->options.lqi = data_ind->mpduLinkQuality;
|
||||||
|
buf->options.dbm = data_ind->signal_dbm;
|
||||||
|
buf->src_sa.addr_type = (addrtype_t)data_ind->SrcAddrMode;
|
||||||
|
ptr = common_write_16_bit(data_ind->SrcPANId, buf->src_sa.address);
|
||||||
|
memcpy(ptr, data_ind->SrcAddr, 8);
|
||||||
|
buf->dst_sa.addr_type = (addrtype_t)data_ind->DstAddrMode;
|
||||||
|
ptr = common_write_16_bit(data_ind->DstPANId, buf->dst_sa.address);
|
||||||
|
memcpy(ptr, data_ind->DstAddr, 8);
|
||||||
|
//Set Link spesific stuff to seperately
|
||||||
|
buf->link_specific.ieee802_15_4.srcPanId = data_ind->SrcPANId;
|
||||||
|
buf->link_specific.ieee802_15_4.dstPanId = data_ind->DstPANId;
|
||||||
|
|
||||||
|
if (mac_data_is_broadcast_addr(&buf->dst_sa)) {
|
||||||
|
buf->options.ll_broadcast_rx = true;
|
||||||
|
}
|
||||||
|
buf->interface = cur;
|
||||||
|
if (data_ind->Key.SecurityLevel) {
|
||||||
|
buf->link_specific.ieee802_15_4.fc_security = true;
|
||||||
|
|
||||||
|
if (cur->mac_security_key_usage_update_cb) {
|
||||||
|
cur->mac_security_key_usage_update_cb(cur, &data_ind->Key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf->link_specific.ieee802_15_4.fc_security = false;
|
||||||
|
if (mac_helper_default_security_level_get(cur) ||
|
||||||
|
!mcps_data_indication_neighbor_validate(cur, &buf->src_sa)) {
|
||||||
|
//SET By Pass
|
||||||
|
buf->options.ll_security_bypass_rx = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->info = (buffer_info_t)(B_TO_IPV6_TXRX | B_FROM_MAC | B_DIR_UP);
|
||||||
|
protocol_push(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status)
|
static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status)
|
||||||
{
|
{
|
||||||
uint8_t socket_event;
|
uint8_t socket_event;
|
||||||
|
@ -1104,22 +1281,38 @@ static bool lowpan_tx_buffer_address_compare(sockaddr_t *dst_sa, uint8_t *addres
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, uint8_t msduhandle)
|
static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, uint8_t msduhandle)
|
||||||
{
|
{
|
||||||
mcps_purge_t purge_req;
|
mcps_purge_t purge_req;
|
||||||
purge_req.msduHandle = msduhandle;
|
purge_req.msduHandle = msduhandle;
|
||||||
cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req);
|
if (interface_ptr->mpx_api) {
|
||||||
|
interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id);
|
||||||
|
} else {
|
||||||
|
if (cur->mac_api->mcps_purge_req) {
|
||||||
|
cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr)
|
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr)
|
||||||
{
|
{
|
||||||
tr_debug("Purge from indirect handle %u", tx_ptr->buf->seq);
|
tr_debug("Purge from indirect handle %u", tx_ptr->buf->seq);
|
||||||
if (cur->mac_api->mcps_purge_req) {
|
lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq);
|
||||||
lowpan_adaptation_purge_from_mac(cur, tx_ptr->buf->seq);
|
|
||||||
}
|
|
||||||
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL);
|
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lowpan_adaptation_remove_free_indirect_table(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *entry_ptr)
|
||||||
|
{
|
||||||
|
//Free firts by defined short address
|
||||||
|
if (entry_ptr->mac16 < 0xfffe) {
|
||||||
|
uint8_t temp_address[2];
|
||||||
|
common_write_16_bit(entry_ptr->mac16, temp_address);
|
||||||
|
lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, temp_address, ADDR_802_15_4_SHORT);
|
||||||
|
}
|
||||||
|
lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, entry_ptr->mac64, ADDR_802_15_4_LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type)
|
int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type)
|
||||||
{
|
{
|
||||||
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id);
|
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -21,13 +21,21 @@
|
||||||
|
|
||||||
struct protocol_interface_info_entry;
|
struct protocol_interface_info_entry;
|
||||||
struct mcps_data_conf_s;
|
struct mcps_data_conf_s;
|
||||||
|
struct mcps_data_ind_s;
|
||||||
struct buffer;
|
struct buffer;
|
||||||
|
struct mpx_api_s;
|
||||||
|
struct mac_neighbor_table_entry;
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_size);
|
int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_size);
|
||||||
|
|
||||||
|
void lowpan_adaptation_interface_etx_update_enable(int8_t interface_id);
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_free(int8_t interface_id);
|
int8_t lowpan_adaptation_interface_free(int8_t interface_id);
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_reset(int8_t interface_id);
|
int8_t lowpan_adaptation_interface_reset(int8_t interface_id);
|
||||||
|
|
||||||
|
int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief call this before normatl TX. This function prepare buffer link spesific metadata and verify packet destination
|
* \brief call this before normatl TX. This function prepare buffer link spesific metadata and verify packet destination
|
||||||
*/
|
*/
|
||||||
|
@ -37,10 +45,14 @@ int8_t lowpan_adaptation_interface_tx(struct protocol_interface_info_entry *cur,
|
||||||
|
|
||||||
int8_t lowpan_adaptation_interface_tx_confirm(struct protocol_interface_info_entry *cur, const struct mcps_data_conf_s *confirm);
|
int8_t lowpan_adaptation_interface_tx_confirm(struct protocol_interface_info_entry *cur, const struct mcps_data_conf_s *confirm);
|
||||||
|
|
||||||
|
void lowpan_adaptation_interface_data_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data_ind);
|
||||||
|
|
||||||
struct buffer *lowpan_adaptation_reassembly(struct protocol_interface_info_entry *cur, struct buffer *buf);
|
struct buffer *lowpan_adaptation_reassembly(struct protocol_interface_info_entry *cur, struct buffer *buf);
|
||||||
|
|
||||||
bool lowpan_adaptation_tx_active(int8_t interface_id);
|
bool lowpan_adaptation_tx_active(int8_t interface_id);
|
||||||
|
|
||||||
|
void lowpan_adaptation_remove_free_indirect_table(struct protocol_interface_info_entry *cur_interface, struct mac_neighbor_table_entry *entry_ptr);
|
||||||
|
|
||||||
int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type);
|
int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type);
|
||||||
|
|
||||||
int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child);
|
int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child);
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS_BOOTSTRAP_H_
|
||||||
|
#define WS_BOOTSTRAP_H_
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WS_INIT_EVENT = 0, /**< tasklet initializion event*/
|
||||||
|
WS_DISCOVERY_START, /**< discovery start*/
|
||||||
|
WS_CONFIGURATION_START, /**< configuration learn start*/
|
||||||
|
WS_AUTHENTICATION_START, /**< authentication start*/
|
||||||
|
WS_OPERATION_START, /**< active operation start*/
|
||||||
|
WS_ROUTING_READY, /**< RPL routing connected to BR*/
|
||||||
|
WS_ADDRESS_ADDED /**< Address added to IF*/
|
||||||
|
} ws_bootsrap_event_type_e;
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode);
|
||||||
|
|
||||||
|
void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
/*State machine transactions*/
|
||||||
|
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bootstrap_event_configuration_start(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bootstrap_event_authentication_start(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bootstrap_event_operation_start(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||||
|
|
||||||
|
void ws_bootstrap_trigle_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
|
||||||
|
#define ws_bootstrap_state_machine(cur)
|
||||||
|
|
||||||
|
#endif //HAVE_WS
|
||||||
|
|
||||||
|
#endif /* WS_BOOTSTRAP_H_ */
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS_COMMON_H_
|
||||||
|
#define WS_COMMON_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "fhss_api.h"
|
||||||
|
#include "fhss_config.h"
|
||||||
|
#include "net_fhss.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||||
|
|
||||||
|
struct ws_pan_information_s;
|
||||||
|
struct ws_neighbor_class_s;
|
||||||
|
|
||||||
|
typedef struct parent_info_s {
|
||||||
|
uint16_t pan_id; /**< PAN ID */
|
||||||
|
uint8_t addr[8]; /**< address */
|
||||||
|
uint8_t link_quality; /**< LQI value measured during reception of the MPDU */
|
||||||
|
int8_t signal_dbm; /**< This extension for normal IEEE 802.15.4 Data indication */
|
||||||
|
ws_pan_information_t pan_information;
|
||||||
|
ws_utt_ie_t ws_utt;
|
||||||
|
ws_us_ie_t ws_us;
|
||||||
|
uint32_t timestamp; /**< Timestamp when packet was received */
|
||||||
|
}parent_info_t;
|
||||||
|
|
||||||
|
typedef struct ws_info_s {
|
||||||
|
char network_name[33]; // Network name max 32 octets + terminating 0.
|
||||||
|
uint16_t network_pan_id;
|
||||||
|
|
||||||
|
trickle_t trickle_pan_config_solicit;
|
||||||
|
trickle_t trickle_pan_config;
|
||||||
|
trickle_t trickle_pan_advertisement_solicit;
|
||||||
|
trickle_t trickle_pan_advertisement;
|
||||||
|
uint8_t rpl_state; // state from rpl_event_t
|
||||||
|
uint8_t pas_requests; // Amount of PAN solicits sent
|
||||||
|
parent_info_t parent_info;
|
||||||
|
uint32_t pan_version_timer; /**< border router version udate timeout */
|
||||||
|
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
|
||||||
|
uint8_t gtkhash[32];
|
||||||
|
bool configuration_learned:1;
|
||||||
|
|
||||||
|
struct ws_pan_information_s pan_information;
|
||||||
|
ws_hopping_schedule_t hopping_schdule;
|
||||||
|
struct ws_neighbor_class_s neighbor_storage;
|
||||||
|
struct fhss_timer *fhss_timer_ptr; // Platform adaptation for FHSS timers.
|
||||||
|
struct fhss_api *fhss_api;
|
||||||
|
} ws_info_t;
|
||||||
|
|
||||||
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
||||||
|
|
||||||
|
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
||||||
|
|
||||||
|
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||||
|
|
||||||
|
#define ws_info(cur) ((cur)->ws_info)
|
||||||
|
#else
|
||||||
|
#define ws_info(cur) ((ws_info_t *) NULL)
|
||||||
|
#define ws_common_seconds_timer(cur, seconds)
|
||||||
|
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
|
||||||
|
#define ws_common_fast_timer(cur, ticks) ((void) 0)
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HAVE_WS
|
||||||
|
#endif //WS_COMMON_H_
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS_COMMON_DEFINES_H_
|
||||||
|
#define WS_COMMON_DEFINES_H_
|
||||||
|
|
||||||
|
#define WH_IE_ELEMENT_HEADER_LENGTH 3
|
||||||
|
|
||||||
|
/* Header IE Sub elements */
|
||||||
|
#define WH_IE_UTT_TYPE 1 /**< Unicast Timing and Frame type information */
|
||||||
|
#define WH_IE_BT_TYPE 2 /**< Broadcast timing information */
|
||||||
|
#define WH_IE_FC_TYPE 3 /**< Flow Control for Extended Direct Frame Exchange */
|
||||||
|
#define WH_IE_RSL_TYPE 4 /**< Received Signal Level information */
|
||||||
|
#define WH_IE_MHDS_TYPE 5 /**< MHDS information for mesh routing */
|
||||||
|
#define WH_IE_VH_TYPE 6 /**< Vendor header information */
|
||||||
|
|
||||||
|
#define WS_WP_NESTED_IE 4 /**< WS nested Payload IE element'selement could include mltiple sub payload IE */
|
||||||
|
|
||||||
|
#define WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH 2
|
||||||
|
|
||||||
|
/* Payload IE sub elements in side WS_WP_NESTED_IE */
|
||||||
|
#define WP_PAYLOAD_IE_US_TYPE 1 /**< Unicast Schedule information */
|
||||||
|
#define WP_PAYLOAD_IE_BS_TYPE 2 /**< Broadcast Schedule information */
|
||||||
|
#define WP_PAYLOAD_IE_VP_TYPE 3 /**< Vendor Payload information */
|
||||||
|
#define WP_PAYLOAD_IE_PAN_TYPE 4 /**< PAN Information */
|
||||||
|
#define WP_PAYLOAD_IE_NETNAME_TYPE 5 /**< Network Name information */
|
||||||
|
#define WP_PAYLOAD_IE_PAN_VER_TYPE 6 /**< Pan configuration version */
|
||||||
|
#define WP_PAYLOAD_IE_GTKHASH_TYPE 7 /**< GTK Hash information */
|
||||||
|
|
||||||
|
/* WS frame types to WH_IE_UTT_TYPE */
|
||||||
|
#define WS_FT_PAN_ADVERT 0 /**< PAN Advert */
|
||||||
|
#define WS_FT_PAN_ADVERT_SOL 1 /**< PAN Advert Solicit */
|
||||||
|
#define WS_FT_PAN_CONF 2 /**< PAN Config */
|
||||||
|
#define WS_FT_PAN_CONF_SOL 3 /**< PAN Config Solicit */
|
||||||
|
#define WS_FT_DATA 4 /**< data type inside MPX */
|
||||||
|
#define WS_FT_ACK 5 /**< Enhanced ACK */
|
||||||
|
#define WS_FT_EAPOL 6 /**< EAPOL message inside MPX */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_pan_information_t PAN information
|
||||||
|
*/
|
||||||
|
typedef struct ws_pan_information_s {
|
||||||
|
uint16_t pan_size; /**< Number devices connected to Border Router. */
|
||||||
|
uint16_t routing_cost; /**< ETX to border Router. */
|
||||||
|
uint16_t pan_version; /**< Pan configuration version will be updatd by Border router at PAN. */
|
||||||
|
bool use_parent_bs:1; /**< 1 for force to follow parent broadcast schedule. 0 node may define own schedule. */
|
||||||
|
bool rpl_routing_method:1; /**< 1 when RPL routing is selected and 0 when L2 routing. */
|
||||||
|
unsigned version:3; /**< Pan version support. */
|
||||||
|
} ws_pan_information_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_hopping_schedule_t Chanel hopping schedule information
|
||||||
|
*/
|
||||||
|
typedef struct ws_hopping_schedule_s {
|
||||||
|
uint8_t fhss_uc_dwell_interval;
|
||||||
|
uint8_t fhss_bc_dwell_interval;
|
||||||
|
uint8_t regulatory_domain; /**< PHY regulatory domain default to "KR" 0x09 */
|
||||||
|
uint8_t operating_class; /**< PHY operating class default to 1 */
|
||||||
|
uint8_t operating_mode; /**< PHY operating mode default to "1b" symbol rate 50, modulation index 1 */
|
||||||
|
uint8_t channel_plan; /**< 0: use regulatory domain values 1: application defined plan */
|
||||||
|
uint8_t channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */
|
||||||
|
uint8_t channel_spacing; /**< derived from regulatory domain. 0:200k, 1:400k, 2:600k, 3:100k */
|
||||||
|
uint8_t number_of_channels; /**< derived from regulatory domain */
|
||||||
|
uint8_t clock_drift;
|
||||||
|
uint8_t timing_accurancy;
|
||||||
|
uint16_t fixed_channel;
|
||||||
|
uint16_t fhss_bsi;
|
||||||
|
uint32_t fhss_broadcast_interval;
|
||||||
|
uint32_t channel_mask[8];
|
||||||
|
uint_fast24_t ch0_freq; // Default should be derived from regulatory domain
|
||||||
|
} ws_hopping_schedule_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_utt_ie_t WS UTT-IE
|
||||||
|
*/
|
||||||
|
typedef struct ws_utt_ie {
|
||||||
|
uint8_t message_type;
|
||||||
|
uint_fast24_t ufsi;
|
||||||
|
} ws_utt_ie_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_bt_ie_t WS BT-IE read
|
||||||
|
*/
|
||||||
|
typedef struct ws_bt_ie {
|
||||||
|
uint16_t broadcast_slot_number;
|
||||||
|
uint_fast24_t broadcast_interval_offset;
|
||||||
|
} ws_bt_ie_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_channel_plan_zero_t WS channel plan 0 define domain and class
|
||||||
|
*/
|
||||||
|
typedef struct ws_channel_plan_zero {
|
||||||
|
uint8_t regulator_domain;
|
||||||
|
uint8_t operation_class;
|
||||||
|
} ws_channel_plan_zero_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_channel_plan_one_t WS channel plan 1 define ch0, spasing and channel count
|
||||||
|
*/
|
||||||
|
typedef struct ws_channel_plan_one {
|
||||||
|
uint_fast24_t ch0;
|
||||||
|
unsigned channel_spacing:4;
|
||||||
|
uint16_t number_of_channel;
|
||||||
|
} ws_channel_plan_one_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_channel_function_zero_t WS function 0 fixed channel
|
||||||
|
*/
|
||||||
|
typedef struct ws_channel_function_zero {
|
||||||
|
uint16_t fixed_channel;
|
||||||
|
} ws_channel_function_zero_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_channel_function_three_t WS function 3 vendor spesific channel hop
|
||||||
|
*/
|
||||||
|
typedef struct ws_channel_function_three {
|
||||||
|
uint8_t channel_hop_count;
|
||||||
|
uint8_t *channel_list;
|
||||||
|
} ws_channel_function_three_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_us_ie_t WS US-IE read
|
||||||
|
*/
|
||||||
|
typedef struct ws_us_ie {
|
||||||
|
uint8_t dwell_interval;
|
||||||
|
uint8_t clock_drift;
|
||||||
|
uint8_t timing_accurancy;
|
||||||
|
unsigned channel_plan:3;
|
||||||
|
unsigned channel_function:3;
|
||||||
|
unsigned excluded_channel_ctrl:2;
|
||||||
|
union {
|
||||||
|
ws_channel_plan_zero_t zero;
|
||||||
|
ws_channel_plan_one_t one;
|
||||||
|
} plan;
|
||||||
|
union {
|
||||||
|
ws_channel_function_zero_t zero;
|
||||||
|
ws_channel_function_three_t three;
|
||||||
|
} function;
|
||||||
|
} ws_us_ie_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ws_bs_ie_t WS BS-IE read
|
||||||
|
*/
|
||||||
|
typedef struct ws_bs_ie {
|
||||||
|
uint32_t broadcast_interval;
|
||||||
|
uint16_t broadcast_schedule_identifier;
|
||||||
|
uint8_t dwell_interval;
|
||||||
|
uint8_t clock_drift;
|
||||||
|
uint8_t timing_accurancy;
|
||||||
|
unsigned channel_plan:3;
|
||||||
|
unsigned channel_function:3;
|
||||||
|
unsigned excluded_channel_ctrl:2;
|
||||||
|
union {
|
||||||
|
ws_channel_plan_zero_t zero;
|
||||||
|
ws_channel_plan_one_t one;
|
||||||
|
} plan;
|
||||||
|
union {
|
||||||
|
ws_channel_function_zero_t zero;
|
||||||
|
ws_channel_function_three_t three;
|
||||||
|
} function;
|
||||||
|
} ws_bs_ie_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define MPX_KEY_MANAGEMENT_ENC_USER_ID 0x0001 /**< MPX Key management user ID */
|
||||||
|
#define MPX_LOWPAN_ENC_USER_ID 0xA0ED /**< MPX Lowpan User Id */
|
||||||
|
|
||||||
|
#define WS_FAN_VERSION_1_0 1
|
||||||
|
|
||||||
|
#define WS_NEIGHBOR_LINK_TIMEOUT 240
|
||||||
|
#define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Threshold (referenced to DEVICE_MIN_SENS) above which a neighbor node may be considered for inclusion into candidate parent set
|
||||||
|
*/
|
||||||
|
#define CAND_PARENT_THRESHOLD 10
|
||||||
|
/*
|
||||||
|
* Hysteresis factor to be applied to CAND_PARENT_THRESHOLD when admitting or dropping nodes from the candidate parent set.
|
||||||
|
*/
|
||||||
|
#define CAND_PARENT_HYSTERISIS 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* value when send the first RPL DIS in 100ms ticks. Value is randomized between timeout/2 - timeout
|
||||||
|
*/
|
||||||
|
#define WS_RPL_DIS_INITIAL_TIMEOUT 600
|
||||||
|
/*
|
||||||
|
* value when send subsequent RPL DIS in 100 ms tics. Value is randomized between timeout/2 - timeout
|
||||||
|
*/
|
||||||
|
#define WS_RPL_DIS_TIMEOUT 1800
|
||||||
|
|
||||||
|
#endif /* WS_COMMON_DEFINES_H_ */
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS_NEIGHBOR_CLASS_H_
|
||||||
|
#define WS_NEIGHBOR_CLASS_H_
|
||||||
|
|
||||||
|
#include "fhss_ws_extension.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
|
||||||
|
typedef struct ws_neighbor_class_entry {
|
||||||
|
fhss_ws_neighbor_timing_info_t fhss_data;
|
||||||
|
uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/
|
||||||
|
uint16_t rsl_out; /*!< RSL EWMA heard by neighbour*/
|
||||||
|
bool candidate_parent:1;
|
||||||
|
} ws_neighbor_class_entry_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Neighbor hopping info data base
|
||||||
|
*/
|
||||||
|
typedef struct ws_neighbor_class_s {
|
||||||
|
ws_neighbor_class_entry_t *neigh_info_list; /*!< Allocated hopping info array*/
|
||||||
|
uint8_t list_size; /*!< List size*/
|
||||||
|
} ws_neighbor_class_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_alloc a function for allocate giving list size
|
||||||
|
*
|
||||||
|
* \param class_data pointer to structure which will be initialized by this function
|
||||||
|
* \param list_size define list size
|
||||||
|
*
|
||||||
|
* \return true Allocate Ok
|
||||||
|
* \return false Allocate Fail
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool ws_neighbor_class_alloc(ws_neighbor_class_t *class_data, uint8_t list_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_dealloc a function for free allocated neighbor hopping info
|
||||||
|
*
|
||||||
|
* \param class_data pointer to structure which will be initialized by this function
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_dealloc(ws_neighbor_class_t *class_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_entry_t a function for search hopping info for giving neighbor attribut
|
||||||
|
*
|
||||||
|
* \param class_data pointer to structure which will be initialized by this function
|
||||||
|
* \param attribute_index define pointer to storage info
|
||||||
|
*
|
||||||
|
* \return NULL when Attribute is not correct
|
||||||
|
* \return Pointer to neighbor hopping info
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ws_neighbor_class_entry_t * ws_neighbor_class_entry_get(ws_neighbor_class_t *class_data, uint8_t attribute_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_entry_t a function for search hopping info for giving neighbor attribute index
|
||||||
|
*
|
||||||
|
* \param class_data pointer to structure which will be initialized by this function
|
||||||
|
* \param entry which attribute index is counted.
|
||||||
|
*
|
||||||
|
* \return Attribute index of entry
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t ws_neighbor_class_entry_index_get(ws_neighbor_class_t *class_data, ws_neighbor_class_entry_t *entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_entry_remove a function for clean information should be call when neighbor is removed
|
||||||
|
*
|
||||||
|
* \param class_data pointer to structure which will be initialized by this function
|
||||||
|
* \param attribute_index define pointer to storage info
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_entry_remove(ws_neighbor_class_t *class_data, uint8_t attribute_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_neighbor_unicast_time_info_update a function for update neighbor unicast time information
|
||||||
|
*
|
||||||
|
* \param ws_neighbor pointer to neighbor
|
||||||
|
* \param ws_utt Unicast time IE data
|
||||||
|
* \param timestamp timestamp for received data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_utt_ie_t *ws_utt, uint32_t timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_neighbor_unicast_schedule_set a function for update neighbor unicast shedule information
|
||||||
|
*
|
||||||
|
* \param ws_neighbor pointer to neighbor
|
||||||
|
* \param ws_us Unicast schedule IE data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_neighbor_broadcast_time_info_update a function for update neighbor broadcast time information
|
||||||
|
*
|
||||||
|
* \param ws_neighbor pointer to neighbor
|
||||||
|
* \param ws_bt_ie Broadcast time IE data
|
||||||
|
* \param timestamp timestamp for received data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_neighbor_broadcast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_bt_ie_t *ws_bt_ie, uint32_t timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information
|
||||||
|
*
|
||||||
|
* \param ws_neighbor pointer to neighbor
|
||||||
|
* \param ws_bs_ie Broadcast schedule IE data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_neighbor_broadcast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_bs_ie_t *ws_bs_ie);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_rssi_from_dbm_calculate
|
||||||
|
*
|
||||||
|
* Calculates rssi value from dbm heard taking into account min sensitivity of radio
|
||||||
|
* dynamically adjusts min sensitivity if value is not properly set
|
||||||
|
*
|
||||||
|
* \param dbm_heard; dbm heard from the neighbour
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t ws_neighbor_class_rssi_from_dbm_calculate(int8_t dbm_heard);
|
||||||
|
|
||||||
|
/** Helper macros to read RSL values from neighbour class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define ws_neighbor_class_rsl_in_get(ws_neighbour) (ws_neighbour->rsl_in >> WS_RSL_SCALING)
|
||||||
|
#define ws_neighbor_class_rsl_out_get(ws_neighbour) (ws_neighbour->rsl_in >> WS_RSL_SCALING)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information
|
||||||
|
*
|
||||||
|
* \param ws_neighbor pointer to neighbor
|
||||||
|
* \param dbm_heard; dbm heard from the neighbour
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor, int8_t dbm_heard);
|
||||||
|
/**
|
||||||
|
* ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information
|
||||||
|
*
|
||||||
|
* \param ws_neighbor pointer to neighbor
|
||||||
|
* \param rsl_reported; rsl value reported by neighbour in packet from RSL-IE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported);
|
||||||
|
|
||||||
|
#endif /* WS_NEIGHBOR_CLASS_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012-2017, Arm Limited and affiliates.
|
* Copyright (c) 2012-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -506,9 +506,8 @@ void border_router_start(protocol_interface_info_entry_t *cur, bool warm_link_re
|
||||||
if (warm_link_restart) {
|
if (warm_link_restart) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
|
||||||
#ifndef NO_MLE
|
#ifndef NO_MLE
|
||||||
mle_class_list_clean(cur->id);
|
|
||||||
blacklist_clear();
|
blacklist_clear();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -708,8 +707,8 @@ static int8_t arm_border_router_interface_down(protocol_interface_info_entry_t *
|
||||||
cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
|
cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
|
||||||
}
|
}
|
||||||
cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id);
|
cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id);
|
||||||
|
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
|
||||||
#ifndef NO_MLE
|
#ifndef NO_MLE
|
||||||
mle_class_list_clean(cur->id);
|
|
||||||
blacklist_clear();
|
blacklist_clear();
|
||||||
#endif
|
#endif
|
||||||
if (nd_nwk) {
|
if (nd_nwk) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "randLIB.h"
|
#include "randLIB.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#ifdef HAVE_RPL
|
|
||||||
#include "RPL/rpl_control.h"
|
#include "RPL/rpl_control.h"
|
||||||
|
#ifdef HAVE_RPL
|
||||||
#include "RPL/rpl_data.h"
|
#include "RPL/rpl_data.h"
|
||||||
#endif
|
#endif
|
||||||
#include "RPL/rpl_protocol.h"
|
#include "RPL/rpl_protocol.h"
|
||||||
|
@ -44,6 +44,8 @@
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "6LoWPAN/ND/nd_router_object.h"
|
#include "6LoWPAN/ND/nd_router_object.h"
|
||||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "icmp"
|
#define TRACE_GROUP "icmp"
|
||||||
|
|
||||||
|
@ -420,6 +422,7 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
uint8_t target[16];
|
uint8_t target[16];
|
||||||
|
uint8_t dummy_sllao[16];
|
||||||
bool proxy = false;
|
bool proxy = false;
|
||||||
const uint8_t *sllao;
|
const uint8_t *sllao;
|
||||||
const uint8_t *aro;
|
const uint8_t *aro;
|
||||||
|
@ -439,7 +442,9 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf)
|
||||||
sllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_SRC_LL_ADDR, 0);
|
sllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_SRC_LL_ADDR, 0);
|
||||||
|
|
||||||
/* If no SLLAO, ignore ARO (RFC 6775 6.5) */
|
/* If no SLLAO, ignore ARO (RFC 6775 6.5) */
|
||||||
if (sllao && cur->ipv6_neighbour_cache.recv_addr_reg) {
|
/* This rule can be bypassed by setting flag "use_eui64_as_slla_in_aro" to true */
|
||||||
|
if (cur->ipv6_neighbour_cache.recv_addr_reg &&
|
||||||
|
(cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro || sllao)) {
|
||||||
aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 0);
|
aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 0);
|
||||||
} else {
|
} else {
|
||||||
aro = NULL;
|
aro = NULL;
|
||||||
|
@ -450,6 +455,15 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf)
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there was no SLLAO on ARO, use mac address to create dummy one... */
|
||||||
|
if (aro && !sllao && cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) {
|
||||||
|
dummy_sllao[0] = ICMPV6_OPT_SRC_LL_ADDR; // Type
|
||||||
|
dummy_sllao[1] = 2; // Length = 2x8 bytes
|
||||||
|
memcpy(dummy_sllao + 2, aro + 8, 8); // EUI-64
|
||||||
|
memset(dummy_sllao + 10, 0, 6); // Padding
|
||||||
|
|
||||||
|
sllao = dummy_sllao;
|
||||||
|
}
|
||||||
// Skip the 4 reserved bytes
|
// Skip the 4 reserved bytes
|
||||||
dptr += 4;
|
dptr += 4;
|
||||||
|
|
||||||
|
@ -529,7 +543,7 @@ drop:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime)
|
int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime)
|
||||||
{
|
{
|
||||||
int ret_val = -1;
|
int ret_val = -1;
|
||||||
|
|
||||||
|
@ -564,7 +578,7 @@ void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur
|
||||||
}
|
}
|
||||||
#endif // HAVE_IPV6_ND
|
#endif // HAVE_IPV6_ND
|
||||||
|
|
||||||
if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src)
|
if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src)
|
||||||
{
|
{
|
||||||
if_address_entry_t *address_entry;
|
if_address_entry_t *address_entry;
|
||||||
uint8_t ipv6_address[16];
|
uint8_t ipv6_address[16];
|
||||||
|
@ -774,7 +788,7 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf)
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
uint32_t preferred_lifetime = common_read_32_bit(ptr);
|
uint32_t preferred_lifetime = common_read_32_bit(ptr);
|
||||||
ptr += 8; //Update 32-bit time and reserved 32-bit
|
ptr += 8; //Update 32-bit time and reserved 32-bit
|
||||||
uint8_t *prefix_ptr = ptr;
|
const uint8_t *prefix_ptr = ptr;
|
||||||
|
|
||||||
//Check is L Flag active
|
//Check is L Flag active
|
||||||
if (prefix_flags & PIO_L) {
|
if (prefix_flags & PIO_L) {
|
||||||
|
@ -990,6 +1004,10 @@ static buffer_t *icmpv6_na_handler(buffer_t *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address);
|
ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address);
|
||||||
|
if (ws_info(cur) && neighbour_entry->state == IP_NEIGHBOUR_REACHABLE) {
|
||||||
|
tr_debug("NA neigh update");
|
||||||
|
ws_common_neighbor_update(cur, target);
|
||||||
|
}
|
||||||
|
|
||||||
drop:
|
drop:
|
||||||
return buffer_free(buf);
|
return buffer_free(buf);
|
||||||
|
@ -1323,7 +1341,7 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
|
||||||
} else {
|
} else {
|
||||||
/* RFC 4861 7.2.2. says we should use the source of traffic prompting the NS, if possible */
|
/* RFC 4861 7.2.2. says we should use the source of traffic prompting the NS, if possible */
|
||||||
/* This is also used to specify the address for ARO messages */
|
/* This is also used to specify the address for ARO messages */
|
||||||
if (prompting_src_addr && addr_is_assigned_to_interface(cur, prompting_src_addr)) {
|
if (aro || (prompting_src_addr && addr_is_assigned_to_interface(cur, prompting_src_addr))) {
|
||||||
memcpy(buf->src_sa.address, prompting_src_addr, 16);
|
memcpy(buf->src_sa.address, prompting_src_addr, 16);
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise, according to RFC 4861, we could use any address.
|
/* Otherwise, according to RFC 4861, we could use any address.
|
||||||
|
@ -1347,7 +1365,15 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* SLLAO is required if we're sending an ARO */
|
/* SLLAO is required if we're sending an ARO */
|
||||||
ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address);
|
/* This rule can be bypassed with flag use_eui64_as_slla_in_aro */
|
||||||
|
if (!cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) {
|
||||||
|
ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address);
|
||||||
|
}
|
||||||
|
/* If ARO Success sending is omitted, MAC ACK is used instead */
|
||||||
|
/* Setting callback for receiving ACK from adaptation layer */
|
||||||
|
if (aro && cur->ipv6_neighbour_cache.omit_aro_success) {
|
||||||
|
buf->ack_receive_cb = rpl_control_address_register_done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf->src_sa.addr_type = ADDR_IPV6;
|
buf->src_sa.addr_type = ADDR_IPV6;
|
||||||
|
|
||||||
|
@ -1481,6 +1507,12 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited,
|
||||||
|
|
||||||
tr_debug("Build NA");
|
tr_debug("Build NA");
|
||||||
|
|
||||||
|
/* Check if ARO status == success, then sending can be omitted with flag */
|
||||||
|
if (aro && cur->ipv6_neighbour_cache.omit_aro_success && aro->status == ARO_SUCCESS) {
|
||||||
|
tr_debug("Omit success reply");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
buffer_t *buf = buffer_get(8 + 16 + 16 + 16); /* fixed, target addr, target ll addr, aro */
|
buffer_t *buf = buffer_get(8 + 16 + 16 + 16); /* fixed, target addr, target ll addr, aro */
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -140,8 +140,8 @@ extern void icmpv6_recv_ra_routes(struct protocol_interface_info_entry *cur, boo
|
||||||
extern void icmpv6_recv_ra_prefixes(struct protocol_interface_info_entry *cur, bool enable);
|
extern void icmpv6_recv_ra_prefixes(struct protocol_interface_info_entry *cur, bool enable);
|
||||||
|
|
||||||
extern void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len);
|
extern void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len);
|
||||||
extern int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime);
|
extern int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime);
|
||||||
extern struct if_address_entry *icmpv6_slaac_address_add(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src);
|
extern struct if_address_entry *icmpv6_slaac_address_add(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2017, Arm Limited and affiliates.
|
* Copyright (c) 2015-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017, Arm Limited and affiliates.
|
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2010-2017, Arm Limited and affiliates.
|
* Copyright (c) 2008, 2010-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2017, Arm Limited and affiliates.
|
* Copyright (c) 2011-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -110,7 +110,7 @@ buffer_t *buffer_get_specific(uint16_t headroom, uint16_t size, uint16_t minspac
|
||||||
#endif
|
#endif
|
||||||
buf->size = total_size;
|
buf->size = total_size;
|
||||||
} else {
|
} else {
|
||||||
tr_error("buffer_get failed: alloc(%zd)", sizeof(buffer_t) + total_size);
|
tr_error("buffer_get failed: alloc(%d)", (int) sizeof(buffer_t) + total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol_stats_update(STATS_BUFFER_ALLOC, 1);
|
protocol_stats_update(STATS_BUFFER_ALLOC, 1);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2010-2017, Arm Limited and affiliates.
|
* Copyright (c) 2008, 2010-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -96,6 +96,8 @@ typedef struct if_address_entry {
|
||||||
bool temporary:1; // RFC 4941 temporary address
|
bool temporary:1; // RFC 4941 temporary address
|
||||||
bool tentative:1; // Tentative address (Duplicate Address Detection running)
|
bool tentative:1; // Tentative address (Duplicate Address Detection running)
|
||||||
bool group_added:1; // Solicited-Node group added
|
bool group_added:1; // Solicited-Node group added
|
||||||
|
uint8_t addr_reg_pend; // Bitmask for pending address registrations. Based on RPL path control bits
|
||||||
|
uint8_t addr_reg_done; // Bitmask for address registration done. Based on RPL path control bits
|
||||||
if_address_source_t source; //
|
if_address_source_t source; //
|
||||||
if_address_callback_fn *cb; // Address protocol callback function
|
if_address_callback_fn *cb; // Address protocol callback function
|
||||||
void *data; // Address protocol data
|
void *data; // Address protocol data
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2017, Arm Limited and affiliates.
|
* Copyright (c) 2008-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -228,6 +228,7 @@ typedef struct buffer {
|
||||||
uint8_t trickle_data_field[4];
|
uint8_t trickle_data_field[4];
|
||||||
buffer_options_t options; /*!< Additional signal info etc */
|
buffer_options_t options; /*!< Additional signal info etc */
|
||||||
buffer_routing_info_t *route; /* A pointer last to try to get neat alignment for data */
|
buffer_routing_info_t *route; /* A pointer last to try to get neat alignment for data */
|
||||||
|
void (*ack_receive_cb)(struct buffer *buffer_ptr, uint8_t status); /*!< ACK receive callback. If set, will be called when TX is done */
|
||||||
uint8_t buf[]; /*!< Trailing buffer data */
|
uint8_t buf[]; /*!< Trailing buffer data */
|
||||||
} buffer_t;
|
} buffer_t;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2015, 2017, Arm Limited and affiliates.
|
* Copyright (c) 2008-2015, 2017-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -1396,6 +1396,10 @@ buffer_t *socket_tx_buffer_event(buffer_t *buf, uint8_t status)
|
||||||
* and we mapped straight to MAC address).
|
* and we mapped straight to MAC address).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (buf->ack_receive_cb) {
|
||||||
|
buf->ack_receive_cb(buf, status);
|
||||||
|
}
|
||||||
|
|
||||||
/* Suppress events once socket orphaned */
|
/* Suppress events once socket orphaned */
|
||||||
if (!buf->socket || (buf->socket->flags & (SOCKET_FLAG_PENDING|SOCKET_FLAG_CLOSED))) {
|
if (!buf->socket || (buf->socket->flags & (SOCKET_FLAG_PENDING|SOCKET_FLAG_CLOSED))) {
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -106,7 +106,7 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
|
||||||
// coverity[returned_null] for ignoring protocol_stack_interface_info_get_by_id NULL return
|
// coverity[returned_null] for ignoring protocol_stack_interface_info_get_by_id NULL return
|
||||||
DHCPV6_server_service_remove_GUA_from_neighcache(protocol_stack_interface_info_get_by_id(serverBase->interfaceId), nonTemporalAddress.requestedAddress);
|
DHCPV6_server_service_remove_GUA_from_neighcache(protocol_stack_interface_info_get_by_id(serverBase->interfaceId), nonTemporalAddress.requestedAddress);
|
||||||
}
|
}
|
||||||
if (thread_bbr_nd_entry_add(serverBase->interfaceId,dhcp_allocated_address->nonTemporalAddress, nonTemporalAddress.validLifeTime, serverBase->guaPrefix, NULL) == -1) {
|
if (thread_bbr_nd_entry_add(serverBase->interfaceId,dhcp_allocated_address->nonTemporalAddress, nonTemporalAddress.validLifeTime, serverBase->guaPrefix) == -1) {
|
||||||
// No nanostack BBR present we will put entry for application implemented BBR
|
// No nanostack BBR present we will put entry for application implemented BBR
|
||||||
ipv6_route_t *route = ipv6_route_add_with_info(dhcp_allocated_address->nonTemporalAddress, 128, serverBase->interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST,serverBase->guaPrefix,0, nonTemporalAddress.validLifeTime, 0);
|
ipv6_route_t *route = ipv6_route_add_with_info(dhcp_allocated_address->nonTemporalAddress, 128, serverBase->interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST,serverBase->guaPrefix,0, nonTemporalAddress.validLifeTime, 0);
|
||||||
if (!route) {
|
if (!route) {
|
||||||
|
@ -114,7 +114,6 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
|
||||||
libdhcpv6_address_rm_from_allocated_list(serverBase,dhcp_allocated_address->nonTemporalAddress);
|
libdhcpv6_address_rm_from_allocated_list(serverBase,dhcp_allocated_address->nonTemporalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -139,6 +139,9 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
bool macUpState;
|
bool macUpState;
|
||||||
bool shortAdressValid: 1; //Define Dynamic src address to mac16 when it is true
|
bool shortAdressValid: 1; //Define Dynamic src address to mac16 when it is true
|
||||||
bool beaconSrcAddressModeLong: 1; //This force beacon src to mac64 otherwise shortAdressValid will define type
|
bool beaconSrcAddressModeLong: 1; //This force beacon src to mac64 otherwise shortAdressValid will define type
|
||||||
|
bool mac_extension_enabled:1;
|
||||||
|
bool mac_ack_tx_active:1;
|
||||||
|
bool mac_frame_pending:1;
|
||||||
uint16_t mac_short_address;
|
uint16_t mac_short_address;
|
||||||
uint16_t pan_id;
|
uint16_t pan_id;
|
||||||
uint8_t mac64[8];
|
uint8_t mac64[8];
|
||||||
|
@ -154,6 +157,8 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
bool macProminousMode:1;
|
bool macProminousMode:1;
|
||||||
bool macGTSPermit:1;
|
bool macGTSPermit:1;
|
||||||
bool mac_security_enabled:1;
|
bool mac_security_enabled:1;
|
||||||
|
/* Let trough packet which is secured properly (MIC authenticated group key) and src address is 64-bit*/
|
||||||
|
bool mac_security_bypass_unknow_device:1;
|
||||||
/* Load balancing need this feature */
|
/* Load balancing need this feature */
|
||||||
bool macAcceptAnyBeacon:1;
|
bool macAcceptAnyBeacon:1;
|
||||||
|
|
||||||
|
@ -169,6 +174,7 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
bool macRfRadioTxActive:1;
|
bool macRfRadioTxActive:1;
|
||||||
bool macBroadcastDisabled:1;
|
bool macBroadcastDisabled:1;
|
||||||
bool scan_active:1;
|
bool scan_active:1;
|
||||||
|
bool rf_csma_extension_supported:1;
|
||||||
/* CSMA Params */
|
/* CSMA Params */
|
||||||
unsigned macMinBE:4;
|
unsigned macMinBE:4;
|
||||||
unsigned macMaxBE:4;
|
unsigned macMaxBE:4;
|
||||||
|
@ -201,6 +207,7 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
uint8_t mac_cca_retry;
|
uint8_t mac_cca_retry;
|
||||||
uint8_t mac_ack_wait_duration;
|
uint8_t mac_ack_wait_duration;
|
||||||
uint8_t mac_mlme_retry_max;
|
uint8_t mac_mlme_retry_max;
|
||||||
|
uint8_t aUnitBackoffPeriod;
|
||||||
/* Indirect queue parameters */
|
/* Indirect queue parameters */
|
||||||
struct mac_pre_build_frame *indirect_pd_data_request_queue;
|
struct mac_pre_build_frame *indirect_pd_data_request_queue;
|
||||||
arm_event_t mac_mcps_timer_event;
|
arm_event_t mac_mcps_timer_event;
|
||||||
|
@ -217,6 +224,8 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
int8_t cca_timer_id;
|
int8_t cca_timer_id;
|
||||||
int8_t bc_timer_id;
|
int8_t bc_timer_id;
|
||||||
uint32_t mlme_tick_count;
|
uint32_t mlme_tick_count;
|
||||||
|
uint32_t symbol_rate;
|
||||||
|
uint32_t symbol_time_us;
|
||||||
uint8_t max_ED;
|
uint8_t max_ED;
|
||||||
uint16_t mlme_ED_counter;
|
uint16_t mlme_ED_counter;
|
||||||
mac_tx_status_t mac_tx_status;
|
mac_tx_status_t mac_tx_status;
|
||||||
|
@ -250,22 +259,26 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
} protocol_interface_rf_mac_setup_s;
|
} protocol_interface_rf_mac_setup_s;
|
||||||
|
|
||||||
|
|
||||||
#define MAC_FCF_FRAME_TYPE_MASK 0x0007
|
#define MAC_FCF_FRAME_TYPE_MASK 0x0007
|
||||||
#define MAC_FCF_FRAME_TYPE_SHIFT 0
|
#define MAC_FCF_FRAME_TYPE_SHIFT 0
|
||||||
#define MAC_FCF_SECURITY_BIT_MASK 0x0008
|
#define MAC_FCF_SECURITY_BIT_MASK 0x0008
|
||||||
#define MAC_FCF_SECURITY_BIT_SHIFT 3
|
#define MAC_FCF_SECURITY_BIT_SHIFT 3
|
||||||
#define MAC_FCF_PENDING_BIT_MASK 0x0010
|
#define MAC_FCF_PENDING_BIT_MASK 0x0010
|
||||||
#define MAC_FCF_PENDING_BIT_SHIFT 4
|
#define MAC_FCF_PENDING_BIT_SHIFT 4
|
||||||
#define MAC_FCF_ACK_REQ_BIT_MASK 0x0020
|
#define MAC_FCF_ACK_REQ_BIT_MASK 0x0020
|
||||||
#define MAC_FCF_ACK_REQ_BIT_SHIFT 5
|
#define MAC_FCF_ACK_REQ_BIT_SHIFT 5
|
||||||
#define MAC_FCF_INTRA_PANID_MASK 0x0040
|
#define MAC_FCF_INTRA_PANID_MASK 0x0040
|
||||||
#define MAC_FCF_INTRA_PANID_SHIFT 6
|
#define MAC_FCF_INTRA_PANID_SHIFT 6
|
||||||
#define MAC_FCF_DST_ADDR_MASK 0x0c00
|
#define MAC_FCF_SEQ_NUM_SUPPRESS_MASK 0x0100
|
||||||
#define MAC_FCF_DST_ADDR_SHIFT 10
|
#define MAC_FCF_SEQ_NUM_SUPPRESS_SHIFT 8
|
||||||
#define MAC_FCF_VERSION_MASK 0x3000
|
#define MAC_FCF_IE_PRESENTS_MASK 0x0200
|
||||||
#define MAC_FCF_VERSION_SHIFT 12
|
#define MAC_FCF_IE_PRESENTS_SHIFT 9
|
||||||
#define MAC_FCF_SRC_ADDR_MASK 0xc000
|
#define MAC_FCF_DST_ADDR_MASK 0x0c00
|
||||||
#define MAC_FCF_SRC_ADDR_SHIFT 14
|
#define MAC_FCF_DST_ADDR_SHIFT 10
|
||||||
|
#define MAC_FCF_VERSION_MASK 0x3000
|
||||||
|
#define MAC_FCF_VERSION_SHIFT 12
|
||||||
|
#define MAC_FCF_SRC_ADDR_MASK 0xc000
|
||||||
|
#define MAC_FCF_SRC_ADDR_SHIFT 14
|
||||||
|
|
||||||
/* MAC supported frame types */
|
/* MAC supported frame types */
|
||||||
#define FC_BEACON_FRAME 0x00
|
#define FC_BEACON_FRAME 0x00
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -57,7 +57,12 @@ uint32_t mac_read_phy_datarate(const fhss_api_t *fhss_api)
|
||||||
if (!mac_setup) {
|
if (!mac_setup) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return dev_get_phy_datarate(mac_setup->dev_driver->phy_driver, mac_setup->mac_channel_list.channel_page);
|
uint32_t datarate = dev_get_phy_datarate(mac_setup->dev_driver->phy_driver, mac_setup->mac_channel_list.channel_page);
|
||||||
|
// If datarate is not set, use default 250kbit/s.
|
||||||
|
if (!datarate) {
|
||||||
|
datarate = 250000;
|
||||||
|
}
|
||||||
|
return datarate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number)
|
int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number)
|
||||||
|
@ -66,9 +71,8 @@ int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number)
|
||||||
if (!mac_setup) {
|
if (!mac_setup) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// If TX is active, send internal CCA fail event. MAC state machine would crash without TX done event.
|
if (mac_setup->mac_ack_tx_active || (mac_setup->active_pd_data_request && mac_setup->active_pd_data_request->asynch_request)) {
|
||||||
if (mac_setup->macRfRadioTxActive == true) {
|
return -1;
|
||||||
mac_setup->dev_driver->phy_driver->phy_tx_done_cb(mac_setup->dev_driver->id, 1, PHY_LINK_TX_FAIL, 0, 0);
|
|
||||||
}
|
}
|
||||||
return mac_mlme_rf_channel_change(mac_setup, channel_number);
|
return mac_mlme_rf_channel_change(mac_setup, channel_number);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2017, Arm Limited and affiliates.
|
* Copyright (c) 2014-2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
#include "mac_filter.h"
|
#include "mac_filter.h"
|
||||||
#include "mac_common_defines.h"
|
#include "mac_common_defines.h"
|
||||||
|
|
||||||
|
#include "mac_mcps.h"
|
||||||
#include "MAC/IEEE802_15_4/mac_mcps_sap.h"
|
#include "MAC/IEEE802_15_4/mac_mcps_sap.h"
|
||||||
#include "MAC/IEEE802_15_4/mac_header_helper_functions.h"
|
#include "MAC/IEEE802_15_4/mac_header_helper_functions.h"
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue